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,
36 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
37 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
38 HasRequiresClause(static_cast<bool>(RequiresClause)) {
39 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
40 NamedDecl *P = Params[Idx];
43 if (!P->isTemplateParameterPack()) {
44 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
45 if (NTTP->getType()->containsUnexpandedParameterPack())
46 ContainsUnexpandedParameterPack = true;
48 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
49 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
50 ContainsUnexpandedParameterPack = true;
52 // FIXME: If a default argument contains an unexpanded parameter pack, the
53 // template parameter list does too.
57 *getTrailingObjects<Expr *>() = RequiresClause;
61 TemplateParameterList *
62 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
63 SourceLocation LAngleLoc,
64 ArrayRef<NamedDecl *> Params,
65 SourceLocation RAngleLoc, Expr *RequiresClause) {
66 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
67 Params.size(), RequiresClause ? 1u : 0u),
68 alignof(TemplateParameterList));
69 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
70 RAngleLoc, RequiresClause);
73 unsigned TemplateParameterList::getMinRequiredArguments() const {
74 unsigned NumRequiredArgs = 0;
75 for (const NamedDecl *P : asArray()) {
76 if (P->isTemplateParameterPack()) {
77 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
78 if (NTTP->isExpandedParameterPack()) {
79 NumRequiredArgs += NTTP->getNumExpansionTypes();
86 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
87 if (TTP->hasDefaultArgument())
89 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
90 if (NTTP->hasDefaultArgument())
92 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
98 return NumRequiredArgs;
101 unsigned TemplateParameterList::getDepth() const {
105 const NamedDecl *FirstParm = getParam(0);
106 if (const TemplateTypeParmDecl *TTP
107 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
108 return TTP->getDepth();
109 else if (const NonTypeTemplateParmDecl *NTTP
110 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
111 return NTTP->getDepth();
113 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
116 static void AdoptTemplateParameterList(TemplateParameterList *Params,
117 DeclContext *Owner) {
118 for (NamedDecl *P : *Params) {
119 P->setDeclContext(Owner);
121 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
122 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
127 void *allocateDefaultArgStorageChain(const ASTContext &C) {
128 return new (C) char[sizeof(void*) * 2];
132 //===----------------------------------------------------------------------===//
133 // RedeclarableTemplateDecl Implementation
134 //===----------------------------------------------------------------------===//
136 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
140 // Walk the previous-declaration chain until we either find a declaration
141 // with a common pointer or we run out of previous declarations.
142 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
143 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
144 Prev = Prev->getPreviousDecl()) {
146 Common = Prev->Common;
150 PrevDecls.push_back(Prev);
153 // If we never found a common pointer, allocate one now.
155 // FIXME: If any of the declarations is from an AST file, we probably
156 // need an update record to add the common data.
158 Common = newCommon(getASTContext());
161 // Update any previous declarations we saw with the common pointer.
162 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
163 Prev->Common = Common;
168 template<class EntryType>
169 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
170 RedeclarableTemplateDecl::findSpecializationImpl(
171 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
173 typedef SpecEntryTraits<EntryType> SETraits;
174 llvm::FoldingSetNodeID ID;
175 EntryType::Profile(ID,Args, getASTContext());
176 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
177 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
180 template<class Derived, class EntryType>
181 void RedeclarableTemplateDecl::addSpecializationImpl(
182 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
184 typedef SpecEntryTraits<EntryType> SETraits;
187 void *CorrectInsertPos;
188 assert(!findSpecializationImpl(Specializations,
189 SETraits::getTemplateArgs(Entry),
191 InsertPos == CorrectInsertPos &&
192 "given incorrect InsertPos for specialization");
194 Specializations.InsertNode(Entry, InsertPos);
196 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
198 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
199 "non-canonical specialization?");
202 if (ASTMutationListener *L = getASTMutationListener())
203 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
204 SETraits::getDecl(Entry));
207 //===----------------------------------------------------------------------===//
208 // FunctionTemplateDecl Implementation
209 //===----------------------------------------------------------------------===//
211 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
212 static_cast<Common *>(Ptr)->~Common();
215 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
218 DeclarationName Name,
219 TemplateParameterList *Params,
221 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
222 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
225 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
227 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
228 DeclarationName(), nullptr, nullptr);
231 RedeclarableTemplateDecl::CommonBase *
232 FunctionTemplateDecl::newCommon(ASTContext &C) const {
233 Common *CommonPtr = new (C) Common;
234 C.AddDeallocation(DeallocateCommon, CommonPtr);
238 void FunctionTemplateDecl::LoadLazySpecializations() const {
239 // Grab the most recent declaration to ensure we've loaded any lazy
240 // redeclarations of this template.
242 // FIXME: Avoid walking the entire redeclaration chain here.
243 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
244 if (CommonPtr->LazySpecializations) {
245 ASTContext &Context = getASTContext();
246 uint32_t *Specs = CommonPtr->LazySpecializations;
247 CommonPtr->LazySpecializations = nullptr;
248 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
249 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
253 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
254 FunctionTemplateDecl::getSpecializations() const {
255 LoadLazySpecializations();
256 return getCommonPtr()->Specializations;
260 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
262 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
265 void FunctionTemplateDecl::addSpecialization(
266 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
267 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
271 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
272 TemplateParameterList *Params = getTemplateParameters();
273 Common *CommonPtr = getCommonPtr();
274 if (!CommonPtr->InjectedArgs) {
275 auto &Context = getASTContext();
276 SmallVector<TemplateArgument, 16> TemplateArgs;
277 Context.getInjectedTemplateArgs(Params, TemplateArgs);
278 CommonPtr->InjectedArgs =
279 new (Context) TemplateArgument[TemplateArgs.size()];
280 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
281 CommonPtr->InjectedArgs);
284 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
287 //===----------------------------------------------------------------------===//
288 // ClassTemplateDecl Implementation
289 //===----------------------------------------------------------------------===//
291 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
292 static_cast<Common *>(Ptr)->~Common();
295 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
298 DeclarationName Name,
299 TemplateParameterList *Params,
301 ClassTemplateDecl *PrevDecl) {
302 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
303 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
305 New->setPreviousDecl(PrevDecl);
309 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
311 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
312 DeclarationName(), nullptr, nullptr);
315 void ClassTemplateDecl::LoadLazySpecializations() const {
316 // Grab the most recent declaration to ensure we've loaded any lazy
317 // redeclarations of this template.
319 // FIXME: Avoid walking the entire redeclaration chain here.
320 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
321 if (CommonPtr->LazySpecializations) {
322 ASTContext &Context = getASTContext();
323 uint32_t *Specs = CommonPtr->LazySpecializations;
324 CommonPtr->LazySpecializations = nullptr;
325 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
326 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
330 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
331 ClassTemplateDecl::getSpecializations() const {
332 LoadLazySpecializations();
333 return getCommonPtr()->Specializations;
336 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
337 ClassTemplateDecl::getPartialSpecializations() {
338 LoadLazySpecializations();
339 return getCommonPtr()->PartialSpecializations;
342 RedeclarableTemplateDecl::CommonBase *
343 ClassTemplateDecl::newCommon(ASTContext &C) const {
344 Common *CommonPtr = new (C) Common;
345 C.AddDeallocation(DeallocateCommon, CommonPtr);
349 ClassTemplateSpecializationDecl *
350 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
352 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
355 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
357 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
360 ClassTemplatePartialSpecializationDecl *
361 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
363 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
366 void ClassTemplateDecl::AddPartialSpecialization(
367 ClassTemplatePartialSpecializationDecl *D,
370 getPartialSpecializations().InsertNode(D, InsertPos);
372 ClassTemplatePartialSpecializationDecl *Existing
373 = getPartialSpecializations().GetOrInsertNode(D);
375 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
378 if (ASTMutationListener *L = getASTMutationListener())
379 L->AddedCXXTemplateSpecialization(this, D);
382 void ClassTemplateDecl::getPartialSpecializations(
383 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
384 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
385 = getPartialSpecializations();
387 PS.reserve(PartialSpecs.size());
388 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
389 PS.push_back(P.getMostRecentDecl());
392 ClassTemplatePartialSpecializationDecl *
393 ClassTemplateDecl::findPartialSpecialization(QualType T) {
394 ASTContext &Context = getASTContext();
395 for (ClassTemplatePartialSpecializationDecl &P :
396 getPartialSpecializations()) {
397 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
398 return P.getMostRecentDecl();
404 ClassTemplatePartialSpecializationDecl *
405 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
406 ClassTemplatePartialSpecializationDecl *D) {
407 Decl *DCanon = D->getCanonicalDecl();
408 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
409 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
410 return P.getMostRecentDecl();
417 ClassTemplateDecl::getInjectedClassNameSpecialization() {
418 Common *CommonPtr = getCommonPtr();
419 if (!CommonPtr->InjectedClassNameType.isNull())
420 return CommonPtr->InjectedClassNameType;
422 // C++0x [temp.dep.type]p2:
423 // The template argument list of a primary template is a template argument
424 // list in which the nth template argument has the value of the nth template
425 // parameter of the class template. If the nth template parameter is a
426 // template parameter pack (14.5.3), the nth template argument is a pack
427 // expansion (14.5.3) whose pattern is the name of the template parameter
429 ASTContext &Context = getASTContext();
430 TemplateParameterList *Params = getTemplateParameters();
431 SmallVector<TemplateArgument, 16> TemplateArgs;
432 Context.getInjectedTemplateArgs(Params, TemplateArgs);
433 CommonPtr->InjectedClassNameType
434 = Context.getTemplateSpecializationType(TemplateName(this),
436 return CommonPtr->InjectedClassNameType;
439 //===----------------------------------------------------------------------===//
440 // TemplateTypeParm Allocation/Deallocation Method Implementations
441 //===----------------------------------------------------------------------===//
443 TemplateTypeParmDecl *
444 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
445 SourceLocation KeyLoc, SourceLocation NameLoc,
446 unsigned D, unsigned P, IdentifierInfo *Id,
447 bool Typename, bool ParameterPack) {
448 TemplateTypeParmDecl *TTPDecl =
449 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
450 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
451 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
455 TemplateTypeParmDecl *
456 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
457 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
458 SourceLocation(), nullptr, false);
461 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
462 return hasDefaultArgument()
463 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
467 SourceRange TemplateTypeParmDecl::getSourceRange() const {
468 if (hasDefaultArgument() && !defaultArgumentWasInherited())
469 return SourceRange(getLocStart(),
470 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
472 return TypeDecl::getSourceRange();
475 unsigned TemplateTypeParmDecl::getDepth() const {
476 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
479 unsigned TemplateTypeParmDecl::getIndex() const {
480 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
483 bool TemplateTypeParmDecl::isParameterPack() const {
484 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
487 //===----------------------------------------------------------------------===//
488 // NonTypeTemplateParmDecl Method Implementations
489 //===----------------------------------------------------------------------===//
491 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
492 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
493 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
494 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
495 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
496 TemplateParmPosition(D, P), ParameterPack(true),
497 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
498 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
500 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
501 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
502 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
503 TypesAndInfos[I].second = ExpandedTInfos[I];
508 NonTypeTemplateParmDecl *
509 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
510 SourceLocation StartLoc, SourceLocation IdLoc,
511 unsigned D, unsigned P, IdentifierInfo *Id,
512 QualType T, bool ParameterPack,
513 TypeSourceInfo *TInfo) {
514 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
515 T, ParameterPack, TInfo);
518 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
519 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
520 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
521 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
522 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
524 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
525 ExpandedTypes.size()))
526 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
527 ExpandedTypes, ExpandedTInfos);
530 NonTypeTemplateParmDecl *
531 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
532 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
533 SourceLocation(), 0, 0, nullptr,
534 QualType(), false, nullptr);
537 NonTypeTemplateParmDecl *
538 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
539 unsigned NumExpandedTypes) {
541 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
543 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
544 0, 0, nullptr, QualType(), nullptr, None,
546 NTTP->NumExpandedTypes = NumExpandedTypes;
550 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
551 if (hasDefaultArgument() && !defaultArgumentWasInherited())
552 return SourceRange(getOuterLocStart(),
553 getDefaultArgument()->getSourceRange().getEnd());
554 return DeclaratorDecl::getSourceRange();
557 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
558 return hasDefaultArgument()
559 ? getDefaultArgument()->getSourceRange().getBegin()
563 //===----------------------------------------------------------------------===//
564 // TemplateTemplateParmDecl Method Implementations
565 //===----------------------------------------------------------------------===//
567 void TemplateTemplateParmDecl::anchor() { }
569 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
570 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
571 IdentifierInfo *Id, TemplateParameterList *Params,
572 ArrayRef<TemplateParameterList *> Expansions)
573 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
574 TemplateParmPosition(D, P), ParameterPack(true),
575 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
576 if (!Expansions.empty())
577 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
578 getTrailingObjects<TemplateParameterList *>());
581 TemplateTemplateParmDecl *
582 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
583 SourceLocation L, unsigned D, unsigned P,
584 bool ParameterPack, IdentifierInfo *Id,
585 TemplateParameterList *Params) {
586 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
590 TemplateTemplateParmDecl *
591 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
592 SourceLocation L, unsigned D, unsigned P,
594 TemplateParameterList *Params,
595 ArrayRef<TemplateParameterList *> Expansions) {
597 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
598 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
601 TemplateTemplateParmDecl *
602 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
603 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
604 false, nullptr, nullptr);
607 TemplateTemplateParmDecl *
608 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
609 unsigned NumExpansions) {
611 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
612 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
614 TTP->NumExpandedParams = NumExpansions;
618 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
619 return hasDefaultArgument() ? getDefaultArgument().getLocation()
623 void TemplateTemplateParmDecl::setDefaultArgument(
624 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
625 if (DefArg.getArgument().isNull())
626 DefaultArgument.set(nullptr);
628 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
631 //===----------------------------------------------------------------------===//
632 // TemplateArgumentList Implementation
633 //===----------------------------------------------------------------------===//
634 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
635 : Arguments(getTrailingObjects<TemplateArgument>()),
636 NumArguments(Args.size()) {
637 std::uninitialized_copy(Args.begin(), Args.end(),
638 getTrailingObjects<TemplateArgument>());
641 TemplateArgumentList *
642 TemplateArgumentList::CreateCopy(ASTContext &Context,
643 ArrayRef<TemplateArgument> Args) {
644 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
645 return new (Mem) TemplateArgumentList(Args);
648 FunctionTemplateSpecializationInfo *
649 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
650 FunctionTemplateDecl *Template,
651 TemplateSpecializationKind TSK,
652 const TemplateArgumentList *TemplateArgs,
653 const TemplateArgumentListInfo *TemplateArgsAsWritten,
654 SourceLocation POI) {
655 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
656 if (TemplateArgsAsWritten)
657 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
658 *TemplateArgsAsWritten);
660 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
666 //===----------------------------------------------------------------------===//
667 // TemplateDecl Implementation
668 //===----------------------------------------------------------------------===//
670 void TemplateDecl::anchor() { }
672 //===----------------------------------------------------------------------===//
673 // ClassTemplateSpecializationDecl Implementation
674 //===----------------------------------------------------------------------===//
675 ClassTemplateSpecializationDecl::
676 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
677 DeclContext *DC, SourceLocation StartLoc,
678 SourceLocation IdLoc,
679 ClassTemplateDecl *SpecializedTemplate,
680 ArrayRef<TemplateArgument> Args,
681 ClassTemplateSpecializationDecl *PrevDecl)
682 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
683 SpecializedTemplate->getIdentifier(),
685 SpecializedTemplate(SpecializedTemplate),
686 ExplicitInfo(nullptr),
687 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
688 SpecializationKind(TSK_Undeclared) {
691 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
693 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
694 SourceLocation(), nullptr, nullptr),
695 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
697 ClassTemplateSpecializationDecl *
698 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
700 SourceLocation StartLoc,
701 SourceLocation IdLoc,
702 ClassTemplateDecl *SpecializedTemplate,
703 ArrayRef<TemplateArgument> Args,
704 ClassTemplateSpecializationDecl *PrevDecl) {
705 ClassTemplateSpecializationDecl *Result =
706 new (Context, DC) ClassTemplateSpecializationDecl(
707 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
708 SpecializedTemplate, Args, PrevDecl);
709 Result->MayHaveOutOfDateDef = false;
711 Context.getTypeDeclType(Result, PrevDecl);
715 ClassTemplateSpecializationDecl *
716 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
718 ClassTemplateSpecializationDecl *Result =
719 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
720 Result->MayHaveOutOfDateDef = false;
724 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
725 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
726 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
728 auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
729 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
730 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
731 TemplateSpecializationType::PrintTemplateArgumentList(
732 OS, ArgsAsWritten->arguments(), Policy);
734 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
735 TemplateSpecializationType::PrintTemplateArgumentList(
736 OS, TemplateArgs.asArray(), Policy);
741 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
742 if (SpecializedPartialSpecialization *PartialSpec
743 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
744 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
745 return SpecializedTemplate.get<ClassTemplateDecl*>();
749 ClassTemplateSpecializationDecl::getSourceRange() const {
751 SourceLocation Begin = getTemplateKeywordLoc();
752 if (Begin.isValid()) {
753 // Here we have an explicit (partial) specialization or instantiation.
754 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
755 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
756 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
757 if (getExternLoc().isValid())
758 Begin = getExternLoc();
759 SourceLocation End = getBraceRange().getEnd();
761 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
762 return SourceRange(Begin, End);
764 // An implicit instantiation of a class template partial specialization
765 // uses ExplicitInfo to record the TypeAsWritten, but the source
766 // locations should be retrieved from the instantiation pattern.
767 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
768 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
769 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
770 assert(inst_from != nullptr);
771 return inst_from->getSourceRange();
774 // No explicit info available.
775 llvm::PointerUnion<ClassTemplateDecl *,
776 ClassTemplatePartialSpecializationDecl *>
777 inst_from = getInstantiatedFrom();
778 if (inst_from.isNull())
779 return getSpecializedTemplate()->getSourceRange();
780 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
781 return ctd->getSourceRange();
782 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
787 //===----------------------------------------------------------------------===//
788 // ClassTemplatePartialSpecializationDecl Implementation
789 //===----------------------------------------------------------------------===//
790 void ClassTemplatePartialSpecializationDecl::anchor() { }
792 ClassTemplatePartialSpecializationDecl::
793 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
795 SourceLocation StartLoc,
796 SourceLocation IdLoc,
797 TemplateParameterList *Params,
798 ClassTemplateDecl *SpecializedTemplate,
799 ArrayRef<TemplateArgument> Args,
800 const ASTTemplateArgumentListInfo *ArgInfos,
801 ClassTemplatePartialSpecializationDecl *PrevDecl)
802 : ClassTemplateSpecializationDecl(Context,
803 ClassTemplatePartialSpecialization,
804 TK, DC, StartLoc, IdLoc,
807 TemplateParams(Params), ArgsAsWritten(ArgInfos),
808 InstantiatedFromMember(nullptr, false)
810 AdoptTemplateParameterList(Params, this);
813 ClassTemplatePartialSpecializationDecl *
814 ClassTemplatePartialSpecializationDecl::
815 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
816 SourceLocation StartLoc, SourceLocation IdLoc,
817 TemplateParameterList *Params,
818 ClassTemplateDecl *SpecializedTemplate,
819 ArrayRef<TemplateArgument> Args,
820 const TemplateArgumentListInfo &ArgInfos,
821 QualType CanonInjectedType,
822 ClassTemplatePartialSpecializationDecl *PrevDecl) {
823 const ASTTemplateArgumentListInfo *ASTArgInfos =
824 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
826 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
827 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
828 Params, SpecializedTemplate, Args,
829 ASTArgInfos, PrevDecl);
830 Result->setSpecializationKind(TSK_ExplicitSpecialization);
831 Result->MayHaveOutOfDateDef = false;
833 Context.getInjectedClassNameType(Result, CanonInjectedType);
837 ClassTemplatePartialSpecializationDecl *
838 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
840 ClassTemplatePartialSpecializationDecl *Result =
841 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
842 Result->MayHaveOutOfDateDef = false;
846 //===----------------------------------------------------------------------===//
847 // FriendTemplateDecl Implementation
848 //===----------------------------------------------------------------------===//
850 void FriendTemplateDecl::anchor() { }
853 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
855 MutableArrayRef<TemplateParameterList *> Params,
856 FriendUnion Friend, SourceLocation FLoc) {
857 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
860 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
862 return new (C, ID) FriendTemplateDecl(EmptyShell());
865 //===----------------------------------------------------------------------===//
866 // TypeAliasTemplateDecl Implementation
867 //===----------------------------------------------------------------------===//
869 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
872 DeclarationName Name,
873 TemplateParameterList *Params,
875 AdoptTemplateParameterList(Params, DC);
876 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
879 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
881 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
882 DeclarationName(), nullptr, nullptr);
885 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
886 static_cast<Common *>(Ptr)->~Common();
888 RedeclarableTemplateDecl::CommonBase *
889 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
890 Common *CommonPtr = new (C) Common;
891 C.AddDeallocation(DeallocateCommon, CommonPtr);
895 //===----------------------------------------------------------------------===//
896 // ClassScopeFunctionSpecializationDecl Implementation
897 //===----------------------------------------------------------------------===//
899 void ClassScopeFunctionSpecializationDecl::anchor() { }
901 ClassScopeFunctionSpecializationDecl *
902 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
904 return new (C, ID) ClassScopeFunctionSpecializationDecl(
905 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
908 //===----------------------------------------------------------------------===//
909 // VarTemplateDecl Implementation
910 //===----------------------------------------------------------------------===//
912 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
913 static_cast<Common *>(Ptr)->~Common();
916 VarTemplateDecl *VarTemplateDecl::getDefinition() {
917 VarTemplateDecl *CurD = this;
919 if (CurD->isThisDeclarationADefinition())
921 CurD = CurD->getPreviousDecl();
926 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
927 SourceLocation L, DeclarationName Name,
928 TemplateParameterList *Params,
930 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
933 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
935 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
936 DeclarationName(), nullptr, nullptr);
939 // TODO: Unify across class, function and variable templates?
940 // May require moving this and Common to RedeclarableTemplateDecl.
941 void VarTemplateDecl::LoadLazySpecializations() const {
942 // Grab the most recent declaration to ensure we've loaded any lazy
943 // redeclarations of this template.
945 // FIXME: Avoid walking the entire redeclaration chain here.
946 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
947 if (CommonPtr->LazySpecializations) {
948 ASTContext &Context = getASTContext();
949 uint32_t *Specs = CommonPtr->LazySpecializations;
950 CommonPtr->LazySpecializations = nullptr;
951 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
952 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
956 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
957 VarTemplateDecl::getSpecializations() const {
958 LoadLazySpecializations();
959 return getCommonPtr()->Specializations;
962 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
963 VarTemplateDecl::getPartialSpecializations() {
964 LoadLazySpecializations();
965 return getCommonPtr()->PartialSpecializations;
968 RedeclarableTemplateDecl::CommonBase *
969 VarTemplateDecl::newCommon(ASTContext &C) const {
970 Common *CommonPtr = new (C) Common;
971 C.AddDeallocation(DeallocateCommon, CommonPtr);
975 VarTemplateSpecializationDecl *
976 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
978 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
981 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
983 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
986 VarTemplatePartialSpecializationDecl *
987 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
989 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
992 void VarTemplateDecl::AddPartialSpecialization(
993 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
995 getPartialSpecializations().InsertNode(D, InsertPos);
997 VarTemplatePartialSpecializationDecl *Existing =
998 getPartialSpecializations().GetOrInsertNode(D);
1000 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1003 if (ASTMutationListener *L = getASTMutationListener())
1004 L->AddedCXXTemplateSpecialization(this, D);
1007 void VarTemplateDecl::getPartialSpecializations(
1008 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1009 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1010 getPartialSpecializations();
1012 PS.reserve(PartialSpecs.size());
1013 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1014 PS.push_back(P.getMostRecentDecl());
1017 VarTemplatePartialSpecializationDecl *
1018 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1019 VarTemplatePartialSpecializationDecl *D) {
1020 Decl *DCanon = D->getCanonicalDecl();
1021 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1022 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1023 return P.getMostRecentDecl();
1029 //===----------------------------------------------------------------------===//
1030 // VarTemplateSpecializationDecl Implementation
1031 //===----------------------------------------------------------------------===//
1032 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1033 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1034 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1035 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1036 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1037 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1038 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1039 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1040 SpecializationKind(TSK_Undeclared) {}
1042 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1044 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1045 QualType(), nullptr, SC_None),
1046 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1048 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1049 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1050 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1051 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1052 return new (Context, DC) VarTemplateSpecializationDecl(
1053 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1054 SpecializedTemplate, T, TInfo, S, Args);
1057 VarTemplateSpecializationDecl *
1058 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1060 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1063 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1064 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1065 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1067 auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1068 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1069 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1070 TemplateSpecializationType::PrintTemplateArgumentList(
1071 OS, ArgsAsWritten->arguments(), Policy);
1073 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1074 TemplateSpecializationType::PrintTemplateArgumentList(
1075 OS, TemplateArgs.asArray(), Policy);
1079 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1080 if (SpecializedPartialSpecialization *PartialSpec =
1081 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1082 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1083 return SpecializedTemplate.get<VarTemplateDecl *>();
1086 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1087 const TemplateArgumentListInfo &ArgsInfo) {
1088 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1089 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1090 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1091 TemplateArgsInfo.addArgument(Loc);
1094 //===----------------------------------------------------------------------===//
1095 // VarTemplatePartialSpecializationDecl Implementation
1096 //===----------------------------------------------------------------------===//
1097 void VarTemplatePartialSpecializationDecl::anchor() {}
1099 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1100 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1101 SourceLocation IdLoc, TemplateParameterList *Params,
1102 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1103 StorageClass S, ArrayRef<TemplateArgument> Args,
1104 const ASTTemplateArgumentListInfo *ArgInfos)
1105 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1106 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1108 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1109 InstantiatedFromMember(nullptr, false) {
1110 // TODO: The template parameters should be in DC by now. Verify.
1111 // AdoptTemplateParameterList(Params, DC);
1114 VarTemplatePartialSpecializationDecl *
1115 VarTemplatePartialSpecializationDecl::Create(
1116 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1117 SourceLocation IdLoc, TemplateParameterList *Params,
1118 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1119 StorageClass S, ArrayRef<TemplateArgument> Args,
1120 const TemplateArgumentListInfo &ArgInfos) {
1121 const ASTTemplateArgumentListInfo *ASTArgInfos
1122 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1124 VarTemplatePartialSpecializationDecl *Result =
1125 new (Context, DC) VarTemplatePartialSpecializationDecl(
1126 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1127 S, Args, ASTArgInfos);
1128 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1132 VarTemplatePartialSpecializationDecl *
1133 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1135 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1138 static TemplateParameterList *
1139 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1141 auto *T = TemplateTypeParmDecl::Create(
1142 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1143 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1144 T->setImplicit(true);
1147 TypeSourceInfo *TI =
1148 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1149 auto *N = NonTypeTemplateParmDecl::Create(
1150 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1151 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1152 N->setImplicit(true);
1154 // <typename T, T ...Ints>
1155 NamedDecl *P[2] = {T, N};
1156 auto *TPL = TemplateParameterList::Create(
1157 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1159 // template <typename T, ...Ints> class IntSeq
1160 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1161 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1162 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1163 TemplateTemplateParm->setImplicit(true);
1166 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1167 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1168 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1169 TemplateTypeParm->setImplicit(true);
1172 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1173 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1174 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1175 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1176 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1177 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1178 NonTypeTemplateParm};
1180 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1181 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1182 Params, SourceLocation(), nullptr);
1185 static TemplateParameterList *
1186 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1187 // std::size_t Index
1188 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1189 auto *Index = NonTypeTemplateParmDecl::Create(
1190 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1191 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1194 auto *Ts = TemplateTypeParmDecl::Create(
1195 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1196 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1197 Ts->setImplicit(true);
1199 // template <std::size_t Index, typename ...T>
1200 NamedDecl *Params[] = {Index, Ts};
1201 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1202 llvm::makeArrayRef(Params),
1203 SourceLocation(), nullptr);
1206 static TemplateParameterList *createBuiltinTemplateParameterList(
1207 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1209 case BTK__make_integer_seq:
1210 return createMakeIntegerSeqParameterList(C, DC);
1211 case BTK__type_pack_element:
1212 return createTypePackElementParameterList(C, DC);
1215 llvm_unreachable("unhandled BuiltinTemplateKind!");
1218 void BuiltinTemplateDecl::anchor() {}
1220 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1221 DeclarationName Name,
1222 BuiltinTemplateKind BTK)
1223 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1224 createBuiltinTemplateParameterList(C, DC, BTK)),