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;
76 TemplateParameterList *
77 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
78 SourceLocation LAngleLoc,
79 ArrayRef<NamedDecl *> Params,
80 SourceLocation RAngleLoc, Expr *RequiresClause) {
81 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
82 Params.size(), RequiresClause ? 1u : 0u),
83 alignof(TemplateParameterList));
84 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
85 RAngleLoc, RequiresClause);
88 unsigned TemplateParameterList::getMinRequiredArguments() const {
89 unsigned NumRequiredArgs = 0;
90 for (const NamedDecl *P : asArray()) {
91 if (P->isTemplateParameterPack()) {
92 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
93 if (NTTP->isExpandedParameterPack()) {
94 NumRequiredArgs += NTTP->getNumExpansionTypes();
101 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
102 if (TTP->hasDefaultArgument())
104 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
105 if (NTTP->hasDefaultArgument())
107 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
113 return NumRequiredArgs;
116 unsigned TemplateParameterList::getDepth() const {
120 const NamedDecl *FirstParm = getParam(0);
121 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
122 return TTP->getDepth();
123 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
124 return NTTP->getDepth();
126 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
129 static void AdoptTemplateParameterList(TemplateParameterList *Params,
130 DeclContext *Owner) {
131 for (NamedDecl *P : *Params) {
132 P->setDeclContext(Owner);
134 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
135 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
141 void *allocateDefaultArgStorageChain(const ASTContext &C) {
142 return new (C) char[sizeof(void*) * 2];
147 //===----------------------------------------------------------------------===//
148 // RedeclarableTemplateDecl Implementation
149 //===----------------------------------------------------------------------===//
151 void RedeclarableTemplateDecl::anchor() {}
153 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
157 // Walk the previous-declaration chain until we either find a declaration
158 // with a common pointer or we run out of previous declarations.
159 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
160 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
161 Prev = Prev->getPreviousDecl()) {
163 Common = Prev->Common;
167 PrevDecls.push_back(Prev);
170 // If we never found a common pointer, allocate one now.
172 // FIXME: If any of the declarations is from an AST file, we probably
173 // need an update record to add the common data.
175 Common = newCommon(getASTContext());
178 // Update any previous declarations we saw with the common pointer.
179 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
180 Prev->Common = Common;
185 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
186 // Grab the most recent declaration to ensure we've loaded any lazy
187 // redeclarations of this template.
188 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
189 if (CommonBasePtr->LazySpecializations) {
190 ASTContext &Context = getASTContext();
191 uint32_t *Specs = CommonBasePtr->LazySpecializations;
192 CommonBasePtr->LazySpecializations = nullptr;
193 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
194 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
198 template<class EntryType>
199 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
200 RedeclarableTemplateDecl::findSpecializationImpl(
201 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
203 using SETraits = SpecEntryTraits<EntryType>;
205 llvm::FoldingSetNodeID ID;
206 EntryType::Profile(ID, Args, getASTContext());
207 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
208 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
211 template<class Derived, class EntryType>
212 void RedeclarableTemplateDecl::addSpecializationImpl(
213 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
215 using SETraits = SpecEntryTraits<EntryType>;
219 void *CorrectInsertPos;
220 assert(!findSpecializationImpl(Specializations,
221 SETraits::getTemplateArgs(Entry),
223 InsertPos == CorrectInsertPos &&
224 "given incorrect InsertPos for specialization");
226 Specializations.InsertNode(Entry, InsertPos);
228 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
230 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
231 "non-canonical specialization?");
234 if (ASTMutationListener *L = getASTMutationListener())
235 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
236 SETraits::getDecl(Entry));
239 //===----------------------------------------------------------------------===//
240 // FunctionTemplateDecl Implementation
241 //===----------------------------------------------------------------------===//
243 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
246 DeclarationName Name,
247 TemplateParameterList *Params,
249 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
250 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
253 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
255 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
256 DeclarationName(), nullptr, nullptr);
259 RedeclarableTemplateDecl::CommonBase *
260 FunctionTemplateDecl::newCommon(ASTContext &C) const {
261 auto *CommonPtr = new (C) Common;
262 C.addDestruction(CommonPtr);
266 void FunctionTemplateDecl::LoadLazySpecializations() const {
267 loadLazySpecializationsImpl();
270 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
271 FunctionTemplateDecl::getSpecializations() const {
272 LoadLazySpecializations();
273 return getCommonPtr()->Specializations;
277 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
279 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
282 void FunctionTemplateDecl::addSpecialization(
283 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
284 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
288 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
289 TemplateParameterList *Params = getTemplateParameters();
290 Common *CommonPtr = getCommonPtr();
291 if (!CommonPtr->InjectedArgs) {
292 auto &Context = getASTContext();
293 SmallVector<TemplateArgument, 16> TemplateArgs;
294 Context.getInjectedTemplateArgs(Params, TemplateArgs);
295 CommonPtr->InjectedArgs =
296 new (Context) TemplateArgument[TemplateArgs.size()];
297 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
298 CommonPtr->InjectedArgs);
301 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
304 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
305 using Base = RedeclarableTemplateDecl;
307 // If we haven't created a common pointer yet, then it can just be created
308 // with the usual method.
312 Common *ThisCommon = static_cast<Common *>(Base::Common);
313 Common *PrevCommon = nullptr;
314 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
315 for (; Prev; Prev = Prev->getPreviousDecl()) {
316 if (Prev->Base::Common) {
317 PrevCommon = static_cast<Common *>(Prev->Base::Common);
320 PreviousDecls.push_back(Prev);
323 // If the previous redecl chain hasn't created a common pointer yet, then just
324 // use this common pointer.
326 for (auto *D : PreviousDecls)
327 D->Base::Common = ThisCommon;
331 // Ensure we don't leak any important state.
332 assert(ThisCommon->Specializations.size() == 0 &&
333 "Can't merge incompatible declarations!");
335 Base::Common = PrevCommon;
338 //===----------------------------------------------------------------------===//
339 // ClassTemplateDecl Implementation
340 //===----------------------------------------------------------------------===//
342 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
345 DeclarationName Name,
346 TemplateParameterList *Params,
348 Expr *AssociatedConstraints) {
349 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
351 if (!AssociatedConstraints) {
352 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
355 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
357 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
358 New->setAssociatedConstraints(AssociatedConstraints);
362 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
364 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
365 DeclarationName(), nullptr, nullptr);
368 void ClassTemplateDecl::LoadLazySpecializations() const {
369 loadLazySpecializationsImpl();
372 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
373 ClassTemplateDecl::getSpecializations() const {
374 LoadLazySpecializations();
375 return getCommonPtr()->Specializations;
378 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
379 ClassTemplateDecl::getPartialSpecializations() {
380 LoadLazySpecializations();
381 return getCommonPtr()->PartialSpecializations;
384 RedeclarableTemplateDecl::CommonBase *
385 ClassTemplateDecl::newCommon(ASTContext &C) const {
386 auto *CommonPtr = new (C) Common;
387 C.addDestruction(CommonPtr);
391 ClassTemplateSpecializationDecl *
392 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
394 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
397 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
399 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
402 ClassTemplatePartialSpecializationDecl *
403 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
405 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
408 void ClassTemplateDecl::AddPartialSpecialization(
409 ClassTemplatePartialSpecializationDecl *D,
412 getPartialSpecializations().InsertNode(D, InsertPos);
414 ClassTemplatePartialSpecializationDecl *Existing
415 = getPartialSpecializations().GetOrInsertNode(D);
417 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
420 if (ASTMutationListener *L = getASTMutationListener())
421 L->AddedCXXTemplateSpecialization(this, D);
424 void ClassTemplateDecl::getPartialSpecializations(
425 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
426 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
427 = getPartialSpecializations();
429 PS.reserve(PartialSpecs.size());
430 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
431 PS.push_back(P.getMostRecentDecl());
434 ClassTemplatePartialSpecializationDecl *
435 ClassTemplateDecl::findPartialSpecialization(QualType T) {
436 ASTContext &Context = getASTContext();
437 for (ClassTemplatePartialSpecializationDecl &P :
438 getPartialSpecializations()) {
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 (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
451 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
452 return P.getMostRecentDecl();
459 ClassTemplateDecl::getInjectedClassNameSpecialization() {
460 Common *CommonPtr = getCommonPtr();
461 if (!CommonPtr->InjectedClassNameType.isNull())
462 return CommonPtr->InjectedClassNameType;
464 // C++0x [temp.dep.type]p2:
465 // The template argument list of a primary template is a template argument
466 // list in which the nth template argument has the value of the nth template
467 // parameter of the class template. If the nth template parameter is a
468 // template parameter pack (14.5.3), the nth template argument is a pack
469 // expansion (14.5.3) whose pattern is the name of the template parameter
471 ASTContext &Context = getASTContext();
472 TemplateParameterList *Params = getTemplateParameters();
473 SmallVector<TemplateArgument, 16> TemplateArgs;
474 Context.getInjectedTemplateArgs(Params, TemplateArgs);
475 CommonPtr->InjectedClassNameType
476 = Context.getTemplateSpecializationType(TemplateName(this),
478 return CommonPtr->InjectedClassNameType;
481 //===----------------------------------------------------------------------===//
482 // TemplateTypeParm Allocation/Deallocation Method Implementations
483 //===----------------------------------------------------------------------===//
485 TemplateTypeParmDecl *
486 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
487 SourceLocation KeyLoc, SourceLocation NameLoc,
488 unsigned D, unsigned P, IdentifierInfo *Id,
489 bool Typename, bool ParameterPack) {
491 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
492 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
493 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
497 TemplateTypeParmDecl *
498 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
499 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
500 SourceLocation(), nullptr, false);
503 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
504 return hasDefaultArgument()
505 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
509 SourceRange TemplateTypeParmDecl::getSourceRange() const {
510 if (hasDefaultArgument() && !defaultArgumentWasInherited())
511 return SourceRange(getBeginLoc(),
512 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
514 return TypeDecl::getSourceRange();
517 unsigned TemplateTypeParmDecl::getDepth() const {
518 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
521 unsigned TemplateTypeParmDecl::getIndex() const {
522 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
525 bool TemplateTypeParmDecl::isParameterPack() const {
526 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
529 //===----------------------------------------------------------------------===//
530 // NonTypeTemplateParmDecl Method Implementations
531 //===----------------------------------------------------------------------===//
533 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
534 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
535 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
536 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
537 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
538 TemplateParmPosition(D, P), ParameterPack(true),
539 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
540 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
542 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
543 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
544 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
545 TypesAndInfos[I].second = ExpandedTInfos[I];
550 NonTypeTemplateParmDecl *
551 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
552 SourceLocation StartLoc, SourceLocation IdLoc,
553 unsigned D, unsigned P, IdentifierInfo *Id,
554 QualType T, bool ParameterPack,
555 TypeSourceInfo *TInfo) {
556 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
557 T, ParameterPack, TInfo);
560 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
561 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
562 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
563 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
564 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
566 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
567 ExpandedTypes.size()))
568 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
569 ExpandedTypes, ExpandedTInfos);
572 NonTypeTemplateParmDecl *
573 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
574 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
575 SourceLocation(), 0, 0, nullptr,
576 QualType(), false, nullptr);
579 NonTypeTemplateParmDecl *
580 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
581 unsigned NumExpandedTypes) {
583 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
585 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
586 0, 0, nullptr, QualType(), nullptr, None,
588 NTTP->NumExpandedTypes = NumExpandedTypes;
592 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
593 if (hasDefaultArgument() && !defaultArgumentWasInherited())
594 return SourceRange(getOuterLocStart(),
595 getDefaultArgument()->getSourceRange().getEnd());
596 return DeclaratorDecl::getSourceRange();
599 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
600 return hasDefaultArgument()
601 ? getDefaultArgument()->getSourceRange().getBegin()
605 //===----------------------------------------------------------------------===//
606 // TemplateTemplateParmDecl Method Implementations
607 //===----------------------------------------------------------------------===//
609 void TemplateTemplateParmDecl::anchor() {}
611 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
612 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
613 IdentifierInfo *Id, TemplateParameterList *Params,
614 ArrayRef<TemplateParameterList *> Expansions)
615 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
616 TemplateParmPosition(D, P), ParameterPack(true),
617 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
618 if (!Expansions.empty())
619 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
620 getTrailingObjects<TemplateParameterList *>());
623 TemplateTemplateParmDecl *
624 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
625 SourceLocation L, unsigned D, unsigned P,
626 bool ParameterPack, IdentifierInfo *Id,
627 TemplateParameterList *Params) {
628 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
632 TemplateTemplateParmDecl *
633 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
634 SourceLocation L, unsigned D, unsigned P,
636 TemplateParameterList *Params,
637 ArrayRef<TemplateParameterList *> Expansions) {
639 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
640 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
643 TemplateTemplateParmDecl *
644 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
645 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
646 false, nullptr, nullptr);
649 TemplateTemplateParmDecl *
650 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
651 unsigned NumExpansions) {
653 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
654 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
656 TTP->NumExpandedParams = NumExpansions;
660 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
661 return hasDefaultArgument() ? getDefaultArgument().getLocation()
665 void TemplateTemplateParmDecl::setDefaultArgument(
666 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
667 if (DefArg.getArgument().isNull())
668 DefaultArgument.set(nullptr);
670 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
673 //===----------------------------------------------------------------------===//
674 // TemplateArgumentList Implementation
675 //===----------------------------------------------------------------------===//
676 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
677 : Arguments(getTrailingObjects<TemplateArgument>()),
678 NumArguments(Args.size()) {
679 std::uninitialized_copy(Args.begin(), Args.end(),
680 getTrailingObjects<TemplateArgument>());
683 TemplateArgumentList *
684 TemplateArgumentList::CreateCopy(ASTContext &Context,
685 ArrayRef<TemplateArgument> Args) {
686 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
687 return new (Mem) TemplateArgumentList(Args);
690 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
691 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
692 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
693 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
694 MemberSpecializationInfo *MSInfo) {
695 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
696 if (TemplateArgsAsWritten)
697 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
698 *TemplateArgsAsWritten);
701 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
702 return new (Mem) FunctionTemplateSpecializationInfo(
703 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
706 //===----------------------------------------------------------------------===//
707 // TemplateDecl Implementation
708 //===----------------------------------------------------------------------===//
710 void TemplateDecl::anchor() {}
712 //===----------------------------------------------------------------------===//
713 // ClassTemplateSpecializationDecl Implementation
714 //===----------------------------------------------------------------------===//
716 ClassTemplateSpecializationDecl::
717 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
718 DeclContext *DC, SourceLocation StartLoc,
719 SourceLocation IdLoc,
720 ClassTemplateDecl *SpecializedTemplate,
721 ArrayRef<TemplateArgument> Args,
722 ClassTemplateSpecializationDecl *PrevDecl)
723 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
724 SpecializedTemplate->getIdentifier(), PrevDecl),
725 SpecializedTemplate(SpecializedTemplate),
726 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
727 SpecializationKind(TSK_Undeclared) {
730 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
732 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
733 SourceLocation(), nullptr, nullptr),
734 SpecializationKind(TSK_Undeclared) {}
736 ClassTemplateSpecializationDecl *
737 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
739 SourceLocation StartLoc,
740 SourceLocation IdLoc,
741 ClassTemplateDecl *SpecializedTemplate,
742 ArrayRef<TemplateArgument> Args,
743 ClassTemplateSpecializationDecl *PrevDecl) {
745 new (Context, DC) ClassTemplateSpecializationDecl(
746 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
747 SpecializedTemplate, Args, PrevDecl);
748 Result->setMayHaveOutOfDateDef(false);
750 Context.getTypeDeclType(Result, PrevDecl);
754 ClassTemplateSpecializationDecl *
755 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
758 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
759 Result->setMayHaveOutOfDateDef(false);
763 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
764 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
765 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
767 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
768 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
769 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
770 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
772 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
773 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
778 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
779 if (const auto *PartialSpec =
780 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
781 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
782 return SpecializedTemplate.get<ClassTemplateDecl*>();
786 ClassTemplateSpecializationDecl::getSourceRange() const {
788 SourceLocation Begin = getTemplateKeywordLoc();
789 if (Begin.isValid()) {
790 // Here we have an explicit (partial) specialization or instantiation.
791 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
792 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
793 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
794 if (getExternLoc().isValid())
795 Begin = getExternLoc();
796 SourceLocation End = getBraceRange().getEnd();
798 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
799 return SourceRange(Begin, End);
801 // An implicit instantiation of a class template partial specialization
802 // uses ExplicitInfo to record the TypeAsWritten, but the source
803 // locations should be retrieved from the instantiation pattern.
804 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
805 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
806 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
807 assert(inst_from != nullptr);
808 return inst_from->getSourceRange();
811 // No explicit info available.
812 llvm::PointerUnion<ClassTemplateDecl *,
813 ClassTemplatePartialSpecializationDecl *>
814 inst_from = getInstantiatedFrom();
815 if (inst_from.isNull())
816 return getSpecializedTemplate()->getSourceRange();
817 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
818 return ctd->getSourceRange();
819 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
824 //===----------------------------------------------------------------------===//
825 // ConceptDecl Implementation
826 //===----------------------------------------------------------------------===//
827 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
828 SourceLocation L, DeclarationName Name,
829 TemplateParameterList *Params,
830 Expr *ConstraintExpr) {
831 AdoptTemplateParameterList(Params, DC);
832 return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
835 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
837 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
844 //===----------------------------------------------------------------------===//
845 // ClassTemplatePartialSpecializationDecl Implementation
846 //===----------------------------------------------------------------------===//
847 void ClassTemplatePartialSpecializationDecl::anchor() {}
849 ClassTemplatePartialSpecializationDecl::
850 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
852 SourceLocation StartLoc,
853 SourceLocation IdLoc,
854 TemplateParameterList *Params,
855 ClassTemplateDecl *SpecializedTemplate,
856 ArrayRef<TemplateArgument> Args,
857 const ASTTemplateArgumentListInfo *ArgInfos,
858 ClassTemplatePartialSpecializationDecl *PrevDecl)
859 : ClassTemplateSpecializationDecl(Context,
860 ClassTemplatePartialSpecialization,
861 TK, DC, StartLoc, IdLoc,
862 SpecializedTemplate, Args, PrevDecl),
863 TemplateParams(Params), ArgsAsWritten(ArgInfos),
864 InstantiatedFromMember(nullptr, false) {
865 AdoptTemplateParameterList(Params, this);
868 ClassTemplatePartialSpecializationDecl *
869 ClassTemplatePartialSpecializationDecl::
870 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
871 SourceLocation StartLoc, SourceLocation IdLoc,
872 TemplateParameterList *Params,
873 ClassTemplateDecl *SpecializedTemplate,
874 ArrayRef<TemplateArgument> Args,
875 const TemplateArgumentListInfo &ArgInfos,
876 QualType CanonInjectedType,
877 ClassTemplatePartialSpecializationDecl *PrevDecl) {
878 const ASTTemplateArgumentListInfo *ASTArgInfos =
879 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
881 auto *Result = new (Context, DC)
882 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
883 Params, SpecializedTemplate, Args,
884 ASTArgInfos, PrevDecl);
885 Result->setSpecializationKind(TSK_ExplicitSpecialization);
886 Result->setMayHaveOutOfDateDef(false);
888 Context.getInjectedClassNameType(Result, CanonInjectedType);
892 ClassTemplatePartialSpecializationDecl *
893 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
895 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
896 Result->setMayHaveOutOfDateDef(false);
900 //===----------------------------------------------------------------------===//
901 // FriendTemplateDecl Implementation
902 //===----------------------------------------------------------------------===//
904 void FriendTemplateDecl::anchor() {}
907 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
909 MutableArrayRef<TemplateParameterList *> Params,
910 FriendUnion Friend, SourceLocation FLoc) {
911 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
914 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
916 return new (C, ID) FriendTemplateDecl(EmptyShell());
919 //===----------------------------------------------------------------------===//
920 // TypeAliasTemplateDecl Implementation
921 //===----------------------------------------------------------------------===//
923 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
926 DeclarationName Name,
927 TemplateParameterList *Params,
929 AdoptTemplateParameterList(Params, DC);
930 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
933 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
935 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
936 DeclarationName(), nullptr, nullptr);
939 RedeclarableTemplateDecl::CommonBase *
940 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
941 auto *CommonPtr = new (C) Common;
942 C.addDestruction(CommonPtr);
946 //===----------------------------------------------------------------------===//
947 // ClassScopeFunctionSpecializationDecl Implementation
948 //===----------------------------------------------------------------------===//
950 void ClassScopeFunctionSpecializationDecl::anchor() {}
952 ClassScopeFunctionSpecializationDecl *
953 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
955 return new (C, ID) ClassScopeFunctionSpecializationDecl(
956 nullptr, SourceLocation(), nullptr, nullptr);
959 //===----------------------------------------------------------------------===//
960 // VarTemplateDecl Implementation
961 //===----------------------------------------------------------------------===//
963 VarTemplateDecl *VarTemplateDecl::getDefinition() {
964 VarTemplateDecl *CurD = this;
966 if (CurD->isThisDeclarationADefinition())
968 CurD = CurD->getPreviousDecl();
973 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
974 SourceLocation L, DeclarationName Name,
975 TemplateParameterList *Params,
977 AdoptTemplateParameterList(Params, DC);
978 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
981 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
983 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
984 DeclarationName(), nullptr, nullptr);
987 void VarTemplateDecl::LoadLazySpecializations() const {
988 loadLazySpecializationsImpl();
991 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
992 VarTemplateDecl::getSpecializations() const {
993 LoadLazySpecializations();
994 return getCommonPtr()->Specializations;
997 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
998 VarTemplateDecl::getPartialSpecializations() {
999 LoadLazySpecializations();
1000 return getCommonPtr()->PartialSpecializations;
1003 RedeclarableTemplateDecl::CommonBase *
1004 VarTemplateDecl::newCommon(ASTContext &C) const {
1005 auto *CommonPtr = new (C) Common;
1006 C.addDestruction(CommonPtr);
1010 VarTemplateSpecializationDecl *
1011 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1013 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1016 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1018 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1021 VarTemplatePartialSpecializationDecl *
1022 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1024 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1027 void VarTemplateDecl::AddPartialSpecialization(
1028 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1030 getPartialSpecializations().InsertNode(D, InsertPos);
1032 VarTemplatePartialSpecializationDecl *Existing =
1033 getPartialSpecializations().GetOrInsertNode(D);
1035 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1038 if (ASTMutationListener *L = getASTMutationListener())
1039 L->AddedCXXTemplateSpecialization(this, D);
1042 void VarTemplateDecl::getPartialSpecializations(
1043 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1044 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1045 getPartialSpecializations();
1047 PS.reserve(PartialSpecs.size());
1048 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1049 PS.push_back(P.getMostRecentDecl());
1052 VarTemplatePartialSpecializationDecl *
1053 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1054 VarTemplatePartialSpecializationDecl *D) {
1055 Decl *DCanon = D->getCanonicalDecl();
1056 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1057 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1058 return P.getMostRecentDecl();
1064 //===----------------------------------------------------------------------===//
1065 // VarTemplateSpecializationDecl Implementation
1066 //===----------------------------------------------------------------------===//
1068 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1069 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1070 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1071 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1072 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1073 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1074 SpecializedTemplate(SpecializedTemplate),
1075 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1076 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1078 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1080 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1081 QualType(), nullptr, SC_None),
1082 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1084 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1085 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1086 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1087 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1088 return new (Context, DC) VarTemplateSpecializationDecl(
1089 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1090 SpecializedTemplate, T, TInfo, S, Args);
1093 VarTemplateSpecializationDecl *
1094 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1096 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1099 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1100 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1101 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1103 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1104 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1105 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1106 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1108 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1109 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1113 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1114 if (const auto *PartialSpec =
1115 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1116 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1117 return SpecializedTemplate.get<VarTemplateDecl *>();
1120 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1121 const TemplateArgumentListInfo &ArgsInfo) {
1122 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1123 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1124 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1125 TemplateArgsInfo.addArgument(Loc);
1128 //===----------------------------------------------------------------------===//
1129 // VarTemplatePartialSpecializationDecl Implementation
1130 //===----------------------------------------------------------------------===//
1132 void VarTemplatePartialSpecializationDecl::anchor() {}
1134 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1135 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1136 SourceLocation IdLoc, TemplateParameterList *Params,
1137 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1138 StorageClass S, ArrayRef<TemplateArgument> Args,
1139 const ASTTemplateArgumentListInfo *ArgInfos)
1140 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1141 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1143 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1144 InstantiatedFromMember(nullptr, false) {
1145 // TODO: The template parameters should be in DC by now. Verify.
1146 // AdoptTemplateParameterList(Params, DC);
1149 VarTemplatePartialSpecializationDecl *
1150 VarTemplatePartialSpecializationDecl::Create(
1151 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1152 SourceLocation IdLoc, TemplateParameterList *Params,
1153 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1154 StorageClass S, ArrayRef<TemplateArgument> Args,
1155 const TemplateArgumentListInfo &ArgInfos) {
1156 const ASTTemplateArgumentListInfo *ASTArgInfos
1157 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1160 new (Context, DC) VarTemplatePartialSpecializationDecl(
1161 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1162 S, Args, ASTArgInfos);
1163 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1167 VarTemplatePartialSpecializationDecl *
1168 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1170 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1173 static TemplateParameterList *
1174 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1176 auto *T = TemplateTypeParmDecl::Create(
1177 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1178 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1179 T->setImplicit(true);
1182 TypeSourceInfo *TI =
1183 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1184 auto *N = NonTypeTemplateParmDecl::Create(
1185 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1186 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1187 N->setImplicit(true);
1189 // <typename T, T ...Ints>
1190 NamedDecl *P[2] = {T, N};
1191 auto *TPL = TemplateParameterList::Create(
1192 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1194 // template <typename T, ...Ints> class IntSeq
1195 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1196 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1197 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1198 TemplateTemplateParm->setImplicit(true);
1201 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1202 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1203 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1204 TemplateTypeParm->setImplicit(true);
1207 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1208 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1209 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1210 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1211 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1212 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1213 NonTypeTemplateParm};
1215 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1216 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1217 Params, SourceLocation(), nullptr);
1220 static TemplateParameterList *
1221 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1222 // std::size_t Index
1223 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1224 auto *Index = NonTypeTemplateParmDecl::Create(
1225 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1226 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1229 auto *Ts = TemplateTypeParmDecl::Create(
1230 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1231 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1232 Ts->setImplicit(true);
1234 // template <std::size_t Index, typename ...T>
1235 NamedDecl *Params[] = {Index, Ts};
1236 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1237 llvm::makeArrayRef(Params),
1238 SourceLocation(), nullptr);
1241 static TemplateParameterList *createBuiltinTemplateParameterList(
1242 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1244 case BTK__make_integer_seq:
1245 return createMakeIntegerSeqParameterList(C, DC);
1246 case BTK__type_pack_element:
1247 return createTypePackElementParameterList(C, DC);
1250 llvm_unreachable("unhandled BuiltinTemplateKind!");
1253 void BuiltinTemplateDecl::anchor() {}
1255 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1256 DeclarationName Name,
1257 BuiltinTemplateKind BTK)
1258 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1259 createBuiltinTemplateParameterList(C, DC, BTK)),