Skip to content

Commit bb06453

Browse files
authored
[Clang][CTAD][NFC] Unify transformTemplateParameter() (#100865)
We ended up having two transformTemplateParameter() after CTAD for type aliases was landed. This patch cleans them up and allows them to share one implementation. As a bonus, this also uses getDepthAndIndex() in preference to getTemplateParameter{Depth,Index}().
1 parent 81595e9 commit bb06453

File tree

1 file changed

+42
-77
lines changed

1 file changed

+42
-77
lines changed

clang/lib/Sema/SemaTemplateDeductionGuide.cpp

Lines changed: 42 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "clang/Sema/Overload.h"
4040
#include "clang/Sema/Ownership.h"
4141
#include "clang/Sema/Scope.h"
42+
#include "clang/Sema/SemaInternal.h"
4243
#include "clang/Sema/Template.h"
4344
#include "clang/Sema/TemplateDeduction.h"
4445
#include "llvm/ADT/ArrayRef.h"
@@ -241,11 +242,10 @@ NamedDecl *buildDeductionGuide(
241242
}
242243

243244
// Transform a given template type parameter `TTP`.
244-
TemplateTypeParmDecl *
245-
transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC,
246-
TemplateTypeParmDecl *TTP,
247-
MultiLevelTemplateArgumentList &Args,
248-
unsigned NewDepth, unsigned NewIndex) {
245+
TemplateTypeParmDecl *transformTemplateTypeParam(
246+
Sema &SemaRef, DeclContext *DC, TemplateTypeParmDecl *TTP,
247+
MultiLevelTemplateArgumentList &Args, unsigned NewDepth, unsigned NewIndex,
248+
bool EvaluateConstraint) {
249249
// TemplateTypeParmDecl's index cannot be changed after creation, so
250250
// substitute it directly.
251251
auto *NewTTP = TemplateTypeParmDecl::Create(
@@ -257,7 +257,7 @@ transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC,
257257
: std::nullopt);
258258
if (const auto *TC = TTP->getTypeConstraint())
259259
SemaRef.SubstTypeConstraint(NewTTP, TC, Args,
260-
/*EvaluateConstraint=*/true);
260+
/*EvaluateConstraint=*/EvaluateConstraint);
261261
if (TTP->hasDefaultArgument()) {
262262
TemplateArgumentLoc InstantiatedDefaultArg;
263263
if (!SemaRef.SubstTemplateArgument(
@@ -284,6 +284,22 @@ transformTemplateParam(Sema &SemaRef, DeclContext *DC,
284284
return NewParam;
285285
}
286286

287+
NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
288+
NamedDecl *TemplateParam,
289+
MultiLevelTemplateArgumentList &Args,
290+
unsigned NewIndex, unsigned NewDepth,
291+
bool EvaluateConstraint = true) {
292+
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
293+
return transformTemplateTypeParam(
294+
SemaRef, DC, TTP, Args, NewDepth, NewIndex,
295+
/*EvaluateConstraint=*/EvaluateConstraint);
296+
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
297+
return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
298+
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
299+
return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
300+
llvm_unreachable("Unhandled template parameter types");
301+
}
302+
287303
/// Transform to convert portions of a constructor declaration into the
288304
/// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
289305
struct ConvertConstructorToDeductionGuideTransform {
@@ -358,20 +374,21 @@ struct ConvertConstructorToDeductionGuideTransform {
358374
Args.addOuterRetainedLevel();
359375
if (NestedPattern)
360376
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
361-
NamedDecl *NewParam = transformTemplateParameter(Param, Args);
377+
auto [Depth, Index] = getDepthAndIndex(Param);
378+
NamedDecl *NewParam = transformTemplateParameter(
379+
SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1);
362380
if (!NewParam)
363381
return nullptr;
364382
// Constraints require that we substitute depth-1 arguments
365383
// to match depths when substituted for evaluation later
366384
Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
367385

368386
if (NestedPattern) {
369-
TemplateDeclInstantiator Instantiator(SemaRef, DC,
370-
OuterInstantiationArgs);
371-
Instantiator.setEvaluateConstraints(false);
372-
SemaRef.runWithSufficientStackSpace(NewParam->getLocation(), [&] {
373-
NewParam = cast<NamedDecl>(Instantiator.Visit(NewParam));
374-
});
387+
auto [Depth, Index] = getDepthAndIndex(NewParam);
388+
NewParam = transformTemplateParameter(
389+
SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
390+
Depth - OuterInstantiationArgs.getNumSubstitutedLevels(),
391+
/*EvaluateConstraint=*/false);
375392
}
376393

377394
assert(NewParam->getTemplateDepth() == 0 &&
@@ -479,25 +496,6 @@ struct ConvertConstructorToDeductionGuideTransform {
479496
}
480497

481498
private:
482-
/// Transform a constructor template parameter into a deduction guide template
483-
/// parameter, rebuilding any internal references to earlier parameters and
484-
/// renumbering as we go.
485-
NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam,
486-
MultiLevelTemplateArgumentList &Args) {
487-
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
488-
return transformTemplateTypeParam(
489-
SemaRef, DC, TTP, Args, TTP->getDepth() - 1,
490-
Depth1IndexAdjustment + TTP->getIndex());
491-
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
492-
return transformTemplateParam(SemaRef, DC, TTP, Args,
493-
Depth1IndexAdjustment + TTP->getIndex(),
494-
TTP->getDepth() - 1);
495-
auto *NTTP = cast<NonTypeTemplateParmDecl>(TemplateParam);
496-
return transformTemplateParam(SemaRef, DC, NTTP, Args,
497-
Depth1IndexAdjustment + NTTP->getIndex(),
498-
NTTP->getDepth() - 1);
499-
}
500-
501499
QualType transformFunctionProtoType(
502500
TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
503501
SmallVectorImpl<ParmVarDecl *> &Params,
@@ -634,26 +632,6 @@ struct ConvertConstructorToDeductionGuideTransform {
634632
}
635633
};
636634

637-
unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
638-
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
639-
return TTP->getDepth();
640-
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
641-
return TTP->getDepth();
642-
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
643-
return NTTP->getDepth();
644-
llvm_unreachable("Unhandled template parameter types");
645-
}
646-
647-
unsigned getTemplateParameterIndex(NamedDecl *TemplateParam) {
648-
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
649-
return TTP->getIndex();
650-
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
651-
return TTP->getIndex();
652-
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
653-
return NTTP->getIndex();
654-
llvm_unreachable("Unhandled template parameter types");
655-
}
656-
657635
// Find all template parameters that appear in the given DeducedArgs.
658636
// Return the indices of the template parameters in the TemplateParams.
659637
SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
@@ -689,8 +667,10 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
689667

690668
void MarkAppeared(NamedDecl *ND) {
691669
if (llvm::isa<NonTypeTemplateParmDecl, TemplateTypeParmDecl,
692-
TemplateTemplateParmDecl>(ND))
693-
Mark(getTemplateParameterDepth(ND), getTemplateParameterIndex(ND));
670+
TemplateTemplateParmDecl>(ND)) {
671+
auto [Depth, Index] = getDepthAndIndex(ND);
672+
Mark(Depth, Index);
673+
}
694674
}
695675
void Mark(unsigned Depth, unsigned Index) {
696676
if (Index < TemplateParamList->size() &&
@@ -722,20 +702,6 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
722702
return false;
723703
}
724704

725-
NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
726-
NamedDecl *TemplateParam,
727-
MultiLevelTemplateArgumentList &Args,
728-
unsigned NewIndex, unsigned NewDepth) {
729-
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
730-
return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth,
731-
NewIndex);
732-
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
733-
return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
734-
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
735-
return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
736-
llvm_unreachable("Unhandled template parameter types");
737-
}
738-
739705
// Build the associated constraints for the alias deduction guides.
740706
// C++ [over.match.class.deduct]p3.3:
741707
// The associated constraints ([temp.constr.decl]) are the conjunction of the
@@ -791,7 +757,7 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
791757
NamedDecl *NewParam = transformTemplateParameter(
792758
SemaRef, AliasTemplate->getDeclContext(), TP, Args,
793759
/*NewIndex=*/AdjustedAliasTemplateArgs.size(),
794-
getTemplateParameterDepth(TP) + AdjustDepth);
760+
getDepthAndIndex(TP).first + AdjustDepth);
795761

796762
TemplateArgument NewTemplateArgument =
797763
Context.getInjectedTemplateArg(NewParam);
@@ -814,10 +780,10 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
814780
Args.setKind(TemplateSubstitutionKind::Rewrite);
815781
Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
816782
// Rebuild the template parameter with updated depth and index.
817-
NamedDecl *NewParam = transformTemplateParameter(
818-
SemaRef, F->getDeclContext(), TP, Args,
819-
/*NewIndex=*/FirstUndeducedParamIdx,
820-
getTemplateParameterDepth(TP) + AdjustDepth);
783+
NamedDecl *NewParam =
784+
transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args,
785+
/*NewIndex=*/FirstUndeducedParamIdx,
786+
getDepthAndIndex(TP).first + AdjustDepth);
821787
FirstUndeducedParamIdx += 1;
822788
assert(TemplateArgsForBuildingRC[Index].isNull());
823789
TemplateArgsForBuildingRC[Index] =
@@ -919,7 +885,7 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef,
919885
NamedDecl *NewParam = transformTemplateParameter(
920886
SemaRef, AliasTemplate->getDeclContext(), TP, Args,
921887
/*NewIndex=*/TransformedTemplateArgs.size(),
922-
getTemplateParameterDepth(TP) + AdjustDepth);
888+
getDepthAndIndex(TP).first + AdjustDepth);
923889

924890
TemplateArgument NewTemplateArgument =
925891
Context.getInjectedTemplateArg(NewParam);
@@ -1081,8 +1047,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
10811047
Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
10821048
NamedDecl *NewParam = transformTemplateParameter(
10831049
SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1084-
/*NewIndex=*/FPrimeTemplateParams.size(),
1085-
getTemplateParameterDepth(TP));
1050+
/*NewIndex=*/FPrimeTemplateParams.size(), getDepthAndIndex(TP).first);
10861051
FPrimeTemplateParams.push_back(NewParam);
10871052

10881053
TemplateArgument NewTemplateArgument =
@@ -1101,7 +1066,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
11011066
Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
11021067
NamedDecl *NewParam = transformTemplateParameter(
11031068
SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1104-
getTemplateParameterDepth(TP));
1069+
getDepthAndIndex(TP).first);
11051070
FPrimeTemplateParams.push_back(NewParam);
11061071

11071072
assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&

0 commit comments

Comments
 (0)