1 //===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===// 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 /// \file 10 /// Defines the clang::TypeLoc interface and its subclasses. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_TYPELOC_H 15 #define LLVM_CLANG_AST_TYPELOC_H 16 17 #include "clang/AST/ASTConcept.h" 18 #include "clang/AST/DeclarationName.h" 19 #include "clang/AST/NestedNameSpecifier.h" 20 #include "clang/AST/TemplateBase.h" 21 #include "clang/AST/Type.h" 22 #include "clang/Basic/LLVM.h" 23 #include "clang/Basic/SourceLocation.h" 24 #include "clang/Basic/Specifiers.h" 25 #include "llvm/ADT/ArrayRef.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/Compiler.h" 28 #include "llvm/Support/MathExtras.h" 29 #include <algorithm> 30 #include <cassert> 31 #include <cstdint> 32 #include <cstring> 33 34 namespace clang { 35 36 class Attr; 37 class ASTContext; 38 class CXXRecordDecl; 39 class ConceptDecl; 40 class Expr; 41 class ObjCInterfaceDecl; 42 class ObjCProtocolDecl; 43 class ObjCTypeParamDecl; 44 class ParmVarDecl; 45 class TemplateTypeParmDecl; 46 class UnqualTypeLoc; 47 class UnresolvedUsingTypenameDecl; 48 49 // Predeclare all the type nodes. 50 #define ABSTRACT_TYPELOC(Class, Base) 51 #define TYPELOC(Class, Base) \ 52 class Class##TypeLoc; 53 #include "clang/AST/TypeLocNodes.def" 54 55 /// Base wrapper for a particular "section" of type source info. 56 /// 57 /// A client should use the TypeLoc subclasses through castAs()/getAs() 58 /// in order to get at the actual information. 59 class TypeLoc { 60 protected: 61 // The correctness of this relies on the property that, for Type *Ty, 62 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 63 const void *Ty = nullptr; 64 void *Data = nullptr; 65 66 public: 67 TypeLoc() = default; 68 TypeLoc(QualType ty, void *opaqueData) 69 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {} 70 TypeLoc(const Type *ty, void *opaqueData) 71 : Ty(ty), Data(opaqueData) {} 72 73 /// Convert to the specified TypeLoc type, asserting that this TypeLoc 74 /// is of the desired type. 75 /// 76 /// \pre T::isKind(*this) 77 template<typename T> 78 T castAs() const { 79 assert(T::isKind(*this)); 80 T t; 81 TypeLoc& tl = t; 82 tl = *this; 83 return t; 84 } 85 86 /// Convert to the specified TypeLoc type, returning a null TypeLoc if 87 /// this TypeLoc is not of the desired type. 88 template<typename T> 89 T getAs() const { 90 if (!T::isKind(*this)) 91 return {}; 92 T t; 93 TypeLoc& tl = t; 94 tl = *this; 95 return t; 96 } 97 98 /// Convert to the specified TypeLoc type, returning a null TypeLoc if 99 /// this TypeLoc is not of the desired type. It will consider type 100 /// adjustments from a type that was written as a T to another type that is 101 /// still canonically a T (ignores parens, attributes, elaborated types, etc). 102 template <typename T> 103 T getAsAdjusted() const; 104 105 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 106 /// except it also defines a Qualified enum that corresponds to the 107 /// QualifiedLoc class. 108 enum TypeLocClass { 109 #define ABSTRACT_TYPE(Class, Base) 110 #define TYPE(Class, Base) \ 111 Class = Type::Class, 112 #include "clang/AST/TypeNodes.inc" 113 Qualified 114 }; 115 116 TypeLocClass getTypeLocClass() const { 117 if (getType().hasLocalQualifiers()) return Qualified; 118 return (TypeLocClass) getType()->getTypeClass(); 119 } 120 121 bool isNull() const { return !Ty; } 122 explicit operator bool() const { return Ty; } 123 124 /// Returns the size of type source info data block for the given type. 125 static unsigned getFullDataSizeForType(QualType Ty); 126 127 /// Returns the alignment of type source info data block for 128 /// the given type. 129 static unsigned getLocalAlignmentForType(QualType Ty); 130 131 /// Get the type for which this source info wrapper provides 132 /// information. 133 QualType getType() const { 134 return QualType::getFromOpaquePtr(Ty); 135 } 136 137 const Type *getTypePtr() const { 138 return QualType::getFromOpaquePtr(Ty).getTypePtr(); 139 } 140 141 /// Get the pointer where source information is stored. 142 void *getOpaqueData() const { 143 return Data; 144 } 145 146 /// Get the begin source location. 147 SourceLocation getBeginLoc() const; 148 149 /// Get the end source location. 150 SourceLocation getEndLoc() const; 151 152 /// Get the full source range. 153 SourceRange getSourceRange() const LLVM_READONLY { 154 return SourceRange(getBeginLoc(), getEndLoc()); 155 } 156 157 158 /// Get the local source range. 159 SourceRange getLocalSourceRange() const { 160 return getLocalSourceRangeImpl(*this); 161 } 162 163 /// Returns the size of the type source info data block. 164 unsigned getFullDataSize() const { 165 return getFullDataSizeForType(getType()); 166 } 167 168 /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 169 /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 170 TypeLoc getNextTypeLoc() const { 171 return getNextTypeLocImpl(*this); 172 } 173 174 /// Skips past any qualifiers, if this is qualified. 175 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 176 177 TypeLoc IgnoreParens() const; 178 179 /// Find a type with the location of an explicit type qualifier. 180 /// 181 /// The result, if non-null, will be one of: 182 /// QualifiedTypeLoc 183 /// AtomicTypeLoc 184 /// AttributedTypeLoc, for those type attributes that behave as qualifiers 185 TypeLoc findExplicitQualifierLoc() const; 186 187 /// Get the typeloc of an AutoType whose type will be deduced for a variable 188 /// with an initializer of this type. This looks through declarators like 189 /// pointer types, but not through decltype or typedefs. 190 AutoTypeLoc getContainedAutoTypeLoc() const; 191 192 /// Get the SourceLocation of the template keyword (if any). 193 SourceLocation getTemplateKeywordLoc() const; 194 195 /// Initializes this to state that every location in this 196 /// type is the given location. 197 /// 198 /// This method exists to provide a simple transition for code that 199 /// relies on location-less types. 200 void initialize(ASTContext &Context, SourceLocation Loc) const { 201 initializeImpl(Context, *this, Loc); 202 } 203 204 /// Initializes this by copying its information from another 205 /// TypeLoc of the same type. 206 void initializeFullCopy(TypeLoc Other) { 207 assert(getType() == Other.getType()); 208 copy(Other); 209 } 210 211 /// Initializes this by copying its information from another 212 /// TypeLoc of the same type. The given size must be the full data 213 /// size. 214 void initializeFullCopy(TypeLoc Other, unsigned Size) { 215 assert(getType() == Other.getType()); 216 assert(getFullDataSize() == Size); 217 copy(Other); 218 } 219 220 /// Copies the other type loc into this one. 221 void copy(TypeLoc other); 222 223 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 224 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 225 } 226 227 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 228 return !(LHS == RHS); 229 } 230 231 /// Find the location of the nullability specifier (__nonnull, 232 /// __nullable, or __null_unspecifier), if there is one. 233 SourceLocation findNullabilityLoc() const; 234 235 void dump() const; 236 void dump(llvm::raw_ostream &, const ASTContext &) const; 237 238 private: 239 static bool isKind(const TypeLoc&) { 240 return true; 241 } 242 243 static void initializeImpl(ASTContext &Context, TypeLoc TL, 244 SourceLocation Loc); 245 static TypeLoc getNextTypeLocImpl(TypeLoc TL); 246 static TypeLoc IgnoreParensImpl(TypeLoc TL); 247 static SourceRange getLocalSourceRangeImpl(TypeLoc TL); 248 }; 249 250 inline TypeSourceInfo::TypeSourceInfo(QualType ty, size_t DataSize) : Ty(ty) { 251 // Init data attached to the object. See getTypeLoc. 252 memset(static_cast<void *>(this + 1), 0, DataSize); 253 } 254 255 /// Return the TypeLoc for a type source info. 256 inline TypeLoc TypeSourceInfo::getTypeLoc() const { 257 // TODO: is this alignment already sufficient? 258 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); 259 } 260 261 /// Wrapper of type source information for a type with 262 /// no direct qualifiers. 263 class UnqualTypeLoc : public TypeLoc { 264 public: 265 UnqualTypeLoc() = default; 266 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 267 268 const Type *getTypePtr() const { 269 return reinterpret_cast<const Type*>(Ty); 270 } 271 272 TypeLocClass getTypeLocClass() const { 273 return (TypeLocClass) getTypePtr()->getTypeClass(); 274 } 275 276 private: 277 friend class TypeLoc; 278 279 static bool isKind(const TypeLoc &TL) { 280 return !TL.getType().hasLocalQualifiers(); 281 } 282 }; 283 284 /// Wrapper of type source information for a type with 285 /// non-trivial direct qualifiers. 286 /// 287 /// Currently, we intentionally do not provide source location for 288 /// type qualifiers. 289 class QualifiedTypeLoc : public TypeLoc { 290 public: 291 SourceRange getLocalSourceRange() const { return {}; } 292 293 UnqualTypeLoc getUnqualifiedLoc() const { 294 unsigned align = 295 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); 296 auto dataInt = reinterpret_cast<uintptr_t>(Data); 297 dataInt = llvm::alignTo(dataInt, align); 298 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt)); 299 } 300 301 /// Initializes the local data of this type source info block to 302 /// provide no information. 303 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 304 // do nothing 305 } 306 307 void copyLocal(TypeLoc other) { 308 // do nothing 309 } 310 311 TypeLoc getNextTypeLoc() const { 312 return getUnqualifiedLoc(); 313 } 314 315 /// Returns the size of the type source info data block that is 316 /// specific to this type. 317 unsigned getLocalDataSize() const { 318 // In fact, we don't currently preserve any location information 319 // for qualifiers. 320 return 0; 321 } 322 323 /// Returns the alignment of the type source info data block that is 324 /// specific to this type. 325 unsigned getLocalDataAlignment() const { 326 // We don't preserve any location information. 327 return 1; 328 } 329 330 private: 331 friend class TypeLoc; 332 333 static bool isKind(const TypeLoc &TL) { 334 return TL.getType().hasLocalQualifiers(); 335 } 336 }; 337 338 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 339 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) 340 return Loc.getUnqualifiedLoc(); 341 return castAs<UnqualTypeLoc>(); 342 } 343 344 /// A metaprogramming base class for TypeLoc classes which correspond 345 /// to a particular Type subclass. It is accepted for a single 346 /// TypeLoc class to correspond to multiple Type classes. 347 /// 348 /// \tparam Base a class from which to derive 349 /// \tparam Derived the class deriving from this one 350 /// \tparam TypeClass the concrete Type subclass associated with this 351 /// location type 352 /// \tparam LocalData the structure type of local location data for 353 /// this type 354 /// 355 /// TypeLocs with non-constant amounts of local data should override 356 /// getExtraLocalDataSize(); getExtraLocalData() will then point to 357 /// this extra memory. 358 /// 359 /// TypeLocs with an inner type should define 360 /// QualType getInnerType() const 361 /// and getInnerTypeLoc() will then point to this inner type's 362 /// location data. 363 /// 364 /// A word about hierarchies: this template is not designed to be 365 /// derived from multiple times in a hierarchy. It is also not 366 /// designed to be used for classes where subtypes might provide 367 /// different amounts of source information. It should be subclassed 368 /// only at the deepest portion of the hierarchy where all children 369 /// have identical source information; if that's an abstract type, 370 /// then further descendents should inherit from 371 /// InheritingConcreteTypeLoc instead. 372 template <class Base, class Derived, class TypeClass, class LocalData> 373 class ConcreteTypeLoc : public Base { 374 friend class TypeLoc; 375 376 const Derived *asDerived() const { 377 return static_cast<const Derived*>(this); 378 } 379 380 static bool isKind(const TypeLoc &TL) { 381 return !TL.getType().hasLocalQualifiers() && 382 Derived::classofType(TL.getTypePtr()); 383 } 384 385 static bool classofType(const Type *Ty) { 386 return TypeClass::classof(Ty); 387 } 388 389 public: 390 unsigned getLocalDataAlignment() const { 391 return std::max(unsigned(alignof(LocalData)), 392 asDerived()->getExtraLocalDataAlignment()); 393 } 394 395 unsigned getLocalDataSize() const { 396 unsigned size = sizeof(LocalData); 397 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 398 size = llvm::alignTo(size, extraAlign); 399 size += asDerived()->getExtraLocalDataSize(); 400 size = llvm::alignTo(size, asDerived()->getLocalDataAlignment()); 401 return size; 402 } 403 404 void copyLocal(Derived other) { 405 // Some subclasses have no data to copy. 406 if (asDerived()->getLocalDataSize() == 0) return; 407 408 // Copy the fixed-sized local data. 409 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData)); 410 411 // Copy the variable-sized local data. We need to do this 412 // separately because the padding in the source and the padding in 413 // the destination might be different. 414 memcpy(getExtraLocalData(), other.getExtraLocalData(), 415 asDerived()->getExtraLocalDataSize()); 416 } 417 418 TypeLoc getNextTypeLoc() const { 419 return getNextTypeLoc(asDerived()->getInnerType()); 420 } 421 422 const TypeClass *getTypePtr() const { 423 return cast<TypeClass>(Base::getTypePtr()); 424 } 425 426 protected: 427 unsigned getExtraLocalDataSize() const { 428 return 0; 429 } 430 431 unsigned getExtraLocalDataAlignment() const { 432 return 1; 433 } 434 435 LocalData *getLocalData() const { 436 return static_cast<LocalData*>(Base::Data); 437 } 438 439 /// Gets a pointer past the Info structure; useful for classes with 440 /// local data that can't be captured in the Info (e.g. because it's 441 /// of variable size). 442 void *getExtraLocalData() const { 443 unsigned size = sizeof(LocalData); 444 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 445 size = llvm::alignTo(size, extraAlign); 446 return reinterpret_cast<char *>(Base::Data) + size; 447 } 448 449 void *getNonLocalData() const { 450 auto data = reinterpret_cast<uintptr_t>(Base::Data); 451 data += asDerived()->getLocalDataSize(); 452 data = llvm::alignTo(data, getNextTypeAlign()); 453 return reinterpret_cast<void*>(data); 454 } 455 456 struct HasNoInnerType {}; 457 HasNoInnerType getInnerType() const { return HasNoInnerType(); } 458 459 TypeLoc getInnerTypeLoc() const { 460 return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 461 } 462 463 private: 464 unsigned getInnerTypeSize() const { 465 return getInnerTypeSize(asDerived()->getInnerType()); 466 } 467 468 unsigned getInnerTypeSize(HasNoInnerType _) const { 469 return 0; 470 } 471 472 unsigned getInnerTypeSize(QualType _) const { 473 return getInnerTypeLoc().getFullDataSize(); 474 } 475 476 unsigned getNextTypeAlign() const { 477 return getNextTypeAlign(asDerived()->getInnerType()); 478 } 479 480 unsigned getNextTypeAlign(HasNoInnerType _) const { 481 return 1; 482 } 483 484 unsigned getNextTypeAlign(QualType T) const { 485 return TypeLoc::getLocalAlignmentForType(T); 486 } 487 488 TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; } 489 490 TypeLoc getNextTypeLoc(QualType T) const { 491 return TypeLoc(T, getNonLocalData()); 492 } 493 }; 494 495 /// A metaprogramming class designed for concrete subtypes of abstract 496 /// types where all subtypes share equivalently-structured source 497 /// information. See the note on ConcreteTypeLoc. 498 template <class Base, class Derived, class TypeClass> 499 class InheritingConcreteTypeLoc : public Base { 500 friend class TypeLoc; 501 502 static bool classofType(const Type *Ty) { 503 return TypeClass::classof(Ty); 504 } 505 506 static bool isKind(const TypeLoc &TL) { 507 return !TL.getType().hasLocalQualifiers() && 508 Derived::classofType(TL.getTypePtr()); 509 } 510 static bool isKind(const UnqualTypeLoc &TL) { 511 return Derived::classofType(TL.getTypePtr()); 512 } 513 514 public: 515 const TypeClass *getTypePtr() const { 516 return cast<TypeClass>(Base::getTypePtr()); 517 } 518 }; 519 520 struct TypeSpecLocInfo { 521 SourceLocation NameLoc; 522 }; 523 524 /// A reasonable base class for TypeLocs that correspond to 525 /// types that are written as a type-specifier. 526 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 527 TypeSpecTypeLoc, 528 Type, 529 TypeSpecLocInfo> { 530 public: 531 enum { 532 LocalDataSize = sizeof(TypeSpecLocInfo), 533 LocalDataAlignment = alignof(TypeSpecLocInfo) 534 }; 535 536 SourceLocation getNameLoc() const { 537 return this->getLocalData()->NameLoc; 538 } 539 540 void setNameLoc(SourceLocation Loc) { 541 this->getLocalData()->NameLoc = Loc; 542 } 543 544 SourceRange getLocalSourceRange() const { 545 return SourceRange(getNameLoc(), getNameLoc()); 546 } 547 548 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 549 setNameLoc(Loc); 550 } 551 552 private: 553 friend class TypeLoc; 554 555 static bool isKind(const TypeLoc &TL); 556 }; 557 558 struct BuiltinLocInfo { 559 SourceRange BuiltinRange; 560 }; 561 562 /// Wrapper for source info for builtin types. 563 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 564 BuiltinTypeLoc, 565 BuiltinType, 566 BuiltinLocInfo> { 567 public: 568 SourceLocation getBuiltinLoc() const { 569 return getLocalData()->BuiltinRange.getBegin(); 570 } 571 572 void setBuiltinLoc(SourceLocation Loc) { 573 getLocalData()->BuiltinRange = Loc; 574 } 575 576 void expandBuiltinRange(SourceRange Range) { 577 SourceRange &BuiltinRange = getLocalData()->BuiltinRange; 578 if (!BuiltinRange.getBegin().isValid()) { 579 BuiltinRange = Range; 580 } else { 581 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin())); 582 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd())); 583 } 584 } 585 586 SourceLocation getNameLoc() const { return getBuiltinLoc(); } 587 588 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 589 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 590 } 591 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 592 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 593 } 594 595 bool needsExtraLocalData() const { 596 BuiltinType::Kind bk = getTypePtr()->getKind(); 597 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) || 598 (bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) || 599 bk == BuiltinType::UChar || bk == BuiltinType::SChar; 600 } 601 602 unsigned getExtraLocalDataSize() const { 603 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 604 } 605 606 unsigned getExtraLocalDataAlignment() const { 607 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1; 608 } 609 610 SourceRange getLocalSourceRange() const { 611 return getLocalData()->BuiltinRange; 612 } 613 614 TypeSpecifierSign getWrittenSignSpec() const { 615 if (needsExtraLocalData()) 616 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 617 else 618 return TypeSpecifierSign::Unspecified; 619 } 620 621 bool hasWrittenSignSpec() const { 622 return getWrittenSignSpec() != TypeSpecifierSign::Unspecified; 623 } 624 625 void setWrittenSignSpec(TypeSpecifierSign written) { 626 if (needsExtraLocalData()) 627 getWrittenBuiltinSpecs().Sign = static_cast<unsigned>(written); 628 } 629 630 TypeSpecifierWidth getWrittenWidthSpec() const { 631 if (needsExtraLocalData()) 632 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 633 else 634 return TypeSpecifierWidth::Unspecified; 635 } 636 637 bool hasWrittenWidthSpec() const { 638 return getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified; 639 } 640 641 void setWrittenWidthSpec(TypeSpecifierWidth written) { 642 if (needsExtraLocalData()) 643 getWrittenBuiltinSpecs().Width = static_cast<unsigned>(written); 644 } 645 646 TypeSpecifierType getWrittenTypeSpec() const; 647 648 bool hasWrittenTypeSpec() const { 649 return getWrittenTypeSpec() != TST_unspecified; 650 } 651 652 void setWrittenTypeSpec(TypeSpecifierType written) { 653 if (needsExtraLocalData()) 654 getWrittenBuiltinSpecs().Type = written; 655 } 656 657 bool hasModeAttr() const { 658 if (needsExtraLocalData()) 659 return getWrittenBuiltinSpecs().ModeAttr; 660 else 661 return false; 662 } 663 664 void setModeAttr(bool written) { 665 if (needsExtraLocalData()) 666 getWrittenBuiltinSpecs().ModeAttr = written; 667 } 668 669 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 670 setBuiltinLoc(Loc); 671 if (needsExtraLocalData()) { 672 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 673 wbs.Sign = static_cast<unsigned>(TypeSpecifierSign::Unspecified); 674 wbs.Width = static_cast<unsigned>(TypeSpecifierWidth::Unspecified); 675 wbs.Type = TST_unspecified; 676 wbs.ModeAttr = false; 677 } 678 } 679 }; 680 681 /// Wrapper for source info for types used via transparent aliases. 682 class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 683 UsingTypeLoc, UsingType> { 684 public: 685 QualType getUnderlyingType() const { 686 return getTypePtr()->getUnderlyingType(); 687 } 688 UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); } 689 }; 690 691 /// Wrapper for source info for typedefs. 692 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 693 TypedefTypeLoc, 694 TypedefType> { 695 public: 696 TypedefNameDecl *getTypedefNameDecl() const { 697 return getTypePtr()->getDecl(); 698 } 699 }; 700 701 /// Wrapper for source info for injected class names of class 702 /// templates. 703 class InjectedClassNameTypeLoc : 704 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 705 InjectedClassNameTypeLoc, 706 InjectedClassNameType> { 707 public: 708 CXXRecordDecl *getDecl() const { 709 return getTypePtr()->getDecl(); 710 } 711 }; 712 713 /// Wrapper for source info for unresolved typename using decls. 714 class UnresolvedUsingTypeLoc : 715 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 716 UnresolvedUsingTypeLoc, 717 UnresolvedUsingType> { 718 public: 719 UnresolvedUsingTypenameDecl *getDecl() const { 720 return getTypePtr()->getDecl(); 721 } 722 }; 723 724 /// Wrapper for source info for tag types. Note that this only 725 /// records source info for the name itself; a type written 'struct foo' 726 /// should be represented as an ElaboratedTypeLoc. We currently 727 /// only do that when C++ is enabled because of the expense of 728 /// creating an ElaboratedType node for so many type references in C. 729 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 730 TagTypeLoc, 731 TagType> { 732 public: 733 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 734 735 /// True if the tag was defined in this type specifier. 736 bool isDefinition() const; 737 }; 738 739 /// Wrapper for source info for record types. 740 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 741 RecordTypeLoc, 742 RecordType> { 743 public: 744 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 745 }; 746 747 /// Wrapper for source info for enum types. 748 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 749 EnumTypeLoc, 750 EnumType> { 751 public: 752 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 753 }; 754 755 /// Wrapper for template type parameters. 756 class TemplateTypeParmTypeLoc : 757 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 758 TemplateTypeParmTypeLoc, 759 TemplateTypeParmType> { 760 public: 761 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 762 }; 763 764 struct ObjCTypeParamTypeLocInfo { 765 SourceLocation NameLoc; 766 }; 767 768 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for 769 /// protocol qualifiers are stored after Info. 770 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 771 ObjCTypeParamTypeLoc, 772 ObjCTypeParamType, 773 ObjCTypeParamTypeLocInfo> { 774 // SourceLocations are stored after Info, one for each protocol qualifier. 775 SourceLocation *getProtocolLocArray() const { 776 return (SourceLocation*)this->getExtraLocalData() + 2; 777 } 778 779 public: 780 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); } 781 782 SourceLocation getNameLoc() const { 783 return this->getLocalData()->NameLoc; 784 } 785 786 void setNameLoc(SourceLocation Loc) { 787 this->getLocalData()->NameLoc = Loc; 788 } 789 790 SourceLocation getProtocolLAngleLoc() const { 791 return getNumProtocols() ? 792 *((SourceLocation*)this->getExtraLocalData()) : 793 SourceLocation(); 794 } 795 796 void setProtocolLAngleLoc(SourceLocation Loc) { 797 *((SourceLocation*)this->getExtraLocalData()) = Loc; 798 } 799 800 SourceLocation getProtocolRAngleLoc() const { 801 return getNumProtocols() ? 802 *((SourceLocation*)this->getExtraLocalData() + 1) : 803 SourceLocation(); 804 } 805 806 void setProtocolRAngleLoc(SourceLocation Loc) { 807 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc; 808 } 809 810 unsigned getNumProtocols() const { 811 return this->getTypePtr()->getNumProtocols(); 812 } 813 814 SourceLocation getProtocolLoc(unsigned i) const { 815 assert(i < getNumProtocols() && "Index is out of bounds!"); 816 return getProtocolLocArray()[i]; 817 } 818 819 void setProtocolLoc(unsigned i, SourceLocation Loc) { 820 assert(i < getNumProtocols() && "Index is out of bounds!"); 821 getProtocolLocArray()[i] = Loc; 822 } 823 824 ObjCProtocolDecl *getProtocol(unsigned i) const { 825 assert(i < getNumProtocols() && "Index is out of bounds!"); 826 return *(this->getTypePtr()->qual_begin() + i); 827 } 828 829 ArrayRef<SourceLocation> getProtocolLocs() const { 830 return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols()); 831 } 832 833 void initializeLocal(ASTContext &Context, SourceLocation Loc); 834 835 unsigned getExtraLocalDataSize() const { 836 if (!this->getNumProtocols()) return 0; 837 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc 838 // as well. 839 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ; 840 } 841 842 unsigned getExtraLocalDataAlignment() const { 843 return alignof(SourceLocation); 844 } 845 846 SourceRange getLocalSourceRange() const { 847 SourceLocation start = getNameLoc(); 848 SourceLocation end = getProtocolRAngleLoc(); 849 if (end.isInvalid()) return SourceRange(start, start); 850 return SourceRange(start, end); 851 } 852 }; 853 854 /// Wrapper for substituted template type parameters. 855 class SubstTemplateTypeParmTypeLoc : 856 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 857 SubstTemplateTypeParmTypeLoc, 858 SubstTemplateTypeParmType> { 859 }; 860 861 /// Wrapper for substituted template type parameters. 862 class SubstTemplateTypeParmPackTypeLoc : 863 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 864 SubstTemplateTypeParmPackTypeLoc, 865 SubstTemplateTypeParmPackType> { 866 }; 867 868 struct AttributedLocInfo { 869 const Attr *TypeAttr; 870 }; 871 872 /// Type source information for an attributed type. 873 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 874 AttributedTypeLoc, 875 AttributedType, 876 AttributedLocInfo> { 877 public: 878 attr::Kind getAttrKind() const { 879 return getTypePtr()->getAttrKind(); 880 } 881 882 bool isQualifier() const { 883 return getTypePtr()->isQualifier(); 884 } 885 886 /// The modified type, which is generally canonically different from 887 /// the attribute type. 888 /// int main(int, char**) __attribute__((noreturn)) 889 /// ~~~ ~~~~~~~~~~~~~ 890 TypeLoc getModifiedLoc() const { 891 return getInnerTypeLoc(); 892 } 893 894 TypeLoc getEquivalentTypeLoc() const { 895 return TypeLoc(getTypePtr()->getEquivalentType(), getNonLocalData()); 896 } 897 898 /// The type attribute. 899 const Attr *getAttr() const { 900 return getLocalData()->TypeAttr; 901 } 902 void setAttr(const Attr *A) { 903 getLocalData()->TypeAttr = A; 904 } 905 906 template<typename T> const T *getAttrAs() { 907 return dyn_cast_or_null<T>(getAttr()); 908 } 909 910 SourceRange getLocalSourceRange() const; 911 912 void initializeLocal(ASTContext &Context, SourceLocation loc) { 913 setAttr(nullptr); 914 } 915 916 QualType getInnerType() const { 917 return getTypePtr()->getModifiedType(); 918 } 919 }; 920 921 struct BTFTagAttributedLocInfo {}; // Nothing. 922 923 /// Type source information for an btf_tag attributed type. 924 class BTFTagAttributedTypeLoc 925 : public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc, 926 BTFTagAttributedType, BTFTagAttributedLocInfo> { 927 public: 928 TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); } 929 930 /// The btf_type_tag attribute. 931 const BTFTypeTagAttr *getAttr() const { return getTypePtr()->getAttr(); } 932 933 template <typename T> T *getAttrAs() { 934 return dyn_cast_or_null<T>(getAttr()); 935 } 936 937 SourceRange getLocalSourceRange() const; 938 939 void initializeLocal(ASTContext &Context, SourceLocation loc) {} 940 941 QualType getInnerType() const { return getTypePtr()->getWrappedType(); } 942 }; 943 944 struct HLSLAttributedResourceLocInfo { 945 SourceRange Range; 946 TypeSourceInfo *ContainedTyInfo; 947 }; 948 949 /// Type source information for HLSL attributed resource type. 950 class HLSLAttributedResourceTypeLoc 951 : public ConcreteTypeLoc<UnqualTypeLoc, HLSLAttributedResourceTypeLoc, 952 HLSLAttributedResourceType, 953 HLSLAttributedResourceLocInfo> { 954 public: 955 TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); } 956 957 TypeSourceInfo *getContainedTypeSourceInfo() const { 958 return getLocalData()->ContainedTyInfo; 959 } 960 void setContainedTypeSourceInfo(TypeSourceInfo *TSI) const { 961 getLocalData()->ContainedTyInfo = TSI; 962 } 963 964 void setSourceRange(const SourceRange &R) { getLocalData()->Range = R; } 965 SourceRange getLocalSourceRange() const { return getLocalData()->Range; } 966 void initializeLocal(ASTContext &Context, SourceLocation loc) { 967 setSourceRange(SourceRange()); 968 } 969 QualType getInnerType() const { return getTypePtr()->getWrappedType(); } 970 unsigned getLocalDataSize() const { 971 return sizeof(HLSLAttributedResourceLocInfo); 972 } 973 }; 974 975 struct ObjCObjectTypeLocInfo { 976 SourceLocation TypeArgsLAngleLoc; 977 SourceLocation TypeArgsRAngleLoc; 978 SourceLocation ProtocolLAngleLoc; 979 SourceLocation ProtocolRAngleLoc; 980 bool HasBaseTypeAsWritten; 981 }; 982 983 // A helper class for defining ObjC TypeLocs that can qualified with 984 // protocols. 985 // 986 // TypeClass basically has to be either ObjCInterfaceType or 987 // ObjCObjectPointerType. 988 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 989 ObjCObjectTypeLoc, 990 ObjCObjectType, 991 ObjCObjectTypeLocInfo> { 992 // TypeSourceInfo*'s are stored after Info, one for each type argument. 993 TypeSourceInfo **getTypeArgLocArray() const { 994 return (TypeSourceInfo**)this->getExtraLocalData(); 995 } 996 997 // SourceLocations are stored after the type argument information, one for 998 // each Protocol. 999 SourceLocation *getProtocolLocArray() const { 1000 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs()); 1001 } 1002 1003 public: 1004 SourceLocation getTypeArgsLAngleLoc() const { 1005 return this->getLocalData()->TypeArgsLAngleLoc; 1006 } 1007 1008 void setTypeArgsLAngleLoc(SourceLocation Loc) { 1009 this->getLocalData()->TypeArgsLAngleLoc = Loc; 1010 } 1011 1012 SourceLocation getTypeArgsRAngleLoc() const { 1013 return this->getLocalData()->TypeArgsRAngleLoc; 1014 } 1015 1016 void setTypeArgsRAngleLoc(SourceLocation Loc) { 1017 this->getLocalData()->TypeArgsRAngleLoc = Loc; 1018 } 1019 1020 unsigned getNumTypeArgs() const { 1021 return this->getTypePtr()->getTypeArgsAsWritten().size(); 1022 } 1023 1024 TypeSourceInfo *getTypeArgTInfo(unsigned i) const { 1025 assert(i < getNumTypeArgs() && "Index is out of bounds!"); 1026 return getTypeArgLocArray()[i]; 1027 } 1028 1029 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) { 1030 assert(i < getNumTypeArgs() && "Index is out of bounds!"); 1031 getTypeArgLocArray()[i] = TInfo; 1032 } 1033 1034 SourceLocation getProtocolLAngleLoc() const { 1035 return this->getLocalData()->ProtocolLAngleLoc; 1036 } 1037 1038 void setProtocolLAngleLoc(SourceLocation Loc) { 1039 this->getLocalData()->ProtocolLAngleLoc = Loc; 1040 } 1041 1042 SourceLocation getProtocolRAngleLoc() const { 1043 return this->getLocalData()->ProtocolRAngleLoc; 1044 } 1045 1046 void setProtocolRAngleLoc(SourceLocation Loc) { 1047 this->getLocalData()->ProtocolRAngleLoc = Loc; 1048 } 1049 1050 unsigned getNumProtocols() const { 1051 return this->getTypePtr()->getNumProtocols(); 1052 } 1053 1054 SourceLocation getProtocolLoc(unsigned i) const { 1055 assert(i < getNumProtocols() && "Index is out of bounds!"); 1056 return getProtocolLocArray()[i]; 1057 } 1058 1059 void setProtocolLoc(unsigned i, SourceLocation Loc) { 1060 assert(i < getNumProtocols() && "Index is out of bounds!"); 1061 getProtocolLocArray()[i] = Loc; 1062 } 1063 1064 ObjCProtocolDecl *getProtocol(unsigned i) const { 1065 assert(i < getNumProtocols() && "Index is out of bounds!"); 1066 return *(this->getTypePtr()->qual_begin() + i); 1067 } 1068 1069 1070 ArrayRef<SourceLocation> getProtocolLocs() const { 1071 return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols()); 1072 } 1073 1074 bool hasBaseTypeAsWritten() const { 1075 return getLocalData()->HasBaseTypeAsWritten; 1076 } 1077 1078 void setHasBaseTypeAsWritten(bool HasBaseType) { 1079 getLocalData()->HasBaseTypeAsWritten = HasBaseType; 1080 } 1081 1082 TypeLoc getBaseLoc() const { 1083 return getInnerTypeLoc(); 1084 } 1085 1086 SourceRange getLocalSourceRange() const { 1087 SourceLocation start = getTypeArgsLAngleLoc(); 1088 if (start.isInvalid()) 1089 start = getProtocolLAngleLoc(); 1090 SourceLocation end = getProtocolRAngleLoc(); 1091 if (end.isInvalid()) 1092 end = getTypeArgsRAngleLoc(); 1093 return SourceRange(start, end); 1094 } 1095 1096 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1097 1098 unsigned getExtraLocalDataSize() const { 1099 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *) 1100 + this->getNumProtocols() * sizeof(SourceLocation); 1101 } 1102 1103 unsigned getExtraLocalDataAlignment() const { 1104 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *), 1105 "not enough alignment for tail-allocated data"); 1106 return alignof(TypeSourceInfo *); 1107 } 1108 1109 QualType getInnerType() const { 1110 return getTypePtr()->getBaseType(); 1111 } 1112 }; 1113 1114 struct ObjCInterfaceLocInfo { 1115 SourceLocation NameLoc; 1116 SourceLocation NameEndLoc; 1117 }; 1118 1119 /// Wrapper for source info for ObjC interfaces. 1120 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 1121 ObjCInterfaceTypeLoc, 1122 ObjCInterfaceType, 1123 ObjCInterfaceLocInfo> { 1124 public: 1125 ObjCInterfaceDecl *getIFaceDecl() const { 1126 return getTypePtr()->getDecl(); 1127 } 1128 1129 SourceLocation getNameLoc() const { 1130 return getLocalData()->NameLoc; 1131 } 1132 1133 void setNameLoc(SourceLocation Loc) { 1134 getLocalData()->NameLoc = Loc; 1135 } 1136 1137 SourceRange getLocalSourceRange() const { 1138 return SourceRange(getNameLoc(), getNameEndLoc()); 1139 } 1140 1141 SourceLocation getNameEndLoc() const { 1142 return getLocalData()->NameEndLoc; 1143 } 1144 1145 void setNameEndLoc(SourceLocation Loc) { 1146 getLocalData()->NameEndLoc = Loc; 1147 } 1148 1149 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1150 setNameLoc(Loc); 1151 setNameEndLoc(Loc); 1152 } 1153 }; 1154 1155 struct BoundsAttributedLocInfo {}; 1156 class BoundsAttributedTypeLoc 1157 : public ConcreteTypeLoc<UnqualTypeLoc, BoundsAttributedTypeLoc, 1158 BoundsAttributedType, BoundsAttributedLocInfo> { 1159 public: 1160 TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } 1161 QualType getInnerType() const { return getTypePtr()->desugar(); } 1162 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1163 // nothing to do 1164 } 1165 // LocalData is empty and TypeLocBuilder doesn't handle DataSize 1. 1166 unsigned getLocalDataSize() const { return 0; } 1167 }; 1168 1169 class CountAttributedTypeLoc final 1170 : public InheritingConcreteTypeLoc<BoundsAttributedTypeLoc, 1171 CountAttributedTypeLoc, 1172 CountAttributedType> { 1173 public: 1174 Expr *getCountExpr() const { return getTypePtr()->getCountExpr(); } 1175 bool isCountInBytes() const { return getTypePtr()->isCountInBytes(); } 1176 bool isOrNull() const { return getTypePtr()->isOrNull(); } 1177 1178 SourceRange getLocalSourceRange() const; 1179 }; 1180 1181 struct MacroQualifiedLocInfo { 1182 SourceLocation ExpansionLoc; 1183 }; 1184 1185 class MacroQualifiedTypeLoc 1186 : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc, 1187 MacroQualifiedType, MacroQualifiedLocInfo> { 1188 public: 1189 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1190 setExpansionLoc(Loc); 1191 } 1192 1193 TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } 1194 1195 const IdentifierInfo *getMacroIdentifier() const { 1196 return getTypePtr()->getMacroIdentifier(); 1197 } 1198 1199 SourceLocation getExpansionLoc() const { 1200 return this->getLocalData()->ExpansionLoc; 1201 } 1202 1203 void setExpansionLoc(SourceLocation Loc) { 1204 this->getLocalData()->ExpansionLoc = Loc; 1205 } 1206 1207 QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); } 1208 1209 SourceRange getLocalSourceRange() const { 1210 return getInnerLoc().getLocalSourceRange(); 1211 } 1212 }; 1213 1214 struct ParenLocInfo { 1215 SourceLocation LParenLoc; 1216 SourceLocation RParenLoc; 1217 }; 1218 1219 class ParenTypeLoc 1220 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 1221 ParenLocInfo> { 1222 public: 1223 SourceLocation getLParenLoc() const { 1224 return this->getLocalData()->LParenLoc; 1225 } 1226 1227 SourceLocation getRParenLoc() const { 1228 return this->getLocalData()->RParenLoc; 1229 } 1230 1231 void setLParenLoc(SourceLocation Loc) { 1232 this->getLocalData()->LParenLoc = Loc; 1233 } 1234 1235 void setRParenLoc(SourceLocation Loc) { 1236 this->getLocalData()->RParenLoc = Loc; 1237 } 1238 1239 SourceRange getLocalSourceRange() const { 1240 return SourceRange(getLParenLoc(), getRParenLoc()); 1241 } 1242 1243 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1244 setLParenLoc(Loc); 1245 setRParenLoc(Loc); 1246 } 1247 1248 TypeLoc getInnerLoc() const { 1249 return getInnerTypeLoc(); 1250 } 1251 1252 QualType getInnerType() const { 1253 return this->getTypePtr()->getInnerType(); 1254 } 1255 }; 1256 1257 inline TypeLoc TypeLoc::IgnoreParens() const { 1258 if (ParenTypeLoc::isKind(*this)) 1259 return IgnoreParensImpl(*this); 1260 return *this; 1261 } 1262 1263 struct AdjustedLocInfo {}; // Nothing. 1264 1265 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc, 1266 AdjustedType, AdjustedLocInfo> { 1267 public: 1268 TypeLoc getOriginalLoc() const { 1269 return getInnerTypeLoc(); 1270 } 1271 1272 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1273 // do nothing 1274 } 1275 1276 QualType getInnerType() const { 1277 // The inner type is the undecayed type, since that's what we have source 1278 // location information for. 1279 return getTypePtr()->getOriginalType(); 1280 } 1281 1282 SourceRange getLocalSourceRange() const { return {}; } 1283 1284 unsigned getLocalDataSize() const { 1285 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique 1286 // anyway. TypeLocBuilder can't handle data sizes of 1. 1287 return 0; // No data. 1288 } 1289 }; 1290 1291 /// Wrapper for source info for pointers decayed from arrays and 1292 /// functions. 1293 class DecayedTypeLoc : public InheritingConcreteTypeLoc< 1294 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> { 1295 }; 1296 1297 struct PointerLikeLocInfo { 1298 SourceLocation StarLoc; 1299 }; 1300 1301 /// A base class for 1302 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 1303 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 1304 TypeClass, LocalData> { 1305 public: 1306 SourceLocation getSigilLoc() const { 1307 return this->getLocalData()->StarLoc; 1308 } 1309 1310 void setSigilLoc(SourceLocation Loc) { 1311 this->getLocalData()->StarLoc = Loc; 1312 } 1313 1314 TypeLoc getPointeeLoc() const { 1315 return this->getInnerTypeLoc(); 1316 } 1317 1318 SourceRange getLocalSourceRange() const { 1319 return SourceRange(getSigilLoc(), getSigilLoc()); 1320 } 1321 1322 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1323 setSigilLoc(Loc); 1324 } 1325 1326 QualType getInnerType() const { 1327 return this->getTypePtr()->getPointeeType(); 1328 } 1329 }; 1330 1331 /// Wrapper for source info for pointers. 1332 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 1333 PointerType> { 1334 public: 1335 SourceLocation getStarLoc() const { 1336 return getSigilLoc(); 1337 } 1338 1339 void setStarLoc(SourceLocation Loc) { 1340 setSigilLoc(Loc); 1341 } 1342 }; 1343 1344 /// Wrapper for source info for block pointers. 1345 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 1346 BlockPointerType> { 1347 public: 1348 SourceLocation getCaretLoc() const { 1349 return getSigilLoc(); 1350 } 1351 1352 void setCaretLoc(SourceLocation Loc) { 1353 setSigilLoc(Loc); 1354 } 1355 }; 1356 1357 struct MemberPointerLocInfo : public PointerLikeLocInfo { 1358 TypeSourceInfo *ClassTInfo; 1359 }; 1360 1361 /// Wrapper for source info for member pointers. 1362 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 1363 MemberPointerType, 1364 MemberPointerLocInfo> { 1365 public: 1366 SourceLocation getStarLoc() const { 1367 return getSigilLoc(); 1368 } 1369 1370 void setStarLoc(SourceLocation Loc) { 1371 setSigilLoc(Loc); 1372 } 1373 1374 const Type *getClass() const { 1375 return getTypePtr()->getClass(); 1376 } 1377 1378 TypeSourceInfo *getClassTInfo() const { 1379 return getLocalData()->ClassTInfo; 1380 } 1381 1382 void setClassTInfo(TypeSourceInfo* TI) { 1383 getLocalData()->ClassTInfo = TI; 1384 } 1385 1386 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1387 setSigilLoc(Loc); 1388 setClassTInfo(nullptr); 1389 } 1390 1391 SourceRange getLocalSourceRange() const { 1392 if (TypeSourceInfo *TI = getClassTInfo()) 1393 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 1394 else 1395 return SourceRange(getStarLoc()); 1396 } 1397 }; 1398 1399 /// Wraps an ObjCPointerType with source location information. 1400 class ObjCObjectPointerTypeLoc : 1401 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1402 ObjCObjectPointerType> { 1403 public: 1404 SourceLocation getStarLoc() const { 1405 return getSigilLoc(); 1406 } 1407 1408 void setStarLoc(SourceLocation Loc) { 1409 setSigilLoc(Loc); 1410 } 1411 }; 1412 1413 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1414 ReferenceType> { 1415 public: 1416 QualType getInnerType() const { 1417 return getTypePtr()->getPointeeTypeAsWritten(); 1418 } 1419 }; 1420 1421 class LValueReferenceTypeLoc : 1422 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1423 LValueReferenceTypeLoc, 1424 LValueReferenceType> { 1425 public: 1426 SourceLocation getAmpLoc() const { 1427 return getSigilLoc(); 1428 } 1429 1430 void setAmpLoc(SourceLocation Loc) { 1431 setSigilLoc(Loc); 1432 } 1433 }; 1434 1435 class RValueReferenceTypeLoc : 1436 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1437 RValueReferenceTypeLoc, 1438 RValueReferenceType> { 1439 public: 1440 SourceLocation getAmpAmpLoc() const { 1441 return getSigilLoc(); 1442 } 1443 1444 void setAmpAmpLoc(SourceLocation Loc) { 1445 setSigilLoc(Loc); 1446 } 1447 }; 1448 1449 struct FunctionLocInfo { 1450 SourceLocation LocalRangeBegin; 1451 SourceLocation LParenLoc; 1452 SourceLocation RParenLoc; 1453 SourceLocation LocalRangeEnd; 1454 }; 1455 1456 /// Wrapper for source info for functions. 1457 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1458 FunctionTypeLoc, 1459 FunctionType, 1460 FunctionLocInfo> { 1461 bool hasExceptionSpec() const { 1462 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) { 1463 return FPT->hasExceptionSpec(); 1464 } 1465 return false; 1466 } 1467 1468 SourceRange *getExceptionSpecRangePtr() const { 1469 assert(hasExceptionSpec() && "No exception spec range"); 1470 // After the Info comes the ParmVarDecl array, and after that comes the 1471 // exception specification information. 1472 return (SourceRange *)(getParmArray() + getNumParams()); 1473 } 1474 1475 public: 1476 SourceLocation getLocalRangeBegin() const { 1477 return getLocalData()->LocalRangeBegin; 1478 } 1479 1480 void setLocalRangeBegin(SourceLocation L) { 1481 getLocalData()->LocalRangeBegin = L; 1482 } 1483 1484 SourceLocation getLocalRangeEnd() const { 1485 return getLocalData()->LocalRangeEnd; 1486 } 1487 1488 void setLocalRangeEnd(SourceLocation L) { 1489 getLocalData()->LocalRangeEnd = L; 1490 } 1491 1492 SourceLocation getLParenLoc() const { 1493 return this->getLocalData()->LParenLoc; 1494 } 1495 1496 void setLParenLoc(SourceLocation Loc) { 1497 this->getLocalData()->LParenLoc = Loc; 1498 } 1499 1500 SourceLocation getRParenLoc() const { 1501 return this->getLocalData()->RParenLoc; 1502 } 1503 1504 void setRParenLoc(SourceLocation Loc) { 1505 this->getLocalData()->RParenLoc = Loc; 1506 } 1507 1508 SourceRange getParensRange() const { 1509 return SourceRange(getLParenLoc(), getRParenLoc()); 1510 } 1511 1512 SourceRange getExceptionSpecRange() const { 1513 if (hasExceptionSpec()) 1514 return *getExceptionSpecRangePtr(); 1515 return {}; 1516 } 1517 1518 void setExceptionSpecRange(SourceRange R) { 1519 if (hasExceptionSpec()) 1520 *getExceptionSpecRangePtr() = R; 1521 } 1522 1523 ArrayRef<ParmVarDecl *> getParams() const { 1524 return llvm::ArrayRef(getParmArray(), getNumParams()); 1525 } 1526 1527 // ParmVarDecls* are stored after Info, one for each parameter. 1528 ParmVarDecl **getParmArray() const { 1529 return (ParmVarDecl**) getExtraLocalData(); 1530 } 1531 1532 unsigned getNumParams() const { 1533 if (isa<FunctionNoProtoType>(getTypePtr())) 1534 return 0; 1535 return cast<FunctionProtoType>(getTypePtr())->getNumParams(); 1536 } 1537 1538 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; } 1539 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1540 1541 TypeLoc getReturnLoc() const { 1542 return getInnerTypeLoc(); 1543 } 1544 1545 SourceRange getLocalSourceRange() const { 1546 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1547 } 1548 1549 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1550 setLocalRangeBegin(Loc); 1551 setLParenLoc(Loc); 1552 setRParenLoc(Loc); 1553 setLocalRangeEnd(Loc); 1554 for (unsigned i = 0, e = getNumParams(); i != e; ++i) 1555 setParam(i, nullptr); 1556 if (hasExceptionSpec()) 1557 setExceptionSpecRange(Loc); 1558 } 1559 1560 /// Returns the size of the type source info data block that is 1561 /// specific to this type. 1562 unsigned getExtraLocalDataSize() const { 1563 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0; 1564 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize; 1565 } 1566 1567 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); } 1568 1569 QualType getInnerType() const { return getTypePtr()->getReturnType(); } 1570 }; 1571 1572 class FunctionProtoTypeLoc : 1573 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1574 FunctionProtoTypeLoc, 1575 FunctionProtoType> { 1576 }; 1577 1578 class FunctionNoProtoTypeLoc : 1579 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1580 FunctionNoProtoTypeLoc, 1581 FunctionNoProtoType> { 1582 }; 1583 1584 struct ArrayLocInfo { 1585 SourceLocation LBracketLoc, RBracketLoc; 1586 Expr *Size; 1587 }; 1588 1589 /// Wrapper for source info for arrays. 1590 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1591 ArrayTypeLoc, 1592 ArrayType, 1593 ArrayLocInfo> { 1594 public: 1595 SourceLocation getLBracketLoc() const { 1596 return getLocalData()->LBracketLoc; 1597 } 1598 1599 void setLBracketLoc(SourceLocation Loc) { 1600 getLocalData()->LBracketLoc = Loc; 1601 } 1602 1603 SourceLocation getRBracketLoc() const { 1604 return getLocalData()->RBracketLoc; 1605 } 1606 1607 void setRBracketLoc(SourceLocation Loc) { 1608 getLocalData()->RBracketLoc = Loc; 1609 } 1610 1611 SourceRange getBracketsRange() const { 1612 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1613 } 1614 1615 Expr *getSizeExpr() const { 1616 return getLocalData()->Size; 1617 } 1618 1619 void setSizeExpr(Expr *Size) { 1620 getLocalData()->Size = Size; 1621 } 1622 1623 TypeLoc getElementLoc() const { 1624 return getInnerTypeLoc(); 1625 } 1626 1627 SourceRange getLocalSourceRange() const { 1628 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1629 } 1630 1631 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1632 setLBracketLoc(Loc); 1633 setRBracketLoc(Loc); 1634 setSizeExpr(nullptr); 1635 } 1636 1637 QualType getInnerType() const { return getTypePtr()->getElementType(); } 1638 }; 1639 1640 class ConstantArrayTypeLoc : 1641 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1642 ConstantArrayTypeLoc, 1643 ConstantArrayType> { 1644 }; 1645 1646 /// Wrapper for source info for array parameter types. 1647 class ArrayParameterTypeLoc 1648 : public InheritingConcreteTypeLoc< 1649 ConstantArrayTypeLoc, ArrayParameterTypeLoc, ArrayParameterType> {}; 1650 1651 class IncompleteArrayTypeLoc : 1652 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1653 IncompleteArrayTypeLoc, 1654 IncompleteArrayType> { 1655 }; 1656 1657 class DependentSizedArrayTypeLoc : 1658 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1659 DependentSizedArrayTypeLoc, 1660 DependentSizedArrayType> { 1661 public: 1662 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1663 ArrayTypeLoc::initializeLocal(Context, Loc); 1664 setSizeExpr(getTypePtr()->getSizeExpr()); 1665 } 1666 }; 1667 1668 class VariableArrayTypeLoc : 1669 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1670 VariableArrayTypeLoc, 1671 VariableArrayType> { 1672 }; 1673 1674 // Location information for a TemplateName. Rudimentary for now. 1675 struct TemplateNameLocInfo { 1676 SourceLocation NameLoc; 1677 }; 1678 1679 struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1680 SourceLocation TemplateKWLoc; 1681 SourceLocation LAngleLoc; 1682 SourceLocation RAngleLoc; 1683 }; 1684 1685 class TemplateSpecializationTypeLoc : 1686 public ConcreteTypeLoc<UnqualTypeLoc, 1687 TemplateSpecializationTypeLoc, 1688 TemplateSpecializationType, 1689 TemplateSpecializationLocInfo> { 1690 public: 1691 SourceLocation getTemplateKeywordLoc() const { 1692 return getLocalData()->TemplateKWLoc; 1693 } 1694 1695 void setTemplateKeywordLoc(SourceLocation Loc) { 1696 getLocalData()->TemplateKWLoc = Loc; 1697 } 1698 1699 SourceLocation getLAngleLoc() const { 1700 return getLocalData()->LAngleLoc; 1701 } 1702 1703 void setLAngleLoc(SourceLocation Loc) { 1704 getLocalData()->LAngleLoc = Loc; 1705 } 1706 1707 SourceLocation getRAngleLoc() const { 1708 return getLocalData()->RAngleLoc; 1709 } 1710 1711 void setRAngleLoc(SourceLocation Loc) { 1712 getLocalData()->RAngleLoc = Loc; 1713 } 1714 1715 unsigned getNumArgs() const { 1716 return getTypePtr()->template_arguments().size(); 1717 } 1718 1719 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1720 getArgInfos()[i] = AI; 1721 } 1722 1723 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1724 return getArgInfos()[i]; 1725 } 1726 1727 TemplateArgumentLoc getArgLoc(unsigned i) const { 1728 return TemplateArgumentLoc(getTypePtr()->template_arguments()[i], 1729 getArgLocInfo(i)); 1730 } 1731 1732 SourceLocation getTemplateNameLoc() const { 1733 return getLocalData()->NameLoc; 1734 } 1735 1736 void setTemplateNameLoc(SourceLocation Loc) { 1737 getLocalData()->NameLoc = Loc; 1738 } 1739 1740 /// - Copy the location information from the given info. 1741 void copy(TemplateSpecializationTypeLoc Loc) { 1742 unsigned size = getFullDataSize(); 1743 assert(size == Loc.getFullDataSize()); 1744 1745 // We're potentially copying Expr references here. We don't 1746 // bother retaining them because TypeSourceInfos live forever, so 1747 // as long as the Expr was retained when originally written into 1748 // the TypeLoc, we're okay. 1749 memcpy(Data, Loc.Data, size); 1750 } 1751 1752 SourceRange getLocalSourceRange() const { 1753 if (getTemplateKeywordLoc().isValid()) 1754 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1755 else 1756 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1757 } 1758 1759 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1760 setTemplateKeywordLoc(SourceLocation()); 1761 setTemplateNameLoc(Loc); 1762 setLAngleLoc(Loc); 1763 setRAngleLoc(Loc); 1764 initializeArgLocs(Context, getTypePtr()->template_arguments(), 1765 getArgInfos(), Loc); 1766 } 1767 1768 static void initializeArgLocs(ASTContext &Context, 1769 ArrayRef<TemplateArgument> Args, 1770 TemplateArgumentLocInfo *ArgInfos, 1771 SourceLocation Loc); 1772 1773 unsigned getExtraLocalDataSize() const { 1774 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1775 } 1776 1777 unsigned getExtraLocalDataAlignment() const { 1778 return alignof(TemplateArgumentLocInfo); 1779 } 1780 1781 private: 1782 TemplateArgumentLocInfo *getArgInfos() const { 1783 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1784 } 1785 }; 1786 1787 struct DependentAddressSpaceLocInfo { 1788 Expr *ExprOperand; 1789 SourceRange OperandParens; 1790 SourceLocation AttrLoc; 1791 }; 1792 1793 class DependentAddressSpaceTypeLoc 1794 : public ConcreteTypeLoc<UnqualTypeLoc, 1795 DependentAddressSpaceTypeLoc, 1796 DependentAddressSpaceType, 1797 DependentAddressSpaceLocInfo> { 1798 public: 1799 /// The location of the attribute name, i.e. 1800 /// int * __attribute__((address_space(11))) 1801 /// ^~~~~~~~~~~~~ 1802 SourceLocation getAttrNameLoc() const { 1803 return getLocalData()->AttrLoc; 1804 } 1805 void setAttrNameLoc(SourceLocation loc) { 1806 getLocalData()->AttrLoc = loc; 1807 } 1808 1809 /// The attribute's expression operand, if it has one. 1810 /// int * __attribute__((address_space(11))) 1811 /// ^~ 1812 Expr *getAttrExprOperand() const { 1813 return getLocalData()->ExprOperand; 1814 } 1815 void setAttrExprOperand(Expr *e) { 1816 getLocalData()->ExprOperand = e; 1817 } 1818 1819 /// The location of the parentheses around the operand, if there is 1820 /// an operand. 1821 /// int * __attribute__((address_space(11))) 1822 /// ^ ^ 1823 SourceRange getAttrOperandParensRange() const { 1824 return getLocalData()->OperandParens; 1825 } 1826 void setAttrOperandParensRange(SourceRange range) { 1827 getLocalData()->OperandParens = range; 1828 } 1829 1830 SourceRange getLocalSourceRange() const { 1831 SourceRange range(getAttrNameLoc()); 1832 range.setEnd(getAttrOperandParensRange().getEnd()); 1833 return range; 1834 } 1835 1836 /// Returns the type before the address space attribute application 1837 /// area. 1838 /// int * __attribute__((address_space(11))) * 1839 /// ^ ^ 1840 QualType getInnerType() const { 1841 return this->getTypePtr()->getPointeeType(); 1842 } 1843 1844 TypeLoc getPointeeTypeLoc() const { 1845 return this->getInnerTypeLoc(); 1846 } 1847 1848 void initializeLocal(ASTContext &Context, SourceLocation loc) { 1849 setAttrNameLoc(loc); 1850 setAttrOperandParensRange(loc); 1851 setAttrOperandParensRange(SourceRange(loc)); 1852 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr()); 1853 } 1854 }; 1855 1856 //===----------------------------------------------------------------------===// 1857 // 1858 // All of these need proper implementations. 1859 // 1860 //===----------------------------------------------------------------------===// 1861 1862 // FIXME: size expression and attribute locations (or keyword if we 1863 // ever fully support altivec syntax). 1864 struct VectorTypeLocInfo { 1865 SourceLocation NameLoc; 1866 }; 1867 1868 class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc, 1869 VectorType, VectorTypeLocInfo> { 1870 public: 1871 SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } 1872 1873 void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } 1874 1875 SourceRange getLocalSourceRange() const { 1876 return SourceRange(getNameLoc(), getNameLoc()); 1877 } 1878 1879 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1880 setNameLoc(Loc); 1881 } 1882 1883 TypeLoc getElementLoc() const { return getInnerTypeLoc(); } 1884 1885 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 1886 }; 1887 1888 // FIXME: size expression and attribute locations (or keyword if we 1889 // ever fully support altivec syntax). 1890 class DependentVectorTypeLoc 1891 : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc, 1892 DependentVectorType, VectorTypeLocInfo> { 1893 public: 1894 SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } 1895 1896 void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } 1897 1898 SourceRange getLocalSourceRange() const { 1899 return SourceRange(getNameLoc(), getNameLoc()); 1900 } 1901 1902 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1903 setNameLoc(Loc); 1904 } 1905 1906 TypeLoc getElementLoc() const { return getInnerTypeLoc(); } 1907 1908 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 1909 }; 1910 1911 // FIXME: size expression and attribute locations. 1912 class ExtVectorTypeLoc 1913 : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc, 1914 ExtVectorType> {}; 1915 1916 // FIXME: attribute locations. 1917 // For some reason, this isn't a subtype of VectorType. 1918 class DependentSizedExtVectorTypeLoc 1919 : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc, 1920 DependentSizedExtVectorType, VectorTypeLocInfo> { 1921 public: 1922 SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } 1923 1924 void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } 1925 1926 SourceRange getLocalSourceRange() const { 1927 return SourceRange(getNameLoc(), getNameLoc()); 1928 } 1929 1930 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1931 setNameLoc(Loc); 1932 } 1933 1934 TypeLoc getElementLoc() const { return getInnerTypeLoc(); } 1935 1936 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 1937 }; 1938 1939 struct MatrixTypeLocInfo { 1940 SourceLocation AttrLoc; 1941 SourceRange OperandParens; 1942 Expr *RowOperand; 1943 Expr *ColumnOperand; 1944 }; 1945 1946 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc, 1947 MatrixType, MatrixTypeLocInfo> { 1948 public: 1949 /// The location of the attribute name, i.e. 1950 /// float __attribute__((matrix_type(4, 2))) 1951 /// ^~~~~~~~~~~~~~~~~ 1952 SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; } 1953 void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; } 1954 1955 /// The attribute's row operand, if it has one. 1956 /// float __attribute__((matrix_type(4, 2))) 1957 /// ^ 1958 Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; } 1959 void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; } 1960 1961 /// The attribute's column operand, if it has one. 1962 /// float __attribute__((matrix_type(4, 2))) 1963 /// ^ 1964 Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; } 1965 void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; } 1966 1967 /// The location of the parentheses around the operand, if there is 1968 /// an operand. 1969 /// float __attribute__((matrix_type(4, 2))) 1970 /// ^ ^ 1971 SourceRange getAttrOperandParensRange() const { 1972 return getLocalData()->OperandParens; 1973 } 1974 void setAttrOperandParensRange(SourceRange range) { 1975 getLocalData()->OperandParens = range; 1976 } 1977 1978 SourceRange getLocalSourceRange() const { 1979 SourceRange range(getAttrNameLoc()); 1980 range.setEnd(getAttrOperandParensRange().getEnd()); 1981 return range; 1982 } 1983 1984 void initializeLocal(ASTContext &Context, SourceLocation loc) { 1985 setAttrNameLoc(loc); 1986 setAttrOperandParensRange(loc); 1987 setAttrRowOperand(nullptr); 1988 setAttrColumnOperand(nullptr); 1989 } 1990 }; 1991 1992 class ConstantMatrixTypeLoc 1993 : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc, 1994 ConstantMatrixType> {}; 1995 1996 class DependentSizedMatrixTypeLoc 1997 : public InheritingConcreteTypeLoc<MatrixTypeLoc, 1998 DependentSizedMatrixTypeLoc, 1999 DependentSizedMatrixType> {}; 2000 2001 // FIXME: location of the '_Complex' keyword. 2002 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 2003 ComplexTypeLoc, 2004 ComplexType> { 2005 }; 2006 2007 struct TypeofLocInfo { 2008 SourceLocation TypeofLoc; 2009 SourceLocation LParenLoc; 2010 SourceLocation RParenLoc; 2011 }; 2012 2013 struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 2014 }; 2015 2016 struct TypeOfTypeLocInfo : public TypeofLocInfo { 2017 TypeSourceInfo *UnmodifiedTInfo; 2018 }; 2019 2020 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 2021 class TypeofLikeTypeLoc 2022 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 2023 public: 2024 SourceLocation getTypeofLoc() const { 2025 return this->getLocalData()->TypeofLoc; 2026 } 2027 2028 void setTypeofLoc(SourceLocation Loc) { 2029 this->getLocalData()->TypeofLoc = Loc; 2030 } 2031 2032 SourceLocation getLParenLoc() const { 2033 return this->getLocalData()->LParenLoc; 2034 } 2035 2036 void setLParenLoc(SourceLocation Loc) { 2037 this->getLocalData()->LParenLoc = Loc; 2038 } 2039 2040 SourceLocation getRParenLoc() const { 2041 return this->getLocalData()->RParenLoc; 2042 } 2043 2044 void setRParenLoc(SourceLocation Loc) { 2045 this->getLocalData()->RParenLoc = Loc; 2046 } 2047 2048 SourceRange getParensRange() const { 2049 return SourceRange(getLParenLoc(), getRParenLoc()); 2050 } 2051 2052 void setParensRange(SourceRange range) { 2053 setLParenLoc(range.getBegin()); 2054 setRParenLoc(range.getEnd()); 2055 } 2056 2057 SourceRange getLocalSourceRange() const { 2058 return SourceRange(getTypeofLoc(), getRParenLoc()); 2059 } 2060 2061 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2062 setTypeofLoc(Loc); 2063 setLParenLoc(Loc); 2064 setRParenLoc(Loc); 2065 } 2066 }; 2067 2068 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 2069 TypeOfExprType, 2070 TypeOfExprTypeLocInfo> { 2071 public: 2072 Expr* getUnderlyingExpr() const { 2073 return getTypePtr()->getUnderlyingExpr(); 2074 } 2075 2076 // Reimplemented to account for GNU/C++ extension 2077 // typeof unary-expression 2078 // where there are no parentheses. 2079 SourceRange getLocalSourceRange() const; 2080 }; 2081 2082 class TypeOfTypeLoc 2083 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 2084 public: 2085 QualType getUnmodifiedType() const { 2086 return this->getTypePtr()->getUnmodifiedType(); 2087 } 2088 2089 TypeSourceInfo *getUnmodifiedTInfo() const { 2090 return this->getLocalData()->UnmodifiedTInfo; 2091 } 2092 2093 void setUnmodifiedTInfo(TypeSourceInfo *TI) const { 2094 this->getLocalData()->UnmodifiedTInfo = TI; 2095 } 2096 2097 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2098 }; 2099 2100 // decltype(expression) abc; 2101 // ~~~~~~~~ DecltypeLoc 2102 // ~ RParenLoc 2103 // FIXME: add LParenLoc, it is tricky to support due to the limitation of 2104 // annotated-decltype token. 2105 struct DecltypeTypeLocInfo { 2106 SourceLocation DecltypeLoc; 2107 SourceLocation RParenLoc; 2108 }; 2109 class DecltypeTypeLoc 2110 : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType, 2111 DecltypeTypeLocInfo> { 2112 public: 2113 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 2114 2115 SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; } 2116 void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; } 2117 2118 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 2119 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 2120 2121 SourceRange getLocalSourceRange() const { 2122 return SourceRange(getDecltypeLoc(), getRParenLoc()); 2123 } 2124 2125 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2126 setDecltypeLoc(Loc); 2127 setRParenLoc(Loc); 2128 } 2129 }; 2130 2131 struct PackIndexingTypeLocInfo { 2132 SourceLocation EllipsisLoc; 2133 }; 2134 2135 class PackIndexingTypeLoc 2136 : public ConcreteTypeLoc<UnqualTypeLoc, PackIndexingTypeLoc, 2137 PackIndexingType, PackIndexingTypeLocInfo> { 2138 2139 public: 2140 Expr *getIndexExpr() const { return getTypePtr()->getIndexExpr(); } 2141 QualType getPattern() const { return getTypePtr()->getPattern(); } 2142 2143 SourceLocation getEllipsisLoc() const { return getLocalData()->EllipsisLoc; } 2144 void setEllipsisLoc(SourceLocation Loc) { getLocalData()->EllipsisLoc = Loc; } 2145 2146 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2147 setEllipsisLoc(Loc); 2148 } 2149 2150 TypeLoc getPatternLoc() const { return getInnerTypeLoc(); } 2151 2152 QualType getInnerType() const { return this->getTypePtr()->getPattern(); } 2153 2154 SourceRange getLocalSourceRange() const { 2155 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 2156 } 2157 }; 2158 2159 struct UnaryTransformTypeLocInfo { 2160 // FIXME: While there's only one unary transform right now, future ones may 2161 // need different representations 2162 SourceLocation KWLoc, LParenLoc, RParenLoc; 2163 TypeSourceInfo *UnderlyingTInfo; 2164 }; 2165 2166 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2167 UnaryTransformTypeLoc, 2168 UnaryTransformType, 2169 UnaryTransformTypeLocInfo> { 2170 public: 2171 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 2172 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 2173 2174 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 2175 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 2176 2177 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 2178 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 2179 2180 TypeSourceInfo* getUnderlyingTInfo() const { 2181 return getLocalData()->UnderlyingTInfo; 2182 } 2183 2184 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 2185 getLocalData()->UnderlyingTInfo = TInfo; 2186 } 2187 2188 SourceRange getLocalSourceRange() const { 2189 return SourceRange(getKWLoc(), getRParenLoc()); 2190 } 2191 2192 SourceRange getParensRange() const { 2193 return SourceRange(getLParenLoc(), getRParenLoc()); 2194 } 2195 2196 void setParensRange(SourceRange Range) { 2197 setLParenLoc(Range.getBegin()); 2198 setRParenLoc(Range.getEnd()); 2199 } 2200 2201 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2202 }; 2203 2204 class DeducedTypeLoc 2205 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc, 2206 DeducedType> {}; 2207 2208 struct AutoTypeLocInfo : TypeSpecLocInfo { 2209 // For decltype(auto). 2210 SourceLocation RParenLoc; 2211 2212 ConceptReference *CR = nullptr; 2213 }; 2214 2215 class AutoTypeLoc 2216 : public ConcreteTypeLoc<DeducedTypeLoc, 2217 AutoTypeLoc, 2218 AutoType, 2219 AutoTypeLocInfo> { 2220 public: 2221 AutoTypeKeyword getAutoKeyword() const { 2222 return getTypePtr()->getKeyword(); 2223 } 2224 2225 bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); } 2226 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 2227 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 2228 2229 bool isConstrained() const { 2230 return getTypePtr()->isConstrained(); 2231 } 2232 2233 void setConceptReference(ConceptReference *CR) { getLocalData()->CR = CR; } 2234 2235 ConceptReference *getConceptReference() const { return getLocalData()->CR; } 2236 2237 // FIXME: Several of the following functions can be removed. Instead the 2238 // caller can directly work with the ConceptReference. 2239 const NestedNameSpecifierLoc getNestedNameSpecifierLoc() const { 2240 if (const auto *CR = getConceptReference()) 2241 return CR->getNestedNameSpecifierLoc(); 2242 return NestedNameSpecifierLoc(); 2243 } 2244 2245 SourceLocation getTemplateKWLoc() const { 2246 if (const auto *CR = getConceptReference()) 2247 return CR->getTemplateKWLoc(); 2248 return SourceLocation(); 2249 } 2250 2251 SourceLocation getConceptNameLoc() const { 2252 if (const auto *CR = getConceptReference()) 2253 return CR->getConceptNameLoc(); 2254 return SourceLocation(); 2255 } 2256 2257 NamedDecl *getFoundDecl() const { 2258 if (const auto *CR = getConceptReference()) 2259 return CR->getFoundDecl(); 2260 return nullptr; 2261 } 2262 2263 ConceptDecl *getNamedConcept() const { 2264 if (const auto *CR = getConceptReference()) 2265 return CR->getNamedConcept(); 2266 return nullptr; 2267 } 2268 2269 DeclarationNameInfo getConceptNameInfo() const { 2270 return getConceptReference()->getConceptNameInfo(); 2271 } 2272 2273 bool hasExplicitTemplateArgs() const { 2274 return (getConceptReference() && 2275 getConceptReference()->getTemplateArgsAsWritten() && 2276 getConceptReference() 2277 ->getTemplateArgsAsWritten() 2278 ->getLAngleLoc() 2279 .isValid()); 2280 } 2281 2282 SourceLocation getLAngleLoc() const { 2283 if (const auto *CR = getConceptReference()) 2284 if (const auto *TAAW = CR->getTemplateArgsAsWritten()) 2285 return TAAW->getLAngleLoc(); 2286 return SourceLocation(); 2287 } 2288 2289 SourceLocation getRAngleLoc() const { 2290 if (const auto *CR = getConceptReference()) 2291 if (const auto *TAAW = CR->getTemplateArgsAsWritten()) 2292 return TAAW->getRAngleLoc(); 2293 return SourceLocation(); 2294 } 2295 2296 unsigned getNumArgs() const { 2297 return getTypePtr()->getTypeConstraintArguments().size(); 2298 } 2299 2300 TemplateArgumentLoc getArgLoc(unsigned i) const { 2301 const auto *CR = getConceptReference(); 2302 assert(CR && "No ConceptReference"); 2303 return CR->getTemplateArgsAsWritten()->getTemplateArgs()[i]; 2304 } 2305 2306 SourceRange getLocalSourceRange() const { 2307 return {isConstrained() 2308 ? (getNestedNameSpecifierLoc() 2309 ? getNestedNameSpecifierLoc().getBeginLoc() 2310 : (getTemplateKWLoc().isValid() ? getTemplateKWLoc() 2311 : getConceptNameLoc())) 2312 : getNameLoc(), 2313 isDecltypeAuto() ? getRParenLoc() : getNameLoc()}; 2314 } 2315 2316 void copy(AutoTypeLoc Loc) { 2317 unsigned size = getFullDataSize(); 2318 assert(size == Loc.getFullDataSize()); 2319 memcpy(Data, Loc.Data, size); 2320 } 2321 2322 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2323 }; 2324 2325 class DeducedTemplateSpecializationTypeLoc 2326 : public InheritingConcreteTypeLoc<DeducedTypeLoc, 2327 DeducedTemplateSpecializationTypeLoc, 2328 DeducedTemplateSpecializationType> { 2329 public: 2330 SourceLocation getTemplateNameLoc() const { 2331 return getNameLoc(); 2332 } 2333 2334 void setTemplateNameLoc(SourceLocation Loc) { 2335 setNameLoc(Loc); 2336 } 2337 }; 2338 2339 struct ElaboratedLocInfo { 2340 SourceLocation ElaboratedKWLoc; 2341 2342 /// Data associated with the nested-name-specifier location. 2343 void *QualifierData; 2344 }; 2345 2346 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2347 ElaboratedTypeLoc, 2348 ElaboratedType, 2349 ElaboratedLocInfo> { 2350 public: 2351 SourceLocation getElaboratedKeywordLoc() const { 2352 return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation(); 2353 } 2354 2355 void setElaboratedKeywordLoc(SourceLocation Loc) { 2356 if (isEmpty()) { 2357 assert(Loc.isInvalid()); 2358 return; 2359 } 2360 getLocalData()->ElaboratedKWLoc = Loc; 2361 } 2362 2363 NestedNameSpecifierLoc getQualifierLoc() const { 2364 return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2365 getLocalData()->QualifierData) 2366 : NestedNameSpecifierLoc(); 2367 } 2368 2369 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2370 assert(QualifierLoc.getNestedNameSpecifier() == 2371 getTypePtr()->getQualifier() && 2372 "Inconsistent nested-name-specifier pointer"); 2373 if (isEmpty()) { 2374 assert(!QualifierLoc.hasQualifier()); 2375 return; 2376 } 2377 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2378 } 2379 2380 SourceRange getLocalSourceRange() const { 2381 if (getElaboratedKeywordLoc().isValid()) 2382 if (getQualifierLoc()) 2383 return SourceRange(getElaboratedKeywordLoc(), 2384 getQualifierLoc().getEndLoc()); 2385 else 2386 return SourceRange(getElaboratedKeywordLoc()); 2387 else 2388 return getQualifierLoc().getSourceRange(); 2389 } 2390 2391 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2392 2393 TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); } 2394 2395 QualType getInnerType() const { return getTypePtr()->getNamedType(); } 2396 2397 bool isEmpty() const { 2398 return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::None && 2399 !getTypePtr()->getQualifier(); 2400 } 2401 2402 unsigned getLocalDataAlignment() const { 2403 // FIXME: We want to return 1 here in the empty case, but 2404 // there are bugs in how alignment is handled in TypeLocs 2405 // that prevent this from working. 2406 return ConcreteTypeLoc::getLocalDataAlignment(); 2407 } 2408 2409 unsigned getLocalDataSize() const { 2410 return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0; 2411 } 2412 2413 void copy(ElaboratedTypeLoc Loc) { 2414 unsigned size = getFullDataSize(); 2415 assert(size == Loc.getFullDataSize()); 2416 memcpy(Data, Loc.Data, size); 2417 } 2418 }; 2419 2420 // This is exactly the structure of an ElaboratedTypeLoc whose inner 2421 // type is some sort of TypeDeclTypeLoc. 2422 struct DependentNameLocInfo : ElaboratedLocInfo { 2423 SourceLocation NameLoc; 2424 }; 2425 2426 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2427 DependentNameTypeLoc, 2428 DependentNameType, 2429 DependentNameLocInfo> { 2430 public: 2431 SourceLocation getElaboratedKeywordLoc() const { 2432 return this->getLocalData()->ElaboratedKWLoc; 2433 } 2434 2435 void setElaboratedKeywordLoc(SourceLocation Loc) { 2436 this->getLocalData()->ElaboratedKWLoc = Loc; 2437 } 2438 2439 NestedNameSpecifierLoc getQualifierLoc() const { 2440 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2441 getLocalData()->QualifierData); 2442 } 2443 2444 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2445 assert(QualifierLoc.getNestedNameSpecifier() 2446 == getTypePtr()->getQualifier() && 2447 "Inconsistent nested-name-specifier pointer"); 2448 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2449 } 2450 2451 SourceLocation getNameLoc() const { 2452 return this->getLocalData()->NameLoc; 2453 } 2454 2455 void setNameLoc(SourceLocation Loc) { 2456 this->getLocalData()->NameLoc = Loc; 2457 } 2458 2459 SourceRange getLocalSourceRange() const { 2460 if (getElaboratedKeywordLoc().isValid()) 2461 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 2462 else 2463 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 2464 } 2465 2466 void copy(DependentNameTypeLoc Loc) { 2467 unsigned size = getFullDataSize(); 2468 assert(size == Loc.getFullDataSize()); 2469 memcpy(Data, Loc.Data, size); 2470 } 2471 2472 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2473 }; 2474 2475 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 2476 SourceLocation TemplateKWLoc; 2477 SourceLocation LAngleLoc; 2478 SourceLocation RAngleLoc; 2479 // followed by a TemplateArgumentLocInfo[] 2480 }; 2481 2482 class DependentTemplateSpecializationTypeLoc : 2483 public ConcreteTypeLoc<UnqualTypeLoc, 2484 DependentTemplateSpecializationTypeLoc, 2485 DependentTemplateSpecializationType, 2486 DependentTemplateSpecializationLocInfo> { 2487 public: 2488 SourceLocation getElaboratedKeywordLoc() const { 2489 return this->getLocalData()->ElaboratedKWLoc; 2490 } 2491 2492 void setElaboratedKeywordLoc(SourceLocation Loc) { 2493 this->getLocalData()->ElaboratedKWLoc = Loc; 2494 } 2495 2496 NestedNameSpecifierLoc getQualifierLoc() const { 2497 if (!getLocalData()->QualifierData) 2498 return NestedNameSpecifierLoc(); 2499 2500 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2501 getLocalData()->QualifierData); 2502 } 2503 2504 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2505 if (!QualifierLoc) { 2506 // Even if we have a nested-name-specifier in the dependent 2507 // template specialization type, we won't record the nested-name-specifier 2508 // location information when this type-source location information is 2509 // part of a nested-name-specifier. 2510 getLocalData()->QualifierData = nullptr; 2511 return; 2512 } 2513 2514 assert(QualifierLoc.getNestedNameSpecifier() 2515 == getTypePtr()->getQualifier() && 2516 "Inconsistent nested-name-specifier pointer"); 2517 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2518 } 2519 2520 SourceLocation getTemplateKeywordLoc() const { 2521 return getLocalData()->TemplateKWLoc; 2522 } 2523 2524 void setTemplateKeywordLoc(SourceLocation Loc) { 2525 getLocalData()->TemplateKWLoc = Loc; 2526 } 2527 2528 SourceLocation getTemplateNameLoc() const { 2529 return this->getLocalData()->NameLoc; 2530 } 2531 2532 void setTemplateNameLoc(SourceLocation Loc) { 2533 this->getLocalData()->NameLoc = Loc; 2534 } 2535 2536 SourceLocation getLAngleLoc() const { 2537 return this->getLocalData()->LAngleLoc; 2538 } 2539 2540 void setLAngleLoc(SourceLocation Loc) { 2541 this->getLocalData()->LAngleLoc = Loc; 2542 } 2543 2544 SourceLocation getRAngleLoc() const { 2545 return this->getLocalData()->RAngleLoc; 2546 } 2547 2548 void setRAngleLoc(SourceLocation Loc) { 2549 this->getLocalData()->RAngleLoc = Loc; 2550 } 2551 2552 unsigned getNumArgs() const { 2553 return getTypePtr()->template_arguments().size(); 2554 } 2555 2556 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2557 getArgInfos()[i] = AI; 2558 } 2559 2560 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2561 return getArgInfos()[i]; 2562 } 2563 2564 TemplateArgumentLoc getArgLoc(unsigned i) const { 2565 return TemplateArgumentLoc(getTypePtr()->template_arguments()[i], 2566 getArgLocInfo(i)); 2567 } 2568 2569 SourceRange getLocalSourceRange() const { 2570 if (getElaboratedKeywordLoc().isValid()) 2571 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 2572 else if (getQualifierLoc()) 2573 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 2574 else if (getTemplateKeywordLoc().isValid()) 2575 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 2576 else 2577 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 2578 } 2579 2580 void copy(DependentTemplateSpecializationTypeLoc Loc) { 2581 unsigned size = getFullDataSize(); 2582 assert(size == Loc.getFullDataSize()); 2583 memcpy(Data, Loc.Data, size); 2584 } 2585 2586 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2587 2588 unsigned getExtraLocalDataSize() const { 2589 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2590 } 2591 2592 unsigned getExtraLocalDataAlignment() const { 2593 return alignof(TemplateArgumentLocInfo); 2594 } 2595 2596 private: 2597 TemplateArgumentLocInfo *getArgInfos() const { 2598 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2599 } 2600 }; 2601 2602 struct PackExpansionTypeLocInfo { 2603 SourceLocation EllipsisLoc; 2604 }; 2605 2606 class PackExpansionTypeLoc 2607 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 2608 PackExpansionType, PackExpansionTypeLocInfo> { 2609 public: 2610 SourceLocation getEllipsisLoc() const { 2611 return this->getLocalData()->EllipsisLoc; 2612 } 2613 2614 void setEllipsisLoc(SourceLocation Loc) { 2615 this->getLocalData()->EllipsisLoc = Loc; 2616 } 2617 2618 SourceRange getLocalSourceRange() const { 2619 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 2620 } 2621 2622 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2623 setEllipsisLoc(Loc); 2624 } 2625 2626 TypeLoc getPatternLoc() const { 2627 return getInnerTypeLoc(); 2628 } 2629 2630 QualType getInnerType() const { 2631 return this->getTypePtr()->getPattern(); 2632 } 2633 }; 2634 2635 struct AtomicTypeLocInfo { 2636 SourceLocation KWLoc, LParenLoc, RParenLoc; 2637 }; 2638 2639 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 2640 AtomicType, AtomicTypeLocInfo> { 2641 public: 2642 TypeLoc getValueLoc() const { 2643 return this->getInnerTypeLoc(); 2644 } 2645 2646 SourceRange getLocalSourceRange() const { 2647 return SourceRange(getKWLoc(), getRParenLoc()); 2648 } 2649 2650 SourceLocation getKWLoc() const { 2651 return this->getLocalData()->KWLoc; 2652 } 2653 2654 void setKWLoc(SourceLocation Loc) { 2655 this->getLocalData()->KWLoc = Loc; 2656 } 2657 2658 SourceLocation getLParenLoc() const { 2659 return this->getLocalData()->LParenLoc; 2660 } 2661 2662 void setLParenLoc(SourceLocation Loc) { 2663 this->getLocalData()->LParenLoc = Loc; 2664 } 2665 2666 SourceLocation getRParenLoc() const { 2667 return this->getLocalData()->RParenLoc; 2668 } 2669 2670 void setRParenLoc(SourceLocation Loc) { 2671 this->getLocalData()->RParenLoc = Loc; 2672 } 2673 2674 SourceRange getParensRange() const { 2675 return SourceRange(getLParenLoc(), getRParenLoc()); 2676 } 2677 2678 void setParensRange(SourceRange Range) { 2679 setLParenLoc(Range.getBegin()); 2680 setRParenLoc(Range.getEnd()); 2681 } 2682 2683 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2684 setKWLoc(Loc); 2685 setLParenLoc(Loc); 2686 setRParenLoc(Loc); 2687 } 2688 2689 QualType getInnerType() const { 2690 return this->getTypePtr()->getValueType(); 2691 } 2692 }; 2693 2694 struct PipeTypeLocInfo { 2695 SourceLocation KWLoc; 2696 }; 2697 2698 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType, 2699 PipeTypeLocInfo> { 2700 public: 2701 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); } 2702 2703 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); } 2704 2705 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; } 2706 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; } 2707 2708 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2709 setKWLoc(Loc); 2710 } 2711 2712 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 2713 }; 2714 2715 template <typename T> 2716 inline T TypeLoc::getAsAdjusted() const { 2717 TypeLoc Cur = *this; 2718 while (!T::isKind(Cur)) { 2719 if (auto PTL = Cur.getAs<ParenTypeLoc>()) 2720 Cur = PTL.getInnerLoc(); 2721 else if (auto ATL = Cur.getAs<AttributedTypeLoc>()) 2722 Cur = ATL.getModifiedLoc(); 2723 else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>()) 2724 Cur = ATL.getWrappedLoc(); 2725 else if (auto ATL = Cur.getAs<HLSLAttributedResourceTypeLoc>()) 2726 Cur = ATL.getWrappedLoc(); 2727 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>()) 2728 Cur = ETL.getNamedTypeLoc(); 2729 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>()) 2730 Cur = ATL.getOriginalLoc(); 2731 else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>()) 2732 Cur = MQL.getInnerLoc(); 2733 else 2734 break; 2735 } 2736 return Cur.getAs<T>(); 2737 } 2738 class BitIntTypeLoc final 2739 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc, 2740 BitIntType> {}; 2741 class DependentBitIntTypeLoc final 2742 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc, 2743 DependentBitIntType> {}; 2744 2745 class ObjCProtocolLoc { 2746 ObjCProtocolDecl *Protocol = nullptr; 2747 SourceLocation Loc = SourceLocation(); 2748 2749 public: 2750 ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc) 2751 : Protocol(protocol), Loc(loc) {} 2752 ObjCProtocolDecl *getProtocol() const { return Protocol; } 2753 SourceLocation getLocation() const { return Loc; } 2754 2755 /// The source range is just the protocol name. 2756 SourceRange getSourceRange() const LLVM_READONLY { 2757 return SourceRange(Loc, Loc); 2758 } 2759 }; 2760 2761 } // namespace clang 2762 2763 #endif // LLVM_CLANG_AST_TYPELOC_H 2764