brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.2 KiB · f54ccf0 Raw
891 lines · cpp
1//===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//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 defines the TypeLoc subclasses implementations.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/TypeLoc.h"14#include "clang/AST/ASTConcept.h"15#include "clang/AST/ASTContext.h"16#include "clang/AST/Attr.h"17#include "clang/AST/DeclTemplate.h"18#include "clang/AST/Expr.h"19#include "clang/AST/NestedNameSpecifier.h"20#include "clang/AST/TemplateBase.h"21#include "clang/AST/TemplateName.h"22#include "clang/AST/TypeLocVisitor.h"23#include "clang/Basic/SourceLocation.h"24#include "clang/Basic/Specifiers.h"25#include "llvm/ADT/SmallVector.h"26#include "llvm/Support/ErrorHandling.h"27#include "llvm/Support/MathExtras.h"28#include <algorithm>29#include <cassert>30#include <cstdint>31#include <cstring>32 33using namespace clang;34 35static const unsigned TypeLocMaxDataAlign = alignof(void *);36 37//===----------------------------------------------------------------------===//38// TypeLoc Implementation39//===----------------------------------------------------------------------===//40 41namespace {42 43class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {44public:45#define ABSTRACT_TYPELOC(CLASS, PARENT)46#define TYPELOC(CLASS, PARENT) \47  SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \48    return TyLoc.getLocalSourceRange(); \49  }50#include "clang/AST/TypeLocNodes.def"51};52 53} // namespace54 55SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {56  if (TL.isNull()) return SourceRange();57  return TypeLocRanger().Visit(TL);58}59 60namespace {61 62class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {63public:64#define ABSTRACT_TYPELOC(CLASS, PARENT)65#define TYPELOC(CLASS, PARENT) \66  unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \67    return TyLoc.getLocalDataAlignment(); \68  }69#include "clang/AST/TypeLocNodes.def"70};71 72} // namespace73 74/// Returns the alignment of the type source info data block.75unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {76  if (Ty.isNull()) return 1;77  return TypeAligner().Visit(TypeLoc(Ty, nullptr));78}79 80namespace {81 82class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {83public:84#define ABSTRACT_TYPELOC(CLASS, PARENT)85#define TYPELOC(CLASS, PARENT) \86  unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \87    return TyLoc.getLocalDataSize(); \88  }89#include "clang/AST/TypeLocNodes.def"90};91 92} // namespace93 94/// Returns the size of the type source info data block.95unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {96  unsigned Total = 0;97  TypeLoc TyLoc(Ty, nullptr);98  unsigned MaxAlign = 1;99  while (!TyLoc.isNull()) {100    unsigned Align = getLocalAlignmentForType(TyLoc.getType());101    MaxAlign = std::max(Align, MaxAlign);102    Total = llvm::alignTo(Total, Align);103    Total += TypeSizer().Visit(TyLoc);104    TyLoc = TyLoc.getNextTypeLoc();105  }106  Total = llvm::alignTo(Total, MaxAlign);107  return Total;108}109 110namespace {111 112class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {113public:114#define ABSTRACT_TYPELOC(CLASS, PARENT)115#define TYPELOC(CLASS, PARENT) \116  TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \117    return TyLoc.getNextTypeLoc(); \118  }119#include "clang/AST/TypeLocNodes.def"120};121 122} // namespace123 124/// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the125/// TypeLoc is a PointerLoc and next TypeLoc is for "int".126TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {127  return NextLoc().Visit(TL);128}129 130/// Initializes a type location, and all of its children131/// recursively, as if the entire tree had been written in the132/// given location.133void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,134                             SourceLocation Loc) {135  while (true) {136    switch (TL.getTypeLocClass()) {137#define ABSTRACT_TYPELOC(CLASS, PARENT)138#define TYPELOC(CLASS, PARENT)        \139    case CLASS: {                     \140      CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \141      TLCasted.initializeLocal(Context, Loc);  \142      TL = TLCasted.getNextTypeLoc(); \143      if (!TL) return;                \144      continue;                       \145    }146#include "clang/AST/TypeLocNodes.def"147    }148  }149}150 151namespace {152 153class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {154  TypeLoc Source;155 156public:157  TypeLocCopier(TypeLoc source) : Source(source) {}158 159#define ABSTRACT_TYPELOC(CLASS, PARENT)160#define TYPELOC(CLASS, PARENT)                          \161  void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \162    dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \163  }164#include "clang/AST/TypeLocNodes.def"165};166 167} // namespace168 169void TypeLoc::copy(TypeLoc other) {170  assert(getFullDataSize() == other.getFullDataSize());171 172  // If both data pointers are aligned to the maximum alignment, we173  // can memcpy because getFullDataSize() accurately reflects the174  // layout of the data.175  if (reinterpret_cast<uintptr_t>(Data) ==176          llvm::alignTo(reinterpret_cast<uintptr_t>(Data),177                        TypeLocMaxDataAlign) &&178      reinterpret_cast<uintptr_t>(other.Data) ==179          llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),180                        TypeLocMaxDataAlign)) {181    memcpy(Data, other.Data, getFullDataSize());182    return;183  }184 185  // Copy each of the pieces.186  TypeLoc TL(getType(), Data);187  do {188    TypeLocCopier(other).Visit(TL);189    other = other.getNextTypeLoc();190  } while ((TL = TL.getNextTypeLoc()));191}192 193SourceLocation TypeLoc::getBeginLoc() const {194  TypeLoc Cur = *this;195  TypeLoc LeftMost = Cur;196  while (true) {197    switch (Cur.getTypeLocClass()) {198    case FunctionProto:199      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()200              ->hasTrailingReturn()) {201        LeftMost = Cur;202        break;203      }204      [[fallthrough]];205    case FunctionNoProto:206    case ConstantArray:207    case DependentSizedArray:208    case IncompleteArray:209    case VariableArray:210      // FIXME: Currently QualifiedTypeLoc does not have a source range211    case Qualified:212      Cur = Cur.getNextTypeLoc();213      continue;214    default:215      if (Cur.getLocalSourceRange().getBegin().isValid())216        LeftMost = Cur;217      Cur = Cur.getNextTypeLoc();218      if (Cur.isNull())219        break;220      continue;221    } // switch222    break;223  } // while224  return LeftMost.getLocalSourceRange().getBegin();225}226 227SourceLocation TypeLoc::getEndLoc() const {228  TypeLoc Cur = *this;229  TypeLoc Last;230  while (true) {231    switch (Cur.getTypeLocClass()) {232    default:233      if (!Last)234        Last = Cur;235      return Last.getLocalSourceRange().getEnd();236    case Paren:237    case ConstantArray:238    case DependentSizedArray:239    case IncompleteArray:240    case VariableArray:241    case FunctionNoProto:242      // The innermost type with suffix syntax always determines the end of the243      // type.244      Last = Cur;245      break;246    case FunctionProto:247      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())248        Last = TypeLoc();249      else250        Last = Cur;251      break;252    case ObjCObjectPointer:253      // `id` and `id<...>` have no star location.254      if (Cur.castAs<ObjCObjectPointerTypeLoc>().getStarLoc().isInvalid())255        break;256      [[fallthrough]];257    case Pointer:258    case BlockPointer:259    case MemberPointer:260    case LValueReference:261    case RValueReference:262    case PackExpansion:263      // Types with prefix syntax only determine the end of the type if there264      // is no suffix type.265      if (!Last)266        Last = Cur;267      break;268    case Qualified:269      break;270    }271    Cur = Cur.getNextTypeLoc();272  }273}274 275namespace {276 277struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {278  // Overload resolution does the real work for us.279  static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }280  static bool isTypeSpec(TypeLoc _) { return false; }281 282#define ABSTRACT_TYPELOC(CLASS, PARENT)283#define TYPELOC(CLASS, PARENT) \284  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \285    return isTypeSpec(TyLoc); \286  }287#include "clang/AST/TypeLocNodes.def"288};289 290} // namespace291 292/// Determines if the given type loc corresponds to a293/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in294/// the type hierarchy, this is made somewhat complicated.295///296/// There are a lot of types that currently use TypeSpecTypeLoc297/// because it's a convenient base class.  Ideally we would not accept298/// those here, but ideally we would have better implementations for299/// them.300bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {301  if (TL.getType().hasLocalQualifiers()) return false;302  return TSTChecker().Visit(TL);303}304 305bool TagTypeLoc::isDefinition() const {306  return getTypePtr()->isTagOwned() && getDecl()->isCompleteDefinition();307}308 309// Reimplemented to account for GNU/C++ extension310//     typeof unary-expression311// where there are no parentheses.312SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {313  if (getRParenLoc().isValid())314    return SourceRange(getTypeofLoc(), getRParenLoc());315  else316    return SourceRange(getTypeofLoc(),317                       getUnderlyingExpr()->getSourceRange().getEnd());318}319 320 321TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {322  if (needsExtraLocalData())323    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);324  switch (getTypePtr()->getKind()) {325  case BuiltinType::Void:326    return TST_void;327  case BuiltinType::Bool:328    return TST_bool;329  case BuiltinType::Char_U:330  case BuiltinType::Char_S:331    return TST_char;332  case BuiltinType::Char8:333    return TST_char8;334  case BuiltinType::Char16:335    return TST_char16;336  case BuiltinType::Char32:337    return TST_char32;338  case BuiltinType::WChar_S:339  case BuiltinType::WChar_U:340    return TST_wchar;341  case BuiltinType::UChar:342  case BuiltinType::UShort:343  case BuiltinType::UInt:344  case BuiltinType::ULong:345  case BuiltinType::ULongLong:346  case BuiltinType::UInt128:347  case BuiltinType::SChar:348  case BuiltinType::Short:349  case BuiltinType::Int:350  case BuiltinType::Long:351  case BuiltinType::LongLong:352  case BuiltinType::Int128:353  case BuiltinType::Half:354  case BuiltinType::Float:355  case BuiltinType::Double:356  case BuiltinType::LongDouble:357  case BuiltinType::Float16:358  case BuiltinType::Float128:359  case BuiltinType::Ibm128:360  case BuiltinType::ShortAccum:361  case BuiltinType::Accum:362  case BuiltinType::LongAccum:363  case BuiltinType::UShortAccum:364  case BuiltinType::UAccum:365  case BuiltinType::ULongAccum:366  case BuiltinType::ShortFract:367  case BuiltinType::Fract:368  case BuiltinType::LongFract:369  case BuiltinType::UShortFract:370  case BuiltinType::UFract:371  case BuiltinType::ULongFract:372  case BuiltinType::SatShortAccum:373  case BuiltinType::SatAccum:374  case BuiltinType::SatLongAccum:375  case BuiltinType::SatUShortAccum:376  case BuiltinType::SatUAccum:377  case BuiltinType::SatULongAccum:378  case BuiltinType::SatShortFract:379  case BuiltinType::SatFract:380  case BuiltinType::SatLongFract:381  case BuiltinType::SatUShortFract:382  case BuiltinType::SatUFract:383  case BuiltinType::SatULongFract:384  case BuiltinType::BFloat16:385    llvm_unreachable("Builtin type needs extra local data!");386    // Fall through, if the impossible happens.387 388  case BuiltinType::NullPtr:389  case BuiltinType::Overload:390  case BuiltinType::Dependent:391  case BuiltinType::UnresolvedTemplate:392  case BuiltinType::BoundMember:393  case BuiltinType::UnknownAny:394  case BuiltinType::ARCUnbridgedCast:395  case BuiltinType::PseudoObject:396  case BuiltinType::ObjCId:397  case BuiltinType::ObjCClass:398  case BuiltinType::ObjCSel:399#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \400  case BuiltinType::Id:401#include "clang/Basic/OpenCLImageTypes.def"402#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \403  case BuiltinType::Id:404#include "clang/Basic/OpenCLExtensionTypes.def"405  case BuiltinType::OCLSampler:406  case BuiltinType::OCLEvent:407  case BuiltinType::OCLClkEvent:408  case BuiltinType::OCLQueue:409  case BuiltinType::OCLReserveID:410#define SVE_TYPE(Name, Id, SingletonId) \411  case BuiltinType::Id:412#include "clang/Basic/AArch64ACLETypes.def"413#define PPC_VECTOR_TYPE(Name, Id, Size) \414  case BuiltinType::Id:415#include "clang/Basic/PPCTypes.def"416#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:417#include "clang/Basic/RISCVVTypes.def"418#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:419#include "clang/Basic/WebAssemblyReferenceTypes.def"420#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:421#include "clang/Basic/AMDGPUTypes.def"422#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:423#include "clang/Basic/HLSLIntangibleTypes.def"424  case BuiltinType::BuiltinFn:425  case BuiltinType::IncompleteMatrixIdx:426  case BuiltinType::ArraySection:427  case BuiltinType::OMPArrayShaping:428  case BuiltinType::OMPIterator:429    return TST_unspecified;430  }431 432  llvm_unreachable("Invalid BuiltinType Kind!");433}434 435TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {436  while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())437    TL = PTL.getInnerLoc();438  return TL;439}440 441SourceLocation TypeLoc::findNullabilityLoc() const {442  if (auto ATL = getAs<AttributedTypeLoc>()) {443    const Attr *A = ATL.getAttr();444    if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||445              isa<TypeNullUnspecifiedAttr>(A)))446      return A->getLocation();447  }448 449  return {};450}451 452TypeLoc TypeLoc::findExplicitQualifierLoc() const {453  // Qualified types.454  if (auto qual = getAs<QualifiedTypeLoc>())455    return qual;456 457  TypeLoc loc = IgnoreParens();458 459  // Attributed types.460  if (auto attr = loc.getAs<AttributedTypeLoc>()) {461    if (attr.isQualifier()) return attr;462    return attr.getModifiedLoc().findExplicitQualifierLoc();463  }464 465  // C11 _Atomic types.466  if (auto atomic = loc.getAs<AtomicTypeLoc>()) {467    return atomic;468  }469 470  return {};471}472 473NestedNameSpecifierLoc TypeLoc::getPrefix() const {474  switch (getTypeLocClass()) {475  case TypeLoc::DependentName:476    return castAs<DependentNameTypeLoc>().getQualifierLoc();477  case TypeLoc::TemplateSpecialization:478    return castAs<TemplateSpecializationTypeLoc>().getQualifierLoc();479  case TypeLoc::DeducedTemplateSpecialization:480    return castAs<DeducedTemplateSpecializationTypeLoc>().getQualifierLoc();481  case TypeLoc::Enum:482  case TypeLoc::Record:483  case TypeLoc::InjectedClassName:484    return castAs<TagTypeLoc>().getQualifierLoc();485  case TypeLoc::Typedef:486    return castAs<TypedefTypeLoc>().getQualifierLoc();487  case TypeLoc::UnresolvedUsing:488    return castAs<UnresolvedUsingTypeLoc>().getQualifierLoc();489  case TypeLoc::Using:490    return castAs<UsingTypeLoc>().getQualifierLoc();491  default:492    return NestedNameSpecifierLoc();493  }494}495 496SourceLocation TypeLoc::getNonElaboratedBeginLoc() const {497  // For elaborated types (e.g. `struct a::A`) we want the portion after the498  // `struct` but including the namespace qualifier, `a::`.499  switch (getTypeLocClass()) {500  case TypeLoc::Qualified:501    return castAs<QualifiedTypeLoc>()502        .getUnqualifiedLoc()503        .getNonElaboratedBeginLoc();504  case TypeLoc::TemplateSpecialization: {505    auto T = castAs<TemplateSpecializationTypeLoc>();506    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())507      return QualifierLoc.getBeginLoc();508    return T.getTemplateNameLoc();509  }510  case TypeLoc::DeducedTemplateSpecialization: {511    auto T = castAs<DeducedTemplateSpecializationTypeLoc>();512    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())513      return QualifierLoc.getBeginLoc();514    return T.getTemplateNameLoc();515  }516  case TypeLoc::DependentName: {517    auto T = castAs<DependentNameTypeLoc>();518    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())519      return QualifierLoc.getBeginLoc();520    return T.getNameLoc();521  }522  case TypeLoc::Enum:523  case TypeLoc::Record:524  case TypeLoc::InjectedClassName: {525    auto T = castAs<TagTypeLoc>();526    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())527      return QualifierLoc.getBeginLoc();528    return T.getNameLoc();529  }530  case TypeLoc::Typedef: {531    auto T = castAs<TypedefTypeLoc>();532    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())533      return QualifierLoc.getBeginLoc();534    return T.getNameLoc();535  }536  case TypeLoc::UnresolvedUsing: {537    auto T = castAs<UnresolvedUsingTypeLoc>();538    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())539      return QualifierLoc.getBeginLoc();540    return T.getNameLoc();541  }542  case TypeLoc::Using: {543    auto T = castAs<UsingTypeLoc>();544    if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())545      return QualifierLoc.getBeginLoc();546    return T.getNameLoc();547  }548  default:549    return getBeginLoc();550  }551}552 553void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,554                                           SourceLocation Loc) {555  setNameLoc(Loc);556  if (!getNumProtocols()) return;557 558  setProtocolLAngleLoc(Loc);559  setProtocolRAngleLoc(Loc);560  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)561    setProtocolLoc(i, Loc);562}563 564void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,565                                        SourceLocation Loc) {566  setHasBaseTypeAsWritten(true);567  setTypeArgsLAngleLoc(Loc);568  setTypeArgsRAngleLoc(Loc);569  for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {570    setTypeArgTInfo(i,571                   Context.getTrivialTypeSourceInfo(572                     getTypePtr()->getTypeArgsAsWritten()[i], Loc));573  }574  setProtocolLAngleLoc(Loc);575  setProtocolRAngleLoc(Loc);576  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)577    setProtocolLoc(i, Loc);578}579 580SourceRange AttributedTypeLoc::getLocalSourceRange() const {581  // Note that this does *not* include the range of the attribute582  // enclosure, e.g.:583  //    __attribute__((foo(bar)))584  //    ^~~~~~~~~~~~~~~        ~~585  // or586  //    [[foo(bar)]]587  //    ^~        ~~588  // That enclosure doesn't necessarily belong to a single attribute589  // anyway.590  return getAttr() ? getAttr()->getRange() : SourceRange();591}592 593SourceRange CountAttributedTypeLoc::getLocalSourceRange() const {594  return getCountExpr() ? getCountExpr()->getSourceRange() : SourceRange();595}596 597SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const {598  return getAttr() ? getAttr()->getRange() : SourceRange();599}600 601void TypeOfTypeLoc::initializeLocal(ASTContext &Context,602                                       SourceLocation Loc) {603  TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>604      ::initializeLocal(Context, Loc);605  this->getLocalData()->UnmodifiedTInfo =606      Context.getTrivialTypeSourceInfo(getUnmodifiedType(), Loc);607}608 609void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,610                                       SourceLocation Loc) {611    setKWLoc(Loc);612    setRParenLoc(Loc);613    setLParenLoc(Loc);614    this->setUnderlyingTInfo(615        Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));616}617 618template <class TL>619static void initializeElaboratedKeyword(TL T, SourceLocation Loc) {620  T.setElaboratedKeywordLoc(T.getTypePtr()->getKeyword() !=621                                    ElaboratedTypeKeyword::None622                                ? Loc623                                : SourceLocation());624}625 626static NestedNameSpecifierLoc initializeQualifier(ASTContext &Context,627                                                  NestedNameSpecifier Qualifier,628                                                  SourceLocation Loc) {629  if (!Qualifier)630    return NestedNameSpecifierLoc();631  NestedNameSpecifierLocBuilder Builder;632  Builder.MakeTrivial(Context, Qualifier, Loc);633  return Builder.getWithLocInContext(Context);634}635 636void DependentNameTypeLoc::initializeLocal(ASTContext &Context,637                                           SourceLocation Loc) {638  initializeElaboratedKeyword(*this, Loc);639  setQualifierLoc(640      initializeQualifier(Context, getTypePtr()->getQualifier(), Loc));641  setNameLoc(Loc);642}643 644void TemplateSpecializationTypeLoc::set(SourceLocation ElaboratedKeywordLoc,645                                        NestedNameSpecifierLoc QualifierLoc,646                                        SourceLocation TemplateKeywordLoc,647                                        SourceLocation NameLoc,648                                        SourceLocation LAngleLoc,649                                        SourceLocation RAngleLoc) {650  TemplateSpecializationLocInfo &Data = *getLocalData();651 652  Data.ElaboratedKWLoc = ElaboratedKeywordLoc;653  SourceLocation BeginLoc = ElaboratedKeywordLoc;654 655  getLocalData()->QualifierData = QualifierLoc.getOpaqueData();656 657  assert(QualifierLoc.getNestedNameSpecifier() ==658         getTypePtr()->getTemplateName().getQualifier());659  Data.QualifierData = QualifierLoc ? QualifierLoc.getOpaqueData() : nullptr;660  if (QualifierLoc && !BeginLoc.isValid())661    BeginLoc = QualifierLoc.getBeginLoc();662 663  Data.TemplateKWLoc = TemplateKeywordLoc;664  if (!BeginLoc.isValid())665    BeginLoc = TemplateKeywordLoc;666 667  Data.NameLoc = NameLoc;668  if (!BeginLoc.isValid())669    BeginLoc = NameLoc;670 671  Data.LAngleLoc = LAngleLoc;672  Data.SR = SourceRange(BeginLoc, RAngleLoc);673}674 675void TemplateSpecializationTypeLoc::set(SourceLocation ElaboratedKeywordLoc,676                                        NestedNameSpecifierLoc QualifierLoc,677                                        SourceLocation TemplateKeywordLoc,678                                        SourceLocation NameLoc,679                                        const TemplateArgumentListInfo &TAL) {680  set(ElaboratedKeywordLoc, QualifierLoc, TemplateKeywordLoc, NameLoc,681      TAL.getLAngleLoc(), TAL.getRAngleLoc());682  MutableArrayRef<TemplateArgumentLocInfo> ArgInfos = getArgLocInfos();683  assert(TAL.size() == ArgInfos.size());684  for (unsigned I = 0, N = TAL.size(); I != N; ++I)685    ArgInfos[I] = TAL[I].getLocInfo();686}687 688void TemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,689                                                    SourceLocation Loc) {690 691  auto [Qualifier, HasTemplateKeyword] =692      getTypePtr()->getTemplateName().getQualifierAndTemplateKeyword();693 694  SourceLocation ElaboratedKeywordLoc =695      getTypePtr()->getKeyword() != ElaboratedTypeKeyword::None696          ? Loc697          : SourceLocation();698 699  NestedNameSpecifierLoc QualifierLoc;700  if (Qualifier) {701    NestedNameSpecifierLocBuilder Builder;702    Builder.MakeTrivial(Context, Qualifier, Loc);703    QualifierLoc = Builder.getWithLocInContext(Context);704  }705 706  TemplateArgumentListInfo TAL(Loc, Loc);707  set(ElaboratedKeywordLoc, QualifierLoc,708      /*TemplateKeywordLoc=*/HasTemplateKeyword ? Loc : SourceLocation(),709      /*NameLoc=*/Loc, /*LAngleLoc=*/Loc, /*RAngleLoc=*/Loc);710  initializeArgLocs(Context, getTypePtr()->template_arguments(), getArgInfos(),711                    Loc);712}713 714void TemplateSpecializationTypeLoc::initializeArgLocs(715    ASTContext &Context, ArrayRef<TemplateArgument> Args,716    TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) {717  for (unsigned i = 0, e = Args.size(); i != e; ++i) {718    switch (Args[i].getKind()) {719    case TemplateArgument::Null:720      llvm_unreachable("Impossible TemplateArgument");721 722    case TemplateArgument::Integral:723    case TemplateArgument::Declaration:724    case TemplateArgument::NullPtr:725    case TemplateArgument::StructuralValue:726      ArgInfos[i] = TemplateArgumentLocInfo();727      break;728 729    case TemplateArgument::Expression:730      ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());731      break;732 733    case TemplateArgument::Type:734      ArgInfos[i] = TemplateArgumentLocInfo(735                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(),736                                                           Loc));737      break;738 739    case TemplateArgument::Template:740    case TemplateArgument::TemplateExpansion: {741      NestedNameSpecifierLocBuilder Builder;742      TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();743      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())744        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);745      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())746        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);747 748      ArgInfos[i] = TemplateArgumentLocInfo(749          Context, Loc, Builder.getWithLocInContext(Context), Loc,750          Args[i].getKind() == TemplateArgument::Template ? SourceLocation()751                                                          : Loc);752      break;753    }754 755    case TemplateArgument::Pack:756      ArgInfos[i] = TemplateArgumentLocInfo();757      break;758    }759  }760}761 762// Builds a ConceptReference where all locations point at the same token,763// for use in trivial TypeSourceInfo for constrained AutoType764static ConceptReference *createTrivialConceptReference(ASTContext &Context,765                                                       SourceLocation Loc,766                                                       const AutoType *AT) {767  DeclarationNameInfo DNI =768      DeclarationNameInfo(AT->getTypeConstraintConcept()->getDeclName(), Loc,769                          AT->getTypeConstraintConcept()->getDeclName());770  unsigned size = AT->getTypeConstraintArguments().size();771  llvm::SmallVector<TemplateArgumentLocInfo, 8> TALI(size);772  TemplateSpecializationTypeLoc::initializeArgLocs(773      Context, AT->getTypeConstraintArguments(), TALI.data(), Loc);774  TemplateArgumentListInfo TAListI;775  for (unsigned i = 0; i < size; ++i) {776    TAListI.addArgument(777        TemplateArgumentLoc(AT->getTypeConstraintArguments()[i],778                            TALI[i])); // TemplateArgumentLocInfo()779  }780 781  auto *ConceptRef = ConceptReference::Create(782      Context, NestedNameSpecifierLoc{}, Loc, DNI, nullptr,783      AT->getTypeConstraintConcept(),784      ASTTemplateArgumentListInfo::Create(Context, TAListI));785  return ConceptRef;786}787 788void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {789  setRParenLoc(Loc);790  setNameLoc(Loc);791  setConceptReference(nullptr);792  if (getTypePtr()->isConstrained()) {793    setConceptReference(794        createTrivialConceptReference(Context, Loc, getTypePtr()));795  }796}797 798void DeducedTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,799                                                           SourceLocation Loc) {800  initializeElaboratedKeyword(*this, Loc);801  setQualifierLoc(initializeQualifier(802      Context, getTypePtr()->getTemplateName().getQualifier(), Loc));803  setTemplateNameLoc(Loc);804}805 806namespace {807 808  class GetContainedAutoTypeLocVisitor :809    public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> {810  public:811    using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit;812 813    TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) {814      return TL;815    }816 817    // Only these types can contain the desired 'auto' type.818 819    TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {820      return Visit(T.getUnqualifiedLoc());821    }822 823    TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) {824      return Visit(T.getPointeeLoc());825    }826 827    TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {828      return Visit(T.getPointeeLoc());829    }830 831    TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) {832      return Visit(T.getPointeeLoc());833    }834 835    TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {836      return Visit(T.getPointeeLoc());837    }838 839    TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) {840      return Visit(T.getElementLoc());841    }842 843    TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) {844      return Visit(T.getReturnLoc());845    }846 847    TypeLoc VisitParenTypeLoc(ParenTypeLoc T) {848      return Visit(T.getInnerLoc());849    }850 851    TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) {852      return Visit(T.getModifiedLoc());853    }854 855    TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) {856      return Visit(T.getWrappedLoc());857    }858 859    TypeLoc860    VisitHLSLAttributedResourceTypeLoc(HLSLAttributedResourceTypeLoc T) {861      return Visit(T.getWrappedLoc());862    }863 864    TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {865      return Visit(T.getInnerLoc());866    }867 868    TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) {869      return Visit(T.getOriginalLoc());870    }871 872    TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) {873      return Visit(T.getPatternLoc());874    }875  };876 877} // namespace878 879AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {880  TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this);881  if (Res.isNull())882    return AutoTypeLoc();883  return Res.getAs<AutoTypeLoc>();884}885 886SourceLocation TypeLoc::getTemplateKeywordLoc() const {887  if (const auto TSTL = getAsAdjusted<TemplateSpecializationTypeLoc>())888    return TSTL.getTemplateKeywordLoc();889  return SourceLocation();890}891