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