Skip to content

Commit 95c86a7

Browse files
committed
[Clang][AST] Store injected template arguments in TemplateParameterList
1 parent a18826d commit 95c86a7

File tree

5 files changed

+44
-103
lines changed

5 files changed

+44
-103
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
239239
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
240240
ASTContext&>
241241
DependentTemplateSpecializationTypes;
242-
llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
242+
mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
243243
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
244244
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
245245
mutable llvm::FoldingSet<DependentUnaryTransformType>
@@ -1778,13 +1778,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
17781778
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
17791779
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
17801780

1781-
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl);
1782-
1783-
/// Get a template argument list with one argument per template parameter
1784-
/// in a template parameter list, such as for the injected class name of
1785-
/// a class template.
1786-
void getInjectedTemplateArgs(const TemplateParameterList *Params,
1787-
SmallVectorImpl<TemplateArgument> &Args);
1781+
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const;
17881782

17891783
/// Form a pack expansion type with the given pattern.
17901784
/// \param NumExpansions The number of expansions for the pack, if known.
@@ -1795,7 +1789,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
17951789
/// if this is the canonical type of another pack expansion type.
17961790
QualType getPackExpansionType(QualType Pattern,
17971791
std::optional<unsigned> NumExpansions,
1798-
bool ExpectPackInType = true);
1792+
bool ExpectPackInType = true) const;
17991793

18001794
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
18011795
ObjCInterfaceDecl *PrevDecl = nullptr) const;

clang/include/clang/AST/DeclTemplate.h

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ NamedDecl *getAsNamedDecl(TemplateParameter P);
7171
class TemplateParameterList final
7272
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
7373
Expr *> {
74+
/// The template argument list of the template parameter list.
75+
llvm::PointerUnion<const ASTContext *, TemplateArgument *> InjectedArgs;
76+
7477
/// The location of the 'template' keyword.
7578
SourceLocation TemplateLoc;
7679

@@ -196,6 +199,9 @@ class TemplateParameterList final
196199

197200
bool hasAssociatedConstraints() const;
198201

202+
/// Get the template argument lisr of the template parameter list.
203+
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
204+
199205
SourceLocation getTemplateLoc() const { return TemplateLoc; }
200206
SourceLocation getLAngleLoc() const { return LAngleLoc; }
201207
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -793,15 +799,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
793799
/// The first value in the array is the number of specializations/partial
794800
/// specializations that follow.
795801
GlobalDeclID *LazySpecializations = nullptr;
796-
797-
/// The set of "injected" template arguments used within this
798-
/// template.
799-
///
800-
/// This pointer refers to the template arguments (there are as
801-
/// many template arguments as template parameters) for the
802-
/// template, and is allocated lazily, since most templates do not
803-
/// require the use of this information.
804-
TemplateArgument *InjectedArgs = nullptr;
805802
};
806803

807804
/// Pointer to the common data shared by all declarations of this
@@ -927,7 +924,9 @@ class RedeclarableTemplateDecl : public TemplateDecl,
927924
/// Although the C++ standard has no notion of the "injected" template
928925
/// arguments for a template, the notion is convenient when
929926
/// we need to perform substitutions inside the definition of a template.
930-
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
927+
ArrayRef<TemplateArgument> getInjectedTemplateArgs() const {
928+
return getTemplateParameters()->getInjectedTemplateArgs();
929+
}
931930

932931
using redecl_range = redeclarable_base::redecl_range;
933932
using redecl_iterator = redeclarable_base::redecl_iterator;
@@ -2087,10 +2086,6 @@ class ClassTemplatePartialSpecializationDecl
20872086
/// The list of template parameters
20882087
TemplateParameterList *TemplateParams = nullptr;
20892088

2090-
/// The set of "injected" template arguments used within this
2091-
/// partial specialization.
2092-
TemplateArgument *InjectedArgs = nullptr;
2093-
20942089
/// The class template partial specialization from which this
20952090
/// class template partial specialization was instantiated.
20962091
///
@@ -2136,9 +2131,10 @@ class ClassTemplatePartialSpecializationDecl
21362131
return TemplateParams;
21372132
}
21382133

2139-
/// Retrieve the template arguments list of the template parameter list
2140-
/// of this template.
2141-
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
2134+
/// Get the template argument lisr of the template parameter list.
2135+
ArrayRef<TemplateArgument> getInjectedTemplateArgs() const {
2136+
return getTemplateParameters()->getInjectedTemplateArgs();
2137+
}
21422138

