Skip to content

Commit 582e5be

Browse files
committed
[Clang] Unify interface for accessing template arguments as written for class/variable template specializations
1 parent 502a88b commit 582e5be

21 files changed

+361
-442
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 78 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,23 +1792,24 @@ class ClassTemplateSpecializationDecl
17921792
llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
17931793
SpecializedTemplate;
17941794

1795-
/// Further info for explicit template specialization/instantiation.
1796-
struct ExplicitSpecializationInfo {
1797-
/// The type-as-written.
1798-
TypeSourceInfo *TypeAsWritten = nullptr;
1795+
struct ExplicitInstantiationInfo {
1796+
/// The template arguments as written..
1797+
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr;
17991798

18001799
/// The location of the extern keyword.
18011800
SourceLocation ExternLoc;
18021801

18031802
/// The location of the template keyword.
18041803
SourceLocation TemplateKeywordLoc;
18051804

1806-
ExplicitSpecializationInfo() = default;
1805+
ExplicitInstantiationInfo() = default;
18071806
};
18081807

18091808
/// Further info for explicit template specialization/instantiation.
18101809
/// Does not apply to implicit specializations.
1811-
ExplicitSpecializationInfo *ExplicitInfo = nullptr;
1810+
llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1811+
ExplicitInstantiationInfo *>
1812+
ExplicitInfo = nullptr;
18121813

18131814
/// The template arguments used to describe this specialization.
18141815
const TemplateArgumentList *TemplateArgs;
@@ -1985,44 +1986,45 @@ class ClassTemplateSpecializationDecl
19851986
SpecializedTemplate = TemplDecl;
19861987
}
19871988

1988-
/// Sets the type of this specialization as it was written by
1989-
/// the user. This will be a class template specialization type.
1990-
void setTypeAsWritten(TypeSourceInfo *T) {
1991-
if (!ExplicitInfo)
1992-
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1993-
ExplicitInfo->TypeAsWritten = T;
1994-
}
1995-
1996-
/// Gets the type of this specialization as it was written by
1997-
/// the user, if it was so written.
1998-
TypeSourceInfo *getTypeAsWritten() const {
1999-
return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
1989+
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
1990+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
1991+
return Info->TemplateArgsAsWritten;
1992+
return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
20001993
}
20011994

20021995
/// Gets the location of the extern keyword, if present.
20031996
SourceLocation getExternLoc() const {
2004-
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1997+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
1998+
return Info->ExternLoc;
1999+
return SourceLocation();
20052000
}
20062001

2007-
/// Sets the location of the extern keyword.
2008-
void setExternLoc(SourceLocation Loc) {
2009-
if (!ExplicitInfo)
2010-
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2011-
ExplicitInfo->ExternLoc = Loc;
2002+
/// Gets the location of the template keyword, if present.
2003+
SourceLocation getTemplateKeywordLoc() const {
2004+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2005+
return Info->TemplateKeywordLoc;
2006+
return SourceLocation();
20122007
}
20132008

2014-
/// Sets the location of the template keyword.
2015-
void setTemplateKeywordLoc(SourceLocation Loc) {
2016-
if (!ExplicitInfo)
2017-
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2018-
ExplicitInfo->TemplateKeywordLoc = Loc;
2009+
void
2010+
setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
2011+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2012+
Info->TemplateArgsAsWritten = ArgsWritten;
2013+
else
2014+
ExplicitInfo = ArgsWritten;
20192015
}
20202016

2021-
/// Gets the location of the template keyword, if present.
2022-
SourceLocation getTemplateKeywordLoc() const {
2023-
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2017+
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
2018+
setTemplateArgsAsWritten(
2019+
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo));
20242020
}
20252021

2022+
/// Sets the location of the extern keyword.
2023+
void setExternLoc(SourceLocation Loc);
2024+
2025+
/// Sets the location of the template keyword.
2026+
void setTemplateKeywordLoc(SourceLocation Loc);
2027+
20262028
SourceRange getSourceRange() const override LLVM_READONLY;
20272029

