1 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the C++ related Decl classes for templates.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/DeclTemplate.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/TypeLoc.h"
21 #include "clang/Basic/Builtins.h"
22 #include "clang/Basic/IdentifierTable.h"
23 #include "llvm/ADT/STLExtras.h"
25 using namespace clang;
27 //===----------------------------------------------------------------------===//
28 // TemplateParameterList Implementation
29 //===----------------------------------------------------------------------===//
31 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32 SourceLocation LAngleLoc,
33 ArrayRef<NamedDecl *> Params,
34 SourceLocation RAngleLoc)
35 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
36 NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
37 assert(this->NumParams == NumParams && "Too many template parameters");
38 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
39 NamedDecl *P = Params[Idx];
42 if (!P->isTemplateParameterPack()) {
43 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
44 if (NTTP->getType()->containsUnexpandedParameterPack())
45 ContainsUnexpandedParameterPack = true;
47 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
48 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
49 ContainsUnexpandedParameterPack = true;
51 // FIXME: If a default argument contains an unexpanded parameter pack, the
52 // template parameter list does too.
57 TemplateParameterList *TemplateParameterList::Create(
58 const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
59 ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
60 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
61 llvm::alignOf<TemplateParameterList>());
62 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
66 unsigned TemplateParameterList::getMinRequiredArguments() const {
67 unsigned NumRequiredArgs = 0;
68 for (const NamedDecl *P : asArray()) {
69 if (P->isTemplateParameterPack()) {
70 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
71 if (NTTP->isExpandedParameterPack()) {
72 NumRequiredArgs += NTTP->getNumExpansionTypes();
79 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
80 if (TTP->hasDefaultArgument())
82 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
83 if (NTTP->hasDefaultArgument())
85 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
91 return NumRequiredArgs;
94 unsigned TemplateParameterList::getDepth() const {
98 const NamedDecl *FirstParm = getParam(0);
99 if (const TemplateTypeParmDecl *TTP
100 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
101 return TTP->getDepth();
102 else if (const NonTypeTemplateParmDecl *NTTP
103 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
104 return NTTP->getDepth();
106 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
109 static void AdoptTemplateParameterList(TemplateParameterList *Params,
110 DeclContext *Owner) {
111 for (NamedDecl *P : *Params) {
112 P->setDeclContext(Owner);
114 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
115 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
120 void *allocateDefaultArgStorageChain(const ASTContext &C) {
121 return new (C) char[sizeof(void*) * 2];
125 //===----------------------------------------------------------------------===//
126 // RedeclarableTemplateDecl Implementation
127 //===----------------------------------------------------------------------===//
129 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
133 // Walk the previous-declaration chain until we either find a declaration
134 // with a common pointer or we run out of previous declarations.
135 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
137 Prev = Prev->getPreviousDecl()) {
139 Common = Prev->Common;
143 PrevDecls.push_back(Prev);
146 // If we never found a common pointer, allocate one now.
148 // FIXME: If any of the declarations is from an AST file, we probably
149 // need an update record to add the common data.
151 Common = newCommon(getASTContext());
154 // Update any previous declarations we saw with the common pointer.
155 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
156 Prev->Common = Common;
161 template<class EntryType>
162 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
163 RedeclarableTemplateDecl::findSpecializationImpl(
164 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
166 typedef SpecEntryTraits<EntryType> SETraits;
167 llvm::FoldingSetNodeID ID;
168 EntryType::Profile(ID,Args, getASTContext());
169 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
170 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
173 template<class Derived, class EntryType>
174 void RedeclarableTemplateDecl::addSpecializationImpl(
175 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
177 typedef SpecEntryTraits<EntryType> SETraits;
180 void *CorrectInsertPos;
181 assert(!findSpecializationImpl(Specializations,
182 SETraits::getTemplateArgs(Entry),
184 InsertPos == CorrectInsertPos &&
185 "given incorrect InsertPos for specialization");
187 Specializations.InsertNode(Entry, InsertPos);
189 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
191 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
192 "non-canonical specialization?");
195 if (ASTMutationListener *L = getASTMutationListener())
196 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
197 SETraits::getDecl(Entry));
200 /// \brief Generate the injected template arguments for the given template
201 /// parameter list, e.g., for the injected-class-name of a class template.
202 static void GenerateInjectedTemplateArgs(ASTContext &Context,
203 TemplateParameterList *Params,
204 TemplateArgument *Args) {
205 for (NamedDecl *Param : *Params) {
206 TemplateArgument Arg;
207 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
208 QualType ArgType = Context.getTypeDeclType(TTP);
209 if (TTP->isParameterPack())
210 ArgType = Context.getPackExpansionType(ArgType, None);
212 Arg = TemplateArgument(ArgType);
213 } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
214 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
215 NTTP->getType().getNonLValueExprType(Context),
216 Expr::getValueKindForType(NTTP->getType()),
217 NTTP->getLocation());
219 if (NTTP->isParameterPack())
220 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
221 NTTP->getLocation(), None);
222 Arg = TemplateArgument(E);
224 auto *TTP = cast<TemplateTemplateParmDecl>(Param);
225 if (TTP->isParameterPack())
226 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
228 Arg = TemplateArgument(TemplateName(TTP));
231 if (Param->isTemplateParameterPack())
232 Arg = TemplateArgument::CreatePackCopy(Context, Arg);
238 //===----------------------------------------------------------------------===//
239 // FunctionTemplateDecl Implementation
240 //===----------------------------------------------------------------------===//
242 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
243 static_cast<Common *>(Ptr)->~Common();
246 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
249 DeclarationName Name,
250 TemplateParameterList *Params,
252 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
253 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
256 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
258 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
259 DeclarationName(), nullptr, nullptr);
262 RedeclarableTemplateDecl::CommonBase *
263 FunctionTemplateDecl::newCommon(ASTContext &C) const {
264 Common *CommonPtr = new (C) Common;
265 C.AddDeallocation(DeallocateCommon, CommonPtr);
269 void FunctionTemplateDecl::LoadLazySpecializations() const {
270 // Grab the most recent declaration to ensure we've loaded any lazy
271 // redeclarations of this template.
273 // FIXME: Avoid walking the entire redeclaration chain here.
274 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
275 if (CommonPtr->LazySpecializations) {
276 ASTContext &Context = getASTContext();
277 uint32_t *Specs = CommonPtr->LazySpecializations;
278 CommonPtr->LazySpecializations = nullptr;
279 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
280 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
284 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
285 FunctionTemplateDecl::getSpecializations() const {
286 LoadLazySpecializations();
287 return getCommonPtr()->Specializations;
291 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
293 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
296 void FunctionTemplateDecl::addSpecialization(
297 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
298 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
302 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
303 TemplateParameterList *Params = getTemplateParameters();
304 Common *CommonPtr = getCommonPtr();
305 if (!CommonPtr->InjectedArgs) {
306 CommonPtr->InjectedArgs
307 = new (getASTContext()) TemplateArgument[Params->size()];
308 GenerateInjectedTemplateArgs(getASTContext(), Params,
309 CommonPtr->InjectedArgs);
312 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
315 //===----------------------------------------------------------------------===//
316 // ClassTemplateDecl Implementation
317 //===----------------------------------------------------------------------===//
319 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
320 static_cast<Common *>(Ptr)->~Common();
323 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
326 DeclarationName Name,
327 TemplateParameterList *Params,
329 ClassTemplateDecl *PrevDecl) {
330 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
331 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
333 New->setPreviousDecl(PrevDecl);
337 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
339 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
340 DeclarationName(), nullptr, nullptr);
343 void ClassTemplateDecl::LoadLazySpecializations() const {
344 // Grab the most recent declaration to ensure we've loaded any lazy
345 // redeclarations of this template.
347 // FIXME: Avoid walking the entire redeclaration chain here.
348 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
349 if (CommonPtr->LazySpecializations) {
350 ASTContext &Context = getASTContext();
351 uint32_t *Specs = CommonPtr->LazySpecializations;
352 CommonPtr->LazySpecializations = nullptr;
353 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
354 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
358 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
359 ClassTemplateDecl::getSpecializations() const {
360 LoadLazySpecializations();
361 return getCommonPtr()->Specializations;
364 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
365 ClassTemplateDecl::getPartialSpecializations() {
366 LoadLazySpecializations();
367 return getCommonPtr()->PartialSpecializations;
370 RedeclarableTemplateDecl::CommonBase *
371 ClassTemplateDecl::newCommon(ASTContext &C) const {
372 Common *CommonPtr = new (C) Common;
373 C.AddDeallocation(DeallocateCommon, CommonPtr);
377 ClassTemplateSpecializationDecl *
378 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
380 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
383 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
385 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
388 ClassTemplatePartialSpecializationDecl *
389 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
391 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
394 void ClassTemplateDecl::AddPartialSpecialization(
395 ClassTemplatePartialSpecializationDecl *D,
398 getPartialSpecializations().InsertNode(D, InsertPos);
400 ClassTemplatePartialSpecializationDecl *Existing
401 = getPartialSpecializations().GetOrInsertNode(D);
403 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
406 if (ASTMutationListener *L = getASTMutationListener())
407 L->AddedCXXTemplateSpecialization(this, D);
410 void ClassTemplateDecl::getPartialSpecializations(
411 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
412 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
413 = getPartialSpecializations();
415 PS.reserve(PartialSpecs.size());
416 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
417 PS.push_back(P.getMostRecentDecl());
420 ClassTemplatePartialSpecializationDecl *
421 ClassTemplateDecl::findPartialSpecialization(QualType T) {
422 ASTContext &Context = getASTContext();
423 for (ClassTemplatePartialSpecializationDecl &P :
424 getPartialSpecializations()) {
425 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
426 return P.getMostRecentDecl();
432 ClassTemplatePartialSpecializationDecl *
433 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
434 ClassTemplatePartialSpecializationDecl *D) {
435 Decl *DCanon = D->getCanonicalDecl();
436 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
437 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
438 return P.getMostRecentDecl();
445 ClassTemplateDecl::getInjectedClassNameSpecialization() {
446 Common *CommonPtr = getCommonPtr();
447 if (!CommonPtr->InjectedClassNameType.isNull())
448 return CommonPtr->InjectedClassNameType;
450 // C++0x [temp.dep.type]p2:
451 // The template argument list of a primary template is a template argument
452 // list in which the nth template argument has the value of the nth template
453 // parameter of the class template. If the nth template parameter is a
454 // template parameter pack (14.5.3), the nth template argument is a pack
455 // expansion (14.5.3) whose pattern is the name of the template parameter
457 ASTContext &Context = getASTContext();
458 TemplateParameterList *Params = getTemplateParameters();
459 SmallVector<TemplateArgument, 16> TemplateArgs;
460 TemplateArgs.resize(Params->size());
461 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
462 CommonPtr->InjectedClassNameType
463 = Context.getTemplateSpecializationType(TemplateName(this),
465 return CommonPtr->InjectedClassNameType;
468 //===----------------------------------------------------------------------===//
469 // TemplateTypeParm Allocation/Deallocation Method Implementations
470 //===----------------------------------------------------------------------===//
472 TemplateTypeParmDecl *
473 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
474 SourceLocation KeyLoc, SourceLocation NameLoc,
475 unsigned D, unsigned P, IdentifierInfo *Id,
476 bool Typename, bool ParameterPack) {
477 TemplateTypeParmDecl *TTPDecl =
478 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
479 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
480 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
484 TemplateTypeParmDecl *
485 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
486 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
487 SourceLocation(), nullptr, false);
490 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
491 return hasDefaultArgument()
492 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
496 SourceRange TemplateTypeParmDecl::getSourceRange() const {
497 if (hasDefaultArgument() && !defaultArgumentWasInherited())
498 return SourceRange(getLocStart(),
499 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
501 return TypeDecl::getSourceRange();
504 unsigned TemplateTypeParmDecl::getDepth() const {
505 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
508 unsigned TemplateTypeParmDecl::getIndex() const {
509 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
512 bool TemplateTypeParmDecl::isParameterPack() const {
513 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
516 //===----------------------------------------------------------------------===//
517 // NonTypeTemplateParmDecl Method Implementations
518 //===----------------------------------------------------------------------===//
520 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
521 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
522 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
523 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
524 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
525 TemplateParmPosition(D, P), ParameterPack(true),
526 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
527 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
529 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
530 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
531 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
532 TypesAndInfos[I].second = ExpandedTInfos[I];
537 NonTypeTemplateParmDecl *
538 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
539 SourceLocation StartLoc, SourceLocation IdLoc,
540 unsigned D, unsigned P, IdentifierInfo *Id,
541 QualType T, bool ParameterPack,
542 TypeSourceInfo *TInfo) {
543 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
544 T, ParameterPack, TInfo);
547 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
548 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
549 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
550 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
551 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
553 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
554 ExpandedTypes.size()))
555 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
556 ExpandedTypes, ExpandedTInfos);
559 NonTypeTemplateParmDecl *
560 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
561 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
562 SourceLocation(), 0, 0, nullptr,
563 QualType(), false, nullptr);
566 NonTypeTemplateParmDecl *
567 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
568 unsigned NumExpandedTypes) {
570 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
572 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
573 0, 0, nullptr, QualType(), nullptr, None,
575 NTTP->NumExpandedTypes = NumExpandedTypes;
579 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
580 if (hasDefaultArgument() && !defaultArgumentWasInherited())
581 return SourceRange(getOuterLocStart(),
582 getDefaultArgument()->getSourceRange().getEnd());
583 return DeclaratorDecl::getSourceRange();
586 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
587 return hasDefaultArgument()
588 ? getDefaultArgument()->getSourceRange().getBegin()
592 //===----------------------------------------------------------------------===//
593 // TemplateTemplateParmDecl Method Implementations
594 //===----------------------------------------------------------------------===//
596 void TemplateTemplateParmDecl::anchor() { }
598 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
599 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
600 IdentifierInfo *Id, TemplateParameterList *Params,
601 ArrayRef<TemplateParameterList *> Expansions)
602 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
603 TemplateParmPosition(D, P), ParameterPack(true),
604 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
605 if (!Expansions.empty())
606 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
607 getTrailingObjects<TemplateParameterList *>());
610 TemplateTemplateParmDecl *
611 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
612 SourceLocation L, unsigned D, unsigned P,
613 bool ParameterPack, IdentifierInfo *Id,
614 TemplateParameterList *Params) {
615 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
619 TemplateTemplateParmDecl *
620 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
621 SourceLocation L, unsigned D, unsigned P,
623 TemplateParameterList *Params,
624 ArrayRef<TemplateParameterList *> Expansions) {
626 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
627 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
630 TemplateTemplateParmDecl *
631 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
632 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
633 false, nullptr, nullptr);
636 TemplateTemplateParmDecl *
637 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
638 unsigned NumExpansions) {
640 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
641 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
643 TTP->NumExpandedParams = NumExpansions;
647 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
648 return hasDefaultArgument() ? getDefaultArgument().getLocation()
652 void TemplateTemplateParmDecl::setDefaultArgument(
653 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
654 if (DefArg.getArgument().isNull())
655 DefaultArgument.set(nullptr);
657 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
660 //===----------------------------------------------------------------------===//
661 // TemplateArgumentList Implementation
662 //===----------------------------------------------------------------------===//
663 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
664 : Arguments(getTrailingObjects<TemplateArgument>()),
665 NumArguments(Args.size()) {
666 std::uninitialized_copy(Args.begin(), Args.end(),
667 getTrailingObjects<TemplateArgument>());
670 TemplateArgumentList *
671 TemplateArgumentList::CreateCopy(ASTContext &Context,
672 ArrayRef<TemplateArgument> Args) {
673 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
674 return new (Mem) TemplateArgumentList(Args);
677 FunctionTemplateSpecializationInfo *
678 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
679 FunctionTemplateDecl *Template,
680 TemplateSpecializationKind TSK,
681 const TemplateArgumentList *TemplateArgs,
682 const TemplateArgumentListInfo *TemplateArgsAsWritten,
683 SourceLocation POI) {
684 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
685 if (TemplateArgsAsWritten)
686 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
687 *TemplateArgsAsWritten);
689 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
695 //===----------------------------------------------------------------------===//
696 // TemplateDecl Implementation
697 //===----------------------------------------------------------------------===//
699 void TemplateDecl::anchor() { }
701 //===----------------------------------------------------------------------===//
702 // ClassTemplateSpecializationDecl Implementation
703 //===----------------------------------------------------------------------===//
704 ClassTemplateSpecializationDecl::
705 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
706 DeclContext *DC, SourceLocation StartLoc,
707 SourceLocation IdLoc,
708 ClassTemplateDecl *SpecializedTemplate,
709 ArrayRef<TemplateArgument> Args,
710 ClassTemplateSpecializationDecl *PrevDecl)
711 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
712 SpecializedTemplate->getIdentifier(),
714 SpecializedTemplate(SpecializedTemplate),
715 ExplicitInfo(nullptr),
716 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
717 SpecializationKind(TSK_Undeclared) {
720 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
722 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
723 SourceLocation(), nullptr, nullptr),
724 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
726 ClassTemplateSpecializationDecl *
727 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
729 SourceLocation StartLoc,
730 SourceLocation IdLoc,
731 ClassTemplateDecl *SpecializedTemplate,
732 ArrayRef<TemplateArgument> Args,
733 ClassTemplateSpecializationDecl *PrevDecl) {
734 ClassTemplateSpecializationDecl *Result =
735 new (Context, DC) ClassTemplateSpecializationDecl(
736 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
737 SpecializedTemplate, Args, PrevDecl);
738 Result->MayHaveOutOfDateDef = false;
740 Context.getTypeDeclType(Result, PrevDecl);
744 ClassTemplateSpecializationDecl *
745 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
747 ClassTemplateSpecializationDecl *Result =
748 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
749 Result->MayHaveOutOfDateDef = false;
753 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
754 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
755 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
757 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
758 TemplateSpecializationType::PrintTemplateArgumentList(
759 OS, TemplateArgs.asArray(), Policy);
763 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
764 if (SpecializedPartialSpecialization *PartialSpec
765 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
766 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
767 return SpecializedTemplate.get<ClassTemplateDecl*>();
771 ClassTemplateSpecializationDecl::getSourceRange() const {
773 SourceLocation Begin = getTemplateKeywordLoc();
774 if (Begin.isValid()) {
775 // Here we have an explicit (partial) specialization or instantiation.
776 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
777 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
778 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
779 if (getExternLoc().isValid())
780 Begin = getExternLoc();
781 SourceLocation End = getBraceRange().getEnd();
783 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
784 return SourceRange(Begin, End);
786 // An implicit instantiation of a class template partial specialization
787 // uses ExplicitInfo to record the TypeAsWritten, but the source
788 // locations should be retrieved from the instantiation pattern.
789 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
790 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
791 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
792 assert(inst_from != nullptr);
793 return inst_from->getSourceRange();
796 // No explicit info available.
797 llvm::PointerUnion<ClassTemplateDecl *,
798 ClassTemplatePartialSpecializationDecl *>
799 inst_from = getInstantiatedFrom();
800 if (inst_from.isNull())
801 return getSpecializedTemplate()->getSourceRange();
802 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
803 return ctd->getSourceRange();
804 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
809 //===----------------------------------------------------------------------===//
810 // ClassTemplatePartialSpecializationDecl Implementation
811 //===----------------------------------------------------------------------===//
812 void ClassTemplatePartialSpecializationDecl::anchor() { }
814 ClassTemplatePartialSpecializationDecl::
815 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
817 SourceLocation StartLoc,
818 SourceLocation IdLoc,
819 TemplateParameterList *Params,
820 ClassTemplateDecl *SpecializedTemplate,
821 ArrayRef<TemplateArgument> Args,
822 const ASTTemplateArgumentListInfo *ArgInfos,
823 ClassTemplatePartialSpecializationDecl *PrevDecl)
824 : ClassTemplateSpecializationDecl(Context,
825 ClassTemplatePartialSpecialization,
826 TK, DC, StartLoc, IdLoc,
829 TemplateParams(Params), ArgsAsWritten(ArgInfos),
830 InstantiatedFromMember(nullptr, false)
832 AdoptTemplateParameterList(Params, this);
835 ClassTemplatePartialSpecializationDecl *
836 ClassTemplatePartialSpecializationDecl::
837 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
838 SourceLocation StartLoc, SourceLocation IdLoc,
839 TemplateParameterList *Params,
840 ClassTemplateDecl *SpecializedTemplate,
841 ArrayRef<TemplateArgument> Args,
842 const TemplateArgumentListInfo &ArgInfos,
843 QualType CanonInjectedType,
844 ClassTemplatePartialSpecializationDecl *PrevDecl) {
845 const ASTTemplateArgumentListInfo *ASTArgInfos =
846 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
848 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
849 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
850 Params, SpecializedTemplate, Args,
851 ASTArgInfos, PrevDecl);
852 Result->setSpecializationKind(TSK_ExplicitSpecialization);
853 Result->MayHaveOutOfDateDef = false;
855 Context.getInjectedClassNameType(Result, CanonInjectedType);
859 ClassTemplatePartialSpecializationDecl *
860 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
862 ClassTemplatePartialSpecializationDecl *Result =
863 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
864 Result->MayHaveOutOfDateDef = false;
868 //===----------------------------------------------------------------------===//
869 // FriendTemplateDecl Implementation
870 //===----------------------------------------------------------------------===//
872 void FriendTemplateDecl::anchor() { }
875 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
877 MutableArrayRef<TemplateParameterList *> Params,
878 FriendUnion Friend, SourceLocation FLoc) {
879 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
882 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
884 return new (C, ID) FriendTemplateDecl(EmptyShell());
887 //===----------------------------------------------------------------------===//
888 // TypeAliasTemplateDecl Implementation
889 //===----------------------------------------------------------------------===//
891 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
894 DeclarationName Name,
895 TemplateParameterList *Params,
897 AdoptTemplateParameterList(Params, DC);
898 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
901 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
903 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
904 DeclarationName(), nullptr, nullptr);
907 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
908 static_cast<Common *>(Ptr)->~Common();
910 RedeclarableTemplateDecl::CommonBase *
911 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
912 Common *CommonPtr = new (C) Common;
913 C.AddDeallocation(DeallocateCommon, CommonPtr);
917 //===----------------------------------------------------------------------===//
918 // ClassScopeFunctionSpecializationDecl Implementation
919 //===----------------------------------------------------------------------===//
921 void ClassScopeFunctionSpecializationDecl::anchor() { }
923 ClassScopeFunctionSpecializationDecl *
924 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
926 return new (C, ID) ClassScopeFunctionSpecializationDecl(
927 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
930 //===----------------------------------------------------------------------===//
931 // VarTemplateDecl Implementation
932 //===----------------------------------------------------------------------===//
934 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
935 static_cast<Common *>(Ptr)->~Common();
938 VarTemplateDecl *VarTemplateDecl::getDefinition() {
939 VarTemplateDecl *CurD = this;
941 if (CurD->isThisDeclarationADefinition())
943 CurD = CurD->getPreviousDecl();
948 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
949 SourceLocation L, DeclarationName Name,
950 TemplateParameterList *Params,
952 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
955 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
957 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
958 DeclarationName(), nullptr, nullptr);
961 // TODO: Unify across class, function and variable templates?
962 // May require moving this and Common to RedeclarableTemplateDecl.
963 void VarTemplateDecl::LoadLazySpecializations() const {
964 // Grab the most recent declaration to ensure we've loaded any lazy
965 // redeclarations of this template.
967 // FIXME: Avoid walking the entire redeclaration chain here.
968 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
969 if (CommonPtr->LazySpecializations) {
970 ASTContext &Context = getASTContext();
971 uint32_t *Specs = CommonPtr->LazySpecializations;
972 CommonPtr->LazySpecializations = nullptr;
973 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
974 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
978 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
979 VarTemplateDecl::getSpecializations() const {
980 LoadLazySpecializations();
981 return getCommonPtr()->Specializations;
984 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
985 VarTemplateDecl::getPartialSpecializations() {
986 LoadLazySpecializations();
987 return getCommonPtr()->PartialSpecializations;
990 RedeclarableTemplateDecl::CommonBase *
991 VarTemplateDecl::newCommon(ASTContext &C) const {
992 Common *CommonPtr = new (C) Common;
993 C.AddDeallocation(DeallocateCommon, CommonPtr);
997 VarTemplateSpecializationDecl *
998 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1000 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1003 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1005 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1008 VarTemplatePartialSpecializationDecl *
1009 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1011 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1014 void VarTemplateDecl::AddPartialSpecialization(
1015 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1017 getPartialSpecializations().InsertNode(D, InsertPos);
1019 VarTemplatePartialSpecializationDecl *Existing =
1020 getPartialSpecializations().GetOrInsertNode(D);
1022 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1025 if (ASTMutationListener *L = getASTMutationListener())
1026 L->AddedCXXTemplateSpecialization(this, D);
1029 void VarTemplateDecl::getPartialSpecializations(
1030 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1031 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1032 getPartialSpecializations();
1034 PS.reserve(PartialSpecs.size());
1035 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1036 PS.push_back(P.getMostRecentDecl());
1039 VarTemplatePartialSpecializationDecl *
1040 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1041 VarTemplatePartialSpecializationDecl *D) {
1042 Decl *DCanon = D->getCanonicalDecl();
1043 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1044 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1045 return P.getMostRecentDecl();
1051 //===----------------------------------------------------------------------===//
1052 // VarTemplateSpecializationDecl Implementation
1053 //===----------------------------------------------------------------------===//
1054 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1055 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1056 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1057 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1058 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1059 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1060 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1061 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1062 SpecializationKind(TSK_Undeclared) {}
1064 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1066 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1067 QualType(), nullptr, SC_None),
1068 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1070 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1071 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1072 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1073 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1074 return new (Context, DC) VarTemplateSpecializationDecl(
1075 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1076 SpecializedTemplate, T, TInfo, S, Args);
1079 VarTemplateSpecializationDecl *
1080 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1082 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1085 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1086 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1087 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1089 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1090 TemplateSpecializationType::PrintTemplateArgumentList(
1091 OS, TemplateArgs.asArray(), Policy);
1094 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1095 if (SpecializedPartialSpecialization *PartialSpec =
1096 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1097 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1098 return SpecializedTemplate.get<VarTemplateDecl *>();
1101 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1102 const TemplateArgumentListInfo &ArgsInfo) {
1103 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1104 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1105 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1106 TemplateArgsInfo.addArgument(Loc);
1109 //===----------------------------------------------------------------------===//
1110 // VarTemplatePartialSpecializationDecl Implementation
1111 //===----------------------------------------------------------------------===//
1112 void VarTemplatePartialSpecializationDecl::anchor() {}
1114 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1115 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1116 SourceLocation IdLoc, TemplateParameterList *Params,
1117 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1118 StorageClass S, ArrayRef<TemplateArgument> Args,
1119 const ASTTemplateArgumentListInfo *ArgInfos)
1120 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1121 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1123 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1124 InstantiatedFromMember(nullptr, false) {
1125 // TODO: The template parameters should be in DC by now. Verify.
1126 // AdoptTemplateParameterList(Params, DC);
1129 VarTemplatePartialSpecializationDecl *
1130 VarTemplatePartialSpecializationDecl::Create(
1131 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1132 SourceLocation IdLoc, TemplateParameterList *Params,
1133 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1134 StorageClass S, ArrayRef<TemplateArgument> Args,
1135 const TemplateArgumentListInfo &ArgInfos) {
1136 const ASTTemplateArgumentListInfo *ASTArgInfos
1137 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1139 VarTemplatePartialSpecializationDecl *Result =
1140 new (Context, DC) VarTemplatePartialSpecializationDecl(
1141 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1142 S, Args, ASTArgInfos);
1143 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1147 VarTemplatePartialSpecializationDecl *
1148 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1150 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1153 static TemplateParameterList *
1154 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1156 auto *T = TemplateTypeParmDecl::Create(
1157 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1158 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1159 T->setImplicit(true);
1162 TypeSourceInfo *TI =
1163 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1164 auto *N = NonTypeTemplateParmDecl::Create(
1165 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1166 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1167 N->setImplicit(true);
1169 // <typename T, T ...Ints>
1170 NamedDecl *P[2] = {T, N};
1171 auto *TPL = TemplateParameterList::Create(
1172 C, SourceLocation(), SourceLocation(), P, SourceLocation());
1174 // template <typename T, ...Ints> class IntSeq
1175 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1176 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1177 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1178 TemplateTemplateParm->setImplicit(true);
1181 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1182 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1183 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1184 TemplateTypeParm->setImplicit(true);
1187 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1188 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1189 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1190 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1191 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1192 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1193 NonTypeTemplateParm};
1195 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1196 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1197 Params, SourceLocation());
1200 static TemplateParameterList *
1201 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1202 // std::size_t Index
1203 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1204 auto *Index = NonTypeTemplateParmDecl::Create(
1205 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1206 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1209 auto *Ts = TemplateTypeParmDecl::Create(
1210 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1212 Ts->setImplicit(true);
1214 // template <std::size_t Index, typename ...T>
1215 NamedDecl *Params[] = {Index, Ts};
1216 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1217 llvm::makeArrayRef(Params),
1221 static TemplateParameterList *createBuiltinTemplateParameterList(
1222 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1224 case BTK__make_integer_seq:
1225 return createMakeIntegerSeqParameterList(C, DC);
1226 case BTK__type_pack_element:
1227 return createTypePackElementParameterList(C, DC);
1230 llvm_unreachable("unhandled BuiltinTemplateKind!");
1233 void BuiltinTemplateDecl::anchor() {}
1235 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1236 DeclarationName Name,
1237 BuiltinTemplateKind BTK)
1238 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1239 createBuiltinTemplateParameterList(C, DC, BTK)),