21432139
/// \brief All associated constraints of this partial specialization,
21442140
/// including the requires clause and any constraints derived from
@@ -2864,10 +2860,6 @@ class VarTemplatePartialSpecializationDecl
28642860
/// The list of template parameters
28652861
TemplateParameterList *TemplateParams = nullptr;
28662862

2867-
/// The set of "injected" template arguments used within this
2868-
/// partial specialization.
2869-
TemplateArgument *InjectedArgs = nullptr;
2870-
28712863
/// The variable template partial specialization from which this
28722864
/// variable template partial specialization was instantiated.
28732865
///
@@ -2914,9 +2906,10 @@ class VarTemplatePartialSpecializationDecl
29142906
return TemplateParams;
29152907
}
29162908

2917-
/// Retrieve the template arguments list of the template parameter list
2918-
/// of this template.
2919-
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
2909+
/// Get the template argument lisr of the template parameter list.
2910+
ArrayRef<TemplateArgument> getInjectedTemplateArgs() const {
2911+
return getTemplateParameters()->getInjectedTemplateArgs();
2912+
}
29202913

29212914
/// \brief All associated constraints of this partial specialization,
29222915
/// including the requires clause and any constraints derived from

clang/lib/AST/ASTContext.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5622,7 +5622,7 @@ ASTContext::getDependentTemplateSpecializationType(
56225622
return QualType(T, 0);
56235623
}
56245624

5625-
TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
5625+
TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) const {
56265626
TemplateArgument Arg;
56275627
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
56285628
QualType ArgType = getTypeDeclType(TTP);
@@ -5666,23 +5666,15 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
56665666
}
56675667

56685668
if (Param->isTemplateParameterPack())
5669-
Arg = TemplateArgument::CreatePackCopy(*this, Arg);
5669+
Arg =
5670+
TemplateArgument::CreatePackCopy(const_cast<ASTContext &>(*this), Arg);
56705671

56715672
return Arg;
56725673
}
56735674

5674-
void
5675-
ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params,
5676-
SmallVectorImpl<TemplateArgument> &Args) {
5677-
Args.reserve(Args.size() + Params->size());
5678-
5679-
for (NamedDecl *Param : *Params)
5680-
Args.push_back(getInjectedTemplateArg(Param));
5681-
}
5682-
56835675
QualType ASTContext::getPackExpansionType(QualType Pattern,
56845676
std::optional<unsigned> NumExpansions,
5685-
bool ExpectPackInType) {
5677+
bool ExpectPackInType) const {
56865678
assert((!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) &&
56875679
"Pack expansions must expand one or more parameter packs");
56885680

clang/lib/AST/DeclTemplate.cpp

Lines changed: 17 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
5151
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
5252
}
5353

