File indexing completed on 2026-05-10 08:36:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
0015 #define LLVM_CLANG_AST_DECLTEMPLATE_H
0016
0017 #include "clang/AST/ASTConcept.h"
0018 #include "clang/AST/ASTContext.h"
0019 #include "clang/AST/Decl.h"
0020 #include "clang/AST/DeclBase.h"
0021 #include "clang/AST/DeclCXX.h"
0022 #include "clang/AST/DeclarationName.h"
0023 #include "clang/AST/Redeclarable.h"
0024 #include "clang/AST/TemplateBase.h"
0025 #include "clang/AST/Type.h"
0026 #include "clang/Basic/LLVM.h"
0027 #include "clang/Basic/SourceLocation.h"
0028 #include "clang/Basic/Specifiers.h"
0029 #include "llvm/ADT/ArrayRef.h"
0030 #include "llvm/ADT/FoldingSet.h"
0031 #include "llvm/ADT/PointerIntPair.h"
0032 #include "llvm/ADT/PointerUnion.h"
0033 #include "llvm/ADT/iterator.h"
0034 #include "llvm/ADT/iterator_range.h"
0035 #include "llvm/Support/Casting.h"
0036 #include "llvm/Support/Compiler.h"
0037 #include "llvm/Support/TrailingObjects.h"
0038 #include <cassert>
0039 #include <cstddef>
0040 #include <cstdint>
0041 #include <iterator>
0042 #include <optional>
0043 #include <utility>
0044
0045 namespace clang {
0046
0047 enum BuiltinTemplateKind : int;
0048 class ClassTemplateDecl;
0049 class ClassTemplatePartialSpecializationDecl;
0050 class Expr;
0051 class FunctionTemplateDecl;
0052 class IdentifierInfo;
0053 class NonTypeTemplateParmDecl;
0054 class TemplateDecl;
0055 class TemplateTemplateParmDecl;
0056 class TemplateTypeParmDecl;
0057 class ConceptDecl;
0058 class UnresolvedSetImpl;
0059 class VarTemplateDecl;
0060 class VarTemplatePartialSpecializationDecl;
0061
0062
0063 using TemplateParameter =
0064 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
0065 TemplateTemplateParmDecl *>;
0066
0067 NamedDecl *getAsNamedDecl(TemplateParameter P);
0068
0069
0070
0071 class TemplateParameterList final
0072 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
0073 Expr *> {
0074
0075 TemplateArgument *InjectedArgs = nullptr;
0076
0077
0078 SourceLocation TemplateLoc;
0079
0080
0081 SourceLocation LAngleLoc, RAngleLoc;
0082
0083
0084
0085 unsigned NumParams : 29;
0086
0087
0088
0089 LLVM_PREFERRED_TYPE(bool)
0090 unsigned ContainsUnexpandedParameterPack : 1;
0091
0092
0093 LLVM_PREFERRED_TYPE(bool)
0094 unsigned HasRequiresClause : 1;
0095
0096
0097
0098 LLVM_PREFERRED_TYPE(bool)
0099 unsigned HasConstrainedParameters : 1;
0100
0101 protected:
0102 TemplateParameterList(const ASTContext& C, SourceLocation TemplateLoc,
0103 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
0104 SourceLocation RAngleLoc, Expr *RequiresClause);
0105
0106 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
0107 return NumParams;
0108 }
0109
0110 size_t numTrailingObjects(OverloadToken<Expr *>) const {
0111 return HasRequiresClause ? 1 : 0;
0112 }
0113
0114 public:
0115 template <size_t N, bool HasRequiresClause>
0116 friend class FixedSizeTemplateParameterListStorage;
0117 friend TrailingObjects;
0118
0119 static TemplateParameterList *Create(const ASTContext &C,
0120 SourceLocation TemplateLoc,
0121 SourceLocation LAngleLoc,
0122 ArrayRef<NamedDecl *> Params,
0123 SourceLocation RAngleLoc,
0124 Expr *RequiresClause);
0125
0126 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
0127
0128
0129 using iterator = NamedDecl **;
0130
0131
0132 using const_iterator = NamedDecl * const *;
0133
0134 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
0135 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
0136 iterator end() { return begin() + NumParams; }
0137 const_iterator end() const { return begin() + NumParams; }
0138
0139 unsigned size() const { return NumParams; }
0140 bool empty() const { return NumParams == 0; }
0141
0142 ArrayRef<NamedDecl *> asArray() { return llvm::ArrayRef(begin(), end()); }
0143 ArrayRef<const NamedDecl*> asArray() const {
0144 return llvm::ArrayRef(begin(), size());
0145 }
0146
0147 NamedDecl* getParam(unsigned Idx) {
0148 assert(Idx < size() && "Template parameter index out-of-range");
0149 return begin()[Idx];
0150 }
0151 const NamedDecl* getParam(unsigned Idx) const {
0152 assert(Idx < size() && "Template parameter index out-of-range");
0153 return begin()[Idx];
0154 }
0155
0156
0157
0158
0159
0160
0161 unsigned getMinRequiredArguments() const;
0162
0163
0164
0165
0166
0167
0168 unsigned getDepth() const;
0169
0170
0171
0172 bool containsUnexpandedParameterPack() const;
0173
0174
0175 bool hasParameterPack() const {
0176 for (const NamedDecl *P : asArray())
0177 if (P->isParameterPack())
0178 return true;
0179 return false;
0180 }
0181
0182
0183 Expr *getRequiresClause() {
0184 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
0185 }
0186
0187
0188 const Expr *getRequiresClause() const {
0189 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
0190 }
0191
0192
0193
0194
0195
0196
0197
0198 void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
0199
0200 bool hasAssociatedConstraints() const;
0201
0202
0203 ArrayRef<TemplateArgument> getInjectedTemplateArgs(const ASTContext &Context);
0204
0205 SourceLocation getTemplateLoc() const { return TemplateLoc; }
0206 SourceLocation getLAngleLoc() const { return LAngleLoc; }
0207 SourceLocation getRAngleLoc() const { return RAngleLoc; }
0208
0209 SourceRange getSourceRange() const LLVM_READONLY {
0210 return SourceRange(TemplateLoc, RAngleLoc);
0211 }
0212
0213 void print(raw_ostream &Out, const ASTContext &Context,
0214 bool OmitTemplateKW = false) const;
0215 void print(raw_ostream &Out, const ASTContext &Context,
0216 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
0217
0218 static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy,
0219 const TemplateParameterList *TPL,
0220 unsigned Idx);
0221 };
0222
0223
0224
0225
0226 template <size_t N, bool HasRequiresClause>
0227 class FixedSizeTemplateParameterListStorage
0228 : public TemplateParameterList::FixedSizeStorageOwner {
0229 typename TemplateParameterList::FixedSizeStorage<
0230 NamedDecl *, Expr *>::with_counts<
0231 N, HasRequiresClause ? 1u : 0u
0232 >::type storage;
0233
0234 public:
0235 FixedSizeTemplateParameterListStorage(const ASTContext &C,
0236 SourceLocation TemplateLoc,
0237 SourceLocation LAngleLoc,
0238 ArrayRef<NamedDecl *> Params,
0239 SourceLocation RAngleLoc,
0240 Expr *RequiresClause)
0241 : FixedSizeStorageOwner(
0242 (assert(N == Params.size()),
0243 assert(HasRequiresClause == (RequiresClause != nullptr)),
0244 new (static_cast<void *>(&storage)) TemplateParameterList(C,
0245 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
0246 };
0247
0248
0249 class TemplateArgumentList final
0250 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
0251
0252
0253 unsigned NumArguments;
0254
0255
0256
0257 TemplateArgumentList(ArrayRef<TemplateArgument> Args);
0258
0259 public:
0260 friend TrailingObjects;
0261
0262 TemplateArgumentList(const TemplateArgumentList &) = delete;
0263 TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
0264
0265
0266
0267 static TemplateArgumentList *CreateCopy(ASTContext &Context,
0268 ArrayRef<TemplateArgument> Args);
0269
0270
0271 const TemplateArgument &get(unsigned Idx) const {
0272 assert(Idx < NumArguments && "Invalid template argument index");
0273 return data()[Idx];
0274 }
0275
0276
0277 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
0278
0279
0280 ArrayRef<TemplateArgument> asArray() const {
0281 return llvm::ArrayRef(data(), size());
0282 }
0283
0284
0285
0286 unsigned size() const { return NumArguments; }
0287
0288
0289 const TemplateArgument *data() const {
0290 return getTrailingObjects<TemplateArgument>();
0291 }
0292 };
0293
0294 void *allocateDefaultArgStorageChain(const ASTContext &C);
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 template<typename ParmDecl, typename ArgType>
0305 class DefaultArgStorage {
0306
0307
0308
0309 struct Chain {
0310 ParmDecl *PrevDeclWithDefaultArg;
0311 ArgType Value;
0312 };
0313 static_assert(sizeof(Chain) == sizeof(void *) * 2,
0314 "non-pointer argument type?");
0315
0316 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
0317
0318 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
0319 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
0320 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
0321 Parm = Prev;
0322 assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
0323 "should only be one level of indirection");
0324 return Parm;
0325 }
0326
0327 public:
0328 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
0329
0330
0331 bool isSet() const { return !ValueOrInherited.isNull(); }
0332
0333
0334
0335 bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
0336
0337
0338
0339 ArgType get() const {
0340 const DefaultArgStorage *Storage = this;
0341 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
0342 Storage = &Prev->getDefaultArgStorage();
0343 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
0344 return C->Value;
0345 return cast<ArgType>(Storage->ValueOrInherited);
0346 }
0347
0348
0349
0350 const ParmDecl *getInheritedFrom() const {
0351 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
0352 return D;
0353 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
0354 return C->PrevDeclWithDefaultArg;
0355 return nullptr;
0356 }
0357
0358
0359 void set(ArgType Arg) {
0360 assert(!isSet() && "default argument already set");
0361 ValueOrInherited = Arg;
0362 }
0363
0364
0365 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
0366 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
0367 if (!isSet())
0368 ValueOrInherited = InheritedFrom;
0369 else if ([[maybe_unused]] auto *D =
0370 dyn_cast<ParmDecl *>(ValueOrInherited)) {
0371 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
0372 ValueOrInherited =
0373 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
0374 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
0375 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
0376 InheritedFrom));
0377 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
0378 } else
0379 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
0380 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
0381 }
0382
0383
0384 void clear() {
0385 ValueOrInherited = ArgType();
0386 }
0387 };
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 class TemplateDecl : public NamedDecl {
0399 void anchor() override;
0400
0401 protected:
0402
0403 TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
0404 TemplateParameterList *Params, NamedDecl *Decl);
0405
0406
0407
0408 TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
0409 TemplateParameterList *Params)
0410 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
0411
0412 public:
0413 friend class ASTDeclReader;
0414 friend class ASTDeclWriter;
0415
0416
0417 TemplateParameterList *getTemplateParameters() const {
0418 return TemplateParams;
0419 }
0420
0421
0422
0423
0424
0425 void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
0426
0427 bool hasAssociatedConstraints() const;
0428
0429
0430 NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
0431
0432
0433 bool isTypeAlias() const;
0434
0435
0436 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
0437
0438 static bool classofKind(Kind K) {
0439 return K >= firstTemplate && K <= lastTemplate;
0440 }
0441
0442 SourceRange getSourceRange() const override LLVM_READONLY {
0443 return SourceRange(getTemplateParameters()->getTemplateLoc(),
0444 TemplatedDecl->getSourceRange().getEnd());
0445 }
0446
0447 protected:
0448 NamedDecl *TemplatedDecl;
0449 TemplateParameterList *TemplateParams;
0450
0451 public:
0452 void setTemplateParameters(TemplateParameterList *TParams) {
0453 TemplateParams = TParams;
0454 }
0455
0456
0457 void init(NamedDecl *NewTemplatedDecl) {
0458 if (TemplatedDecl)
0459 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
0460 else
0461 TemplatedDecl = NewTemplatedDecl;
0462 }
0463 };
0464
0465
0466
0467
0468 class FunctionTemplateSpecializationInfo final
0469 : public llvm::FoldingSetNode,
0470 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
0471 MemberSpecializationInfo *> {
0472
0473
0474 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
0475
0476
0477
0478
0479
0480 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
0481
0482 public:
0483
0484
0485 TemplateArgumentList *TemplateArguments;
0486
0487
0488
0489 const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
0490
0491
0492
0493 SourceLocation PointOfInstantiation;
0494
0495 private:
0496 FunctionTemplateSpecializationInfo(
0497 FunctionDecl *FD, FunctionTemplateDecl *Template,
0498 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
0499 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
0500 SourceLocation POI, MemberSpecializationInfo *MSInfo)
0501 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
0502 TemplateArguments(TemplateArgs),
0503 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
0504 PointOfInstantiation(POI) {
0505 if (MSInfo)
0506 getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
0507 }
0508
0509 size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
0510 return Function.getInt();
0511 }
0512
0513 public:
0514 friend TrailingObjects;
0515
0516 static FunctionTemplateSpecializationInfo *
0517 Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
0518 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
0519 const TemplateArgumentListInfo *TemplateArgsAsWritten,
0520 SourceLocation POI, MemberSpecializationInfo *MSInfo);
0521
0522
0523 FunctionDecl *getFunction() const { return Function.getPointer(); }
0524
0525
0526 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
0527
0528
0529 TemplateSpecializationKind getTemplateSpecializationKind() const {
0530 return (TemplateSpecializationKind)(Template.getInt() + 1);
0531 }
0532
0533 bool isExplicitSpecialization() const {
0534 return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
0535 }
0536
0537
0538
0539
0540 bool isExplicitInstantiationOrSpecialization() const {
0541 return isTemplateExplicitInstantiationOrSpecialization(
0542 getTemplateSpecializationKind());
0543 }
0544
0545
0546 void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
0547 assert(TSK != TSK_Undeclared &&
0548 "Cannot encode TSK_Undeclared for a function template specialization");
0549 Template.setInt(TSK - 1);
0550 }
0551
0552
0553
0554
0555
0556
0557 SourceLocation getPointOfInstantiation() const {
0558 return PointOfInstantiation;
0559 }
0560
0561
0562
0563 void setPointOfInstantiation(SourceLocation POI) {
0564 PointOfInstantiation = POI;
0565 }
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 MemberSpecializationInfo *getMemberSpecializationInfo() const {
0598 return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
0599 ? getTrailingObjects<MemberSpecializationInfo *>()[0]
0600 : nullptr;
0601 }
0602
0603 void Profile(llvm::FoldingSetNodeID &ID) {
0604 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
0605 }
0606
0607 static void
0608 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
0609 const ASTContext &Context) {
0610 ID.AddInteger(TemplateArgs.size());
0611 for (const TemplateArgument &TemplateArg : TemplateArgs)
0612 TemplateArg.Profile(ID, Context);
0613 }
0614 };
0615
0616
0617
0618
0619 class MemberSpecializationInfo {
0620
0621
0622 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
0623
0624
0625 SourceLocation PointOfInstantiation;
0626
0627 public:
0628 explicit
0629 MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
0630 SourceLocation POI = SourceLocation())
0631 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
0632 assert(TSK != TSK_Undeclared &&
0633 "Cannot encode undeclared template specializations for members");
0634 }
0635
0636
0637
0638 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
0639
0640
0641 TemplateSpecializationKind getTemplateSpecializationKind() const {
0642 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
0643 }
0644
0645 bool isExplicitSpecialization() const {
0646 return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
0647 }
0648
0649
0650 void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
0651 assert(TSK != TSK_Undeclared &&
0652 "Cannot encode undeclared template specializations for members");
0653 MemberAndTSK.setInt(TSK - 1);
0654 }
0655
0656
0657
0658
0659 SourceLocation getPointOfInstantiation() const {
0660 return PointOfInstantiation;
0661 }
0662
0663
0664 void setPointOfInstantiation(SourceLocation POI) {
0665 PointOfInstantiation = POI;
0666 }
0667 };
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691 class DependentFunctionTemplateSpecializationInfo final
0692 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
0693 FunctionTemplateDecl *> {
0694 friend TrailingObjects;
0695
0696
0697 unsigned NumCandidates;
0698
0699 DependentFunctionTemplateSpecializationInfo(
0700 const UnresolvedSetImpl &Candidates,
0701 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
0702
0703 public:
0704
0705 const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
0706
0707 static DependentFunctionTemplateSpecializationInfo *
0708 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
0709 const TemplateArgumentListInfo *TemplateArgs);
0710
0711
0712 ArrayRef<FunctionTemplateDecl *> getCandidates() const {
0713 return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
0714 }
0715 };
0716
0717
0718 class RedeclarableTemplateDecl : public TemplateDecl,
0719 public Redeclarable<RedeclarableTemplateDecl>
0720 {
0721 using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
0722
0723 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
0724 return getNextRedeclaration();
0725 }
0726
0727 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
0728 return getPreviousDecl();
0729 }
0730
0731 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
0732 return getMostRecentDecl();
0733 }
0734
0735 void anchor() override;
0736
0737 protected:
0738 template <typename EntryType> struct SpecEntryTraits {
0739 using DeclType = EntryType;
0740
0741 static DeclType *getDecl(EntryType *D) {
0742 return D;
0743 }
0744
0745 static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
0746 return D->getTemplateArgs().asArray();
0747 }
0748 };
0749
0750 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
0751 typename DeclType = typename SETraits::DeclType>
0752 struct SpecIterator
0753 : llvm::iterator_adaptor_base<
0754 SpecIterator<EntryType, SETraits, DeclType>,
0755 typename llvm::FoldingSetVector<EntryType>::iterator,
0756 typename std::iterator_traits<typename llvm::FoldingSetVector<
0757 EntryType>::iterator>::iterator_category,
0758 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
0759 SpecIterator() = default;
0760 explicit SpecIterator(
0761 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
0762 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
0763
0764 DeclType *operator*() const {
0765 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
0766 }
0767
0768 DeclType *operator->() const { return **this; }
0769 };
0770
0771 template <typename EntryType>
0772 static SpecIterator<EntryType>
0773 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
0774 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
0775 }
0776
0777 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
0778
0779 bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
0780 TemplateParameterList *TPL = nullptr) const;
0781
0782 template <class EntryType, typename ...ProfileArguments>
0783 typename SpecEntryTraits<EntryType>::DeclType*
0784 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
0785 void *&InsertPos, ProfileArguments &&...ProfileArgs);
0786
0787 template <class EntryType, typename... ProfileArguments>
0788 typename SpecEntryTraits<EntryType>::DeclType *
0789 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
0790 void *&InsertPos,
0791 ProfileArguments &&...ProfileArgs);
0792
0793 template <class Derived, class EntryType>
0794 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
0795 EntryType *Entry, void *InsertPos);
0796
0797 struct CommonBase {
0798 CommonBase() : InstantiatedFromMember(nullptr, false) {}
0799
0800
0801
0802
0803
0804
0805 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
0806 InstantiatedFromMember;
0807 };
0808
0809
0810
0811 mutable CommonBase *Common = nullptr;
0812
0813
0814
0815
0816 CommonBase *getCommonPtr() const;
0817
0818 virtual CommonBase *newCommon(ASTContext &C) const = 0;
0819
0820
0821 RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
0822 SourceLocation L, DeclarationName Name,
0823 TemplateParameterList *Params, NamedDecl *Decl)
0824 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
0825
0826 public:
0827 friend class ASTDeclReader;
0828 friend class ASTDeclWriter;
0829 friend class ASTReader;
0830 template <class decl_type> friend class RedeclarableTemplate;
0831
0832
0833 RedeclarableTemplateDecl *getCanonicalDecl() override {
0834 return getFirstDecl();
0835 }
0836 const RedeclarableTemplateDecl *getCanonicalDecl() const {
0837 return getFirstDecl();
0838 }
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858 bool isMemberSpecialization() const {
0859 return getCommonPtr()->InstantiatedFromMember.getInt();
0860 }
0861
0862
0863 void setMemberSpecialization() {
0864 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
0865 "Only member templates can be member template specializations");
0866 getCommonPtr()->InstantiatedFromMember.setInt(true);
0867 }
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
0906 return getCommonPtr()->InstantiatedFromMember.getPointer();
0907 }
0908
0909 void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
0910 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
0911 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
0912 }
0913
0914
0915
0916
0917
0918
0919
0920 ArrayRef<TemplateArgument>
0921 getInjectedTemplateArgs(const ASTContext &Context) const {
0922 return getTemplateParameters()->getInjectedTemplateArgs(Context);
0923 }
0924
0925 using redecl_range = redeclarable_base::redecl_range;
0926 using redecl_iterator = redeclarable_base::redecl_iterator;
0927
0928 using redeclarable_base::redecls_begin;
0929 using redeclarable_base::redecls_end;
0930 using redeclarable_base::redecls;
0931 using redeclarable_base::getPreviousDecl;
0932 using redeclarable_base::getMostRecentDecl;
0933 using redeclarable_base::isFirstDecl;
0934
0935
0936 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
0937
0938 static bool classofKind(Kind K) {
0939 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
0940 }
0941 };
0942
0943 template <> struct RedeclarableTemplateDecl::
0944 SpecEntryTraits<FunctionTemplateSpecializationInfo> {
0945 using DeclType = FunctionDecl;
0946
0947 static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
0948 return I->getFunction();
0949 }
0950
0951 static ArrayRef<TemplateArgument>
0952 getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
0953 return I->TemplateArguments->asArray();
0954 }
0955 };
0956
0957
0958 class FunctionTemplateDecl : public RedeclarableTemplateDecl {
0959 protected:
0960 friend class FunctionDecl;
0961
0962
0963
0964 struct Common : CommonBase {
0965
0966
0967 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
0968
0969 Common() = default;
0970 };
0971
0972 FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
0973 DeclarationName Name, TemplateParameterList *Params,
0974 NamedDecl *Decl)
0975 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
0976 Decl) {}
0977
0978 CommonBase *newCommon(ASTContext &C) const override;
0979
0980 Common *getCommonPtr() const {
0981 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
0982 }
0983
0984
0985
0986 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
0987 getSpecializations() const;
0988
0989
0990
0991
0992
0993 void addSpecialization(FunctionTemplateSpecializationInfo* Info,
0994 void *InsertPos);
0995
0996 public:
0997 friend class ASTDeclReader;
0998 friend class ASTDeclWriter;
0999
1000
1001 void LoadLazySpecializations() const;
1002
1003
1004 FunctionDecl *getTemplatedDecl() const {
1005 return static_cast<FunctionDecl *>(TemplatedDecl);
1006 }
1007
1008
1009
1010 bool isThisDeclarationADefinition() const {
1011 return getTemplatedDecl()->isThisDeclarationADefinition();
1012 }
1013
1014 bool isCompatibleWithDefinition() const {
1015 return getTemplatedDecl()->isInstantiatedFromMemberTemplate() ||
1016 isThisDeclarationADefinition();
1017 }
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029 void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D) {
1030 getTemplatedDecl()->setInstantiatedFromMemberTemplate();
1031 RedeclarableTemplateDecl::setInstantiatedFromMemberTemplate(D);
1032 }
1033
1034
1035
1036 FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
1037 void *&InsertPos);
1038
1039 FunctionTemplateDecl *getCanonicalDecl() override {
1040 return cast<FunctionTemplateDecl>(
1041 RedeclarableTemplateDecl::getCanonicalDecl());
1042 }
1043 const FunctionTemplateDecl *getCanonicalDecl() const {
1044 return cast<FunctionTemplateDecl>(
1045 RedeclarableTemplateDecl::getCanonicalDecl());
1046 }
1047
1048
1049
1050 FunctionTemplateDecl *getPreviousDecl() {
1051 return cast_or_null<FunctionTemplateDecl>(
1052 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1053 }
1054 const FunctionTemplateDecl *getPreviousDecl() const {
1055 return cast_or_null<FunctionTemplateDecl>(
1056 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1057 }
1058
1059 FunctionTemplateDecl *getMostRecentDecl() {
1060 return cast<FunctionTemplateDecl>(
1061 static_cast<RedeclarableTemplateDecl *>(this)
1062 ->getMostRecentDecl());
1063 }
1064 const FunctionTemplateDecl *getMostRecentDecl() const {
1065 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1066 }
1067
1068 FunctionTemplateDecl *getInstantiatedFromMemberTemplate() const {
1069 return cast_or_null<FunctionTemplateDecl>(
1070 RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
1071 }
1072
1073 using spec_iterator = SpecIterator<FunctionTemplateSpecializationInfo>;
1074 using spec_range = llvm::iterator_range<spec_iterator>;
1075
1076 spec_range specializations() const {
1077 return spec_range(spec_begin(), spec_end());
1078 }
1079
1080 spec_iterator spec_begin() const {
1081 return makeSpecIterator(getSpecializations(), false);
1082 }
1083
1084 spec_iterator spec_end() const {
1085 return makeSpecIterator(getSpecializations(), true);
1086 }
1087
1088
1089
1090 bool isAbbreviated() const {
1091
1092
1093
1094
1095 const TemplateParameterList *TPL = getTemplateParameters();
1096 return TPL->getParam(TPL->size() - 1)->isImplicit();
1097 }
1098
1099
1100 void mergePrevDecl(FunctionTemplateDecl *Prev);
1101
1102
1103 static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
1104 SourceLocation L,
1105 DeclarationName Name,
1106 TemplateParameterList *Params,
1107 NamedDecl *Decl);
1108
1109
1110 static FunctionTemplateDecl *CreateDeserialized(ASTContext &C,
1111 GlobalDeclID ID);
1112
1113
1114 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1115 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1116 };
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131 class TemplateParmPosition {
1132 protected:
1133 enum { DepthWidth = 20, PositionWidth = 12 };
1134 unsigned Depth : DepthWidth;
1135 unsigned Position : PositionWidth;
1136
1137 static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
1138 static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
1139
1140 TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
1141
1142
1143 assert((D + 1) <= MaxDepth &&
1144 "The depth of template parmeter position is more than 2^20!");
1145 assert((P + 1) <= MaxPosition &&
1146 "The position of template parmeter position is more than 2^12!");
1147 }
1148
1149 public:
1150 TemplateParmPosition() = delete;
1151
1152
1153 unsigned getDepth() const { return Depth; }
1154 void setDepth(unsigned D) {
1155 assert((D + 1) <= MaxDepth &&
1156 "The depth of template parmeter position is more than 2^20!");
1157 Depth = D;
1158 }
1159
1160
1161 unsigned getPosition() const { return Position; }
1162 void setPosition(unsigned P) {
1163 assert((P + 1) <= MaxPosition &&
1164 "The position of template parmeter position is more than 2^12!");
1165 Position = P;
1166 }
1167
1168
1169 unsigned getIndex() const { return Position; }
1170 };
1171
1172
1173
1174
1175
1176
1177
1178 class TemplateTypeParmDecl final : public TypeDecl,
1179 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1180
1181 friend class Sema;
1182 friend TrailingObjects;
1183 friend class ASTDeclReader;
1184
1185
1186
1187
1188
1189 bool Typename : 1;
1190
1191
1192 bool HasTypeConstraint : 1;
1193
1194
1195
1196
1197 bool TypeConstraintInitialized : 1;
1198
1199
1200
1201
1202 bool ExpandedParameterPack : 1;
1203
1204
1205 unsigned NumExpanded = 0;
1206
1207
1208 using DefArgStorage =
1209 DefaultArgStorage<TemplateTypeParmDecl, TemplateArgumentLoc *>;
1210 DefArgStorage DefaultArgument;
1211
1212 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1213 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1214 bool HasTypeConstraint,
1215 std::optional<unsigned> NumExpanded)
1216 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1217 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1218 ExpandedParameterPack(NumExpanded),
1219 NumExpanded(NumExpanded.value_or(0)) {}
1220
1221 public:
1222 static TemplateTypeParmDecl *
1223 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1224 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1225 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1226 std::optional<unsigned> NumExpanded = std::nullopt);
1227 static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
1228 GlobalDeclID ID);
1229 static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
1230 GlobalDeclID ID,
1231 bool HasTypeConstraint);
1232
1233
1234
1235
1236
1237
1238 bool wasDeclaredWithTypename() const {
1239 return Typename && !HasTypeConstraint;
1240 }
1241
1242 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1243
1244
1245
1246 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1247
1248
1249 const TemplateArgumentLoc &getDefaultArgument() const {
1250 static const TemplateArgumentLoc NoneLoc;
1251 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1252 }
1253
1254
1255 SourceLocation getDefaultArgumentLoc() const;
1256
1257
1258
1259 bool defaultArgumentWasInherited() const {
1260 return DefaultArgument.isInherited();
1261 }
1262
1263
1264 void setDefaultArgument(const ASTContext &C,
1265 const TemplateArgumentLoc &DefArg);
1266
1267
1268
1269 void setInheritedDefaultArgument(const ASTContext &C,
1270 TemplateTypeParmDecl *Prev) {
1271 DefaultArgument.setInherited(C, Prev);
1272 }
1273
1274
1275 void removeDefaultArgument() {
1276 DefaultArgument.clear();
1277 }
1278
1279
1280
1281 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1282
1283
1284 unsigned getDepth() const;
1285
1286
1287 unsigned getIndex() const;
1288
1289
1290 bool isParameterPack() const;
1291
1292
1293
1294
1295
1296 bool isPackExpansion() const {
1297 if (!isParameterPack())
1298 return false;
1299 if (const TypeConstraint *TC = getTypeConstraint())
1300 if (TC->hasExplicitTemplateArgs())
1301 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1302 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1303 return true;
1304 return false;
1305 }
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1329
1330
1331 unsigned getNumExpansionParameters() const {
1332 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1333 return NumExpanded;
1334 }
1335
1336
1337
1338 const TypeConstraint *getTypeConstraint() const {
1339 return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
1340 nullptr;
1341 }
1342
1343 void setTypeConstraint(ConceptReference *CR,
1344 Expr *ImmediatelyDeclaredConstraint);
1345
1346
1347 bool hasTypeConstraint() const {
1348 return HasTypeConstraint;
1349 }
1350
1351
1352
1353
1354
1355
1356 void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
1357 if (HasTypeConstraint)
1358 AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
1359 }
1360
1361 SourceRange getSourceRange() const override LLVM_READONLY;
1362
1363
1364 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1365 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1366 };
1367
1368
1369
1370
1371
1372
1373 class NonTypeTemplateParmDecl final
1374 : public DeclaratorDecl,
1375 protected TemplateParmPosition,
1376 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1377 std::pair<QualType, TypeSourceInfo *>,
1378 Expr *> {
1379 friend class ASTDeclReader;
1380 friend TrailingObjects;
1381
1382
1383
1384 using DefArgStorage =
1385 DefaultArgStorage<NonTypeTemplateParmDecl, TemplateArgumentLoc *>;
1386 DefArgStorage DefaultArgument;
1387
1388
1389
1390
1391
1392 bool ParameterPack;
1393
1394
1395
1396
1397 bool ExpandedParameterPack = false;
1398
1399
1400 unsigned NumExpandedTypes = 0;
1401
1402 size_t numTrailingObjects(
1403 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1404 return NumExpandedTypes;
1405 }
1406
1407 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1408 SourceLocation IdLoc, unsigned D, unsigned P,
1409 const IdentifierInfo *Id, QualType T,
1410 bool ParameterPack, TypeSourceInfo *TInfo)
1411 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1412 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1413
1414 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1415 SourceLocation IdLoc, unsigned D, unsigned P,
1416 const IdentifierInfo *Id, QualType T,
1417 TypeSourceInfo *TInfo,
1418 ArrayRef<QualType> ExpandedTypes,
1419 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1420
1421 public:
1422 static NonTypeTemplateParmDecl *
1423 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1424 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1425 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1426
1427 static NonTypeTemplateParmDecl *
1428 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1429 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1430 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1431 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1432
1433 static NonTypeTemplateParmDecl *
1434 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1435 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1436 GlobalDeclID ID,
1437 unsigned NumExpandedTypes,
1438 bool HasTypeConstraint);
1439
1440 using TemplateParmPosition::getDepth;
1441 using TemplateParmPosition::setDepth;
1442 using TemplateParmPosition::getPosition;
1443 using TemplateParmPosition::setPosition;
1444 using TemplateParmPosition::getIndex;
1445
1446 SourceRange getSourceRange() const override LLVM_READONLY;
1447
1448 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1449
1450
1451
1452 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1453
1454
1455 const TemplateArgumentLoc &getDefaultArgument() const {
1456 static const TemplateArgumentLoc NoneLoc;
1457 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1458 }
1459
1460
1461 SourceLocation getDefaultArgumentLoc() const;
1462
1463
1464
1465 bool defaultArgumentWasInherited() const {
1466 return DefaultArgument.isInherited();
1467 }
1468
1469
1470
1471
1472 void setDefaultArgument(const ASTContext &C,
1473 const TemplateArgumentLoc &DefArg);
1474 void setInheritedDefaultArgument(const ASTContext &C,
1475 NonTypeTemplateParmDecl *Parm) {
1476 DefaultArgument.setInherited(C, Parm);
1477 }
1478
1479
1480 void removeDefaultArgument() { DefaultArgument.clear(); }
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491 bool isParameterPack() const { return ParameterPack; }
1492
1493
1494
1495
1496
1497
1498 bool isPackExpansion() const {
1499 return ParameterPack && getType()->getAs<PackExpansionType>();
1500 }
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1527
1528
1529
1530 unsigned getNumExpansionTypes() const {
1531 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1532 return NumExpandedTypes;
1533 }
1534
1535
1536
1537 QualType getExpansionType(unsigned I) const {
1538 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1539 auto TypesAndInfos =
1540 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1541 return TypesAndInfos[I].first;
1542 }
1543
1544
1545
1546 TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
1547 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1548 auto TypesAndInfos =
1549 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1550 return TypesAndInfos[I].second;
1551 }
1552
1553
1554
1555 Expr *getPlaceholderTypeConstraint() const {
1556 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1557 nullptr;
1558 }
1559
1560 void setPlaceholderTypeConstraint(Expr *E) {
1561 *getTrailingObjects<Expr *>() = E;
1562 }
1563
1564
1565
1566 bool hasPlaceholderTypeConstraint() const {
1567 auto *AT = getType()->getContainedAutoType();
1568 return AT && AT->isConstrained();
1569 }
1570
1571
1572
1573
1574
1575
1576
1577 void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
1578 if (Expr *E = getPlaceholderTypeConstraint())
1579 AC.push_back(E);
1580 }
1581
1582
1583 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1584 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1585 };
1586
1587
1588
1589
1590
1591
1592
1593
1594 class TemplateTemplateParmDecl final
1595 : public TemplateDecl,
1596 protected TemplateParmPosition,
1597 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1598 TemplateParameterList *> {
1599
1600 using DefArgStorage =
1601 DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>;
1602 DefArgStorage DefaultArgument;
1603
1604
1605
1606
1607
1608 LLVM_PREFERRED_TYPE(bool)
1609 unsigned Typename : 1;
1610
1611
1612 LLVM_PREFERRED_TYPE(bool)
1613 unsigned ParameterPack : 1;
1614
1615
1616
1617
1618 LLVM_PREFERRED_TYPE(bool)
1619 unsigned ExpandedParameterPack : 1;
1620
1621
1622 unsigned NumExpandedParams = 0;
1623
1624 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
1625 unsigned P, bool ParameterPack, IdentifierInfo *Id,
1626 bool Typename, TemplateParameterList *Params)
1627 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1628 TemplateParmPosition(D, P), Typename(Typename),
1629 ParameterPack(ParameterPack), ExpandedParameterPack(false) {}
1630
1631 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
1632 unsigned P, IdentifierInfo *Id, bool Typename,
1633 TemplateParameterList *Params,
1634 ArrayRef<TemplateParameterList *> Expansions);
1635
1636 void anchor() override;
1637
1638 public:
1639 friend class ASTDeclReader;
1640 friend class ASTDeclWriter;
1641 friend TrailingObjects;
1642
1643 static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1644 SourceLocation L, unsigned D,
1645 unsigned P, bool ParameterPack,
1646 IdentifierInfo *Id, bool Typename,
1647 TemplateParameterList *Params);
1648 static TemplateTemplateParmDecl *
1649 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
1650 unsigned P, IdentifierInfo *Id, bool Typename,
1651 TemplateParameterList *Params,
1652 ArrayRef<TemplateParameterList *> Expansions);
1653
1654 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1655 GlobalDeclID ID);
1656 static TemplateTemplateParmDecl *
1657 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1658
1659 using TemplateParmPosition::getDepth;
1660 using TemplateParmPosition::setDepth;
1661 using TemplateParmPosition::getPosition;
1662 using TemplateParmPosition::setPosition;
1663 using TemplateParmPosition::getIndex;
1664
1665
1666
1667 bool wasDeclaredWithTypename() const { return Typename; }
1668
1669
1670
1671 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1672
1673
1674
1675
1676
1677
1678
1679 bool isParameterPack() const { return ParameterPack; }
1680
1681
1682
1683
1684
1685 bool isPackExpansion() const {
1686 return ParameterPack &&
1687 getTemplateParameters()->containsUnexpandedParameterPack();
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1709
1710
1711
1712 unsigned getNumExpansionTemplateParameters() const {
1713 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1714 return NumExpandedParams;
1715 }
1716
1717
1718
1719 TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
1720 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1721 return getTrailingObjects<TemplateParameterList *>()[I];
1722 }
1723
1724 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1725
1726
1727
1728 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1729
1730
1731 const TemplateArgumentLoc &getDefaultArgument() const {
1732 static const TemplateArgumentLoc NoneLoc;
1733 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1734 }
1735
1736
1737 SourceLocation getDefaultArgumentLoc() const;
1738
1739
1740
1741 bool defaultArgumentWasInherited() const {
1742 return DefaultArgument.isInherited();
1743 }
1744
1745
1746
1747
1748 void setDefaultArgument(const ASTContext &C,
1749 const TemplateArgumentLoc &DefArg);
1750 void setInheritedDefaultArgument(const ASTContext &C,
1751 TemplateTemplateParmDecl *Prev) {
1752 DefaultArgument.setInherited(C, Prev);
1753 }
1754
1755
1756 void removeDefaultArgument() { DefaultArgument.clear(); }
1757
1758 SourceRange getSourceRange() const override LLVM_READONLY {
1759 SourceLocation End = getLocation();
1760 if (hasDefaultArgument() && !defaultArgumentWasInherited())
1761 End = getDefaultArgument().getSourceRange().getEnd();
1762 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1763 }
1764
1765
1766 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1767 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1768 };
1769
1770
1771
1772
1773 class BuiltinTemplateDecl : public TemplateDecl {
1774 BuiltinTemplateKind BTK;
1775
1776 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1777 DeclarationName Name, BuiltinTemplateKind BTK);
1778
1779 void anchor() override;
1780
1781 public:
1782
1783 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1784 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1785
1786 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1787 DeclarationName Name,
1788 BuiltinTemplateKind BTK) {
1789 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1790 }
1791
1792 SourceRange getSourceRange() const override LLVM_READONLY {
1793 return {};
1794 }
1795
1796 BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
1797 };
1798
1799
1800
1801 struct ExplicitInstantiationInfo {
1802
1803 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr;
1804
1805
1806 SourceLocation ExternKeywordLoc;
1807
1808
1809 SourceLocation TemplateKeywordLoc;
1810
1811 ExplicitInstantiationInfo() = default;
1812 };
1813
1814 using SpecializationOrInstantiationInfo =
1815 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1816 ExplicitInstantiationInfo *>;
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831 class ClassTemplateSpecializationDecl : public CXXRecordDecl,
1832 public llvm::FoldingSetNode {
1833
1834
1835
1836 struct SpecializedPartialSpecialization {
1837
1838
1839 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1840
1841
1842
1843 const TemplateArgumentList *TemplateArgs;
1844 };
1845
1846
1847 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1848 SpecializedTemplate;
1849
1850
1851
1852 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1853
1854
1855 const TemplateArgumentList *TemplateArgs;
1856
1857
1858 SourceLocation PointOfInstantiation;
1859
1860
1861 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1862 unsigned SpecializationKind : 3;
1863
1864
1865
1866
1867
1868
1869 bool MatchedPackOnParmToNonPackOnArg : 1;
1870
1871 protected:
1872 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1873 DeclContext *DC, SourceLocation StartLoc,
1874 SourceLocation IdLoc,
1875 ClassTemplateDecl *SpecializedTemplate,
1876 ArrayRef<TemplateArgument> Args,
1877 bool MatchedPackOnParmToNonPackOnArg,
1878 ClassTemplateSpecializationDecl *PrevDecl);
1879
1880 ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
1881
1882 public:
1883 friend class ASTDeclReader;
1884 friend class ASTDeclWriter;
1885
1886 static ClassTemplateSpecializationDecl *
1887 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1888 SourceLocation StartLoc, SourceLocation IdLoc,
1889 ClassTemplateDecl *SpecializedTemplate,
1890 ArrayRef<TemplateArgument> Args, bool MatchedPackOnParmToNonPackOnArg,
1891 ClassTemplateSpecializationDecl *PrevDecl);
1892 static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
1893 GlobalDeclID ID);
1894
1895 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1896 bool Qualified) const override;
1897
1898
1899
1900
1901
1902
1903 ClassTemplateSpecializationDecl *getMostRecentDecl() {
1904 return cast<ClassTemplateSpecializationDecl>(
1905 getMostRecentNonInjectedDecl());
1906 }
1907
1908
1909 ClassTemplateDecl *getSpecializedTemplate() const;
1910
1911
1912
1913 const TemplateArgumentList &getTemplateArgs() const {
1914 return *TemplateArgs;
1915 }
1916
1917 void setTemplateArgs(TemplateArgumentList *Args) {
1918 TemplateArgs = Args;
1919 }
1920
1921
1922
1923 TemplateSpecializationKind getSpecializationKind() const {
1924 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1925 }
1926
1927 bool isExplicitSpecialization() const {
1928 return getSpecializationKind() == TSK_ExplicitSpecialization;
1929 }
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940 bool isClassScopeExplicitSpecialization() const {
1941 return isExplicitSpecialization() &&
1942 isa<CXXRecordDecl>(getLexicalDeclContext());
1943 }
1944
1945
1946
1947
1948 bool isExplicitInstantiationOrSpecialization() const {
1949 return isTemplateExplicitInstantiationOrSpecialization(
1950 getTemplateSpecializationKind());
1951 }
1952
1953 void setSpecializedTemplate(ClassTemplateDecl *Specialized) {
1954 SpecializedTemplate = Specialized;
1955 }
1956
1957 void setSpecializationKind(TemplateSpecializationKind TSK) {
1958 SpecializationKind = TSK;
1959 }
1960
1961 bool hasMatchedPackOnParmToNonPackOnArg() const {
1962 return MatchedPackOnParmToNonPackOnArg;
1963 }
1964
1965
1966 SourceLocation getPointOfInstantiation() const {
1967 return PointOfInstantiation;
1968 }
1969
1970 void setPointOfInstantiation(SourceLocation Loc) {
1971 assert(Loc.isValid() && "point of instantiation must be valid!");
1972 PointOfInstantiation = Loc;
1973 }
1974
1975
1976
1977
1978
1979 llvm::PointerUnion<ClassTemplateDecl *,
1980 ClassTemplatePartialSpecializationDecl *>
1981 getInstantiatedFrom() const {
1982 if (!isTemplateInstantiation(getSpecializationKind()))
1983 return llvm::PointerUnion<ClassTemplateDecl *,
1984 ClassTemplatePartialSpecializationDecl *>();
1985
1986 return getSpecializedTemplateOrPartial();
1987 }
1988
1989
1990
1991 llvm::PointerUnion<ClassTemplateDecl *,
1992 ClassTemplatePartialSpecializationDecl *>
1993 getSpecializedTemplateOrPartial() const {
1994 if (const auto *PartialSpec =
1995 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1996 return PartialSpec->PartialSpecialization;
1997
1998 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1999 }
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012 const TemplateArgumentList &getTemplateInstantiationArgs() const {
2013 if (const auto *PartialSpec =
2014 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2015 return *PartialSpec->TemplateArgs;
2016
2017 return getTemplateArgs();
2018 }
2019
2020
2021
2022
2023 void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
2024 const TemplateArgumentList *TemplateArgs) {
2025 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2026 "Already set to a class template partial specialization!");
2027 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2028 PS->PartialSpecialization = PartialSpec;
2029 PS->TemplateArgs = TemplateArgs;
2030 SpecializedTemplate = PS;
2031 }
2032
2033
2034
2035 void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
2036 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2037 "Previously set to a class template partial specialization!");
2038 SpecializedTemplate = TemplDecl;
2039 }
2040
2041
2042
2043 const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2044 if (auto *Info =
2045 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2046 return Info->TemplateArgsAsWritten;
2047 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2048 }
2049
2050
2051 void
2052 setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
2053 if (auto *Info =
2054 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2055 Info->TemplateArgsAsWritten = ArgsWritten;
2056 else
2057 ExplicitInfo = ArgsWritten;
2058 }
2059
2060
2061 void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
2062 setTemplateArgsAsWritten(
2063 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo));
2064 }
2065
2066
2067 SourceLocation getExternKeywordLoc() const {
2068 if (auto *Info =
2069 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2070 return Info->ExternKeywordLoc;
2071 return SourceLocation();
2072 }
2073
2074
2075 void setExternKeywordLoc(SourceLocation Loc);
2076
2077
2078 SourceLocation getTemplateKeywordLoc() const {
2079 if (auto *Info =
2080 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2081 return Info->TemplateKeywordLoc;
2082 return SourceLocation();
2083 }
2084
2085
2086 void setTemplateKeywordLoc(SourceLocation Loc);
2087
2088 SourceRange getSourceRange() const override LLVM_READONLY;
2089
2090 void Profile(llvm::FoldingSetNodeID &ID) const {
2091 Profile(ID, TemplateArgs->asArray(), getASTContext());
2092 }
2093
2094 static void
2095 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2096 const ASTContext &Context) {
2097 ID.AddInteger(TemplateArgs.size());
2098 for (const TemplateArgument &TemplateArg : TemplateArgs)
2099 TemplateArg.Profile(ID, Context);
2100 }
2101
2102 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2103
2104 static bool classofKind(Kind K) {
2105 return K >= firstClassTemplateSpecialization &&
2106 K <= lastClassTemplateSpecialization;
2107 }
2108 };
2109
2110 class ClassTemplatePartialSpecializationDecl
2111 : public ClassTemplateSpecializationDecl {
2112
2113 TemplateParameterList *TemplateParams = nullptr;
2114
2115
2116
2117
2118
2119
2120 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2121 InstantiatedFromMember;
2122
2123 ClassTemplatePartialSpecializationDecl(
2124 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2125 SourceLocation IdLoc, TemplateParameterList *Params,
2126 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2127 ClassTemplatePartialSpecializationDecl *PrevDecl);
2128
2129 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2130 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2131 InstantiatedFromMember(nullptr, false) {}
2132
2133 void anchor() override;
2134
2135 public:
2136 friend class ASTDeclReader;
2137 friend class ASTDeclWriter;
2138
2139 static ClassTemplatePartialSpecializationDecl *
2140 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2141 SourceLocation StartLoc, SourceLocation IdLoc,
2142 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2143 ArrayRef<TemplateArgument> Args, QualType CanonInjectedType,
2144 ClassTemplatePartialSpecializationDecl *PrevDecl);
2145
2146 static ClassTemplatePartialSpecializationDecl *
2147 CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2148
2149 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2150 return cast<ClassTemplatePartialSpecializationDecl>(
2151 static_cast<ClassTemplateSpecializationDecl *>(
2152 this)->getMostRecentDecl());
2153 }
2154
2155
2156 TemplateParameterList *getTemplateParameters() const {
2157 return TemplateParams;
2158 }
2159
2160
2161 ArrayRef<TemplateArgument>
2162 getInjectedTemplateArgs(const ASTContext &Context) const {
2163 return getTemplateParameters()->getInjectedTemplateArgs(Context);
2164 }
2165
2166
2167
2168
2169
2170
2171
2172 void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
2173 TemplateParams->getAssociatedConstraints(AC);
2174 }
2175
2176 bool hasAssociatedConstraints() const {
2177 return TemplateParams->hasAssociatedConstraints();
2178 }
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2201 const auto *First =
2202 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2203 return First->InstantiatedFromMember.getPointer();
2204 }
2205 ClassTemplatePartialSpecializationDecl *
2206 getInstantiatedFromMemberTemplate() const {
2207 return getInstantiatedFromMember();
2208 }
2209
2210 void setInstantiatedFromMember(
2211 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2212 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2213 First->InstantiatedFromMember.setPointer(PartialSpec);
2214 }
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232 bool isMemberSpecialization() const {
2233 const auto *First =
2234 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2235 return First->InstantiatedFromMember.getInt();
2236 }
2237
2238
2239 void setMemberSpecialization() {
2240 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2241 assert(First->InstantiatedFromMember.getPointer() &&
2242 "Only member templates can be member template specializations");
2243 return First->InstantiatedFromMember.setInt(true);
2244 }
2245
2246
2247
2248
2249 QualType getInjectedSpecializationType() const {
2250 assert(getTypeForDecl() && "partial specialization has no type set!");
2251 return cast<InjectedClassNameType>(getTypeForDecl())
2252 ->getInjectedSpecializationType();
2253 }
2254
2255 SourceRange getSourceRange() const override LLVM_READONLY;
2256
2257 void Profile(llvm::FoldingSetNodeID &ID) const {
2258 Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
2259 getASTContext());
2260 }
2261
2262 static void
2263 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2264 TemplateParameterList *TPL, const ASTContext &Context);
2265
2266 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2267
2268 static bool classofKind(Kind K) {
2269 return K == ClassTemplatePartialSpecialization;
2270 }
2271 };
2272
2273
2274 class ClassTemplateDecl : public RedeclarableTemplateDecl {
2275 protected:
2276
2277
2278 struct Common : CommonBase {
2279
2280
2281 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2282
2283
2284
2285 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2286 PartialSpecializations;
2287
2288
2289 QualType InjectedClassNameType;
2290
2291 Common() = default;
2292 };
2293
2294
2295 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2296 getSpecializations() const;
2297
2298
2299
2300 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2301 getPartialSpecializations() const;
2302
2303 ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
2304 DeclarationName Name, TemplateParameterList *Params,
2305 NamedDecl *Decl)
2306 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2307
2308 CommonBase *newCommon(ASTContext &C) const override;
2309
2310 Common *getCommonPtr() const {
2311 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2312 }
2313
2314 void setCommonPtr(Common *C) { RedeclarableTemplateDecl::Common = C; }
2315
2316 public:
2317
2318 friend class ASTDeclReader;
2319 friend class ASTDeclWriter;
2320 friend class TemplateDeclInstantiator;
2321
2322
2323 void LoadLazySpecializations(bool OnlyPartial = false) const;
2324
2325
2326 CXXRecordDecl *getTemplatedDecl() const {
2327 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2328 }
2329
2330
2331
2332 bool isThisDeclarationADefinition() const {
2333 return getTemplatedDecl()->isThisDeclarationADefinition();
2334 }
2335
2336
2337 static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2338 SourceLocation L,
2339 DeclarationName Name,
2340 TemplateParameterList *Params,
2341 NamedDecl *Decl);
2342
2343
2344 static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2345
2346
2347
2348 ClassTemplateSpecializationDecl *
2349 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2350
2351
2352
2353 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2354
2355 ClassTemplateDecl *getCanonicalDecl() override {
2356 return cast<ClassTemplateDecl>(
2357 RedeclarableTemplateDecl::getCanonicalDecl());
2358 }
2359 const ClassTemplateDecl *getCanonicalDecl() const {
2360 return cast<ClassTemplateDecl>(
2361 RedeclarableTemplateDecl::getCanonicalDecl());
2362 }
2363
2364
2365
2366 ClassTemplateDecl *getPreviousDecl() {
2367 return cast_or_null<ClassTemplateDecl>(
2368 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2369 }
2370 const ClassTemplateDecl *getPreviousDecl() const {
2371 return cast_or_null<ClassTemplateDecl>(
2372 static_cast<const RedeclarableTemplateDecl *>(
2373 this)->getPreviousDecl());
2374 }
2375
2376 ClassTemplateDecl *getMostRecentDecl() {
2377 return cast<ClassTemplateDecl>(
2378 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2379 }
2380 const ClassTemplateDecl *getMostRecentDecl() const {
2381 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2382 }
2383
2384 ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
2385 return cast_or_null<ClassTemplateDecl>(
2386 RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2387 }
2388
2389
2390
2391 ClassTemplatePartialSpecializationDecl *
2392 findPartialSpecialization(ArrayRef<TemplateArgument> Args,
2393 TemplateParameterList *TPL, void *&InsertPos);
2394
2395
2396
2397 void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
2398 void *InsertPos);
2399
2400
2401 void getPartialSpecializations(
2402 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const;
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412 ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422 ClassTemplatePartialSpecializationDecl *
2423 findPartialSpecInstantiatedFromMember(
2424 ClassTemplatePartialSpecializationDecl *D);
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440 QualType getInjectedClassNameSpecialization();
2441
2442 using spec_iterator = SpecIterator<ClassTemplateSpecializationDecl>;
2443 using spec_range = llvm::iterator_range<spec_iterator>;
2444
2445 spec_range specializations() const {
2446 return spec_range(spec_begin(), spec_end());
2447 }
2448
2449 spec_iterator spec_begin() const {
2450 return makeSpecIterator(getSpecializations(), false);
2451 }
2452
2453 spec_iterator spec_end() const {
2454 return makeSpecIterator(getSpecializations(), true);
2455 }
2456
2457
2458 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2459 static bool classofKind(Kind K) { return K == ClassTemplate; }
2460 };
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475 class FriendTemplateDecl : public Decl {
2476 virtual void anchor();
2477
2478 public:
2479 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2480
2481 private:
2482
2483 unsigned NumParams = 0;
2484
2485
2486 TemplateParameterList **Params = nullptr;
2487
2488
2489 FriendUnion Friend;
2490
2491
2492 SourceLocation FriendLoc;
2493
2494 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2495 TemplateParameterList **Params, unsigned NumParams,
2496 FriendUnion Friend, SourceLocation FriendLoc)
2497 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2498 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2499
2500 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2501
2502 public:
2503 friend class ASTDeclReader;
2504
2505 static FriendTemplateDecl *
2506 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2507 MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend,
2508 SourceLocation FriendLoc);
2509
2510 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2511
2512
2513
2514
2515 TypeSourceInfo *getFriendType() const {
2516 return Friend.dyn_cast<TypeSourceInfo*>();
2517 }
2518
2519
2520
2521
2522 NamedDecl *getFriendDecl() const {
2523 return Friend.dyn_cast<NamedDecl*>();
2524 }
2525
2526
2527 SourceLocation getFriendLoc() const {
2528 return FriendLoc;
2529 }
2530
2531 TemplateParameterList *getTemplateParameterList(unsigned i) const {
2532 assert(i <= NumParams);
2533 return Params[i];
2534 }
2535
2536 unsigned getNumTemplateParameters() const {
2537 return NumParams;
2538 }
2539
2540
2541 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2542 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2543 };
2544
2545
2546
2547
2548
2549
2550
2551 class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
2552 protected:
2553 using Common = CommonBase;
2554
2555 TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
2556 DeclarationName Name, TemplateParameterList *Params,
2557 NamedDecl *Decl)
2558 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2559 Decl) {}
2560
2561 CommonBase *newCommon(ASTContext &C) const override;
2562
2563 Common *getCommonPtr() {
2564 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2565 }
2566
2567 public:
2568 friend class ASTDeclReader;
2569 friend class ASTDeclWriter;
2570
2571
2572 TypeAliasDecl *getTemplatedDecl() const {
2573 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2574 }
2575
2576
2577 TypeAliasTemplateDecl *getCanonicalDecl() override {
2578 return cast<TypeAliasTemplateDecl>(
2579 RedeclarableTemplateDecl::getCanonicalDecl());
2580 }
2581 const TypeAliasTemplateDecl *getCanonicalDecl() const {
2582 return cast<TypeAliasTemplateDecl>(
2583 RedeclarableTemplateDecl::getCanonicalDecl());
2584 }
2585
2586
2587
2588 TypeAliasTemplateDecl *getPreviousDecl() {
2589 return cast_or_null<TypeAliasTemplateDecl>(
2590 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2591 }
2592 const TypeAliasTemplateDecl *getPreviousDecl() const {
2593 return cast_or_null<TypeAliasTemplateDecl>(
2594 static_cast<const RedeclarableTemplateDecl *>(
2595 this)->getPreviousDecl());
2596 }
2597
2598 TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() const {
2599 return cast_or_null<TypeAliasTemplateDecl>(
2600 RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2601 }
2602
2603
2604 static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2605 SourceLocation L,
2606 DeclarationName Name,
2607 TemplateParameterList *Params,
2608 NamedDecl *Decl);
2609
2610
2611 static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C,
2612 GlobalDeclID ID);
2613
2614
2615 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2616 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2617 };
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632 class VarTemplateSpecializationDecl : public VarDecl,
2633 public llvm::FoldingSetNode {
2634
2635
2636
2637
2638 struct SpecializedPartialSpecialization {
2639
2640
2641 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2642
2643
2644
2645 const TemplateArgumentList *TemplateArgs;
2646 };
2647
2648
2649 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2650 SpecializedTemplate;
2651
2652
2653
2654 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2655
2656
2657 const TemplateArgumentList *TemplateArgs;
2658
2659
2660 SourceLocation PointOfInstantiation;
2661
2662
2663 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2664 unsigned SpecializationKind : 3;
2665
2666
2667
2668
2669
2670 LLVM_PREFERRED_TYPE(bool)
2671 unsigned IsCompleteDefinition : 1;
2672
2673 protected:
2674 VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
2675 SourceLocation StartLoc, SourceLocation IdLoc,
2676 VarTemplateDecl *SpecializedTemplate,
2677 QualType T, TypeSourceInfo *TInfo,
2678 StorageClass S,
2679 ArrayRef<TemplateArgument> Args);
2680
2681 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2682
2683 public:
2684 friend class ASTDeclReader;
2685 friend class ASTDeclWriter;
2686 friend class VarDecl;
2687
2688 static VarTemplateSpecializationDecl *
2689 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2690 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2691 TypeSourceInfo *TInfo, StorageClass S,
2692 ArrayRef<TemplateArgument> Args);
2693 static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
2694 GlobalDeclID ID);
2695
2696 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2697 bool Qualified) const override;
2698
2699 VarTemplateSpecializationDecl *getMostRecentDecl() {
2700 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2701 return cast<VarTemplateSpecializationDecl>(Recent);
2702 }
2703
2704
2705 VarTemplateDecl *getSpecializedTemplate() const;
2706
2707
2708
2709 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2710
2711
2712
2713 TemplateSpecializationKind getSpecializationKind() const {
2714 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2715 }
2716
2717 bool isExplicitSpecialization() const {
2718 return getSpecializationKind() == TSK_ExplicitSpecialization;
2719 }
2720
2721 bool isClassScopeExplicitSpecialization() const {
2722 return isExplicitSpecialization() &&
2723 isa<CXXRecordDecl>(getLexicalDeclContext());
2724 }
2725
2726
2727
2728
2729 bool isExplicitInstantiationOrSpecialization() const {
2730 return isTemplateExplicitInstantiationOrSpecialization(
2731 getTemplateSpecializationKind());
2732 }
2733
2734 void setSpecializationKind(TemplateSpecializationKind TSK) {
2735 SpecializationKind = TSK;
2736 }
2737
2738
2739 SourceLocation getPointOfInstantiation() const {
2740 return PointOfInstantiation;
2741 }
2742
2743 void setPointOfInstantiation(SourceLocation Loc) {
2744 assert(Loc.isValid() && "point of instantiation must be valid!");
2745 PointOfInstantiation = Loc;
2746 }
2747
2748 void setCompleteDefinition() { IsCompleteDefinition = true; }
2749
2750
2751
2752
2753
2754 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2755 getInstantiatedFrom() const {
2756 if (!isTemplateInstantiation(getSpecializationKind()))
2757 return llvm::PointerUnion<VarTemplateDecl *,
2758 VarTemplatePartialSpecializationDecl *>();
2759
2760 return getSpecializedTemplateOrPartial();
2761 }
2762
2763
2764
2765 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2766 getSpecializedTemplateOrPartial() const {
2767 if (const auto *PartialSpec =
2768 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2769 return PartialSpec->PartialSpecialization;
2770
2771 return cast<VarTemplateDecl *>(SpecializedTemplate);
2772 }
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785 const TemplateArgumentList &getTemplateInstantiationArgs() const {
2786 if (const auto *PartialSpec =
2787 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2788 return *PartialSpec->TemplateArgs;
2789
2790 return getTemplateArgs();
2791 }
2792
2793
2794
2795
2796 void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
2797 const TemplateArgumentList *TemplateArgs) {
2798 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2799 "Already set to a variable template partial specialization!");
2800 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2801 PS->PartialSpecialization = PartialSpec;
2802 PS->TemplateArgs = TemplateArgs;
2803 SpecializedTemplate = PS;
2804 }
2805
2806
2807
2808 void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2809 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2810 "Previously set to a variable template partial specialization!");
2811 SpecializedTemplate = TemplDecl;
2812 }
2813
2814
2815
2816 const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2817 if (auto *Info =
2818 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2819 return Info->TemplateArgsAsWritten;
2820 return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
2821 }
2822
2823
2824 void
2825 setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
2826 if (auto *Info =
2827 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2828 Info->TemplateArgsAsWritten = ArgsWritten;
2829 else
2830 ExplicitInfo = ArgsWritten;
2831 }
2832
2833
2834 void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
2835 setTemplateArgsAsWritten(
2836 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo));
2837 }
2838
2839
2840 SourceLocation getExternKeywordLoc() const {
2841 if (auto *Info =
2842 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2843 return Info->ExternKeywordLoc;
2844 return SourceLocation();
2845 }
2846
2847
2848 void setExternKeywordLoc(SourceLocation Loc);
2849
2850
2851 SourceLocation getTemplateKeywordLoc() const {
2852 if (auto *Info =
2853 dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo))
2854 return Info->TemplateKeywordLoc;
2855 return SourceLocation();
2856 }
2857
2858
2859 void setTemplateKeywordLoc(SourceLocation Loc);
2860
2861 SourceRange getSourceRange() const override LLVM_READONLY;
2862
2863 void Profile(llvm::FoldingSetNodeID &ID) const {
2864 Profile(ID, TemplateArgs->asArray(), getASTContext());
2865 }
2866
2867 static void Profile(llvm::FoldingSetNodeID &ID,
2868 ArrayRef<TemplateArgument> TemplateArgs,
2869 const ASTContext &Context) {
2870 ID.AddInteger(TemplateArgs.size());
2871 for (const TemplateArgument &TemplateArg : TemplateArgs)
2872 TemplateArg.Profile(ID, Context);
2873 }
2874
2875 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2876
2877 static bool classofKind(Kind K) {
2878 return K >= firstVarTemplateSpecialization &&
2879 K <= lastVarTemplateSpecialization;
2880 }
2881 };
2882
2883 class VarTemplatePartialSpecializationDecl
2884 : public VarTemplateSpecializationDecl {
2885
2886 TemplateParameterList *TemplateParams = nullptr;
2887
2888
2889
2890
2891
2892
2893 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2894 InstantiatedFromMember;
2895
2896 VarTemplatePartialSpecializationDecl(
2897 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2898 SourceLocation IdLoc, TemplateParameterList *Params,
2899 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2900 StorageClass S, ArrayRef<TemplateArgument> Args);
2901
2902 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2903 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2904 Context),
2905 InstantiatedFromMember(nullptr, false) {}
2906
2907 void anchor() override;
2908
2909 public:
2910 friend class ASTDeclReader;
2911 friend class ASTDeclWriter;
2912
2913 static VarTemplatePartialSpecializationDecl *
2914 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2915 SourceLocation IdLoc, TemplateParameterList *Params,
2916 VarTemplateDecl *SpecializedTemplate, QualType T,
2917 TypeSourceInfo *TInfo, StorageClass S,
2918 ArrayRef<TemplateArgument> Args);
2919
2920 static VarTemplatePartialSpecializationDecl *
2921 CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2922
2923 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2924 return cast<VarTemplatePartialSpecializationDecl>(
2925 static_cast<VarTemplateSpecializationDecl *>(
2926 this)->getMostRecentDecl());
2927 }
2928
2929
2930 TemplateParameterList *getTemplateParameters() const {
2931 return TemplateParams;
2932 }
2933
2934
2935 ArrayRef<TemplateArgument>
2936 getInjectedTemplateArgs(const ASTContext &Context) const {
2937 return getTemplateParameters()->getInjectedTemplateArgs(Context);
2938 }
2939
2940
2941
2942
2943
2944
2945
2946 void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
2947 TemplateParams->getAssociatedConstraints(AC);
2948 }
2949
2950 bool hasAssociatedConstraints() const {
2951 return TemplateParams->hasAssociatedConstraints();
2952 }
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2975 const auto *First =
2976 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2977 return First->InstantiatedFromMember.getPointer();
2978 }
2979
2980 void
2981 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2982 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2983 First->InstantiatedFromMember.setPointer(PartialSpec);
2984 }
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002 bool isMemberSpecialization() const {
3003 const auto *First =
3004 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
3005 return First->InstantiatedFromMember.getInt();
3006 }
3007
3008
3009 void setMemberSpecialization() {
3010 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
3011 assert(First->InstantiatedFromMember.getPointer() &&
3012 "Only member templates can be member template specializations");
3013 return First->InstantiatedFromMember.setInt(true);
3014 }
3015
3016 SourceRange getSourceRange() const override LLVM_READONLY;
3017
3018 void Profile(llvm::FoldingSetNodeID &ID) const {
3019 Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
3020 getASTContext());
3021 }
3022
3023 static void
3024 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3025 TemplateParameterList *TPL, const ASTContext &Context);
3026
3027 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3028
3029 static bool classofKind(Kind K) {
3030 return K == VarTemplatePartialSpecialization;
3031 }
3032 };
3033
3034
3035 class VarTemplateDecl : public RedeclarableTemplateDecl {
3036 protected:
3037
3038
3039 struct Common : CommonBase {
3040
3041
3042 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3043
3044
3045
3046 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3047 PartialSpecializations;
3048
3049 Common() = default;
3050 };
3051
3052
3053 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3054 getSpecializations() const;
3055
3056
3057
3058 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3059 getPartialSpecializations() const;
3060
3061 VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
3062 DeclarationName Name, TemplateParameterList *Params,
3063 NamedDecl *Decl)
3064 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3065
3066 CommonBase *newCommon(ASTContext &C) const override;
3067
3068 Common *getCommonPtr() const {
3069 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3070 }
3071
3072 public:
3073 friend class ASTDeclReader;
3074 friend class ASTDeclWriter;
3075
3076
3077 void LoadLazySpecializations(bool OnlyPartial = false) const;
3078
3079
3080 VarDecl *getTemplatedDecl() const {
3081 return static_cast<VarDecl *>(TemplatedDecl);
3082 }
3083
3084
3085
3086 bool isThisDeclarationADefinition() const {
3087 return getTemplatedDecl()->isThisDeclarationADefinition();
3088 }
3089
3090 VarTemplateDecl *getDefinition();
3091
3092
3093 static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
3094 SourceLocation L, DeclarationName Name,
3095 TemplateParameterList *Params,
3096 VarDecl *Decl);
3097
3098
3099 static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
3100
3101
3102
3103 VarTemplateSpecializationDecl *
3104 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3105
3106
3107
3108 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3109
3110 VarTemplateDecl *getCanonicalDecl() override {
3111 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3112 }
3113 const VarTemplateDecl *getCanonicalDecl() const {
3114 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3115 }
3116
3117
3118
3119 VarTemplateDecl *getPreviousDecl() {
3120 return cast_or_null<VarTemplateDecl>(
3121 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3122 }
3123 const VarTemplateDecl *getPreviousDecl() const {
3124 return cast_or_null<VarTemplateDecl>(
3125 static_cast<const RedeclarableTemplateDecl *>(
3126 this)->getPreviousDecl());
3127 }
3128
3129 VarTemplateDecl *getMostRecentDecl() {
3130 return cast<VarTemplateDecl>(
3131 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3132 }
3133 const VarTemplateDecl *getMostRecentDecl() const {
3134 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3135 }
3136
3137 VarTemplateDecl *getInstantiatedFromMemberTemplate() const {
3138 return cast_or_null<VarTemplateDecl>(
3139 RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
3140 }
3141
3142
3143
3144 VarTemplatePartialSpecializationDecl *
3145 findPartialSpecialization(ArrayRef<TemplateArgument> Args,
3146 TemplateParameterList *TPL, void *&InsertPos);
3147
3148
3149
3150 void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
3151 void *InsertPos);
3152
3153
3154 void getPartialSpecializations(
3155 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const;
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167 VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
3168 VarTemplatePartialSpecializationDecl *D);
3169
3170 using spec_iterator = SpecIterator<VarTemplateSpecializationDecl>;
3171 using spec_range = llvm::iterator_range<spec_iterator>;
3172
3173 spec_range specializations() const {
3174 return spec_range(spec_begin(), spec_end());
3175 }
3176
3177 spec_iterator spec_begin() const {
3178 return makeSpecIterator(getSpecializations(), false);
3179 }
3180
3181 spec_iterator spec_end() const {
3182 return makeSpecIterator(getSpecializations(), true);
3183 }
3184
3185
3186 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3187 static bool classofKind(Kind K) { return K == VarTemplate; }
3188 };
3189
3190
3191 class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3192 protected:
3193 Expr *ConstraintExpr;
3194
3195 ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
3196 TemplateParameterList *Params, Expr *ConstraintExpr)
3197 : TemplateDecl(Concept, DC, L, Name, Params),
3198 ConstraintExpr(ConstraintExpr) {};
3199 public:
3200 static ConceptDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
3201 DeclarationName Name,
3202 TemplateParameterList *Params,
3203 Expr *ConstraintExpr = nullptr);
3204 static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
3205
3206 Expr *getConstraintExpr() const {
3207 return ConstraintExpr;
3208 }
3209
3210 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3211
3212 void setDefinition(Expr *E) { ConstraintExpr = E; }
3213
3214 SourceRange getSourceRange() const override LLVM_READONLY {
3215 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3216 ConstraintExpr ? ConstraintExpr->getEndLoc()
3217 : SourceLocation());
3218 }
3219
3220 bool isTypeConcept() const {
3221 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3222 }
3223
3224 ConceptDecl *getCanonicalDecl() override {
3225 return cast<ConceptDecl>(getPrimaryMergedDecl(this));
3226 }
3227 const ConceptDecl *getCanonicalDecl() const {
3228 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3229 }
3230
3231
3232 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3233 static bool classofKind(Kind K) { return K == Concept; }
3234
3235 friend class ASTReader;
3236 friend class ASTDeclReader;
3237 friend class ASTDeclWriter;
3238 };
3239
3240
3241
3242
3243 class ImplicitConceptSpecializationDecl final
3244 : public Decl,
3245 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3246 TemplateArgument> {
3247 unsigned NumTemplateArgs;
3248
3249 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3250 ArrayRef<TemplateArgument> ConvertedArgs);
3251 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3252
3253 public:
3254 static ImplicitConceptSpecializationDecl *
3255 Create(const ASTContext &C, DeclContext *DC, SourceLocation SL,
3256 ArrayRef<TemplateArgument> ConvertedArgs);
3257 static ImplicitConceptSpecializationDecl *
3258 CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
3259 unsigned NumTemplateArgs);
3260
3261 ArrayRef<TemplateArgument> getTemplateArguments() const {
3262 return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
3263 NumTemplateArgs);
3264 }
3265 void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
3266
3267 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3268 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3269
3270 friend TrailingObjects;
3271 friend class ASTDeclReader;
3272 };
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286 class TemplateParamObjectDecl : public ValueDecl,
3287 public Mergeable<TemplateParamObjectDecl>,
3288 public llvm::FoldingSetNode {
3289 private:
3290
3291 APValue Value;
3292
3293 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3294 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3295 T),
3296 Value(V) {}
3297
3298 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3299 const APValue &V);
3300 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3301 GlobalDeclID ID);
3302
3303
3304
3305 friend class ASTContext;
3306 friend class ASTReader;
3307 friend class ASTDeclReader;
3308
3309 public:
3310
3311 void printName(llvm::raw_ostream &OS,
3312 const PrintingPolicy &Policy) const override;
3313
3314
3315 void printAsExpr(llvm::raw_ostream &OS) const;
3316 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3317
3318
3319
3320 void printAsInit(llvm::raw_ostream &OS) const;
3321 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3322
3323 const APValue &getValue() const { return Value; }
3324
3325 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3326 const APValue &V) {
3327 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3328 V.Profile(ID);
3329 }
3330 void Profile(llvm::FoldingSetNodeID &ID) {
3331 Profile(ID, getType(), getValue());
3332 }
3333
3334 TemplateParamObjectDecl *getCanonicalDecl() override {
3335 return getFirstDecl();
3336 }
3337 const TemplateParamObjectDecl *getCanonicalDecl() const {
3338 return getFirstDecl();
3339 }
3340
3341 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3342 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3343 };
3344
3345 inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
3346 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3347 return PD;
3348 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3349 return PD;
3350 return cast<TemplateTemplateParmDecl *>(P);
3351 }
3352
3353 inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
3354 auto *TD = dyn_cast<TemplateDecl>(D);
3355 return TD && (isa<ClassTemplateDecl>(TD) ||
3356 isa<ClassTemplatePartialSpecializationDecl>(TD) ||
3357 isa<TypeAliasTemplateDecl>(TD) ||
3358 isa<TemplateTemplateParmDecl>(TD))
3359 ? TD
3360 : nullptr;
3361 }
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374 inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
3375 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3376 if (TTP->isExpandedParameterPack())
3377 return TTP->getNumExpansionParameters();
3378 }
3379
3380 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3381 if (NTTP->isExpandedParameterPack())
3382 return NTTP->getNumExpansionTypes();
3383 }
3384
3385 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3386 if (TTP->isExpandedParameterPack())
3387 return TTP->getNumExpansionTemplateParameters();
3388 }
3389
3390 return std::nullopt;
3391 }
3392
3393
3394
3395 TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
3396
3397 }
3398
3399 #endif