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