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