20282030
void Profile(llvm::FoldingSetNodeID &ID) const {
@@ -2050,10 +2052,6 @@ class ClassTemplatePartialSpecializationDecl
20502052
/// The list of template parameters
20512053
TemplateParameterList* TemplateParams = nullptr;
20522054

2053-
/// The source info for the template arguments as written.
2054-
/// FIXME: redundant with TypeAsWritten?
2055-
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2056-
20572055
/// The class template partial specialization from which this
20582056
/// class template partial specialization was instantiated.
20592057
///
@@ -2062,15 +2060,11 @@ class ClassTemplatePartialSpecializationDecl
20622060
llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
20632061
InstantiatedFromMember;
20642062

2065-
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
2066-
DeclContext *DC,
2067-
SourceLocation StartLoc,
2068-
SourceLocation IdLoc,
2069-
TemplateParameterList *Params,
2070-
ClassTemplateDecl *SpecializedTemplate,
2071-
ArrayRef<TemplateArgument> Args,
2072-
const ASTTemplateArgumentListInfo *ArgsAsWritten,
2073-
ClassTemplatePartialSpecializationDecl *PrevDecl);
2063+
ClassTemplatePartialSpecializationDecl(
2064+
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2065+
SourceLocation IdLoc, TemplateParameterList *Params,
2066+
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2067+
ClassTemplatePartialSpecializationDecl *PrevDecl);
20742068

20752069
ClassTemplatePartialSpecializationDecl(ASTContext &C)
20762070
: ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
@@ -2085,11 +2079,8 @@ class ClassTemplatePartialSpecializationDecl
20852079
static ClassTemplatePartialSpecializationDecl *
20862080
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
20872081
SourceLocation StartLoc, SourceLocation IdLoc,
2088-
TemplateParameterList *Params,
2089-
ClassTemplateDecl *SpecializedTemplate,
2090-
ArrayRef<TemplateArgument> Args,
2091-
const TemplateArgumentListInfo &ArgInfos,
2092-
QualType CanonInjectedType,
2082+
TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2083+
ArrayRef<TemplateArgument> Args, QualType CanonInjectedType,
20932084
ClassTemplatePartialSpecializationDecl *PrevDecl);
20942085

20952086
static ClassTemplatePartialSpecializationDecl *
@@ -2120,11 +2111,6 @@ class ClassTemplatePartialSpecializationDecl
21202111
return TemplateParams->hasAssociatedConstraints();
21212112
}
21222113

2123-
/// Get the template arguments as written.
2124-
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2125-
return ArgsAsWritten;
2126-
}
2127-
21282114
/// Retrieve the member class template partial specialization from
21292115
/// which this particular class template partial specialization was
21302116
/// instantiated.
@@ -2596,23 +2582,24 @@ class VarTemplateSpecializationDecl : public VarDecl,
25962582
llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
25972583
SpecializedTemplate;
25982584

2599-
/// Further info for explicit template specialization/instantiation.
2600-
struct ExplicitSpecializationInfo {
2601-
/// The type-as-written.
2602-
TypeSourceInfo *TypeAsWritten = nullptr;
2585+
struct ExplicitInstantiationInfo {
2586+
/// The template arguments as written..
2587+
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr;
26032588

26042589
/// The location of the extern keyword.
26052590
SourceLocation ExternLoc;
26062591

26072592
/// The location of the template keyword.
26082593
SourceLocation TemplateKeywordLoc;
26092594

2610-
ExplicitSpecializationInfo() = default;
2595+
ExplicitInstantiationInfo() = default;
26112596
};
26122597

26132598
/// Further info for explicit template specialization/instantiation.
26142599
/// Does not apply to implicit specializations.
2615-
ExplicitSpecializationInfo *ExplicitInfo = nullptr;
2600+
llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
2601+
ExplicitInstantiationInfo *>
2602+
ExplicitInfo = nullptr;
26162603

26172604
/// The template arguments used to describe this specialization.
26182605
const TemplateArgumentList *TemplateArgs;
@@ -2670,14 +2657,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
26702657
/// specialization.
26712658
const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
26722659

2673-
// TODO: Always set this when creating the new specialization?
2674-
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2675-
void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo);
2676-
2677-
const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const {
2678-
return TemplateArgsInfo;
2679-
}
2680-
26812660
/// Determine the kind of specialization that this
26822661
/// declaration represents.
26832662
TemplateSpecializationKind getSpecializationKind() const {
@@ -2781,44 +2760,45 @@ class VarTemplateSpecializationDecl : public VarDecl,
27812760
SpecializedTemplate = TemplDecl;
27822761
}
27832762

