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) case BuiltinType::Id: 432 #include "clang/Basic/AMDGPUTypes.def" 433 case BuiltinType::BuiltinFn: 434 case BuiltinType::IncompleteMatrixIdx: 435 case BuiltinType::ArraySection: 436 case BuiltinType::OMPArrayShaping: 437 case BuiltinType::OMPIterator: 438 return TST_unspecified; 439 } 440 441 llvm_unreachable("Invalid BuiltinType Kind!"); 442 } 443 444 TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { 445 while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>()) 446 TL = PTL.getInnerLoc(); 447 return TL; 448 } 449 450 SourceLocation TypeLoc::findNullabilityLoc() const { 451 if (auto ATL = getAs<AttributedTypeLoc>()) { 452 const Attr *A = ATL.getAttr(); 453 if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) || 454 isa<TypeNullUnspecifiedAttr>(A))) 455 return A->getLocation(); 456 } 457 458 return {}; 459 } 460 461 TypeLoc TypeLoc::findExplicitQualifierLoc() const { 462 // Qualified types. 463 if (auto qual = getAs<QualifiedTypeLoc>()) 464 return qual; 465 466 TypeLoc loc = IgnoreParens(); 467 468 // Attributed types. 469 if (auto attr = loc.getAs<AttributedTypeLoc>()) { 470 if (attr.isQualifier()) return attr; 471 return attr.getModifiedLoc().findExplicitQualifierLoc(); 472 } 473 474 // C11 _Atomic types. 475 if (auto atomic = loc.getAs<AtomicTypeLoc>()) { 476 return atomic; 477 } 478 479 return {}; 480 } 481 482 void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context, 483 SourceLocation Loc) { 484 setNameLoc(Loc); 485 if (!getNumProtocols()) return; 486 487 setProtocolLAngleLoc(Loc); 488 setProtocolRAngleLoc(Loc); 489 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 490 setProtocolLoc(i, Loc); 491 } 492 493 void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context, 494 SourceLocation Loc) { 495 setHasBaseTypeAsWritten(true); 496 setTypeArgsLAngleLoc(Loc); 497 setTypeArgsRAngleLoc(Loc); 498 for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) { 499 setTypeArgTInfo(i, 500 Context.getTrivialTypeSourceInfo( 501 getTypePtr()->getTypeArgsAsWritten()[i], Loc)); 502 } 503 setProtocolLAngleLoc(Loc); 504 setProtocolRAngleLoc(Loc); 505 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 506 setProtocolLoc(i, Loc); 507 } 508 509 SourceRange AttributedTypeLoc::getLocalSourceRange() const { 510 // Note that this does *not* include the range of the attribute 511 // enclosure, e.g.: 512 // __attribute__((foo(bar))) 513 // ^~~~~~~~~~~~~~~ ~~ 514 // or 515 // [[foo(bar)]] 516 // ^~ ~~ 517 // That enclosure doesn't necessarily belong to a single attribute 518 // anyway. 519 return getAttr() ? getAttr()->getRange() : SourceRange(); 520 } 521 522 SourceRange CountAttributedTypeLoc::getLocalSourceRange() const { 523 return getCountExpr() ? getCountExpr()->getSourceRange() : SourceRange(); 524 } 525 526 SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const { 527 return getAttr() ? getAttr()->getRange() : SourceRange(); 528 } 529 530 void TypeOfTypeLoc::initializeLocal(ASTContext &Context, 531 SourceLocation Loc) { 532 TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> 533 ::initializeLocal(Context, Loc); 534 this->getLocalData()->UnmodifiedTInfo = 535 Context.getTrivialTypeSourceInfo(getUnmodifiedType(), Loc); 536 } 537 538 void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context, 539 SourceLocation Loc) { 540 setKWLoc(Loc); 541 setRParenLoc(Loc); 542 setLParenLoc(Loc); 543 this->setUnderlyingTInfo( 544 Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc)); 545 } 546 547 void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 548 SourceLocation Loc) { 549 if (isEmpty()) 550 return; 551 setElaboratedKeywordLoc(Loc); 552 NestedNameSpecifierLocBuilder Builder; 553 Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); 554 setQualifierLoc(Builder.getWithLocInContext(Context)); 555 } 556 557 void DependentNameTypeLoc::initializeLocal(ASTContext &Context, 558 SourceLocation Loc) { 559 setElaboratedKeywordLoc(Loc); 560 NestedNameSpecifierLocBuilder Builder; 561 Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); 562 setQualifierLoc(Builder.getWithLocInContext(Context)); 563 setNameLoc(Loc); 564 } 565 566 void 567 DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context, 568 SourceLocation Loc) { 569 setElaboratedKeywordLoc(Loc); 570 if (getTypePtr()->getQualifier()) { 571 NestedNameSpecifierLocBuilder Builder; 572 Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); 573 setQualifierLoc(Builder.getWithLocInContext(Context)); 574 } else { 575 setQualifierLoc(NestedNameSpecifierLoc()); 576 } 577 setTemplateKeywordLoc(Loc); 578 setTemplateNameLoc(Loc); 579 setLAngleLoc(Loc); 580 setRAngleLoc(Loc); 581 TemplateSpecializationTypeLoc::initializeArgLocs( 582 Context, getTypePtr()->template_arguments(), getArgInfos(), Loc); 583 } 584 585 void TemplateSpecializationTypeLoc::initializeArgLocs( 586 ASTContext &Context, ArrayRef<TemplateArgument> Args, 587 TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) { 588 for (unsigned i = 0, e = Args.size(); i != e; ++i) { 589 switch (Args[i].getKind()) { 590 case TemplateArgument::Null: 591 llvm_unreachable("Impossible TemplateArgument"); 592 593 case TemplateArgument::Integral: 594 case TemplateArgument::Declaration: 595 case TemplateArgument::NullPtr: 596 case TemplateArgument::StructuralValue: 597 ArgInfos[i] = TemplateArgumentLocInfo(); 598 break; 599 600 case TemplateArgument::Expression: 601 ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr()); 602 break; 603 604 case TemplateArgument::Type: 605 ArgInfos[i] = TemplateArgumentLocInfo( 606 Context.getTrivialTypeSourceInfo(Args[i].getAsType(), 607 Loc)); 608 break; 609 610 case TemplateArgument::Template: 611 case TemplateArgument::TemplateExpansion: { 612 NestedNameSpecifierLocBuilder Builder; 613 TemplateName Template = Args[i].getAsTemplateOrTemplatePattern(); 614 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) 615 Builder.MakeTrivial(Context, DTN->getQualifier(), Loc); 616 else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) 617 Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); 618 619 ArgInfos[i] = TemplateArgumentLocInfo( 620 Context, Builder.getWithLocInContext(Context), Loc, 621 Args[i].getKind() == TemplateArgument::Template ? SourceLocation() 622 : Loc); 623 break; 624 } 625 626 case TemplateArgument::Pack: 627 ArgInfos[i] = TemplateArgumentLocInfo(); 628 break; 629 } 630 } 631 } 632 633 // Builds a ConceptReference where all locations point at the same token, 634 // for use in trivial TypeSourceInfo for constrained AutoType 635 static ConceptReference *createTrivialConceptReference(ASTContext &Context, 636 SourceLocation Loc, 637 const AutoType *AT) { 638 DeclarationNameInfo DNI = 639 DeclarationNameInfo(AT->getTypeConstraintConcept()->getDeclName(), Loc, 640 AT->getTypeConstraintConcept()->getDeclName()); 641 unsigned size = AT->getTypeConstraintArguments().size(); 642 TemplateArgumentLocInfo *TALI = new TemplateArgumentLocInfo[size]; 643 TemplateSpecializationTypeLoc::initializeArgLocs( 644 Context, AT->getTypeConstraintArguments(), TALI, Loc); 645 TemplateArgumentListInfo TAListI; 646 for (unsigned i = 0; i < size; ++i) { 647 TAListI.addArgument( 648 TemplateArgumentLoc(AT->getTypeConstraintArguments()[i], 649 TALI[i])); // TemplateArgumentLocInfo() 650 } 651 652 auto *ConceptRef = ConceptReference::Create( 653 Context, NestedNameSpecifierLoc{}, Loc, DNI, nullptr, 654 AT->getTypeConstraintConcept(), 655 ASTTemplateArgumentListInfo::Create(Context, TAListI)); 656 delete[] TALI; 657 return ConceptRef; 658 } 659 660 void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) { 661 setRParenLoc(Loc); 662 setNameLoc(Loc); 663 setConceptReference(nullptr); 664 if (getTypePtr()->isConstrained()) { 665 setConceptReference( 666 createTrivialConceptReference(Context, Loc, getTypePtr())); 667 } 668 } 669 670 namespace { 671 672 class GetContainedAutoTypeLocVisitor : 673 public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> { 674 public: 675 using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit; 676 677 TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) { 678 return TL; 679 } 680 681 // Only these types can contain the desired 'auto' type. 682 683 TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) { 684 return Visit(T.getNamedTypeLoc()); 685 } 686 687 TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) { 688 return Visit(T.getUnqualifiedLoc()); 689 } 690 691 TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) { 692 return Visit(T.getPointeeLoc()); 693 } 694 695 TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) { 696 return Visit(T.getPointeeLoc()); 697 } 698 699 TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) { 700 return Visit(T.getPointeeLoc()); 701 } 702 703 TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) { 704 return Visit(T.getPointeeLoc()); 705 } 706 707 TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) { 708 return Visit(T.getElementLoc()); 709 } 710 711 TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) { 712 return Visit(T.getReturnLoc()); 713 } 714 715 TypeLoc VisitParenTypeLoc(ParenTypeLoc T) { 716 return Visit(T.getInnerLoc()); 717 } 718 719 TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) { 720 return Visit(T.getModifiedLoc()); 721 } 722 723 TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) { 724 return Visit(T.getWrappedLoc()); 725 } 726 727 TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) { 728 return Visit(T.getInnerLoc()); 729 } 730 731 TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) { 732 return Visit(T.getOriginalLoc()); 733 } 734 735 TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) { 736 return Visit(T.getPatternLoc()); 737 } 738 }; 739 740 } // namespace 741 742 AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const { 743 TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this); 744 if (Res.isNull()) 745 return AutoTypeLoc(); 746 return Res.getAs<AutoTypeLoc>(); 747 } 748 749 SourceLocation TypeLoc::getTemplateKeywordLoc() const { 750 if (const auto TSTL = getAsAdjusted<TemplateSpecializationTypeLoc>()) 751 return TSTL.getTemplateKeywordLoc(); 752 if (const auto DTSTL = 753 getAsAdjusted<DependentTemplateSpecializationTypeLoc>()) 754 return DTSTL.getTemplateKeywordLoc(); 755 return SourceLocation(); 756 } 757