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/DeclarationName.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExternalASTSource.h"
21 #include "clang/AST/TemplateBase.h"
22 #include "clang/AST/TemplateName.h"
23 #include "clang/AST/Type.h"
24 #include "clang/AST/TypeLoc.h"
25 #include "clang/Basic/Builtins.h"
26 #include "clang/Basic/LLVM.h"
27 #include "clang/Basic/SourceLocation.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/FoldingSet.h"
30 #include "llvm/ADT/None.h"
31 #include "llvm/ADT/PointerUnion.h"
32 #include "llvm/ADT/SmallVector.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/ErrorHandling.h"
41 using namespace clang;
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
47 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
48 SourceLocation LAngleLoc,
49 ArrayRef<NamedDecl *> Params,
50 SourceLocation RAngleLoc,
52 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
53 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
54 HasRequiresClause(static_cast<bool>(RequiresClause)) {
55 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
56 NamedDecl *P = Params[Idx];
59 if (!P->isTemplateParameterPack()) {
60 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
61 if (NTTP->getType()->containsUnexpandedParameterPack())
62 ContainsUnexpandedParameterPack = true;
64 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
65 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
66 ContainsUnexpandedParameterPack = true;
68 // FIXME: If a default argument contains an unexpanded parameter pack, the
69 // template parameter list does too.
73 *getTrailingObjects<Expr *>() = RequiresClause;
77 TemplateParameterList *
78 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
79 SourceLocation LAngleLoc,
80 ArrayRef<NamedDecl *> Params,
81 SourceLocation RAngleLoc, Expr *RequiresClause) {
82 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
83 Params.size(), RequiresClause ? 1u : 0u),
84 alignof(TemplateParameterList));
85 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
86 RAngleLoc, RequiresClause);
89 unsigned TemplateParameterList::getMinRequiredArguments() const {
90 unsigned NumRequiredArgs = 0;
91 for (const NamedDecl *P : asArray()) {
92 if (P->isTemplateParameterPack()) {
93 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
94 if (NTTP->isExpandedParameterPack()) {
95 NumRequiredArgs += NTTP->getNumExpansionTypes();
102 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
103 if (TTP->hasDefaultArgument())
105 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
106 if (NTTP->hasDefaultArgument())
108 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
114 return NumRequiredArgs;
117 unsigned TemplateParameterList::getDepth() const {
121 const NamedDecl *FirstParm = getParam(0);
122 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
123 return TTP->getDepth();
124 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
125 return NTTP->getDepth();
127 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
130 static void AdoptTemplateParameterList(TemplateParameterList *Params,
131 DeclContext *Owner) {
132 for (NamedDecl *P : *Params) {
133 P->setDeclContext(Owner);
135 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
136 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
142 void *allocateDefaultArgStorageChain(const ASTContext &C) {
143 return new (C) char[sizeof(void*) * 2];
148 //===----------------------------------------------------------------------===//
149 // RedeclarableTemplateDecl Implementation
150 //===----------------------------------------------------------------------===//
152 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
156 // Walk the previous-declaration chain until we either find a declaration
157 // with a common pointer or we run out of previous declarations.
158 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
159 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
160 Prev = Prev->getPreviousDecl()) {
162 Common = Prev->Common;
166 PrevDecls.push_back(Prev);
169 // If we never found a common pointer, allocate one now.
171 // FIXME: If any of the declarations is from an AST file, we probably
172 // need an update record to add the common data.
174 Common = newCommon(getASTContext());
177 // Update any previous declarations we saw with the common pointer.
178 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
179 Prev->Common = Common;
184 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
185 // Grab the most recent declaration to ensure we've loaded any lazy
186 // redeclarations of this template.
187 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
188 if (CommonBasePtr->LazySpecializations) {
189 ASTContext &Context = getASTContext();
190 uint32_t *Specs = CommonBasePtr->LazySpecializations;
191 CommonBasePtr->LazySpecializations = nullptr;
192 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
193 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
197 template<class EntryType>
198 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
199 RedeclarableTemplateDecl::findSpecializationImpl(
200 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
202 using SETraits = SpecEntryTraits<EntryType>;
204 llvm::FoldingSetNodeID ID;
205 EntryType::Profile(ID, Args, getASTContext());
206 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
207 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
210 template<class Derived, class EntryType>
211 void RedeclarableTemplateDecl::addSpecializationImpl(
212 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
214 using SETraits = SpecEntryTraits<EntryType>;
218 void *CorrectInsertPos;
219 assert(!findSpecializationImpl(Specializations,
220 SETraits::getTemplateArgs(Entry),
222 InsertPos == CorrectInsertPos &&
223 "given incorrect InsertPos for specialization");
225 Specializations.InsertNode(Entry, InsertPos);
227 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
229 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
230 "non-canonical specialization?");
233 if (ASTMutationListener *L = getASTMutationListener())
234 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
235 SETraits::getDecl(Entry));
238 //===----------------------------------------------------------------------===//
239 // FunctionTemplateDecl Implementation
240 //===----------------------------------------------------------------------===//
242 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
245 DeclarationName Name,
246 TemplateParameterList *Params,
248 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
249 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
252 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
254 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
255 DeclarationName(), nullptr, nullptr);
258 RedeclarableTemplateDecl::CommonBase *
259 FunctionTemplateDecl::newCommon(ASTContext &C) const {
260 auto *CommonPtr = new (C) Common;
261 C.addDestruction(CommonPtr);
265 void FunctionTemplateDecl::LoadLazySpecializations() const {
266 loadLazySpecializationsImpl();
269 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
270 FunctionTemplateDecl::getSpecializations() const {
271 LoadLazySpecializations();
272 return getCommonPtr()->Specializations;
276 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
278 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
281 void FunctionTemplateDecl::addSpecialization(
282 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
283 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
287 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
288 TemplateParameterList *Params = getTemplateParameters();
289 Common *CommonPtr = getCommonPtr();
290 if (!CommonPtr->InjectedArgs) {
291 auto &Context = getASTContext();
292 SmallVector<TemplateArgument, 16> TemplateArgs;
293 Context.getInjectedTemplateArgs(Params, TemplateArgs);
294 CommonPtr->InjectedArgs =
295 new (Context) TemplateArgument[TemplateArgs.size()];
296 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
297 CommonPtr->InjectedArgs);
300 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
303 //===----------------------------------------------------------------------===//
304 // ClassTemplateDecl Implementation
305 //===----------------------------------------------------------------------===//
307 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
310 DeclarationName Name,
311 TemplateParameterList *Params,
313 Expr *AssociatedConstraints) {
314 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
316 if (!AssociatedConstraints) {
317 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
320 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
322 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
323 New->setAssociatedConstraints(AssociatedConstraints);
327 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
329 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
330 DeclarationName(), nullptr, nullptr);
333 void ClassTemplateDecl::LoadLazySpecializations() const {
334 loadLazySpecializationsImpl();
337 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
338 ClassTemplateDecl::getSpecializations() const {
339 LoadLazySpecializations();
340 return getCommonPtr()->Specializations;
343 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
344 ClassTemplateDecl::getPartialSpecializations() {
345 LoadLazySpecializations();
346 return getCommonPtr()->PartialSpecializations;
349 RedeclarableTemplateDecl::CommonBase *
350 ClassTemplateDecl::newCommon(ASTContext &C) const {
351 auto *CommonPtr = new (C) Common;
352 C.addDestruction(CommonPtr);
356 ClassTemplateSpecializationDecl *
357 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
359 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
362 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
364 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
367 ClassTemplatePartialSpecializationDecl *
368 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
370 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
373 void ClassTemplateDecl::AddPartialSpecialization(
374 ClassTemplatePartialSpecializationDecl *D,
377 getPartialSpecializations().InsertNode(D, InsertPos);
379 ClassTemplatePartialSpecializationDecl *Existing
380 = getPartialSpecializations().GetOrInsertNode(D);
382 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
385 if (ASTMutationListener *L = getASTMutationListener())
386 L->AddedCXXTemplateSpecialization(this, D);
389 void ClassTemplateDecl::getPartialSpecializations(
390 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
391 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
392 = getPartialSpecializations();
394 PS.reserve(PartialSpecs.size());
395 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
396 PS.push_back(P.getMostRecentDecl());
399 ClassTemplatePartialSpecializationDecl *
400 ClassTemplateDecl::findPartialSpecialization(QualType T) {
401 ASTContext &Context = getASTContext();
402 for (ClassTemplatePartialSpecializationDecl &P :
403 getPartialSpecializations()) {
404 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
405 return P.getMostRecentDecl();
411 ClassTemplatePartialSpecializationDecl *
412 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
413 ClassTemplatePartialSpecializationDecl *D) {
414 Decl *DCanon = D->getCanonicalDecl();
415 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
416 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
417 return P.getMostRecentDecl();
424 ClassTemplateDecl::getInjectedClassNameSpecialization() {
425 Common *CommonPtr = getCommonPtr();
426 if (!CommonPtr->InjectedClassNameType.isNull())
427 return CommonPtr->InjectedClassNameType;
429 // C++0x [temp.dep.type]p2:
430 // The template argument list of a primary template is a template argument
431 // list in which the nth template argument has the value of the nth template
432 // parameter of the class template. If the nth template parameter is a
433 // template parameter pack (14.5.3), the nth template argument is a pack
434 // expansion (14.5.3) whose pattern is the name of the template parameter
436 ASTContext &Context = getASTContext();
437 TemplateParameterList *Params = getTemplateParameters();
438 SmallVector<TemplateArgument, 16> TemplateArgs;
439 Context.getInjectedTemplateArgs(Params, TemplateArgs);
440 CommonPtr->InjectedClassNameType
441 = Context.getTemplateSpecializationType(TemplateName(this),
443 return CommonPtr->InjectedClassNameType;
446 //===----------------------------------------------------------------------===//
447 // TemplateTypeParm Allocation/Deallocation Method Implementations
448 //===----------------------------------------------------------------------===//
450 TemplateTypeParmDecl *
451 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
452 SourceLocation KeyLoc, SourceLocation NameLoc,
453 unsigned D, unsigned P, IdentifierInfo *Id,
454 bool Typename, bool ParameterPack) {
456 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
457 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
458 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
462 TemplateTypeParmDecl *
463 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
464 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
465 SourceLocation(), nullptr, false);
468 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
469 return hasDefaultArgument()
470 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
474 SourceRange TemplateTypeParmDecl::getSourceRange() const {
475 if (hasDefaultArgument() && !defaultArgumentWasInherited())
476 return SourceRange(getLocStart(),
477 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
479 return TypeDecl::getSourceRange();
482 unsigned TemplateTypeParmDecl::getDepth() const {
483 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
486 unsigned TemplateTypeParmDecl::getIndex() const {
487 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
490 bool TemplateTypeParmDecl::isParameterPack() const {
491 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
494 //===----------------------------------------------------------------------===//
495 // NonTypeTemplateParmDecl Method Implementations
496 //===----------------------------------------------------------------------===//
498 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
499 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
500 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
501 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
502 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
503 TemplateParmPosition(D, P), ParameterPack(true),
504 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
505 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
507 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
508 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
509 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
510 TypesAndInfos[I].second = ExpandedTInfos[I];
515 NonTypeTemplateParmDecl *
516 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
517 SourceLocation StartLoc, SourceLocation IdLoc,
518 unsigned D, unsigned P, IdentifierInfo *Id,
519 QualType T, bool ParameterPack,
520 TypeSourceInfo *TInfo) {
521 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
522 T, ParameterPack, TInfo);
525 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
526 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
527 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
528 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
529 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
531 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
532 ExpandedTypes.size()))
533 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
534 ExpandedTypes, ExpandedTInfos);
537 NonTypeTemplateParmDecl *
538 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
539 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
540 SourceLocation(), 0, 0, nullptr,
541 QualType(), false, nullptr);
544 NonTypeTemplateParmDecl *
545 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
546 unsigned NumExpandedTypes) {
548 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
550 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
551 0, 0, nullptr, QualType(), nullptr, None,
553 NTTP->NumExpandedTypes = NumExpandedTypes;
557 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
558 if (hasDefaultArgument() && !defaultArgumentWasInherited())
559 return SourceRange(getOuterLocStart(),
560 getDefaultArgument()->getSourceRange().getEnd());
561 return DeclaratorDecl::getSourceRange();
564 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
565 return hasDefaultArgument()
566 ? getDefaultArgument()->getSourceRange().getBegin()
570 //===----------------------------------------------------------------------===//
571 // TemplateTemplateParmDecl Method Implementations
572 //===----------------------------------------------------------------------===//
574 void TemplateTemplateParmDecl::anchor() {}
576 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
577 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
578 IdentifierInfo *Id, TemplateParameterList *Params,
579 ArrayRef<TemplateParameterList *> Expansions)
580 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
581 TemplateParmPosition(D, P), ParameterPack(true),
582 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
583 if (!Expansions.empty())
584 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
585 getTrailingObjects<TemplateParameterList *>());
588 TemplateTemplateParmDecl *
589 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
590 SourceLocation L, unsigned D, unsigned P,
591 bool ParameterPack, IdentifierInfo *Id,
592 TemplateParameterList *Params) {
593 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
597 TemplateTemplateParmDecl *
598 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
599 SourceLocation L, unsigned D, unsigned P,
601 TemplateParameterList *Params,
602 ArrayRef<TemplateParameterList *> Expansions) {
604 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
605 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
608 TemplateTemplateParmDecl *
609 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
610 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
611 false, nullptr, nullptr);
614 TemplateTemplateParmDecl *
615 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
616 unsigned NumExpansions) {
618 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
619 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
621 TTP->NumExpandedParams = NumExpansions;
625 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
626 return hasDefaultArgument() ? getDefaultArgument().getLocation()
630 void TemplateTemplateParmDecl::setDefaultArgument(
631 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
632 if (DefArg.getArgument().isNull())
633 DefaultArgument.set(nullptr);
635 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
638 //===----------------------------------------------------------------------===//
639 // TemplateArgumentList Implementation
640 //===----------------------------------------------------------------------===//
641 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
642 : Arguments(getTrailingObjects<TemplateArgument>()),
643 NumArguments(Args.size()) {
644 std::uninitialized_copy(Args.begin(), Args.end(),
645 getTrailingObjects<TemplateArgument>());
648 TemplateArgumentList *
649 TemplateArgumentList::CreateCopy(ASTContext &Context,
650 ArrayRef<TemplateArgument> Args) {
651 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
652 return new (Mem) TemplateArgumentList(Args);
655 FunctionTemplateSpecializationInfo *
656 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
657 FunctionTemplateDecl *Template,
658 TemplateSpecializationKind TSK,
659 const TemplateArgumentList *TemplateArgs,
660 const TemplateArgumentListInfo *TemplateArgsAsWritten,
661 SourceLocation POI) {
662 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
663 if (TemplateArgsAsWritten)
664 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
665 *TemplateArgsAsWritten);
667 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
673 //===----------------------------------------------------------------------===//
674 // TemplateDecl Implementation
675 //===----------------------------------------------------------------------===//
677 void TemplateDecl::anchor() {}
679 //===----------------------------------------------------------------------===//
680 // ClassTemplateSpecializationDecl Implementation
681 //===----------------------------------------------------------------------===//
683 ClassTemplateSpecializationDecl::
684 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
685 DeclContext *DC, SourceLocation StartLoc,
686 SourceLocation IdLoc,
687 ClassTemplateDecl *SpecializedTemplate,
688 ArrayRef<TemplateArgument> Args,
689 ClassTemplateSpecializationDecl *PrevDecl)
690 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
691 SpecializedTemplate->getIdentifier(), PrevDecl),
692 SpecializedTemplate(SpecializedTemplate),
693 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
694 SpecializationKind(TSK_Undeclared) {
697 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
699 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
700 SourceLocation(), nullptr, nullptr),
701 SpecializationKind(TSK_Undeclared) {}
703 ClassTemplateSpecializationDecl *
704 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
706 SourceLocation StartLoc,
707 SourceLocation IdLoc,
708 ClassTemplateDecl *SpecializedTemplate,
709 ArrayRef<TemplateArgument> Args,
710 ClassTemplateSpecializationDecl *PrevDecl) {
712 new (Context, DC) ClassTemplateSpecializationDecl(
713 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
714 SpecializedTemplate, Args, PrevDecl);
715 Result->MayHaveOutOfDateDef = false;
717 Context.getTypeDeclType(Result, PrevDecl);
721 ClassTemplateSpecializationDecl *
722 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
725 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
726 Result->MayHaveOutOfDateDef = false;
730 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
731 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
732 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
734 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
735 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
736 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
737 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
739 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
740 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
745 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
746 if (const auto *PartialSpec =
747 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
748 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
749 return SpecializedTemplate.get<ClassTemplateDecl*>();
753 ClassTemplateSpecializationDecl::getSourceRange() const {
755 SourceLocation Begin = getTemplateKeywordLoc();
756 if (Begin.isValid()) {
757 // Here we have an explicit (partial) specialization or instantiation.
758 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
759 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
760 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
761 if (getExternLoc().isValid())
762 Begin = getExternLoc();
763 SourceLocation End = getBraceRange().getEnd();
765 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
766 return SourceRange(Begin, End);
768 // An implicit instantiation of a class template partial specialization
769 // uses ExplicitInfo to record the TypeAsWritten, but the source
770 // locations should be retrieved from the instantiation pattern.
771 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
772 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
773 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
774 assert(inst_from != nullptr);
775 return inst_from->getSourceRange();
778 // No explicit info available.
779 llvm::PointerUnion<ClassTemplateDecl *,
780 ClassTemplatePartialSpecializationDecl *>
781 inst_from = getInstantiatedFrom();
782 if (inst_from.isNull())
783 return getSpecializedTemplate()->getSourceRange();
784 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
785 return ctd->getSourceRange();
786 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
791 //===----------------------------------------------------------------------===//
792 // ClassTemplatePartialSpecializationDecl Implementation
793 //===----------------------------------------------------------------------===//
794 void ClassTemplatePartialSpecializationDecl::anchor() {}
796 ClassTemplatePartialSpecializationDecl::
797 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
799 SourceLocation StartLoc,
800 SourceLocation IdLoc,
801 TemplateParameterList *Params,
802 ClassTemplateDecl *SpecializedTemplate,
803 ArrayRef<TemplateArgument> Args,
804 const ASTTemplateArgumentListInfo *ArgInfos,
805 ClassTemplatePartialSpecializationDecl *PrevDecl)
806 : ClassTemplateSpecializationDecl(Context,
807 ClassTemplatePartialSpecialization,
808 TK, DC, StartLoc, IdLoc,
809 SpecializedTemplate, Args, PrevDecl),
810 TemplateParams(Params), ArgsAsWritten(ArgInfos),
811 InstantiatedFromMember(nullptr, false) {
812 AdoptTemplateParameterList(Params, this);
815 ClassTemplatePartialSpecializationDecl *
816 ClassTemplatePartialSpecializationDecl::
817 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
818 SourceLocation StartLoc, SourceLocation IdLoc,
819 TemplateParameterList *Params,
820 ClassTemplateDecl *SpecializedTemplate,
821 ArrayRef<TemplateArgument> Args,
822 const TemplateArgumentListInfo &ArgInfos,
823 QualType CanonInjectedType,
824 ClassTemplatePartialSpecializationDecl *PrevDecl) {
825 const ASTTemplateArgumentListInfo *ASTArgInfos =
826 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
828 auto *Result = new (Context, DC)
829 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
830 Params, SpecializedTemplate, Args,
831 ASTArgInfos, PrevDecl);
832 Result->setSpecializationKind(TSK_ExplicitSpecialization);
833 Result->MayHaveOutOfDateDef = false;
835 Context.getInjectedClassNameType(Result, CanonInjectedType);
839 ClassTemplatePartialSpecializationDecl *
840 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
842 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
843 Result->MayHaveOutOfDateDef = false;
847 //===----------------------------------------------------------------------===//
848 // FriendTemplateDecl Implementation
849 //===----------------------------------------------------------------------===//
851 void FriendTemplateDecl::anchor() {}
854 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
856 MutableArrayRef<TemplateParameterList *> Params,
857 FriendUnion Friend, SourceLocation FLoc) {
858 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
861 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
863 return new (C, ID) FriendTemplateDecl(EmptyShell());
866 //===----------------------------------------------------------------------===//
867 // TypeAliasTemplateDecl Implementation
868 //===----------------------------------------------------------------------===//
870 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
873 DeclarationName Name,
874 TemplateParameterList *Params,
876 AdoptTemplateParameterList(Params, DC);
877 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
880 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
882 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
883 DeclarationName(), nullptr, nullptr);
886 RedeclarableTemplateDecl::CommonBase *
887 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
888 auto *CommonPtr = new (C) Common;
889 C.addDestruction(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 VarTemplateDecl *VarTemplateDecl::getDefinition() {
911 VarTemplateDecl *CurD = this;
913 if (CurD->isThisDeclarationADefinition())
915 CurD = CurD->getPreviousDecl();
920 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
921 SourceLocation L, DeclarationName Name,
922 TemplateParameterList *Params,
924 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
927 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
929 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
930 DeclarationName(), nullptr, nullptr);
933 void VarTemplateDecl::LoadLazySpecializations() const {
934 loadLazySpecializationsImpl();
937 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
938 VarTemplateDecl::getSpecializations() const {
939 LoadLazySpecializations();
940 return getCommonPtr()->Specializations;
943 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
944 VarTemplateDecl::getPartialSpecializations() {
945 LoadLazySpecializations();
946 return getCommonPtr()->PartialSpecializations;
949 RedeclarableTemplateDecl::CommonBase *
950 VarTemplateDecl::newCommon(ASTContext &C) const {
951 auto *CommonPtr = new (C) Common;
952 C.addDestruction(CommonPtr);
956 VarTemplateSpecializationDecl *
957 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
959 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
962 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
964 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
967 VarTemplatePartialSpecializationDecl *
968 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
970 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
973 void VarTemplateDecl::AddPartialSpecialization(
974 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
976 getPartialSpecializations().InsertNode(D, InsertPos);
978 VarTemplatePartialSpecializationDecl *Existing =
979 getPartialSpecializations().GetOrInsertNode(D);
981 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
984 if (ASTMutationListener *L = getASTMutationListener())
985 L->AddedCXXTemplateSpecialization(this, D);
988 void VarTemplateDecl::getPartialSpecializations(
989 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
990 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
991 getPartialSpecializations();
993 PS.reserve(PartialSpecs.size());
994 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
995 PS.push_back(P.getMostRecentDecl());
998 VarTemplatePartialSpecializationDecl *
999 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1000 VarTemplatePartialSpecializationDecl *D) {
1001 Decl *DCanon = D->getCanonicalDecl();
1002 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1003 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1004 return P.getMostRecentDecl();
1010 //===----------------------------------------------------------------------===//
1011 // VarTemplateSpecializationDecl Implementation
1012 //===----------------------------------------------------------------------===//
1014 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1015 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1016 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1017 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1018 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1019 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1020 SpecializedTemplate(SpecializedTemplate),
1021 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1022 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1024 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1026 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1027 QualType(), nullptr, SC_None),
1028 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1030 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1031 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1032 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1033 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1034 return new (Context, DC) VarTemplateSpecializationDecl(
1035 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1036 SpecializedTemplate, T, TInfo, S, Args);
1039 VarTemplateSpecializationDecl *
1040 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1042 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1045 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1046 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1047 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1049 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1050 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1051 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1052 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1054 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1055 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1059 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1060 if (const auto *PartialSpec =
1061 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1062 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1063 return SpecializedTemplate.get<VarTemplateDecl *>();
1066 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1067 const TemplateArgumentListInfo &ArgsInfo) {
1068 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1069 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1070 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1071 TemplateArgsInfo.addArgument(Loc);
1074 //===----------------------------------------------------------------------===//
1075 // VarTemplatePartialSpecializationDecl Implementation
1076 //===----------------------------------------------------------------------===//
1078 void VarTemplatePartialSpecializationDecl::anchor() {}
1080 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1081 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1082 SourceLocation IdLoc, TemplateParameterList *Params,
1083 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1084 StorageClass S, ArrayRef<TemplateArgument> Args,
1085 const ASTTemplateArgumentListInfo *ArgInfos)
1086 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1087 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1089 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1090 InstantiatedFromMember(nullptr, false) {
1091 // TODO: The template parameters should be in DC by now. Verify.
1092 // AdoptTemplateParameterList(Params, DC);
1095 VarTemplatePartialSpecializationDecl *
1096 VarTemplatePartialSpecializationDecl::Create(
1097 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1098 SourceLocation IdLoc, TemplateParameterList *Params,
1099 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1100 StorageClass S, ArrayRef<TemplateArgument> Args,
1101 const TemplateArgumentListInfo &ArgInfos) {
1102 const ASTTemplateArgumentListInfo *ASTArgInfos
1103 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1106 new (Context, DC) VarTemplatePartialSpecializationDecl(
1107 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1108 S, Args, ASTArgInfos);
1109 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1113 VarTemplatePartialSpecializationDecl *
1114 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1116 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1119 static TemplateParameterList *
1120 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1122 auto *T = TemplateTypeParmDecl::Create(
1123 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1124 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1125 T->setImplicit(true);
1128 TypeSourceInfo *TI =
1129 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1130 auto *N = NonTypeTemplateParmDecl::Create(
1131 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1132 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1133 N->setImplicit(true);
1135 // <typename T, T ...Ints>
1136 NamedDecl *P[2] = {T, N};
1137 auto *TPL = TemplateParameterList::Create(
1138 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1140 // template <typename T, ...Ints> class IntSeq
1141 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1142 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1143 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1144 TemplateTemplateParm->setImplicit(true);
1147 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1148 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1149 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1150 TemplateTypeParm->setImplicit(true);
1153 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1154 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1155 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1156 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1157 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1158 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1159 NonTypeTemplateParm};
1161 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1162 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1163 Params, SourceLocation(), nullptr);
1166 static TemplateParameterList *
1167 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1168 // std::size_t Index
1169 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1170 auto *Index = NonTypeTemplateParmDecl::Create(
1171 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1172 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1175 auto *Ts = TemplateTypeParmDecl::Create(
1176 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1177 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1178 Ts->setImplicit(true);
1180 // template <std::size_t Index, typename ...T>
1181 NamedDecl *Params[] = {Index, Ts};
1182 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1183 llvm::makeArrayRef(Params),
1184 SourceLocation(), nullptr);
1187 static TemplateParameterList *createBuiltinTemplateParameterList(
1188 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1190 case BTK__make_integer_seq:
1191 return createMakeIntegerSeqParameterList(C, DC);
1192 case BTK__type_pack_element:
1193 return createTypePackElementParameterList(C, DC);
1196 llvm_unreachable("unhandled BuiltinTemplateKind!");
1199 void BuiltinTemplateDecl::anchor() {}
1201 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1202 DeclarationName Name,
1203 BuiltinTemplateKind BTK)
1204 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1205 createBuiltinTemplateParameterList(C, DC, BTK)),