2784-
/// Sets the type of this specialization as it was written by
2785-
/// the user.
2786-
void setTypeAsWritten(TypeSourceInfo *T) {
2787-
if (!ExplicitInfo)
2788-
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2789-
ExplicitInfo->TypeAsWritten = T;
2790-
}
2791-
2792-
/// Gets the type of this specialization as it was written by
2793-
/// the user, if it was so written.
2794-
TypeSourceInfo *getTypeAsWritten() const {
2795-
return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2763+
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2764+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2765+
return Info->TemplateArgsAsWritten;
2766+
return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
27962767
}
27972768

27982769
/// Gets the location of the extern keyword, if present.
27992770
SourceLocation getExternLoc() const {
2800-
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2771+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2772+
return Info->ExternLoc;
2773+
return SourceLocation();
28012774
}
28022775

2803-
/// Sets the location of the extern keyword.
2804-
void setExternLoc(SourceLocation Loc) {
2805-
if (!ExplicitInfo)
2806-
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2807-
ExplicitInfo->ExternLoc = Loc;
2776+
/// Gets the location of the template keyword, if present.
2777+
SourceLocation getTemplateKeywordLoc() const {
2778+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2779+
return Info->TemplateKeywordLoc;
2780+
return SourceLocation();
28082781
}
28092782

2810-
/// Sets the location of the template keyword.
2811-
void setTemplateKeywordLoc(SourceLocation Loc) {
2812-
if (!ExplicitInfo)
2813-
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2814-
ExplicitInfo->TemplateKeywordLoc = Loc;
2783+
void
2784+
setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
2785+
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
2786+
Info->TemplateArgsAsWritten = ArgsWritten;
2787+
else
2788+
ExplicitInfo = ArgsWritten;
28152789
}
28162790

2817-
/// Gets the location of the template keyword, if present.
2818-
SourceLocation getTemplateKeywordLoc() const {
2819-
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2791+
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
2792+
setTemplateArgsAsWritten(
2793+
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo));
28202794
}
28212795

2796+
/// Sets the location of the extern keyword.
2797+
void setExternLoc(SourceLocation Loc);
2798+
2799+
/// Sets the location of the template keyword.
2800+
void setTemplateKeywordLoc(SourceLocation Loc);
2801+
28222802
SourceRange getSourceRange() const override LLVM_READONLY;
28232803

28242804
void Profile(llvm::FoldingSetNodeID &ID) const {
@@ -2846,10 +2826,6 @@ class VarTemplatePartialSpecializationDecl
28462826
/// The list of template parameters
28472827
TemplateParameterList *TemplateParams = nullptr;
28482828

2849-
/// The source info for the template arguments as written.
2850-
/// FIXME: redundant with TypeAsWritten?
2851-
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2852-
28532829
/// The variable template partial specialization from which this
28542830
/// variable template partial specialization was instantiated.
28552831
///
@@ -2862,8 +2838,7 @@ class VarTemplatePartialSpecializationDecl
28622838
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
28632839
SourceLocation IdLoc, TemplateParameterList *Params,
28642840
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2865-
StorageClass S, ArrayRef<TemplateArgument> Args,
2866-
const ASTTemplateArgumentListInfo *ArgInfos);
2841+
StorageClass S, ArrayRef<TemplateArgument> Args);
28672842

