[clang] [clang] CTAD: use index and depth to retrieve template parameter for TemplateParamsReferencedInTemplateArgumentList (PR #98013)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 11 02:41:26 PDT 2024
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/98013
>From c9297f8abe8d480fdcd3ba6d6598268fef74ddb4 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 8 Jul 2024 13:19:13 +0200
Subject: [PATCH 1/3] [clang] CTAD: use index and depth to retrieve template
parameters in TemplateParamsReferencedInTemplateArgumentList.
---
clang/lib/Sema/SemaTemplate.cpp | 31 +++++++++++++++++++-------
clang/test/AST/ast-dump-ctad-alias.cpp | 25 +++++++++++++++++++++
2 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3d8cf750c12c1..196a5cc10ce40 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2754,20 +2754,34 @@ struct ConvertConstructorToDeductionGuideTransform {
// Find all template parameters that appear in the given DeducedArgs.
// Return the indices of the template parameters in the TemplateParams.
SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
- ArrayRef<NamedDecl *> TemplateParams,
+ const TemplateParameterList* TemplateParamsList,
ArrayRef<TemplateArgument> DeducedArgs) {
struct TemplateParamsReferencedFinder
: public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
+ const TemplateParameterList* TemplateParamList;
llvm::DenseSet<NamedDecl *> TemplateParams;
llvm::DenseSet<const NamedDecl *> ReferencedTemplateParams;
- TemplateParamsReferencedFinder(ArrayRef<NamedDecl *> TemplateParams)
- : TemplateParams(TemplateParams.begin(), TemplateParams.end()) {}
+ TemplateParamsReferencedFinder(
+ const TemplateParameterList *TemplateParamList)
+ : TemplateParamList(TemplateParamList),
+ TemplateParams(TemplateParamList->begin(), TemplateParamList->end()) {
+ }
bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
- MarkAppeared(TTP->getDecl());
+ // We use the index and depth to retrieve the corresponding template
+ // parameter from the parameter list.
+ // Note that Clang may not preserve type sugar during template argument
+ // deduction. In such cases, the TTP is a canonical TemplateTypeParamType,
+ // which only retains its index and depth information.
+ if (TTP->getDepth() == TemplateParamList->getDepth() &&
+ TTP->getIndex() < TemplateParamList->size()) {
+ ReferencedTemplateParams.insert(
+ TemplateParamList->getParam(TTP->getIndex()));
+ }
return true;
}
+
bool VisitDeclRefExpr(DeclRefExpr *DRE) {
MarkAppeared(DRE->getFoundDecl());
return true;
@@ -2784,12 +2798,13 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
ReferencedTemplateParams.insert(ND);
}
};
- TemplateParamsReferencedFinder Finder(TemplateParams);
+ TemplateParamsReferencedFinder Finder(TemplateParamsList);
Finder.TraverseTemplateArguments(DeducedArgs);
SmallVector<unsigned> Results;
- for (unsigned Index = 0; Index < TemplateParams.size(); ++Index) {
- if (Finder.ReferencedTemplateParams.contains(TemplateParams[Index]))
+ for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
+ if (Finder.ReferencedTemplateParams.contains(
+ TemplateParamsList->getParam(Index)))
Results.push_back(Index);
}
return Results;
@@ -3149,7 +3164,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
}
auto DeducedAliasTemplateParams =
TemplateParamsReferencedInTemplateArgumentList(
- AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+ AliasTemplate->getTemplateParameters(), DeducedArgs);
// All template arguments null by default.
SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime(
F->getTemplateParameters()->size());
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp b/clang/test/AST/ast-dump-ctad-alias.cpp
index 6f07a62e9a069..adccad97a205b 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -99,3 +99,28 @@ BFoo b2(1.0, 2.0);
// CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'type-parameter-0-0'
// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0'
// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for BFoo> 'auto (double, double) -> Foo<double, double>' implicit_instantiation
+
+namespace GH90209 {
+template <class Ts>
+struct List {
+ List(int);
+};
+
+template <class T1>
+struct TemplatedClass {
+ TemplatedClass(T1);
+};
+
+template <class T1>
+TemplatedClass(T1) -> TemplatedClass<List<T1>>;
+
+template <class T2>
+using ATemplatedClass = TemplatedClass<List<T2>>;
+
+ATemplatedClass test(1);
+// Verify that we have a correct template parameter list for the deduction guide.
+//
+// CHECK: FunctionTemplateDecl {{.*}} <deduction guide for ATemplatedClass>
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} class depth 0 index 0 T2
+// CHECK-NEXT: |-TypeTraitExpr {{.*}} 'bool' __is_deducible
+} // namespace GH90209
\ No newline at end of file
>From 7626982d97d7f0f088af95be371f65d5a0f02ee9 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 11 Jul 2024 11:09:55 +0200
Subject: [PATCH 2/3] Address review comment.
---
clang/lib/Sema/SemaTemplate.cpp | 61 ++++++++++++++++++---------------
1 file changed, 34 insertions(+), 27 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 196a5cc10ce40..58082cd111a9a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -37,6 +37,7 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -2751,6 +2752,26 @@ struct ConvertConstructorToDeductionGuideTransform {
}
};
+unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
+ if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
+ return TTP->getDepth();
+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
+ return TTP->getDepth();
+ if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
+ return NTTP->getDepth();
+ llvm_unreachable("Unhandled template parameter types");
+}
+
+unsigned getTemplateParameterIndex(NamedDecl *TemplateParam) {
+ if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
+ return TTP->getIndex();
+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
+ return TTP->getIndex();
+ if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
+ return NTTP->getIndex();
+ llvm_unreachable("Unhandled template parameter types");
+}
+
// Find all template parameters that appear in the given DeducedArgs.
// Return the indices of the template parameters in the TemplateParams.
SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
@@ -2759,26 +2780,17 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
struct TemplateParamsReferencedFinder
: public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
const TemplateParameterList* TemplateParamList;
- llvm::DenseSet<NamedDecl *> TemplateParams;
- llvm::DenseSet<const NamedDecl *> ReferencedTemplateParams;
+ llvm::BitVector ReferencedTemplateParams;
TemplateParamsReferencedFinder(
const TemplateParameterList *TemplateParamList)
: TemplateParamList(TemplateParamList),
- TemplateParams(TemplateParamList->begin(), TemplateParamList->end()) {
- }
+ ReferencedTemplateParams(TemplateParamList->size()) {}
bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
// We use the index and depth to retrieve the corresponding template
- // parameter from the parameter list.
- // Note that Clang may not preserve type sugar during template argument
- // deduction. In such cases, the TTP is a canonical TemplateTypeParamType,
- // which only retains its index and depth information.
- if (TTP->getDepth() == TemplateParamList->getDepth() &&
- TTP->getIndex() < TemplateParamList->size()) {
- ReferencedTemplateParams.insert(
- TemplateParamList->getParam(TTP->getIndex()));
- }
+ // parameter from the parameter list, which is more robost.
+ Mark(TTP->getDepth(), TTP->getIndex());
return true;
}
@@ -2794,8 +2806,14 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
}
void MarkAppeared(NamedDecl *ND) {
- if (TemplateParams.contains(ND))
- ReferencedTemplateParams.insert(ND);
+ if (llvm::isa<NonTypeTemplateParmDecl, TemplateTypeParmDecl,
+ TemplateTemplateParmDecl>(ND))
+ Mark(getTemplateParameterDepth(ND), getTemplateParameterIndex(ND));
+ }
+ void Mark(unsigned Depth, unsigned Index) {
+ if (Index < TemplateParamList->size() &&
+ TemplateParamList->getParam(Index)->getTemplateDepth() == Depth)
+ ReferencedTemplateParams.set(Index);
}
};
TemplateParamsReferencedFinder Finder(TemplateParamsList);
@@ -2803,8 +2821,7 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
SmallVector<unsigned> Results;
for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
- if (Finder.ReferencedTemplateParams.contains(
- TemplateParamsList->getParam(Index)))
+ if (Finder.ReferencedTemplateParams[Index])
Results.push_back(Index);
}
return Results;
@@ -2823,16 +2840,6 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
return false;
}
-unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
- return TTP->getDepth();
- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
- return TTP->getDepth();
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
- return NTTP->getDepth();
- llvm_unreachable("Unhandled template parameter types");
-}
-
NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
NamedDecl *TemplateParam,
MultiLevelTemplateArgumentList &Args,
>From 71b589bb019c27f4855278d035f602d77738f028 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 11 Jul 2024 11:41:05 +0200
Subject: [PATCH 3/3] clang-format
---
clang/lib/Sema/SemaTemplate.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 58082cd111a9a..6d52ca23940dc 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2779,7 +2779,7 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
ArrayRef<TemplateArgument> DeducedArgs) {
struct TemplateParamsReferencedFinder
: public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
- const TemplateParameterList* TemplateParamList;
+ const TemplateParameterList *TemplateParamList;
llvm::BitVector ReferencedTemplateParams;
TemplateParamsReferencedFinder(
More information about the cfe-commits
mailing list