1791 lines · cpp
1//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the C++ related Decl classes for templates.10//11//===----------------------------------------------------------------------===//12 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/ExprCXX.h"20#include "clang/AST/ExternalASTSource.h"21#include "clang/AST/ODRHash.h"22#include "clang/AST/TemplateBase.h"23#include "clang/AST/TemplateName.h"24#include "clang/AST/Type.h"25#include "clang/AST/TypeLoc.h"26#include "clang/Basic/Builtins.h"27#include "clang/Basic/LLVM.h"28#include "clang/Basic/SourceLocation.h"29#include "llvm/ADT/ArrayRef.h"30#include "llvm/ADT/FoldingSet.h"31#include "llvm/ADT/PointerUnion.h"32#include "llvm/ADT/STLExtras.h"33#include "llvm/ADT/SmallVector.h"34#include "llvm/Support/ErrorHandling.h"35#include <cassert>36#include <optional>37#include <utility>38 39using namespace clang;40 41//===----------------------------------------------------------------------===//42// TemplateParameterList Implementation43//===----------------------------------------------------------------------===//44 45template <class TemplateParam>46static bool47DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {48 return P.hasDefaultArgument() &&49 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();50}51 52TemplateParameterList::TemplateParameterList(const ASTContext &C,53 SourceLocation TemplateLoc,54 SourceLocation LAngleLoc,55 ArrayRef<NamedDecl *> Params,56 SourceLocation RAngleLoc,57 Expr *RequiresClause)58 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),59 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),60 HasRequiresClause(RequiresClause != nullptr),61 HasConstrainedParameters(false) {62 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {63 NamedDecl *P = Params[Idx];64 begin()[Idx] = P;65 66 bool IsPack = P->isTemplateParameterPack();67 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {68 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||69 DefaultTemplateArgumentContainsUnexpandedPack(*NTTP)))70 ContainsUnexpandedParameterPack = true;71 if (NTTP->hasPlaceholderTypeConstraint())72 HasConstrainedParameters = true;73 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {74 if (!IsPack &&75 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||76 DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) {77 ContainsUnexpandedParameterPack = true;78 }79 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {80 if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) {81 ContainsUnexpandedParameterPack = true;82 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();83 TC && TC->getImmediatelyDeclaredConstraint()84 ->containsUnexpandedParameterPack()) {85 ContainsUnexpandedParameterPack = true;86 }87 if (TTP->hasTypeConstraint())88 HasConstrainedParameters = true;89 } else {90 llvm_unreachable("unexpected template parameter type");91 }92 }93 94 if (HasRequiresClause) {95 if (RequiresClause->containsUnexpandedParameterPack())96 ContainsUnexpandedParameterPack = true;97 *getTrailingObjects<Expr *>() = RequiresClause;98 }99}100 101bool TemplateParameterList::containsUnexpandedParameterPack() const {102 if (ContainsUnexpandedParameterPack)103 return true;104 if (!HasConstrainedParameters)105 return false;106 107 // An implicit constrained parameter might have had a use of an unexpanded108 // pack added to it after the template parameter list was created. All109 // implicit parameters are at the end of the parameter list.110 for (const NamedDecl *Param : llvm::reverse(asArray())) {111 if (!Param->isImplicit())112 break;113 114 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {115 const auto *TC = TTP->getTypeConstraint();116 if (TC && TC->getImmediatelyDeclaredConstraint()117 ->containsUnexpandedParameterPack())118 return true;119 }120 }121 122 return false;123}124 125TemplateParameterList *126TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,127 SourceLocation LAngleLoc,128 ArrayRef<NamedDecl *> Params,129 SourceLocation RAngleLoc, Expr *RequiresClause) {130 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(131 Params.size(), RequiresClause ? 1u : 0u),132 alignof(TemplateParameterList));133 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,134 RAngleLoc, RequiresClause);135}136 137void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,138 const ASTContext &C) const {139 const Expr *RC = getRequiresClause();140 ID.AddBoolean(RC != nullptr);141 if (RC)142 RC->Profile(ID, C, /*Canonical=*/true);143 ID.AddInteger(size());144 for (NamedDecl *D : *this) {145 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {146 ID.AddInteger(0);147 ID.AddBoolean(NTTP->isParameterPack());148 NTTP->getType().getCanonicalType().Profile(ID);149 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());150 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())151 E->Profile(ID, C, /*Canonical=*/true);152 continue;153 }154 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {155 ID.AddInteger(1);156 ID.AddBoolean(TTP->isParameterPack());157 ID.AddBoolean(TTP->hasTypeConstraint());158 if (const TypeConstraint *TC = TTP->getTypeConstraint())159 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,160 /*Canonical=*/true);161 continue;162 }163 const auto *TTP = cast<TemplateTemplateParmDecl>(D);164 ID.AddInteger(2);165 ID.AddInteger(TTP->templateParameterKind());166 ID.AddBoolean(TTP->isParameterPack());167 TTP->getTemplateParameters()->Profile(ID, C);168 }169}170 171unsigned TemplateParameterList::getMinRequiredArguments() const {172 unsigned NumRequiredArgs = 0;173 for (const NamedDecl *P : asArray()) {174 if (P->isTemplateParameterPack()) {175 if (UnsignedOrNone Expansions = getExpandedPackSize(P)) {176 NumRequiredArgs += *Expansions;177 continue;178 }179 break;180 }181 182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {183 if (TTP->hasDefaultArgument())184 break;185 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {186 if (NTTP->hasDefaultArgument())187 break;188 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P);189 TTP && TTP->hasDefaultArgument())190 break;191 192 ++NumRequiredArgs;193 }194 195 return NumRequiredArgs;196}197 198unsigned TemplateParameterList::getDepth() const {199 if (size() == 0)200 return 0;201 202 const NamedDecl *FirstParm = getParam(0);203 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))204 return TTP->getDepth();205 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))206 return NTTP->getDepth();207 else208 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();209}210 211static bool AdoptTemplateParameterList(TemplateParameterList *Params,212 DeclContext *Owner) {213 bool Invalid = false;214 for (NamedDecl *P : *Params) {215 P->setDeclContext(Owner);216 217 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))218 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))219 Invalid = true;220 221 if (P->isInvalidDecl())222 Invalid = true;223 }224 return Invalid;225}226 227void TemplateParameterList::getAssociatedConstraints(228 llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const {229 if (HasConstrainedParameters)230 for (const NamedDecl *Param : *this) {231 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {232 if (const auto *TC = TTP->getTypeConstraint())233 ACs.emplace_back(TC->getImmediatelyDeclaredConstraint(),234 TC->getArgPackSubstIndex());235 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {236 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())237 ACs.emplace_back(E);238 }239 }240 if (HasRequiresClause)241 ACs.emplace_back(getRequiresClause());242}243 244bool TemplateParameterList::hasAssociatedConstraints() const {245 return HasRequiresClause || HasConstrainedParameters;246}247 248ArrayRef<TemplateArgument>249TemplateParameterList::getInjectedTemplateArgs(const ASTContext &Context) {250 if (!InjectedArgs) {251 InjectedArgs = new (Context) TemplateArgument[size()];252 llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) {253 return Context.getInjectedTemplateArg(ND);254 });255 }256 return {InjectedArgs, NumParams};257}258 259bool TemplateParameterList::shouldIncludeTypeForArgument(260 const PrintingPolicy &Policy, const TemplateParameterList *TPL,261 unsigned Idx) {262 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)263 return true;264 const NamedDecl *TemplParam = TPL->getParam(Idx);265 if (const auto *ParamValueDecl =266 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))267 if (ParamValueDecl->getType()->getContainedDeducedType())268 return true;269 return false;270}271 272namespace clang {273 274void *allocateDefaultArgStorageChain(const ASTContext &C) {275 return new (C) char[sizeof(void*) * 2];276}277 278} // namespace clang279 280//===----------------------------------------------------------------------===//281// TemplateDecl Implementation282//===----------------------------------------------------------------------===//283 284TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,285 DeclarationName Name, TemplateParameterList *Params,286 NamedDecl *Decl)287 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}288 289void TemplateDecl::anchor() {}290 291void TemplateDecl::getAssociatedConstraints(292 llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const {293 TemplateParams->getAssociatedConstraints(ACs);294 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))295 if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause())296 ACs.emplace_back(TRC);297}298 299bool TemplateDecl::hasAssociatedConstraints() const {300 if (TemplateParams->hasAssociatedConstraints())301 return true;302 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))303 return static_cast<bool>(FD->getTrailingRequiresClause());304 return false;305}306 307bool TemplateDecl::isTypeAlias() const {308 switch (getKind()) {309 case TemplateDecl::TypeAliasTemplate:310 return true;311 case TemplateDecl::BuiltinTemplate:312 return !cast<BuiltinTemplateDecl>(this)->isPackProducingBuiltinTemplate();313 default:314 return false;315 };316}317 318//===----------------------------------------------------------------------===//319// RedeclarableTemplateDecl Implementation320//===----------------------------------------------------------------------===//321 322void RedeclarableTemplateDecl::anchor() {}323 324RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {325 if (Common)326 return Common;327 328 // Walk the previous-declaration chain until we either find a declaration329 // with a common pointer or we run out of previous declarations.330 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;331 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;332 Prev = Prev->getPreviousDecl()) {333 if (Prev->Common) {334 Common = Prev->Common;335 break;336 }337 338 PrevDecls.push_back(Prev);339 }340 341 // If we never found a common pointer, allocate one now.342 if (!Common) {343 // FIXME: If any of the declarations is from an AST file, we probably344 // need an update record to add the common data.345 346 Common = newCommon(getASTContext());347 }348 349 // Update any previous declarations we saw with the common pointer.350 for (const RedeclarableTemplateDecl *Prev : PrevDecls)351 Prev->Common = Common;352 353 return Common;354}355 356void RedeclarableTemplateDecl::loadLazySpecializationsImpl(357 bool OnlyPartial /*=false*/) const {358 auto *ExternalSource = getASTContext().getExternalSource();359 if (!ExternalSource)360 return;361 362 ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),363 OnlyPartial);364}365 366bool RedeclarableTemplateDecl::loadLazySpecializationsImpl(367 ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {368 auto *ExternalSource = getASTContext().getExternalSource();369 if (!ExternalSource)370 return false;371 372 // If TPL is not null, it implies that we're loading specializations for373 // partial templates. We need to load all specializations in such cases.374 if (TPL)375 return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),376 /*OnlyPartial=*/false);377 378 return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),379 Args);380}381 382template <class EntryType, typename... ProfileArguments>383typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *384RedeclarableTemplateDecl::findSpecializationLocally(385 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,386 ProfileArguments... ProfileArgs) {387 using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;388 389 llvm::FoldingSetNodeID ID;390 EntryType::Profile(ID, ProfileArgs..., getASTContext());391 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);392 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;393}394 395template <class EntryType, typename... ProfileArguments>396typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *397RedeclarableTemplateDecl::findSpecializationImpl(398 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,399 ProfileArguments... ProfileArgs) {400 401 if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...))402 return Found;403 404 if (!loadLazySpecializationsImpl(ProfileArgs...))405 return nullptr;406 407 return findSpecializationLocally(Specs, InsertPos, ProfileArgs...);408}409 410template<class Derived, class EntryType>411void RedeclarableTemplateDecl::addSpecializationImpl(412 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,413 void *InsertPos) {414 using SETraits = SpecEntryTraits<EntryType>;415 416 if (InsertPos) {417#ifndef NDEBUG418 auto Args = SETraits::getTemplateArgs(Entry);419 // Due to hash collisions, it can happen that we load another template420 // specialization with the same hash. This is fine, as long as the next421 // call to findSpecializationImpl does not find a matching Decl for the422 // template arguments.423 loadLazySpecializationsImpl(Args);424 void *CorrectInsertPos;425 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) &&426 InsertPos == CorrectInsertPos &&427 "given incorrect InsertPos for specialization");428#endif429 Specializations.InsertNode(Entry, InsertPos);430 } else {431 EntryType *Existing = Specializations.GetOrInsertNode(Entry);432 (void)Existing;433 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&434 "non-canonical specialization?");435 }436 437 if (ASTMutationListener *L = getASTMutationListener())438 L->AddedCXXTemplateSpecialization(cast<Derived>(this),439 SETraits::getDecl(Entry));440}441 442//===----------------------------------------------------------------------===//443// FunctionTemplateDecl Implementation444//===----------------------------------------------------------------------===//445 446FunctionTemplateDecl *447FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,448 DeclarationName Name,449 TemplateParameterList *Params, NamedDecl *Decl) {450 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));451 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);452 if (Invalid)453 TD->setInvalidDecl();454 return TD;455}456 457FunctionTemplateDecl *458FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {459 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),460 DeclarationName(), nullptr, nullptr);461}462 463RedeclarableTemplateDecl::CommonBase *464FunctionTemplateDecl::newCommon(ASTContext &C) const {465 auto *CommonPtr = new (C) Common;466 C.addDestruction(CommonPtr);467 return CommonPtr;468}469 470void FunctionTemplateDecl::LoadLazySpecializations() const {471 loadLazySpecializationsImpl();472}473 474llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &475FunctionTemplateDecl::getSpecializations() const {476 LoadLazySpecializations();477 return getCommonPtr()->Specializations;478}479 480FunctionDecl *481FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,482 void *&InsertPos) {483 auto *Common = getCommonPtr();484 return findSpecializationImpl(Common->Specializations, InsertPos, Args);485}486 487void FunctionTemplateDecl::addSpecialization(488 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {489 auto *Common = getCommonPtr();490 addSpecializationImpl<FunctionTemplateDecl>(Common->Specializations, Info,491 InsertPos);492}493 494void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {495 using Base = RedeclarableTemplateDecl;496 497 // If we haven't created a common pointer yet, then it can just be created498 // with the usual method.499 if (!Base::Common)500 return;501 502 Common *ThisCommon = static_cast<Common *>(Base::Common);503 Common *PrevCommon = nullptr;504 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;505 for (; Prev; Prev = Prev->getPreviousDecl()) {506 if (Prev->Base::Common) {507 PrevCommon = static_cast<Common *>(Prev->Base::Common);508 break;509 }510 PreviousDecls.push_back(Prev);511 }512 513 // If the previous redecl chain hasn't created a common pointer yet, then just514 // use this common pointer.515 if (!PrevCommon) {516 for (auto *D : PreviousDecls)517 D->Base::Common = ThisCommon;518 return;519 }520 521 // Ensure we don't leak any important state.522 assert(ThisCommon->Specializations.size() == 0 &&523 "Can't merge incompatible declarations!");524 525 Base::Common = PrevCommon;526}527 528//===----------------------------------------------------------------------===//529// ClassTemplateDecl Implementation530//===----------------------------------------------------------------------===//531 532ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,533 SourceLocation L,534 DeclarationName Name,535 TemplateParameterList *Params,536 NamedDecl *Decl) {537 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));538 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);539 if (Invalid)540 TD->setInvalidDecl();541 return TD;542}543 544ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,545 GlobalDeclID ID) {546 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),547 DeclarationName(), nullptr, nullptr);548}549 550void ClassTemplateDecl::LoadLazySpecializations(551 bool OnlyPartial /*=false*/) const {552 loadLazySpecializationsImpl(OnlyPartial);553}554 555llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &556ClassTemplateDecl::getSpecializations() const {557 LoadLazySpecializations();558 return getCommonPtr()->Specializations;559}560 561llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &562ClassTemplateDecl::getPartialSpecializations() const {563 LoadLazySpecializations(/*PartialOnly = */ true);564 return getCommonPtr()->PartialSpecializations;565}566 567RedeclarableTemplateDecl::CommonBase *568ClassTemplateDecl::newCommon(ASTContext &C) const {569 auto *CommonPtr = new (C) Common;570 C.addDestruction(CommonPtr);571 return CommonPtr;572}573 574ClassTemplateSpecializationDecl *575ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,576 void *&InsertPos) {577 auto *Common = getCommonPtr();578 return findSpecializationImpl(Common->Specializations, InsertPos, Args);579}580 581void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,582 void *InsertPos) {583 auto *Common = getCommonPtr();584 addSpecializationImpl<ClassTemplateDecl>(Common->Specializations, D,585 InsertPos);586}587 588ClassTemplatePartialSpecializationDecl *589ClassTemplateDecl::findPartialSpecialization(590 ArrayRef<TemplateArgument> Args,591 TemplateParameterList *TPL, void *&InsertPos) {592 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,593 TPL);594}595 596void ClassTemplatePartialSpecializationDecl::Profile(597 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,598 TemplateParameterList *TPL, const ASTContext &Context) {599 ID.AddInteger(TemplateArgs.size());600 for (const TemplateArgument &TemplateArg : TemplateArgs)601 TemplateArg.Profile(ID, Context);602 TPL->Profile(ID, Context);603}604 605void ClassTemplateDecl::AddPartialSpecialization(606 ClassTemplatePartialSpecializationDecl *D,607 void *InsertPos) {608 if (InsertPos)609 getPartialSpecializations().InsertNode(D, InsertPos);610 else {611 ClassTemplatePartialSpecializationDecl *Existing612 = getPartialSpecializations().GetOrInsertNode(D);613 (void)Existing;614 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");615 }616 617 if (ASTMutationListener *L = getASTMutationListener())618 L->AddedCXXTemplateSpecialization(this, D);619}620 621void ClassTemplateDecl::getPartialSpecializations(622 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {623 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs624 = getPartialSpecializations();625 PS.clear();626 PS.reserve(PartialSpecs.size());627 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)628 PS.push_back(P.getMostRecentDecl());629}630 631ClassTemplatePartialSpecializationDecl *632ClassTemplateDecl::findPartialSpecialization(QualType T) {633 ASTContext &Context = getASTContext();634 for (ClassTemplatePartialSpecializationDecl &P :635 getPartialSpecializations()) {636 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),637 T))638 return P.getMostRecentDecl();639 }640 641 return nullptr;642}643 644ClassTemplatePartialSpecializationDecl *645ClassTemplateDecl::findPartialSpecInstantiatedFromMember(646 ClassTemplatePartialSpecializationDecl *D) {647 Decl *DCanon = D->getCanonicalDecl();648 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {649 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)650 return P.getMostRecentDecl();651 }652 653 return nullptr;654}655 656CanQualType ClassTemplateDecl::getCanonicalInjectedSpecializationType(657 const ASTContext &Ctx) const {658 Common *CommonPtr = getCommonPtr();659 660 if (CommonPtr->CanonInjectedTST.isNull()) {661 SmallVector<TemplateArgument> CanonicalArgs(662 getTemplateParameters()->getInjectedTemplateArgs(Ctx));663 Ctx.canonicalizeTemplateArguments(CanonicalArgs);664 CommonPtr->CanonInjectedTST =665 CanQualType::CreateUnsafe(Ctx.getCanonicalTemplateSpecializationType(666 ElaboratedTypeKeyword::None,667 TemplateName(const_cast<ClassTemplateDecl *>(getCanonicalDecl())),668 CanonicalArgs));669 }670 return CommonPtr->CanonInjectedTST;671}672 673//===----------------------------------------------------------------------===//674// TemplateTypeParm Allocation/Deallocation Method Implementations675//===----------------------------------------------------------------------===//676 677TemplateTypeParmDecl *TemplateTypeParmDecl::Create(678 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,679 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,680 bool Typename, bool ParameterPack, bool HasTypeConstraint,681 UnsignedOrNone NumExpanded) {682 auto *TTPDecl =683 new (C, DC,684 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))685 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,686 HasTypeConstraint, NumExpanded);687 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);688 TTPDecl->setTypeForDecl(TTPType.getTypePtr());689 return TTPDecl;690}691 692TemplateTypeParmDecl *693TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) {694 return new (C, ID)695 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,696 false, false, std::nullopt);697}698 699TemplateTypeParmDecl *700TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID,701 bool HasTypeConstraint) {702 return new (C, ID,703 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))704 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,705 false, HasTypeConstraint, std::nullopt);706}707 708SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {709 return hasDefaultArgument() ? getDefaultArgument().getLocation()710 : SourceLocation();711}712 713SourceRange TemplateTypeParmDecl::getSourceRange() const {714 if (hasDefaultArgument() && !defaultArgumentWasInherited())715 return SourceRange(getBeginLoc(),716 getDefaultArgument().getSourceRange().getEnd());717 // TypeDecl::getSourceRange returns a range containing name location, which is718 // wrong for unnamed template parameters. e.g:719 // it will return <[[typename>]] instead of <[[typename]]>720 if (getDeclName().isEmpty())721 return SourceRange(getBeginLoc());722 return TypeDecl::getSourceRange();723}724 725void TemplateTypeParmDecl::setDefaultArgument(726 const ASTContext &C, const TemplateArgumentLoc &DefArg) {727 if (DefArg.getArgument().isNull())728 DefaultArgument.set(nullptr);729 else730 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));731}732 733unsigned TemplateTypeParmDecl::getDepth() const {734 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();735}736 737unsigned TemplateTypeParmDecl::getIndex() const {738 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();739}740 741bool TemplateTypeParmDecl::isParameterPack() const {742 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();743}744 745void TemplateTypeParmDecl::setTypeConstraint(746 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,747 UnsignedOrNone ArgPackSubstIndex) {748 assert(HasTypeConstraint &&749 "HasTypeConstraint=true must be passed at construction in order to "750 "call setTypeConstraint");751 assert(!TypeConstraintInitialized &&752 "TypeConstraint was already initialized!");753 new (getTrailingObjects())754 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);755 TypeConstraintInitialized = true;756}757 758//===----------------------------------------------------------------------===//759// NonTypeTemplateParmDecl Method Implementations760//===----------------------------------------------------------------------===//761 762NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(763 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,764 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,765 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)766 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),767 TemplateParmPosition(D, P), ParameterPack(true),768 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {769 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {770 auto TypesAndInfos =771 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();772 for (unsigned I = 0; I != NumExpandedTypes; ++I) {773 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);774 TypesAndInfos[I].second = ExpandedTInfos[I];775 }776 }777}778 779NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(780 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,781 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,782 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {783 AutoType *AT =784 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;785 const bool HasConstraint = AT && AT->isConstrained();786 auto *NTTP =787 new (C, DC,788 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(789 0, HasConstraint ? 1 : 0))790 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,791 ParameterPack, TInfo);792 if (HasConstraint)793 NTTP->setPlaceholderTypeConstraint(nullptr);794 return NTTP;795}796 797NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(798 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,799 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,800 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,801 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {802 AutoType *AT = TInfo->getType()->getContainedAutoType();803 const bool HasConstraint = AT && AT->isConstrained();804 auto *NTTP =805 new (C, DC,806 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(807 ExpandedTypes.size(), HasConstraint ? 1 : 0))808 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,809 ExpandedTypes, ExpandedTInfos);810 if (HasConstraint)811 NTTP->setPlaceholderTypeConstraint(nullptr);812 return NTTP;813}814 815NonTypeTemplateParmDecl *816NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,817 bool HasTypeConstraint) {818 auto *NTTP =819 new (C, ID,820 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(821 0, HasTypeConstraint ? 1 : 0))822 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),823 0, 0, nullptr, QualType(), false, nullptr);824 if (HasTypeConstraint)825 NTTP->setPlaceholderTypeConstraint(nullptr);826 return NTTP;827}828 829NonTypeTemplateParmDecl *830NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,831 unsigned NumExpandedTypes,832 bool HasTypeConstraint) {833 auto *NTTP =834 new (C, ID,835 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(836 NumExpandedTypes, HasTypeConstraint ? 1 : 0))837 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),838 0, 0, nullptr, QualType(), nullptr, {}, {});839 NTTP->NumExpandedTypes = NumExpandedTypes;840 if (HasTypeConstraint)841 NTTP->setPlaceholderTypeConstraint(nullptr);842 return NTTP;843}844 845SourceRange NonTypeTemplateParmDecl::getSourceRange() const {846 if (hasDefaultArgument() && !defaultArgumentWasInherited())847 return SourceRange(getOuterLocStart(),848 getDefaultArgument().getSourceRange().getEnd());849 return DeclaratorDecl::getSourceRange();850}851 852SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {853 return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin()854 : SourceLocation();855}856 857void NonTypeTemplateParmDecl::setDefaultArgument(858 const ASTContext &C, const TemplateArgumentLoc &DefArg) {859 if (DefArg.getArgument().isNull())860 DefaultArgument.set(nullptr);861 else862 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));863}864 865//===----------------------------------------------------------------------===//866// TemplateTemplateParmDecl Method Implementations867//===----------------------------------------------------------------------===//868 869void TemplateTemplateParmDecl::anchor() {}870 871TemplateTemplateParmDecl::TemplateTemplateParmDecl(872 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,873 IdentifierInfo *Id, TemplateNameKind Kind, bool Typename,874 TemplateParameterList *Params, ArrayRef<TemplateParameterList *> Expansions)875 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),876 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),877 ParameterPack(true), ExpandedParameterPack(true),878 NumExpandedParams(Expansions.size()) {879 llvm::uninitialized_copy(Expansions, getTrailingObjects());880}881 882TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(883 const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,884 unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,885 bool Typename, TemplateParameterList *Params) {886 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,887 Kind, Typename, Params);888}889 890TemplateTemplateParmDecl *891TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,892 SourceLocation L, unsigned D, unsigned P,893 IdentifierInfo *Id, TemplateNameKind Kind,894 bool Typename, TemplateParameterList *Params,895 ArrayRef<TemplateParameterList *> Expansions) {896 return new (C, DC,897 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))898 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,899 Expansions);900}901 902TemplateTemplateParmDecl *903TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {904 return new (C, ID) TemplateTemplateParmDecl(905 nullptr, SourceLocation(), 0, 0, false, nullptr,906 TemplateNameKind::TNK_Type_template, false, nullptr);907}908 909TemplateTemplateParmDecl *910TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,911 unsigned NumExpansions) {912 auto *TTP =913 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))914 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,915 TemplateNameKind::TNK_Type_template, false,916 nullptr, {});917 TTP->NumExpandedParams = NumExpansions;918 return TTP;919}920 921SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {922 return hasDefaultArgument() ? getDefaultArgument().getLocation()923 : SourceLocation();924}925 926void TemplateTemplateParmDecl::setDefaultArgument(927 const ASTContext &C, const TemplateArgumentLoc &DefArg) {928 if (DefArg.getArgument().isNull())929 DefaultArgument.set(nullptr);930 else931 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));932}933 934//===----------------------------------------------------------------------===//935// TemplateArgumentList Implementation936//===----------------------------------------------------------------------===//937TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)938 : NumArguments(Args.size()) {939 llvm::uninitialized_copy(Args, getTrailingObjects());940}941 942TemplateArgumentList *943TemplateArgumentList::CreateCopy(ASTContext &Context,944 ArrayRef<TemplateArgument> Args) {945 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));946 return new (Mem) TemplateArgumentList(Args);947}948 949FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(950 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,951 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,952 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,953 MemberSpecializationInfo *MSInfo) {954 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;955 if (TemplateArgsAsWritten)956 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,957 *TemplateArgsAsWritten);958 959 void *Mem =960 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));961 return new (Mem) FunctionTemplateSpecializationInfo(962 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);963}964 965//===----------------------------------------------------------------------===//966// ClassTemplateSpecializationDecl Implementation967//===----------------------------------------------------------------------===//968 969ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(970 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,971 SourceLocation StartLoc, SourceLocation IdLoc,972 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,973 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)974 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,975 SpecializedTemplate->getIdentifier(), PrevDecl),976 SpecializedTemplate(SpecializedTemplate),977 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),978 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {979 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);980}981 982ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,983 Kind DK)984 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),985 SourceLocation(), nullptr, nullptr),986 SpecializationKind(TSK_Undeclared) {}987 988ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create(989 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,990 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,991 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,992 ClassTemplateSpecializationDecl *PrevDecl) {993 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(994 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,995 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);996 997 // If the template decl is incomplete, copy the external lexical storage from998 // the base template. This allows instantiations of incomplete types to999 // complete using the external AST if the template's declaration came from an1000 // external AST.1001 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())1002 Result->setHasExternalLexicalStorage(1003 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());1004 1005 return Result;1006}1007 1008ClassTemplateSpecializationDecl *1009ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,1010 GlobalDeclID ID) {1011 return new (C, ID)1012 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);1013}1014 1015void ClassTemplateSpecializationDecl::getNameForDiagnostic(1016 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {1017 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);1018 1019 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);1020 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =1021 PS ? PS->getTemplateArgsAsWritten() : nullptr) {1022 printTemplateArgumentList(1023 OS, ArgsAsWritten->arguments(), Policy,1024 getSpecializedTemplate()->getTemplateParameters());1025 } else {1026 const TemplateArgumentList &TemplateArgs = getTemplateArgs();1027 printTemplateArgumentList(1028 OS, TemplateArgs.asArray(), Policy,1029 getSpecializedTemplate()->getTemplateParameters());1030 }1031}1032 1033ClassTemplateDecl *1034ClassTemplateSpecializationDecl::getSpecializedTemplate() const {1035 if (const auto *PartialSpec =1036 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())1037 return PartialSpec->PartialSpecialization->getSpecializedTemplate();1038 return cast<ClassTemplateDecl *>(SpecializedTemplate);1039}1040 1041SourceRange1042ClassTemplateSpecializationDecl::getSourceRange() const {1043 switch (getSpecializationKind()) {1044 case TSK_Undeclared:1045 case TSK_ImplicitInstantiation: {1046 llvm::PointerUnion<ClassTemplateDecl *,1047 ClassTemplatePartialSpecializationDecl *>1048 Pattern = getSpecializedTemplateOrPartial();1049 assert(!Pattern.isNull() &&1050 "Class template specialization without pattern?");1051 if (const auto *CTPSD =1052 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))1053 return CTPSD->getSourceRange();1054 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();1055 }1056 case TSK_ExplicitSpecialization: {1057 SourceRange Range = CXXRecordDecl::getSourceRange();1058 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();1059 !isThisDeclarationADefinition() && Args)1060 Range.setEnd(Args->getRAngleLoc());1061 return Range;1062 }1063 case TSK_ExplicitInstantiationDeclaration:1064 case TSK_ExplicitInstantiationDefinition: {1065 SourceRange Range = CXXRecordDecl::getSourceRange();1066 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())1067 Range.setBegin(ExternKW);1068 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();1069 TemplateKW.isValid())1070 Range.setBegin(TemplateKW);1071 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())1072 Range.setEnd(Args->getRAngleLoc());1073 return Range;1074 }1075 }1076 llvm_unreachable("unhandled template specialization kind");1077}1078 1079void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {1080 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);1081 if (!Info) {1082 // Don't allocate if the location is invalid.1083 if (Loc.isInvalid())1084 return;1085 Info = new (getASTContext()) ExplicitInstantiationInfo;1086 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1087 ExplicitInfo = Info;1088 }1089 Info->ExternKeywordLoc = Loc;1090}1091 1092void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(1093 SourceLocation Loc) {1094 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);1095 if (!Info) {1096 // Don't allocate if the location is invalid.1097 if (Loc.isInvalid())1098 return;1099 Info = new (getASTContext()) ExplicitInstantiationInfo;1100 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1101 ExplicitInfo = Info;1102 }1103 Info->TemplateKeywordLoc = Loc;1104}1105 1106//===----------------------------------------------------------------------===//1107// ConceptDecl Implementation1108//===----------------------------------------------------------------------===//1109ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,1110 SourceLocation L, DeclarationName Name,1111 TemplateParameterList *Params,1112 Expr *ConstraintExpr) {1113 bool Invalid = AdoptTemplateParameterList(Params, DC);1114 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);1115 if (Invalid)1116 TD->setInvalidDecl();1117 return TD;1118}1119 1120ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1121 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),1122 DeclarationName(),1123 nullptr, nullptr);1124 1125 return Result;1126}1127 1128//===----------------------------------------------------------------------===//1129// ImplicitConceptSpecializationDecl Implementation1130//===----------------------------------------------------------------------===//1131ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(1132 DeclContext *DC, SourceLocation SL,1133 ArrayRef<TemplateArgument> ConvertedArgs)1134 : Decl(ImplicitConceptSpecialization, DC, SL),1135 NumTemplateArgs(ConvertedArgs.size()) {1136 setTemplateArguments(ConvertedArgs);1137}1138 1139ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(1140 EmptyShell Empty, unsigned NumTemplateArgs)1141 : Decl(ImplicitConceptSpecialization, Empty),1142 NumTemplateArgs(NumTemplateArgs) {}1143 1144ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(1145 const ASTContext &C, DeclContext *DC, SourceLocation SL,1146 ArrayRef<TemplateArgument> ConvertedArgs) {1147 return new (C, DC,1148 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))1149 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);1150}1151 1152ImplicitConceptSpecializationDecl *1153ImplicitConceptSpecializationDecl::CreateDeserialized(1154 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {1155 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))1156 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);1157}1158 1159void ImplicitConceptSpecializationDecl::setTemplateArguments(1160 ArrayRef<TemplateArgument> Converted) {1161 assert(Converted.size() == NumTemplateArgs);1162 llvm::uninitialized_copy(Converted, getTrailingObjects());1163}1164 1165//===----------------------------------------------------------------------===//1166// ClassTemplatePartialSpecializationDecl Implementation1167//===----------------------------------------------------------------------===//1168void ClassTemplatePartialSpecializationDecl::anchor() {}1169 1170ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(1171 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,1172 SourceLocation IdLoc, TemplateParameterList *Params,1173 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,1174 CanQualType CanonInjectedTST,1175 ClassTemplatePartialSpecializationDecl *PrevDecl)1176 : ClassTemplateSpecializationDecl(1177 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,1178 // Tracking StrictPackMatch for Partial1179 // Specializations is not needed.1180 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),1181 TemplateParams(Params), InstantiatedFromMember(nullptr, false),1182 CanonInjectedTST(CanonInjectedTST) {1183 if (AdoptTemplateParameterList(Params, this))1184 setInvalidDecl();1185}1186 1187ClassTemplatePartialSpecializationDecl *1188ClassTemplatePartialSpecializationDecl::Create(1189 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,1190 SourceLocation IdLoc, TemplateParameterList *Params,1191 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,1192 CanQualType CanonInjectedTST,1193 ClassTemplatePartialSpecializationDecl *PrevDecl) {1194 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(1195 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,1196 CanonInjectedTST, PrevDecl);1197 Result->setSpecializationKind(TSK_ExplicitSpecialization);1198 return Result;1199}1200 1201ClassTemplatePartialSpecializationDecl *1202ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,1203 GlobalDeclID ID) {1204 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);1205}1206 1207CanQualType1208ClassTemplatePartialSpecializationDecl::getCanonicalInjectedSpecializationType(1209 const ASTContext &Ctx) const {1210 if (CanonInjectedTST.isNull()) {1211 CanonInjectedTST =1212 CanQualType::CreateUnsafe(Ctx.getCanonicalTemplateSpecializationType(1213 ElaboratedTypeKeyword::None,1214 TemplateName(getSpecializedTemplate()->getCanonicalDecl()),1215 getTemplateArgs().asArray()));1216 }1217 return CanonInjectedTST;1218}1219 1220SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {1221 if (const ClassTemplatePartialSpecializationDecl *MT =1222 getInstantiatedFromMember();1223 MT && !isMemberSpecialization())1224 return MT->getSourceRange();1225 SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();1226 if (const TemplateParameterList *TPL = getTemplateParameters();1227 TPL && !getNumTemplateParameterLists())1228 Range.setBegin(TPL->getTemplateLoc());1229 return Range;1230}1231 1232//===----------------------------------------------------------------------===//1233// FriendTemplateDecl Implementation1234//===----------------------------------------------------------------------===//1235 1236void FriendTemplateDecl::anchor() {}1237 1238FriendTemplateDecl *1239FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,1240 SourceLocation L,1241 MutableArrayRef<TemplateParameterList *> Params,1242 FriendUnion Friend, SourceLocation FLoc) {1243 TemplateParameterList **TPL = nullptr;1244 if (!Params.empty()) {1245 TPL = new (Context) TemplateParameterList *[Params.size()];1246 llvm::copy(Params, TPL);1247 }1248 return new (Context, DC)1249 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);1250}1251 1252FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,1253 GlobalDeclID ID) {1254 return new (C, ID) FriendTemplateDecl(EmptyShell());1255}1256 1257//===----------------------------------------------------------------------===//1258// TypeAliasTemplateDecl Implementation1259//===----------------------------------------------------------------------===//1260 1261TypeAliasTemplateDecl *1262TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,1263 DeclarationName Name,1264 TemplateParameterList *Params, NamedDecl *Decl) {1265 bool Invalid = AdoptTemplateParameterList(Params, DC);1266 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);1267 if (Invalid)1268 TD->setInvalidDecl();1269 return TD;1270}1271 1272TypeAliasTemplateDecl *1273TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1274 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),1275 DeclarationName(), nullptr, nullptr);1276}1277 1278RedeclarableTemplateDecl::CommonBase *1279TypeAliasTemplateDecl::newCommon(ASTContext &C) const {1280 auto *CommonPtr = new (C) Common;1281 C.addDestruction(CommonPtr);1282 return CommonPtr;1283}1284 1285//===----------------------------------------------------------------------===//1286// VarTemplateDecl Implementation1287//===----------------------------------------------------------------------===//1288 1289VarTemplateDecl *VarTemplateDecl::getDefinition() {1290 VarTemplateDecl *CurD = this;1291 while (CurD) {1292 if (CurD->isThisDeclarationADefinition())1293 return CurD;1294 CurD = CurD->getPreviousDecl();1295 }1296 return nullptr;1297}1298 1299VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,1300 SourceLocation L, DeclarationName Name,1301 TemplateParameterList *Params,1302 VarDecl *Decl) {1303 bool Invalid = AdoptTemplateParameterList(Params, DC);1304 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);1305 if (Invalid)1306 TD->setInvalidDecl();1307 return TD;1308}1309 1310VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,1311 GlobalDeclID ID) {1312 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),1313 DeclarationName(), nullptr, nullptr);1314}1315 1316void VarTemplateDecl::LoadLazySpecializations(1317 bool OnlyPartial /*=false*/) const {1318 loadLazySpecializationsImpl(OnlyPartial);1319}1320 1321llvm::FoldingSetVector<VarTemplateSpecializationDecl> &1322VarTemplateDecl::getSpecializations() const {1323 LoadLazySpecializations();1324 return getCommonPtr()->Specializations;1325}1326 1327llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &1328VarTemplateDecl::getPartialSpecializations() const {1329 LoadLazySpecializations(/*PartialOnly = */ true);1330 return getCommonPtr()->PartialSpecializations;1331}1332 1333RedeclarableTemplateDecl::CommonBase *1334VarTemplateDecl::newCommon(ASTContext &C) const {1335 auto *CommonPtr = new (C) Common;1336 C.addDestruction(CommonPtr);1337 return CommonPtr;1338}1339 1340VarTemplateSpecializationDecl *1341VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,1342 void *&InsertPos) {1343 auto *Common = getCommonPtr();1344 return findSpecializationImpl(Common->Specializations, InsertPos, Args);1345}1346 1347void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,1348 void *InsertPos) {1349 auto *Common = getCommonPtr();1350 addSpecializationImpl<VarTemplateDecl>(Common->Specializations, D, InsertPos);1351}1352 1353VarTemplatePartialSpecializationDecl *1354VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,1355 TemplateParameterList *TPL, void *&InsertPos) {1356 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,1357 TPL);1358}1359 1360void VarTemplatePartialSpecializationDecl::Profile(1361 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,1362 TemplateParameterList *TPL, const ASTContext &Context) {1363 ID.AddInteger(TemplateArgs.size());1364 for (const TemplateArgument &TemplateArg : TemplateArgs)1365 TemplateArg.Profile(ID, Context);1366 TPL->Profile(ID, Context);1367}1368 1369void VarTemplateDecl::AddPartialSpecialization(1370 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {1371 if (InsertPos)1372 getPartialSpecializations().InsertNode(D, InsertPos);1373 else {1374 VarTemplatePartialSpecializationDecl *Existing =1375 getPartialSpecializations().GetOrInsertNode(D);1376 (void)Existing;1377 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");1378 }1379 1380 if (ASTMutationListener *L = getASTMutationListener())1381 L->AddedCXXTemplateSpecialization(this, D);1382}1383 1384void VarTemplateDecl::getPartialSpecializations(1385 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {1386 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =1387 getPartialSpecializations();1388 PS.clear();1389 PS.reserve(PartialSpecs.size());1390 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)1391 PS.push_back(P.getMostRecentDecl());1392}1393 1394VarTemplatePartialSpecializationDecl *1395VarTemplateDecl::findPartialSpecInstantiatedFromMember(1396 VarTemplatePartialSpecializationDecl *D) {1397 Decl *DCanon = D->getCanonicalDecl();1398 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {1399 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)1400 return P.getMostRecentDecl();1401 }1402 1403 return nullptr;1404}1405 1406//===----------------------------------------------------------------------===//1407// VarTemplateSpecializationDecl Implementation1408//===----------------------------------------------------------------------===//1409 1410VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(1411 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1412 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,1413 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)1414 : VarDecl(DK, Context, DC, StartLoc, IdLoc,1415 SpecializedTemplate->getIdentifier(), T, TInfo, S),1416 SpecializedTemplate(SpecializedTemplate),1417 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),1418 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}1419 1420VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,1421 ASTContext &C)1422 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,1423 QualType(), nullptr, SC_None),1424 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}1425 1426VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(1427 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1428 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,1429 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {1430 return new (Context, DC) VarTemplateSpecializationDecl(1431 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,1432 SpecializedTemplate, T, TInfo, S, Args);1433}1434 1435VarTemplateSpecializationDecl *1436VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,1437 GlobalDeclID ID) {1438 return new (C, ID)1439 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);1440}1441 1442void VarTemplateSpecializationDecl::getNameForDiagnostic(1443 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {1444 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);1445 1446 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);1447 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =1448 PS ? PS->getTemplateArgsAsWritten() : nullptr) {1449 printTemplateArgumentList(1450 OS, ArgsAsWritten->arguments(), Policy,1451 getSpecializedTemplate()->getTemplateParameters());1452 } else {1453 const TemplateArgumentList &TemplateArgs = getTemplateArgs();1454 printTemplateArgumentList(1455 OS, TemplateArgs.asArray(), Policy,1456 getSpecializedTemplate()->getTemplateParameters());1457 }1458}1459 1460VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {1461 if (const auto *PartialSpec =1462 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())1463 return PartialSpec->PartialSpecialization->getSpecializedTemplate();1464 return cast<VarTemplateDecl *>(SpecializedTemplate);1465}1466 1467SourceRange VarTemplateSpecializationDecl::getSourceRange() const {1468 switch (getSpecializationKind()) {1469 case TSK_Undeclared:1470 case TSK_ImplicitInstantiation: {1471 llvm::PointerUnion<VarTemplateDecl *,1472 VarTemplatePartialSpecializationDecl *>1473 Pattern = getSpecializedTemplateOrPartial();1474 assert(!Pattern.isNull() &&1475 "Variable template specialization without pattern?");1476 if (const auto *VTPSD =1477 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))1478 return VTPSD->getSourceRange();1479 VarTemplateDecl *VTD = cast<VarTemplateDecl *>(Pattern);1480 if (hasInit()) {1481 if (VarTemplateDecl *Definition = VTD->getDefinition())1482 return Definition->getSourceRange();1483 }1484 return VTD->getCanonicalDecl()->getSourceRange();1485 }1486 case TSK_ExplicitSpecialization: {1487 SourceRange Range = VarDecl::getSourceRange();1488 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();1489 !hasInit() && Args)1490 Range.setEnd(Args->getRAngleLoc());1491 return Range;1492 }1493 case TSK_ExplicitInstantiationDeclaration:1494 case TSK_ExplicitInstantiationDefinition: {1495 SourceRange Range = VarDecl::getSourceRange();1496 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())1497 Range.setBegin(ExternKW);1498 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();1499 TemplateKW.isValid())1500 Range.setBegin(TemplateKW);1501 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())1502 Range.setEnd(Args->getRAngleLoc());1503 return Range;1504 }1505 }1506 llvm_unreachable("unhandled template specialization kind");1507}1508 1509void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {1510 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);1511 if (!Info) {1512 // Don't allocate if the location is invalid.1513 if (Loc.isInvalid())1514 return;1515 Info = new (getASTContext()) ExplicitInstantiationInfo;1516 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1517 ExplicitInfo = Info;1518 }1519 Info->ExternKeywordLoc = Loc;1520}1521 1522void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {1523 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);1524 if (!Info) {1525 // Don't allocate if the location is invalid.1526 if (Loc.isInvalid())1527 return;1528 Info = new (getASTContext()) ExplicitInstantiationInfo;1529 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1530 ExplicitInfo = Info;1531 }1532 Info->TemplateKeywordLoc = Loc;1533}1534 1535//===----------------------------------------------------------------------===//1536// VarTemplatePartialSpecializationDecl Implementation1537//===----------------------------------------------------------------------===//1538 1539void VarTemplatePartialSpecializationDecl::anchor() {}1540 1541VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(1542 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1543 SourceLocation IdLoc, TemplateParameterList *Params,1544 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,1545 StorageClass S, ArrayRef<TemplateArgument> Args)1546 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,1547 DC, StartLoc, IdLoc, SpecializedTemplate, T,1548 TInfo, S, Args),1549 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {1550 if (AdoptTemplateParameterList(Params, DC))1551 setInvalidDecl();1552}1553 1554VarTemplatePartialSpecializationDecl *1555VarTemplatePartialSpecializationDecl::Create(1556 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1557 SourceLocation IdLoc, TemplateParameterList *Params,1558 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,1559 StorageClass S, ArrayRef<TemplateArgument> Args) {1560 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(1561 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,1562 Args);1563 Result->setSpecializationKind(TSK_ExplicitSpecialization);1564 return Result;1565}1566 1567VarTemplatePartialSpecializationDecl *1568VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,1569 GlobalDeclID ID) {1570 return new (C, ID) VarTemplatePartialSpecializationDecl(C);1571}1572 1573SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {1574 if (const VarTemplatePartialSpecializationDecl *MT =1575 getInstantiatedFromMember();1576 MT && !isMemberSpecialization())1577 return MT->getSourceRange();1578 SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();1579 if (const TemplateParameterList *TPL = getTemplateParameters();1580 TPL && !getNumTemplateParameterLists())1581 Range.setBegin(TPL->getTemplateLoc());1582 return Range;1583}1584 1585static TemplateParameterList *createBuiltinTemplateParameterList(1586 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {1587 switch (BTK) {1588#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST1589#include "clang/Basic/BuiltinTemplates.inc"1590 }1591 1592 llvm_unreachable("unhandled BuiltinTemplateKind!");1593}1594 1595void BuiltinTemplateDecl::anchor() {}1596 1597BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,1598 DeclarationName Name,1599 BuiltinTemplateKind BTK)1600 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,1601 createBuiltinTemplateParameterList(C, DC, BTK)),1602 BTK(BTK) {}1603 1604bool BuiltinTemplateDecl::isPackProducingBuiltinTemplate() const {1605 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;1606}1607 1608bool clang::isPackProducingBuiltinTemplateName(TemplateName N) {1609 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(1610 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));1611 return T && T->isPackProducingBuiltinTemplate();1612}1613 1614TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,1615 QualType T,1616 const APValue &V) {1617 DeclContext *DC = C.getTranslationUnitDecl();1618 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);1619 C.addDestruction(&TPOD->Value);1620 return TPOD;1621}1622 1623TemplateParamObjectDecl *1624TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1625 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());1626 C.addDestruction(&TPOD->Value);1627 return TPOD;1628}1629 1630void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,1631 const PrintingPolicy &Policy) const {1632 OS << "<template param ";1633 printAsExpr(OS, Policy);1634 OS << ">";1635}1636 1637void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {1638 printAsExpr(OS, getASTContext().getPrintingPolicy());1639}1640 1641void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,1642 const PrintingPolicy &Policy) const {1643 getType().getUnqualifiedType().print(OS, Policy);1644 printAsInit(OS, Policy);1645}1646 1647void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {1648 printAsInit(OS, getASTContext().getPrintingPolicy());1649}1650 1651void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,1652 const PrintingPolicy &Policy) const {1653 getValue().printPretty(OS, Policy, getType(), &getASTContext());1654}1655 1656std::tuple<NamedDecl *, TemplateArgument>1657clang::getReplacedTemplateParameter(Decl *D, unsigned Index) {1658 switch (D->getKind()) {1659 case Decl::Kind::BuiltinTemplate:1660 case Decl::Kind::ClassTemplate:1661 case Decl::Kind::Concept:1662 case Decl::Kind::FunctionTemplate:1663 case Decl::Kind::TemplateTemplateParm:1664 case Decl::Kind::TypeAliasTemplate:1665 case Decl::Kind::VarTemplate:1666 return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index),1667 {}};1668 case Decl::Kind::ClassTemplateSpecialization: {1669 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);1670 auto P = CTSD->getSpecializedTemplateOrPartial();1671 TemplateParameterList *TPL;1672 if (const auto *CTPSD =1673 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {1674 TPL = CTPSD->getTemplateParameters();1675 // FIXME: Obtain Args deduced for the partial specialization.1676 return {TPL->getParam(Index), {}};1677 }1678 TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();1679 return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};1680 }1681 case Decl::Kind::VarTemplateSpecialization: {1682 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);1683 auto P = VTSD->getSpecializedTemplateOrPartial();1684 TemplateParameterList *TPL;1685 if (const auto *VTPSD =1686 dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {1687 TPL = VTPSD->getTemplateParameters();1688 // FIXME: Obtain Args deduced for the partial specialization.1689 return {TPL->getParam(Index), {}};1690 }1691 TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();1692 return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};1693 }1694 case Decl::Kind::ClassTemplatePartialSpecialization:1695 return {cast<ClassTemplatePartialSpecializationDecl>(D)1696 ->getTemplateParameters()1697 ->getParam(Index),1698 {}};1699 case Decl::Kind::VarTemplatePartialSpecialization:1700 return {cast<VarTemplatePartialSpecializationDecl>(D)1701 ->getTemplateParameters()1702 ->getParam(Index),1703 {}};1704 // This is used as the AssociatedDecl for placeholder type deduction.1705 case Decl::TemplateTypeParm:1706 return {cast<NamedDecl>(D), {}};1707 // FIXME: Always use the template decl as the AssociatedDecl.1708 case Decl::Kind::CXXRecord:1709 return getReplacedTemplateParameter(1710 cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index);1711 case Decl::Kind::CXXDeductionGuide:1712 case Decl::Kind::CXXConversion:1713 case Decl::Kind::CXXConstructor:1714 case Decl::Kind::CXXDestructor:1715 case Decl::Kind::CXXMethod:1716 case Decl::Kind::Function:1717 return getReplacedTemplateParameter(1718 cast<FunctionDecl>(D)->getTemplateSpecializationInfo()->getTemplate(),1719 Index);1720 default:1721 llvm_unreachable("Unhandled templated declaration kind");1722 }1723}1724 1725const Decl &clang::adjustDeclToTemplate(const Decl &D) {1726 if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {1727 // Is this function declaration part of a function template?1728 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())1729 return *FTD;1730 1731 // Nothing to do if function is not an implicit instantiation.1732 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)1733 return D;1734 1735 // Function is an implicit instantiation of a function template?1736 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())1737 return *FTD;1738 1739 // Function is instantiated from a member definition of a class template?1740 if (const FunctionDecl *MemberDecl =1741 FD->getInstantiatedFromMemberFunction())1742 return *MemberDecl;1743 1744 return D;1745 }1746 if (const auto *VD = dyn_cast<VarDecl>(&D)) {1747 // Static data member is instantiated from a member definition of a class1748 // template?1749 if (VD->isStaticDataMember())1750 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())1751 return *MemberDecl;1752 1753 return D;1754 }1755 if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {1756 // Is this class declaration part of a class template?1757 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())1758 return *CTD;1759 1760 // Class is an implicit instantiation of a class template or partial1761 // specialization?1762 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {1763 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)1764 return D;1765 llvm::PointerUnion<ClassTemplateDecl *,1766 ClassTemplatePartialSpecializationDecl *>1767 PU = CTSD->getSpecializedTemplateOrPartial();1768 return isa<ClassTemplateDecl *>(PU)1769 ? *static_cast<const Decl *>(cast<ClassTemplateDecl *>(PU))1770 : *static_cast<const Decl *>(1771 cast<ClassTemplatePartialSpecializationDecl *>(PU));1772 }1773 1774 // Class is instantiated from a member definition of a class template?1775 if (const MemberSpecializationInfo *Info =1776 CRD->getMemberSpecializationInfo())1777 return *Info->getInstantiatedFrom();1778 1779 return D;1780 }1781 if (const auto *ED = dyn_cast<EnumDecl>(&D)) {1782 // Enum is instantiated from a member definition of a class template?1783 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())1784 return *MemberDecl;1785 1786 return D;1787 }1788 // FIXME: Adjust alias templates?1789 return D;1790}1791