28682843
VarTemplatePartialSpecializationDecl(ASTContext &Context)
28692844
: VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
@@ -2880,8 +2855,8 @@ class VarTemplatePartialSpecializationDecl
28802855
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
28812856
SourceLocation IdLoc, TemplateParameterList *Params,
28822857
VarTemplateDecl *SpecializedTemplate, QualType T,
2883-
TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args,
2884-
const TemplateArgumentListInfo &ArgInfos);
2858+
TypeSourceInfo *TInfo, StorageClass S,
2859+
ArrayRef<TemplateArgument> Args);
28852860

28862861
static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
28872862
unsigned ID);
@@ -2897,11 +2872,6 @@ class VarTemplatePartialSpecializationDecl
28972872
return TemplateParams;
28982873
}
28992874

2900-
/// Get the template arguments as written.
2901-
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2902-
return ArgsAsWritten;
2903-
}
2904-
29052875
/// \brief All associated constraints of this partial specialization,
29062876
/// including the requires clause and any constraints derived from
29072877
/// constrained-parameters.

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,15 @@ DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
20092009

20102010
DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
20112011

2012+
template <typename Derived>
2013+
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2014+
const TemplateArgumentLoc *TAL, unsigned Count) {
2015+
for (unsigned I = 0; I < Count; ++I) {
2016+
TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2017+
}
2018+
return true;
2019+
}
2020+
20122021
#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
20132022
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
20142023
/* For implicit instantiations ("set<int> x;"), we don't want to \
@@ -2018,9 +2027,12 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
20182027
TemplateSpecializationType). For explicit instantiations \
20192028
("template set<int>;"), we do need a callback, since this \
20202029
is the only callback that's made for this instantiation. \
2021-
We use getTypeAsWritten() to distinguish. */ \
2022-
if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
2023-
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
2030+
We use getTemplateArgsAsWritten() to distinguish. */ \
2031+
if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2032+
/* The args that remains unspecialized. */ \
2033+
TRY_TO(TraverseTemplateArgumentLocsHelper( \
2034+
ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2035+
} \
20242036
\
20252037
if (getDerived().shouldVisitTemplateInstantiations() || \
20262038
D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
@@ -2040,15 +2052,6 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
20402052
DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
20412053
DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var)
20422054

2043-
template <typename Derived>
2044-
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2045-
const TemplateArgumentLoc *TAL, unsigned Count) {
2046-
for (unsigned I = 0; I < Count; ++I) {
2047-
TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2048-
}
2049-
return true;
2050-
}
2051-
20522055
#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
20532056
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
20542057
/* The partial specialization. */ \

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4066,7 +4066,7 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
40664066
/// Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
40674067
/// Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>,
40684068
/// Matcher<CXXUnresolvedConstructExpr>,
4069-
/// Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>,
4069+
/// Matcher<CompoundLiteralExpr>,
40704070
/// Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>,
40714071
/// Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>,
40724072
/// Matcher<TypedefNameDecl>
@@ -4075,9 +4075,8 @@ AST_POLYMORPHIC_MATCHER_P(
40754075
AST_POLYMORPHIC_SUPPORTED_TYPES(
40764076
BlockDecl, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr,
40774077
CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,
4078-
ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl,
4079-
ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc,
4080-
TypedefNameDecl),
4078+
CompoundLiteralExpr, DeclaratorDecl, ExplicitCastExpr, ObjCPropertyDecl,
4079+
TemplateArgumentLoc, TypedefNameDecl),
40814080
internal::Matcher<TypeLoc>, Inner) {
40824081
TypeSourceInfo *source = internal::GetTypeSourceInfo(Node);
40834082
if (source == nullptr) {

0 commit comments

Comments
 (0)