29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/Support/ErrorHandling.h"
45template <
class TemplateParam>
48 return P.hasDefaultArgument() &&
49 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
58 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
59 NumParams(Params.size()), ContainsUnexpandedParameterPack(
false),
60 HasRequiresClause(RequiresClause !=
nullptr),
61 HasConstrainedParameters(
false) {
62 for (
unsigned Idx = 0; Idx < NumParams; ++Idx) {
67 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
68 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
70 ContainsUnexpandedParameterPack =
true;
71 if (NTTP->hasPlaceholderTypeConstraint())
72 HasConstrainedParameters =
true;
73 }
else if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
75 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
77 ContainsUnexpandedParameterPack =
true;
79 }
else if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
81 ContainsUnexpandedParameterPack =
true;
85 ContainsUnexpandedParameterPack =
true;
87 if (TTP->hasTypeConstraint())
88 HasConstrainedParameters =
true;
90 llvm_unreachable(
"unexpected template parameter type");
94 if (HasRequiresClause) {
96 ContainsUnexpandedParameterPack =
true;
97 *getTrailingObjects<Expr *>() = RequiresClause;
102 if (ContainsUnexpandedParameterPack)
104 if (!HasConstrainedParameters)
110 for (
const NamedDecl *Param : llvm::reverse(
asArray())) {
111 if (!Param->isImplicit())
114 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
115 const auto *TC = TTP->getTypeConstraint();
116 if (TC && TC->getImmediatelyDeclaredConstraint()
117 ->containsUnexpandedParameterPack())
130 void *Mem =
C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
131 Params.size(), RequiresClause ? 1u : 0u),
134 RAngleLoc, RequiresClause);
140 ID.AddBoolean(RC !=
nullptr);
144 for (NamedDecl *D : *
this) {
145 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
147 ID.AddBoolean(NTTP->isParameterPack());
148 NTTP->getType().getCanonicalType().Profile(ID);
149 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
150 if (
const Expr *E = NTTP->getPlaceholderTypeConstraint())
151 E->Profile(ID,
C,
true);
154 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
156 ID.AddBoolean(TTP->isParameterPack());
157 ID.AddBoolean(TTP->hasTypeConstraint());
158 if (
const TypeConstraint *TC = TTP->getTypeConstraint())
159 TC->getImmediatelyDeclaredConstraint()->Profile(ID,
C,
165 ID.AddInteger(TTP->templateParameterKind());
166 ID.AddBoolean(TTP->isParameterPack());
167 TTP->getTemplateParameters()->Profile(ID,
C);
172 unsigned NumRequiredArgs = 0;
173 for (
const NamedDecl *P :
asArray()) {
176 NumRequiredArgs += *Expansions;
182 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
183 if (TTP->hasDefaultArgument())
185 }
else if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
186 if (NTTP->hasDefaultArgument())
188 }
else if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P);
189 TTP && TTP->hasDefaultArgument())
195 return NumRequiredArgs;
202 const NamedDecl *FirstParm =
getParam(0);
203 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
204 return TTP->getDepth();
205 else if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
206 return NTTP->getDepth();
217 if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
229 if (HasConstrainedParameters)
230 for (
const NamedDecl *Param : *
this) {
231 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
232 if (
const auto *TC = TTP->getTypeConstraint())
233 ACs.emplace_back(TC->getImmediatelyDeclaredConstraint(),
234 TC->getArgPackSubstIndex());
235 }
else if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
236 if (
const Expr *E = NTTP->getPlaceholderTypeConstraint())
240 if (HasRequiresClause)
245 return HasRequiresClause || HasConstrainedParameters;
251 InjectedArgs =
new (Context) TemplateArgument[
size()];
252 llvm::transform(*
this, InjectedArgs, [&](NamedDecl *ND) {
256 return {InjectedArgs, NumParams};
264 const NamedDecl *TemplParam = TPL->
getParam(Idx);
265 if (
const auto *ParamValueDecl =
266 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
267 if (ParamValueDecl->getType()->getContainedDeducedType())
275 return new (
C)
char[
sizeof(
void*) * 2];
289void TemplateDecl::anchor() {}
296 ACs.emplace_back(TRC);
303 return static_cast<bool>(FD->getTrailingRequiresClause());
309 case TemplateDecl::TypeAliasTemplate:
311 case TemplateDecl::BuiltinTemplate:
322void RedeclarableTemplateDecl::anchor() {}
338 PrevDecls.push_back(Prev);
376template <
class EntryType,
typename... ProfileArguments>
379 llvm::FoldingSetVector<EntryType> &Specs,
380 llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs) {
383 llvm::FoldingSetNodeID ID;
385 EntryType *Entry = Specs.lookup(ID, InsertToken);
386 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() :
nullptr;
389template <
class EntryType,
typename... ProfileArguments>
392 llvm::FoldingSetVector<EntryType> &Specs,
393 llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs) {
405template <
class Derived,
class EntryType>
407 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
408 llvm::FoldingSetInsertToken InsertToken) {
413 auto Args = SETraits::getTemplateArgs(Entry);
419 llvm::FoldingSetInsertToken CorrectToken;
421 InsertToken == CorrectToken &&
422 "given incorrect InsertToken for specialization");
424 Specializations.insert(Entry, InsertToken);
426 EntryType *Existing = Specializations.getOrInsert(Entry);
429 "non-canonical specialization?");
434 SETraits::getDecl(Entry));
445 assert(!Params->
empty() &&
"template with no template parameters");
449 TD->setInvalidDecl();
461 auto *CommonPtr =
new (
C)
Common;
462 C.addDestruction(CommonPtr);
470llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
484 llvm::FoldingSetInsertToken InsertToken) {
498 Common *ThisCommon =
static_cast<Common *
>(Base::Common);
499 Common *PrevCommon =
nullptr;
502 if (Prev->Base::Common) {
503 PrevCommon =
static_cast<Common *
>(Prev->Base::Common);
506 PreviousDecls.push_back(Prev);
512 for (
auto *D : PreviousDecls)
513 D->Base::Common = ThisCommon;
519 "Can't merge incompatible declarations!");
521 Base::Common = PrevCommon;
533 assert(!Params->
empty() &&
"template with no template parameters");
537 TD->setInvalidDecl();
552llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
558llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
566 auto *CommonPtr =
new (
C)
Common;
567 C.addDestruction(CommonPtr);
579 llvm::FoldingSetInsertToken InsertToken) {
588 llvm::FoldingSetInsertToken &InsertToken) {
596 ID.AddInteger(TemplateArgs.size());
604 llvm::FoldingSetInsertToken InsertToken) {
611 assert(Existing->
isCanonicalDecl() &&
"Non-canonical specialization?");
615 L->AddedCXXTemplateSpecialization(
this, D);
620 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
623 PS.reserve(PartialSpecs.size());
633 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
677 bool ParameterPack,
bool HasTypeConstraint,
UnsignedOrNone NumExpanded) {
680 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
681 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
682 HasTypeConstraint, NumExpanded);
683 QualType TTPType =
C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
684 TTPDecl->setTypeForDecl(TTPType.
getTypePtr());
692 false,
false, std::nullopt);
697 bool HasTypeConstraint) {
699 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
701 false, HasTypeConstraint, std::nullopt);
724 DefaultArgument.set(
nullptr);
730 return dyn_cast<TemplateTypeParmType>(
getTypeForDecl())->getDepth();
734 return dyn_cast<TemplateTypeParmType>(
getTypeForDecl())->getIndex();
738 return dyn_cast<TemplateTypeParmType>(
getTypeForDecl())->isParameterPack();
744 assert(HasTypeConstraint &&
745 "HasTypeConstraint=true must be passed at construction in order to "
746 "call setTypeConstraint");
747 assert(!TypeConstraintInitialized &&
748 "TypeConstraint was already initialized!");
749 new (getTrailingObjects())
750 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
751 TypeConstraintInitialized =
true;
758NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
762 :
DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id,
T, TInfo, StartLoc),
764 ExpandedParameterPack(
true), NumExpandedTypes(ExpandedTypes.size()) {
765 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
767 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
768 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
769 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
770 TypesAndInfos[I].second = ExpandedTInfos[I];
780 C.getLangOpts().CPlusPlus20 ?
T->getContainedAutoType() :
nullptr;
781 const bool HasConstraint = AT && AT->isConstrained();
784 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
Expr *>(
785 0, HasConstraint ? 1 : 0))
786 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
T,
787 ParameterPack, TInfo);
789 NTTP->setPlaceholderTypeConstraint(
nullptr);
799 const bool HasConstraint = AT && AT->isConstrained();
802 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
Expr *>(
803 ExpandedTypes.size(), HasConstraint ? 1 : 0))
804 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
T, TInfo,
805 ExpandedTypes, ExpandedTInfos);
807 NTTP->setPlaceholderTypeConstraint(
nullptr);
813 bool HasTypeConstraint) {
816 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
Expr *>(
817 0, HasTypeConstraint ? 1 : 0))
819 0, 0,
nullptr,
QualType(),
false,
nullptr);
820 if (HasTypeConstraint)
827 unsigned NumExpandedTypes,
828 bool HasTypeConstraint) {
831 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
Expr *>(
832 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
834 0, 0,
nullptr,
QualType(),
nullptr, {}, {});
835 NTTP->NumExpandedTypes = NumExpandedTypes;
836 if (HasTypeConstraint)
837 NTTP->setPlaceholderTypeConstraint(
nullptr);
856 DefaultArgument.set(
nullptr);
865void TemplateTemplateParmDecl::anchor() {}
867TemplateTemplateParmDecl::TemplateTemplateParmDecl(
871 :
TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
873 ParameterPack(
true), ExpandedParameterPack(
true),
874 NumExpandedParams(Expansions.size()) {
875 llvm::uninitialized_copy(Expansions, getTrailingObjects());
882 assert(!Params->
empty() &&
"template with no template parameters");
883 return new (
C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
884 Kind, Typename, Params);
893 assert(!Params->
empty() &&
"template with no template parameters");
895 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
896 TemplateTemplateParmDecl(DC, L, D, P, Id,
Kind, Typename, Params,
902 return new (
C, ID) TemplateTemplateParmDecl(
909 unsigned NumExpansions) {
911 new (
C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
912 TemplateTemplateParmDecl(
nullptr,
SourceLocation(), 0, 0,
nullptr,
915 TTP->NumExpandedParams = NumExpansions;
927 DefaultArgument.set(
nullptr);
936 : NumArguments(Args.size()) {
937 llvm::uninitialized_copy(Args, getTrailingObjects());
943 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
944 return new (Mem) TemplateArgumentList(Args);
953 if (TemplateArgsAsWritten)
955 *TemplateArgsAsWritten);
958 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
959 return new (Mem) FunctionTemplateSpecializationInfo(
960 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
974 SpecializedTemplate(SpecializedTemplate),
976 SpecializationKind(
TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
977 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch ==
false);
992 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
993 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
1009 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(
this);
1011 PS ? PS->getTemplateArgsAsWritten() :
nullptr) {
1012 printTemplateArgumentList(
1013 OS, ArgsAsWritten->arguments(), Policy,
1017 printTemplateArgumentList(
1018 OS, TemplateArgs.asArray(), Policy,
1025 if (
const auto *PartialSpec =
1026 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1027 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1039 assert(!Pattern.isNull() &&
1040 "Class template specialization without pattern?");
1041 if (
const auto *CTPSD =
1042 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
1043 return CTPSD->getSourceRange();
1050 Range.setEnd(Args->getRAngleLoc());
1057 Range.setBegin(ExternKW);
1060 Range.setBegin(TemplateKW);
1062 Range.setEnd(Args->getRAngleLoc());
1066 llvm_unreachable(
"unhandled template specialization kind");
1070 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1073 if (Loc.isInvalid())
1077 ExplicitInfo = Info;
1079 Info->ExternKeywordLoc = Loc;
1084 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1087 if (Loc.isInvalid())
1091 ExplicitInfo = Info;
1093 Info->TemplateKeywordLoc = Loc;
1103 assert(!Params->
empty() &&
"template with no template parameters");
1107 TD->setInvalidDecl();
1122ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1125 :
Decl(ImplicitConceptSpecialization, DC, SL),
1126 NumTemplateArgs(ConvertedArgs.size()) {
1127 setTemplateArguments(ConvertedArgs);
1130ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1131 EmptyShell
Empty,
unsigned NumTemplateArgs)
1132 :
Decl(ImplicitConceptSpecialization,
Empty),
1133 NumTemplateArgs(NumTemplateArgs) {}
1139 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1140 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1146 return new (
C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1147 ImplicitConceptSpecializationDecl(
EmptyShell{}, NumTemplateArgs);
1152 assert(Converted.size() == NumTemplateArgs);
1153 llvm::uninitialized_copy(Converted, getTrailingObjects());
1159void ClassTemplatePartialSpecializationDecl::anchor() {}
1161ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1168 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1171 SpecializedTemplate, Args,
false, PrevDecl),
1172 TemplateParams(Params), InstantiatedFromMember(
nullptr,
false),
1173 CanonInjectedTST(CanonInjectedTST) {
1184 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1185 assert(!Params->
empty() &&
"template with no template parameters");
1186 auto *
Result =
new (Context, DC) ClassTemplatePartialSpecializationDecl(
1187 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1188 CanonInjectedTST, PrevDecl);
1196 return new (
C, ID) ClassTemplatePartialSpecializationDecl(
C);
1202 if (CanonInjectedTST.isNull()) {
1209 return CanonInjectedTST;
1213 if (
const ClassTemplatePartialSpecializationDecl *MT =
1216 return MT->getSourceRange();
1228void FriendTemplateDecl::anchor() {}
1237 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1238 FriendTPLists.size());
1239 auto *FTD =
new (Context, DC,
Extra) FriendTemplateDecl(
1240 DC, Loc,
Friend, FriendLoc, EllipsisLoc, FriendTPLists, Template);
1251 auto *
Friend = Template.getAsTemplateDecl();
1252 assert(
Friend &&
"friend template name must be resolved");
1254 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1255 FriendTPLists.size());
1256 auto *FTD =
new (Context, DC,
Extra) FriendTemplateDecl(
1257 DC, Loc,
Friend, FriendLoc, EllipsisLoc, FriendTPLists, Template);
1264 unsigned NumFriendTPLists) {
1266 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1268 return new (
C, ID,
Extra) FriendTemplateDecl(
EmptyShell(), NumFriendTPLists);
1288 assert(!Params->
empty() &&
"template with no template parameters");
1292 TD->setInvalidDecl();
1304 auto *CommonPtr =
new (
C)
Common;
1305 C.addDestruction(CommonPtr);
1327 assert(!Params->
empty() &&
"template with no template parameters");
1331 TD->setInvalidDecl();
1346llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1352llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1360 auto *CommonPtr =
new (
C)
Common;
1361 C.addDestruction(CommonPtr);
1367 llvm::FoldingSetInsertToken &InsertToken) {
1382 llvm::FoldingSetInsertToken &InsertToken) {
1390 ID.AddInteger(TemplateArgs.size());
1398 llvm::FoldingSetInsertToken InsertToken) {
1405 assert(Existing->
isCanonicalDecl() &&
"Non-canonical specialization?");
1409 L->AddedCXXTemplateSpecialization(
this, D);
1414 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1417 PS.reserve(PartialSpecs.size());
1419 PS.push_back(P.getMostRecentDecl());
1427 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1428 return P.getMostRecentDecl();
1442 :
VarDecl(DK, Context, DC, StartLoc, IdLoc,
1444 SpecializedTemplate(SpecializedTemplate),
1459 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1460 SpecializedTemplate,
T, TInfo, S, Args);
1474 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(
this);
1476 PS ? PS->getTemplateArgsAsWritten() :
nullptr) {
1477 printTemplateArgumentList(
1478 OS, ArgsAsWritten->arguments(), Policy,
1482 printTemplateArgumentList(
1483 OS, TemplateArgs.asArray(), Policy,
1489 if (
const auto *PartialSpec =
1490 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1491 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1502 assert(!Pattern.isNull() &&
1503 "Variable template specialization without pattern?");
1504 if (
const auto *VTPSD =
1505 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1506 return VTPSD->getSourceRange();
1518 Range.setEnd(Args->getRAngleLoc());
1525 Range.setBegin(ExternKW);
1528 Range.setBegin(TemplateKW);
1530 Range.setEnd(Args->getRAngleLoc());
1534 llvm_unreachable(
"unhandled template specialization kind");
1538 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1541 if (Loc.isInvalid())
1545 ExplicitInfo = Info;
1547 Info->ExternKeywordLoc = Loc;
1551 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1554 if (Loc.isInvalid())
1558 ExplicitInfo = Info;
1560 Info->TemplateKeywordLoc = Loc;
1567void VarTemplatePartialSpecializationDecl::anchor() {}
1569VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1575 DC, StartLoc, IdLoc, SpecializedTemplate,
T,
1577 TemplateParams(Params), InstantiatedFromMember(
nullptr,
false) {
1588 assert(!Params->
empty() &&
"template with no template parameters");
1589 auto *
Result =
new (Context, DC) VarTemplatePartialSpecializationDecl(
1590 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate,
T, TInfo, S,
1599 return new (
C, ID) VarTemplatePartialSpecializationDecl(
C);
1603 if (
const VarTemplatePartialSpecializationDecl *MT =
1606 return MT->getSourceRange();
1617#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1618#include "clang/Basic/BuiltinTemplates.inc"
1621 llvm_unreachable(
"unhandled BuiltinTemplateKind!");
1624void BuiltinTemplateDecl::anchor() {}
1638 auto *
T = dyn_cast_or_null<BuiltinTemplateDecl>(
1640 return T &&
T->isPackProducingBuiltinTemplate();
1648 C.addDestruction(&TPOD->Value);
1654 auto *TPOD =
new (
C,
ID) TemplateParamObjectDecl(
nullptr, QualType(),
APValue());
1655 C.addDestruction(&TPOD->Value);
1661 OS <<
"<template param ";
1685std::tuple<NamedDecl *, TemplateArgument>
1688 case Decl::Kind::BuiltinTemplate:
1689 case Decl::Kind::ClassTemplate:
1690 case Decl::Kind::Concept:
1691 case Decl::Kind::FunctionTemplate:
1692 case Decl::Kind::TemplateTemplateParm:
1693 case Decl::Kind::TypeAliasTemplate:
1694 case Decl::Kind::VarTemplate:
1697 case Decl::Kind::ClassTemplateSpecialization: {
1699 auto P = CTSD->getSpecializedTemplateOrPartial();
1700 if (
const auto *CTPSD =
1701 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
1704 CTSD->getTemplateInstantiationArgs()[Index]};
1708 return {TPL->
getParam(Index), CTSD->getTemplateArgs()[Index]};
1710 case Decl::Kind::VarTemplateSpecialization: {
1712 auto P = VTSD->getSpecializedTemplateOrPartial();
1713 if (
const auto *VTPSD =
1714 dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
1717 VTSD->getTemplateInstantiationArgs()[Index]};
1721 return {TPL->
getParam(Index), VTSD->getTemplateArgs()[Index]};
1723 case Decl::Kind::ClassTemplatePartialSpecialization:
1725 ->getTemplateParameters()
1728 case Decl::Kind::VarTemplatePartialSpecialization:
1730 ->getTemplateParameters()
1734 case Decl::TemplateTypeParm:
1737 case Decl::Kind::CXXRecord:
1740 case Decl::Kind::CXXDeductionGuide:
1741 case Decl::Kind::CXXConversion:
1742 case Decl::Kind::CXXConstructor:
1743 case Decl::Kind::CXXDestructor:
1744 case Decl::Kind::CXXMethod:
1745 case Decl::Kind::Function: {
1751 case Decl::Kind::CXXExpansionStmt:
1752 assert(Index == 0 &&
"expansion stmts only have a single template param");
1755 llvm_unreachable(
"Unhandled templated declaration kind");
1760 if (
const auto *FD = dyn_cast<FunctionDecl>(&D)) {
1780 if (
const auto *VD = dyn_cast<VarDecl>(&D)) {
1783 if (VD->isStaticDataMember())
1789 if (
const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {
1796 if (
const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
1804 : *
static_cast<const Decl *
>(
1810 CRD->getMemberSpecializationInfo())
1811 return *Info->getInstantiatedFrom();
1815 if (
const auto *ED = dyn_cast<EnumDecl>(&D)) {
1826ExplicitInstantiationDecl::ExplicitInstantiationDecl(
1832 SpecAndTSK(
Specialization, TSK), ExternLoc(ExternLoc), NameLoc(NameLoc) {
1835 Flags |= HasQualifierFlag;
1837 Flags |= HasArgsAsWrittenFlag;
1840 TypeAndFlags.setPointerAndInt(TypeAsWritten, Flags);
1842 *getTrailingObjects<NestedNameSpecifierLoc>() = QualifierLoc;
1844 *getTrailingObjects<const ASTTemplateArgumentListInfo *>() = ArgsAsWritten;
1855 QualifierLoc ? 1 : 0, ArgsAsWritten ? 1 : 0);
1856 return new (
C, DC,
Extra) ExplicitInstantiationDecl(
1857 DC,
Specialization, ExternLoc, TemplateLoc, QualifierLoc, ArgsAsWritten,
1858 NameLoc, TypeAsWritten, TSK);
1863 unsigned TrailingFlags) {
1866 (TrailingFlags & HasQualifierFlag) ? 1 : 0,
1867 (TrailingFlags & HasArgsAsWrittenFlag) ? 1 : 0);
1870 D->TypeAndFlags.setInt(TrailingFlags);
1875 if (
auto TL = getClassTypeLoc()) {
1877 return TST.getElaboratedKeywordLoc();
1879 return Tag.getElaboratedKeywordLoc();
1886 return *getTrailingObjects<NestedNameSpecifierLoc>();
1887 if (
auto TL = getClassTypeLoc())
1888 return TL->getPrefix();
1894 if (getClassTypeLoc())
1896 return getRawTypeSourceInfo();
1900 if (
const auto *Args = getTrailingArgsInfo())
1901 return Args->NumTemplateArgs;
1902 if (
auto TL = getClassTypeLoc())
1904 return TST.getNumArgs();
1905 return std::nullopt;
1910 if (
const auto *Args = getTrailingArgsInfo())
1912 if (
auto TL = getClassTypeLoc())
1914 return TST.getArgLoc(I);
1915 llvm_unreachable(
"template arguments not found in trailing args or TypeLoc");
1919 if (
const auto *Args = getTrailingArgsInfo())
1920 return Args->getLAngleLoc();
1921 if (
auto TL = getClassTypeLoc())
1923 return TST.getLAngleLoc();
1924 llvm_unreachable(
"template arguments not found in trailing args or TypeLoc");
1928 if (
const auto *Args = getTrailingArgsInfo())
1929 return Args->getRAngleLoc();
1930 if (
auto TL = getClassTypeLoc())
1932 return TST.getRAngleLoc();
1933 llvm_unreachable(
"template arguments not found in trailing args or TypeLoc");
1940 if (TSI->getType().hasPostfixDeclaratorSyntax())
1941 return TSI->getTypeLoc().getEndLoc();
1964 return new (
C, DC) CXXExpansionStmtDecl(DC, Loc, NTTP);
1973 return Pattern ? Pattern->getSourceRange() :
SourceRange();
Defines the clang::ASTContext interface.
#define BuiltinTemplate(BTName)
Defines enum values for all the target-independent builtin functions.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static bool DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P)
static bool AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner)
static TemplateParameterList * createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK)
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
static StringRef getIdentifier(const Token &Tok)
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getCanonicalTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T, ArrayRef< TemplateArgument > CanonicalArgs) const
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
bool canonicalizeTemplateArguments(MutableArrayRef< TemplateArgument > Args) const
Canonicalize the given template argument list.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
BuiltinTemplateKind getBuiltinTemplateKind() const
bool isPackProducingBuiltinTemplate() const
Represents a C++26 expansion statement declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static CXXExpansionStmtDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static CXXExpansionStmtDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, NonTypeTemplateParmDecl *NTTP)
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
static CanQual< Type > CreateUnsafe(QualType Other)
Declaration of a class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified specialization knowing that it is not already in.
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl)
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr=nullptr)
A reference to a concept and its template args, as it appears in the code.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
ASTMutationListener * getASTMutationListener() const
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Kind
Lists the kind of concrete classes of Decl.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
Represents an explicit instantiation of a template entity in source code.
SourceLocation getEndLoc() const LLVM_READONLY
static ExplicitInstantiationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags)
TypeSourceInfo * getTypeAsWritten() const
The declared type (return type or variable type) for function / variable templates.
SourceLocation getTemplateArgsLAngleLoc() const
std::optional< unsigned > getNumTemplateArgs() const
Returns the number of explicit template arguments, or std::nullopt if this entity has no template arg...
TemplateArgumentLoc getTemplateArg(unsigned I) const
bool hasTrailingQualifier() const
SourceLocation getTemplateArgsRAngleLoc() const
SourceLocation getTagKWLoc() const
The tag keyword (struct/class/union) location for class templates / nested classes; invalid for funct...
NestedNameSpecifierLoc getQualifierLoc() const
Returns the qualifier regardless of where it is stored.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ExplicitInstantiationDecl * Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc, SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc, const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
This represents one expression.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial)
Load all the external specializations for the Decl.
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getEllipsisLoc() const
Retrieves the location of the '...', if present.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
bool isPackExpansion() const
Declaration of a friend template.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, FriendUnion Friend, SourceLocation FriendLoc, ArrayRef< TemplateParameterList * > FriendTPLists, SourceLocation EllipsisLoc={}, TemplateName Template={})
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumFriendTPLists)
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Declaration of a template function.
CommonBase * newCommon(ASTContext &C) const override
Common * getCommonPtr() const
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
friend class FunctionDecl
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
void addSpecialization(FunctionTemplateSpecializationInfo *Info, llvm::FoldingSetInsertToken InsertToken)
Add a specialization of this function template.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
Provides information a specialization of a member of a class template, which may be a member function...
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
NamedDecl * getMostRecentDecl()
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
A C++ nested-name-specifier augmented with source location information.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
void setPlaceholderTypeConstraint(Expr *E)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, llvm::FoldingSetInsertToken InsertToken)
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
A convenient class for passing around template argument information.
A template argument list.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
SourceLocation getLocation() const
const TemplateArgument & getArgument() const
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
bool isNull() const
Determine whether this template argument has no value.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * TemplatedDecl
TemplateParameterList * TemplateParams
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
A template parameter object.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const APValue & getValue() const
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
TemplateParameterList(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Defines the position of a template parameter within a template parameter list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, TemplateParameterList *Params)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint, UnsignedOrNone ArgPackSubstIndex)
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
Declaration of an alias template.
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
const Type * getTypeForDecl() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getBeginLoc() const LLVM_READONLY
A container of type source information.
QualType getType() const
Return the type wrapped by this type source info.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Represents a variable declaration or definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
VarDecl * getInstantiatedFromStaticDataMember() const
If this variable is an instantiated static data member of a class template specialization,...
@ Definition
This declaration is definitely a definition.
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
void AddSpecialization(VarTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified specialization knowing that it is not already in.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a variable template specialization, which refers to a variable template with a given set o...
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
bool isPackProducingBuiltinTemplateName(TemplateName N)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ Result
The result type of a method or function.
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ ExplicitInstantiation
We are parsing an explicit instantiation.
TagTypeKind
The kind of a tag type.
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
const Decl & adjustDeclToTemplate(const Decl &D)
If we have a 'templated' declaration for a template, adjust 'D' to refer to the actual template.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
CanQualType CanonInjectedTST
The Injected Template Specialization Type for this declaration.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Provides information about an explicit instantiation of a variable or class template.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
Data that is common to all of the declarations of a given function template.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Describes how types, statements, expressions, and declarations should be printed.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
Data that is common to all of the declarations of a given variable template.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > PartialSpecializations
The variable template partial specializations for this variable template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > Specializations
The variable template specializations for this variable template, including explicit specializations ...