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