[clang-tidy][NFC]remove deps of clang in clang tidy test (#116588)
[llvm-project.git] / clang / lib / AST / DeclTemplate.cpp
blobf487032a37ab733da130ec7aaa1fa4fe617fbace
1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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/PointerUnion.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include <cassert>
34 #include <memory>
35 #include <optional>
36 #include <utility>
38 using namespace clang;
40 //===----------------------------------------------------------------------===//
41 // TemplateParameterList Implementation
42 //===----------------------------------------------------------------------===//
44 template <class TemplateParam>
45 static bool
46 DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
47 return P.hasDefaultArgument() &&
48 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
51 TemplateParameterList::TemplateParameterList(const ASTContext &C,
52 SourceLocation TemplateLoc,
53 SourceLocation LAngleLoc,
54 ArrayRef<NamedDecl *> Params,
55 SourceLocation RAngleLoc,
56 Expr *RequiresClause)
57 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
58 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
59 HasRequiresClause(RequiresClause != nullptr),
60 HasConstrainedParameters(false) {
61 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
62 NamedDecl *P = Params[Idx];
63 begin()[Idx] = P;
65 bool IsPack = P->isTemplateParameterPack();
66 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
67 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
68 DefaultTemplateArgumentContainsUnexpandedPack(*NTTP)))
69 ContainsUnexpandedParameterPack = true;
70 if (NTTP->hasPlaceholderTypeConstraint())
71 HasConstrainedParameters = true;
72 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
73 if (!IsPack &&
74 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
75 DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) {
76 ContainsUnexpandedParameterPack = true;
78 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
79 if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) {
80 ContainsUnexpandedParameterPack = true;
81 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
82 TC && TC->getImmediatelyDeclaredConstraint()
83 ->containsUnexpandedParameterPack()) {
84 ContainsUnexpandedParameterPack = true;
86 if (TTP->hasTypeConstraint())
87 HasConstrainedParameters = true;
88 } else {
89 llvm_unreachable("unexpected template parameter type");
93 if (HasRequiresClause) {
94 if (RequiresClause->containsUnexpandedParameterPack())
95 ContainsUnexpandedParameterPack = true;
96 *getTrailingObjects<Expr *>() = RequiresClause;
100 bool TemplateParameterList::containsUnexpandedParameterPack() const {
101 if (ContainsUnexpandedParameterPack)
102 return true;
103 if (!HasConstrainedParameters)
104 return false;
106 // An implicit constrained parameter might have had a use of an unexpanded
107 // pack added to it after the template parameter list was created. All
108 // implicit parameters are at the end of the parameter list.
109 for (const NamedDecl *Param : llvm::reverse(asArray())) {
110 if (!Param->isImplicit())
111 break;
113 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
114 const auto *TC = TTP->getTypeConstraint();
115 if (TC && TC->getImmediatelyDeclaredConstraint()
116 ->containsUnexpandedParameterPack())
117 return true;
121 return false;
124 TemplateParameterList *
125 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
126 SourceLocation LAngleLoc,
127 ArrayRef<NamedDecl *> Params,
128 SourceLocation RAngleLoc, Expr *RequiresClause) {
129 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
130 Params.size(), RequiresClause ? 1u : 0u),
131 alignof(TemplateParameterList));
132 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
133 RAngleLoc, RequiresClause);
136 void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
137 const ASTContext &C) const {
138 const Expr *RC = getRequiresClause();
139 ID.AddBoolean(RC != nullptr);
140 if (RC)
141 RC->Profile(ID, C, /*Canonical=*/true);
142 ID.AddInteger(size());
143 for (NamedDecl *D : *this) {
144 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
145 ID.AddInteger(0);
146 ID.AddBoolean(NTTP->isParameterPack());
147 NTTP->getType().getCanonicalType().Profile(ID);
148 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
149 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
150 E->Profile(ID, C, /*Canonical=*/true);
151 continue;
153 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
154 ID.AddInteger(1);
155 ID.AddBoolean(TTP->isParameterPack());
156 ID.AddBoolean(TTP->hasTypeConstraint());
157 if (const TypeConstraint *TC = TTP->getTypeConstraint())
158 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
159 /*Canonical=*/true);
160 continue;
162 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
163 ID.AddInteger(2);
164 ID.AddBoolean(TTP->isParameterPack());
165 TTP->getTemplateParameters()->Profile(ID, C);
169 unsigned TemplateParameterList::getMinRequiredArguments() const {
170 unsigned NumRequiredArgs = 0;
171 for (const NamedDecl *P : asArray()) {
172 if (P->isTemplateParameterPack()) {
173 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
174 NumRequiredArgs += *Expansions;
175 continue;
177 break;
180 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
181 if (TTP->hasDefaultArgument())
182 break;
183 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
184 if (NTTP->hasDefaultArgument())
185 break;
186 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
187 break;
189 ++NumRequiredArgs;
192 return NumRequiredArgs;
195 unsigned TemplateParameterList::getDepth() const {
196 if (size() == 0)
197 return 0;
199 const NamedDecl *FirstParm = getParam(0);
200 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
201 return TTP->getDepth();
202 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
203 return NTTP->getDepth();
204 else
205 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
208 static bool AdoptTemplateParameterList(TemplateParameterList *Params,
209 DeclContext *Owner) {
210 bool Invalid = false;
211 for (NamedDecl *P : *Params) {
212 P->setDeclContext(Owner);
214 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
215 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
216 Invalid = true;
218 if (P->isInvalidDecl())
219 Invalid = true;
221 return Invalid;
224 void TemplateParameterList::
225 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
226 if (HasConstrainedParameters)
227 for (const NamedDecl *Param : *this) {
228 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
229 if (const auto *TC = TTP->getTypeConstraint())
230 AC.push_back(TC->getImmediatelyDeclaredConstraint());
231 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
232 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
233 AC.push_back(E);
236 if (HasRequiresClause)
237 AC.push_back(getRequiresClause());
240 bool TemplateParameterList::hasAssociatedConstraints() const {
241 return HasRequiresClause || HasConstrainedParameters;
244 ArrayRef<TemplateArgument>
245 TemplateParameterList::getInjectedTemplateArgs(const ASTContext &Context) {
246 if (!InjectedArgs) {
247 InjectedArgs = new (Context) TemplateArgument[size()];
248 llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) {
249 return Context.getInjectedTemplateArg(ND);
252 return {InjectedArgs, NumParams};
255 bool TemplateParameterList::shouldIncludeTypeForArgument(
256 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
257 unsigned Idx) {
258 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
259 return true;
260 const NamedDecl *TemplParam = TPL->getParam(Idx);
261 if (const auto *ParamValueDecl =
262 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
263 if (ParamValueDecl->getType()->getContainedDeducedType())
264 return true;
265 return false;
268 namespace clang {
270 void *allocateDefaultArgStorageChain(const ASTContext &C) {
271 return new (C) char[sizeof(void*) * 2];
274 } // namespace clang
276 //===----------------------------------------------------------------------===//
277 // TemplateDecl Implementation
278 //===----------------------------------------------------------------------===//
280 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
281 DeclarationName Name, TemplateParameterList *Params,
282 NamedDecl *Decl)
283 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
285 void TemplateDecl::anchor() {}
287 void TemplateDecl::
288 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
289 TemplateParams->getAssociatedConstraints(AC);
290 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
291 if (const Expr *TRC = FD->getTrailingRequiresClause())
292 AC.push_back(TRC);
295 bool TemplateDecl::hasAssociatedConstraints() const {
296 if (TemplateParams->hasAssociatedConstraints())
297 return true;
298 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
299 return FD->getTrailingRequiresClause();
300 return false;
303 bool TemplateDecl::isTypeAlias() const {
304 switch (getKind()) {
305 case TemplateDecl::TypeAliasTemplate:
306 case TemplateDecl::BuiltinTemplate:
307 return true;
308 default:
309 return false;
313 //===----------------------------------------------------------------------===//
314 // RedeclarableTemplateDecl Implementation
315 //===----------------------------------------------------------------------===//
317 void RedeclarableTemplateDecl::anchor() {}
319 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
320 if (Common)
321 return Common;
323 // Walk the previous-declaration chain until we either find a declaration
324 // with a common pointer or we run out of previous declarations.
325 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
326 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
327 Prev = Prev->getPreviousDecl()) {
328 if (Prev->Common) {
329 Common = Prev->Common;
330 break;
333 PrevDecls.push_back(Prev);
336 // If we never found a common pointer, allocate one now.
337 if (!Common) {
338 // FIXME: If any of the declarations is from an AST file, we probably
339 // need an update record to add the common data.
341 Common = newCommon(getASTContext());
344 // Update any previous declarations we saw with the common pointer.
345 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
346 Prev->Common = Common;
348 return Common;
351 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
352 // Grab the most recent declaration to ensure we've loaded any lazy
353 // redeclarations of this template.
354 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
355 if (CommonBasePtr->LazySpecializations) {
356 ASTContext &Context = getASTContext();
357 GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
358 CommonBasePtr->LazySpecializations = nullptr;
359 unsigned SpecSize = (*Specs++).getRawValue();
360 for (unsigned I = 0; I != SpecSize; ++I)
361 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
365 template<class EntryType, typename... ProfileArguments>
366 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
367 RedeclarableTemplateDecl::findSpecializationImpl(
368 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
369 ProfileArguments&&... ProfileArgs) {
370 using SETraits = SpecEntryTraits<EntryType>;
372 llvm::FoldingSetNodeID ID;
373 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
374 getASTContext());
375 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
376 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
379 template<class Derived, class EntryType>
380 void RedeclarableTemplateDecl::addSpecializationImpl(
381 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
382 void *InsertPos) {
383 using SETraits = SpecEntryTraits<EntryType>;
385 if (InsertPos) {
386 #ifndef NDEBUG
387 void *CorrectInsertPos;
388 assert(!findSpecializationImpl(Specializations,
389 CorrectInsertPos,
390 SETraits::getTemplateArgs(Entry)) &&
391 InsertPos == CorrectInsertPos &&
392 "given incorrect InsertPos for specialization");
393 #endif
394 Specializations.InsertNode(Entry, InsertPos);
395 } else {
396 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
397 (void)Existing;
398 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
399 "non-canonical specialization?");
402 if (ASTMutationListener *L = getASTMutationListener())
403 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
404 SETraits::getDecl(Entry));
407 //===----------------------------------------------------------------------===//
408 // FunctionTemplateDecl Implementation
409 //===----------------------------------------------------------------------===//
411 FunctionTemplateDecl *
412 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
413 DeclarationName Name,
414 TemplateParameterList *Params, NamedDecl *Decl) {
415 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
416 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
417 if (Invalid)
418 TD->setInvalidDecl();
419 return TD;
422 FunctionTemplateDecl *
423 FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
424 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
425 DeclarationName(), nullptr, nullptr);
428 RedeclarableTemplateDecl::CommonBase *
429 FunctionTemplateDecl::newCommon(ASTContext &C) const {
430 auto *CommonPtr = new (C) Common;
431 C.addDestruction(CommonPtr);
432 return CommonPtr;
435 void FunctionTemplateDecl::LoadLazySpecializations() const {
436 loadLazySpecializationsImpl();
439 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
440 FunctionTemplateDecl::getSpecializations() const {
441 LoadLazySpecializations();
442 return getCommonPtr()->Specializations;
445 FunctionDecl *
446 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
447 void *&InsertPos) {
448 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
451 void FunctionTemplateDecl::addSpecialization(
452 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
453 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
454 InsertPos);
457 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
458 using Base = RedeclarableTemplateDecl;
460 // If we haven't created a common pointer yet, then it can just be created
461 // with the usual method.
462 if (!Base::Common)
463 return;
465 Common *ThisCommon = static_cast<Common *>(Base::Common);
466 Common *PrevCommon = nullptr;
467 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
468 for (; Prev; Prev = Prev->getPreviousDecl()) {
469 if (Prev->Base::Common) {
470 PrevCommon = static_cast<Common *>(Prev->Base::Common);
471 break;
473 PreviousDecls.push_back(Prev);
476 // If the previous redecl chain hasn't created a common pointer yet, then just
477 // use this common pointer.
478 if (!PrevCommon) {
479 for (auto *D : PreviousDecls)
480 D->Base::Common = ThisCommon;
481 return;
484 // Ensure we don't leak any important state.
485 assert(ThisCommon->Specializations.size() == 0 &&
486 "Can't merge incompatible declarations!");
488 Base::Common = PrevCommon;
491 //===----------------------------------------------------------------------===//
492 // ClassTemplateDecl Implementation
493 //===----------------------------------------------------------------------===//
495 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
496 SourceLocation L,
497 DeclarationName Name,
498 TemplateParameterList *Params,
499 NamedDecl *Decl) {
500 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
501 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
502 if (Invalid)
503 TD->setInvalidDecl();
504 return TD;
507 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
508 GlobalDeclID ID) {
509 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
510 DeclarationName(), nullptr, nullptr);
513 void ClassTemplateDecl::LoadLazySpecializations() const {
514 loadLazySpecializationsImpl();
517 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
518 ClassTemplateDecl::getSpecializations() const {
519 LoadLazySpecializations();
520 return getCommonPtr()->Specializations;
523 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
524 ClassTemplateDecl::getPartialSpecializations() const {
525 LoadLazySpecializations();
526 return getCommonPtr()->PartialSpecializations;
529 RedeclarableTemplateDecl::CommonBase *
530 ClassTemplateDecl::newCommon(ASTContext &C) const {
531 auto *CommonPtr = new (C) Common;
532 C.addDestruction(CommonPtr);
533 return CommonPtr;
536 ClassTemplateSpecializationDecl *
537 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
538 void *&InsertPos) {
539 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
542 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
543 void *InsertPos) {
544 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
547 ClassTemplatePartialSpecializationDecl *
548 ClassTemplateDecl::findPartialSpecialization(
549 ArrayRef<TemplateArgument> Args,
550 TemplateParameterList *TPL, void *&InsertPos) {
551 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
552 TPL);
555 void ClassTemplatePartialSpecializationDecl::Profile(
556 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
557 TemplateParameterList *TPL, const ASTContext &Context) {
558 ID.AddInteger(TemplateArgs.size());
559 for (const TemplateArgument &TemplateArg : TemplateArgs)
560 TemplateArg.Profile(ID, Context);
561 TPL->Profile(ID, Context);
564 void ClassTemplateDecl::AddPartialSpecialization(
565 ClassTemplatePartialSpecializationDecl *D,
566 void *InsertPos) {
567 if (InsertPos)
568 getPartialSpecializations().InsertNode(D, InsertPos);
569 else {
570 ClassTemplatePartialSpecializationDecl *Existing
571 = getPartialSpecializations().GetOrInsertNode(D);
572 (void)Existing;
573 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
576 if (ASTMutationListener *L = getASTMutationListener())
577 L->AddedCXXTemplateSpecialization(this, D);
580 void ClassTemplateDecl::getPartialSpecializations(
581 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
582 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
583 = getPartialSpecializations();
584 PS.clear();
585 PS.reserve(PartialSpecs.size());
586 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
587 PS.push_back(P.getMostRecentDecl());
590 ClassTemplatePartialSpecializationDecl *
591 ClassTemplateDecl::findPartialSpecialization(QualType T) {
592 ASTContext &Context = getASTContext();
593 for (ClassTemplatePartialSpecializationDecl &P :
594 getPartialSpecializations()) {
595 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
596 return P.getMostRecentDecl();
599 return nullptr;
602 ClassTemplatePartialSpecializationDecl *
603 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
604 ClassTemplatePartialSpecializationDecl *D) {
605 Decl *DCanon = D->getCanonicalDecl();
606 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
607 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
608 return P.getMostRecentDecl();
611 return nullptr;
614 QualType
615 ClassTemplateDecl::getInjectedClassNameSpecialization() {
616 Common *CommonPtr = getCommonPtr();
617 if (!CommonPtr->InjectedClassNameType.isNull())
618 return CommonPtr->InjectedClassNameType;
620 // C++0x [temp.dep.type]p2:
621 // The template argument list of a primary template is a template argument
622 // list in which the nth template argument has the value of the nth template
623 // parameter of the class template. If the nth template parameter is a
624 // template parameter pack (14.5.3), the nth template argument is a pack
625 // expansion (14.5.3) whose pattern is the name of the template parameter
626 // pack.
627 ASTContext &Context = getASTContext();
628 TemplateName Name = Context.getQualifiedTemplateName(
629 /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
630 CommonPtr->InjectedClassNameType = Context.getTemplateSpecializationType(
631 Name, getTemplateParameters()->getInjectedTemplateArgs(Context));
632 return CommonPtr->InjectedClassNameType;
635 //===----------------------------------------------------------------------===//
636 // TemplateTypeParm Allocation/Deallocation Method Implementations
637 //===----------------------------------------------------------------------===//
639 TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
640 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
641 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
642 bool Typename, bool ParameterPack, bool HasTypeConstraint,
643 std::optional<unsigned> NumExpanded) {
644 auto *TTPDecl =
645 new (C, DC,
646 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
647 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
648 HasTypeConstraint, NumExpanded);
649 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
650 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
651 return TTPDecl;
654 TemplateTypeParmDecl *
655 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) {
656 return new (C, ID)
657 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
658 false, false, std::nullopt);
661 TemplateTypeParmDecl *
662 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
663 bool HasTypeConstraint) {
664 return new (C, ID,
665 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
666 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
667 false, HasTypeConstraint, std::nullopt);
670 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
671 return hasDefaultArgument() ? getDefaultArgument().getLocation()
672 : SourceLocation();
675 SourceRange TemplateTypeParmDecl::getSourceRange() const {
676 if (hasDefaultArgument() && !defaultArgumentWasInherited())
677 return SourceRange(getBeginLoc(),
678 getDefaultArgument().getSourceRange().getEnd());
679 // TypeDecl::getSourceRange returns a range containing name location, which is
680 // wrong for unnamed template parameters. e.g:
681 // it will return <[[typename>]] instead of <[[typename]]>
682 if (getDeclName().isEmpty())
683 return SourceRange(getBeginLoc());
684 return TypeDecl::getSourceRange();
687 void TemplateTypeParmDecl::setDefaultArgument(
688 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
689 if (DefArg.getArgument().isNull())
690 DefaultArgument.set(nullptr);
691 else
692 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
695 unsigned TemplateTypeParmDecl::getDepth() const {
696 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
699 unsigned TemplateTypeParmDecl::getIndex() const {
700 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
703 bool TemplateTypeParmDecl::isParameterPack() const {
704 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
707 void TemplateTypeParmDecl::setTypeConstraint(
708 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
709 assert(HasTypeConstraint &&
710 "HasTypeConstraint=true must be passed at construction in order to "
711 "call setTypeConstraint");
712 assert(!TypeConstraintInitialized &&
713 "TypeConstraint was already initialized!");
714 new (getTrailingObjects<TypeConstraint>())
715 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
716 TypeConstraintInitialized = true;
719 //===----------------------------------------------------------------------===//
720 // NonTypeTemplateParmDecl Method Implementations
721 //===----------------------------------------------------------------------===//
723 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
724 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
725 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
726 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
727 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
728 TemplateParmPosition(D, P), ParameterPack(true),
729 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
730 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
731 auto TypesAndInfos =
732 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
733 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
734 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
735 TypesAndInfos[I].second = ExpandedTInfos[I];
740 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
741 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
742 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
743 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
744 AutoType *AT =
745 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
746 return new (C, DC,
747 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
748 Expr *>(0,
749 AT && AT->isConstrained() ? 1 : 0))
750 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
751 TInfo);
754 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
755 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
756 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
757 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
758 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
759 AutoType *AT = TInfo->getType()->getContainedAutoType();
760 return new (C, DC,
761 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
762 Expr *>(
763 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
764 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
765 ExpandedTypes, ExpandedTInfos);
768 NonTypeTemplateParmDecl *
769 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
770 bool HasTypeConstraint) {
771 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
772 TypeSourceInfo *>,
773 Expr *>(0,
774 HasTypeConstraint ? 1 : 0))
775 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
776 0, 0, nullptr, QualType(), false, nullptr);
779 NonTypeTemplateParmDecl *
780 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
781 unsigned NumExpandedTypes,
782 bool HasTypeConstraint) {
783 auto *NTTP =
784 new (C, ID,
785 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
786 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
787 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
788 0, 0, nullptr, QualType(), nullptr, {}, {});
789 NTTP->NumExpandedTypes = NumExpandedTypes;
790 return NTTP;
793 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
794 if (hasDefaultArgument() && !defaultArgumentWasInherited())
795 return SourceRange(getOuterLocStart(),
796 getDefaultArgument().getSourceRange().getEnd());
797 return DeclaratorDecl::getSourceRange();
800 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
801 return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin()
802 : SourceLocation();
805 void NonTypeTemplateParmDecl::setDefaultArgument(
806 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
807 if (DefArg.getArgument().isNull())
808 DefaultArgument.set(nullptr);
809 else
810 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
813 //===----------------------------------------------------------------------===//
814 // TemplateTemplateParmDecl Method Implementations
815 //===----------------------------------------------------------------------===//
817 void TemplateTemplateParmDecl::anchor() {}
819 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
820 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
821 IdentifierInfo *Id, bool Typename, TemplateParameterList *Params,
822 ArrayRef<TemplateParameterList *> Expansions)
823 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
824 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),
825 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
826 if (!Expansions.empty())
827 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
828 getTrailingObjects<TemplateParameterList *>());
831 TemplateTemplateParmDecl *
832 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
833 SourceLocation L, unsigned D, unsigned P,
834 bool ParameterPack, IdentifierInfo *Id,
835 bool Typename, TemplateParameterList *Params) {
836 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
837 Typename, Params);
840 TemplateTemplateParmDecl *
841 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
842 SourceLocation L, unsigned D, unsigned P,
843 IdentifierInfo *Id, bool Typename,
844 TemplateParameterList *Params,
845 ArrayRef<TemplateParameterList *> Expansions) {
846 return new (C, DC,
847 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
848 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);
851 TemplateTemplateParmDecl *
852 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
853 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
854 false, nullptr, false, nullptr);
857 TemplateTemplateParmDecl *
858 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
859 unsigned NumExpansions) {
860 auto *TTP =
861 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
862 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
863 false, nullptr, {});
864 TTP->NumExpandedParams = NumExpansions;
865 return TTP;
868 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
869 return hasDefaultArgument() ? getDefaultArgument().getLocation()
870 : SourceLocation();
873 void TemplateTemplateParmDecl::setDefaultArgument(
874 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
875 if (DefArg.getArgument().isNull())
876 DefaultArgument.set(nullptr);
877 else
878 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
881 //===----------------------------------------------------------------------===//
882 // TemplateArgumentList Implementation
883 //===----------------------------------------------------------------------===//
884 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
885 : NumArguments(Args.size()) {
886 std::uninitialized_copy(Args.begin(), Args.end(),
887 getTrailingObjects<TemplateArgument>());
890 TemplateArgumentList *
891 TemplateArgumentList::CreateCopy(ASTContext &Context,
892 ArrayRef<TemplateArgument> Args) {
893 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
894 return new (Mem) TemplateArgumentList(Args);
897 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
898 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
899 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
900 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
901 MemberSpecializationInfo *MSInfo) {
902 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
903 if (TemplateArgsAsWritten)
904 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
905 *TemplateArgsAsWritten);
907 void *Mem =
908 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
909 return new (Mem) FunctionTemplateSpecializationInfo(
910 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
913 //===----------------------------------------------------------------------===//
914 // ClassTemplateSpecializationDecl Implementation
915 //===----------------------------------------------------------------------===//
917 ClassTemplateSpecializationDecl::
918 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
919 DeclContext *DC, SourceLocation StartLoc,
920 SourceLocation IdLoc,
921 ClassTemplateDecl *SpecializedTemplate,
922 ArrayRef<TemplateArgument> Args,
923 ClassTemplateSpecializationDecl *PrevDecl)
924 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
925 SpecializedTemplate->getIdentifier(), PrevDecl),
926 SpecializedTemplate(SpecializedTemplate),
927 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
928 SpecializationKind(TSK_Undeclared) {
931 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
932 Kind DK)
933 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
934 SourceLocation(), nullptr, nullptr),
935 SpecializationKind(TSK_Undeclared) {}
937 ClassTemplateSpecializationDecl *
938 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
939 DeclContext *DC,
940 SourceLocation StartLoc,
941 SourceLocation IdLoc,
942 ClassTemplateDecl *SpecializedTemplate,
943 ArrayRef<TemplateArgument> Args,
944 ClassTemplateSpecializationDecl *PrevDecl) {
945 auto *Result =
946 new (Context, DC) ClassTemplateSpecializationDecl(
947 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
948 SpecializedTemplate, Args, PrevDecl);
949 Result->setMayHaveOutOfDateDef(false);
951 // If the template decl is incomplete, copy the external lexical storage from
952 // the base template. This allows instantiations of incomplete types to
953 // complete using the external AST if the template's declaration came from an
954 // external AST.
955 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
956 Result->setHasExternalLexicalStorage(
957 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
959 Context.getTypeDeclType(Result, PrevDecl);
960 return Result;
963 ClassTemplateSpecializationDecl *
964 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
965 GlobalDeclID ID) {
966 auto *Result =
967 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
968 Result->setMayHaveOutOfDateDef(false);
969 return Result;
972 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
973 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
974 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
976 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
977 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
978 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
979 printTemplateArgumentList(
980 OS, ArgsAsWritten->arguments(), Policy,
981 getSpecializedTemplate()->getTemplateParameters());
982 } else {
983 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
984 printTemplateArgumentList(
985 OS, TemplateArgs.asArray(), Policy,
986 getSpecializedTemplate()->getTemplateParameters());
990 ClassTemplateDecl *
991 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
992 if (const auto *PartialSpec =
993 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
994 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
995 return SpecializedTemplate.get<ClassTemplateDecl*>();
998 SourceRange
999 ClassTemplateSpecializationDecl::getSourceRange() const {
1000 switch (getSpecializationKind()) {
1001 case TSK_Undeclared:
1002 case TSK_ImplicitInstantiation: {
1003 llvm::PointerUnion<ClassTemplateDecl *,
1004 ClassTemplatePartialSpecializationDecl *>
1005 Pattern = getSpecializedTemplateOrPartial();
1006 assert(!Pattern.isNull() &&
1007 "Class template specialization without pattern?");
1008 if (const auto *CTPSD =
1009 Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1010 return CTPSD->getSourceRange();
1011 return Pattern.get<ClassTemplateDecl *>()->getSourceRange();
1013 case TSK_ExplicitSpecialization: {
1014 SourceRange Range = CXXRecordDecl::getSourceRange();
1015 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1016 !isThisDeclarationADefinition() && Args)
1017 Range.setEnd(Args->getRAngleLoc());
1018 return Range;
1020 case TSK_ExplicitInstantiationDeclaration:
1021 case TSK_ExplicitInstantiationDefinition: {
1022 SourceRange Range = CXXRecordDecl::getSourceRange();
1023 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1024 Range.setBegin(ExternKW);
1025 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1026 TemplateKW.isValid())
1027 Range.setBegin(TemplateKW);
1028 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1029 Range.setEnd(Args->getRAngleLoc());
1030 return Range;
1033 llvm_unreachable("unhandled template specialization kind");
1036 void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1037 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1038 if (!Info) {
1039 // Don't allocate if the location is invalid.
1040 if (Loc.isInvalid())
1041 return;
1042 Info = new (getASTContext()) ExplicitInstantiationInfo;
1043 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1044 ExplicitInfo = Info;
1046 Info->ExternKeywordLoc = Loc;
1049 void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(
1050 SourceLocation Loc) {
1051 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1052 if (!Info) {
1053 // Don't allocate if the location is invalid.
1054 if (Loc.isInvalid())
1055 return;
1056 Info = new (getASTContext()) ExplicitInstantiationInfo;
1057 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1058 ExplicitInfo = Info;
1060 Info->TemplateKeywordLoc = Loc;
1063 //===----------------------------------------------------------------------===//
1064 // ConceptDecl Implementation
1065 //===----------------------------------------------------------------------===//
1066 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1067 SourceLocation L, DeclarationName Name,
1068 TemplateParameterList *Params,
1069 Expr *ConstraintExpr) {
1070 bool Invalid = AdoptTemplateParameterList(Params, DC);
1071 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1072 if (Invalid)
1073 TD->setInvalidDecl();
1074 return TD;
1077 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1078 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1079 DeclarationName(),
1080 nullptr, nullptr);
1082 return Result;
1085 //===----------------------------------------------------------------------===//
1086 // ImplicitConceptSpecializationDecl Implementation
1087 //===----------------------------------------------------------------------===//
1088 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1089 DeclContext *DC, SourceLocation SL,
1090 ArrayRef<TemplateArgument> ConvertedArgs)
1091 : Decl(ImplicitConceptSpecialization, DC, SL),
1092 NumTemplateArgs(ConvertedArgs.size()) {
1093 setTemplateArguments(ConvertedArgs);
1096 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1097 EmptyShell Empty, unsigned NumTemplateArgs)
1098 : Decl(ImplicitConceptSpecialization, Empty),
1099 NumTemplateArgs(NumTemplateArgs) {}
1101 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1102 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1103 ArrayRef<TemplateArgument> ConvertedArgs) {
1104 return new (C, DC,
1105 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1106 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1109 ImplicitConceptSpecializationDecl *
1110 ImplicitConceptSpecializationDecl::CreateDeserialized(
1111 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1112 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1113 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1116 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1117 ArrayRef<TemplateArgument> Converted) {
1118 assert(Converted.size() == NumTemplateArgs);
1119 std::uninitialized_copy(Converted.begin(), Converted.end(),
1120 getTrailingObjects<TemplateArgument>());
1123 //===----------------------------------------------------------------------===//
1124 // ClassTemplatePartialSpecializationDecl Implementation
1125 //===----------------------------------------------------------------------===//
1126 void ClassTemplatePartialSpecializationDecl::anchor() {}
1128 ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1129 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1130 SourceLocation IdLoc, TemplateParameterList *Params,
1131 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1132 ClassTemplatePartialSpecializationDecl *PrevDecl)
1133 : ClassTemplateSpecializationDecl(
1134 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1135 SpecializedTemplate, Args, PrevDecl),
1136 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1137 if (AdoptTemplateParameterList(Params, this))
1138 setInvalidDecl();
1141 ClassTemplatePartialSpecializationDecl *
1142 ClassTemplatePartialSpecializationDecl::Create(
1143 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1144 SourceLocation IdLoc, TemplateParameterList *Params,
1145 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1146 QualType CanonInjectedType,
1147 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1148 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1149 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1150 PrevDecl);
1151 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1152 Result->setMayHaveOutOfDateDef(false);
1154 Context.getInjectedClassNameType(Result, CanonInjectedType);
1155 return Result;
1158 ClassTemplatePartialSpecializationDecl *
1159 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1160 GlobalDeclID ID) {
1161 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1162 Result->setMayHaveOutOfDateDef(false);
1163 return Result;
1166 SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
1167 if (const ClassTemplatePartialSpecializationDecl *MT =
1168 getInstantiatedFromMember();
1169 MT && !isMemberSpecialization())
1170 return MT->getSourceRange();
1171 SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();
1172 if (const TemplateParameterList *TPL = getTemplateParameters();
1173 TPL && !getNumTemplateParameterLists())
1174 Range.setBegin(TPL->getTemplateLoc());
1175 return Range;
1178 //===----------------------------------------------------------------------===//
1179 // FriendTemplateDecl Implementation
1180 //===----------------------------------------------------------------------===//
1182 void FriendTemplateDecl::anchor() {}
1184 FriendTemplateDecl *
1185 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1186 SourceLocation L,
1187 MutableArrayRef<TemplateParameterList *> Params,
1188 FriendUnion Friend, SourceLocation FLoc) {
1189 TemplateParameterList **TPL = nullptr;
1190 if (!Params.empty()) {
1191 TPL = new (Context) TemplateParameterList *[Params.size()];
1192 llvm::copy(Params, TPL);
1194 return new (Context, DC)
1195 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1198 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1199 GlobalDeclID ID) {
1200 return new (C, ID) FriendTemplateDecl(EmptyShell());
1203 //===----------------------------------------------------------------------===//
1204 // TypeAliasTemplateDecl Implementation
1205 //===----------------------------------------------------------------------===//
1207 TypeAliasTemplateDecl *
1208 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1209 DeclarationName Name,
1210 TemplateParameterList *Params, NamedDecl *Decl) {
1211 bool Invalid = AdoptTemplateParameterList(Params, DC);
1212 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1213 if (Invalid)
1214 TD->setInvalidDecl();
1215 return TD;
1218 TypeAliasTemplateDecl *
1219 TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1220 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1221 DeclarationName(), nullptr, nullptr);
1224 RedeclarableTemplateDecl::CommonBase *
1225 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1226 auto *CommonPtr = new (C) Common;
1227 C.addDestruction(CommonPtr);
1228 return CommonPtr;
1231 //===----------------------------------------------------------------------===//
1232 // VarTemplateDecl Implementation
1233 //===----------------------------------------------------------------------===//
1235 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1236 VarTemplateDecl *CurD = this;
1237 while (CurD) {
1238 if (CurD->isThisDeclarationADefinition())
1239 return CurD;
1240 CurD = CurD->getPreviousDecl();
1242 return nullptr;
1245 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1246 SourceLocation L, DeclarationName Name,
1247 TemplateParameterList *Params,
1248 VarDecl *Decl) {
1249 bool Invalid = AdoptTemplateParameterList(Params, DC);
1250 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1251 if (Invalid)
1252 TD->setInvalidDecl();
1253 return TD;
1256 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1257 GlobalDeclID ID) {
1258 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1259 DeclarationName(), nullptr, nullptr);
1262 void VarTemplateDecl::LoadLazySpecializations() const {
1263 loadLazySpecializationsImpl();
1266 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1267 VarTemplateDecl::getSpecializations() const {
1268 LoadLazySpecializations();
1269 return getCommonPtr()->Specializations;
1272 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1273 VarTemplateDecl::getPartialSpecializations() const {
1274 LoadLazySpecializations();
1275 return getCommonPtr()->PartialSpecializations;
1278 RedeclarableTemplateDecl::CommonBase *
1279 VarTemplateDecl::newCommon(ASTContext &C) const {
1280 auto *CommonPtr = new (C) Common;
1281 C.addDestruction(CommonPtr);
1282 return CommonPtr;
1285 VarTemplateSpecializationDecl *
1286 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1287 void *&InsertPos) {
1288 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1291 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1292 void *InsertPos) {
1293 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1296 VarTemplatePartialSpecializationDecl *
1297 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1298 TemplateParameterList *TPL, void *&InsertPos) {
1299 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1300 TPL);
1303 void VarTemplatePartialSpecializationDecl::Profile(
1304 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1305 TemplateParameterList *TPL, const ASTContext &Context) {
1306 ID.AddInteger(TemplateArgs.size());
1307 for (const TemplateArgument &TemplateArg : TemplateArgs)
1308 TemplateArg.Profile(ID, Context);
1309 TPL->Profile(ID, Context);
1312 void VarTemplateDecl::AddPartialSpecialization(
1313 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1314 if (InsertPos)
1315 getPartialSpecializations().InsertNode(D, InsertPos);
1316 else {
1317 VarTemplatePartialSpecializationDecl *Existing =
1318 getPartialSpecializations().GetOrInsertNode(D);
1319 (void)Existing;
1320 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1323 if (ASTMutationListener *L = getASTMutationListener())
1324 L->AddedCXXTemplateSpecialization(this, D);
1327 void VarTemplateDecl::getPartialSpecializations(
1328 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1329 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1330 getPartialSpecializations();
1331 PS.clear();
1332 PS.reserve(PartialSpecs.size());
1333 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1334 PS.push_back(P.getMostRecentDecl());
1337 VarTemplatePartialSpecializationDecl *
1338 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1339 VarTemplatePartialSpecializationDecl *D) {
1340 Decl *DCanon = D->getCanonicalDecl();
1341 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1342 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1343 return P.getMostRecentDecl();
1346 return nullptr;
1349 //===----------------------------------------------------------------------===//
1350 // VarTemplateSpecializationDecl Implementation
1351 //===----------------------------------------------------------------------===//
1353 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1354 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1355 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1356 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1357 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1358 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1359 SpecializedTemplate(SpecializedTemplate),
1360 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1361 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1363 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1364 ASTContext &C)
1365 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1366 QualType(), nullptr, SC_None),
1367 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1369 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1370 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1371 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1372 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1373 return new (Context, DC) VarTemplateSpecializationDecl(
1374 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1375 SpecializedTemplate, T, TInfo, S, Args);
1378 VarTemplateSpecializationDecl *
1379 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
1380 GlobalDeclID ID) {
1381 return new (C, ID)
1382 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1385 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1386 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1387 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1389 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1390 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1391 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1392 printTemplateArgumentList(
1393 OS, ArgsAsWritten->arguments(), Policy,
1394 getSpecializedTemplate()->getTemplateParameters());
1395 } else {
1396 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1397 printTemplateArgumentList(
1398 OS, TemplateArgs.asArray(), Policy,
1399 getSpecializedTemplate()->getTemplateParameters());
1403 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1404 if (const auto *PartialSpec =
1405 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1406 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1407 return SpecializedTemplate.get<VarTemplateDecl *>();
1410 SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1411 switch (getSpecializationKind()) {
1412 case TSK_Undeclared:
1413 case TSK_ImplicitInstantiation: {
1414 llvm::PointerUnion<VarTemplateDecl *,
1415 VarTemplatePartialSpecializationDecl *>
1416 Pattern = getSpecializedTemplateOrPartial();
1417 assert(!Pattern.isNull() &&
1418 "Variable template specialization without pattern?");
1419 if (const auto *VTPSD =
1420 Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1421 return VTPSD->getSourceRange();
1422 VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();
1423 if (hasInit()) {
1424 if (VarTemplateDecl *Definition = VTD->getDefinition())
1425 return Definition->getSourceRange();
1427 return VTD->getCanonicalDecl()->getSourceRange();
1429 case TSK_ExplicitSpecialization: {
1430 SourceRange Range = VarDecl::getSourceRange();
1431 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1432 !hasInit() && Args)
1433 Range.setEnd(Args->getRAngleLoc());
1434 return Range;
1436 case TSK_ExplicitInstantiationDeclaration:
1437 case TSK_ExplicitInstantiationDefinition: {
1438 SourceRange Range = VarDecl::getSourceRange();
1439 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1440 Range.setBegin(ExternKW);
1441 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1442 TemplateKW.isValid())
1443 Range.setBegin(TemplateKW);
1444 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1445 Range.setEnd(Args->getRAngleLoc());
1446 return Range;
1449 llvm_unreachable("unhandled template specialization kind");
1452 void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1453 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1454 if (!Info) {
1455 // Don't allocate if the location is invalid.
1456 if (Loc.isInvalid())
1457 return;
1458 Info = new (getASTContext()) ExplicitInstantiationInfo;
1459 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1460 ExplicitInfo = Info;
1462 Info->ExternKeywordLoc = Loc;
1465 void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {
1466 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1467 if (!Info) {
1468 // Don't allocate if the location is invalid.
1469 if (Loc.isInvalid())
1470 return;
1471 Info = new (getASTContext()) ExplicitInstantiationInfo;
1472 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1473 ExplicitInfo = Info;
1475 Info->TemplateKeywordLoc = Loc;
1478 //===----------------------------------------------------------------------===//
1479 // VarTemplatePartialSpecializationDecl Implementation
1480 //===----------------------------------------------------------------------===//
1482 void VarTemplatePartialSpecializationDecl::anchor() {}
1484 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1485 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1486 SourceLocation IdLoc, TemplateParameterList *Params,
1487 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1488 StorageClass S, ArrayRef<TemplateArgument> Args)
1489 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1490 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1491 TInfo, S, Args),
1492 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1493 if (AdoptTemplateParameterList(Params, DC))
1494 setInvalidDecl();
1497 VarTemplatePartialSpecializationDecl *
1498 VarTemplatePartialSpecializationDecl::Create(
1499 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1500 SourceLocation IdLoc, TemplateParameterList *Params,
1501 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1502 StorageClass S, ArrayRef<TemplateArgument> Args) {
1503 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1504 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1505 Args);
1506 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1507 return Result;
1510 VarTemplatePartialSpecializationDecl *
1511 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1512 GlobalDeclID ID) {
1513 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1516 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1517 if (const VarTemplatePartialSpecializationDecl *MT =
1518 getInstantiatedFromMember();
1519 MT && !isMemberSpecialization())
1520 return MT->getSourceRange();
1521 SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();
1522 if (const TemplateParameterList *TPL = getTemplateParameters();
1523 TPL && !getNumTemplateParameterLists())
1524 Range.setBegin(TPL->getTemplateLoc());
1525 return Range;
1528 static TemplateParameterList *
1529 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1530 // typename T
1531 auto *T = TemplateTypeParmDecl::Create(
1532 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1533 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1534 /*HasTypeConstraint=*/false);
1535 T->setImplicit(true);
1537 // T ...Ints
1538 TypeSourceInfo *TI =
1539 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1540 auto *N = NonTypeTemplateParmDecl::Create(
1541 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1542 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1543 N->setImplicit(true);
1545 // <typename T, T ...Ints>
1546 NamedDecl *P[2] = {T, N};
1547 auto *TPL = TemplateParameterList::Create(
1548 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1550 // template <typename T, ...Ints> class IntSeq
1551 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1552 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1553 /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
1554 TemplateTemplateParm->setImplicit(true);
1556 // typename T
1557 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1558 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1559 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1560 /*HasTypeConstraint=*/false);
1561 TemplateTypeParm->setImplicit(true);
1563 // T N
1564 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1565 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1566 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1567 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1568 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1569 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1570 NonTypeTemplateParm};
1572 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1573 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1574 Params, SourceLocation(), nullptr);
1577 static TemplateParameterList *
1578 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1579 // std::size_t Index
1580 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1581 auto *Index = NonTypeTemplateParmDecl::Create(
1582 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1583 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1585 // typename ...T
1586 auto *Ts = TemplateTypeParmDecl::Create(
1587 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1588 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1589 /*HasTypeConstraint=*/false);
1590 Ts->setImplicit(true);
1592 // template <std::size_t Index, typename ...T>
1593 NamedDecl *Params[] = {Index, Ts};
1594 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1595 llvm::ArrayRef(Params), SourceLocation(),
1596 nullptr);
1599 static TemplateParameterList *createBuiltinCommonTypeList(const ASTContext &C,
1600 DeclContext *DC) {
1601 // class... Args
1602 auto *Args =
1603 TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
1604 /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1605 /*Typename=*/false, /*ParameterPack=*/true);
1607 // <class... Args>
1608 auto *BaseTemplateList = TemplateParameterList::Create(
1609 C, SourceLocation(), SourceLocation(), Args, SourceLocation(), nullptr);
1611 // template <class... Args> class BaseTemplate
1612 auto *BaseTemplate = TemplateTemplateParmDecl::Create(
1613 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1614 /*ParameterPack=*/false, /*Id=*/nullptr,
1615 /*Typename=*/false, BaseTemplateList);
1617 // class TypeMember
1618 auto *TypeMember =
1619 TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
1620 /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1621 /*Typename=*/false, /*ParameterPack=*/false);
1623 // <class TypeMember>
1624 auto *HasTypeMemberList =
1625 TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1626 TypeMember, SourceLocation(), nullptr);
1628 // template <class TypeMember> class HasTypeMember
1629 auto *HasTypeMember = TemplateTemplateParmDecl::Create(
1630 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/1,
1631 /*ParameterPack=*/false, /*Id=*/nullptr,
1632 /*Typename=*/false, HasTypeMemberList);
1634 // class HasNoTypeMember
1635 auto *HasNoTypeMember = TemplateTypeParmDecl::Create(
1636 C, DC, {}, {}, /*Depth=*/0, /*Position=*/2, /*Id=*/nullptr,
1637 /*Typename=*/false, /*ParameterPack=*/false);
1639 // class... Ts
1640 auto *Ts = TemplateTypeParmDecl::Create(
1641 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/3,
1642 /*Id=*/nullptr, /*Typename=*/false, /*ParameterPack=*/true);
1644 // template <template <class... Args> class BaseTemplate,
1645 // template <class TypeMember> class HasTypeMember, class HasNoTypeMember,
1646 // class... Ts>
1647 return TemplateParameterList::Create(
1648 C, SourceLocation(), SourceLocation(),
1649 {BaseTemplate, HasTypeMember, HasNoTypeMember, Ts}, SourceLocation(),
1650 nullptr);
1653 static TemplateParameterList *createBuiltinTemplateParameterList(
1654 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1655 switch (BTK) {
1656 case BTK__make_integer_seq:
1657 return createMakeIntegerSeqParameterList(C, DC);
1658 case BTK__type_pack_element:
1659 return createTypePackElementParameterList(C, DC);
1660 case BTK__builtin_common_type:
1661 return createBuiltinCommonTypeList(C, DC);
1664 llvm_unreachable("unhandled BuiltinTemplateKind!");
1667 void BuiltinTemplateDecl::anchor() {}
1669 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1670 DeclarationName Name,
1671 BuiltinTemplateKind BTK)
1672 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1673 createBuiltinTemplateParameterList(C, DC, BTK)),
1674 BTK(BTK) {}
1676 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1677 QualType T,
1678 const APValue &V) {
1679 DeclContext *DC = C.getTranslationUnitDecl();
1680 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1681 C.addDestruction(&TPOD->Value);
1682 return TPOD;
1685 TemplateParamObjectDecl *
1686 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1687 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1688 C.addDestruction(&TPOD->Value);
1689 return TPOD;
1692 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1693 const PrintingPolicy &Policy) const {
1694 OS << "<template param ";
1695 printAsExpr(OS, Policy);
1696 OS << ">";
1699 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1700 printAsExpr(OS, getASTContext().getPrintingPolicy());
1703 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1704 const PrintingPolicy &Policy) const {
1705 getType().getUnqualifiedType().print(OS, Policy);
1706 printAsInit(OS, Policy);
1709 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1710 printAsInit(OS, getASTContext().getPrintingPolicy());
1713 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1714 const PrintingPolicy &Policy) const {
1715 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1718 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1719 switch (D->getKind()) {
1720 case Decl::Kind::CXXRecord:
1721 return cast<CXXRecordDecl>(D)
1722 ->getDescribedTemplate()
1723 ->getTemplateParameters();
1724 case Decl::Kind::ClassTemplate:
1725 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1726 case Decl::Kind::ClassTemplateSpecialization: {
1727 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1728 auto P = CTSD->getSpecializedTemplateOrPartial();
1729 if (const auto *CTPSD =
1730 P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1731 return CTPSD->getTemplateParameters();
1732 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1734 case Decl::Kind::ClassTemplatePartialSpecialization:
1735 return cast<ClassTemplatePartialSpecializationDecl>(D)
1736 ->getTemplateParameters();
1737 case Decl::Kind::TypeAliasTemplate:
1738 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1739 case Decl::Kind::BuiltinTemplate:
1740 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1741 case Decl::Kind::CXXDeductionGuide:
1742 case Decl::Kind::CXXConversion:
1743 case Decl::Kind::CXXConstructor:
1744 case Decl::Kind::CXXDestructor:
1745 case Decl::Kind::CXXMethod:
1746 case Decl::Kind::Function:
1747 return cast<FunctionDecl>(D)
1748 ->getTemplateSpecializationInfo()
1749 ->getTemplate()
1750 ->getTemplateParameters();
1751 case Decl::Kind::FunctionTemplate:
1752 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1753 case Decl::Kind::VarTemplate:
1754 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1755 case Decl::Kind::VarTemplateSpecialization: {
1756 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1757 auto P = VTSD->getSpecializedTemplateOrPartial();
1758 if (const auto *VTPSD =
1759 P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1760 return VTPSD->getTemplateParameters();
1761 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1763 case Decl::Kind::VarTemplatePartialSpecialization:
1764 return cast<VarTemplatePartialSpecializationDecl>(D)
1765 ->getTemplateParameters();
1766 case Decl::Kind::TemplateTemplateParm:
1767 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1768 case Decl::Kind::Concept:
1769 return cast<ConceptDecl>(D)->getTemplateParameters();
1770 default:
1771 llvm_unreachable("Unhandled templated declaration kind");