brintos

brintos / llvm-project-archived public Read only

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