1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the C++ related Decl classes for templates.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/TemplateName.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Basic/Builtins.h"
25 #include "clang/Basic/LLVM.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/FoldingSet.h"
29 #include "llvm/ADT/None.h"
30 #include "llvm/ADT/PointerUnion.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
40 using namespace clang;
42 //===----------------------------------------------------------------------===//
43 // TemplateParameterList Implementation
44 //===----------------------------------------------------------------------===//
46 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
47 SourceLocation LAngleLoc,
48 ArrayRef<NamedDecl *> Params,
49 SourceLocation RAngleLoc,
51 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
52 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
53 HasRequiresClause(static_cast<bool>(RequiresClause)) {
54 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
55 NamedDecl *P = Params[Idx];
58 if (!P->isTemplateParameterPack()) {
59 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
60 if (NTTP->getType()->containsUnexpandedParameterPack())
61 ContainsUnexpandedParameterPack = true;
63 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
64 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
65 ContainsUnexpandedParameterPack = true;
67 // FIXME: If a default argument contains an unexpanded parameter pack, the
68 // template parameter list does too.
72 *getTrailingObjects<Expr *>() = RequiresClause;
73 if (RequiresClause->containsUnexpandedParameterPack())
74 ContainsUnexpandedParameterPack = true;
78 TemplateParameterList *
79 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
80 SourceLocation LAngleLoc,
81 ArrayRef<NamedDecl *> Params,
82 SourceLocation RAngleLoc, Expr *RequiresClause) {
83 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
84 Params.size(), RequiresClause ? 1u : 0u),
85 alignof(TemplateParameterList));
86 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
87 RAngleLoc, RequiresClause);
90 unsigned TemplateParameterList::getMinRequiredArguments() const {
91 unsigned NumRequiredArgs = 0;
92 for (const NamedDecl *P : asArray()) {
93 if (P->isTemplateParameterPack()) {
94 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
95 if (NTTP->isExpandedParameterPack()) {
96 NumRequiredArgs += NTTP->getNumExpansionTypes();
103 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
104 if (TTP->hasDefaultArgument())
106 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
107 if (NTTP->hasDefaultArgument())
109 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
115 return NumRequiredArgs;
118 unsigned TemplateParameterList::getDepth() const {
122 const NamedDecl *FirstParm = getParam(0);
123 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
124 return TTP->getDepth();
125 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
126 return NTTP->getDepth();
128 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
131 static void AdoptTemplateParameterList(TemplateParameterList *Params,
132 DeclContext *Owner) {
133 for (NamedDecl *P : *Params) {
134 P->setDeclContext(Owner);
136 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
137 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
141 void TemplateParameterList::
142 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
143 // TODO: Concepts: Collect immediately-introduced constraints.
144 if (HasRequiresClause)
145 AC.push_back(getRequiresClause());
148 bool TemplateParameterList::hasAssociatedConstraints() const {
149 // TODO: Concepts: Regard immediately-introduced constraints.
150 return HasRequiresClause;
155 void *allocateDefaultArgStorageChain(const ASTContext &C) {
156 return new (C) char[sizeof(void*) * 2];
161 //===----------------------------------------------------------------------===//
162 // TemplateDecl Implementation
163 //===----------------------------------------------------------------------===//
165 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
166 DeclarationName Name, TemplateParameterList *Params,
168 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
170 void TemplateDecl::anchor() {}
173 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
174 // TODO: Concepts: Append function trailing requires clause.
175 TemplateParams->getAssociatedConstraints(AC);
178 bool TemplateDecl::hasAssociatedConstraints() const {
179 // TODO: Concepts: Regard function trailing requires clause.
180 return TemplateParams->hasAssociatedConstraints();
183 //===----------------------------------------------------------------------===//
184 // RedeclarableTemplateDecl Implementation
185 //===----------------------------------------------------------------------===//
187 void RedeclarableTemplateDecl::anchor() {}
189 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
193 // Walk the previous-declaration chain until we either find a declaration
194 // with a common pointer or we run out of previous declarations.
195 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
196 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
197 Prev = Prev->getPreviousDecl()) {
199 Common = Prev->Common;
203 PrevDecls.push_back(Prev);
206 // If we never found a common pointer, allocate one now.
208 // FIXME: If any of the declarations is from an AST file, we probably
209 // need an update record to add the common data.
211 Common = newCommon(getASTContext());
214 // Update any previous declarations we saw with the common pointer.
215 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
216 Prev->Common = Common;
221 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
222 // Grab the most recent declaration to ensure we've loaded any lazy
223 // redeclarations of this template.
224 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
225 if (CommonBasePtr->LazySpecializations) {
226 ASTContext &Context = getASTContext();
227 uint32_t *Specs = CommonBasePtr->LazySpecializations;
228 CommonBasePtr->LazySpecializations = nullptr;
229 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
230 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
234 template<class EntryType>
235 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
236 RedeclarableTemplateDecl::findSpecializationImpl(
237 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
239 using SETraits = SpecEntryTraits<EntryType>;
241 llvm::FoldingSetNodeID ID;
242 EntryType::Profile(ID, Args, getASTContext());
243 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
244 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
247 template<class Derived, class EntryType>
248 void RedeclarableTemplateDecl::addSpecializationImpl(
249 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
251 using SETraits = SpecEntryTraits<EntryType>;
255 void *CorrectInsertPos;
256 assert(!findSpecializationImpl(Specializations,
257 SETraits::getTemplateArgs(Entry),
259 InsertPos == CorrectInsertPos &&
260 "given incorrect InsertPos for specialization");
262 Specializations.InsertNode(Entry, InsertPos);
264 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
266 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
267 "non-canonical specialization?");
270 if (ASTMutationListener *L = getASTMutationListener())
271 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
272 SETraits::getDecl(Entry));
275 //===----------------------------------------------------------------------===//
276 // FunctionTemplateDecl Implementation
277 //===----------------------------------------------------------------------===//
279 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
282 DeclarationName Name,
283 TemplateParameterList *Params,
285 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
286 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
289 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
291 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
292 DeclarationName(), nullptr, nullptr);
295 RedeclarableTemplateDecl::CommonBase *
296 FunctionTemplateDecl::newCommon(ASTContext &C) const {
297 auto *CommonPtr = new (C) Common;
298 C.addDestruction(CommonPtr);
302 void FunctionTemplateDecl::LoadLazySpecializations() const {
303 loadLazySpecializationsImpl();
306 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
307 FunctionTemplateDecl::getSpecializations() const {
308 LoadLazySpecializations();
309 return getCommonPtr()->Specializations;
313 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
315 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
318 void FunctionTemplateDecl::addSpecialization(
319 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
320 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
324 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
325 TemplateParameterList *Params = getTemplateParameters();
326 Common *CommonPtr = getCommonPtr();
327 if (!CommonPtr->InjectedArgs) {
328 auto &Context = getASTContext();
329 SmallVector<TemplateArgument, 16> TemplateArgs;
330 Context.getInjectedTemplateArgs(Params, TemplateArgs);
331 CommonPtr->InjectedArgs =
332 new (Context) TemplateArgument[TemplateArgs.size()];
333 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
334 CommonPtr->InjectedArgs);
337 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
340 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
341 using Base = RedeclarableTemplateDecl;
343 // If we haven't created a common pointer yet, then it can just be created
344 // with the usual method.
348 Common *ThisCommon = static_cast<Common *>(Base::Common);
349 Common *PrevCommon = nullptr;
350 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
351 for (; Prev; Prev = Prev->getPreviousDecl()) {
352 if (Prev->Base::Common) {
353 PrevCommon = static_cast<Common *>(Prev->Base::Common);
356 PreviousDecls.push_back(Prev);
359 // If the previous redecl chain hasn't created a common pointer yet, then just
360 // use this common pointer.
362 for (auto *D : PreviousDecls)
363 D->Base::Common = ThisCommon;
367 // Ensure we don't leak any important state.
368 assert(ThisCommon->Specializations.size() == 0 &&
369 "Can't merge incompatible declarations!");
371 Base::Common = PrevCommon;
374 //===----------------------------------------------------------------------===//
375 // ClassTemplateDecl Implementation
376 //===----------------------------------------------------------------------===//
378 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
381 DeclarationName Name,
382 TemplateParameterList *Params,
384 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
386 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
389 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
391 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
392 DeclarationName(), nullptr, nullptr);
395 void ClassTemplateDecl::LoadLazySpecializations() const {
396 loadLazySpecializationsImpl();
399 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
400 ClassTemplateDecl::getSpecializations() const {
401 LoadLazySpecializations();
402 return getCommonPtr()->Specializations;
405 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
406 ClassTemplateDecl::getPartialSpecializations() {
407 LoadLazySpecializations();
408 return getCommonPtr()->PartialSpecializations;
411 RedeclarableTemplateDecl::CommonBase *
412 ClassTemplateDecl::newCommon(ASTContext &C) const {
413 auto *CommonPtr = new (C) Common;
414 C.addDestruction(CommonPtr);
418 ClassTemplateSpecializationDecl *
419 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
421 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
424 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
426 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
429 ClassTemplatePartialSpecializationDecl *
430 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
432 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
435 void ClassTemplateDecl::AddPartialSpecialization(
436 ClassTemplatePartialSpecializationDecl *D,
439 getPartialSpecializations().InsertNode(D, InsertPos);
441 ClassTemplatePartialSpecializationDecl *Existing
442 = getPartialSpecializations().GetOrInsertNode(D);
444 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
447 if (ASTMutationListener *L = getASTMutationListener())
448 L->AddedCXXTemplateSpecialization(this, D);
451 void ClassTemplateDecl::getPartialSpecializations(
452 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
453 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
454 = getPartialSpecializations();
456 PS.reserve(PartialSpecs.size());
457 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
458 PS.push_back(P.getMostRecentDecl());
461 ClassTemplatePartialSpecializationDecl *
462 ClassTemplateDecl::findPartialSpecialization(QualType T) {
463 ASTContext &Context = getASTContext();
464 for (ClassTemplatePartialSpecializationDecl &P :
465 getPartialSpecializations()) {
466 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
467 return P.getMostRecentDecl();
473 ClassTemplatePartialSpecializationDecl *
474 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
475 ClassTemplatePartialSpecializationDecl *D) {
476 Decl *DCanon = D->getCanonicalDecl();
477 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
478 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
479 return P.getMostRecentDecl();
486 ClassTemplateDecl::getInjectedClassNameSpecialization() {
487 Common *CommonPtr = getCommonPtr();
488 if (!CommonPtr->InjectedClassNameType.isNull())
489 return CommonPtr->InjectedClassNameType;
491 // C++0x [temp.dep.type]p2:
492 // The template argument list of a primary template is a template argument
493 // list in which the nth template argument has the value of the nth template
494 // parameter of the class template. If the nth template parameter is a
495 // template parameter pack (14.5.3), the nth template argument is a pack
496 // expansion (14.5.3) whose pattern is the name of the template parameter
498 ASTContext &Context = getASTContext();
499 TemplateParameterList *Params = getTemplateParameters();
500 SmallVector<TemplateArgument, 16> TemplateArgs;
501 Context.getInjectedTemplateArgs(Params, TemplateArgs);
502 CommonPtr->InjectedClassNameType
503 = Context.getTemplateSpecializationType(TemplateName(this),
505 return CommonPtr->InjectedClassNameType;
508 //===----------------------------------------------------------------------===//
509 // TemplateTypeParm Allocation/Deallocation Method Implementations
510 //===----------------------------------------------------------------------===//
512 TemplateTypeParmDecl *
513 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
514 SourceLocation KeyLoc, SourceLocation NameLoc,
515 unsigned D, unsigned P, IdentifierInfo *Id,
516 bool Typename, bool ParameterPack) {
518 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
519 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
520 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
524 TemplateTypeParmDecl *
525 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
526 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
527 SourceLocation(), nullptr, false);
530 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
531 return hasDefaultArgument()
532 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
536 SourceRange TemplateTypeParmDecl::getSourceRange() const {
537 if (hasDefaultArgument() && !defaultArgumentWasInherited())
538 return SourceRange(getBeginLoc(),
539 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
540 // TypeDecl::getSourceRange returns a range containing name location, which is
541 // wrong for unnamed template parameters. e.g:
542 // it will return <[[typename>]] instead of <[[typename]]>
543 else if (getDeclName().isEmpty())
544 return SourceRange(getBeginLoc());
545 return TypeDecl::getSourceRange();
548 unsigned TemplateTypeParmDecl::getDepth() const {
549 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
552 unsigned TemplateTypeParmDecl::getIndex() const {
553 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
556 bool TemplateTypeParmDecl::isParameterPack() const {
557 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
560 //===----------------------------------------------------------------------===//
561 // NonTypeTemplateParmDecl Method Implementations
562 //===----------------------------------------------------------------------===//
564 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
565 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
566 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
567 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
568 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
569 TemplateParmPosition(D, P), ParameterPack(true),
570 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
571 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
573 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
574 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
575 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
576 TypesAndInfos[I].second = ExpandedTInfos[I];
581 NonTypeTemplateParmDecl *
582 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
583 SourceLocation StartLoc, SourceLocation IdLoc,
584 unsigned D, unsigned P, IdentifierInfo *Id,
585 QualType T, bool ParameterPack,
586 TypeSourceInfo *TInfo) {
587 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
588 T, ParameterPack, TInfo);
591 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
592 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
593 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
594 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
595 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
597 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
598 ExpandedTypes.size()))
599 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
600 ExpandedTypes, ExpandedTInfos);
603 NonTypeTemplateParmDecl *
604 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
605 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
606 SourceLocation(), 0, 0, nullptr,
607 QualType(), false, nullptr);
610 NonTypeTemplateParmDecl *
611 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
612 unsigned NumExpandedTypes) {
614 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
616 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
617 0, 0, nullptr, QualType(), nullptr, None,
619 NTTP->NumExpandedTypes = NumExpandedTypes;
623 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
624 if (hasDefaultArgument() && !defaultArgumentWasInherited())
625 return SourceRange(getOuterLocStart(),
626 getDefaultArgument()->getSourceRange().getEnd());
627 return DeclaratorDecl::getSourceRange();
630 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
631 return hasDefaultArgument()
632 ? getDefaultArgument()->getSourceRange().getBegin()
636 //===----------------------------------------------------------------------===//
637 // TemplateTemplateParmDecl Method Implementations
638 //===----------------------------------------------------------------------===//
640 void TemplateTemplateParmDecl::anchor() {}
642 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
643 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
644 IdentifierInfo *Id, TemplateParameterList *Params,
645 ArrayRef<TemplateParameterList *> Expansions)
646 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
647 TemplateParmPosition(D, P), ParameterPack(true),
648 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
649 if (!Expansions.empty())
650 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
651 getTrailingObjects<TemplateParameterList *>());
654 TemplateTemplateParmDecl *
655 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
656 SourceLocation L, unsigned D, unsigned P,
657 bool ParameterPack, IdentifierInfo *Id,
658 TemplateParameterList *Params) {
659 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
663 TemplateTemplateParmDecl *
664 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
665 SourceLocation L, unsigned D, unsigned P,
667 TemplateParameterList *Params,
668 ArrayRef<TemplateParameterList *> Expansions) {
670 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
671 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
674 TemplateTemplateParmDecl *
675 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
676 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
677 false, nullptr, nullptr);
680 TemplateTemplateParmDecl *
681 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
682 unsigned NumExpansions) {
684 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
685 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
687 TTP->NumExpandedParams = NumExpansions;
691 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
692 return hasDefaultArgument() ? getDefaultArgument().getLocation()
696 void TemplateTemplateParmDecl::setDefaultArgument(
697 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
698 if (DefArg.getArgument().isNull())
699 DefaultArgument.set(nullptr);
701 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
704 //===----------------------------------------------------------------------===//
705 // TemplateArgumentList Implementation
706 //===----------------------------------------------------------------------===//
707 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
708 : Arguments(getTrailingObjects<TemplateArgument>()),
709 NumArguments(Args.size()) {
710 std::uninitialized_copy(Args.begin(), Args.end(),
711 getTrailingObjects<TemplateArgument>());
714 TemplateArgumentList *
715 TemplateArgumentList::CreateCopy(ASTContext &Context,
716 ArrayRef<TemplateArgument> Args) {
717 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
718 return new (Mem) TemplateArgumentList(Args);
721 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
722 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
723 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
724 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
725 MemberSpecializationInfo *MSInfo) {
726 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
727 if (TemplateArgsAsWritten)
728 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
729 *TemplateArgsAsWritten);
732 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
733 return new (Mem) FunctionTemplateSpecializationInfo(
734 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
737 //===----------------------------------------------------------------------===//
738 // ClassTemplateSpecializationDecl Implementation
739 //===----------------------------------------------------------------------===//
741 ClassTemplateSpecializationDecl::
742 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
743 DeclContext *DC, SourceLocation StartLoc,
744 SourceLocation IdLoc,
745 ClassTemplateDecl *SpecializedTemplate,
746 ArrayRef<TemplateArgument> Args,
747 ClassTemplateSpecializationDecl *PrevDecl)
748 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
749 SpecializedTemplate->getIdentifier(), PrevDecl),
750 SpecializedTemplate(SpecializedTemplate),
751 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
752 SpecializationKind(TSK_Undeclared) {
755 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
757 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
758 SourceLocation(), nullptr, nullptr),
759 SpecializationKind(TSK_Undeclared) {}
761 ClassTemplateSpecializationDecl *
762 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
764 SourceLocation StartLoc,
765 SourceLocation IdLoc,
766 ClassTemplateDecl *SpecializedTemplate,
767 ArrayRef<TemplateArgument> Args,
768 ClassTemplateSpecializationDecl *PrevDecl) {
770 new (Context, DC) ClassTemplateSpecializationDecl(
771 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
772 SpecializedTemplate, Args, PrevDecl);
773 Result->setMayHaveOutOfDateDef(false);
775 Context.getTypeDeclType(Result, PrevDecl);
779 ClassTemplateSpecializationDecl *
780 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
783 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
784 Result->setMayHaveOutOfDateDef(false);
788 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
789 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
790 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
792 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
793 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
794 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
795 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
797 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
798 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
803 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
804 if (const auto *PartialSpec =
805 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
806 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
807 return SpecializedTemplate.get<ClassTemplateDecl*>();
811 ClassTemplateSpecializationDecl::getSourceRange() const {
813 SourceLocation Begin = getTemplateKeywordLoc();
814 if (Begin.isValid()) {
815 // Here we have an explicit (partial) specialization or instantiation.
816 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
817 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
818 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
819 if (getExternLoc().isValid())
820 Begin = getExternLoc();
821 SourceLocation End = getBraceRange().getEnd();
823 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
824 return SourceRange(Begin, End);
826 // An implicit instantiation of a class template partial specialization
827 // uses ExplicitInfo to record the TypeAsWritten, but the source
828 // locations should be retrieved from the instantiation pattern.
829 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
830 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
831 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
832 assert(inst_from != nullptr);
833 return inst_from->getSourceRange();
836 // No explicit info available.
837 llvm::PointerUnion<ClassTemplateDecl *,
838 ClassTemplatePartialSpecializationDecl *>
839 inst_from = getInstantiatedFrom();
840 if (inst_from.isNull())
841 return getSpecializedTemplate()->getSourceRange();
842 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
843 return ctd->getSourceRange();
844 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
849 //===----------------------------------------------------------------------===//
850 // ConceptDecl Implementation
851 //===----------------------------------------------------------------------===//
852 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
853 SourceLocation L, DeclarationName Name,
854 TemplateParameterList *Params,
855 Expr *ConstraintExpr) {
856 AdoptTemplateParameterList(Params, DC);
857 return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
860 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
862 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
869 //===----------------------------------------------------------------------===//
870 // ClassTemplatePartialSpecializationDecl Implementation
871 //===----------------------------------------------------------------------===//
872 void ClassTemplatePartialSpecializationDecl::anchor() {}
874 ClassTemplatePartialSpecializationDecl::
875 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
877 SourceLocation StartLoc,
878 SourceLocation IdLoc,
879 TemplateParameterList *Params,
880 ClassTemplateDecl *SpecializedTemplate,
881 ArrayRef<TemplateArgument> Args,
882 const ASTTemplateArgumentListInfo *ArgInfos,
883 ClassTemplatePartialSpecializationDecl *PrevDecl)
884 : ClassTemplateSpecializationDecl(Context,
885 ClassTemplatePartialSpecialization,
886 TK, DC, StartLoc, IdLoc,
887 SpecializedTemplate, Args, PrevDecl),
888 TemplateParams(Params), ArgsAsWritten(ArgInfos),
889 InstantiatedFromMember(nullptr, false) {
890 AdoptTemplateParameterList(Params, this);
893 ClassTemplatePartialSpecializationDecl *
894 ClassTemplatePartialSpecializationDecl::
895 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
896 SourceLocation StartLoc, SourceLocation IdLoc,
897 TemplateParameterList *Params,
898 ClassTemplateDecl *SpecializedTemplate,
899 ArrayRef<TemplateArgument> Args,
900 const TemplateArgumentListInfo &ArgInfos,
901 QualType CanonInjectedType,
902 ClassTemplatePartialSpecializationDecl *PrevDecl) {
903 const ASTTemplateArgumentListInfo *ASTArgInfos =
904 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
906 auto *Result = new (Context, DC)
907 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
908 Params, SpecializedTemplate, Args,
909 ASTArgInfos, PrevDecl);
910 Result->setSpecializationKind(TSK_ExplicitSpecialization);
911 Result->setMayHaveOutOfDateDef(false);
913 Context.getInjectedClassNameType(Result, CanonInjectedType);
917 ClassTemplatePartialSpecializationDecl *
918 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
920 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
921 Result->setMayHaveOutOfDateDef(false);
925 //===----------------------------------------------------------------------===//
926 // FriendTemplateDecl Implementation
927 //===----------------------------------------------------------------------===//
929 void FriendTemplateDecl::anchor() {}
932 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
934 MutableArrayRef<TemplateParameterList *> Params,
935 FriendUnion Friend, SourceLocation FLoc) {
936 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
939 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
941 return new (C, ID) FriendTemplateDecl(EmptyShell());
944 //===----------------------------------------------------------------------===//
945 // TypeAliasTemplateDecl Implementation
946 //===----------------------------------------------------------------------===//
948 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
951 DeclarationName Name,
952 TemplateParameterList *Params,
954 AdoptTemplateParameterList(Params, DC);
955 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
958 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
960 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
961 DeclarationName(), nullptr, nullptr);
964 RedeclarableTemplateDecl::CommonBase *
965 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
966 auto *CommonPtr = new (C) Common;
967 C.addDestruction(CommonPtr);
971 //===----------------------------------------------------------------------===//
972 // ClassScopeFunctionSpecializationDecl Implementation
973 //===----------------------------------------------------------------------===//
975 void ClassScopeFunctionSpecializationDecl::anchor() {}
977 ClassScopeFunctionSpecializationDecl *
978 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
980 return new (C, ID) ClassScopeFunctionSpecializationDecl(
981 nullptr, SourceLocation(), nullptr, nullptr);
984 //===----------------------------------------------------------------------===//
985 // VarTemplateDecl Implementation
986 //===----------------------------------------------------------------------===//
988 VarTemplateDecl *VarTemplateDecl::getDefinition() {
989 VarTemplateDecl *CurD = this;
991 if (CurD->isThisDeclarationADefinition())
993 CurD = CurD->getPreviousDecl();
998 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
999 SourceLocation L, DeclarationName Name,
1000 TemplateParameterList *Params,
1002 AdoptTemplateParameterList(Params, DC);
1003 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1006 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1008 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1009 DeclarationName(), nullptr, nullptr);
1012 void VarTemplateDecl::LoadLazySpecializations() const {
1013 loadLazySpecializationsImpl();
1016 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1017 VarTemplateDecl::getSpecializations() const {
1018 LoadLazySpecializations();
1019 return getCommonPtr()->Specializations;
1022 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1023 VarTemplateDecl::getPartialSpecializations() {
1024 LoadLazySpecializations();
1025 return getCommonPtr()->PartialSpecializations;
1028 RedeclarableTemplateDecl::CommonBase *
1029 VarTemplateDecl::newCommon(ASTContext &C) const {
1030 auto *CommonPtr = new (C) Common;
1031 C.addDestruction(CommonPtr);
1035 VarTemplateSpecializationDecl *
1036 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1038 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1041 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1043 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1046 VarTemplatePartialSpecializationDecl *
1047 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1049 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1052 void VarTemplateDecl::AddPartialSpecialization(
1053 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1055 getPartialSpecializations().InsertNode(D, InsertPos);
1057 VarTemplatePartialSpecializationDecl *Existing =
1058 getPartialSpecializations().GetOrInsertNode(D);
1060 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1063 if (ASTMutationListener *L = getASTMutationListener())
1064 L->AddedCXXTemplateSpecialization(this, D);
1067 void VarTemplateDecl::getPartialSpecializations(
1068 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1069 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1070 getPartialSpecializations();
1072 PS.reserve(PartialSpecs.size());
1073 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1074 PS.push_back(P.getMostRecentDecl());
1077 VarTemplatePartialSpecializationDecl *
1078 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1079 VarTemplatePartialSpecializationDecl *D) {
1080 Decl *DCanon = D->getCanonicalDecl();
1081 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1082 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1083 return P.getMostRecentDecl();
1089 //===----------------------------------------------------------------------===//
1090 // VarTemplateSpecializationDecl Implementation
1091 //===----------------------------------------------------------------------===//
1093 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1094 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1095 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1096 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1097 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1098 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1099 SpecializedTemplate(SpecializedTemplate),
1100 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1101 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1103 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1105 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1106 QualType(), nullptr, SC_None),
1107 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1109 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1110 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1111 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1112 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1113 return new (Context, DC) VarTemplateSpecializationDecl(
1114 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1115 SpecializedTemplate, T, TInfo, S, Args);
1118 VarTemplateSpecializationDecl *
1119 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1121 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1124 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1125 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1126 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1128 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1129 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1130 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1131 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1133 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1134 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1138 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1139 if (const auto *PartialSpec =
1140 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1141 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1142 return SpecializedTemplate.get<VarTemplateDecl *>();
1145 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1146 const TemplateArgumentListInfo &ArgsInfo) {
1147 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1148 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1149 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1150 TemplateArgsInfo.addArgument(Loc);
1153 //===----------------------------------------------------------------------===//
1154 // VarTemplatePartialSpecializationDecl Implementation
1155 //===----------------------------------------------------------------------===//
1157 void VarTemplatePartialSpecializationDecl::anchor() {}
1159 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1160 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1161 SourceLocation IdLoc, TemplateParameterList *Params,
1162 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1163 StorageClass S, ArrayRef<TemplateArgument> Args,
1164 const ASTTemplateArgumentListInfo *ArgInfos)
1165 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1166 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1168 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1169 InstantiatedFromMember(nullptr, false) {
1170 // TODO: The template parameters should be in DC by now. Verify.
1171 // AdoptTemplateParameterList(Params, DC);
1174 VarTemplatePartialSpecializationDecl *
1175 VarTemplatePartialSpecializationDecl::Create(
1176 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1177 SourceLocation IdLoc, TemplateParameterList *Params,
1178 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1179 StorageClass S, ArrayRef<TemplateArgument> Args,
1180 const TemplateArgumentListInfo &ArgInfos) {
1181 const ASTTemplateArgumentListInfo *ASTArgInfos
1182 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1185 new (Context, DC) VarTemplatePartialSpecializationDecl(
1186 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1187 S, Args, ASTArgInfos);
1188 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1192 VarTemplatePartialSpecializationDecl *
1193 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1195 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1198 static TemplateParameterList *
1199 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1201 auto *T = TemplateTypeParmDecl::Create(
1202 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1203 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1204 T->setImplicit(true);
1207 TypeSourceInfo *TI =
1208 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1209 auto *N = NonTypeTemplateParmDecl::Create(
1210 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1212 N->setImplicit(true);
1214 // <typename T, T ...Ints>
1215 NamedDecl *P[2] = {T, N};
1216 auto *TPL = TemplateParameterList::Create(
1217 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1219 // template <typename T, ...Ints> class IntSeq
1220 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1221 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1222 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1223 TemplateTemplateParm->setImplicit(true);
1226 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1227 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1228 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1229 TemplateTypeParm->setImplicit(true);
1232 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1233 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1234 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1235 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1236 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1237 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1238 NonTypeTemplateParm};
1240 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1241 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1242 Params, SourceLocation(), nullptr);
1245 static TemplateParameterList *
1246 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1247 // std::size_t Index
1248 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1249 auto *Index = NonTypeTemplateParmDecl::Create(
1250 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1251 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1254 auto *Ts = TemplateTypeParmDecl::Create(
1255 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1256 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1257 Ts->setImplicit(true);
1259 // template <std::size_t Index, typename ...T>
1260 NamedDecl *Params[] = {Index, Ts};
1261 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1262 llvm::makeArrayRef(Params),
1263 SourceLocation(), nullptr);
1266 static TemplateParameterList *createBuiltinTemplateParameterList(
1267 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1269 case BTK__make_integer_seq:
1270 return createMakeIntegerSeqParameterList(C, DC);
1271 case BTK__type_pack_element:
1272 return createTypePackElementParameterList(C, DC);
1275 llvm_unreachable("unhandled BuiltinTemplateKind!");
1278 void BuiltinTemplateDecl::anchor() {}
1280 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1281 DeclarationName Name,
1282 BuiltinTemplateKind BTK)
1283 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1284 createBuiltinTemplateParameterList(C, DC, BTK)),