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,
36 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
37 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
38 HasRequiresClause(static_cast<bool>(RequiresClause)) {
39 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
40 NamedDecl *P = Params[Idx];
43 if (!P->isTemplateParameterPack()) {
44 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
45 if (NTTP->getType()->containsUnexpandedParameterPack())
46 ContainsUnexpandedParameterPack = true;
48 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
49 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
50 ContainsUnexpandedParameterPack = true;
52 // FIXME: If a default argument contains an unexpanded parameter pack, the
53 // template parameter list does too.
57 *getTrailingObjects<Expr *>() = RequiresClause;
61 TemplateParameterList *
62 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
63 SourceLocation LAngleLoc,
64 ArrayRef<NamedDecl *> Params,
65 SourceLocation RAngleLoc, Expr *RequiresClause) {
66 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
67 Params.size(), RequiresClause ? 1u : 0u),
68 alignof(TemplateParameterList));
69 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
70 RAngleLoc, RequiresClause);
73 unsigned TemplateParameterList::getMinRequiredArguments() const {
74 unsigned NumRequiredArgs = 0;
75 for (const NamedDecl *P : asArray()) {
76 if (P->isTemplateParameterPack()) {
77 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
78 if (NTTP->isExpandedParameterPack()) {
79 NumRequiredArgs += NTTP->getNumExpansionTypes();
86 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
87 if (TTP->hasDefaultArgument())
89 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
90 if (NTTP->hasDefaultArgument())
92 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
98 return NumRequiredArgs;
101 unsigned TemplateParameterList::getDepth() const {
105 const NamedDecl *FirstParm = getParam(0);
106 if (const TemplateTypeParmDecl *TTP
107 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
108 return TTP->getDepth();
109 else if (const NonTypeTemplateParmDecl *NTTP
110 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
111 return NTTP->getDepth();
113 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
116 static void AdoptTemplateParameterList(TemplateParameterList *Params,
117 DeclContext *Owner) {
118 for (NamedDecl *P : *Params) {
119 P->setDeclContext(Owner);
121 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
122 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
127 void *allocateDefaultArgStorageChain(const ASTContext &C) {
128 return new (C) char[sizeof(void*) * 2];
132 //===----------------------------------------------------------------------===//
133 // RedeclarableTemplateDecl Implementation
134 //===----------------------------------------------------------------------===//
136 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
140 // Walk the previous-declaration chain until we either find a declaration
141 // with a common pointer or we run out of previous declarations.
142 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
143 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
144 Prev = Prev->getPreviousDecl()) {
146 Common = Prev->Common;
150 PrevDecls.push_back(Prev);
153 // If we never found a common pointer, allocate one now.
155 // FIXME: If any of the declarations is from an AST file, we probably
156 // need an update record to add the common data.
158 Common = newCommon(getASTContext());
161 // Update any previous declarations we saw with the common pointer.
162 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
163 Prev->Common = Common;
168 template<class EntryType>
169 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
170 RedeclarableTemplateDecl::findSpecializationImpl(
171 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
173 typedef SpecEntryTraits<EntryType> SETraits;
174 llvm::FoldingSetNodeID ID;
175 EntryType::Profile(ID,Args, getASTContext());
176 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
177 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
180 template<class Derived, class EntryType>
181 void RedeclarableTemplateDecl::addSpecializationImpl(
182 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
184 typedef SpecEntryTraits<EntryType> SETraits;
187 void *CorrectInsertPos;
188 assert(!findSpecializationImpl(Specializations,
189 SETraits::getTemplateArgs(Entry),
191 InsertPos == CorrectInsertPos &&
192 "given incorrect InsertPos for specialization");
194 Specializations.InsertNode(Entry, InsertPos);
196 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
198 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
199 "non-canonical specialization?");
202 if (ASTMutationListener *L = getASTMutationListener())
203 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
204 SETraits::getDecl(Entry));
207 //===----------------------------------------------------------------------===//
208 // FunctionTemplateDecl Implementation
209 //===----------------------------------------------------------------------===//
211 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
212 static_cast<Common *>(Ptr)->~Common();
215 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
218 DeclarationName Name,
219 TemplateParameterList *Params,
221 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
222 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
225 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
227 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
228 DeclarationName(), nullptr, nullptr);
231 RedeclarableTemplateDecl::CommonBase *
232 FunctionTemplateDecl::newCommon(ASTContext &C) const {
233 Common *CommonPtr = new (C) Common;
234 C.AddDeallocation(DeallocateCommon, CommonPtr);
238 void FunctionTemplateDecl::LoadLazySpecializations() const {
239 // Grab the most recent declaration to ensure we've loaded any lazy
240 // redeclarations of this template.
242 // FIXME: Avoid walking the entire redeclaration chain here.
243 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
244 if (CommonPtr->LazySpecializations) {
245 ASTContext &Context = getASTContext();
246 uint32_t *Specs = CommonPtr->LazySpecializations;
247 CommonPtr->LazySpecializations = nullptr;
248 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
249 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
253 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
254 FunctionTemplateDecl::getSpecializations() const {
255 LoadLazySpecializations();
256 return getCommonPtr()->Specializations;
260 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
262 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
265 void FunctionTemplateDecl::addSpecialization(
266 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
267 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
271 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
272 TemplateParameterList *Params = getTemplateParameters();
273 Common *CommonPtr = getCommonPtr();
274 if (!CommonPtr->InjectedArgs) {
275 auto &Context = getASTContext();
276 SmallVector<TemplateArgument, 16> TemplateArgs;
277 Context.getInjectedTemplateArgs(Params, TemplateArgs);
278 CommonPtr->InjectedArgs =
279 new (Context) TemplateArgument[TemplateArgs.size()];
280 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
281 CommonPtr->InjectedArgs);
284 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
287 //===----------------------------------------------------------------------===//
288 // ClassTemplateDecl Implementation
289 //===----------------------------------------------------------------------===//
291 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
292 static_cast<Common *>(Ptr)->~Common();
295 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
298 DeclarationName Name,
299 TemplateParameterList *Params,
301 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
302 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
307 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
309 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
310 DeclarationName(), nullptr, nullptr);
313 void ClassTemplateDecl::LoadLazySpecializations() const {
314 // Grab the most recent declaration to ensure we've loaded any lazy
315 // redeclarations of this template.
317 // FIXME: Avoid walking the entire redeclaration chain here.
318 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
319 if (CommonPtr->LazySpecializations) {
320 ASTContext &Context = getASTContext();
321 uint32_t *Specs = CommonPtr->LazySpecializations;
322 CommonPtr->LazySpecializations = nullptr;
323 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
324 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
328 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
329 ClassTemplateDecl::getSpecializations() const {
330 LoadLazySpecializations();
331 return getCommonPtr()->Specializations;
334 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
335 ClassTemplateDecl::getPartialSpecializations() {
336 LoadLazySpecializations();
337 return getCommonPtr()->PartialSpecializations;
340 RedeclarableTemplateDecl::CommonBase *
341 ClassTemplateDecl::newCommon(ASTContext &C) const {
342 Common *CommonPtr = new (C) Common;
343 C.AddDeallocation(DeallocateCommon, CommonPtr);
347 ClassTemplateSpecializationDecl *
348 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
350 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
353 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
355 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
358 ClassTemplatePartialSpecializationDecl *
359 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
361 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
364 void ClassTemplateDecl::AddPartialSpecialization(
365 ClassTemplatePartialSpecializationDecl *D,
368 getPartialSpecializations().InsertNode(D, InsertPos);
370 ClassTemplatePartialSpecializationDecl *Existing
371 = getPartialSpecializations().GetOrInsertNode(D);
373 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
376 if (ASTMutationListener *L = getASTMutationListener())
377 L->AddedCXXTemplateSpecialization(this, D);
380 void ClassTemplateDecl::getPartialSpecializations(
381 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
382 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
383 = getPartialSpecializations();
385 PS.reserve(PartialSpecs.size());
386 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
387 PS.push_back(P.getMostRecentDecl());
390 ClassTemplatePartialSpecializationDecl *
391 ClassTemplateDecl::findPartialSpecialization(QualType T) {
392 ASTContext &Context = getASTContext();
393 for (ClassTemplatePartialSpecializationDecl &P :
394 getPartialSpecializations()) {
395 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
396 return P.getMostRecentDecl();
402 ClassTemplatePartialSpecializationDecl *
403 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
404 ClassTemplatePartialSpecializationDecl *D) {
405 Decl *DCanon = D->getCanonicalDecl();
406 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
407 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
408 return P.getMostRecentDecl();
415 ClassTemplateDecl::getInjectedClassNameSpecialization() {
416 Common *CommonPtr = getCommonPtr();
417 if (!CommonPtr->InjectedClassNameType.isNull())
418 return CommonPtr->InjectedClassNameType;
420 // C++0x [temp.dep.type]p2:
421 // The template argument list of a primary template is a template argument
422 // list in which the nth template argument has the value of the nth template
423 // parameter of the class template. If the nth template parameter is a
424 // template parameter pack (14.5.3), the nth template argument is a pack
425 // expansion (14.5.3) whose pattern is the name of the template parameter
427 ASTContext &Context = getASTContext();
428 TemplateParameterList *Params = getTemplateParameters();
429 SmallVector<TemplateArgument, 16> TemplateArgs;
430 Context.getInjectedTemplateArgs(Params, TemplateArgs);
431 CommonPtr->InjectedClassNameType
432 = Context.getTemplateSpecializationType(TemplateName(this),
434 return CommonPtr->InjectedClassNameType;
437 //===----------------------------------------------------------------------===//
438 // TemplateTypeParm Allocation/Deallocation Method Implementations
439 //===----------------------------------------------------------------------===//
441 TemplateTypeParmDecl *
442 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
443 SourceLocation KeyLoc, SourceLocation NameLoc,
444 unsigned D, unsigned P, IdentifierInfo *Id,
445 bool Typename, bool ParameterPack) {
446 TemplateTypeParmDecl *TTPDecl =
447 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
448 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
449 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
453 TemplateTypeParmDecl *
454 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
455 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
456 SourceLocation(), nullptr, false);
459 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
460 return hasDefaultArgument()
461 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
465 SourceRange TemplateTypeParmDecl::getSourceRange() const {
466 if (hasDefaultArgument() && !defaultArgumentWasInherited())
467 return SourceRange(getLocStart(),
468 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
470 return TypeDecl::getSourceRange();
473 unsigned TemplateTypeParmDecl::getDepth() const {
474 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
477 unsigned TemplateTypeParmDecl::getIndex() const {
478 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
481 bool TemplateTypeParmDecl::isParameterPack() const {
482 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
485 //===----------------------------------------------------------------------===//
486 // NonTypeTemplateParmDecl Method Implementations
487 //===----------------------------------------------------------------------===//
489 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
490 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
491 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
492 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
493 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
494 TemplateParmPosition(D, P), ParameterPack(true),
495 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
496 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
498 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
499 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
500 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
501 TypesAndInfos[I].second = ExpandedTInfos[I];
506 NonTypeTemplateParmDecl *
507 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
508 SourceLocation StartLoc, SourceLocation IdLoc,
509 unsigned D, unsigned P, IdentifierInfo *Id,
510 QualType T, bool ParameterPack,
511 TypeSourceInfo *TInfo) {
512 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
513 T, ParameterPack, TInfo);
516 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
517 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
518 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
519 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
520 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
522 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
523 ExpandedTypes.size()))
524 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
525 ExpandedTypes, ExpandedTInfos);
528 NonTypeTemplateParmDecl *
529 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
530 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
531 SourceLocation(), 0, 0, nullptr,
532 QualType(), false, nullptr);
535 NonTypeTemplateParmDecl *
536 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
537 unsigned NumExpandedTypes) {
539 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
541 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
542 0, 0, nullptr, QualType(), nullptr, None,
544 NTTP->NumExpandedTypes = NumExpandedTypes;
548 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
549 if (hasDefaultArgument() && !defaultArgumentWasInherited())
550 return SourceRange(getOuterLocStart(),
551 getDefaultArgument()->getSourceRange().getEnd());
552 return DeclaratorDecl::getSourceRange();
555 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
556 return hasDefaultArgument()
557 ? getDefaultArgument()->getSourceRange().getBegin()
561 //===----------------------------------------------------------------------===//
562 // TemplateTemplateParmDecl Method Implementations
563 //===----------------------------------------------------------------------===//
565 void TemplateTemplateParmDecl::anchor() { }
567 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
568 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
569 IdentifierInfo *Id, TemplateParameterList *Params,
570 ArrayRef<TemplateParameterList *> Expansions)
571 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
572 TemplateParmPosition(D, P), ParameterPack(true),
573 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
574 if (!Expansions.empty())
575 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
576 getTrailingObjects<TemplateParameterList *>());
579 TemplateTemplateParmDecl *
580 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
581 SourceLocation L, unsigned D, unsigned P,
582 bool ParameterPack, IdentifierInfo *Id,
583 TemplateParameterList *Params) {
584 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
588 TemplateTemplateParmDecl *
589 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
590 SourceLocation L, unsigned D, unsigned P,
592 TemplateParameterList *Params,
593 ArrayRef<TemplateParameterList *> Expansions) {
595 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
596 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
599 TemplateTemplateParmDecl *
600 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
601 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
602 false, nullptr, nullptr);
605 TemplateTemplateParmDecl *
606 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
607 unsigned NumExpansions) {
609 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
610 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
612 TTP->NumExpandedParams = NumExpansions;
616 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
617 return hasDefaultArgument() ? getDefaultArgument().getLocation()
621 void TemplateTemplateParmDecl::setDefaultArgument(
622 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
623 if (DefArg.getArgument().isNull())
624 DefaultArgument.set(nullptr);
626 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
629 //===----------------------------------------------------------------------===//
630 // TemplateArgumentList Implementation
631 //===----------------------------------------------------------------------===//
632 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
633 : Arguments(getTrailingObjects<TemplateArgument>()),
634 NumArguments(Args.size()) {
635 std::uninitialized_copy(Args.begin(), Args.end(),
636 getTrailingObjects<TemplateArgument>());
639 TemplateArgumentList *
640 TemplateArgumentList::CreateCopy(ASTContext &Context,
641 ArrayRef<TemplateArgument> Args) {
642 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
643 return new (Mem) TemplateArgumentList(Args);
646 FunctionTemplateSpecializationInfo *
647 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
648 FunctionTemplateDecl *Template,
649 TemplateSpecializationKind TSK,
650 const TemplateArgumentList *TemplateArgs,
651 const TemplateArgumentListInfo *TemplateArgsAsWritten,
652 SourceLocation POI) {
653 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
654 if (TemplateArgsAsWritten)
655 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
656 *TemplateArgsAsWritten);
658 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
664 //===----------------------------------------------------------------------===//
665 // TemplateDecl Implementation
666 //===----------------------------------------------------------------------===//
668 void TemplateDecl::anchor() { }
670 //===----------------------------------------------------------------------===//
671 // ClassTemplateSpecializationDecl Implementation
672 //===----------------------------------------------------------------------===//
673 ClassTemplateSpecializationDecl::
674 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
675 DeclContext *DC, SourceLocation StartLoc,
676 SourceLocation IdLoc,
677 ClassTemplateDecl *SpecializedTemplate,
678 ArrayRef<TemplateArgument> Args,
679 ClassTemplateSpecializationDecl *PrevDecl)
680 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
681 SpecializedTemplate->getIdentifier(),
683 SpecializedTemplate(SpecializedTemplate),
684 ExplicitInfo(nullptr),
685 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
686 SpecializationKind(TSK_Undeclared) {
689 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
691 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
692 SourceLocation(), nullptr, nullptr),
693 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
695 ClassTemplateSpecializationDecl *
696 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
698 SourceLocation StartLoc,
699 SourceLocation IdLoc,
700 ClassTemplateDecl *SpecializedTemplate,
701 ArrayRef<TemplateArgument> Args,
702 ClassTemplateSpecializationDecl *PrevDecl) {
703 ClassTemplateSpecializationDecl *Result =
704 new (Context, DC) ClassTemplateSpecializationDecl(
705 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
706 SpecializedTemplate, Args, PrevDecl);
707 Result->MayHaveOutOfDateDef = false;
709 Context.getTypeDeclType(Result, PrevDecl);
713 ClassTemplateSpecializationDecl *
714 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
716 ClassTemplateSpecializationDecl *Result =
717 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
718 Result->MayHaveOutOfDateDef = false;
722 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
723 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
724 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
726 auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
727 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
728 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
729 TemplateSpecializationType::PrintTemplateArgumentList(
730 OS, ArgsAsWritten->arguments(), Policy);
732 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
733 TemplateSpecializationType::PrintTemplateArgumentList(
734 OS, TemplateArgs.asArray(), Policy);
739 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
740 if (SpecializedPartialSpecialization *PartialSpec
741 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
742 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
743 return SpecializedTemplate.get<ClassTemplateDecl*>();
747 ClassTemplateSpecializationDecl::getSourceRange() const {
749 SourceLocation Begin = getTemplateKeywordLoc();
750 if (Begin.isValid()) {
751 // Here we have an explicit (partial) specialization or instantiation.
752 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
753 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
754 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
755 if (getExternLoc().isValid())
756 Begin = getExternLoc();
757 SourceLocation End = getBraceRange().getEnd();
759 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
760 return SourceRange(Begin, End);
762 // An implicit instantiation of a class template partial specialization
763 // uses ExplicitInfo to record the TypeAsWritten, but the source
764 // locations should be retrieved from the instantiation pattern.
765 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
766 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
767 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
768 assert(inst_from != nullptr);
769 return inst_from->getSourceRange();
772 // No explicit info available.
773 llvm::PointerUnion<ClassTemplateDecl *,
774 ClassTemplatePartialSpecializationDecl *>
775 inst_from = getInstantiatedFrom();
776 if (inst_from.isNull())
777 return getSpecializedTemplate()->getSourceRange();
778 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
779 return ctd->getSourceRange();
780 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
785 //===----------------------------------------------------------------------===//
786 // ClassTemplatePartialSpecializationDecl Implementation
787 //===----------------------------------------------------------------------===//
788 void ClassTemplatePartialSpecializationDecl::anchor() { }
790 ClassTemplatePartialSpecializationDecl::
791 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
793 SourceLocation StartLoc,
794 SourceLocation IdLoc,
795 TemplateParameterList *Params,
796 ClassTemplateDecl *SpecializedTemplate,
797 ArrayRef<TemplateArgument> Args,
798 const ASTTemplateArgumentListInfo *ArgInfos,
799 ClassTemplatePartialSpecializationDecl *PrevDecl)
800 : ClassTemplateSpecializationDecl(Context,
801 ClassTemplatePartialSpecialization,
802 TK, DC, StartLoc, IdLoc,
805 TemplateParams(Params), ArgsAsWritten(ArgInfos),
806 InstantiatedFromMember(nullptr, false)
808 AdoptTemplateParameterList(Params, this);
811 ClassTemplatePartialSpecializationDecl *
812 ClassTemplatePartialSpecializationDecl::
813 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
814 SourceLocation StartLoc, SourceLocation IdLoc,
815 TemplateParameterList *Params,
816 ClassTemplateDecl *SpecializedTemplate,
817 ArrayRef<TemplateArgument> Args,
818 const TemplateArgumentListInfo &ArgInfos,
819 QualType CanonInjectedType,
820 ClassTemplatePartialSpecializationDecl *PrevDecl) {
821 const ASTTemplateArgumentListInfo *ASTArgInfos =
822 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
824 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
825 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
826 Params, SpecializedTemplate, Args,
827 ASTArgInfos, PrevDecl);
828 Result->setSpecializationKind(TSK_ExplicitSpecialization);
829 Result->MayHaveOutOfDateDef = false;
831 Context.getInjectedClassNameType(Result, CanonInjectedType);
835 ClassTemplatePartialSpecializationDecl *
836 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
838 ClassTemplatePartialSpecializationDecl *Result =
839 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
840 Result->MayHaveOutOfDateDef = false;
844 //===----------------------------------------------------------------------===//
845 // FriendTemplateDecl Implementation
846 //===----------------------------------------------------------------------===//
848 void FriendTemplateDecl::anchor() { }
851 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
853 MutableArrayRef<TemplateParameterList *> Params,
854 FriendUnion Friend, SourceLocation FLoc) {
855 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
858 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
860 return new (C, ID) FriendTemplateDecl(EmptyShell());
863 //===----------------------------------------------------------------------===//
864 // TypeAliasTemplateDecl Implementation
865 //===----------------------------------------------------------------------===//
867 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
870 DeclarationName Name,
871 TemplateParameterList *Params,
873 AdoptTemplateParameterList(Params, DC);
874 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
877 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
879 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
880 DeclarationName(), nullptr, nullptr);
883 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
884 static_cast<Common *>(Ptr)->~Common();
886 RedeclarableTemplateDecl::CommonBase *
887 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
888 Common *CommonPtr = new (C) Common;
889 C.AddDeallocation(DeallocateCommon, CommonPtr);
893 //===----------------------------------------------------------------------===//
894 // ClassScopeFunctionSpecializationDecl Implementation
895 //===----------------------------------------------------------------------===//
897 void ClassScopeFunctionSpecializationDecl::anchor() { }
899 ClassScopeFunctionSpecializationDecl *
900 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
902 return new (C, ID) ClassScopeFunctionSpecializationDecl(
903 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
906 //===----------------------------------------------------------------------===//
907 // VarTemplateDecl Implementation
908 //===----------------------------------------------------------------------===//
910 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
911 static_cast<Common *>(Ptr)->~Common();
914 VarTemplateDecl *VarTemplateDecl::getDefinition() {
915 VarTemplateDecl *CurD = this;
917 if (CurD->isThisDeclarationADefinition())
919 CurD = CurD->getPreviousDecl();
924 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
925 SourceLocation L, DeclarationName Name,
926 TemplateParameterList *Params,
928 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
931 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
933 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
934 DeclarationName(), nullptr, nullptr);
937 // TODO: Unify across class, function and variable templates?
938 // May require moving this and Common to RedeclarableTemplateDecl.
939 void VarTemplateDecl::LoadLazySpecializations() const {
940 // Grab the most recent declaration to ensure we've loaded any lazy
941 // redeclarations of this template.
943 // FIXME: Avoid walking the entire redeclaration chain here.
944 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
945 if (CommonPtr->LazySpecializations) {
946 ASTContext &Context = getASTContext();
947 uint32_t *Specs = CommonPtr->LazySpecializations;
948 CommonPtr->LazySpecializations = nullptr;
949 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
950 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
954 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
955 VarTemplateDecl::getSpecializations() const {
956 LoadLazySpecializations();
957 return getCommonPtr()->Specializations;
960 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
961 VarTemplateDecl::getPartialSpecializations() {
962 LoadLazySpecializations();
963 return getCommonPtr()->PartialSpecializations;
966 RedeclarableTemplateDecl::CommonBase *
967 VarTemplateDecl::newCommon(ASTContext &C) const {
968 Common *CommonPtr = new (C) Common;
969 C.AddDeallocation(DeallocateCommon, CommonPtr);
973 VarTemplateSpecializationDecl *
974 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
976 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
979 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
981 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
984 VarTemplatePartialSpecializationDecl *
985 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
987 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
990 void VarTemplateDecl::AddPartialSpecialization(
991 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
993 getPartialSpecializations().InsertNode(D, InsertPos);
995 VarTemplatePartialSpecializationDecl *Existing =
996 getPartialSpecializations().GetOrInsertNode(D);
998 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1001 if (ASTMutationListener *L = getASTMutationListener())
1002 L->AddedCXXTemplateSpecialization(this, D);
1005 void VarTemplateDecl::getPartialSpecializations(
1006 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1007 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1008 getPartialSpecializations();
1010 PS.reserve(PartialSpecs.size());
1011 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1012 PS.push_back(P.getMostRecentDecl());
1015 VarTemplatePartialSpecializationDecl *
1016 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1017 VarTemplatePartialSpecializationDecl *D) {
1018 Decl *DCanon = D->getCanonicalDecl();
1019 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1020 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1021 return P.getMostRecentDecl();
1027 //===----------------------------------------------------------------------===//
1028 // VarTemplateSpecializationDecl Implementation
1029 //===----------------------------------------------------------------------===//
1030 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1031 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1032 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1033 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1034 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1035 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1036 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1037 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1038 SpecializationKind(TSK_Undeclared) {}
1040 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1042 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1043 QualType(), nullptr, SC_None),
1044 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1046 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1047 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1048 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1049 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1050 return new (Context, DC) VarTemplateSpecializationDecl(
1051 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1052 SpecializedTemplate, T, TInfo, S, Args);
1055 VarTemplateSpecializationDecl *
1056 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1058 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1061 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1062 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1063 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1065 auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1066 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1067 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1068 TemplateSpecializationType::PrintTemplateArgumentList(
1069 OS, ArgsAsWritten->arguments(), Policy);
1071 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1072 TemplateSpecializationType::PrintTemplateArgumentList(
1073 OS, TemplateArgs.asArray(), Policy);
1077 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1078 if (SpecializedPartialSpecialization *PartialSpec =
1079 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1080 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1081 return SpecializedTemplate.get<VarTemplateDecl *>();
1084 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1085 const TemplateArgumentListInfo &ArgsInfo) {
1086 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1087 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1088 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1089 TemplateArgsInfo.addArgument(Loc);
1092 //===----------------------------------------------------------------------===//
1093 // VarTemplatePartialSpecializationDecl Implementation
1094 //===----------------------------------------------------------------------===//
1095 void VarTemplatePartialSpecializationDecl::anchor() {}
1097 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1098 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1099 SourceLocation IdLoc, TemplateParameterList *Params,
1100 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1101 StorageClass S, ArrayRef<TemplateArgument> Args,
1102 const ASTTemplateArgumentListInfo *ArgInfos)
1103 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1104 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1106 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1107 InstantiatedFromMember(nullptr, false) {
1108 // TODO: The template parameters should be in DC by now. Verify.
1109 // AdoptTemplateParameterList(Params, DC);
1112 VarTemplatePartialSpecializationDecl *
1113 VarTemplatePartialSpecializationDecl::Create(
1114 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1115 SourceLocation IdLoc, TemplateParameterList *Params,
1116 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1117 StorageClass S, ArrayRef<TemplateArgument> Args,
1118 const TemplateArgumentListInfo &ArgInfos) {
1119 const ASTTemplateArgumentListInfo *ASTArgInfos
1120 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1122 VarTemplatePartialSpecializationDecl *Result =
1123 new (Context, DC) VarTemplatePartialSpecializationDecl(
1124 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1125 S, Args, ASTArgInfos);
1126 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1130 VarTemplatePartialSpecializationDecl *
1131 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1133 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1136 static TemplateParameterList *
1137 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1139 auto *T = TemplateTypeParmDecl::Create(
1140 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1141 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1142 T->setImplicit(true);
1145 TypeSourceInfo *TI =
1146 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1147 auto *N = NonTypeTemplateParmDecl::Create(
1148 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1149 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1150 N->setImplicit(true);
1152 // <typename T, T ...Ints>
1153 NamedDecl *P[2] = {T, N};
1154 auto *TPL = TemplateParameterList::Create(
1155 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1157 // template <typename T, ...Ints> class IntSeq
1158 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1159 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1160 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1161 TemplateTemplateParm->setImplicit(true);
1164 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1165 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1166 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1167 TemplateTypeParm->setImplicit(true);
1170 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1171 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1172 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1173 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1174 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1175 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1176 NonTypeTemplateParm};
1178 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1179 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1180 Params, SourceLocation(), nullptr);
1183 static TemplateParameterList *
1184 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1185 // std::size_t Index
1186 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1187 auto *Index = NonTypeTemplateParmDecl::Create(
1188 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1189 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1192 auto *Ts = TemplateTypeParmDecl::Create(
1193 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1194 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1195 Ts->setImplicit(true);
1197 // template <std::size_t Index, typename ...T>
1198 NamedDecl *Params[] = {Index, Ts};
1199 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1200 llvm::makeArrayRef(Params),
1201 SourceLocation(), nullptr);
1204 static TemplateParameterList *createBuiltinTemplateParameterList(
1205 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1207 case BTK__make_integer_seq:
1208 return createMakeIntegerSeqParameterList(C, DC);
1209 case BTK__type_pack_element:
1210 return createTypePackElementParameterList(C, DC);
1213 llvm_unreachable("unhandled BuiltinTemplateKind!");
1216 void BuiltinTemplateDecl::anchor() {}
1218 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1219 DeclarationName Name,
1220 BuiltinTemplateKind BTK)
1221 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1222 createBuiltinTemplateParameterList(C, DC, BTK)),