Skip to content

Commit c9297f8

Browse files
committed
[clang] CTAD: use index and depth to retrieve template parameters in TemplateParamsReferencedInTemplateArgumentList.
1 parent 7eae9bb commit c9297f8

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2754,20 +2754,34 @@ struct ConvertConstructorToDeductionGuideTransform {
27542754
// Find all template parameters that appear in the given DeducedArgs.
27552755
// Return the indices of the template parameters in the TemplateParams.
27562756
SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
2757-
ArrayRef<NamedDecl *> TemplateParams,
2757+
const TemplateParameterList* TemplateParamsList,
27582758
ArrayRef<TemplateArgument> DeducedArgs) {
27592759
struct TemplateParamsReferencedFinder
27602760
: public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
2761+
const TemplateParameterList* TemplateParamList;
27612762
llvm::DenseSet<NamedDecl *> TemplateParams;
27622763
llvm::DenseSet<const NamedDecl *> ReferencedTemplateParams;
27632764

2764-
TemplateParamsReferencedFinder(ArrayRef<NamedDecl *> TemplateParams)
2765-
: TemplateParams(TemplateParams.begin(), TemplateParams.end()) {}
2765+
TemplateParamsReferencedFinder(
2766+
const TemplateParameterList *TemplateParamList)
2767+
: TemplateParamList(TemplateParamList),
2768+
TemplateParams(TemplateParamList->begin(), TemplateParamList->end()) {
2769+
}
27662770

27672771
bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
2768-
MarkAppeared(TTP->getDecl());
2772+
// We use the index and depth to retrieve the corresponding template
2773+
// parameter from the parameter list.
2774+
// Note that Clang may not preserve type sugar during template argument
2775+
// deduction. In such cases, the TTP is a canonical TemplateTypeParamType,
2776+
// which only retains its index and depth information.
2777+
if (TTP->getDepth() == TemplateParamList->getDepth() &&
2778+
TTP->getIndex() < TemplateParamList->size()) {
2779+
ReferencedTemplateParams.insert(
2780+
TemplateParamList->getParam(TTP->getIndex()));
2781+
}
27692782
return true;
27702783
}
2784+
27712785
bool VisitDeclRefExpr(DeclRefExpr *DRE) {
27722786
MarkAppeared(DRE->getFoundDecl());
27732787
return true;
@@ -2784,12 +2798,13 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
27842798
ReferencedTemplateParams.insert(ND);
27852799
}
27862800
};
2787-
TemplateParamsReferencedFinder Finder(TemplateParams);
2801+
TemplateParamsReferencedFinder Finder(TemplateParamsList);
27882802
Finder.TraverseTemplateArguments(DeducedArgs);
27892803

27902804
SmallVector<unsigned> Results;
2791-
for (unsigned Index = 0; Index < TemplateParams.size(); ++Index) {
2792-
if (Finder.ReferencedTemplateParams.contains(TemplateParams[Index]))
2805+
for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
2806+
if (Finder.ReferencedTemplateParams.contains(
2807+
TemplateParamsList->getParam(Index)))
27932808
Results.push_back(Index);
27942809
}
27952810
return Results;
@@ -3149,7 +3164,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
31493164
}
31503165
auto DeducedAliasTemplateParams =
31513166
TemplateParamsReferencedInTemplateArgumentList(
3152-
AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
3167+
AliasTemplate->getTemplateParameters(), DeducedArgs);
31533168
// All template arguments null by default.
31543169
SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime(
31553170
F->getTemplateParameters()->size());

clang/test/AST/ast-dump-ctad-alias.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,28 @@ BFoo b2(1.0, 2.0);
9999
// CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'type-parameter-0-0'
100100
// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0'
101101
// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for BFoo> 'auto (double, double) -> Foo<double, double>' implicit_instantiation
102+
103+
namespace GH90209 {
104+
template <class Ts>
105+
struct List {
106+
List(int);
107+
};
108+
109+
template <class T1>
110+
struct TemplatedClass {
111+
TemplatedClass(T1);
112+
};
113+
114+
template <class T1>
115+
TemplatedClass(T1) -> TemplatedClass<List<T1>>;
116+
117+
template <class T2>
118+
using ATemplatedClass = TemplatedClass<List<T2>>;
119+
120+
ATemplatedClass test(1);
121+
// Verify that we have a correct template parameter list for the deduction guide.
122+
//
123+
// CHECK: FunctionTemplateDecl {{.*}} <deduction guide for ATemplatedClass>
124+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} class depth 0 index 0 T2
125+
// CHECK-NEXT: |-TypeTraitExpr {{.*}} 'bool' __is_deducible
126+
} // namespace GH90209

0 commit comments

Comments
 (0)