Path: blob/main/contrib/llvm-project/clang/lib/AST/DeclTemplate.cpp
35260 views
//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the C++ related Decl classes for templates.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/DeclTemplate.h"13#include "clang/AST/ASTContext.h"14#include "clang/AST/ASTMutationListener.h"15#include "clang/AST/DeclCXX.h"16#include "clang/AST/DeclarationName.h"17#include "clang/AST/Expr.h"18#include "clang/AST/ExternalASTSource.h"19#include "clang/AST/TemplateBase.h"20#include "clang/AST/TemplateName.h"21#include "clang/AST/Type.h"22#include "clang/AST/TypeLoc.h"23#include "clang/Basic/Builtins.h"24#include "clang/Basic/LLVM.h"25#include "clang/Basic/SourceLocation.h"26#include "llvm/ADT/ArrayRef.h"27#include "llvm/ADT/FoldingSet.h"28#include "llvm/ADT/PointerUnion.h"29#include "llvm/ADT/STLExtras.h"30#include "llvm/ADT/SmallVector.h"31#include "llvm/Support/Casting.h"32#include "llvm/Support/ErrorHandling.h"33#include <algorithm>34#include <cassert>35#include <cstdint>36#include <memory>37#include <optional>38#include <utility>3940using namespace clang;4142//===----------------------------------------------------------------------===//43// TemplateParameterList Implementation44//===----------------------------------------------------------------------===//454647TemplateParameterList::TemplateParameterList(const ASTContext& C,48SourceLocation TemplateLoc,49SourceLocation LAngleLoc,50ArrayRef<NamedDecl *> Params,51SourceLocation RAngleLoc,52Expr *RequiresClause)53: TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),54NumParams(Params.size()), ContainsUnexpandedParameterPack(false),55HasRequiresClause(RequiresClause != nullptr),56HasConstrainedParameters(false) {57for (unsigned Idx = 0; Idx < NumParams; ++Idx) {58NamedDecl *P = Params[Idx];59begin()[Idx] = P;6061bool IsPack = P->isTemplateParameterPack();62if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {63if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())64ContainsUnexpandedParameterPack = true;65if (NTTP->hasPlaceholderTypeConstraint())66HasConstrainedParameters = true;67} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {68if (!IsPack &&69TTP->getTemplateParameters()->containsUnexpandedParameterPack())70ContainsUnexpandedParameterPack = true;71} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {72if (const TypeConstraint *TC = TTP->getTypeConstraint()) {73if (TC->getImmediatelyDeclaredConstraint()74->containsUnexpandedParameterPack())75ContainsUnexpandedParameterPack = true;76}77if (TTP->hasTypeConstraint())78HasConstrainedParameters = true;79} else {80llvm_unreachable("unexpected template parameter type");81}82// FIXME: If a default argument contains an unexpanded parameter pack, the83// template parameter list does too.84}8586if (HasRequiresClause) {87if (RequiresClause->containsUnexpandedParameterPack())88ContainsUnexpandedParameterPack = true;89*getTrailingObjects<Expr *>() = RequiresClause;90}91}9293bool TemplateParameterList::containsUnexpandedParameterPack() const {94if (ContainsUnexpandedParameterPack)95return true;96if (!HasConstrainedParameters)97return false;9899// An implicit constrained parameter might have had a use of an unexpanded100// pack added to it after the template parameter list was created. All101// implicit parameters are at the end of the parameter list.102for (const NamedDecl *Param : llvm::reverse(asArray())) {103if (!Param->isImplicit())104break;105106if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {107const auto *TC = TTP->getTypeConstraint();108if (TC && TC->getImmediatelyDeclaredConstraint()109->containsUnexpandedParameterPack())110return true;111}112}113114return false;115}116117TemplateParameterList *118TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,119SourceLocation LAngleLoc,120ArrayRef<NamedDecl *> Params,121SourceLocation RAngleLoc, Expr *RequiresClause) {122void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(123Params.size(), RequiresClause ? 1u : 0u),124alignof(TemplateParameterList));125return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,126RAngleLoc, RequiresClause);127}128129void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,130const ASTContext &C) const {131const Expr *RC = getRequiresClause();132ID.AddBoolean(RC != nullptr);133if (RC)134RC->Profile(ID, C, /*Canonical=*/true);135ID.AddInteger(size());136for (NamedDecl *D : *this) {137if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {138ID.AddInteger(0);139ID.AddBoolean(NTTP->isParameterPack());140NTTP->getType().getCanonicalType().Profile(ID);141ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());142if (const Expr *E = NTTP->getPlaceholderTypeConstraint())143E->Profile(ID, C, /*Canonical=*/true);144continue;145}146if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {147ID.AddInteger(1);148ID.AddBoolean(TTP->isParameterPack());149ID.AddBoolean(TTP->hasTypeConstraint());150if (const TypeConstraint *TC = TTP->getTypeConstraint())151TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,152/*Canonical=*/true);153continue;154}155const auto *TTP = cast<TemplateTemplateParmDecl>(D);156ID.AddInteger(2);157ID.AddBoolean(TTP->isParameterPack());158TTP->getTemplateParameters()->Profile(ID, C);159}160}161162unsigned TemplateParameterList::getMinRequiredArguments() const {163unsigned NumRequiredArgs = 0;164for (const NamedDecl *P : asArray()) {165if (P->isTemplateParameterPack()) {166if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {167NumRequiredArgs += *Expansions;168continue;169}170break;171}172173if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {174if (TTP->hasDefaultArgument())175break;176} else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {177if (NTTP->hasDefaultArgument())178break;179} else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())180break;181182++NumRequiredArgs;183}184185return NumRequiredArgs;186}187188unsigned TemplateParameterList::getDepth() const {189if (size() == 0)190return 0;191192const NamedDecl *FirstParm = getParam(0);193if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))194return TTP->getDepth();195else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))196return NTTP->getDepth();197else198return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();199}200201static bool AdoptTemplateParameterList(TemplateParameterList *Params,202DeclContext *Owner) {203bool Invalid = false;204for (NamedDecl *P : *Params) {205P->setDeclContext(Owner);206207if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))208if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))209Invalid = true;210211if (P->isInvalidDecl())212Invalid = true;213}214return Invalid;215}216217void TemplateParameterList::218getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {219if (HasConstrainedParameters)220for (const NamedDecl *Param : *this) {221if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {222if (const auto *TC = TTP->getTypeConstraint())223AC.push_back(TC->getImmediatelyDeclaredConstraint());224} else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {225if (const Expr *E = NTTP->getPlaceholderTypeConstraint())226AC.push_back(E);227}228}229if (HasRequiresClause)230AC.push_back(getRequiresClause());231}232233bool TemplateParameterList::hasAssociatedConstraints() const {234return HasRequiresClause || HasConstrainedParameters;235}236237bool TemplateParameterList::shouldIncludeTypeForArgument(238const PrintingPolicy &Policy, const TemplateParameterList *TPL,239unsigned Idx) {240if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)241return true;242const NamedDecl *TemplParam = TPL->getParam(Idx);243if (const auto *ParamValueDecl =244dyn_cast<NonTypeTemplateParmDecl>(TemplParam))245if (ParamValueDecl->getType()->getContainedDeducedType())246return true;247return false;248}249250namespace clang {251252void *allocateDefaultArgStorageChain(const ASTContext &C) {253return new (C) char[sizeof(void*) * 2];254}255256} // namespace clang257258//===----------------------------------------------------------------------===//259// TemplateDecl Implementation260//===----------------------------------------------------------------------===//261262TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,263DeclarationName Name, TemplateParameterList *Params,264NamedDecl *Decl)265: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}266267void TemplateDecl::anchor() {}268269void TemplateDecl::270getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {271TemplateParams->getAssociatedConstraints(AC);272if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))273if (const Expr *TRC = FD->getTrailingRequiresClause())274AC.push_back(TRC);275}276277bool TemplateDecl::hasAssociatedConstraints() const {278if (TemplateParams->hasAssociatedConstraints())279return true;280if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))281return FD->getTrailingRequiresClause();282return false;283}284285bool TemplateDecl::isTypeAlias() const {286switch (getKind()) {287case TemplateDecl::TypeAliasTemplate:288case TemplateDecl::BuiltinTemplate:289return true;290default:291return false;292};293}294295//===----------------------------------------------------------------------===//296// RedeclarableTemplateDecl Implementation297//===----------------------------------------------------------------------===//298299void RedeclarableTemplateDecl::anchor() {}300301RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {302if (Common)303return Common;304305// Walk the previous-declaration chain until we either find a declaration306// with a common pointer or we run out of previous declarations.307SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;308for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;309Prev = Prev->getPreviousDecl()) {310if (Prev->Common) {311Common = Prev->Common;312break;313}314315PrevDecls.push_back(Prev);316}317318// If we never found a common pointer, allocate one now.319if (!Common) {320// FIXME: If any of the declarations is from an AST file, we probably321// need an update record to add the common data.322323Common = newCommon(getASTContext());324}325326// Update any previous declarations we saw with the common pointer.327for (const RedeclarableTemplateDecl *Prev : PrevDecls)328Prev->Common = Common;329330return Common;331}332333void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {334// Grab the most recent declaration to ensure we've loaded any lazy335// redeclarations of this template.336CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();337if (CommonBasePtr->LazySpecializations) {338ASTContext &Context = getASTContext();339GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;340CommonBasePtr->LazySpecializations = nullptr;341unsigned SpecSize = (*Specs++).getRawValue();342for (unsigned I = 0; I != SpecSize; ++I)343(void)Context.getExternalSource()->GetExternalDecl(Specs[I]);344}345}346347template<class EntryType, typename... ProfileArguments>348typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *349RedeclarableTemplateDecl::findSpecializationImpl(350llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,351ProfileArguments&&... ProfileArgs) {352using SETraits = SpecEntryTraits<EntryType>;353354llvm::FoldingSetNodeID ID;355EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,356getASTContext());357EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);358return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;359}360361template<class Derived, class EntryType>362void RedeclarableTemplateDecl::addSpecializationImpl(363llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,364void *InsertPos) {365using SETraits = SpecEntryTraits<EntryType>;366367if (InsertPos) {368#ifndef NDEBUG369void *CorrectInsertPos;370assert(!findSpecializationImpl(Specializations,371CorrectInsertPos,372SETraits::getTemplateArgs(Entry)) &&373InsertPos == CorrectInsertPos &&374"given incorrect InsertPos for specialization");375#endif376Specializations.InsertNode(Entry, InsertPos);377} else {378EntryType *Existing = Specializations.GetOrInsertNode(Entry);379(void)Existing;380assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&381"non-canonical specialization?");382}383384if (ASTMutationListener *L = getASTMutationListener())385L->AddedCXXTemplateSpecialization(cast<Derived>(this),386SETraits::getDecl(Entry));387}388389ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {390TemplateParameterList *Params = getTemplateParameters();391auto *CommonPtr = getCommonPtr();392if (!CommonPtr->InjectedArgs) {393auto &Context = getASTContext();394SmallVector<TemplateArgument, 16> TemplateArgs;395Context.getInjectedTemplateArgs(Params, TemplateArgs);396CommonPtr->InjectedArgs =397new (Context) TemplateArgument[TemplateArgs.size()];398std::copy(TemplateArgs.begin(), TemplateArgs.end(),399CommonPtr->InjectedArgs);400}401402return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());403}404405//===----------------------------------------------------------------------===//406// FunctionTemplateDecl Implementation407//===----------------------------------------------------------------------===//408409FunctionTemplateDecl *410FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,411DeclarationName Name,412TemplateParameterList *Params, NamedDecl *Decl) {413bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));414auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);415if (Invalid)416TD->setInvalidDecl();417return TD;418}419420FunctionTemplateDecl *421FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {422return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),423DeclarationName(), nullptr, nullptr);424}425426RedeclarableTemplateDecl::CommonBase *427FunctionTemplateDecl::newCommon(ASTContext &C) const {428auto *CommonPtr = new (C) Common;429C.addDestruction(CommonPtr);430return CommonPtr;431}432433void FunctionTemplateDecl::LoadLazySpecializations() const {434loadLazySpecializationsImpl();435}436437llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &438FunctionTemplateDecl::getSpecializations() const {439LoadLazySpecializations();440return getCommonPtr()->Specializations;441}442443FunctionDecl *444FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,445void *&InsertPos) {446return findSpecializationImpl(getSpecializations(), InsertPos, Args);447}448449void FunctionTemplateDecl::addSpecialization(450FunctionTemplateSpecializationInfo *Info, void *InsertPos) {451addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,452InsertPos);453}454455void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {456using Base = RedeclarableTemplateDecl;457458// If we haven't created a common pointer yet, then it can just be created459// with the usual method.460if (!Base::Common)461return;462463Common *ThisCommon = static_cast<Common *>(Base::Common);464Common *PrevCommon = nullptr;465SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;466for (; Prev; Prev = Prev->getPreviousDecl()) {467if (Prev->Base::Common) {468PrevCommon = static_cast<Common *>(Prev->Base::Common);469break;470}471PreviousDecls.push_back(Prev);472}473474// If the previous redecl chain hasn't created a common pointer yet, then just475// use this common pointer.476if (!PrevCommon) {477for (auto *D : PreviousDecls)478D->Base::Common = ThisCommon;479return;480}481482// Ensure we don't leak any important state.483assert(ThisCommon->Specializations.size() == 0 &&484"Can't merge incompatible declarations!");485486Base::Common = PrevCommon;487}488489//===----------------------------------------------------------------------===//490// ClassTemplateDecl Implementation491//===----------------------------------------------------------------------===//492493ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,494SourceLocation L,495DeclarationName Name,496TemplateParameterList *Params,497NamedDecl *Decl) {498bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));499auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);500if (Invalid)501TD->setInvalidDecl();502return TD;503}504505ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,506GlobalDeclID ID) {507return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),508DeclarationName(), nullptr, nullptr);509}510511void ClassTemplateDecl::LoadLazySpecializations() const {512loadLazySpecializationsImpl();513}514515llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &516ClassTemplateDecl::getSpecializations() const {517LoadLazySpecializations();518return getCommonPtr()->Specializations;519}520521llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &522ClassTemplateDecl::getPartialSpecializations() const {523LoadLazySpecializations();524return getCommonPtr()->PartialSpecializations;525}526527RedeclarableTemplateDecl::CommonBase *528ClassTemplateDecl::newCommon(ASTContext &C) const {529auto *CommonPtr = new (C) Common;530C.addDestruction(CommonPtr);531return CommonPtr;532}533534ClassTemplateSpecializationDecl *535ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,536void *&InsertPos) {537return findSpecializationImpl(getSpecializations(), InsertPos, Args);538}539540void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,541void *InsertPos) {542addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);543}544545ClassTemplatePartialSpecializationDecl *546ClassTemplateDecl::findPartialSpecialization(547ArrayRef<TemplateArgument> Args,548TemplateParameterList *TPL, void *&InsertPos) {549return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,550TPL);551}552553void ClassTemplatePartialSpecializationDecl::Profile(554llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,555TemplateParameterList *TPL, const ASTContext &Context) {556ID.AddInteger(TemplateArgs.size());557for (const TemplateArgument &TemplateArg : TemplateArgs)558TemplateArg.Profile(ID, Context);559TPL->Profile(ID, Context);560}561562void ClassTemplateDecl::AddPartialSpecialization(563ClassTemplatePartialSpecializationDecl *D,564void *InsertPos) {565if (InsertPos)566getPartialSpecializations().InsertNode(D, InsertPos);567else {568ClassTemplatePartialSpecializationDecl *Existing569= getPartialSpecializations().GetOrInsertNode(D);570(void)Existing;571assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");572}573574if (ASTMutationListener *L = getASTMutationListener())575L->AddedCXXTemplateSpecialization(this, D);576}577578void ClassTemplateDecl::getPartialSpecializations(579SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {580llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs581= getPartialSpecializations();582PS.clear();583PS.reserve(PartialSpecs.size());584for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)585PS.push_back(P.getMostRecentDecl());586}587588ClassTemplatePartialSpecializationDecl *589ClassTemplateDecl::findPartialSpecialization(QualType T) {590ASTContext &Context = getASTContext();591for (ClassTemplatePartialSpecializationDecl &P :592getPartialSpecializations()) {593if (Context.hasSameType(P.getInjectedSpecializationType(), T))594return P.getMostRecentDecl();595}596597return nullptr;598}599600ClassTemplatePartialSpecializationDecl *601ClassTemplateDecl::findPartialSpecInstantiatedFromMember(602ClassTemplatePartialSpecializationDecl *D) {603Decl *DCanon = D->getCanonicalDecl();604for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {605if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)606return P.getMostRecentDecl();607}608609return nullptr;610}611612QualType613ClassTemplateDecl::getInjectedClassNameSpecialization() {614Common *CommonPtr = getCommonPtr();615if (!CommonPtr->InjectedClassNameType.isNull())616return CommonPtr->InjectedClassNameType;617618// C++0x [temp.dep.type]p2:619// The template argument list of a primary template is a template argument620// list in which the nth template argument has the value of the nth template621// parameter of the class template. If the nth template parameter is a622// template parameter pack (14.5.3), the nth template argument is a pack623// expansion (14.5.3) whose pattern is the name of the template parameter624// pack.625ASTContext &Context = getASTContext();626TemplateParameterList *Params = getTemplateParameters();627SmallVector<TemplateArgument, 16> TemplateArgs;628Context.getInjectedTemplateArgs(Params, TemplateArgs);629TemplateName Name = Context.getQualifiedTemplateName(630/*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));631CommonPtr->InjectedClassNameType =632Context.getTemplateSpecializationType(Name, TemplateArgs);633return CommonPtr->InjectedClassNameType;634}635636//===----------------------------------------------------------------------===//637// TemplateTypeParm Allocation/Deallocation Method Implementations638//===----------------------------------------------------------------------===//639640TemplateTypeParmDecl *TemplateTypeParmDecl::Create(641const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,642SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,643bool Typename, bool ParameterPack, bool HasTypeConstraint,644std::optional<unsigned> NumExpanded) {645auto *TTPDecl =646new (C, DC,647additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))648TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,649HasTypeConstraint, NumExpanded);650QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);651TTPDecl->setTypeForDecl(TTPType.getTypePtr());652return TTPDecl;653}654655TemplateTypeParmDecl *656TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) {657return new (C, ID)658TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,659false, false, std::nullopt);660}661662TemplateTypeParmDecl *663TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID,664bool HasTypeConstraint) {665return new (C, ID,666additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))667TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,668false, HasTypeConstraint, std::nullopt);669}670671SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {672return hasDefaultArgument() ? getDefaultArgument().getLocation()673: SourceLocation();674}675676SourceRange TemplateTypeParmDecl::getSourceRange() const {677if (hasDefaultArgument() && !defaultArgumentWasInherited())678return SourceRange(getBeginLoc(),679getDefaultArgument().getSourceRange().getEnd());680// TypeDecl::getSourceRange returns a range containing name location, which is681// wrong for unnamed template parameters. e.g:682// it will return <[[typename>]] instead of <[[typename]]>683if (getDeclName().isEmpty())684return SourceRange(getBeginLoc());685return TypeDecl::getSourceRange();686}687688void TemplateTypeParmDecl::setDefaultArgument(689const ASTContext &C, const TemplateArgumentLoc &DefArg) {690if (DefArg.getArgument().isNull())691DefaultArgument.set(nullptr);692else693DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));694}695696unsigned TemplateTypeParmDecl::getDepth() const {697return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();698}699700unsigned TemplateTypeParmDecl::getIndex() const {701return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();702}703704bool TemplateTypeParmDecl::isParameterPack() const {705return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();706}707708void TemplateTypeParmDecl::setTypeConstraint(709ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {710assert(HasTypeConstraint &&711"HasTypeConstraint=true must be passed at construction in order to "712"call setTypeConstraint");713assert(!TypeConstraintInitialized &&714"TypeConstraint was already initialized!");715new (getTrailingObjects<TypeConstraint>())716TypeConstraint(Loc, ImmediatelyDeclaredConstraint);717TypeConstraintInitialized = true;718}719720//===----------------------------------------------------------------------===//721// NonTypeTemplateParmDecl Method Implementations722//===----------------------------------------------------------------------===//723724NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(725DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,726unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,727ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)728: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),729TemplateParmPosition(D, P), ParameterPack(true),730ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {731if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {732auto TypesAndInfos =733getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();734for (unsigned I = 0; I != NumExpandedTypes; ++I) {735new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);736TypesAndInfos[I].second = ExpandedTInfos[I];737}738}739}740741NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(742const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,743SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,744QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {745AutoType *AT =746C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;747return new (C, DC,748additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,749Expr *>(0,750AT && AT->isConstrained() ? 1 : 0))751NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,752TInfo);753}754755NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(756const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,757SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,758QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,759ArrayRef<TypeSourceInfo *> ExpandedTInfos) {760AutoType *AT = TInfo->getType()->getContainedAutoType();761return new (C, DC,762additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,763Expr *>(764ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))765NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,766ExpandedTypes, ExpandedTInfos);767}768769NonTypeTemplateParmDecl *770NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,771bool HasTypeConstraint) {772return new (C, ID, additionalSizeToAlloc<std::pair<QualType,773TypeSourceInfo *>,774Expr *>(0,775HasTypeConstraint ? 1 : 0))776NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),7770, 0, nullptr, QualType(), false, nullptr);778}779780NonTypeTemplateParmDecl *781NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,782unsigned NumExpandedTypes,783bool HasTypeConstraint) {784auto *NTTP =785new (C, ID,786additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(787NumExpandedTypes, HasTypeConstraint ? 1 : 0))788NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),7890, 0, nullptr, QualType(), nullptr,790std::nullopt, std::nullopt);791NTTP->NumExpandedTypes = NumExpandedTypes;792return NTTP;793}794795SourceRange NonTypeTemplateParmDecl::getSourceRange() const {796if (hasDefaultArgument() && !defaultArgumentWasInherited())797return SourceRange(getOuterLocStart(),798getDefaultArgument().getSourceRange().getEnd());799return DeclaratorDecl::getSourceRange();800}801802SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {803return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin()804: SourceLocation();805}806807void NonTypeTemplateParmDecl::setDefaultArgument(808const ASTContext &C, const TemplateArgumentLoc &DefArg) {809if (DefArg.getArgument().isNull())810DefaultArgument.set(nullptr);811else812DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));813}814815//===----------------------------------------------------------------------===//816// TemplateTemplateParmDecl Method Implementations817//===----------------------------------------------------------------------===//818819void TemplateTemplateParmDecl::anchor() {}820821TemplateTemplateParmDecl::TemplateTemplateParmDecl(822DeclContext *DC, SourceLocation L, unsigned D, unsigned P,823IdentifierInfo *Id, bool Typename, TemplateParameterList *Params,824ArrayRef<TemplateParameterList *> Expansions)825: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),826TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),827ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {828if (!Expansions.empty())829std::uninitialized_copy(Expansions.begin(), Expansions.end(),830getTrailingObjects<TemplateParameterList *>());831}832833TemplateTemplateParmDecl *834TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,835SourceLocation L, unsigned D, unsigned P,836bool ParameterPack, IdentifierInfo *Id,837bool Typename, TemplateParameterList *Params) {838return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,839Typename, Params);840}841842TemplateTemplateParmDecl *843TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,844SourceLocation L, unsigned D, unsigned P,845IdentifierInfo *Id, bool Typename,846TemplateParameterList *Params,847ArrayRef<TemplateParameterList *> Expansions) {848return new (C, DC,849additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))850TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);851}852853TemplateTemplateParmDecl *854TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {855return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,856false, nullptr, false, nullptr);857}858859TemplateTemplateParmDecl *860TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,861unsigned NumExpansions) {862auto *TTP =863new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))864TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,865false, nullptr, std::nullopt);866TTP->NumExpandedParams = NumExpansions;867return TTP;868}869870SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {871return hasDefaultArgument() ? getDefaultArgument().getLocation()872: SourceLocation();873}874875void TemplateTemplateParmDecl::setDefaultArgument(876const ASTContext &C, const TemplateArgumentLoc &DefArg) {877if (DefArg.getArgument().isNull())878DefaultArgument.set(nullptr);879else880DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));881}882883//===----------------------------------------------------------------------===//884// TemplateArgumentList Implementation885//===----------------------------------------------------------------------===//886TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)887: NumArguments(Args.size()) {888std::uninitialized_copy(Args.begin(), Args.end(),889getTrailingObjects<TemplateArgument>());890}891892TemplateArgumentList *893TemplateArgumentList::CreateCopy(ASTContext &Context,894ArrayRef<TemplateArgument> Args) {895void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));896return new (Mem) TemplateArgumentList(Args);897}898899FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(900ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,901TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,902const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,903MemberSpecializationInfo *MSInfo) {904const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;905if (TemplateArgsAsWritten)906ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,907*TemplateArgsAsWritten);908909void *Mem =910C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));911return new (Mem) FunctionTemplateSpecializationInfo(912FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);913}914915//===----------------------------------------------------------------------===//916// ClassTemplateSpecializationDecl Implementation917//===----------------------------------------------------------------------===//918919ClassTemplateSpecializationDecl::920ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,921DeclContext *DC, SourceLocation StartLoc,922SourceLocation IdLoc,923ClassTemplateDecl *SpecializedTemplate,924ArrayRef<TemplateArgument> Args,925ClassTemplateSpecializationDecl *PrevDecl)926: CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,927SpecializedTemplate->getIdentifier(), PrevDecl),928SpecializedTemplate(SpecializedTemplate),929TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),930SpecializationKind(TSK_Undeclared) {931}932933ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,934Kind DK)935: CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),936SourceLocation(), nullptr, nullptr),937SpecializationKind(TSK_Undeclared) {}938939ClassTemplateSpecializationDecl *940ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,941DeclContext *DC,942SourceLocation StartLoc,943SourceLocation IdLoc,944ClassTemplateDecl *SpecializedTemplate,945ArrayRef<TemplateArgument> Args,946ClassTemplateSpecializationDecl *PrevDecl) {947auto *Result =948new (Context, DC) ClassTemplateSpecializationDecl(949Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,950SpecializedTemplate, Args, PrevDecl);951Result->setMayHaveOutOfDateDef(false);952953// If the template decl is incomplete, copy the external lexical storage from954// the base template. This allows instantiations of incomplete types to955// complete using the external AST if the template's declaration came from an956// external AST.957if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())958Result->setHasExternalLexicalStorage(959SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());960961Context.getTypeDeclType(Result, PrevDecl);962return Result;963}964965ClassTemplateSpecializationDecl *966ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,967GlobalDeclID ID) {968auto *Result =969new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);970Result->setMayHaveOutOfDateDef(false);971return Result;972}973974void ClassTemplateSpecializationDecl::getNameForDiagnostic(975raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {976NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);977978const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);979if (const ASTTemplateArgumentListInfo *ArgsAsWritten =980PS ? PS->getTemplateArgsAsWritten() : nullptr) {981printTemplateArgumentList(982OS, ArgsAsWritten->arguments(), Policy,983getSpecializedTemplate()->getTemplateParameters());984} else {985const TemplateArgumentList &TemplateArgs = getTemplateArgs();986printTemplateArgumentList(987OS, TemplateArgs.asArray(), Policy,988getSpecializedTemplate()->getTemplateParameters());989}990}991992ClassTemplateDecl *993ClassTemplateSpecializationDecl::getSpecializedTemplate() const {994if (const auto *PartialSpec =995SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())996return PartialSpec->PartialSpecialization->getSpecializedTemplate();997return SpecializedTemplate.get<ClassTemplateDecl*>();998}9991000SourceRange1001ClassTemplateSpecializationDecl::getSourceRange() const {1002switch (getSpecializationKind()) {1003case TSK_Undeclared:1004case TSK_ImplicitInstantiation: {1005llvm::PointerUnion<ClassTemplateDecl *,1006ClassTemplatePartialSpecializationDecl *>1007Pattern = getSpecializedTemplateOrPartial();1008assert(!Pattern.isNull() &&1009"Class template specialization without pattern?");1010if (const auto *CTPSD =1011Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())1012return CTPSD->getSourceRange();1013return Pattern.get<ClassTemplateDecl *>()->getSourceRange();1014}1015case TSK_ExplicitSpecialization: {1016SourceRange Range = CXXRecordDecl::getSourceRange();1017if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();1018!isThisDeclarationADefinition() && Args)1019Range.setEnd(Args->getRAngleLoc());1020return Range;1021}1022case TSK_ExplicitInstantiationDeclaration:1023case TSK_ExplicitInstantiationDefinition: {1024SourceRange Range = CXXRecordDecl::getSourceRange();1025if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())1026Range.setBegin(ExternKW);1027else if (SourceLocation TemplateKW = getTemplateKeywordLoc();1028TemplateKW.isValid())1029Range.setBegin(TemplateKW);1030if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())1031Range.setEnd(Args->getRAngleLoc());1032return Range;1033}1034}1035llvm_unreachable("unhandled template specialization kind");1036}10371038void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {1039auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();1040if (!Info) {1041// Don't allocate if the location is invalid.1042if (Loc.isInvalid())1043return;1044Info = new (getASTContext()) ExplicitInstantiationInfo;1045Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1046ExplicitInfo = Info;1047}1048Info->ExternKeywordLoc = Loc;1049}10501051void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(1052SourceLocation Loc) {1053auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();1054if (!Info) {1055// Don't allocate if the location is invalid.1056if (Loc.isInvalid())1057return;1058Info = new (getASTContext()) ExplicitInstantiationInfo;1059Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1060ExplicitInfo = Info;1061}1062Info->TemplateKeywordLoc = Loc;1063}10641065//===----------------------------------------------------------------------===//1066// ConceptDecl Implementation1067//===----------------------------------------------------------------------===//1068ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,1069SourceLocation L, DeclarationName Name,1070TemplateParameterList *Params,1071Expr *ConstraintExpr) {1072bool Invalid = AdoptTemplateParameterList(Params, DC);1073auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);1074if (Invalid)1075TD->setInvalidDecl();1076return TD;1077}10781079ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1080ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),1081DeclarationName(),1082nullptr, nullptr);10831084return Result;1085}10861087//===----------------------------------------------------------------------===//1088// ImplicitConceptSpecializationDecl Implementation1089//===----------------------------------------------------------------------===//1090ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(1091DeclContext *DC, SourceLocation SL,1092ArrayRef<TemplateArgument> ConvertedArgs)1093: Decl(ImplicitConceptSpecialization, DC, SL),1094NumTemplateArgs(ConvertedArgs.size()) {1095setTemplateArguments(ConvertedArgs);1096}10971098ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(1099EmptyShell Empty, unsigned NumTemplateArgs)1100: Decl(ImplicitConceptSpecialization, Empty),1101NumTemplateArgs(NumTemplateArgs) {}11021103ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(1104const ASTContext &C, DeclContext *DC, SourceLocation SL,1105ArrayRef<TemplateArgument> ConvertedArgs) {1106return new (C, DC,1107additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))1108ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);1109}11101111ImplicitConceptSpecializationDecl *1112ImplicitConceptSpecializationDecl::CreateDeserialized(1113const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {1114return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))1115ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);1116}11171118void ImplicitConceptSpecializationDecl::setTemplateArguments(1119ArrayRef<TemplateArgument> Converted) {1120assert(Converted.size() == NumTemplateArgs);1121std::uninitialized_copy(Converted.begin(), Converted.end(),1122getTrailingObjects<TemplateArgument>());1123}11241125//===----------------------------------------------------------------------===//1126// ClassTemplatePartialSpecializationDecl Implementation1127//===----------------------------------------------------------------------===//1128void ClassTemplatePartialSpecializationDecl::anchor() {}11291130ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(1131ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,1132SourceLocation IdLoc, TemplateParameterList *Params,1133ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,1134ClassTemplatePartialSpecializationDecl *PrevDecl)1135: ClassTemplateSpecializationDecl(1136Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,1137SpecializedTemplate, Args, PrevDecl),1138TemplateParams(Params), InstantiatedFromMember(nullptr, false) {1139if (AdoptTemplateParameterList(Params, this))1140setInvalidDecl();1141}11421143ClassTemplatePartialSpecializationDecl *1144ClassTemplatePartialSpecializationDecl::Create(1145ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,1146SourceLocation IdLoc, TemplateParameterList *Params,1147ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,1148QualType CanonInjectedType,1149ClassTemplatePartialSpecializationDecl *PrevDecl) {1150auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(1151Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,1152PrevDecl);1153Result->setSpecializationKind(TSK_ExplicitSpecialization);1154Result->setMayHaveOutOfDateDef(false);11551156Context.getInjectedClassNameType(Result, CanonInjectedType);1157return Result;1158}11591160ClassTemplatePartialSpecializationDecl *1161ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,1162GlobalDeclID ID) {1163auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);1164Result->setMayHaveOutOfDateDef(false);1165return Result;1166}11671168SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {1169if (const ClassTemplatePartialSpecializationDecl *MT =1170getInstantiatedFromMember();1171MT && !isMemberSpecialization())1172return MT->getSourceRange();1173SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();1174if (const TemplateParameterList *TPL = getTemplateParameters();1175TPL && !getNumTemplateParameterLists())1176Range.setBegin(TPL->getTemplateLoc());1177return Range;1178}11791180//===----------------------------------------------------------------------===//1181// FriendTemplateDecl Implementation1182//===----------------------------------------------------------------------===//11831184void FriendTemplateDecl::anchor() {}11851186FriendTemplateDecl *1187FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,1188SourceLocation L,1189MutableArrayRef<TemplateParameterList *> Params,1190FriendUnion Friend, SourceLocation FLoc) {1191TemplateParameterList **TPL = nullptr;1192if (!Params.empty()) {1193TPL = new (Context) TemplateParameterList *[Params.size()];1194llvm::copy(Params, TPL);1195}1196return new (Context, DC)1197FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);1198}11991200FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,1201GlobalDeclID ID) {1202return new (C, ID) FriendTemplateDecl(EmptyShell());1203}12041205//===----------------------------------------------------------------------===//1206// TypeAliasTemplateDecl Implementation1207//===----------------------------------------------------------------------===//12081209TypeAliasTemplateDecl *1210TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,1211DeclarationName Name,1212TemplateParameterList *Params, NamedDecl *Decl) {1213bool Invalid = AdoptTemplateParameterList(Params, DC);1214auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);1215if (Invalid)1216TD->setInvalidDecl();1217return TD;1218}12191220TypeAliasTemplateDecl *1221TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1222return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),1223DeclarationName(), nullptr, nullptr);1224}12251226RedeclarableTemplateDecl::CommonBase *1227TypeAliasTemplateDecl::newCommon(ASTContext &C) const {1228auto *CommonPtr = new (C) Common;1229C.addDestruction(CommonPtr);1230return CommonPtr;1231}12321233//===----------------------------------------------------------------------===//1234// VarTemplateDecl Implementation1235//===----------------------------------------------------------------------===//12361237VarTemplateDecl *VarTemplateDecl::getDefinition() {1238VarTemplateDecl *CurD = this;1239while (CurD) {1240if (CurD->isThisDeclarationADefinition())1241return CurD;1242CurD = CurD->getPreviousDecl();1243}1244return nullptr;1245}12461247VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,1248SourceLocation L, DeclarationName Name,1249TemplateParameterList *Params,1250VarDecl *Decl) {1251bool Invalid = AdoptTemplateParameterList(Params, DC);1252auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);1253if (Invalid)1254TD->setInvalidDecl();1255return TD;1256}12571258VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,1259GlobalDeclID ID) {1260return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),1261DeclarationName(), nullptr, nullptr);1262}12631264void VarTemplateDecl::LoadLazySpecializations() const {1265loadLazySpecializationsImpl();1266}12671268llvm::FoldingSetVector<VarTemplateSpecializationDecl> &1269VarTemplateDecl::getSpecializations() const {1270LoadLazySpecializations();1271return getCommonPtr()->Specializations;1272}12731274llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &1275VarTemplateDecl::getPartialSpecializations() const {1276LoadLazySpecializations();1277return getCommonPtr()->PartialSpecializations;1278}12791280RedeclarableTemplateDecl::CommonBase *1281VarTemplateDecl::newCommon(ASTContext &C) const {1282auto *CommonPtr = new (C) Common;1283C.addDestruction(CommonPtr);1284return CommonPtr;1285}12861287VarTemplateSpecializationDecl *1288VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,1289void *&InsertPos) {1290return findSpecializationImpl(getSpecializations(), InsertPos, Args);1291}12921293void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,1294void *InsertPos) {1295addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);1296}12971298VarTemplatePartialSpecializationDecl *1299VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,1300TemplateParameterList *TPL, void *&InsertPos) {1301return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,1302TPL);1303}13041305void VarTemplatePartialSpecializationDecl::Profile(1306llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,1307TemplateParameterList *TPL, const ASTContext &Context) {1308ID.AddInteger(TemplateArgs.size());1309for (const TemplateArgument &TemplateArg : TemplateArgs)1310TemplateArg.Profile(ID, Context);1311TPL->Profile(ID, Context);1312}13131314void VarTemplateDecl::AddPartialSpecialization(1315VarTemplatePartialSpecializationDecl *D, void *InsertPos) {1316if (InsertPos)1317getPartialSpecializations().InsertNode(D, InsertPos);1318else {1319VarTemplatePartialSpecializationDecl *Existing =1320getPartialSpecializations().GetOrInsertNode(D);1321(void)Existing;1322assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");1323}13241325if (ASTMutationListener *L = getASTMutationListener())1326L->AddedCXXTemplateSpecialization(this, D);1327}13281329void VarTemplateDecl::getPartialSpecializations(1330SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {1331llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =1332getPartialSpecializations();1333PS.clear();1334PS.reserve(PartialSpecs.size());1335for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)1336PS.push_back(P.getMostRecentDecl());1337}13381339VarTemplatePartialSpecializationDecl *1340VarTemplateDecl::findPartialSpecInstantiatedFromMember(1341VarTemplatePartialSpecializationDecl *D) {1342Decl *DCanon = D->getCanonicalDecl();1343for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {1344if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)1345return P.getMostRecentDecl();1346}13471348return nullptr;1349}13501351//===----------------------------------------------------------------------===//1352// VarTemplateSpecializationDecl Implementation1353//===----------------------------------------------------------------------===//13541355VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(1356Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1357SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,1358TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)1359: VarDecl(DK, Context, DC, StartLoc, IdLoc,1360SpecializedTemplate->getIdentifier(), T, TInfo, S),1361SpecializedTemplate(SpecializedTemplate),1362TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),1363SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}13641365VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,1366ASTContext &C)1367: VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,1368QualType(), nullptr, SC_None),1369SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}13701371VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(1372ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1373SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,1374TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {1375return new (Context, DC) VarTemplateSpecializationDecl(1376VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,1377SpecializedTemplate, T, TInfo, S, Args);1378}13791380VarTemplateSpecializationDecl *1381VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,1382GlobalDeclID ID) {1383return new (C, ID)1384VarTemplateSpecializationDecl(VarTemplateSpecialization, C);1385}13861387void VarTemplateSpecializationDecl::getNameForDiagnostic(1388raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {1389NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);13901391const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);1392if (const ASTTemplateArgumentListInfo *ArgsAsWritten =1393PS ? PS->getTemplateArgsAsWritten() : nullptr) {1394printTemplateArgumentList(1395OS, ArgsAsWritten->arguments(), Policy,1396getSpecializedTemplate()->getTemplateParameters());1397} else {1398const TemplateArgumentList &TemplateArgs = getTemplateArgs();1399printTemplateArgumentList(1400OS, TemplateArgs.asArray(), Policy,1401getSpecializedTemplate()->getTemplateParameters());1402}1403}14041405VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {1406if (const auto *PartialSpec =1407SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())1408return PartialSpec->PartialSpecialization->getSpecializedTemplate();1409return SpecializedTemplate.get<VarTemplateDecl *>();1410}14111412SourceRange VarTemplateSpecializationDecl::getSourceRange() const {1413switch (getSpecializationKind()) {1414case TSK_Undeclared:1415case TSK_ImplicitInstantiation: {1416llvm::PointerUnion<VarTemplateDecl *,1417VarTemplatePartialSpecializationDecl *>1418Pattern = getSpecializedTemplateOrPartial();1419assert(!Pattern.isNull() &&1420"Variable template specialization without pattern?");1421if (const auto *VTPSD =1422Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())1423return VTPSD->getSourceRange();1424VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();1425if (hasInit()) {1426if (VarTemplateDecl *Definition = VTD->getDefinition())1427return Definition->getSourceRange();1428}1429return VTD->getCanonicalDecl()->getSourceRange();1430}1431case TSK_ExplicitSpecialization: {1432SourceRange Range = VarDecl::getSourceRange();1433if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();1434!hasInit() && Args)1435Range.setEnd(Args->getRAngleLoc());1436return Range;1437}1438case TSK_ExplicitInstantiationDeclaration:1439case TSK_ExplicitInstantiationDefinition: {1440SourceRange Range = VarDecl::getSourceRange();1441if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())1442Range.setBegin(ExternKW);1443else if (SourceLocation TemplateKW = getTemplateKeywordLoc();1444TemplateKW.isValid())1445Range.setBegin(TemplateKW);1446if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())1447Range.setEnd(Args->getRAngleLoc());1448return Range;1449}1450}1451llvm_unreachable("unhandled template specialization kind");1452}14531454void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {1455auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();1456if (!Info) {1457// Don't allocate if the location is invalid.1458if (Loc.isInvalid())1459return;1460Info = new (getASTContext()) ExplicitInstantiationInfo;1461Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1462ExplicitInfo = Info;1463}1464Info->ExternKeywordLoc = Loc;1465}14661467void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {1468auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();1469if (!Info) {1470// Don't allocate if the location is invalid.1471if (Loc.isInvalid())1472return;1473Info = new (getASTContext()) ExplicitInstantiationInfo;1474Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();1475ExplicitInfo = Info;1476}1477Info->TemplateKeywordLoc = Loc;1478}14791480//===----------------------------------------------------------------------===//1481// VarTemplatePartialSpecializationDecl Implementation1482//===----------------------------------------------------------------------===//14831484void VarTemplatePartialSpecializationDecl::anchor() {}14851486VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(1487ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1488SourceLocation IdLoc, TemplateParameterList *Params,1489VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,1490StorageClass S, ArrayRef<TemplateArgument> Args)1491: VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,1492DC, StartLoc, IdLoc, SpecializedTemplate, T,1493TInfo, S, Args),1494TemplateParams(Params), InstantiatedFromMember(nullptr, false) {1495if (AdoptTemplateParameterList(Params, DC))1496setInvalidDecl();1497}14981499VarTemplatePartialSpecializationDecl *1500VarTemplatePartialSpecializationDecl::Create(1501ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,1502SourceLocation IdLoc, TemplateParameterList *Params,1503VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,1504StorageClass S, ArrayRef<TemplateArgument> Args) {1505auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(1506Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,1507Args);1508Result->setSpecializationKind(TSK_ExplicitSpecialization);1509return Result;1510}15111512VarTemplatePartialSpecializationDecl *1513VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,1514GlobalDeclID ID) {1515return new (C, ID) VarTemplatePartialSpecializationDecl(C);1516}15171518SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {1519if (const VarTemplatePartialSpecializationDecl *MT =1520getInstantiatedFromMember();1521MT && !isMemberSpecialization())1522return MT->getSourceRange();1523SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();1524if (const TemplateParameterList *TPL = getTemplateParameters();1525TPL && !getNumTemplateParameterLists())1526Range.setBegin(TPL->getTemplateLoc());1527return Range;1528}15291530static TemplateParameterList *1531createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {1532// typename T1533auto *T = TemplateTypeParmDecl::Create(1534C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,1535/*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,1536/*HasTypeConstraint=*/false);1537T->setImplicit(true);15381539// T ...Ints1540TypeSourceInfo *TI =1541C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));1542auto *N = NonTypeTemplateParmDecl::Create(1543C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,1544/*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);1545N->setImplicit(true);15461547// <typename T, T ...Ints>1548NamedDecl *P[2] = {T, N};1549auto *TPL = TemplateParameterList::Create(1550C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);15511552// template <typename T, ...Ints> class IntSeq1553auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(1554C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,1555/*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);1556TemplateTemplateParm->setImplicit(true);15571558// typename T1559auto *TemplateTypeParm = TemplateTypeParmDecl::Create(1560C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,1561/*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,1562/*HasTypeConstraint=*/false);1563TemplateTypeParm->setImplicit(true);15641565// T N1566TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(1567QualType(TemplateTypeParm->getTypeForDecl(), 0));1568auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(1569C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,1570/*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);1571NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,1572NonTypeTemplateParm};15731574// template <template <typename T, T ...Ints> class IntSeq, typename T, T N>1575return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),1576Params, SourceLocation(), nullptr);1577}15781579static TemplateParameterList *1580createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {1581// std::size_t Index1582TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());1583auto *Index = NonTypeTemplateParmDecl::Create(1584C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,1585/*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);15861587// typename ...T1588auto *Ts = TemplateTypeParmDecl::Create(1589C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,1590/*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,1591/*HasTypeConstraint=*/false);1592Ts->setImplicit(true);15931594// template <std::size_t Index, typename ...T>1595NamedDecl *Params[] = {Index, Ts};1596return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),1597llvm::ArrayRef(Params), SourceLocation(),1598nullptr);1599}16001601static TemplateParameterList *createBuiltinTemplateParameterList(1602const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {1603switch (BTK) {1604case BTK__make_integer_seq:1605return createMakeIntegerSeqParameterList(C, DC);1606case BTK__type_pack_element:1607return createTypePackElementParameterList(C, DC);1608}16091610llvm_unreachable("unhandled BuiltinTemplateKind!");1611}16121613void BuiltinTemplateDecl::anchor() {}16141615BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,1616DeclarationName Name,1617BuiltinTemplateKind BTK)1618: TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,1619createBuiltinTemplateParameterList(C, DC, BTK)),1620BTK(BTK) {}16211622TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,1623QualType T,1624const APValue &V) {1625DeclContext *DC = C.getTranslationUnitDecl();1626auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);1627C.addDestruction(&TPOD->Value);1628return TPOD;1629}16301631TemplateParamObjectDecl *1632TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1633auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());1634C.addDestruction(&TPOD->Value);1635return TPOD;1636}16371638void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,1639const PrintingPolicy &Policy) const {1640OS << "<template param ";1641printAsExpr(OS, Policy);1642OS << ">";1643}16441645void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {1646printAsExpr(OS, getASTContext().getPrintingPolicy());1647}16481649void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,1650const PrintingPolicy &Policy) const {1651getType().getUnqualifiedType().print(OS, Policy);1652printAsInit(OS, Policy);1653}16541655void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {1656printAsInit(OS, getASTContext().getPrintingPolicy());1657}16581659void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,1660const PrintingPolicy &Policy) const {1661getValue().printPretty(OS, Policy, getType(), &getASTContext());1662}16631664TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {1665switch (D->getKind()) {1666case Decl::Kind::CXXRecord:1667return cast<CXXRecordDecl>(D)1668->getDescribedTemplate()1669->getTemplateParameters();1670case Decl::Kind::ClassTemplate:1671return cast<ClassTemplateDecl>(D)->getTemplateParameters();1672case Decl::Kind::ClassTemplateSpecialization: {1673const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);1674auto P = CTSD->getSpecializedTemplateOrPartial();1675if (const auto *CTPSD =1676P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())1677return CTPSD->getTemplateParameters();1678return cast<ClassTemplateDecl *>(P)->getTemplateParameters();1679}1680case Decl::Kind::ClassTemplatePartialSpecialization:1681return cast<ClassTemplatePartialSpecializationDecl>(D)1682->getTemplateParameters();1683case Decl::Kind::TypeAliasTemplate:1684return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();1685case Decl::Kind::BuiltinTemplate:1686return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();1687case Decl::Kind::CXXDeductionGuide:1688case Decl::Kind::CXXConversion:1689case Decl::Kind::CXXConstructor:1690case Decl::Kind::CXXDestructor:1691case Decl::Kind::CXXMethod:1692case Decl::Kind::Function:1693return cast<FunctionDecl>(D)1694->getTemplateSpecializationInfo()1695->getTemplate()1696->getTemplateParameters();1697case Decl::Kind::FunctionTemplate:1698return cast<FunctionTemplateDecl>(D)->getTemplateParameters();1699case Decl::Kind::VarTemplate:1700return cast<VarTemplateDecl>(D)->getTemplateParameters();1701case Decl::Kind::VarTemplateSpecialization: {1702const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);1703auto P = VTSD->getSpecializedTemplateOrPartial();1704if (const auto *VTPSD =1705P.dyn_cast<VarTemplatePartialSpecializationDecl *>())1706return VTPSD->getTemplateParameters();1707return cast<VarTemplateDecl *>(P)->getTemplateParameters();1708}1709case Decl::Kind::VarTemplatePartialSpecialization:1710return cast<VarTemplatePartialSpecializationDecl>(D)1711->getTemplateParameters();1712case Decl::Kind::TemplateTemplateParm:1713return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();1714case Decl::Kind::Concept:1715return cast<ConceptDecl>(D)->getTemplateParameters();1716default:1717llvm_unreachable("Unhandled templated declaration kind");1718}1719}172017211722