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/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
41 using namespace clang
;
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
48 TemplateParameterList::TemplateParameterList(const ASTContext
& C
,
49 SourceLocation TemplateLoc
,
50 SourceLocation LAngleLoc
,
51 ArrayRef
<NamedDecl
*> Params
,
52 SourceLocation RAngleLoc
,
54 : TemplateLoc(TemplateLoc
), LAngleLoc(LAngleLoc
), RAngleLoc(RAngleLoc
),
55 NumParams(Params
.size()), ContainsUnexpandedParameterPack(false),
56 HasRequiresClause(RequiresClause
!= nullptr),
57 HasConstrainedParameters(false) {
58 for (unsigned Idx
= 0; Idx
< NumParams
; ++Idx
) {
59 NamedDecl
*P
= Params
[Idx
];
62 bool IsPack
= P
->isTemplateParameterPack();
63 if (const auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(P
)) {
64 if (!IsPack
&& NTTP
->getType()->containsUnexpandedParameterPack())
65 ContainsUnexpandedParameterPack
= true;
66 if (NTTP
->hasPlaceholderTypeConstraint())
67 HasConstrainedParameters
= true;
68 } else if (const auto *TTP
= dyn_cast
<TemplateTemplateParmDecl
>(P
)) {
70 TTP
->getTemplateParameters()->containsUnexpandedParameterPack())
71 ContainsUnexpandedParameterPack
= true;
72 } else if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(P
)) {
73 if (const TypeConstraint
*TC
= TTP
->getTypeConstraint()) {
74 if (TC
->getImmediatelyDeclaredConstraint()
75 ->containsUnexpandedParameterPack())
76 ContainsUnexpandedParameterPack
= true;
78 if (TTP
->hasTypeConstraint())
79 HasConstrainedParameters
= true;
81 llvm_unreachable("unexpected template parameter type");
83 // FIXME: If a default argument contains an unexpanded parameter pack, the
84 // template parameter list does too.
87 if (HasRequiresClause
) {
88 if (RequiresClause
->containsUnexpandedParameterPack())
89 ContainsUnexpandedParameterPack
= true;
90 *getTrailingObjects
<Expr
*>() = RequiresClause
;
94 bool TemplateParameterList::containsUnexpandedParameterPack() const {
95 if (ContainsUnexpandedParameterPack
)
97 if (!HasConstrainedParameters
)
100 // An implicit constrained parameter might have had a use of an unexpanded
101 // pack added to it after the template parameter list was created. All
102 // implicit parameters are at the end of the parameter list.
103 for (const NamedDecl
*Param
: llvm::reverse(asArray())) {
104 if (!Param
->isImplicit())
107 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(Param
)) {
108 const auto *TC
= TTP
->getTypeConstraint();
109 if (TC
&& TC
->getImmediatelyDeclaredConstraint()
110 ->containsUnexpandedParameterPack())
118 TemplateParameterList
*
119 TemplateParameterList::Create(const ASTContext
&C
, SourceLocation TemplateLoc
,
120 SourceLocation LAngleLoc
,
121 ArrayRef
<NamedDecl
*> Params
,
122 SourceLocation RAngleLoc
, Expr
*RequiresClause
) {
123 void *Mem
= C
.Allocate(totalSizeToAlloc
<NamedDecl
*, Expr
*>(
124 Params
.size(), RequiresClause
? 1u : 0u),
125 alignof(TemplateParameterList
));
126 return new (Mem
) TemplateParameterList(C
, TemplateLoc
, LAngleLoc
, Params
,
127 RAngleLoc
, RequiresClause
);
130 void TemplateParameterList::Profile(llvm::FoldingSetNodeID
&ID
,
131 const ASTContext
&C
) const {
132 const Expr
*RC
= getRequiresClause();
133 ID
.AddBoolean(RC
!= nullptr);
135 RC
->Profile(ID
, C
, /*Canonical=*/true);
136 ID
.AddInteger(size());
137 for (NamedDecl
*D
: *this) {
138 if (const auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(D
)) {
140 ID
.AddBoolean(NTTP
->isParameterPack());
141 NTTP
->getType().getCanonicalType().Profile(ID
);
142 ID
.AddBoolean(NTTP
->hasPlaceholderTypeConstraint());
143 if (const Expr
*E
= NTTP
->getPlaceholderTypeConstraint())
144 E
->Profile(ID
, C
, /*Canonical=*/true);
147 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(D
)) {
149 ID
.AddBoolean(TTP
->isParameterPack());
150 ID
.AddBoolean(TTP
->hasTypeConstraint());
151 if (const TypeConstraint
*TC
= TTP
->getTypeConstraint())
152 TC
->getImmediatelyDeclaredConstraint()->Profile(ID
, C
,
156 const auto *TTP
= cast
<TemplateTemplateParmDecl
>(D
);
158 ID
.AddBoolean(TTP
->isParameterPack());
159 TTP
->getTemplateParameters()->Profile(ID
, C
);
163 unsigned TemplateParameterList::getMinRequiredArguments() const {
164 unsigned NumRequiredArgs
= 0;
165 for (const NamedDecl
*P
: asArray()) {
166 if (P
->isTemplateParameterPack()) {
167 if (std::optional
<unsigned> Expansions
= getExpandedPackSize(P
)) {
168 NumRequiredArgs
+= *Expansions
;
174 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(P
)) {
175 if (TTP
->hasDefaultArgument())
177 } else if (const auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(P
)) {
178 if (NTTP
->hasDefaultArgument())
180 } else if (cast
<TemplateTemplateParmDecl
>(P
)->hasDefaultArgument())
186 return NumRequiredArgs
;
189 unsigned TemplateParameterList::getDepth() const {
193 const NamedDecl
*FirstParm
= getParam(0);
194 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(FirstParm
))
195 return TTP
->getDepth();
196 else if (const auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(FirstParm
))
197 return NTTP
->getDepth();
199 return cast
<TemplateTemplateParmDecl
>(FirstParm
)->getDepth();
202 static bool AdoptTemplateParameterList(TemplateParameterList
*Params
,
203 DeclContext
*Owner
) {
204 bool Invalid
= false;
205 for (NamedDecl
*P
: *Params
) {
206 P
->setDeclContext(Owner
);
208 if (const auto *TTP
= dyn_cast
<TemplateTemplateParmDecl
>(P
))
209 if (AdoptTemplateParameterList(TTP
->getTemplateParameters(), Owner
))
212 if (P
->isInvalidDecl())
218 void TemplateParameterList::
219 getAssociatedConstraints(llvm::SmallVectorImpl
<const Expr
*> &AC
) const {
220 if (HasConstrainedParameters
)
221 for (const NamedDecl
*Param
: *this) {
222 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(Param
)) {
223 if (const auto *TC
= TTP
->getTypeConstraint())
224 AC
.push_back(TC
->getImmediatelyDeclaredConstraint());
225 } else if (const auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(Param
)) {
226 if (const Expr
*E
= NTTP
->getPlaceholderTypeConstraint())
230 if (HasRequiresClause
)
231 AC
.push_back(getRequiresClause());
234 bool TemplateParameterList::hasAssociatedConstraints() const {
235 return HasRequiresClause
|| HasConstrainedParameters
;
238 bool TemplateParameterList::shouldIncludeTypeForArgument(
239 const PrintingPolicy
&Policy
, const TemplateParameterList
*TPL
,
241 if (!TPL
|| Idx
>= TPL
->size() || Policy
.AlwaysIncludeTypeForTemplateArgument
)
243 const NamedDecl
*TemplParam
= TPL
->getParam(Idx
);
244 if (const auto *ParamValueDecl
=
245 dyn_cast
<NonTypeTemplateParmDecl
>(TemplParam
))
246 if (ParamValueDecl
->getType()->getContainedDeducedType())
253 void *allocateDefaultArgStorageChain(const ASTContext
&C
) {
254 return new (C
) char[sizeof(void*) * 2];
259 //===----------------------------------------------------------------------===//
260 // TemplateDecl Implementation
261 //===----------------------------------------------------------------------===//
263 TemplateDecl::TemplateDecl(Kind DK
, DeclContext
*DC
, SourceLocation L
,
264 DeclarationName Name
, TemplateParameterList
*Params
,
266 : NamedDecl(DK
, DC
, L
, Name
), TemplatedDecl(Decl
), TemplateParams(Params
) {}
268 void TemplateDecl::anchor() {}
271 getAssociatedConstraints(llvm::SmallVectorImpl
<const Expr
*> &AC
) const {
272 TemplateParams
->getAssociatedConstraints(AC
);
273 if (auto *FD
= dyn_cast_or_null
<FunctionDecl
>(getTemplatedDecl()))
274 if (const Expr
*TRC
= FD
->getTrailingRequiresClause())
278 bool TemplateDecl::hasAssociatedConstraints() const {
279 if (TemplateParams
->hasAssociatedConstraints())
281 if (auto *FD
= dyn_cast_or_null
<FunctionDecl
>(getTemplatedDecl()))
282 return FD
->getTrailingRequiresClause();
286 bool TemplateDecl::isTypeAlias() const {
288 case TemplateDecl::TypeAliasTemplate
:
289 case TemplateDecl::BuiltinTemplate
:
296 //===----------------------------------------------------------------------===//
297 // RedeclarableTemplateDecl Implementation
298 //===----------------------------------------------------------------------===//
300 void RedeclarableTemplateDecl::anchor() {}
302 RedeclarableTemplateDecl::CommonBase
*RedeclarableTemplateDecl::getCommonPtr() const {
306 // Walk the previous-declaration chain until we either find a declaration
307 // with a common pointer or we run out of previous declarations.
308 SmallVector
<const RedeclarableTemplateDecl
*, 2> PrevDecls
;
309 for (const RedeclarableTemplateDecl
*Prev
= getPreviousDecl(); Prev
;
310 Prev
= Prev
->getPreviousDecl()) {
312 Common
= Prev
->Common
;
316 PrevDecls
.push_back(Prev
);
319 // If we never found a common pointer, allocate one now.
321 // FIXME: If any of the declarations is from an AST file, we probably
322 // need an update record to add the common data.
324 Common
= newCommon(getASTContext());
327 // Update any previous declarations we saw with the common pointer.
328 for (const RedeclarableTemplateDecl
*Prev
: PrevDecls
)
329 Prev
->Common
= Common
;
334 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
335 // Grab the most recent declaration to ensure we've loaded any lazy
336 // redeclarations of this template.
337 CommonBase
*CommonBasePtr
= getMostRecentDecl()->getCommonPtr();
338 if (CommonBasePtr
->LazySpecializations
) {
339 ASTContext
&Context
= getASTContext();
340 uint32_t *Specs
= CommonBasePtr
->LazySpecializations
;
341 CommonBasePtr
->LazySpecializations
= nullptr;
342 for (uint32_t I
= 0, N
= *Specs
++; I
!= N
; ++I
)
343 (void)Context
.getExternalSource()->GetExternalDecl(Specs
[I
]);
347 template<class EntryType
, typename
... ProfileArguments
>
348 typename
RedeclarableTemplateDecl::SpecEntryTraits
<EntryType
>::DeclType
*
349 RedeclarableTemplateDecl::findSpecializationImpl(
350 llvm::FoldingSetVector
<EntryType
> &Specs
, void *&InsertPos
,
351 ProfileArguments
&&... ProfileArgs
) {
352 using SETraits
= SpecEntryTraits
<EntryType
>;
354 llvm::FoldingSetNodeID ID
;
355 EntryType::Profile(ID
, std::forward
<ProfileArguments
>(ProfileArgs
)...,
357 EntryType
*Entry
= Specs
.FindNodeOrInsertPos(ID
, InsertPos
);
358 return Entry
? SETraits::getDecl(Entry
)->getMostRecentDecl() : nullptr;
361 template<class Derived
, class EntryType
>
362 void RedeclarableTemplateDecl::addSpecializationImpl(
363 llvm::FoldingSetVector
<EntryType
> &Specializations
, EntryType
*Entry
,
365 using SETraits
= SpecEntryTraits
<EntryType
>;
369 void *CorrectInsertPos
;
370 assert(!findSpecializationImpl(Specializations
,
372 SETraits::getTemplateArgs(Entry
)) &&
373 InsertPos
== CorrectInsertPos
&&
374 "given incorrect InsertPos for specialization");
376 Specializations
.InsertNode(Entry
, InsertPos
);
378 EntryType
*Existing
= Specializations
.GetOrInsertNode(Entry
);
380 assert(SETraits::getDecl(Existing
)->isCanonicalDecl() &&
381 "non-canonical specialization?");
384 if (ASTMutationListener
*L
= getASTMutationListener())
385 L
->AddedCXXTemplateSpecialization(cast
<Derived
>(this),
386 SETraits::getDecl(Entry
));
389 ArrayRef
<TemplateArgument
> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
390 TemplateParameterList
*Params
= getTemplateParameters();
391 auto *CommonPtr
= getCommonPtr();
392 if (!CommonPtr
->InjectedArgs
) {
393 auto &Context
= getASTContext();
394 SmallVector
<TemplateArgument
, 16> TemplateArgs
;
395 Context
.getInjectedTemplateArgs(Params
, TemplateArgs
);
396 CommonPtr
->InjectedArgs
=
397 new (Context
) TemplateArgument
[TemplateArgs
.size()];
398 std::copy(TemplateArgs
.begin(), TemplateArgs
.end(),
399 CommonPtr
->InjectedArgs
);
402 return llvm::ArrayRef(CommonPtr
->InjectedArgs
, Params
->size());
405 //===----------------------------------------------------------------------===//
406 // FunctionTemplateDecl Implementation
407 //===----------------------------------------------------------------------===//
409 FunctionTemplateDecl
*
410 FunctionTemplateDecl::Create(ASTContext
&C
, DeclContext
*DC
, SourceLocation L
,
411 DeclarationName Name
,
412 TemplateParameterList
*Params
, NamedDecl
*Decl
) {
413 bool Invalid
= AdoptTemplateParameterList(Params
, cast
<DeclContext
>(Decl
));
414 auto *TD
= new (C
, DC
) FunctionTemplateDecl(C
, DC
, L
, Name
, Params
, Decl
);
416 TD
->setInvalidDecl();
420 FunctionTemplateDecl
*FunctionTemplateDecl::CreateDeserialized(ASTContext
&C
,
422 return new (C
, ID
) FunctionTemplateDecl(C
, nullptr, SourceLocation(),
423 DeclarationName(), nullptr, nullptr);
426 RedeclarableTemplateDecl::CommonBase
*
427 FunctionTemplateDecl::newCommon(ASTContext
&C
) const {
428 auto *CommonPtr
= new (C
) Common
;
429 C
.addDestruction(CommonPtr
);
433 void FunctionTemplateDecl::LoadLazySpecializations() const {
434 loadLazySpecializationsImpl();
437 llvm::FoldingSetVector
<FunctionTemplateSpecializationInfo
> &
438 FunctionTemplateDecl::getSpecializations() const {
439 LoadLazySpecializations();
440 return getCommonPtr()->Specializations
;
444 FunctionTemplateDecl::findSpecialization(ArrayRef
<TemplateArgument
> Args
,
446 return findSpecializationImpl(getSpecializations(), InsertPos
, Args
);
449 void FunctionTemplateDecl::addSpecialization(
450 FunctionTemplateSpecializationInfo
*Info
, void *InsertPos
) {
451 addSpecializationImpl
<FunctionTemplateDecl
>(getSpecializations(), Info
,
455 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl
*Prev
) {
456 using Base
= RedeclarableTemplateDecl
;
458 // If we haven't created a common pointer yet, then it can just be created
459 // with the usual method.
463 Common
*ThisCommon
= static_cast<Common
*>(Base::Common
);
464 Common
*PrevCommon
= nullptr;
465 SmallVector
<FunctionTemplateDecl
*, 8> PreviousDecls
;
466 for (; Prev
; Prev
= Prev
->getPreviousDecl()) {
467 if (Prev
->Base::Common
) {
468 PrevCommon
= static_cast<Common
*>(Prev
->Base::Common
);
471 PreviousDecls
.push_back(Prev
);
474 // If the previous redecl chain hasn't created a common pointer yet, then just
475 // use this common pointer.
477 for (auto *D
: PreviousDecls
)
478 D
->Base::Common
= ThisCommon
;
482 // Ensure we don't leak any important state.
483 assert(ThisCommon
->Specializations
.size() == 0 &&
484 "Can't merge incompatible declarations!");
486 Base::Common
= PrevCommon
;
489 //===----------------------------------------------------------------------===//
490 // ClassTemplateDecl Implementation
491 //===----------------------------------------------------------------------===//
493 ClassTemplateDecl
*ClassTemplateDecl::Create(ASTContext
&C
, DeclContext
*DC
,
495 DeclarationName Name
,
496 TemplateParameterList
*Params
,
498 bool Invalid
= AdoptTemplateParameterList(Params
, cast
<DeclContext
>(Decl
));
499 auto *TD
= new (C
, DC
) ClassTemplateDecl(C
, DC
, L
, Name
, Params
, Decl
);
501 TD
->setInvalidDecl();
505 ClassTemplateDecl
*ClassTemplateDecl::CreateDeserialized(ASTContext
&C
,
507 return new (C
, ID
) ClassTemplateDecl(C
, nullptr, SourceLocation(),
508 DeclarationName(), nullptr, nullptr);
511 void ClassTemplateDecl::LoadLazySpecializations() const {
512 loadLazySpecializationsImpl();
515 llvm::FoldingSetVector
<ClassTemplateSpecializationDecl
> &
516 ClassTemplateDecl::getSpecializations() const {
517 LoadLazySpecializations();
518 return getCommonPtr()->Specializations
;
521 llvm::FoldingSetVector
<ClassTemplatePartialSpecializationDecl
> &
522 ClassTemplateDecl::getPartialSpecializations() const {
523 LoadLazySpecializations();
524 return getCommonPtr()->PartialSpecializations
;
527 RedeclarableTemplateDecl::CommonBase
*
528 ClassTemplateDecl::newCommon(ASTContext
&C
) const {
529 auto *CommonPtr
= new (C
) Common
;
530 C
.addDestruction(CommonPtr
);
534 ClassTemplateSpecializationDecl
*
535 ClassTemplateDecl::findSpecialization(ArrayRef
<TemplateArgument
> Args
,
537 return findSpecializationImpl(getSpecializations(), InsertPos
, Args
);
540 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl
*D
,
542 addSpecializationImpl
<ClassTemplateDecl
>(getSpecializations(), D
, InsertPos
);
545 ClassTemplatePartialSpecializationDecl
*
546 ClassTemplateDecl::findPartialSpecialization(
547 ArrayRef
<TemplateArgument
> Args
,
548 TemplateParameterList
*TPL
, void *&InsertPos
) {
549 return findSpecializationImpl(getPartialSpecializations(), InsertPos
, Args
,
553 void ClassTemplatePartialSpecializationDecl::Profile(
554 llvm::FoldingSetNodeID
&ID
, ArrayRef
<TemplateArgument
> TemplateArgs
,
555 TemplateParameterList
*TPL
, const ASTContext
&Context
) {
556 ID
.AddInteger(TemplateArgs
.size());
557 for (const TemplateArgument
&TemplateArg
: TemplateArgs
)
558 TemplateArg
.Profile(ID
, Context
);
559 TPL
->Profile(ID
, Context
);
562 void ClassTemplateDecl::AddPartialSpecialization(
563 ClassTemplatePartialSpecializationDecl
*D
,
566 getPartialSpecializations().InsertNode(D
, InsertPos
);
568 ClassTemplatePartialSpecializationDecl
*Existing
569 = getPartialSpecializations().GetOrInsertNode(D
);
571 assert(Existing
->isCanonicalDecl() && "Non-canonical specialization?");
574 if (ASTMutationListener
*L
= getASTMutationListener())
575 L
->AddedCXXTemplateSpecialization(this, D
);
578 void ClassTemplateDecl::getPartialSpecializations(
579 SmallVectorImpl
<ClassTemplatePartialSpecializationDecl
*> &PS
) const {
580 llvm::FoldingSetVector
<ClassTemplatePartialSpecializationDecl
> &PartialSpecs
581 = getPartialSpecializations();
583 PS
.reserve(PartialSpecs
.size());
584 for (ClassTemplatePartialSpecializationDecl
&P
: PartialSpecs
)
585 PS
.push_back(P
.getMostRecentDecl());
588 ClassTemplatePartialSpecializationDecl
*
589 ClassTemplateDecl::findPartialSpecialization(QualType T
) {
590 ASTContext
&Context
= getASTContext();
591 for (ClassTemplatePartialSpecializationDecl
&P
:
592 getPartialSpecializations()) {
593 if (Context
.hasSameType(P
.getInjectedSpecializationType(), T
))
594 return P
.getMostRecentDecl();
600 ClassTemplatePartialSpecializationDecl
*
601 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
602 ClassTemplatePartialSpecializationDecl
*D
) {
603 Decl
*DCanon
= D
->getCanonicalDecl();
604 for (ClassTemplatePartialSpecializationDecl
&P
: getPartialSpecializations()) {
605 if (P
.getInstantiatedFromMember()->getCanonicalDecl() == DCanon
)
606 return P
.getMostRecentDecl();
613 ClassTemplateDecl::getInjectedClassNameSpecialization() {
614 Common
*CommonPtr
= getCommonPtr();
615 if (!CommonPtr
->InjectedClassNameType
.isNull())
616 return CommonPtr
->InjectedClassNameType
;
618 // C++0x [temp.dep.type]p2:
619 // The template argument list of a primary template is a template argument
620 // list in which the nth template argument has the value of the nth template
621 // parameter of the class template. If the nth template parameter is a
622 // template parameter pack (14.5.3), the nth template argument is a pack
623 // expansion (14.5.3) whose pattern is the name of the template parameter
625 ASTContext
&Context
= getASTContext();
626 TemplateParameterList
*Params
= getTemplateParameters();
627 SmallVector
<TemplateArgument
, 16> TemplateArgs
;
628 Context
.getInjectedTemplateArgs(Params
, TemplateArgs
);
629 CommonPtr
->InjectedClassNameType
630 = Context
.getTemplateSpecializationType(TemplateName(this),
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
, unsigned ID
) {
657 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
658 false, false, std::nullopt
);
661 TemplateTypeParmDecl
*
662 TemplateTypeParmDecl::CreateDeserialized(const ASTContext
&C
, unsigned 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()
672 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
676 SourceRange
TemplateTypeParmDecl::getSourceRange() const {
677 if (hasDefaultArgument() && !defaultArgumentWasInherited())
678 return SourceRange(getBeginLoc(),
679 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
680 // TypeDecl::getSourceRange returns a range containing name location, which is
681 // wrong for unnamed template parameters. e.g:
682 // it will return <[[typename>]] instead of <[[typename]]>
683 else if (getDeclName().isEmpty())
684 return SourceRange(getBeginLoc());
685 return TypeDecl::getSourceRange();
688 unsigned TemplateTypeParmDecl::getDepth() const {
689 return getTypeForDecl()->castAs
<TemplateTypeParmType
>()->getDepth();
692 unsigned TemplateTypeParmDecl::getIndex() const {
693 return getTypeForDecl()->castAs
<TemplateTypeParmType
>()->getIndex();
696 bool TemplateTypeParmDecl::isParameterPack() const {
697 return getTypeForDecl()->castAs
<TemplateTypeParmType
>()->isParameterPack();
700 void TemplateTypeParmDecl::setTypeConstraint(
701 ConceptReference
*Loc
, Expr
*ImmediatelyDeclaredConstraint
) {
702 assert(HasTypeConstraint
&&
703 "HasTypeConstraint=true must be passed at construction in order to "
704 "call setTypeConstraint");
705 assert(!TypeConstraintInitialized
&&
706 "TypeConstraint was already initialized!");
707 new (getTrailingObjects
<TypeConstraint
>())
708 TypeConstraint(Loc
, ImmediatelyDeclaredConstraint
);
709 TypeConstraintInitialized
= true;
712 //===----------------------------------------------------------------------===//
713 // NonTypeTemplateParmDecl Method Implementations
714 //===----------------------------------------------------------------------===//
716 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
717 DeclContext
*DC
, SourceLocation StartLoc
, SourceLocation IdLoc
, unsigned D
,
718 unsigned P
, IdentifierInfo
*Id
, QualType T
, TypeSourceInfo
*TInfo
,
719 ArrayRef
<QualType
> ExpandedTypes
, ArrayRef
<TypeSourceInfo
*> ExpandedTInfos
)
720 : DeclaratorDecl(NonTypeTemplateParm
, DC
, IdLoc
, Id
, T
, TInfo
, StartLoc
),
721 TemplateParmPosition(D
, P
), ParameterPack(true),
722 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes
.size()) {
723 if (!ExpandedTypes
.empty() && !ExpandedTInfos
.empty()) {
725 getTrailingObjects
<std::pair
<QualType
, TypeSourceInfo
*>>();
726 for (unsigned I
= 0; I
!= NumExpandedTypes
; ++I
) {
727 new (&TypesAndInfos
[I
].first
) QualType(ExpandedTypes
[I
]);
728 TypesAndInfos
[I
].second
= ExpandedTInfos
[I
];
733 NonTypeTemplateParmDecl
*
734 NonTypeTemplateParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
735 SourceLocation StartLoc
, SourceLocation IdLoc
,
736 unsigned D
, unsigned P
, IdentifierInfo
*Id
,
737 QualType T
, bool ParameterPack
,
738 TypeSourceInfo
*TInfo
) {
740 C
.getLangOpts().CPlusPlus20
? T
->getContainedAutoType() : nullptr;
742 additionalSizeToAlloc
<std::pair
<QualType
, TypeSourceInfo
*>,
744 AT
&& AT
->isConstrained() ? 1 : 0))
745 NonTypeTemplateParmDecl(DC
, StartLoc
, IdLoc
, D
, P
, Id
, T
, ParameterPack
,
749 NonTypeTemplateParmDecl
*NonTypeTemplateParmDecl::Create(
750 const ASTContext
&C
, DeclContext
*DC
, SourceLocation StartLoc
,
751 SourceLocation IdLoc
, unsigned D
, unsigned P
, IdentifierInfo
*Id
,
752 QualType T
, TypeSourceInfo
*TInfo
, ArrayRef
<QualType
> ExpandedTypes
,
753 ArrayRef
<TypeSourceInfo
*> ExpandedTInfos
) {
754 AutoType
*AT
= TInfo
->getType()->getContainedAutoType();
756 additionalSizeToAlloc
<std::pair
<QualType
, TypeSourceInfo
*>,
758 ExpandedTypes
.size(), AT
&& AT
->isConstrained() ? 1 : 0))
759 NonTypeTemplateParmDecl(DC
, StartLoc
, IdLoc
, D
, P
, Id
, T
, TInfo
,
760 ExpandedTypes
, ExpandedTInfos
);
763 NonTypeTemplateParmDecl
*
764 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext
&C
, unsigned ID
,
765 bool HasTypeConstraint
) {
766 return new (C
, ID
, additionalSizeToAlloc
<std::pair
<QualType
,
769 HasTypeConstraint
? 1 : 0))
770 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
771 0, 0, nullptr, QualType(), false, nullptr);
774 NonTypeTemplateParmDecl
*
775 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext
&C
, unsigned ID
,
776 unsigned NumExpandedTypes
,
777 bool HasTypeConstraint
) {
780 additionalSizeToAlloc
<std::pair
<QualType
, TypeSourceInfo
*>, Expr
*>(
781 NumExpandedTypes
, HasTypeConstraint
? 1 : 0))
782 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
783 0, 0, nullptr, QualType(), nullptr,
784 std::nullopt
, std::nullopt
);
785 NTTP
->NumExpandedTypes
= NumExpandedTypes
;
789 SourceRange
NonTypeTemplateParmDecl::getSourceRange() const {
790 if (hasDefaultArgument() && !defaultArgumentWasInherited())
791 return SourceRange(getOuterLocStart(),
792 getDefaultArgument()->getSourceRange().getEnd());
793 return DeclaratorDecl::getSourceRange();
796 SourceLocation
NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
797 return hasDefaultArgument()
798 ? getDefaultArgument()->getSourceRange().getBegin()
802 //===----------------------------------------------------------------------===//
803 // TemplateTemplateParmDecl Method Implementations
804 //===----------------------------------------------------------------------===//
806 void TemplateTemplateParmDecl::anchor() {}
808 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
809 DeclContext
*DC
, SourceLocation L
, unsigned D
, unsigned P
,
810 IdentifierInfo
*Id
, TemplateParameterList
*Params
,
811 ArrayRef
<TemplateParameterList
*> Expansions
)
812 : TemplateDecl(TemplateTemplateParm
, DC
, L
, Id
, Params
),
813 TemplateParmPosition(D
, P
), ParameterPack(true),
814 ExpandedParameterPack(true), NumExpandedParams(Expansions
.size()) {
815 if (!Expansions
.empty())
816 std::uninitialized_copy(Expansions
.begin(), Expansions
.end(),
817 getTrailingObjects
<TemplateParameterList
*>());
820 TemplateTemplateParmDecl
*
821 TemplateTemplateParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
822 SourceLocation L
, unsigned D
, unsigned P
,
823 bool ParameterPack
, IdentifierInfo
*Id
,
824 TemplateParameterList
*Params
) {
825 return new (C
, DC
) TemplateTemplateParmDecl(DC
, L
, D
, P
, ParameterPack
, Id
,
829 TemplateTemplateParmDecl
*
830 TemplateTemplateParmDecl::Create(const ASTContext
&C
, DeclContext
*DC
,
831 SourceLocation L
, unsigned D
, unsigned P
,
833 TemplateParameterList
*Params
,
834 ArrayRef
<TemplateParameterList
*> Expansions
) {
836 additionalSizeToAlloc
<TemplateParameterList
*>(Expansions
.size()))
837 TemplateTemplateParmDecl(DC
, L
, D
, P
, Id
, Params
, Expansions
);
840 TemplateTemplateParmDecl
*
841 TemplateTemplateParmDecl::CreateDeserialized(ASTContext
&C
, unsigned ID
) {
842 return new (C
, ID
) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
843 false, nullptr, nullptr);
846 TemplateTemplateParmDecl
*
847 TemplateTemplateParmDecl::CreateDeserialized(ASTContext
&C
, unsigned ID
,
848 unsigned NumExpansions
) {
850 new (C
, ID
, additionalSizeToAlloc
<TemplateParameterList
*>(NumExpansions
))
851 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
852 nullptr, std::nullopt
);
853 TTP
->NumExpandedParams
= NumExpansions
;
857 SourceLocation
TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
858 return hasDefaultArgument() ? getDefaultArgument().getLocation()
862 void TemplateTemplateParmDecl::setDefaultArgument(
863 const ASTContext
&C
, const TemplateArgumentLoc
&DefArg
) {
864 if (DefArg
.getArgument().isNull())
865 DefaultArgument
.set(nullptr);
867 DefaultArgument
.set(new (C
) TemplateArgumentLoc(DefArg
));
870 //===----------------------------------------------------------------------===//
871 // TemplateArgumentList Implementation
872 //===----------------------------------------------------------------------===//
873 TemplateArgumentList::TemplateArgumentList(ArrayRef
<TemplateArgument
> Args
)
874 : Arguments(getTrailingObjects
<TemplateArgument
>()),
875 NumArguments(Args
.size()) {
876 std::uninitialized_copy(Args
.begin(), Args
.end(),
877 getTrailingObjects
<TemplateArgument
>());
880 TemplateArgumentList
*
881 TemplateArgumentList::CreateCopy(ASTContext
&Context
,
882 ArrayRef
<TemplateArgument
> Args
) {
883 void *Mem
= Context
.Allocate(totalSizeToAlloc
<TemplateArgument
>(Args
.size()));
884 return new (Mem
) TemplateArgumentList(Args
);
887 FunctionTemplateSpecializationInfo
*FunctionTemplateSpecializationInfo::Create(
888 ASTContext
&C
, FunctionDecl
*FD
, FunctionTemplateDecl
*Template
,
889 TemplateSpecializationKind TSK
, const TemplateArgumentList
*TemplateArgs
,
890 const TemplateArgumentListInfo
*TemplateArgsAsWritten
, SourceLocation POI
,
891 MemberSpecializationInfo
*MSInfo
) {
892 const ASTTemplateArgumentListInfo
*ArgsAsWritten
= nullptr;
893 if (TemplateArgsAsWritten
)
894 ArgsAsWritten
= ASTTemplateArgumentListInfo::Create(C
,
895 *TemplateArgsAsWritten
);
898 C
.Allocate(totalSizeToAlloc
<MemberSpecializationInfo
*>(MSInfo
? 1 : 0));
899 return new (Mem
) FunctionTemplateSpecializationInfo(
900 FD
, Template
, TSK
, TemplateArgs
, ArgsAsWritten
, POI
, MSInfo
);
903 //===----------------------------------------------------------------------===//
904 // ClassTemplateSpecializationDecl Implementation
905 //===----------------------------------------------------------------------===//
907 ClassTemplateSpecializationDecl::
908 ClassTemplateSpecializationDecl(ASTContext
&Context
, Kind DK
, TagKind TK
,
909 DeclContext
*DC
, SourceLocation StartLoc
,
910 SourceLocation IdLoc
,
911 ClassTemplateDecl
*SpecializedTemplate
,
912 ArrayRef
<TemplateArgument
> Args
,
913 ClassTemplateSpecializationDecl
*PrevDecl
)
914 : CXXRecordDecl(DK
, TK
, Context
, DC
, StartLoc
, IdLoc
,
915 SpecializedTemplate
->getIdentifier(), PrevDecl
),
916 SpecializedTemplate(SpecializedTemplate
),
917 TemplateArgs(TemplateArgumentList::CreateCopy(Context
, Args
)),
918 SpecializationKind(TSK_Undeclared
) {
921 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext
&C
,
923 : CXXRecordDecl(DK
, TTK_Struct
, C
, nullptr, SourceLocation(),
924 SourceLocation(), nullptr, nullptr),
925 SpecializationKind(TSK_Undeclared
) {}
927 ClassTemplateSpecializationDecl
*
928 ClassTemplateSpecializationDecl::Create(ASTContext
&Context
, TagKind TK
,
930 SourceLocation StartLoc
,
931 SourceLocation IdLoc
,
932 ClassTemplateDecl
*SpecializedTemplate
,
933 ArrayRef
<TemplateArgument
> Args
,
934 ClassTemplateSpecializationDecl
*PrevDecl
) {
936 new (Context
, DC
) ClassTemplateSpecializationDecl(
937 Context
, ClassTemplateSpecialization
, TK
, DC
, StartLoc
, IdLoc
,
938 SpecializedTemplate
, Args
, PrevDecl
);
939 Result
->setMayHaveOutOfDateDef(false);
941 // If the template decl is incomplete, copy the external lexical storage from
942 // the base template. This allows instantiations of incomplete types to
943 // complete using the external AST if the template's declaration came from an
945 if (!SpecializedTemplate
->getTemplatedDecl()->isCompleteDefinition())
946 Result
->setHasExternalLexicalStorage(
947 SpecializedTemplate
->getTemplatedDecl()->hasExternalLexicalStorage());
949 Context
.getTypeDeclType(Result
, PrevDecl
);
953 ClassTemplateSpecializationDecl
*
954 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext
&C
,
957 new (C
, ID
) ClassTemplateSpecializationDecl(C
, ClassTemplateSpecialization
);
958 Result
->setMayHaveOutOfDateDef(false);
962 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
963 raw_ostream
&OS
, const PrintingPolicy
&Policy
, bool Qualified
) const {
964 NamedDecl::getNameForDiagnostic(OS
, Policy
, Qualified
);
966 const auto *PS
= dyn_cast
<ClassTemplatePartialSpecializationDecl
>(this);
967 if (const ASTTemplateArgumentListInfo
*ArgsAsWritten
=
968 PS
? PS
->getTemplateArgsAsWritten() : nullptr) {
969 printTemplateArgumentList(
970 OS
, ArgsAsWritten
->arguments(), Policy
,
971 getSpecializedTemplate()->getTemplateParameters());
973 const TemplateArgumentList
&TemplateArgs
= getTemplateArgs();
974 printTemplateArgumentList(
975 OS
, TemplateArgs
.asArray(), Policy
,
976 getSpecializedTemplate()->getTemplateParameters());
981 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
982 if (const auto *PartialSpec
=
983 SpecializedTemplate
.dyn_cast
<SpecializedPartialSpecialization
*>())
984 return PartialSpec
->PartialSpecialization
->getSpecializedTemplate();
985 return SpecializedTemplate
.get
<ClassTemplateDecl
*>();
989 ClassTemplateSpecializationDecl::getSourceRange() const {
991 SourceLocation Begin
= getTemplateKeywordLoc();
992 if (Begin
.isValid()) {
993 // Here we have an explicit (partial) specialization or instantiation.
994 assert(getSpecializationKind() == TSK_ExplicitSpecialization
||
995 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration
||
996 getSpecializationKind() == TSK_ExplicitInstantiationDefinition
);
997 if (getExternLoc().isValid())
998 Begin
= getExternLoc();
999 SourceLocation End
= getBraceRange().getEnd();
1000 if (End
.isInvalid())
1001 End
= getTypeAsWritten()->getTypeLoc().getEndLoc();
1002 return SourceRange(Begin
, End
);
1004 // An implicit instantiation of a class template partial specialization
1005 // uses ExplicitInfo to record the TypeAsWritten, but the source
1006 // locations should be retrieved from the instantiation pattern.
1007 using CTPSDecl
= ClassTemplatePartialSpecializationDecl
;
1008 auto *ctpsd
= const_cast<CTPSDecl
*>(cast
<CTPSDecl
>(this));
1009 CTPSDecl
*inst_from
= ctpsd
->getInstantiatedFromMember();
1010 assert(inst_from
!= nullptr);
1011 return inst_from
->getSourceRange();
1014 // No explicit info available.
1015 llvm::PointerUnion
<ClassTemplateDecl
*,
1016 ClassTemplatePartialSpecializationDecl
*>
1017 inst_from
= getInstantiatedFrom();
1018 if (inst_from
.isNull())
1019 return getSpecializedTemplate()->getSourceRange();
1020 if (const auto *ctd
= inst_from
.dyn_cast
<ClassTemplateDecl
*>())
1021 return ctd
->getSourceRange();
1022 return inst_from
.get
<ClassTemplatePartialSpecializationDecl
*>()
1027 //===----------------------------------------------------------------------===//
1028 // ConceptDecl Implementation
1029 //===----------------------------------------------------------------------===//
1030 ConceptDecl
*ConceptDecl::Create(ASTContext
&C
, DeclContext
*DC
,
1031 SourceLocation L
, DeclarationName Name
,
1032 TemplateParameterList
*Params
,
1033 Expr
*ConstraintExpr
) {
1034 bool Invalid
= AdoptTemplateParameterList(Params
, DC
);
1035 auto *TD
= new (C
, DC
) ConceptDecl(DC
, L
, Name
, Params
, ConstraintExpr
);
1037 TD
->setInvalidDecl();
1041 ConceptDecl
*ConceptDecl::CreateDeserialized(ASTContext
&C
,
1043 ConceptDecl
*Result
= new (C
, ID
) ConceptDecl(nullptr, SourceLocation(),
1050 //===----------------------------------------------------------------------===//
1051 // ImplicitConceptSpecializationDecl Implementation
1052 //===----------------------------------------------------------------------===//
1053 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1054 DeclContext
*DC
, SourceLocation SL
,
1055 ArrayRef
<TemplateArgument
> ConvertedArgs
)
1056 : Decl(ImplicitConceptSpecialization
, DC
, SL
),
1057 NumTemplateArgs(ConvertedArgs
.size()) {
1058 setTemplateArguments(ConvertedArgs
);
1061 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1062 EmptyShell Empty
, unsigned NumTemplateArgs
)
1063 : Decl(ImplicitConceptSpecialization
, Empty
),
1064 NumTemplateArgs(NumTemplateArgs
) {}
1066 ImplicitConceptSpecializationDecl
*ImplicitConceptSpecializationDecl::Create(
1067 const ASTContext
&C
, DeclContext
*DC
, SourceLocation SL
,
1068 ArrayRef
<TemplateArgument
> ConvertedArgs
) {
1070 additionalSizeToAlloc
<TemplateArgument
>(ConvertedArgs
.size()))
1071 ImplicitConceptSpecializationDecl(DC
, SL
, ConvertedArgs
);
1074 ImplicitConceptSpecializationDecl
*
1075 ImplicitConceptSpecializationDecl::CreateDeserialized(
1076 const ASTContext
&C
, unsigned ID
, unsigned NumTemplateArgs
) {
1077 return new (C
, ID
, additionalSizeToAlloc
<TemplateArgument
>(NumTemplateArgs
))
1078 ImplicitConceptSpecializationDecl(EmptyShell
{}, NumTemplateArgs
);
1081 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1082 ArrayRef
<TemplateArgument
> Converted
) {
1083 assert(Converted
.size() == NumTemplateArgs
);
1084 std::uninitialized_copy(Converted
.begin(), Converted
.end(),
1085 getTrailingObjects
<TemplateArgument
>());
1088 //===----------------------------------------------------------------------===//
1089 // ClassTemplatePartialSpecializationDecl Implementation
1090 //===----------------------------------------------------------------------===//
1091 void ClassTemplatePartialSpecializationDecl::anchor() {}
1093 ClassTemplatePartialSpecializationDecl::
1094 ClassTemplatePartialSpecializationDecl(ASTContext
&Context
, TagKind TK
,
1096 SourceLocation StartLoc
,
1097 SourceLocation IdLoc
,
1098 TemplateParameterList
*Params
,
1099 ClassTemplateDecl
*SpecializedTemplate
,
1100 ArrayRef
<TemplateArgument
> Args
,
1101 const ASTTemplateArgumentListInfo
*ArgInfos
,
1102 ClassTemplatePartialSpecializationDecl
*PrevDecl
)
1103 : ClassTemplateSpecializationDecl(Context
,
1104 ClassTemplatePartialSpecialization
,
1105 TK
, DC
, StartLoc
, IdLoc
,
1106 SpecializedTemplate
, Args
, PrevDecl
),
1107 TemplateParams(Params
), ArgsAsWritten(ArgInfos
),
1108 InstantiatedFromMember(nullptr, false) {
1109 if (AdoptTemplateParameterList(Params
, this))
1113 ClassTemplatePartialSpecializationDecl
*
1114 ClassTemplatePartialSpecializationDecl::
1115 Create(ASTContext
&Context
, TagKind TK
,DeclContext
*DC
,
1116 SourceLocation StartLoc
, SourceLocation IdLoc
,
1117 TemplateParameterList
*Params
,
1118 ClassTemplateDecl
*SpecializedTemplate
,
1119 ArrayRef
<TemplateArgument
> Args
,
1120 const TemplateArgumentListInfo
&ArgInfos
,
1121 QualType CanonInjectedType
,
1122 ClassTemplatePartialSpecializationDecl
*PrevDecl
) {
1123 const ASTTemplateArgumentListInfo
*ASTArgInfos
=
1124 ASTTemplateArgumentListInfo::Create(Context
, ArgInfos
);
1126 auto *Result
= new (Context
, DC
)
1127 ClassTemplatePartialSpecializationDecl(Context
, TK
, DC
, StartLoc
, IdLoc
,
1128 Params
, SpecializedTemplate
, Args
,
1129 ASTArgInfos
, PrevDecl
);
1130 Result
->setSpecializationKind(TSK_ExplicitSpecialization
);
1131 Result
->setMayHaveOutOfDateDef(false);
1133 Context
.getInjectedClassNameType(Result
, CanonInjectedType
);
1137 ClassTemplatePartialSpecializationDecl
*
1138 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext
&C
,
1140 auto *Result
= new (C
, ID
) ClassTemplatePartialSpecializationDecl(C
);
1141 Result
->setMayHaveOutOfDateDef(false);
1145 //===----------------------------------------------------------------------===//
1146 // FriendTemplateDecl Implementation
1147 //===----------------------------------------------------------------------===//
1149 void FriendTemplateDecl::anchor() {}
1151 FriendTemplateDecl
*
1152 FriendTemplateDecl::Create(ASTContext
&Context
, DeclContext
*DC
,
1154 MutableArrayRef
<TemplateParameterList
*> Params
,
1155 FriendUnion Friend
, SourceLocation FLoc
) {
1156 TemplateParameterList
**TPL
= nullptr;
1157 if (!Params
.empty()) {
1158 TPL
= new (Context
) TemplateParameterList
*[Params
.size()];
1159 llvm::copy(Params
, TPL
);
1161 return new (Context
, DC
)
1162 FriendTemplateDecl(DC
, L
, TPL
, Params
.size(), Friend
, FLoc
);
1165 FriendTemplateDecl
*FriendTemplateDecl::CreateDeserialized(ASTContext
&C
,
1167 return new (C
, ID
) FriendTemplateDecl(EmptyShell());
1170 //===----------------------------------------------------------------------===//
1171 // TypeAliasTemplateDecl Implementation
1172 //===----------------------------------------------------------------------===//
1174 TypeAliasTemplateDecl
*
1175 TypeAliasTemplateDecl::Create(ASTContext
&C
, DeclContext
*DC
, SourceLocation L
,
1176 DeclarationName Name
,
1177 TemplateParameterList
*Params
, NamedDecl
*Decl
) {
1178 bool Invalid
= AdoptTemplateParameterList(Params
, DC
);
1179 auto *TD
= new (C
, DC
) TypeAliasTemplateDecl(C
, DC
, L
, Name
, Params
, Decl
);
1181 TD
->setInvalidDecl();
1185 TypeAliasTemplateDecl
*TypeAliasTemplateDecl::CreateDeserialized(ASTContext
&C
,
1187 return new (C
, ID
) TypeAliasTemplateDecl(C
, nullptr, SourceLocation(),
1188 DeclarationName(), nullptr, nullptr);
1191 RedeclarableTemplateDecl::CommonBase
*
1192 TypeAliasTemplateDecl::newCommon(ASTContext
&C
) const {
1193 auto *CommonPtr
= new (C
) Common
;
1194 C
.addDestruction(CommonPtr
);
1198 //===----------------------------------------------------------------------===//
1199 // VarTemplateDecl Implementation
1200 //===----------------------------------------------------------------------===//
1202 VarTemplateDecl
*VarTemplateDecl::getDefinition() {
1203 VarTemplateDecl
*CurD
= this;
1205 if (CurD
->isThisDeclarationADefinition())
1207 CurD
= CurD
->getPreviousDecl();
1212 VarTemplateDecl
*VarTemplateDecl::Create(ASTContext
&C
, DeclContext
*DC
,
1213 SourceLocation L
, DeclarationName Name
,
1214 TemplateParameterList
*Params
,
1216 bool Invalid
= AdoptTemplateParameterList(Params
, DC
);
1217 auto *TD
= new (C
, DC
) VarTemplateDecl(C
, DC
, L
, Name
, Params
, Decl
);
1219 TD
->setInvalidDecl();
1223 VarTemplateDecl
*VarTemplateDecl::CreateDeserialized(ASTContext
&C
,
1225 return new (C
, ID
) VarTemplateDecl(C
, nullptr, SourceLocation(),
1226 DeclarationName(), nullptr, nullptr);
1229 void VarTemplateDecl::LoadLazySpecializations() const {
1230 loadLazySpecializationsImpl();
1233 llvm::FoldingSetVector
<VarTemplateSpecializationDecl
> &
1234 VarTemplateDecl::getSpecializations() const {
1235 LoadLazySpecializations();
1236 return getCommonPtr()->Specializations
;
1239 llvm::FoldingSetVector
<VarTemplatePartialSpecializationDecl
> &
1240 VarTemplateDecl::getPartialSpecializations() const {
1241 LoadLazySpecializations();
1242 return getCommonPtr()->PartialSpecializations
;
1245 RedeclarableTemplateDecl::CommonBase
*
1246 VarTemplateDecl::newCommon(ASTContext
&C
) const {
1247 auto *CommonPtr
= new (C
) Common
;
1248 C
.addDestruction(CommonPtr
);
1252 VarTemplateSpecializationDecl
*
1253 VarTemplateDecl::findSpecialization(ArrayRef
<TemplateArgument
> Args
,
1255 return findSpecializationImpl(getSpecializations(), InsertPos
, Args
);
1258 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl
*D
,
1260 addSpecializationImpl
<VarTemplateDecl
>(getSpecializations(), D
, InsertPos
);
1263 VarTemplatePartialSpecializationDecl
*
1264 VarTemplateDecl::findPartialSpecialization(ArrayRef
<TemplateArgument
> Args
,
1265 TemplateParameterList
*TPL
, void *&InsertPos
) {
1266 return findSpecializationImpl(getPartialSpecializations(), InsertPos
, Args
,
1270 void VarTemplatePartialSpecializationDecl::Profile(
1271 llvm::FoldingSetNodeID
&ID
, ArrayRef
<TemplateArgument
> TemplateArgs
,
1272 TemplateParameterList
*TPL
, const ASTContext
&Context
) {
1273 ID
.AddInteger(TemplateArgs
.size());
1274 for (const TemplateArgument
&TemplateArg
: TemplateArgs
)
1275 TemplateArg
.Profile(ID
, Context
);
1276 TPL
->Profile(ID
, Context
);
1279 void VarTemplateDecl::AddPartialSpecialization(
1280 VarTemplatePartialSpecializationDecl
*D
, void *InsertPos
) {
1282 getPartialSpecializations().InsertNode(D
, InsertPos
);
1284 VarTemplatePartialSpecializationDecl
*Existing
=
1285 getPartialSpecializations().GetOrInsertNode(D
);
1287 assert(Existing
->isCanonicalDecl() && "Non-canonical specialization?");
1290 if (ASTMutationListener
*L
= getASTMutationListener())
1291 L
->AddedCXXTemplateSpecialization(this, D
);
1294 void VarTemplateDecl::getPartialSpecializations(
1295 SmallVectorImpl
<VarTemplatePartialSpecializationDecl
*> &PS
) const {
1296 llvm::FoldingSetVector
<VarTemplatePartialSpecializationDecl
> &PartialSpecs
=
1297 getPartialSpecializations();
1299 PS
.reserve(PartialSpecs
.size());
1300 for (VarTemplatePartialSpecializationDecl
&P
: PartialSpecs
)
1301 PS
.push_back(P
.getMostRecentDecl());
1304 VarTemplatePartialSpecializationDecl
*
1305 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1306 VarTemplatePartialSpecializationDecl
*D
) {
1307 Decl
*DCanon
= D
->getCanonicalDecl();
1308 for (VarTemplatePartialSpecializationDecl
&P
: getPartialSpecializations()) {
1309 if (P
.getInstantiatedFromMember()->getCanonicalDecl() == DCanon
)
1310 return P
.getMostRecentDecl();
1316 //===----------------------------------------------------------------------===//
1317 // VarTemplateSpecializationDecl Implementation
1318 //===----------------------------------------------------------------------===//
1320 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1321 Kind DK
, ASTContext
&Context
, DeclContext
*DC
, SourceLocation StartLoc
,
1322 SourceLocation IdLoc
, VarTemplateDecl
*SpecializedTemplate
, QualType T
,
1323 TypeSourceInfo
*TInfo
, StorageClass S
, ArrayRef
<TemplateArgument
> Args
)
1324 : VarDecl(DK
, Context
, DC
, StartLoc
, IdLoc
,
1325 SpecializedTemplate
->getIdentifier(), T
, TInfo
, S
),
1326 SpecializedTemplate(SpecializedTemplate
),
1327 TemplateArgs(TemplateArgumentList::CreateCopy(Context
, Args
)),
1328 SpecializationKind(TSK_Undeclared
), IsCompleteDefinition(false) {}
1330 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK
,
1332 : VarDecl(DK
, C
, nullptr, SourceLocation(), SourceLocation(), nullptr,
1333 QualType(), nullptr, SC_None
),
1334 SpecializationKind(TSK_Undeclared
), IsCompleteDefinition(false) {}
1336 VarTemplateSpecializationDecl
*VarTemplateSpecializationDecl::Create(
1337 ASTContext
&Context
, DeclContext
*DC
, SourceLocation StartLoc
,
1338 SourceLocation IdLoc
, VarTemplateDecl
*SpecializedTemplate
, QualType T
,
1339 TypeSourceInfo
*TInfo
, StorageClass S
, ArrayRef
<TemplateArgument
> Args
) {
1340 return new (Context
, DC
) VarTemplateSpecializationDecl(
1341 VarTemplateSpecialization
, Context
, DC
, StartLoc
, IdLoc
,
1342 SpecializedTemplate
, T
, TInfo
, S
, Args
);
1345 VarTemplateSpecializationDecl
*
1346 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext
&C
, unsigned ID
) {
1348 VarTemplateSpecializationDecl(VarTemplateSpecialization
, C
);
1351 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1352 raw_ostream
&OS
, const PrintingPolicy
&Policy
, bool Qualified
) const {
1353 NamedDecl::getNameForDiagnostic(OS
, Policy
, Qualified
);
1355 const auto *PS
= dyn_cast
<VarTemplatePartialSpecializationDecl
>(this);
1356 if (const ASTTemplateArgumentListInfo
*ArgsAsWritten
=
1357 PS
? PS
->getTemplateArgsAsWritten() : nullptr) {
1358 printTemplateArgumentList(
1359 OS
, ArgsAsWritten
->arguments(), Policy
,
1360 getSpecializedTemplate()->getTemplateParameters());
1362 const TemplateArgumentList
&TemplateArgs
= getTemplateArgs();
1363 printTemplateArgumentList(
1364 OS
, TemplateArgs
.asArray(), Policy
,
1365 getSpecializedTemplate()->getTemplateParameters());
1369 VarTemplateDecl
*VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1370 if (const auto *PartialSpec
=
1371 SpecializedTemplate
.dyn_cast
<SpecializedPartialSpecialization
*>())
1372 return PartialSpec
->PartialSpecialization
->getSpecializedTemplate();
1373 return SpecializedTemplate
.get
<VarTemplateDecl
*>();
1376 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1377 const TemplateArgumentListInfo
&ArgsInfo
) {
1379 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo
);
1382 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1383 const ASTTemplateArgumentListInfo
*ArgsInfo
) {
1385 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo
);
1388 SourceRange
VarTemplateSpecializationDecl::getSourceRange() const {
1389 if (isExplicitSpecialization() && !hasInit()) {
1390 if (const ASTTemplateArgumentListInfo
*Info
= getTemplateArgsInfo())
1391 return SourceRange(getOuterLocStart(), Info
->getRAngleLoc());
1393 return VarDecl::getSourceRange();
1397 //===----------------------------------------------------------------------===//
1398 // VarTemplatePartialSpecializationDecl Implementation
1399 //===----------------------------------------------------------------------===//
1401 void VarTemplatePartialSpecializationDecl::anchor() {}
1403 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1404 ASTContext
&Context
, DeclContext
*DC
, SourceLocation StartLoc
,
1405 SourceLocation IdLoc
, TemplateParameterList
*Params
,
1406 VarTemplateDecl
*SpecializedTemplate
, QualType T
, TypeSourceInfo
*TInfo
,
1407 StorageClass S
, ArrayRef
<TemplateArgument
> Args
,
1408 const ASTTemplateArgumentListInfo
*ArgInfos
)
1409 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization
, Context
,
1410 DC
, StartLoc
, IdLoc
, SpecializedTemplate
, T
,
1412 TemplateParams(Params
), ArgsAsWritten(ArgInfos
),
1413 InstantiatedFromMember(nullptr, false) {
1414 if (AdoptTemplateParameterList(Params
, DC
))
1418 VarTemplatePartialSpecializationDecl
*
1419 VarTemplatePartialSpecializationDecl::Create(
1420 ASTContext
&Context
, DeclContext
*DC
, SourceLocation StartLoc
,
1421 SourceLocation IdLoc
, TemplateParameterList
*Params
,
1422 VarTemplateDecl
*SpecializedTemplate
, QualType T
, TypeSourceInfo
*TInfo
,
1423 StorageClass S
, ArrayRef
<TemplateArgument
> Args
,
1424 const TemplateArgumentListInfo
&ArgInfos
) {
1425 const ASTTemplateArgumentListInfo
*ASTArgInfos
1426 = ASTTemplateArgumentListInfo::Create(Context
, ArgInfos
);
1429 new (Context
, DC
) VarTemplatePartialSpecializationDecl(
1430 Context
, DC
, StartLoc
, IdLoc
, Params
, SpecializedTemplate
, T
, TInfo
,
1431 S
, Args
, ASTArgInfos
);
1432 Result
->setSpecializationKind(TSK_ExplicitSpecialization
);
1436 VarTemplatePartialSpecializationDecl
*
1437 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext
&C
,
1439 return new (C
, ID
) VarTemplatePartialSpecializationDecl(C
);
1442 SourceRange
VarTemplatePartialSpecializationDecl::getSourceRange() const {
1443 if (isExplicitSpecialization() && !hasInit()) {
1444 if (const ASTTemplateArgumentListInfo
*Info
= getTemplateArgsAsWritten())
1445 return SourceRange(getOuterLocStart(), Info
->getRAngleLoc());
1447 return VarDecl::getSourceRange();
1450 static TemplateParameterList
*
1451 createMakeIntegerSeqParameterList(const ASTContext
&C
, DeclContext
*DC
) {
1453 auto *T
= TemplateTypeParmDecl::Create(
1454 C
, DC
, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1455 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1456 /*HasTypeConstraint=*/false);
1457 T
->setImplicit(true);
1460 TypeSourceInfo
*TI
=
1461 C
.getTrivialTypeSourceInfo(QualType(T
->getTypeForDecl(), 0));
1462 auto *N
= NonTypeTemplateParmDecl::Create(
1463 C
, DC
, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1464 /*Id=*/nullptr, TI
->getType(), /*ParameterPack=*/true, TI
);
1465 N
->setImplicit(true);
1467 // <typename T, T ...Ints>
1468 NamedDecl
*P
[2] = {T
, N
};
1469 auto *TPL
= TemplateParameterList::Create(
1470 C
, SourceLocation(), SourceLocation(), P
, SourceLocation(), nullptr);
1472 // template <typename T, ...Ints> class IntSeq
1473 auto *TemplateTemplateParm
= TemplateTemplateParmDecl::Create(
1474 C
, DC
, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1475 /*ParameterPack=*/false, /*Id=*/nullptr, TPL
);
1476 TemplateTemplateParm
->setImplicit(true);
1479 auto *TemplateTypeParm
= TemplateTypeParmDecl::Create(
1480 C
, DC
, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1481 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1482 /*HasTypeConstraint=*/false);
1483 TemplateTypeParm
->setImplicit(true);
1486 TypeSourceInfo
*TInfo
= C
.getTrivialTypeSourceInfo(
1487 QualType(TemplateTypeParm
->getTypeForDecl(), 0));
1488 auto *NonTypeTemplateParm
= NonTypeTemplateParmDecl::Create(
1489 C
, DC
, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1490 /*Id=*/nullptr, TInfo
->getType(), /*ParameterPack=*/false, TInfo
);
1491 NamedDecl
*Params
[] = {TemplateTemplateParm
, TemplateTypeParm
,
1492 NonTypeTemplateParm
};
1494 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1495 return TemplateParameterList::Create(C
, SourceLocation(), SourceLocation(),
1496 Params
, SourceLocation(), nullptr);
1499 static TemplateParameterList
*
1500 createTypePackElementParameterList(const ASTContext
&C
, DeclContext
*DC
) {
1501 // std::size_t Index
1502 TypeSourceInfo
*TInfo
= C
.getTrivialTypeSourceInfo(C
.getSizeType());
1503 auto *Index
= NonTypeTemplateParmDecl::Create(
1504 C
, DC
, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1505 /*Id=*/nullptr, TInfo
->getType(), /*ParameterPack=*/false, TInfo
);
1508 auto *Ts
= TemplateTypeParmDecl::Create(
1509 C
, DC
, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1510 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1511 /*HasTypeConstraint=*/false);
1512 Ts
->setImplicit(true);
1514 // template <std::size_t Index, typename ...T>
1515 NamedDecl
*Params
[] = {Index
, Ts
};
1516 return TemplateParameterList::Create(C
, SourceLocation(), SourceLocation(),
1517 llvm::ArrayRef(Params
), SourceLocation(),
1521 static TemplateParameterList
*createBuiltinTemplateParameterList(
1522 const ASTContext
&C
, DeclContext
*DC
, BuiltinTemplateKind BTK
) {
1524 case BTK__make_integer_seq
:
1525 return createMakeIntegerSeqParameterList(C
, DC
);
1526 case BTK__type_pack_element
:
1527 return createTypePackElementParameterList(C
, DC
);
1530 llvm_unreachable("unhandled BuiltinTemplateKind!");
1533 void BuiltinTemplateDecl::anchor() {}
1535 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext
&C
, DeclContext
*DC
,
1536 DeclarationName Name
,
1537 BuiltinTemplateKind BTK
)
1538 : TemplateDecl(BuiltinTemplate
, DC
, SourceLocation(), Name
,
1539 createBuiltinTemplateParameterList(C
, DC
, BTK
)),
1542 TemplateParamObjectDecl
*TemplateParamObjectDecl::Create(const ASTContext
&C
,
1545 DeclContext
*DC
= C
.getTranslationUnitDecl();
1546 auto *TPOD
= new (C
, DC
) TemplateParamObjectDecl(DC
, T
, V
);
1547 C
.addDestruction(&TPOD
->Value
);
1551 TemplateParamObjectDecl
*
1552 TemplateParamObjectDecl::CreateDeserialized(ASTContext
&C
, unsigned ID
) {
1553 auto *TPOD
= new (C
, ID
) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1554 C
.addDestruction(&TPOD
->Value
);
1558 void TemplateParamObjectDecl::printName(llvm::raw_ostream
&OS
,
1559 const PrintingPolicy
&Policy
) const {
1560 OS
<< "<template param ";
1561 printAsExpr(OS
, Policy
);
1565 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream
&OS
) const {
1566 printAsExpr(OS
, getASTContext().getPrintingPolicy());
1569 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream
&OS
,
1570 const PrintingPolicy
&Policy
) const {
1571 getType().getUnqualifiedType().print(OS
, Policy
);
1572 printAsInit(OS
, Policy
);
1575 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream
&OS
) const {
1576 printAsInit(OS
, getASTContext().getPrintingPolicy());
1579 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream
&OS
,
1580 const PrintingPolicy
&Policy
) const {
1581 getValue().printPretty(OS
, Policy
, getType(), &getASTContext());
1584 TemplateParameterList
*clang::getReplacedTemplateParameterList(Decl
*D
) {
1585 switch (D
->getKind()) {
1586 case Decl::Kind::ClassTemplate
:
1587 return cast
<ClassTemplateDecl
>(D
)->getTemplateParameters();
1588 case Decl::Kind::ClassTemplateSpecialization
: {
1589 const auto *CTSD
= cast
<ClassTemplateSpecializationDecl
>(D
);
1590 auto P
= CTSD
->getSpecializedTemplateOrPartial();
1591 if (const auto *CTPSD
=
1592 P
.dyn_cast
<ClassTemplatePartialSpecializationDecl
*>())
1593 return CTPSD
->getTemplateParameters();
1594 return cast
<ClassTemplateDecl
*>(P
)->getTemplateParameters();
1596 case Decl::Kind::ClassTemplatePartialSpecialization
:
1597 return cast
<ClassTemplatePartialSpecializationDecl
>(D
)
1598 ->getTemplateParameters();
1599 case Decl::Kind::TypeAliasTemplate
:
1600 return cast
<TypeAliasTemplateDecl
>(D
)->getTemplateParameters();
1601 case Decl::Kind::BuiltinTemplate
:
1602 return cast
<BuiltinTemplateDecl
>(D
)->getTemplateParameters();
1603 case Decl::Kind::CXXDeductionGuide
:
1604 case Decl::Kind::CXXConversion
:
1605 case Decl::Kind::CXXConstructor
:
1606 case Decl::Kind::CXXDestructor
:
1607 case Decl::Kind::CXXMethod
:
1608 case Decl::Kind::Function
:
1609 return cast
<FunctionDecl
>(D
)
1610 ->getTemplateSpecializationInfo()
1612 ->getTemplateParameters();
1613 case Decl::Kind::FunctionTemplate
:
1614 return cast
<FunctionTemplateDecl
>(D
)->getTemplateParameters();
1615 case Decl::Kind::VarTemplate
:
1616 return cast
<VarTemplateDecl
>(D
)->getTemplateParameters();
1617 case Decl::Kind::VarTemplateSpecialization
: {
1618 const auto *VTSD
= cast
<VarTemplateSpecializationDecl
>(D
);
1619 auto P
= VTSD
->getSpecializedTemplateOrPartial();
1620 if (const auto *VTPSD
=
1621 P
.dyn_cast
<VarTemplatePartialSpecializationDecl
*>())
1622 return VTPSD
->getTemplateParameters();
1623 return cast
<VarTemplateDecl
*>(P
)->getTemplateParameters();
1625 case Decl::Kind::VarTemplatePartialSpecialization
:
1626 return cast
<VarTemplatePartialSpecializationDecl
>(D
)
1627 ->getTemplateParameters();
1628 case Decl::Kind::TemplateTemplateParm
:
1629 return cast
<TemplateTemplateParmDecl
>(D
)->getTemplateParameters();
1630 case Decl::Kind::Concept
:
1631 return cast
<ConceptDecl
>(D
)->getTemplateParameters();
1633 llvm_unreachable("Unhandled templated declaration kind");