54-
TemplateParameterList::TemplateParameterList(const ASTContext& C,
54+
TemplateParameterList::TemplateParameterList(const ASTContext &C,
5555
SourceLocation TemplateLoc,
5656
SourceLocation LAngleLoc,
5757
ArrayRef<NamedDecl *> Params,
5858
SourceLocation RAngleLoc,
5959
Expr *RequiresClause)
60-
: TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
61-
NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
60+
: InjectedArgs(&C), TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc),
61+
RAngleLoc(RAngleLoc), NumParams(Params.size()),
62+
ContainsUnexpandedParameterPack(false),
6263
HasRequiresClause(RequiresClause != nullptr),
6364
HasConstrainedParameters(false) {
6465
for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
@@ -244,6 +245,17 @@ bool TemplateParameterList::hasAssociatedConstraints() const {
244245
return HasRequiresClause || HasConstrainedParameters;
245246
}
246247

248+
ArrayRef<TemplateArgument> TemplateParameterList::getInjectedTemplateArgs() {
249+
if (const auto *Context = InjectedArgs.dyn_cast<const ASTContext *>()) {
250+
TemplateArgument *Args = new (*Context) TemplateArgument[size()];
251+
llvm::transform(*this, Args, [&](NamedDecl *ND) {
252+
return Context->getInjectedTemplateArg(ND);
253+
});
254+
InjectedArgs = Args;
255+
}
256+
return {InjectedArgs.get<TemplateArgument *>(), NumParams};
257+
}
258+
247259
bool TemplateParameterList::shouldIncludeTypeForArgument(
248260
const PrintingPolicy &Policy, const TemplateParameterList *TPL,
249261
unsigned Idx) {
@@ -396,22 +408,6 @@ void RedeclarableTemplateDecl::addSpecializationImpl(
396408
SETraits::getDecl(Entry));
397409
}
398410

399-
ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
400-
TemplateParameterList *Params = getTemplateParameters();
401-
auto *CommonPtr = getCommonPtr();
402-
if (!CommonPtr->InjectedArgs) {
403-
auto &Context = getASTContext();
404-
SmallVector<TemplateArgument, 16> TemplateArgs;
405-
Context.getInjectedTemplateArgs(Params, TemplateArgs);
406-
CommonPtr->InjectedArgs =
407-
new (Context) TemplateArgument[TemplateArgs.size()];
408-
std::copy(TemplateArgs.begin(), TemplateArgs.end(),
409-
CommonPtr->InjectedArgs);
410-
}
411-
412-
return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
413-
}
414-
415411
//===----------------------------------------------------------------------===//
416412
// FunctionTemplateDecl Implementation
417413
//===----------------------------------------------------------------------===//
@@ -631,13 +627,10 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() {
631627
// expansion (14.5.3) whose pattern is the name of the template parameter
632628
// pack.
633629
ASTContext &Context = getASTContext();
634-
TemplateParameterList *Params = getTemplateParameters();
635-
SmallVector<TemplateArgument, 16> TemplateArgs;
636-
Context.getInjectedTemplateArgs(Params, TemplateArgs);
637630
TemplateName Name = Context.getQualifiedTemplateName(
638631
/*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
639-
CommonPtr->InjectedClassNameType =
640-
Context.getTemplateSpecializationType(Name, TemplateArgs);
632+
CommonPtr->InjectedClassNameType = Context.getTemplateSpecializationType(
633+
Name, getTemplateParameters()->getInjectedTemplateArgs());
641634
return CommonPtr->InjectedClassNameType;
642635
}
643636

@@ -1185,20 +1178,6 @@ SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
11851178
return Range;
11861179
}
11871180

1188-
ArrayRef<TemplateArgument>
1189-
ClassTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
1190-
TemplateParameterList *Params = getTemplateParameters();
1191-
auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1192-
if (!First->InjectedArgs) {
1193-
auto &Context = getASTContext();
1194-
SmallVector<TemplateArgument, 16> TemplateArgs;
1195-
Context.getInjectedTemplateArgs(Params, TemplateArgs);
1196-
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
1197-
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
1198-
}
1199-
return llvm::ArrayRef(First->InjectedArgs, Params->size());
1200-
}
1201-
12021181
//===----------------------------------------------------------------------===//
12031182
// FriendTemplateDecl Implementation
12041183
//===----------------------------------------------------------------------===//
@@ -1549,20 +1528,6 @@ SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
15491528
return Range;
15501529
}
15511530

1552-
ArrayRef<TemplateArgument>
1553-
VarTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
1554-
TemplateParameterList *Params = getTemplateParameters();
1555-
auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
1556-
if (!First->InjectedArgs) {
1557-
auto &Context = getASTContext();
1558-
SmallVector<TemplateArgument, 16> TemplateArgs;
1559-
Context.getInjectedTemplateArgs(Params, TemplateArgs);
1560-
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
1561-
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
1562-
}
1563-
return llvm::ArrayRef(First->InjectedArgs, Params->size());
1564-
}
1565-
15661531
static TemplateParameterList *
15671532
createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
15681533
// typename T

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6372,18 +6372,14 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
63726372
// - Each function template has a single function parameter whose type is
63736373
// a specialization of X with template arguments corresponding to the
63746374
// template parameters from the respective function template
6375-
SmallVector<TemplateArgument, 8> AArgs;
6376-
Context.getInjectedTemplateArgs(A, AArgs);
6375+
SmallVector<TemplateArgument, 8> AArgs(A->getInjectedTemplateArgs());
63776376

63786377
// Check P's arguments against A's parameter list. This will fill in default
63796378
// template arguments as needed. AArgs are already correct by construction.
63806379
// We can't just use CheckTemplateIdType because that will expand alias
63816380
// templates.
6382-
SmallVector<TemplateArgument, 4> PArgs;
6381+
SmallVector<TemplateArgument, 4> PArgs(P->getInjectedTemplateArgs());
63836382
{
6384-
SFINAETrap Trap(*this);
6385-
6386-
Context.getInjectedTemplateArgs(P, PArgs);
63876383
TemplateArgumentListInfo PArgList(P->getLAngleLoc(),
63886384
P->getRAngleLoc());
63896385
for (unsigned I = 0, N = P->size(); I != N; ++I) {
@@ -6399,6 +6395,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
63996395
}
64006396
PArgs.clear();
64016397

6398+
SFINAETrap Trap(*this);
64026399
// C++1z [temp.arg.template]p3:
64036400
// If the rewrite produces an invalid type, then P is not at least as
64046401
// specialized as A.

0 commit comments

Comments
 (0)