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