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 void RedeclarableTemplateDecl::anchor() {}
154 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
158 // Walk the previous-declaration chain until we either find a declaration
159 // with a common pointer or we run out of previous declarations.
160 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
161 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
162 Prev = Prev->getPreviousDecl()) {
164 Common = Prev->Common;
168 PrevDecls.push_back(Prev);
171 // If we never found a common pointer, allocate one now.
173 // FIXME: If any of the declarations is from an AST file, we probably
174 // need an update record to add the common data.
176 Common = newCommon(getASTContext());
179 // Update any previous declarations we saw with the common pointer.
180 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
181 Prev->Common = Common;
186 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
187 // Grab the most recent declaration to ensure we've loaded any lazy
188 // redeclarations of this template.
189 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
190 if (CommonBasePtr->LazySpecializations) {
191 ASTContext &Context = getASTContext();
192 uint32_t *Specs = CommonBasePtr->LazySpecializations;
193 CommonBasePtr->LazySpecializations = nullptr;
194 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
195 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
199 template<class EntryType>
200 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
201 RedeclarableTemplateDecl::findSpecializationImpl(
202 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
204 using SETraits = SpecEntryTraits<EntryType>;
206 llvm::FoldingSetNodeID ID;
207 EntryType::Profile(ID, Args, getASTContext());
208 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
209 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
212 template<class Derived, class EntryType>
213 void RedeclarableTemplateDecl::addSpecializationImpl(
214 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
216 using SETraits = SpecEntryTraits<EntryType>;
220 void *CorrectInsertPos;
221 assert(!findSpecializationImpl(Specializations,
222 SETraits::getTemplateArgs(Entry),
224 InsertPos == CorrectInsertPos &&
225 "given incorrect InsertPos for specialization");
227 Specializations.InsertNode(Entry, InsertPos);
229 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
231 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
232 "non-canonical specialization?");
235 if (ASTMutationListener *L = getASTMutationListener())
236 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
237 SETraits::getDecl(Entry));
240 //===----------------------------------------------------------------------===//
241 // FunctionTemplateDecl Implementation
242 //===----------------------------------------------------------------------===//
244 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
247 DeclarationName Name,
248 TemplateParameterList *Params,
250 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
251 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
254 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
256 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
257 DeclarationName(), nullptr, nullptr);
260 RedeclarableTemplateDecl::CommonBase *
261 FunctionTemplateDecl::newCommon(ASTContext &C) const {
262 auto *CommonPtr = new (C) Common;
263 C.addDestruction(CommonPtr);
267 void FunctionTemplateDecl::LoadLazySpecializations() const {
268 loadLazySpecializationsImpl();
271 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
272 FunctionTemplateDecl::getSpecializations() const {
273 LoadLazySpecializations();
274 return getCommonPtr()->Specializations;
278 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
280 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
283 void FunctionTemplateDecl::addSpecialization(
284 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
285 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
289 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
290 TemplateParameterList *Params = getTemplateParameters();
291 Common *CommonPtr = getCommonPtr();
292 if (!CommonPtr->InjectedArgs) {
293 auto &Context = getASTContext();
294 SmallVector<TemplateArgument, 16> TemplateArgs;
295 Context.getInjectedTemplateArgs(Params, TemplateArgs);
296 CommonPtr->InjectedArgs =
297 new (Context) TemplateArgument[TemplateArgs.size()];
298 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
299 CommonPtr->InjectedArgs);
302 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
305 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
306 using Base = RedeclarableTemplateDecl;
308 // If we haven't created a common pointer yet, then it can just be created
309 // with the usual method.
313 Common *ThisCommon = static_cast<Common *>(Base::Common);
314 Common *PrevCommon = nullptr;
315 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
316 for (; Prev; Prev = Prev->getPreviousDecl()) {
317 if (Prev->Base::Common) {
318 PrevCommon = static_cast<Common *>(Prev->Base::Common);
321 PreviousDecls.push_back(Prev);
324 // If the previous redecl chain hasn't created a common pointer yet, then just
325 // use this common pointer.
327 for (auto *D : PreviousDecls)
328 D->Base::Common = ThisCommon;
332 // Ensure we don't leak any important state.
333 assert(ThisCommon->Specializations.size() == 0 &&
334 "Can't merge incompatible declarations!");
336 Base::Common = PrevCommon;
339 //===----------------------------------------------------------------------===//
340 // ClassTemplateDecl Implementation
341 //===----------------------------------------------------------------------===//
343 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
346 DeclarationName Name,
347 TemplateParameterList *Params,
349 Expr *AssociatedConstraints) {
350 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
352 if (!AssociatedConstraints) {
353 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
356 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
358 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
359 New->setAssociatedConstraints(AssociatedConstraints);
363 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
365 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
366 DeclarationName(), nullptr, nullptr);
369 void ClassTemplateDecl::LoadLazySpecializations() const {
370 loadLazySpecializationsImpl();
373 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
374 ClassTemplateDecl::getSpecializations() const {
375 LoadLazySpecializations();
376 return getCommonPtr()->Specializations;
379 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
380 ClassTemplateDecl::getPartialSpecializations() {
381 LoadLazySpecializations();
382 return getCommonPtr()->PartialSpecializations;
385 RedeclarableTemplateDecl::CommonBase *
386 ClassTemplateDecl::newCommon(ASTContext &C) const {
387 auto *CommonPtr = new (C) Common;
388 C.addDestruction(CommonPtr);
392 ClassTemplateSpecializationDecl *
393 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
395 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
398 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
400 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
403 ClassTemplatePartialSpecializationDecl *
404 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
406 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
409 void ClassTemplateDecl::AddPartialSpecialization(
410 ClassTemplatePartialSpecializationDecl *D,
413 getPartialSpecializations().InsertNode(D, InsertPos);
415 ClassTemplatePartialSpecializationDecl *Existing
416 = getPartialSpecializations().GetOrInsertNode(D);
418 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
421 if (ASTMutationListener *L = getASTMutationListener())
422 L->AddedCXXTemplateSpecialization(this, D);
425 void ClassTemplateDecl::getPartialSpecializations(
426 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
427 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
428 = getPartialSpecializations();
430 PS.reserve(PartialSpecs.size());
431 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
432 PS.push_back(P.getMostRecentDecl());
435 ClassTemplatePartialSpecializationDecl *
436 ClassTemplateDecl::findPartialSpecialization(QualType T) {
437 ASTContext &Context = getASTContext();
438 for (ClassTemplatePartialSpecializationDecl &P :
439 getPartialSpecializations()) {
440 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
441 return P.getMostRecentDecl();
447 ClassTemplatePartialSpecializationDecl *
448 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
449 ClassTemplatePartialSpecializationDecl *D) {
450 Decl *DCanon = D->getCanonicalDecl();
451 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
452 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
453 return P.getMostRecentDecl();
460 ClassTemplateDecl::getInjectedClassNameSpecialization() {
461 Common *CommonPtr = getCommonPtr();
462 if (!CommonPtr->InjectedClassNameType.isNull())
463 return CommonPtr->InjectedClassNameType;
465 // C++0x [temp.dep.type]p2:
466 // The template argument list of a primary template is a template argument
467 // list in which the nth template argument has the value of the nth template
468 // parameter of the class template. If the nth template parameter is a
469 // template parameter pack (14.5.3), the nth template argument is a pack
470 // expansion (14.5.3) whose pattern is the name of the template parameter
472 ASTContext &Context = getASTContext();
473 TemplateParameterList *Params = getTemplateParameters();
474 SmallVector<TemplateArgument, 16> TemplateArgs;
475 Context.getInjectedTemplateArgs(Params, TemplateArgs);
476 CommonPtr->InjectedClassNameType
477 = Context.getTemplateSpecializationType(TemplateName(this),
479 return CommonPtr->InjectedClassNameType;
482 //===----------------------------------------------------------------------===//
483 // TemplateTypeParm Allocation/Deallocation Method Implementations
484 //===----------------------------------------------------------------------===//
486 TemplateTypeParmDecl *
487 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
488 SourceLocation KeyLoc, SourceLocation NameLoc,
489 unsigned D, unsigned P, IdentifierInfo *Id,
490 bool Typename, bool ParameterPack) {
492 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
493 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
494 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
498 TemplateTypeParmDecl *
499 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
500 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
501 SourceLocation(), nullptr, false);
504 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
505 return hasDefaultArgument()
506 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
510 SourceRange TemplateTypeParmDecl::getSourceRange() const {
511 if (hasDefaultArgument() && !defaultArgumentWasInherited())
512 return SourceRange(getBeginLoc(),
513 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
515 return TypeDecl::getSourceRange();
518 unsigned TemplateTypeParmDecl::getDepth() const {
519 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
522 unsigned TemplateTypeParmDecl::getIndex() const {
523 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
526 bool TemplateTypeParmDecl::isParameterPack() const {
527 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
530 //===----------------------------------------------------------------------===//
531 // NonTypeTemplateParmDecl Method Implementations
532 //===----------------------------------------------------------------------===//
534 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
535 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
536 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
537 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
538 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
539 TemplateParmPosition(D, P), ParameterPack(true),
540 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
541 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
543 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
544 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
545 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
546 TypesAndInfos[I].second = ExpandedTInfos[I];
551 NonTypeTemplateParmDecl *
552 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
553 SourceLocation StartLoc, SourceLocation IdLoc,
554 unsigned D, unsigned P, IdentifierInfo *Id,
555 QualType T, bool ParameterPack,
556 TypeSourceInfo *TInfo) {
557 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
558 T, ParameterPack, TInfo);
561 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
562 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
563 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
564 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
565 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
567 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
568 ExpandedTypes.size()))
569 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
570 ExpandedTypes, ExpandedTInfos);
573 NonTypeTemplateParmDecl *
574 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
575 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
576 SourceLocation(), 0, 0, nullptr,
577 QualType(), false, nullptr);
580 NonTypeTemplateParmDecl *
581 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
582 unsigned NumExpandedTypes) {
584 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
586 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
587 0, 0, nullptr, QualType(), nullptr, None,
589 NTTP->NumExpandedTypes = NumExpandedTypes;
593 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
594 if (hasDefaultArgument() && !defaultArgumentWasInherited())
595 return SourceRange(getOuterLocStart(),
596 getDefaultArgument()->getSourceRange().getEnd());
597 return DeclaratorDecl::getSourceRange();
600 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
601 return hasDefaultArgument()
602 ? getDefaultArgument()->getSourceRange().getBegin()
606 //===----------------------------------------------------------------------===//
607 // TemplateTemplateParmDecl Method Implementations
608 //===----------------------------------------------------------------------===//
610 void TemplateTemplateParmDecl::anchor() {}
612 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
613 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
614 IdentifierInfo *Id, TemplateParameterList *Params,
615 ArrayRef<TemplateParameterList *> Expansions)
616 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
617 TemplateParmPosition(D, P), ParameterPack(true),
618 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
619 if (!Expansions.empty())
620 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
621 getTrailingObjects<TemplateParameterList *>());
624 TemplateTemplateParmDecl *
625 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
626 SourceLocation L, unsigned D, unsigned P,
627 bool ParameterPack, IdentifierInfo *Id,
628 TemplateParameterList *Params) {
629 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
633 TemplateTemplateParmDecl *
634 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
635 SourceLocation L, unsigned D, unsigned P,
637 TemplateParameterList *Params,
638 ArrayRef<TemplateParameterList *> Expansions) {
640 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
641 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
644 TemplateTemplateParmDecl *
645 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
646 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
647 false, nullptr, nullptr);
650 TemplateTemplateParmDecl *
651 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
652 unsigned NumExpansions) {
654 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
655 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
657 TTP->NumExpandedParams = NumExpansions;
661 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
662 return hasDefaultArgument() ? getDefaultArgument().getLocation()
666 void TemplateTemplateParmDecl::setDefaultArgument(
667 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
668 if (DefArg.getArgument().isNull())
669 DefaultArgument.set(nullptr);
671 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
674 //===----------------------------------------------------------------------===//
675 // TemplateArgumentList Implementation
676 //===----------------------------------------------------------------------===//
677 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
678 : Arguments(getTrailingObjects<TemplateArgument>()),
679 NumArguments(Args.size()) {
680 std::uninitialized_copy(Args.begin(), Args.end(),
681 getTrailingObjects<TemplateArgument>());
684 TemplateArgumentList *
685 TemplateArgumentList::CreateCopy(ASTContext &Context,
686 ArrayRef<TemplateArgument> Args) {
687 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
688 return new (Mem) TemplateArgumentList(Args);
691 FunctionTemplateSpecializationInfo *
692 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
693 FunctionTemplateDecl *Template,
694 TemplateSpecializationKind TSK,
695 const TemplateArgumentList *TemplateArgs,
696 const TemplateArgumentListInfo *TemplateArgsAsWritten,
697 SourceLocation POI) {
698 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
699 if (TemplateArgsAsWritten)
700 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
701 *TemplateArgsAsWritten);
703 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
709 //===----------------------------------------------------------------------===//
710 // TemplateDecl Implementation
711 //===----------------------------------------------------------------------===//
713 void TemplateDecl::anchor() {}
715 //===----------------------------------------------------------------------===//
716 // ClassTemplateSpecializationDecl Implementation
717 //===----------------------------------------------------------------------===//
719 ClassTemplateSpecializationDecl::
720 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
721 DeclContext *DC, SourceLocation StartLoc,
722 SourceLocation IdLoc,
723 ClassTemplateDecl *SpecializedTemplate,
724 ArrayRef<TemplateArgument> Args,
725 ClassTemplateSpecializationDecl *PrevDecl)
726 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
727 SpecializedTemplate->getIdentifier(), PrevDecl),
728 SpecializedTemplate(SpecializedTemplate),
729 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
730 SpecializationKind(TSK_Undeclared) {
733 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
735 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
736 SourceLocation(), nullptr, nullptr),
737 SpecializationKind(TSK_Undeclared) {}
739 ClassTemplateSpecializationDecl *
740 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
742 SourceLocation StartLoc,
743 SourceLocation IdLoc,
744 ClassTemplateDecl *SpecializedTemplate,
745 ArrayRef<TemplateArgument> Args,
746 ClassTemplateSpecializationDecl *PrevDecl) {
748 new (Context, DC) ClassTemplateSpecializationDecl(
749 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
750 SpecializedTemplate, Args, PrevDecl);
751 Result->setMayHaveOutOfDateDef(false);
753 Context.getTypeDeclType(Result, PrevDecl);
757 ClassTemplateSpecializationDecl *
758 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
761 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
762 Result->setMayHaveOutOfDateDef(false);
766 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
767 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
768 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
770 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
771 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
772 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
773 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
775 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
776 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
781 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
782 if (const auto *PartialSpec =
783 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
784 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
785 return SpecializedTemplate.get<ClassTemplateDecl*>();
789 ClassTemplateSpecializationDecl::getSourceRange() const {
791 SourceLocation Begin = getTemplateKeywordLoc();
792 if (Begin.isValid()) {
793 // Here we have an explicit (partial) specialization or instantiation.
794 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
795 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
796 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
797 if (getExternLoc().isValid())
798 Begin = getExternLoc();
799 SourceLocation End = getBraceRange().getEnd();
801 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
802 return SourceRange(Begin, End);
804 // An implicit instantiation of a class template partial specialization
805 // uses ExplicitInfo to record the TypeAsWritten, but the source
806 // locations should be retrieved from the instantiation pattern.
807 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
808 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
809 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
810 assert(inst_from != nullptr);
811 return inst_from->getSourceRange();
814 // No explicit info available.
815 llvm::PointerUnion<ClassTemplateDecl *,
816 ClassTemplatePartialSpecializationDecl *>
817 inst_from = getInstantiatedFrom();
818 if (inst_from.isNull())
819 return getSpecializedTemplate()->getSourceRange();
820 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
821 return ctd->getSourceRange();
822 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
827 //===----------------------------------------------------------------------===//
828 // ClassTemplatePartialSpecializationDecl Implementation
829 //===----------------------------------------------------------------------===//
830 void ClassTemplatePartialSpecializationDecl::anchor() {}
832 ClassTemplatePartialSpecializationDecl::
833 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
835 SourceLocation StartLoc,
836 SourceLocation IdLoc,
837 TemplateParameterList *Params,
838 ClassTemplateDecl *SpecializedTemplate,
839 ArrayRef<TemplateArgument> Args,
840 const ASTTemplateArgumentListInfo *ArgInfos,
841 ClassTemplatePartialSpecializationDecl *PrevDecl)
842 : ClassTemplateSpecializationDecl(Context,
843 ClassTemplatePartialSpecialization,
844 TK, DC, StartLoc, IdLoc,
845 SpecializedTemplate, Args, PrevDecl),
846 TemplateParams(Params), ArgsAsWritten(ArgInfos),
847 InstantiatedFromMember(nullptr, false) {
848 AdoptTemplateParameterList(Params, this);
851 ClassTemplatePartialSpecializationDecl *
852 ClassTemplatePartialSpecializationDecl::
853 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
854 SourceLocation StartLoc, SourceLocation IdLoc,
855 TemplateParameterList *Params,
856 ClassTemplateDecl *SpecializedTemplate,
857 ArrayRef<TemplateArgument> Args,
858 const TemplateArgumentListInfo &ArgInfos,
859 QualType CanonInjectedType,
860 ClassTemplatePartialSpecializationDecl *PrevDecl) {
861 const ASTTemplateArgumentListInfo *ASTArgInfos =
862 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
864 auto *Result = new (Context, DC)
865 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
866 Params, SpecializedTemplate, Args,
867 ASTArgInfos, PrevDecl);
868 Result->setSpecializationKind(TSK_ExplicitSpecialization);
869 Result->setMayHaveOutOfDateDef(false);
871 Context.getInjectedClassNameType(Result, CanonInjectedType);
875 ClassTemplatePartialSpecializationDecl *
876 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
878 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
879 Result->setMayHaveOutOfDateDef(false);
883 //===----------------------------------------------------------------------===//
884 // FriendTemplateDecl Implementation
885 //===----------------------------------------------------------------------===//
887 void FriendTemplateDecl::anchor() {}
890 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
892 MutableArrayRef<TemplateParameterList *> Params,
893 FriendUnion Friend, SourceLocation FLoc) {
894 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
897 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
899 return new (C, ID) FriendTemplateDecl(EmptyShell());
902 //===----------------------------------------------------------------------===//
903 // TypeAliasTemplateDecl Implementation
904 //===----------------------------------------------------------------------===//
906 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
909 DeclarationName Name,
910 TemplateParameterList *Params,
912 AdoptTemplateParameterList(Params, DC);
913 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
916 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
918 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
919 DeclarationName(), nullptr, nullptr);
922 RedeclarableTemplateDecl::CommonBase *
923 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
924 auto *CommonPtr = new (C) Common;
925 C.addDestruction(CommonPtr);
929 //===----------------------------------------------------------------------===//
930 // ClassScopeFunctionSpecializationDecl Implementation
931 //===----------------------------------------------------------------------===//
933 void ClassScopeFunctionSpecializationDecl::anchor() {}
935 ClassScopeFunctionSpecializationDecl *
936 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
938 return new (C, ID) ClassScopeFunctionSpecializationDecl(
939 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
942 //===----------------------------------------------------------------------===//
943 // VarTemplateDecl Implementation
944 //===----------------------------------------------------------------------===//
946 VarTemplateDecl *VarTemplateDecl::getDefinition() {
947 VarTemplateDecl *CurD = this;
949 if (CurD->isThisDeclarationADefinition())
951 CurD = CurD->getPreviousDecl();
956 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
957 SourceLocation L, DeclarationName Name,
958 TemplateParameterList *Params,
960 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
963 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
965 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
966 DeclarationName(), nullptr, nullptr);
969 void VarTemplateDecl::LoadLazySpecializations() const {
970 loadLazySpecializationsImpl();
973 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
974 VarTemplateDecl::getSpecializations() const {
975 LoadLazySpecializations();
976 return getCommonPtr()->Specializations;
979 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
980 VarTemplateDecl::getPartialSpecializations() {
981 LoadLazySpecializations();
982 return getCommonPtr()->PartialSpecializations;
985 RedeclarableTemplateDecl::CommonBase *
986 VarTemplateDecl::newCommon(ASTContext &C) const {
987 auto *CommonPtr = new (C) Common;
988 C.addDestruction(CommonPtr);
992 VarTemplateSpecializationDecl *
993 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
995 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
998 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1000 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1003 VarTemplatePartialSpecializationDecl *
1004 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1006 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1009 void VarTemplateDecl::AddPartialSpecialization(
1010 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1012 getPartialSpecializations().InsertNode(D, InsertPos);
1014 VarTemplatePartialSpecializationDecl *Existing =
1015 getPartialSpecializations().GetOrInsertNode(D);
1017 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1020 if (ASTMutationListener *L = getASTMutationListener())
1021 L->AddedCXXTemplateSpecialization(this, D);
1024 void VarTemplateDecl::getPartialSpecializations(
1025 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1026 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1027 getPartialSpecializations();
1029 PS.reserve(PartialSpecs.size());
1030 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1031 PS.push_back(P.getMostRecentDecl());
1034 VarTemplatePartialSpecializationDecl *
1035 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1036 VarTemplatePartialSpecializationDecl *D) {
1037 Decl *DCanon = D->getCanonicalDecl();
1038 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1039 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1040 return P.getMostRecentDecl();
1046 //===----------------------------------------------------------------------===//
1047 // VarTemplateSpecializationDecl Implementation
1048 //===----------------------------------------------------------------------===//
1050 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1051 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1052 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1053 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1054 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1055 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1056 SpecializedTemplate(SpecializedTemplate),
1057 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1058 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1060 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1062 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1063 QualType(), nullptr, SC_None),
1064 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1066 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1067 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1068 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1069 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1070 return new (Context, DC) VarTemplateSpecializationDecl(
1071 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1072 SpecializedTemplate, T, TInfo, S, Args);
1075 VarTemplateSpecializationDecl *
1076 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1078 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1081 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1082 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1083 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1085 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1086 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1087 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1088 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1090 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1091 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1095 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1096 if (const auto *PartialSpec =
1097 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1098 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1099 return SpecializedTemplate.get<VarTemplateDecl *>();
1102 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1103 const TemplateArgumentListInfo &ArgsInfo) {
1104 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1105 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1106 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1107 TemplateArgsInfo.addArgument(Loc);
1110 //===----------------------------------------------------------------------===//
1111 // VarTemplatePartialSpecializationDecl Implementation
1112 //===----------------------------------------------------------------------===//
1114 void VarTemplatePartialSpecializationDecl::anchor() {}
1116 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1117 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1118 SourceLocation IdLoc, TemplateParameterList *Params,
1119 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1120 StorageClass S, ArrayRef<TemplateArgument> Args,
1121 const ASTTemplateArgumentListInfo *ArgInfos)
1122 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1123 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1125 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1126 InstantiatedFromMember(nullptr, false) {
1127 // TODO: The template parameters should be in DC by now. Verify.
1128 // AdoptTemplateParameterList(Params, DC);
1131 VarTemplatePartialSpecializationDecl *
1132 VarTemplatePartialSpecializationDecl::Create(
1133 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1134 SourceLocation IdLoc, TemplateParameterList *Params,
1135 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1136 StorageClass S, ArrayRef<TemplateArgument> Args,
1137 const TemplateArgumentListInfo &ArgInfos) {
1138 const ASTTemplateArgumentListInfo *ASTArgInfos
1139 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1142 new (Context, DC) VarTemplatePartialSpecializationDecl(
1143 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1144 S, Args, ASTArgInfos);
1145 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1149 VarTemplatePartialSpecializationDecl *
1150 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1152 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1155 static TemplateParameterList *
1156 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1158 auto *T = TemplateTypeParmDecl::Create(
1159 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1160 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1161 T->setImplicit(true);
1164 TypeSourceInfo *TI =
1165 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1166 auto *N = NonTypeTemplateParmDecl::Create(
1167 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1168 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1169 N->setImplicit(true);
1171 // <typename T, T ...Ints>
1172 NamedDecl *P[2] = {T, N};
1173 auto *TPL = TemplateParameterList::Create(
1174 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1176 // template <typename T, ...Ints> class IntSeq
1177 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1178 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1179 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1180 TemplateTemplateParm->setImplicit(true);
1183 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1184 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1185 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1186 TemplateTypeParm->setImplicit(true);
1189 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1190 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1191 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1192 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1193 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1194 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1195 NonTypeTemplateParm};
1197 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1198 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1199 Params, SourceLocation(), nullptr);
1202 static TemplateParameterList *
1203 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1204 // std::size_t Index
1205 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1206 auto *Index = NonTypeTemplateParmDecl::Create(
1207 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1208 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1211 auto *Ts = TemplateTypeParmDecl::Create(
1212 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1213 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1214 Ts->setImplicit(true);
1216 // template <std::size_t Index, typename ...T>
1217 NamedDecl *Params[] = {Index, Ts};
1218 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1219 llvm::makeArrayRef(Params),
1220 SourceLocation(), nullptr);
1223 static TemplateParameterList *createBuiltinTemplateParameterList(
1224 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1226 case BTK__make_integer_seq:
1227 return createMakeIntegerSeqParameterList(C, DC);
1228 case BTK__type_pack_element:
1229 return createTypePackElementParameterList(C, DC);
1232 llvm_unreachable("unhandled BuiltinTemplateKind!");
1235 void BuiltinTemplateDecl::anchor() {}
1237 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1238 DeclarationName Name,
1239 BuiltinTemplateKind BTK)
1240 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1241 createBuiltinTemplateParameterList(C, DC, BTK)),