1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the C++ related Decl classes for templates.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/TemplateName.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Basic/Builtins.h"
25 #include "clang/Basic/LLVM.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/FoldingSet.h"
29 #include "llvm/ADT/PointerUnion.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Support/ErrorHandling.h"
38 using namespace clang
;
40 //===----------------------------------------------------------------------===//
41 // TemplateParameterList Implementation
42 //===----------------------------------------------------------------------===//
44 template <class TemplateParam
>
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
,
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
];
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
)) {
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;
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
)
103 if (!HasConstrainedParameters
)
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())
113 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(Param
)) {
114 const auto *TC
= TTP
->getTypeConstraint();
115 if (TC
&& TC
->getImmediatelyDeclaredConstraint()
116 ->containsUnexpandedParameterPack())
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);
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
)) {
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);
153 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(D
)) {
155 ID
.AddBoolean(TTP
->isParameterPack());
156 ID
.AddBoolean(TTP
->hasTypeConstraint());
157 if (const TypeConstraint
*TC
= TTP
->getTypeConstraint())
158 TC
->getImmediatelyDeclaredConstraint()->Profile(ID
, C
,
162 const auto *TTP
= cast
<TemplateTemplateParmDecl
>(D
);
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
;
180 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(P
)) {
181 if (TTP
->hasDefaultArgument())
183 } else if (const auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(P
)) {
184 if (NTTP
->hasDefaultArgument())
186 } else if (cast
<TemplateTemplateParmDecl
>(P
)->hasDefaultArgument())
192 return NumRequiredArgs
;
195 unsigned TemplateParameterList::getDepth() const {
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();
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
))
218 if (P
->isInvalidDecl())
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())
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
) {
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
,
258 if (!TPL
|| Idx
>= TPL
->size() || Policy
.AlwaysIncludeTypeForTemplateArgument
)
260 const NamedDecl
*TemplParam
= TPL
->getParam(Idx
);
261 if (const auto *ParamValueDecl
=
262 dyn_cast
<NonTypeTemplateParmDecl
>(TemplParam
))
263 if (ParamValueDecl
->getType()->getContainedDeducedType())
270 void *allocateDefaultArgStorageChain(const ASTContext
&C
) {
271 return new (C
) char[sizeof(void*) * 2];
276 //===----------------------------------------------------------------------===//
277 // TemplateDecl Implementation
278 //===----------------------------------------------------------------------===//
280 TemplateDecl::TemplateDecl(Kind DK
, DeclContext
*DC
, SourceLocation L
,
281 DeclarationName Name
, TemplateParameterList
*Params
,
283 : NamedDecl(DK
, DC
, L
, Name
), TemplatedDecl(Decl
), TemplateParams(Params
) {}
285 void TemplateDecl::anchor() {}
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())
295 bool TemplateDecl::hasAssociatedConstraints() const {
296 if (TemplateParams
->hasAssociatedConstraints())
298 if (auto *FD
= dyn_cast_or_null
<FunctionDecl
>(getTemplatedDecl()))
299 return FD
->getTrailingRequiresClause();
303 bool TemplateDecl::isTypeAlias() const {
305 case TemplateDecl::TypeAliasTemplate
:
306 case TemplateDecl::BuiltinTemplate
:
313 //===----------------------------------------------------------------------===//
314 // RedeclarableTemplateDecl Implementation
315 //===----------------------------------------------------------------------===//
317 void RedeclarableTemplateDecl::anchor() {}
319 RedeclarableTemplateDecl::CommonBase
*RedeclarableTemplateDecl::getCommonPtr() const {
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()) {
329 Common
= Prev
->Common
;
333 PrevDecls
.push_back(Prev
);
336 // If we never found a common pointer, allocate one now.
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
;
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
)...,
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
,
383 using SETraits
= SpecEntryTraits
<EntryType
>;
387 void *CorrectInsertPos
;
388 assert(!findSpecializationImpl(Specializations
,
390 SETraits::getTemplateArgs(Entry
)) &&
391 InsertPos
== CorrectInsertPos
&&
392 "given incorrect InsertPos for specialization");
394 Specializations
.InsertNode(Entry
, InsertPos
);
396 EntryType
*Existing
= Specializations
.GetOrInsertNode(Entry
);
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
);
418 TD
->setInvalidDecl();
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
);
435 void FunctionTemplateDecl::LoadLazySpecializations() const {
436 loadLazySpecializationsImpl();
439 llvm::FoldingSetVector
<FunctionTemplateSpecializationInfo
> &
440 FunctionTemplateDecl::getSpecializations() const {
441 LoadLazySpecializations();
442 return getCommonPtr()->Specializations
;
446 FunctionTemplateDecl::findSpecialization(ArrayRef
<TemplateArgument
> Args
,
448 return findSpecializationImpl(getSpecializations(), InsertPos
, Args
);
451 void FunctionTemplateDecl::addSpecialization(
452 FunctionTemplateSpecializationInfo
*Info
, void *InsertPos
) {
453 addSpecializationImpl
<FunctionTemplateDecl
>(getSpecializations(), Info
,
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.
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
);
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.
479 for (auto *D
: PreviousDecls
)
480 D
->Base::Common
= ThisCommon
;
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
,
497 DeclarationName Name
,
498 TemplateParameterList
*Params
,
500 bool Invalid
= AdoptTemplateParameterList(Params
, cast
<DeclContext
>(Decl
));
501 auto *TD
= new (C
, DC
) ClassTemplateDecl(C
, DC
, L
, Name
, Params
, Decl
);
503 TD
->setInvalidDecl();
507 ClassTemplateDecl
*ClassTemplateDecl::CreateDeserialized(ASTContext
&C
,
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
);
536 ClassTemplateSpecializationDecl
*
537 ClassTemplateDecl::findSpecialization(ArrayRef
<TemplateArgument
> Args
,
539 return findSpecializationImpl(getSpecializations(), InsertPos
, Args
);
542 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl
*D
,
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
,
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
,
568 getPartialSpecializations().InsertNode(D
, InsertPos
);
570 ClassTemplatePartialSpecializationDecl
*Existing
571 = getPartialSpecializations().GetOrInsertNode(D
);
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();
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();
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();
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
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
) {
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());
654 TemplateTypeParmDecl
*
655 TemplateTypeParmDecl::CreateDeserialized(const ASTContext
&C
, GlobalDeclID 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
) {
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()
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);
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()) {
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
) {
745 C
.getLangOpts().CPlusPlus20
? T
->getContainedAutoType() : nullptr;
747 additionalSizeToAlloc
<std::pair
<QualType
, TypeSourceInfo
*>,
749 AT
&& AT
->isConstrained() ? 1 : 0))
750 NonTypeTemplateParmDecl(DC
, StartLoc
, IdLoc
, D
, P
, Id
, T
, ParameterPack
,
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();
761 additionalSizeToAlloc
<std::pair
<QualType
, TypeSourceInfo
*>,
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
,
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
) {
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
;
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()
805 void NonTypeTemplateParmDecl::setDefaultArgument(
806 const ASTContext
&C
, const TemplateArgumentLoc
&DefArg
) {
807 if (DefArg
.getArgument().isNull())
808 DefaultArgument
.set(nullptr);
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
,
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
) {
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
) {
861 new (C
, ID
, additionalSizeToAlloc
<TemplateParameterList
*>(NumExpansions
))
862 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
864 TTP
->NumExpandedParams
= NumExpansions
;
868 SourceLocation
TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
869 return hasDefaultArgument() ? getDefaultArgument().getLocation()
873 void TemplateTemplateParmDecl::setDefaultArgument(
874 const ASTContext
&C
, const TemplateArgumentLoc
&DefArg
) {
875 if (DefArg
.getArgument().isNull())
876 DefaultArgument
.set(nullptr);
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
);
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
,
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
,
940 SourceLocation StartLoc
,
941 SourceLocation IdLoc
,
942 ClassTemplateDecl
*SpecializedTemplate
,
943 ArrayRef
<TemplateArgument
> Args
,
944 ClassTemplateSpecializationDecl
*PrevDecl
) {
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
955 if (!SpecializedTemplate
->getTemplatedDecl()->isCompleteDefinition())
956 Result
->setHasExternalLexicalStorage(
957 SpecializedTemplate
->getTemplatedDecl()->hasExternalLexicalStorage());
959 Context
.getTypeDeclType(Result
, PrevDecl
);
963 ClassTemplateSpecializationDecl
*
964 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext
&C
,
967 new (C
, ID
) ClassTemplateSpecializationDecl(C
, ClassTemplateSpecialization
);
968 Result
->setMayHaveOutOfDateDef(false);
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());
983 const TemplateArgumentList
&TemplateArgs
= getTemplateArgs();
984 printTemplateArgumentList(
985 OS
, TemplateArgs
.asArray(), Policy
,
986 getSpecializedTemplate()->getTemplateParameters());
991 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
992 if (const auto *PartialSpec
=
993 SpecializedTemplate
.dyn_cast
<SpecializedPartialSpecialization
*>())
994 return PartialSpec
->PartialSpecialization
->getSpecializedTemplate();
995 return SpecializedTemplate
.get
<ClassTemplateDecl
*>();
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());
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());
1033 llvm_unreachable("unhandled template specialization kind");
1036 void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc
) {
1037 auto *Info
= ExplicitInfo
.dyn_cast
<ExplicitInstantiationInfo
*>();
1039 // Don't allocate if the location is invalid.
1040 if (Loc
.isInvalid())
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
*>();
1053 // Don't allocate if the location is invalid.
1054 if (Loc
.isInvalid())
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
);
1073 TD
->setInvalidDecl();
1077 ConceptDecl
*ConceptDecl::CreateDeserialized(ASTContext
&C
, GlobalDeclID ID
) {
1078 ConceptDecl
*Result
= new (C
, ID
) ConceptDecl(nullptr, SourceLocation(),
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
) {
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))
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
,
1151 Result
->setSpecializationKind(TSK_ExplicitSpecialization
);
1152 Result
->setMayHaveOutOfDateDef(false);
1154 Context
.getInjectedClassNameType(Result
, CanonInjectedType
);
1158 ClassTemplatePartialSpecializationDecl
*
1159 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext
&C
,
1161 auto *Result
= new (C
, ID
) ClassTemplatePartialSpecializationDecl(C
);
1162 Result
->setMayHaveOutOfDateDef(false);
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());
1178 //===----------------------------------------------------------------------===//
1179 // FriendTemplateDecl Implementation
1180 //===----------------------------------------------------------------------===//
1182 void FriendTemplateDecl::anchor() {}
1184 FriendTemplateDecl
*
1185 FriendTemplateDecl::Create(ASTContext
&Context
, DeclContext
*DC
,
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
,
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
);
1214 TD
->setInvalidDecl();
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
);
1231 //===----------------------------------------------------------------------===//
1232 // VarTemplateDecl Implementation
1233 //===----------------------------------------------------------------------===//
1235 VarTemplateDecl
*VarTemplateDecl::getDefinition() {
1236 VarTemplateDecl
*CurD
= this;
1238 if (CurD
->isThisDeclarationADefinition())
1240 CurD
= CurD
->getPreviousDecl();
1245 VarTemplateDecl
*VarTemplateDecl::Create(ASTContext
&C
, DeclContext
*DC
,
1246 SourceLocation L
, DeclarationName Name
,
1247 TemplateParameterList
*Params
,
1249 bool Invalid
= AdoptTemplateParameterList(Params
, DC
);
1250 auto *TD
= new (C
, DC
) VarTemplateDecl(C
, DC
, L
, Name
, Params
, Decl
);
1252 TD
->setInvalidDecl();
1256 VarTemplateDecl
*VarTemplateDecl::CreateDeserialized(ASTContext
&C
,
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
);
1285 VarTemplateSpecializationDecl
*
1286 VarTemplateDecl::findSpecialization(ArrayRef
<TemplateArgument
> Args
,
1288 return findSpecializationImpl(getSpecializations(), InsertPos
, Args
);
1291 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl
*D
,
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
,
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
) {
1315 getPartialSpecializations().InsertNode(D
, InsertPos
);
1317 VarTemplatePartialSpecializationDecl
*Existing
=
1318 getPartialSpecializations().GetOrInsertNode(D
);
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();
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();
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
,
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
,
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());
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
*>();
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();
1433 Range
.setEnd(Args
->getRAngleLoc());
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());
1449 llvm_unreachable("unhandled template specialization kind");
1452 void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc
) {
1453 auto *Info
= ExplicitInfo
.dyn_cast
<ExplicitInstantiationInfo
*>();
1455 // Don't allocate if the location is invalid.
1456 if (Loc
.isInvalid())
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
*>();
1468 // Don't allocate if the location is invalid.
1469 if (Loc
.isInvalid())
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
,
1492 TemplateParams(Params
), InstantiatedFromMember(nullptr, false) {
1493 if (AdoptTemplateParameterList(Params
, DC
))
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
,
1506 Result
->setSpecializationKind(TSK_ExplicitSpecialization
);
1510 VarTemplatePartialSpecializationDecl
*
1511 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext
&C
,
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());
1528 static TemplateParameterList
*
1529 createMakeIntegerSeqParameterList(const ASTContext
&C
, DeclContext
*DC
) {
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);
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);
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);
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
);
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(),
1599 static TemplateParameterList
*createBuiltinCommonTypeList(const ASTContext
&C
,
1603 TemplateTypeParmDecl::Create(C
, DC
, SourceLocation(), SourceLocation(),
1604 /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1605 /*Typename=*/false, /*ParameterPack=*/true);
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
);
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);
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,
1647 return TemplateParameterList::Create(
1648 C
, SourceLocation(), SourceLocation(),
1649 {BaseTemplate
, HasTypeMember
, HasNoTypeMember
, Ts
}, SourceLocation(),
1653 static TemplateParameterList
*createBuiltinTemplateParameterList(
1654 const ASTContext
&C
, DeclContext
*DC
, BuiltinTemplateKind 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
)),
1676 TemplateParamObjectDecl
*TemplateParamObjectDecl::Create(const ASTContext
&C
,
1679 DeclContext
*DC
= C
.getTranslationUnitDecl();
1680 auto *TPOD
= new (C
, DC
) TemplateParamObjectDecl(DC
, T
, V
);
1681 C
.addDestruction(&TPOD
->Value
);
1685 TemplateParamObjectDecl
*
1686 TemplateParamObjectDecl::CreateDeserialized(ASTContext
&C
, GlobalDeclID ID
) {
1687 auto *TPOD
= new (C
, ID
) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1688 C
.addDestruction(&TPOD
->Value
);
1692 void TemplateParamObjectDecl::printName(llvm::raw_ostream
&OS
,
1693 const PrintingPolicy
&Policy
) const {
1694 OS
<< "<template param ";
1695 printAsExpr(OS
, Policy
);
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()
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();
1771 llvm_unreachable("Unhandled templated declaration kind");