1 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the C++ related Decl classes for templates.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/DeclTemplate.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/TypeLoc.h"
21 #include "clang/Basic/Builtins.h"
22 #include "clang/Basic/IdentifierTable.h"
23 #include "llvm/ADT/STLExtras.h"
25 using namespace clang;
27 //===----------------------------------------------------------------------===//
28 // TemplateParameterList Implementation
29 //===----------------------------------------------------------------------===//
31 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32 SourceLocation LAngleLoc,
33 ArrayRef<NamedDecl *> Params,
34 SourceLocation RAngleLoc)
35 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
36 NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
37 assert(this->NumParams == NumParams && "Too many template parameters");
38 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
39 NamedDecl *P = Params[Idx];
42 if (!P->isTemplateParameterPack()) {
43 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
44 if (NTTP->getType()->containsUnexpandedParameterPack())
45 ContainsUnexpandedParameterPack = true;
47 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
48 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
49 ContainsUnexpandedParameterPack = true;
51 // FIXME: If a default argument contains an unexpanded parameter pack, the
52 // template parameter list does too.
57 TemplateParameterList *TemplateParameterList::Create(
58 const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
59 ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
60 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
61 llvm::alignOf<TemplateParameterList>());
62 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
66 unsigned TemplateParameterList::getMinRequiredArguments() const {
67 unsigned NumRequiredArgs = 0;
68 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
69 PEnd = const_cast<TemplateParameterList *>(this)->end();
71 if ((*P)->isTemplateParameterPack()) {
72 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
73 if (NTTP->isExpandedParameterPack()) {
74 NumRequiredArgs += NTTP->getNumExpansionTypes();
81 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
82 if (TTP->hasDefaultArgument())
84 } else if (NonTypeTemplateParmDecl *NTTP
85 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
86 if (NTTP->hasDefaultArgument())
88 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
94 return NumRequiredArgs;
97 unsigned TemplateParameterList::getDepth() const {
101 const NamedDecl *FirstParm = getParam(0);
102 if (const TemplateTypeParmDecl *TTP
103 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
104 return TTP->getDepth();
105 else if (const NonTypeTemplateParmDecl *NTTP
106 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
107 return NTTP->getDepth();
109 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
112 static void AdoptTemplateParameterList(TemplateParameterList *Params,
113 DeclContext *Owner) {
114 for (TemplateParameterList::iterator P = Params->begin(),
115 PEnd = Params->end();
117 (*P)->setDeclContext(Owner);
119 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
120 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
125 void *allocateDefaultArgStorageChain(const ASTContext &C) {
126 return new (C) char[sizeof(void*) * 2];
130 //===----------------------------------------------------------------------===//
131 // RedeclarableTemplateDecl Implementation
132 //===----------------------------------------------------------------------===//
134 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
138 // Walk the previous-declaration chain until we either find a declaration
139 // with a common pointer or we run out of previous declarations.
140 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
141 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
142 Prev = Prev->getPreviousDecl()) {
144 Common = Prev->Common;
148 PrevDecls.push_back(Prev);
151 // If we never found a common pointer, allocate one now.
153 // FIXME: If any of the declarations is from an AST file, we probably
154 // need an update record to add the common data.
156 Common = newCommon(getASTContext());
159 // Update any previous declarations we saw with the common pointer.
160 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
161 PrevDecls[I]->Common = Common;
166 template<class EntryType>
167 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
168 RedeclarableTemplateDecl::findSpecializationImpl(
169 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
171 typedef SpecEntryTraits<EntryType> SETraits;
172 llvm::FoldingSetNodeID ID;
173 EntryType::Profile(ID,Args, getASTContext());
174 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
175 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
178 template<class Derived, class EntryType>
179 void RedeclarableTemplateDecl::addSpecializationImpl(
180 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
182 typedef SpecEntryTraits<EntryType> SETraits;
185 void *CorrectInsertPos;
186 assert(!findSpecializationImpl(Specializations,
187 SETraits::getTemplateArgs(Entry),
189 InsertPos == CorrectInsertPos &&
190 "given incorrect InsertPos for specialization");
192 Specializations.InsertNode(Entry, InsertPos);
194 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
196 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
197 "non-canonical specialization?");
200 if (ASTMutationListener *L = getASTMutationListener())
201 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
202 SETraits::getDecl(Entry));
205 /// \brief Generate the injected template arguments for the given template
206 /// parameter list, e.g., for the injected-class-name of a class template.
207 static void GenerateInjectedTemplateArgs(ASTContext &Context,
208 TemplateParameterList *Params,
209 TemplateArgument *Args) {
210 for (TemplateParameterList::iterator Param = Params->begin(),
211 ParamEnd = Params->end();
212 Param != ParamEnd; ++Param) {
213 TemplateArgument Arg;
214 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
215 QualType ArgType = Context.getTypeDeclType(TTP);
216 if (TTP->isParameterPack())
217 ArgType = Context.getPackExpansionType(ArgType, None);
219 Arg = TemplateArgument(ArgType);
220 } else if (NonTypeTemplateParmDecl *NTTP =
221 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
222 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
223 NTTP->getType().getNonLValueExprType(Context),
224 Expr::getValueKindForType(NTTP->getType()),
225 NTTP->getLocation());
227 if (NTTP->isParameterPack())
228 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
229 NTTP->getLocation(), None);
230 Arg = TemplateArgument(E);
232 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
233 if (TTP->isParameterPack())
234 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
236 Arg = TemplateArgument(TemplateName(TTP));
239 if ((*Param)->isTemplateParameterPack())
240 Arg = TemplateArgument::CreatePackCopy(Context, Arg);
246 //===----------------------------------------------------------------------===//
247 // FunctionTemplateDecl Implementation
248 //===----------------------------------------------------------------------===//
250 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
251 static_cast<Common *>(Ptr)->~Common();
254 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
257 DeclarationName Name,
258 TemplateParameterList *Params,
260 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
261 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
264 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
266 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
267 DeclarationName(), nullptr, nullptr);
270 RedeclarableTemplateDecl::CommonBase *
271 FunctionTemplateDecl::newCommon(ASTContext &C) const {
272 Common *CommonPtr = new (C) Common;
273 C.AddDeallocation(DeallocateCommon, CommonPtr);
277 void FunctionTemplateDecl::LoadLazySpecializations() const {
278 // Grab the most recent declaration to ensure we've loaded any lazy
279 // redeclarations of this template.
281 // FIXME: Avoid walking the entire redeclaration chain here.
282 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
283 if (CommonPtr->LazySpecializations) {
284 ASTContext &Context = getASTContext();
285 uint32_t *Specs = CommonPtr->LazySpecializations;
286 CommonPtr->LazySpecializations = nullptr;
287 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
288 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
292 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
293 FunctionTemplateDecl::getSpecializations() const {
294 LoadLazySpecializations();
295 return getCommonPtr()->Specializations;
299 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
301 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
304 void FunctionTemplateDecl::addSpecialization(
305 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
306 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
310 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
311 TemplateParameterList *Params = getTemplateParameters();
312 Common *CommonPtr = getCommonPtr();
313 if (!CommonPtr->InjectedArgs) {
314 CommonPtr->InjectedArgs
315 = new (getASTContext()) TemplateArgument[Params->size()];
316 GenerateInjectedTemplateArgs(getASTContext(), Params,
317 CommonPtr->InjectedArgs);
320 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
323 //===----------------------------------------------------------------------===//
324 // ClassTemplateDecl Implementation
325 //===----------------------------------------------------------------------===//
327 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
328 static_cast<Common *>(Ptr)->~Common();
331 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
334 DeclarationName Name,
335 TemplateParameterList *Params,
337 ClassTemplateDecl *PrevDecl) {
338 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
339 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
341 New->setPreviousDecl(PrevDecl);
345 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
347 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
348 DeclarationName(), nullptr, nullptr);
351 void ClassTemplateDecl::LoadLazySpecializations() const {
352 // Grab the most recent declaration to ensure we've loaded any lazy
353 // redeclarations of this template.
355 // FIXME: Avoid walking the entire redeclaration chain here.
356 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
357 if (CommonPtr->LazySpecializations) {
358 ASTContext &Context = getASTContext();
359 uint32_t *Specs = CommonPtr->LazySpecializations;
360 CommonPtr->LazySpecializations = nullptr;
361 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
362 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
366 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
367 ClassTemplateDecl::getSpecializations() const {
368 LoadLazySpecializations();
369 return getCommonPtr()->Specializations;
372 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
373 ClassTemplateDecl::getPartialSpecializations() {
374 LoadLazySpecializations();
375 return getCommonPtr()->PartialSpecializations;
378 RedeclarableTemplateDecl::CommonBase *
379 ClassTemplateDecl::newCommon(ASTContext &C) const {
380 Common *CommonPtr = new (C) Common;
381 C.AddDeallocation(DeallocateCommon, CommonPtr);
385 ClassTemplateSpecializationDecl *
386 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
388 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
391 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
393 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
396 ClassTemplatePartialSpecializationDecl *
397 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
399 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
402 void ClassTemplateDecl::AddPartialSpecialization(
403 ClassTemplatePartialSpecializationDecl *D,
406 getPartialSpecializations().InsertNode(D, InsertPos);
408 ClassTemplatePartialSpecializationDecl *Existing
409 = getPartialSpecializations().GetOrInsertNode(D);
411 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
414 if (ASTMutationListener *L = getASTMutationListener())
415 L->AddedCXXTemplateSpecialization(this, D);
418 void ClassTemplateDecl::getPartialSpecializations(
419 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
420 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
421 = getPartialSpecializations();
423 PS.reserve(PartialSpecs.size());
424 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
425 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
427 PS.push_back(P->getMostRecentDecl());
430 ClassTemplatePartialSpecializationDecl *
431 ClassTemplateDecl::findPartialSpecialization(QualType T) {
432 ASTContext &Context = getASTContext();
433 using llvm::FoldingSetVector;
434 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
435 partial_spec_iterator;
436 for (partial_spec_iterator P = getPartialSpecializations().begin(),
437 PEnd = getPartialSpecializations().end();
439 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
440 return P->getMostRecentDecl();
446 ClassTemplatePartialSpecializationDecl *
447 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
448 ClassTemplatePartialSpecializationDecl *D) {
449 Decl *DCanon = D->getCanonicalDecl();
450 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
451 P = getPartialSpecializations().begin(),
452 PEnd = getPartialSpecializations().end();
454 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
455 return P->getMostRecentDecl();
462 ClassTemplateDecl::getInjectedClassNameSpecialization() {
463 Common *CommonPtr = getCommonPtr();
464 if (!CommonPtr->InjectedClassNameType.isNull())
465 return CommonPtr->InjectedClassNameType;
467 // C++0x [temp.dep.type]p2:
468 // The template argument list of a primary template is a template argument
469 // list in which the nth template argument has the value of the nth template
470 // parameter of the class template. If the nth template parameter is a
471 // template parameter pack (14.5.3), the nth template argument is a pack
472 // expansion (14.5.3) whose pattern is the name of the template parameter
474 ASTContext &Context = getASTContext();
475 TemplateParameterList *Params = getTemplateParameters();
476 SmallVector<TemplateArgument, 16> TemplateArgs;
477 TemplateArgs.resize(Params->size());
478 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
479 CommonPtr->InjectedClassNameType
480 = Context.getTemplateSpecializationType(TemplateName(this),
482 TemplateArgs.size());
483 return CommonPtr->InjectedClassNameType;
486 //===----------------------------------------------------------------------===//
487 // TemplateTypeParm Allocation/Deallocation Method Implementations
488 //===----------------------------------------------------------------------===//
490 TemplateTypeParmDecl *
491 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
492 SourceLocation KeyLoc, SourceLocation NameLoc,
493 unsigned D, unsigned P, IdentifierInfo *Id,
494 bool Typename, bool ParameterPack) {
495 TemplateTypeParmDecl *TTPDecl =
496 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
497 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
498 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
502 TemplateTypeParmDecl *
503 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
504 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
505 SourceLocation(), nullptr, false);
508 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
509 return hasDefaultArgument()
510 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
514 SourceRange TemplateTypeParmDecl::getSourceRange() const {
515 if (hasDefaultArgument() && !defaultArgumentWasInherited())
516 return SourceRange(getLocStart(),
517 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
519 return TypeDecl::getSourceRange();
522 unsigned TemplateTypeParmDecl::getDepth() const {
523 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
526 unsigned TemplateTypeParmDecl::getIndex() const {
527 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
530 bool TemplateTypeParmDecl::isParameterPack() const {
531 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
534 //===----------------------------------------------------------------------===//
535 // NonTypeTemplateParmDecl Method Implementations
536 //===----------------------------------------------------------------------===//
538 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
539 SourceLocation StartLoc,
540 SourceLocation IdLoc,
541 unsigned D, unsigned P,
544 TypeSourceInfo *TInfo,
545 const QualType *ExpandedTypes,
546 unsigned NumExpandedTypes,
547 TypeSourceInfo **ExpandedTInfos)
548 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
549 TemplateParmPosition(D, P), ParameterPack(true),
550 ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) {
551 if (ExpandedTypes && ExpandedTInfos) {
553 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
554 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
555 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
556 TypesAndInfos[I].second = ExpandedTInfos[I];
561 NonTypeTemplateParmDecl *
562 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
563 SourceLocation StartLoc, SourceLocation IdLoc,
564 unsigned D, unsigned P, IdentifierInfo *Id,
565 QualType T, bool ParameterPack,
566 TypeSourceInfo *TInfo) {
567 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
568 T, ParameterPack, TInfo);
571 NonTypeTemplateParmDecl *
572 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
573 SourceLocation StartLoc, SourceLocation IdLoc,
574 unsigned D, unsigned P,
575 IdentifierInfo *Id, QualType T,
576 TypeSourceInfo *TInfo,
577 const QualType *ExpandedTypes,
578 unsigned NumExpandedTypes,
579 TypeSourceInfo **ExpandedTInfos) {
581 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
583 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
584 ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
587 NonTypeTemplateParmDecl *
588 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
589 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
590 SourceLocation(), 0, 0, nullptr,
591 QualType(), false, nullptr);
594 NonTypeTemplateParmDecl *
595 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
596 unsigned NumExpandedTypes) {
598 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
600 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0,
601 nullptr, QualType(), nullptr, nullptr,
602 NumExpandedTypes, nullptr);
605 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
606 if (hasDefaultArgument() && !defaultArgumentWasInherited())
607 return SourceRange(getOuterLocStart(),
608 getDefaultArgument()->getSourceRange().getEnd());
609 return DeclaratorDecl::getSourceRange();
612 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
613 return hasDefaultArgument()
614 ? getDefaultArgument()->getSourceRange().getBegin()
618 //===----------------------------------------------------------------------===//
619 // TemplateTemplateParmDecl Method Implementations
620 //===----------------------------------------------------------------------===//
622 void TemplateTemplateParmDecl::anchor() { }
624 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
625 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
626 IdentifierInfo *Id, TemplateParameterList *Params,
627 unsigned NumExpansions, TemplateParameterList * const *Expansions)
628 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
629 TemplateParmPosition(D, P), ParameterPack(true),
630 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
632 std::uninitialized_copy(Expansions, Expansions + NumExpandedParams,
633 getTrailingObjects<TemplateParameterList *>());
636 TemplateTemplateParmDecl *
637 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
638 SourceLocation L, unsigned D, unsigned P,
639 bool ParameterPack, IdentifierInfo *Id,
640 TemplateParameterList *Params) {
641 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
645 TemplateTemplateParmDecl *
646 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
647 SourceLocation L, unsigned D, unsigned P,
649 TemplateParameterList *Params,
650 ArrayRef<TemplateParameterList *> Expansions) {
652 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
653 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions.size(),
657 TemplateTemplateParmDecl *
658 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
659 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
660 false, nullptr, nullptr);
663 TemplateTemplateParmDecl *
664 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
665 unsigned NumExpansions) {
667 additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
668 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
669 nullptr, NumExpansions, nullptr);
672 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
673 return hasDefaultArgument() ? getDefaultArgument().getLocation()
677 void TemplateTemplateParmDecl::setDefaultArgument(
678 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
679 if (DefArg.getArgument().isNull())
680 DefaultArgument.set(nullptr);
682 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
685 //===----------------------------------------------------------------------===//
686 // TemplateArgumentList Implementation
687 //===----------------------------------------------------------------------===//
688 TemplateArgumentList::TemplateArgumentList(const TemplateArgument *Args,
690 : Arguments(getTrailingObjects<TemplateArgument>()), NumArguments(NumArgs) {
691 std::uninitialized_copy(Args, Args + NumArgs,
692 getTrailingObjects<TemplateArgument>());
695 TemplateArgumentList *
696 TemplateArgumentList::CreateCopy(ASTContext &Context,
697 const TemplateArgument *Args,
699 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumArgs));
700 return new (Mem) TemplateArgumentList(Args, NumArgs);
703 FunctionTemplateSpecializationInfo *
704 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
705 FunctionTemplateDecl *Template,
706 TemplateSpecializationKind TSK,
707 const TemplateArgumentList *TemplateArgs,
708 const TemplateArgumentListInfo *TemplateArgsAsWritten,
709 SourceLocation POI) {
710 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
711 if (TemplateArgsAsWritten)
712 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
713 *TemplateArgsAsWritten);
715 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
721 //===----------------------------------------------------------------------===//
722 // TemplateDecl Implementation
723 //===----------------------------------------------------------------------===//
725 void TemplateDecl::anchor() { }
727 //===----------------------------------------------------------------------===//
728 // ClassTemplateSpecializationDecl Implementation
729 //===----------------------------------------------------------------------===//
730 ClassTemplateSpecializationDecl::
731 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
732 DeclContext *DC, SourceLocation StartLoc,
733 SourceLocation IdLoc,
734 ClassTemplateDecl *SpecializedTemplate,
735 const TemplateArgument *Args,
737 ClassTemplateSpecializationDecl *PrevDecl)
738 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
739 SpecializedTemplate->getIdentifier(),
741 SpecializedTemplate(SpecializedTemplate),
742 ExplicitInfo(nullptr),
743 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
744 SpecializationKind(TSK_Undeclared) {
747 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
749 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
750 SourceLocation(), nullptr, nullptr),
751 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
753 ClassTemplateSpecializationDecl *
754 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
756 SourceLocation StartLoc,
757 SourceLocation IdLoc,
758 ClassTemplateDecl *SpecializedTemplate,
759 const TemplateArgument *Args,
761 ClassTemplateSpecializationDecl *PrevDecl) {
762 ClassTemplateSpecializationDecl *Result =
763 new (Context, DC) ClassTemplateSpecializationDecl(
764 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
765 SpecializedTemplate, Args, NumArgs, PrevDecl);
766 Result->MayHaveOutOfDateDef = false;
768 Context.getTypeDeclType(Result, PrevDecl);
772 ClassTemplateSpecializationDecl *
773 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
775 ClassTemplateSpecializationDecl *Result =
776 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
777 Result->MayHaveOutOfDateDef = false;
781 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
782 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
783 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
785 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
786 TemplateSpecializationType::PrintTemplateArgumentList(
787 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
791 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
792 if (SpecializedPartialSpecialization *PartialSpec
793 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
794 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
795 return SpecializedTemplate.get<ClassTemplateDecl*>();
799 ClassTemplateSpecializationDecl::getSourceRange() const {
801 SourceLocation Begin = getTemplateKeywordLoc();
802 if (Begin.isValid()) {
803 // Here we have an explicit (partial) specialization or instantiation.
804 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
805 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
806 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
807 if (getExternLoc().isValid())
808 Begin = getExternLoc();
809 SourceLocation End = getRBraceLoc();
811 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
812 return SourceRange(Begin, End);
814 // An implicit instantiation of a class template partial specialization
815 // uses ExplicitInfo to record the TypeAsWritten, but the source
816 // locations should be retrieved from the instantiation pattern.
817 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
818 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
819 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
820 assert(inst_from != nullptr);
821 return inst_from->getSourceRange();
824 // No explicit info available.
825 llvm::PointerUnion<ClassTemplateDecl *,
826 ClassTemplatePartialSpecializationDecl *>
827 inst_from = getInstantiatedFrom();
828 if (inst_from.isNull())
829 return getSpecializedTemplate()->getSourceRange();
830 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
831 return ctd->getSourceRange();
832 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
837 //===----------------------------------------------------------------------===//
838 // ClassTemplatePartialSpecializationDecl Implementation
839 //===----------------------------------------------------------------------===//
840 void ClassTemplatePartialSpecializationDecl::anchor() { }
842 ClassTemplatePartialSpecializationDecl::
843 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
845 SourceLocation StartLoc,
846 SourceLocation IdLoc,
847 TemplateParameterList *Params,
848 ClassTemplateDecl *SpecializedTemplate,
849 const TemplateArgument *Args,
851 const ASTTemplateArgumentListInfo *ArgInfos,
852 ClassTemplatePartialSpecializationDecl *PrevDecl)
853 : ClassTemplateSpecializationDecl(Context,
854 ClassTemplatePartialSpecialization,
855 TK, DC, StartLoc, IdLoc,
857 Args, NumArgs, PrevDecl),
858 TemplateParams(Params), ArgsAsWritten(ArgInfos),
859 InstantiatedFromMember(nullptr, false)
861 AdoptTemplateParameterList(Params, this);
864 ClassTemplatePartialSpecializationDecl *
865 ClassTemplatePartialSpecializationDecl::
866 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
867 SourceLocation StartLoc, SourceLocation IdLoc,
868 TemplateParameterList *Params,
869 ClassTemplateDecl *SpecializedTemplate,
870 const TemplateArgument *Args,
872 const TemplateArgumentListInfo &ArgInfos,
873 QualType CanonInjectedType,
874 ClassTemplatePartialSpecializationDecl *PrevDecl) {
875 const ASTTemplateArgumentListInfo *ASTArgInfos =
876 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
878 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
879 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
880 Params, SpecializedTemplate, Args,
881 NumArgs, ASTArgInfos, PrevDecl);
882 Result->setSpecializationKind(TSK_ExplicitSpecialization);
883 Result->MayHaveOutOfDateDef = false;
885 Context.getInjectedClassNameType(Result, CanonInjectedType);
889 ClassTemplatePartialSpecializationDecl *
890 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
892 ClassTemplatePartialSpecializationDecl *Result =
893 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
894 Result->MayHaveOutOfDateDef = false;
898 //===----------------------------------------------------------------------===//
899 // FriendTemplateDecl Implementation
900 //===----------------------------------------------------------------------===//
902 void FriendTemplateDecl::anchor() { }
904 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
908 TemplateParameterList **Params,
910 SourceLocation FLoc) {
911 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
915 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
917 return new (C, ID) FriendTemplateDecl(EmptyShell());
920 //===----------------------------------------------------------------------===//
921 // TypeAliasTemplateDecl Implementation
922 //===----------------------------------------------------------------------===//
924 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
927 DeclarationName Name,
928 TemplateParameterList *Params,
930 AdoptTemplateParameterList(Params, DC);
931 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
934 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
936 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
937 DeclarationName(), nullptr, nullptr);
940 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
941 static_cast<Common *>(Ptr)->~Common();
943 RedeclarableTemplateDecl::CommonBase *
944 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
945 Common *CommonPtr = new (C) Common;
946 C.AddDeallocation(DeallocateCommon, CommonPtr);
950 //===----------------------------------------------------------------------===//
951 // ClassScopeFunctionSpecializationDecl Implementation
952 //===----------------------------------------------------------------------===//
954 void ClassScopeFunctionSpecializationDecl::anchor() { }
956 ClassScopeFunctionSpecializationDecl *
957 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
959 return new (C, ID) ClassScopeFunctionSpecializationDecl(
960 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
963 //===----------------------------------------------------------------------===//
964 // VarTemplateDecl Implementation
965 //===----------------------------------------------------------------------===//
967 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
968 static_cast<Common *>(Ptr)->~Common();
971 VarTemplateDecl *VarTemplateDecl::getDefinition() {
972 VarTemplateDecl *CurD = this;
974 if (CurD->isThisDeclarationADefinition())
976 CurD = CurD->getPreviousDecl();
981 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
982 SourceLocation L, DeclarationName Name,
983 TemplateParameterList *Params,
985 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
988 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
990 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
991 DeclarationName(), nullptr, nullptr);
994 // TODO: Unify across class, function and variable templates?
995 // May require moving this and Common to RedeclarableTemplateDecl.
996 void VarTemplateDecl::LoadLazySpecializations() const {
997 // Grab the most recent declaration to ensure we've loaded any lazy
998 // redeclarations of this template.
1000 // FIXME: Avoid walking the entire redeclaration chain here.
1001 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
1002 if (CommonPtr->LazySpecializations) {
1003 ASTContext &Context = getASTContext();
1004 uint32_t *Specs = CommonPtr->LazySpecializations;
1005 CommonPtr->LazySpecializations = nullptr;
1006 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
1007 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
1011 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1012 VarTemplateDecl::getSpecializations() const {
1013 LoadLazySpecializations();
1014 return getCommonPtr()->Specializations;
1017 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1018 VarTemplateDecl::getPartialSpecializations() {
1019 LoadLazySpecializations();
1020 return getCommonPtr()->PartialSpecializations;
1023 RedeclarableTemplateDecl::CommonBase *
1024 VarTemplateDecl::newCommon(ASTContext &C) const {
1025 Common *CommonPtr = new (C) Common;
1026 C.AddDeallocation(DeallocateCommon, CommonPtr);
1030 VarTemplateSpecializationDecl *
1031 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1033 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1036 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1038 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1041 VarTemplatePartialSpecializationDecl *
1042 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1044 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1047 void VarTemplateDecl::AddPartialSpecialization(
1048 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1050 getPartialSpecializations().InsertNode(D, InsertPos);
1052 VarTemplatePartialSpecializationDecl *Existing =
1053 getPartialSpecializations().GetOrInsertNode(D);
1055 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1058 if (ASTMutationListener *L = getASTMutationListener())
1059 L->AddedCXXTemplateSpecialization(this, D);
1062 void VarTemplateDecl::getPartialSpecializations(
1063 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1064 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1065 getPartialSpecializations();
1067 PS.reserve(PartialSpecs.size());
1068 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1069 P = PartialSpecs.begin(),
1070 PEnd = PartialSpecs.end();
1072 PS.push_back(P->getMostRecentDecl());
1075 VarTemplatePartialSpecializationDecl *
1076 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1077 VarTemplatePartialSpecializationDecl *D) {
1078 Decl *DCanon = D->getCanonicalDecl();
1079 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1080 P = getPartialSpecializations().begin(),
1081 PEnd = getPartialSpecializations().end();
1083 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1084 return P->getMostRecentDecl();
1090 //===----------------------------------------------------------------------===//
1091 // VarTemplateSpecializationDecl Implementation
1092 //===----------------------------------------------------------------------===//
1093 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1094 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1095 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1096 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1098 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1099 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1100 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1101 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1102 SpecializationKind(TSK_Undeclared) {}
1104 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1106 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1107 QualType(), nullptr, SC_None),
1108 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1110 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1111 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1112 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1113 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1115 return new (Context, DC) VarTemplateSpecializationDecl(
1116 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1117 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
1120 VarTemplateSpecializationDecl *
1121 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1123 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1126 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1127 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1128 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1130 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1131 TemplateSpecializationType::PrintTemplateArgumentList(
1132 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1135 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1136 if (SpecializedPartialSpecialization *PartialSpec =
1137 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1138 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1139 return SpecializedTemplate.get<VarTemplateDecl *>();
1142 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1143 const TemplateArgumentListInfo &ArgsInfo) {
1144 unsigned N = ArgsInfo.size();
1145 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1146 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1147 for (unsigned I = 0; I != N; ++I)
1148 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1151 //===----------------------------------------------------------------------===//
1152 // VarTemplatePartialSpecializationDecl Implementation
1153 //===----------------------------------------------------------------------===//
1154 void VarTemplatePartialSpecializationDecl::anchor() {}
1156 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1157 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1158 SourceLocation IdLoc, TemplateParameterList *Params,
1159 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1160 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1161 const ASTTemplateArgumentListInfo *ArgInfos)
1162 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1163 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1164 TInfo, S, Args, NumArgs),
1165 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1166 InstantiatedFromMember(nullptr, false) {
1167 // TODO: The template parameters should be in DC by now. Verify.
1168 // AdoptTemplateParameterList(Params, DC);
1171 VarTemplatePartialSpecializationDecl *
1172 VarTemplatePartialSpecializationDecl::Create(
1173 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1174 SourceLocation IdLoc, TemplateParameterList *Params,
1175 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1176 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1177 const TemplateArgumentListInfo &ArgInfos) {
1178 const ASTTemplateArgumentListInfo *ASTArgInfos
1179 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1181 VarTemplatePartialSpecializationDecl *Result =
1182 new (Context, DC) VarTemplatePartialSpecializationDecl(
1183 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1184 S, Args, NumArgs, ASTArgInfos);
1185 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1189 VarTemplatePartialSpecializationDecl *
1190 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1192 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1195 static TemplateParameterList *
1196 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1198 auto *T = TemplateTypeParmDecl::Create(
1199 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1200 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1201 T->setImplicit(true);
1204 TypeSourceInfo *TI =
1205 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1206 auto *N = NonTypeTemplateParmDecl::Create(
1207 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1208 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1209 N->setImplicit(true);
1211 // <typename T, T ...Ints>
1212 NamedDecl *P[2] = {T, N};
1213 auto *TPL = TemplateParameterList::Create(
1214 C, SourceLocation(), SourceLocation(), P, SourceLocation());
1216 // template <typename T, ...Ints> class IntSeq
1217 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1218 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1219 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1220 TemplateTemplateParm->setImplicit(true);
1223 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1224 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1225 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1226 TemplateTypeParm->setImplicit(true);
1229 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1230 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1231 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1232 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1233 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1234 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1235 NonTypeTemplateParm};
1237 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1238 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1239 Params, SourceLocation());
1242 static TemplateParameterList *createBuiltinTemplateParameterList(
1243 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1245 case BTK__make_integer_seq:
1246 return createMakeIntegerSeqParameterList(C, DC);
1249 llvm_unreachable("unhandled BuiltinTemplateKind!");
1252 void BuiltinTemplateDecl::anchor() {}
1254 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1255 DeclarationName Name,
1256 BuiltinTemplateKind BTK)
1257 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1258 createBuiltinTemplateParameterList(C, DC, BTK)),