1//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the TypeLoc interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_TYPELOC_H 15#define LLVM_CLANG_AST_TYPELOC_H 16 17#include "clang/AST/Type.h" 18#include "clang/AST/Decl.h" 19#include "clang/AST/TemplateBase.h" 20#include "clang/Basic/Specifiers.h" 21#include "llvm/Support/Compiler.h" 22 23namespace clang { 24 class ASTContext; 25 class ParmVarDecl; 26 class TypeSourceInfo; 27 class UnqualTypeLoc; 28 29// Predeclare all the type nodes. 30#define ABSTRACT_TYPELOC(Class, Base) 31#define TYPELOC(Class, Base) \ 32 class Class##TypeLoc; 33#include "clang/AST/TypeLocNodes.def" 34 35/// \brief Base wrapper for a particular "section" of type source info. 36/// 37/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to 38/// get at the actual information. 39class TypeLoc { 40protected: 41 // The correctness of this relies on the property that, for Type *Ty, 42 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 43 const void *Ty; 44 void *Data; 45 46public: 47 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 48 /// except it also defines a Qualified enum that corresponds to the 49 /// QualifiedLoc class. 50 enum TypeLocClass { 51#define ABSTRACT_TYPE(Class, Base) 52#define TYPE(Class, Base) \ 53 Class = Type::Class, 54#include "clang/AST/TypeNodes.def" 55 Qualified 56 }; 57 58 TypeLoc() : Ty(0), Data(0) { } 59 TypeLoc(QualType ty, void *opaqueData) 60 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { } 61 TypeLoc(const Type *ty, void *opaqueData) 62 : Ty(ty), Data(opaqueData) { } 63 64 TypeLocClass getTypeLocClass() const { 65 if (getType().hasLocalQualifiers()) return Qualified; 66 return (TypeLocClass) getType()->getTypeClass(); 67 } 68 69 bool isNull() const { return !Ty; } 70 operator bool() const { return Ty; } 71 72 /// \brief Returns the size of type source info data block for the given type. 73 static unsigned getFullDataSizeForType(QualType Ty); 74 75 /// \brief Get the type for which this source info wrapper provides 76 /// information. 77 QualType getType() const { 78 return QualType::getFromOpaquePtr(Ty); 79 } 80 81 const Type *getTypePtr() const { 82 return QualType::getFromOpaquePtr(Ty).getTypePtr(); 83 } 84 85 /// \brief Get the pointer where source information is stored. 86 void *getOpaqueData() const { 87 return Data; 88 } 89 90 /// \brief Get the begin source location. 91 SourceLocation getBeginLoc() const; 92 93 /// \brief Get the end source location. 94 SourceLocation getEndLoc() const; 95 96 /// \brief Get the full source range. 97 SourceRange getSourceRange() const LLVM_READONLY { 98 return SourceRange(getBeginLoc(), getEndLoc()); 99 } 100 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } 101 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 102 103 /// \brief Get the local source range. 104 SourceRange getLocalSourceRange() const { 105 return getLocalSourceRangeImpl(*this); 106 } 107 108 /// \brief Returns the size of the type source info data block. 109 unsigned getFullDataSize() const { 110 return getFullDataSizeForType(getType()); 111 } 112 113 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 114 /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 115 TypeLoc getNextTypeLoc() const { 116 return getNextTypeLocImpl(*this); 117 } 118 119 /// \brief Skips past any qualifiers, if this is qualified. 120 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 121 122 TypeLoc IgnoreParens() const { 123 if (isa<ParenTypeLoc>(this)) 124 return IgnoreParensImpl(*this); 125 return *this; 126 } 127 128 /// \brief Initializes this to state that every location in this 129 /// type is the given location. 130 /// 131 /// This method exists to provide a simple transition for code that 132 /// relies on location-less types. 133 void initialize(ASTContext &Context, SourceLocation Loc) const { 134 initializeImpl(Context, *this, Loc); 135 } 136 137 /// \brief Initializes this by copying its information from another 138 /// TypeLoc of the same type. 139 void initializeFullCopy(TypeLoc Other) const { 140 assert(getType() == Other.getType()); 141 size_t Size = getFullDataSize(); 142 memcpy(getOpaqueData(), Other.getOpaqueData(), Size); 143 } 144 145 /// \brief Initializes this by copying its information from another 146 /// TypeLoc of the same type. The given size must be the full data 147 /// size. 148 void initializeFullCopy(TypeLoc Other, unsigned Size) const { 149 assert(getType() == Other.getType()); 150 assert(getFullDataSize() == Size); 151 memcpy(getOpaqueData(), Other.getOpaqueData(), Size); 152 } 153 154 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 155 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 156 } 157 158 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 159 return !(LHS == RHS); 160 } 161 162 static bool classof(const TypeLoc *TL) { return true; } 163 164private: 165 static void initializeImpl(ASTContext &Context, TypeLoc TL, 166 SourceLocation Loc); 167 static TypeLoc getNextTypeLocImpl(TypeLoc TL); 168 static TypeLoc IgnoreParensImpl(TypeLoc TL); 169 static SourceRange getLocalSourceRangeImpl(TypeLoc TL); 170}; 171 172/// \brief Return the TypeLoc for a type source info. 173inline TypeLoc TypeSourceInfo::getTypeLoc() const { 174 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); 175} 176 177/// \brief Wrapper of type source information for a type with 178/// no direct qualifiers. 179class UnqualTypeLoc : public TypeLoc { 180public: 181 UnqualTypeLoc() {} 182 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 183 184 const Type *getTypePtr() const { 185 return reinterpret_cast<const Type*>(Ty); 186 } 187 188 TypeLocClass getTypeLocClass() const { 189 return (TypeLocClass) getTypePtr()->getTypeClass(); 190 } 191 192 static bool classof(const TypeLoc *TL) { 193 return !TL->getType().hasLocalQualifiers(); 194 } 195 static bool classof(const UnqualTypeLoc *TL) { return true; } 196}; 197 198/// \brief Wrapper of type source information for a type with 199/// non-trivial direct qualifiers. 200/// 201/// Currently, we intentionally do not provide source location for 202/// type qualifiers. 203class QualifiedTypeLoc : public TypeLoc { 204public: 205 SourceRange getLocalSourceRange() const { 206 return SourceRange(); 207 } 208 209 UnqualTypeLoc getUnqualifiedLoc() const { 210 return UnqualTypeLoc(getTypePtr(), Data); 211 } 212 213 /// Initializes the local data of this type source info block to 214 /// provide no information. 215 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 216 // do nothing 217 } 218 219 TypeLoc getNextTypeLoc() const { 220 return getUnqualifiedLoc(); 221 } 222 223 /// \brief Returns the size of the type source info data block that is 224 /// specific to this type. 225 unsigned getLocalDataSize() const { 226 // In fact, we don't currently preserve any location information 227 // for qualifiers. 228 return 0; 229 } 230 231 /// \brief Returns the size of the type source info data block. 232 unsigned getFullDataSize() const { 233 return getLocalDataSize() + 234 getFullDataSizeForType(getType().getLocalUnqualifiedType()); 235 } 236 237 static bool classof(const TypeLoc *TL) { 238 return TL->getType().hasLocalQualifiers(); 239 } 240 static bool classof(const QualifiedTypeLoc *TL) { return true; } 241}; 242 243inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 244 if (isa<QualifiedTypeLoc>(this)) 245 return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc(); 246 return cast<UnqualTypeLoc>(*this); 247} 248 249/// A metaprogramming base class for TypeLoc classes which correspond 250/// to a particular Type subclass. It is accepted for a single 251/// TypeLoc class to correspond to multiple Type classes. 252/// 253/// \tparam Base a class from which to derive 254/// \tparam Derived the class deriving from this one 255/// \tparam TypeClass the concrete Type subclass associated with this 256/// location type 257/// \tparam LocalData the structure type of local location data for 258/// this type 259/// 260/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or 261/// else the world will end. 262/// 263/// TypeLocs with non-constant amounts of local data should override 264/// getExtraLocalDataSize(); getExtraLocalData() will then point to 265/// this extra memory. 266/// 267/// TypeLocs with an inner type should define 268/// QualType getInnerType() const 269/// and getInnerTypeLoc() will then point to this inner type's 270/// location data. 271/// 272/// A word about hierarchies: this template is not designed to be 273/// derived from multiple times in a hierarchy. It is also not 274/// designed to be used for classes where subtypes might provide 275/// different amounts of source information. It should be subclassed 276/// only at the deepest portion of the hierarchy where all children 277/// have identical source information; if that's an abstract type, 278/// then further descendents should inherit from 279/// InheritingConcreteTypeLoc instead. 280template <class Base, class Derived, class TypeClass, class LocalData> 281class ConcreteTypeLoc : public Base { 282 283 const Derived *asDerived() const { 284 return static_cast<const Derived*>(this); 285 } 286 287public: 288 unsigned getLocalDataSize() const { 289 return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); 290 } 291 // Give a default implementation that's useful for leaf types. 292 unsigned getFullDataSize() const { 293 return asDerived()->getLocalDataSize() + getInnerTypeSize(); 294 } 295 296 static bool classofType(const Type *Ty) { 297 return TypeClass::classof(Ty); 298 } 299 300 static bool classof(const TypeLoc *TL) { 301 return Derived::classofType(TL->getTypePtr()); 302 } 303 static bool classof(const UnqualTypeLoc *TL) { 304 return Derived::classofType(TL->getTypePtr()); 305 } 306 static bool classof(const Derived *TL) { 307 return true; 308 } 309 310 TypeLoc getNextTypeLoc() const { 311 return getNextTypeLoc(asDerived()->getInnerType()); 312 } 313 314 const TypeClass *getTypePtr() const { 315 return cast<TypeClass>(Base::getTypePtr()); 316 } 317 318protected: 319 unsigned getExtraLocalDataSize() const { 320 return 0; 321 } 322 323 LocalData *getLocalData() const { 324 return static_cast<LocalData*>(Base::Data); 325 } 326 327 /// Gets a pointer past the Info structure; useful for classes with 328 /// local data that can't be captured in the Info (e.g. because it's 329 /// of variable size). 330 void *getExtraLocalData() const { 331 return getLocalData() + 1; 332 } 333 334 void *getNonLocalData() const { 335 return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize(); 336 } 337 338 struct HasNoInnerType {}; 339 HasNoInnerType getInnerType() const { return HasNoInnerType(); } 340 341 TypeLoc getInnerTypeLoc() const { 342 return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 343 } 344 345private: 346 unsigned getInnerTypeSize() const { 347 return getInnerTypeSize(asDerived()->getInnerType()); 348 } 349 350 unsigned getInnerTypeSize(HasNoInnerType _) const { 351 return 0; 352 } 353 354 unsigned getInnerTypeSize(QualType _) const { 355 return getInnerTypeLoc().getFullDataSize(); 356 } 357 358 TypeLoc getNextTypeLoc(HasNoInnerType _) const { 359 return TypeLoc(); 360 } 361 362 TypeLoc getNextTypeLoc(QualType T) const { 363 return TypeLoc(T, getNonLocalData()); 364 } 365}; 366 367/// A metaprogramming class designed for concrete subtypes of abstract 368/// types where all subtypes share equivalently-structured source 369/// information. See the note on ConcreteTypeLoc. 370template <class Base, class Derived, class TypeClass> 371class InheritingConcreteTypeLoc : public Base { 372public: 373 static bool classofType(const Type *Ty) { 374 return TypeClass::classof(Ty); 375 } 376 377 static bool classof(const TypeLoc *TL) { 378 return Derived::classofType(TL->getTypePtr()); 379 } 380 static bool classof(const UnqualTypeLoc *TL) { 381 return Derived::classofType(TL->getTypePtr()); 382 } 383 static bool classof(const Derived *TL) { 384 return true; 385 } 386 387 const TypeClass *getTypePtr() const { 388 return cast<TypeClass>(Base::getTypePtr()); 389 } 390}; 391 392 393struct TypeSpecLocInfo { 394 SourceLocation NameLoc; 395}; 396 397/// \brief A reasonable base class for TypeLocs that correspond to 398/// types that are written as a type-specifier. 399class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 400 TypeSpecTypeLoc, 401 Type, 402 TypeSpecLocInfo> { 403public: 404 enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; 405 406 SourceLocation getNameLoc() const { 407 return this->getLocalData()->NameLoc; 408 } 409 void setNameLoc(SourceLocation Loc) { 410 this->getLocalData()->NameLoc = Loc; 411 } 412 SourceRange getLocalSourceRange() const { 413 return SourceRange(getNameLoc(), getNameLoc()); 414 } 415 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 416 setNameLoc(Loc); 417 } 418 419 static bool classof(const TypeLoc *TL); 420 static bool classof(const TypeSpecTypeLoc *TL) { return true; } 421}; 422 423 424struct BuiltinLocInfo { 425 SourceLocation BuiltinLoc; 426}; 427 428/// \brief Wrapper for source info for builtin types. 429class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 430 BuiltinTypeLoc, 431 BuiltinType, 432 BuiltinLocInfo> { 433public: 434 enum { LocalDataSize = sizeof(BuiltinLocInfo) }; 435 436 SourceLocation getBuiltinLoc() const { 437 return getLocalData()->BuiltinLoc; 438 } 439 void setBuiltinLoc(SourceLocation Loc) { 440 getLocalData()->BuiltinLoc = Loc; 441 } 442 443 SourceLocation getNameLoc() const { return getBuiltinLoc(); } 444 445 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 446 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 447 } 448 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 449 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 450 } 451 452 bool needsExtraLocalData() const { 453 BuiltinType::Kind bk = getTypePtr()->getKind(); 454 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) 455 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) 456 || bk == BuiltinType::UChar 457 || bk == BuiltinType::SChar; 458 } 459 460 unsigned getExtraLocalDataSize() const { 461 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 462 } 463 464 SourceRange getLocalSourceRange() const { 465 return SourceRange(getBuiltinLoc(), getBuiltinLoc()); 466 } 467 468 TypeSpecifierSign getWrittenSignSpec() const { 469 if (needsExtraLocalData()) 470 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 471 else 472 return TSS_unspecified; 473 } 474 bool hasWrittenSignSpec() const { 475 return getWrittenSignSpec() != TSS_unspecified; 476 } 477 void setWrittenSignSpec(TypeSpecifierSign written) { 478 if (needsExtraLocalData()) 479 getWrittenBuiltinSpecs().Sign = written; 480 } 481 482 TypeSpecifierWidth getWrittenWidthSpec() const { 483 if (needsExtraLocalData()) 484 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 485 else 486 return TSW_unspecified; 487 } 488 bool hasWrittenWidthSpec() const { 489 return getWrittenWidthSpec() != TSW_unspecified; 490 } 491 void setWrittenWidthSpec(TypeSpecifierWidth written) { 492 if (needsExtraLocalData()) 493 getWrittenBuiltinSpecs().Width = written; 494 } 495 496 TypeSpecifierType getWrittenTypeSpec() const; 497 bool hasWrittenTypeSpec() const { 498 return getWrittenTypeSpec() != TST_unspecified; 499 } 500 void setWrittenTypeSpec(TypeSpecifierType written) { 501 if (needsExtraLocalData()) 502 getWrittenBuiltinSpecs().Type = written; 503 } 504 505 bool hasModeAttr() const { 506 if (needsExtraLocalData()) 507 return getWrittenBuiltinSpecs().ModeAttr; 508 else 509 return false; 510 } 511 void setModeAttr(bool written) { 512 if (needsExtraLocalData()) 513 getWrittenBuiltinSpecs().ModeAttr = written; 514 } 515 516 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 517 setBuiltinLoc(Loc); 518 if (needsExtraLocalData()) { 519 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 520 wbs.Sign = TSS_unspecified; 521 wbs.Width = TSW_unspecified; 522 wbs.Type = TST_unspecified; 523 wbs.ModeAttr = false; 524 } 525 } 526}; 527 528 529/// \brief Wrapper for source info for typedefs. 530class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 531 TypedefTypeLoc, 532 TypedefType> { 533public: 534 TypedefNameDecl *getTypedefNameDecl() const { 535 return getTypePtr()->getDecl(); 536 } 537}; 538 539/// \brief Wrapper for source info for injected class names of class 540/// templates. 541class InjectedClassNameTypeLoc : 542 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 543 InjectedClassNameTypeLoc, 544 InjectedClassNameType> { 545public: 546 CXXRecordDecl *getDecl() const { 547 return getTypePtr()->getDecl(); 548 } 549}; 550 551/// \brief Wrapper for source info for unresolved typename using decls. 552class UnresolvedUsingTypeLoc : 553 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 554 UnresolvedUsingTypeLoc, 555 UnresolvedUsingType> { 556public: 557 UnresolvedUsingTypenameDecl *getDecl() const { 558 return getTypePtr()->getDecl(); 559 } 560}; 561 562/// \brief Wrapper for source info for tag types. Note that this only 563/// records source info for the name itself; a type written 'struct foo' 564/// should be represented as an ElaboratedTypeLoc. We currently 565/// only do that when C++ is enabled because of the expense of 566/// creating an ElaboratedType node for so many type references in C. 567class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 568 TagTypeLoc, 569 TagType> { 570public: 571 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 572 573 /// \brief True if the tag was defined in this type specifier. 574 bool isDefinition() const { 575 TagDecl *D = getDecl(); 576 return D->isCompleteDefinition() && 577 (D->getIdentifier() == 0 || D->getLocation() == getNameLoc()); 578 } 579}; 580 581/// \brief Wrapper for source info for record types. 582class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 583 RecordTypeLoc, 584 RecordType> { 585public: 586 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 587}; 588 589/// \brief Wrapper for source info for enum types. 590class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 591 EnumTypeLoc, 592 EnumType> { 593public: 594 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 595}; 596 597/// \brief Wrapper for template type parameters. 598class TemplateTypeParmTypeLoc : 599 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 600 TemplateTypeParmTypeLoc, 601 TemplateTypeParmType> { 602public: 603 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 604}; 605 606/// \brief Wrapper for substituted template type parameters. 607class SubstTemplateTypeParmTypeLoc : 608 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 609 SubstTemplateTypeParmTypeLoc, 610 SubstTemplateTypeParmType> { 611}; 612 613 /// \brief Wrapper for substituted template type parameters. 614class SubstTemplateTypeParmPackTypeLoc : 615 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 616 SubstTemplateTypeParmPackTypeLoc, 617 SubstTemplateTypeParmPackType> { 618}; 619 620struct AttributedLocInfo { 621 union { 622 Expr *ExprOperand; 623 624 /// A raw SourceLocation. 625 unsigned EnumOperandLoc; 626 }; 627 628 SourceRange OperandParens; 629 630 SourceLocation AttrLoc; 631}; 632 633/// \brief Type source information for an attributed type. 634class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 635 AttributedTypeLoc, 636 AttributedType, 637 AttributedLocInfo> { 638public: 639 AttributedType::Kind getAttrKind() const { 640 return getTypePtr()->getAttrKind(); 641 } 642 643 bool hasAttrExprOperand() const { 644 return (getAttrKind() >= AttributedType::FirstExprOperandKind && 645 getAttrKind() <= AttributedType::LastExprOperandKind); 646 } 647 648 bool hasAttrEnumOperand() const { 649 return (getAttrKind() >= AttributedType::FirstEnumOperandKind && 650 getAttrKind() <= AttributedType::LastEnumOperandKind); 651 } 652 653 bool hasAttrOperand() const { 654 return hasAttrExprOperand() || hasAttrEnumOperand(); 655 } 656 657 /// The modified type, which is generally canonically different from 658 /// the attribute type. 659 /// int main(int, char**) __attribute__((noreturn)) 660 /// ~~~ ~~~~~~~~~~~~~ 661 TypeLoc getModifiedLoc() const { 662 return getInnerTypeLoc(); 663 } 664 665 /// The location of the attribute name, i.e. 666 /// __attribute__((regparm(1000))) 667 /// ^~~~~~~ 668 SourceLocation getAttrNameLoc() const { 669 return getLocalData()->AttrLoc; 670 } 671 void setAttrNameLoc(SourceLocation loc) { 672 getLocalData()->AttrLoc = loc; 673 } 674 675 /// The attribute's expression operand, if it has one. 676 /// void *cur_thread __attribute__((address_space(21))) 677 /// ^~ 678 Expr *getAttrExprOperand() const { 679 assert(hasAttrExprOperand()); 680 return getLocalData()->ExprOperand; 681 } 682 void setAttrExprOperand(Expr *e) { 683 assert(hasAttrExprOperand()); 684 getLocalData()->ExprOperand = e; 685 } 686 687 /// The location of the attribute's enumerated operand, if it has one. 688 /// void * __attribute__((objc_gc(weak))) 689 /// ^~~~ 690 SourceLocation getAttrEnumOperandLoc() const { 691 assert(hasAttrEnumOperand()); 692 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc); 693 } 694 void setAttrEnumOperandLoc(SourceLocation loc) { 695 assert(hasAttrEnumOperand()); 696 getLocalData()->EnumOperandLoc = loc.getRawEncoding(); 697 } 698 699 /// The location of the parentheses around the operand, if there is 700 /// an operand. 701 /// void * __attribute__((objc_gc(weak))) 702 /// ^ ^ 703 SourceRange getAttrOperandParensRange() const { 704 assert(hasAttrOperand()); 705 return getLocalData()->OperandParens; 706 } 707 void setAttrOperandParensRange(SourceRange range) { 708 assert(hasAttrOperand()); 709 getLocalData()->OperandParens = range; 710 } 711 712 SourceRange getLocalSourceRange() const { 713 // Note that this does *not* include the range of the attribute 714 // enclosure, e.g.: 715 // __attribute__((foo(bar))) 716 // ^~~~~~~~~~~~~~~ ~~ 717 // or 718 // [[foo(bar)]] 719 // ^~ ~~ 720 // That enclosure doesn't necessarily belong to a single attribute 721 // anyway. 722 SourceRange range(getAttrNameLoc()); 723 if (hasAttrOperand()) 724 range.setEnd(getAttrOperandParensRange().getEnd()); 725 return range; 726 } 727 728 void initializeLocal(ASTContext &Context, SourceLocation loc) { 729 setAttrNameLoc(loc); 730 if (hasAttrExprOperand()) { 731 setAttrOperandParensRange(SourceRange(loc)); 732 setAttrExprOperand(0); 733 } else if (hasAttrEnumOperand()) { 734 setAttrOperandParensRange(SourceRange(loc)); 735 setAttrEnumOperandLoc(loc); 736 } 737 } 738 739 QualType getInnerType() const { 740 return getTypePtr()->getModifiedType(); 741 } 742}; 743 744 745struct ObjCProtocolListLocInfo { 746 SourceLocation LAngleLoc; 747 SourceLocation RAngleLoc; 748 bool HasBaseTypeAsWritten; 749}; 750 751// A helper class for defining ObjC TypeLocs that can qualified with 752// protocols. 753// 754// TypeClass basically has to be either ObjCInterfaceType or 755// ObjCObjectPointerType. 756class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 757 ObjCObjectTypeLoc, 758 ObjCObjectType, 759 ObjCProtocolListLocInfo> { 760 // SourceLocations are stored after Info, one for each Protocol. 761 SourceLocation *getProtocolLocArray() const { 762 return (SourceLocation*) this->getExtraLocalData(); 763 } 764 765public: 766 SourceLocation getLAngleLoc() const { 767 return this->getLocalData()->LAngleLoc; 768 } 769 void setLAngleLoc(SourceLocation Loc) { 770 this->getLocalData()->LAngleLoc = Loc; 771 } 772 773 SourceLocation getRAngleLoc() const { 774 return this->getLocalData()->RAngleLoc; 775 } 776 void setRAngleLoc(SourceLocation Loc) { 777 this->getLocalData()->RAngleLoc = Loc; 778 } 779 780 unsigned getNumProtocols() const { 781 return this->getTypePtr()->getNumProtocols(); 782 } 783 784 SourceLocation getProtocolLoc(unsigned i) const { 785 assert(i < getNumProtocols() && "Index is out of bounds!"); 786 return getProtocolLocArray()[i]; 787 } 788 void setProtocolLoc(unsigned i, SourceLocation Loc) { 789 assert(i < getNumProtocols() && "Index is out of bounds!"); 790 getProtocolLocArray()[i] = Loc; 791 } 792 793 ObjCProtocolDecl *getProtocol(unsigned i) const { 794 assert(i < getNumProtocols() && "Index is out of bounds!"); 795 return *(this->getTypePtr()->qual_begin() + i); 796 } 797 798 bool hasBaseTypeAsWritten() const { 799 return getLocalData()->HasBaseTypeAsWritten; 800 } 801 802 void setHasBaseTypeAsWritten(bool HasBaseType) { 803 getLocalData()->HasBaseTypeAsWritten = HasBaseType; 804 } 805 806 TypeLoc getBaseLoc() const { 807 return getInnerTypeLoc(); 808 } 809 810 SourceRange getLocalSourceRange() const { 811 return SourceRange(getLAngleLoc(), getRAngleLoc()); 812 } 813 814 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 815 setHasBaseTypeAsWritten(true); 816 setLAngleLoc(Loc); 817 setRAngleLoc(Loc); 818 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 819 setProtocolLoc(i, Loc); 820 } 821 822 unsigned getExtraLocalDataSize() const { 823 return this->getNumProtocols() * sizeof(SourceLocation); 824 } 825 826 QualType getInnerType() const { 827 return getTypePtr()->getBaseType(); 828 } 829}; 830 831 832struct ObjCInterfaceLocInfo { 833 SourceLocation NameLoc; 834 SourceLocation NameEndLoc; 835}; 836 837/// \brief Wrapper for source info for ObjC interfaces. 838class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 839 ObjCInterfaceTypeLoc, 840 ObjCInterfaceType, 841 ObjCInterfaceLocInfo> { 842public: 843 ObjCInterfaceDecl *getIFaceDecl() const { 844 return getTypePtr()->getDecl(); 845 } 846 847 SourceLocation getNameLoc() const { 848 return getLocalData()->NameLoc; 849 } 850 851 void setNameLoc(SourceLocation Loc) { 852 getLocalData()->NameLoc = Loc; 853 } 854 855 SourceRange getLocalSourceRange() const { 856 return SourceRange(getNameLoc(), getNameEndLoc()); 857 } 858 859 SourceLocation getNameEndLoc() const { 860 return getLocalData()->NameEndLoc; 861 } 862 863 void setNameEndLoc(SourceLocation Loc) { 864 getLocalData()->NameEndLoc = Loc; 865 } 866 867 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 868 setNameLoc(Loc); 869 } 870}; 871 872struct ParenLocInfo { 873 SourceLocation LParenLoc; 874 SourceLocation RParenLoc; 875}; 876 877class ParenTypeLoc 878 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 879 ParenLocInfo> { 880public: 881 SourceLocation getLParenLoc() const { 882 return this->getLocalData()->LParenLoc; 883 } 884 SourceLocation getRParenLoc() const { 885 return this->getLocalData()->RParenLoc; 886 } 887 void setLParenLoc(SourceLocation Loc) { 888 this->getLocalData()->LParenLoc = Loc; 889 } 890 void setRParenLoc(SourceLocation Loc) { 891 this->getLocalData()->RParenLoc = Loc; 892 } 893 894 SourceRange getLocalSourceRange() const { 895 return SourceRange(getLParenLoc(), getRParenLoc()); 896 } 897 898 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 899 setLParenLoc(Loc); 900 setRParenLoc(Loc); 901 } 902 903 TypeLoc getInnerLoc() const { 904 return getInnerTypeLoc(); 905 } 906 907 QualType getInnerType() const { 908 return this->getTypePtr()->getInnerType(); 909 } 910}; 911 912 913struct PointerLikeLocInfo { 914 SourceLocation StarLoc; 915}; 916 917/// A base class for 918template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 919class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 920 TypeClass, LocalData> { 921public: 922 SourceLocation getSigilLoc() const { 923 return this->getLocalData()->StarLoc; 924 } 925 void setSigilLoc(SourceLocation Loc) { 926 this->getLocalData()->StarLoc = Loc; 927 } 928 929 TypeLoc getPointeeLoc() const { 930 return this->getInnerTypeLoc(); 931 } 932 933 SourceRange getLocalSourceRange() const { 934 return SourceRange(getSigilLoc(), getSigilLoc()); 935 } 936 937 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 938 setSigilLoc(Loc); 939 } 940 941 QualType getInnerType() const { 942 return this->getTypePtr()->getPointeeType(); 943 } 944}; 945 946 947/// \brief Wrapper for source info for pointers. 948class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 949 PointerType> { 950public: 951 SourceLocation getStarLoc() const { 952 return getSigilLoc(); 953 } 954 void setStarLoc(SourceLocation Loc) { 955 setSigilLoc(Loc); 956 } 957}; 958 959 960/// \brief Wrapper for source info for block pointers. 961class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 962 BlockPointerType> { 963public: 964 SourceLocation getCaretLoc() const { 965 return getSigilLoc(); 966 } 967 void setCaretLoc(SourceLocation Loc) { 968 setSigilLoc(Loc); 969 } 970}; 971 972struct MemberPointerLocInfo : public PointerLikeLocInfo { 973 TypeSourceInfo *ClassTInfo; 974}; 975 976/// \brief Wrapper for source info for member pointers. 977class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 978 MemberPointerType, 979 MemberPointerLocInfo> { 980public: 981 SourceLocation getStarLoc() const { 982 return getSigilLoc(); 983 } 984 void setStarLoc(SourceLocation Loc) { 985 setSigilLoc(Loc); 986 } 987 988 const Type *getClass() const { 989 return getTypePtr()->getClass(); 990 } 991 TypeSourceInfo *getClassTInfo() const { 992 return getLocalData()->ClassTInfo; 993 } 994 void setClassTInfo(TypeSourceInfo* TI) { 995 getLocalData()->ClassTInfo = TI; 996 } 997 998 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 999 setSigilLoc(Loc); 1000 setClassTInfo(0); 1001 } 1002 1003 SourceRange getLocalSourceRange() const { 1004 if (TypeSourceInfo *TI = getClassTInfo()) 1005 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 1006 else 1007 return SourceRange(getStarLoc()); 1008 } 1009}; 1010 1011/// Wraps an ObjCPointerType with source location information. 1012class ObjCObjectPointerTypeLoc : 1013 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1014 ObjCObjectPointerType> { 1015public: 1016 SourceLocation getStarLoc() const { 1017 return getSigilLoc(); 1018 } 1019 1020 void setStarLoc(SourceLocation Loc) { 1021 setSigilLoc(Loc); 1022 } 1023}; 1024 1025 1026class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1027 ReferenceType> { 1028public: 1029 QualType getInnerType() const { 1030 return getTypePtr()->getPointeeTypeAsWritten(); 1031 } 1032}; 1033 1034class LValueReferenceTypeLoc : 1035 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1036 LValueReferenceTypeLoc, 1037 LValueReferenceType> { 1038public: 1039 SourceLocation getAmpLoc() const { 1040 return getSigilLoc(); 1041 } 1042 void setAmpLoc(SourceLocation Loc) { 1043 setSigilLoc(Loc); 1044 } 1045}; 1046 1047class RValueReferenceTypeLoc : 1048 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1049 RValueReferenceTypeLoc, 1050 RValueReferenceType> { 1051public: 1052 SourceLocation getAmpAmpLoc() const { 1053 return getSigilLoc(); 1054 } 1055 void setAmpAmpLoc(SourceLocation Loc) { 1056 setSigilLoc(Loc); 1057 } 1058}; 1059 1060 1061struct FunctionLocInfo { 1062 SourceLocation LocalRangeBegin; 1063 SourceLocation LocalRangeEnd; 1064}; 1065 1066/// \brief Wrapper for source info for functions. 1067class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1068 FunctionTypeLoc, 1069 FunctionType, 1070 FunctionLocInfo> { 1071public: 1072 SourceLocation getLocalRangeBegin() const { 1073 return getLocalData()->LocalRangeBegin; 1074 } 1075 void setLocalRangeBegin(SourceLocation L) { 1076 getLocalData()->LocalRangeBegin = L; 1077 } 1078 1079 SourceLocation getLocalRangeEnd() const { 1080 return getLocalData()->LocalRangeEnd; 1081 } 1082 void setLocalRangeEnd(SourceLocation L) { 1083 getLocalData()->LocalRangeEnd = L; 1084 } 1085 1086 ArrayRef<ParmVarDecl *> getParams() const { 1087 return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs()); 1088 } 1089 1090 // ParmVarDecls* are stored after Info, one for each argument. 1091 ParmVarDecl **getParmArray() const { 1092 return (ParmVarDecl**) getExtraLocalData(); 1093 } 1094 1095 unsigned getNumArgs() const { 1096 if (isa<FunctionNoProtoType>(getTypePtr())) 1097 return 0; 1098 return cast<FunctionProtoType>(getTypePtr())->getNumArgs(); 1099 } 1100 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } 1101 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1102 1103 TypeLoc getResultLoc() const { 1104 return getInnerTypeLoc(); 1105 } 1106 1107 SourceRange getLocalSourceRange() const { 1108 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1109 } 1110 1111 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1112 setLocalRangeBegin(Loc); 1113 setLocalRangeEnd(Loc); 1114 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) 1115 setArg(i, NULL); 1116 } 1117 1118 /// \brief Returns the size of the type source info data block that is 1119 /// specific to this type. 1120 unsigned getExtraLocalDataSize() const { 1121 return getNumArgs() * sizeof(ParmVarDecl*); 1122 } 1123 1124 QualType getInnerType() const { return getTypePtr()->getResultType(); } 1125}; 1126 1127class FunctionProtoTypeLoc : 1128 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1129 FunctionProtoTypeLoc, 1130 FunctionProtoType> { 1131}; 1132 1133class FunctionNoProtoTypeLoc : 1134 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1135 FunctionNoProtoTypeLoc, 1136 FunctionNoProtoType> { 1137}; 1138 1139 1140struct ArrayLocInfo { 1141 SourceLocation LBracketLoc, RBracketLoc; 1142 Expr *Size; 1143}; 1144 1145/// \brief Wrapper for source info for arrays. 1146class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1147 ArrayTypeLoc, 1148 ArrayType, 1149 ArrayLocInfo> { 1150public: 1151 SourceLocation getLBracketLoc() const { 1152 return getLocalData()->LBracketLoc; 1153 } 1154 void setLBracketLoc(SourceLocation Loc) { 1155 getLocalData()->LBracketLoc = Loc; 1156 } 1157 1158 SourceLocation getRBracketLoc() const { 1159 return getLocalData()->RBracketLoc; 1160 } 1161 void setRBracketLoc(SourceLocation Loc) { 1162 getLocalData()->RBracketLoc = Loc; 1163 } 1164 1165 SourceRange getBracketsRange() const { 1166 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1167 } 1168 1169 Expr *getSizeExpr() const { 1170 return getLocalData()->Size; 1171 } 1172 void setSizeExpr(Expr *Size) { 1173 getLocalData()->Size = Size; 1174 } 1175 1176 TypeLoc getElementLoc() const { 1177 return getInnerTypeLoc(); 1178 } 1179 1180 SourceRange getLocalSourceRange() const { 1181 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1182 } 1183 1184 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1185 setLBracketLoc(Loc); 1186 setRBracketLoc(Loc); 1187 setSizeExpr(NULL); 1188 } 1189 1190 QualType getInnerType() const { return getTypePtr()->getElementType(); } 1191}; 1192 1193class ConstantArrayTypeLoc : 1194 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1195 ConstantArrayTypeLoc, 1196 ConstantArrayType> { 1197}; 1198 1199class IncompleteArrayTypeLoc : 1200 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1201 IncompleteArrayTypeLoc, 1202 IncompleteArrayType> { 1203}; 1204 1205class DependentSizedArrayTypeLoc : 1206 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1207 DependentSizedArrayTypeLoc, 1208 DependentSizedArrayType> { 1209 1210}; 1211 1212class VariableArrayTypeLoc : 1213 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1214 VariableArrayTypeLoc, 1215 VariableArrayType> { 1216}; 1217 1218 1219// Location information for a TemplateName. Rudimentary for now. 1220struct TemplateNameLocInfo { 1221 SourceLocation NameLoc; 1222}; 1223 1224struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1225 SourceLocation TemplateKWLoc; 1226 SourceLocation LAngleLoc; 1227 SourceLocation RAngleLoc; 1228}; 1229 1230class TemplateSpecializationTypeLoc : 1231 public ConcreteTypeLoc<UnqualTypeLoc, 1232 TemplateSpecializationTypeLoc, 1233 TemplateSpecializationType, 1234 TemplateSpecializationLocInfo> { 1235public: 1236 SourceLocation getTemplateKeywordLoc() const { 1237 return getLocalData()->TemplateKWLoc; 1238 } 1239 void setTemplateKeywordLoc(SourceLocation Loc) { 1240 getLocalData()->TemplateKWLoc = Loc; 1241 } 1242 1243 SourceLocation getLAngleLoc() const { 1244 return getLocalData()->LAngleLoc; 1245 } 1246 void setLAngleLoc(SourceLocation Loc) { 1247 getLocalData()->LAngleLoc = Loc; 1248 } 1249 1250 SourceLocation getRAngleLoc() const { 1251 return getLocalData()->RAngleLoc; 1252 } 1253 void setRAngleLoc(SourceLocation Loc) { 1254 getLocalData()->RAngleLoc = Loc; 1255 } 1256 1257 unsigned getNumArgs() const { 1258 return getTypePtr()->getNumArgs(); 1259 } 1260 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1261 getArgInfos()[i] = AI; 1262 } 1263 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1264 return getArgInfos()[i]; 1265 } 1266 1267 TemplateArgumentLoc getArgLoc(unsigned i) const { 1268 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1269 } 1270 1271 SourceLocation getTemplateNameLoc() const { 1272 return getLocalData()->NameLoc; 1273 } 1274 void setTemplateNameLoc(SourceLocation Loc) { 1275 getLocalData()->NameLoc = Loc; 1276 } 1277 1278 /// \brief - Copy the location information from the given info. 1279 void copy(TemplateSpecializationTypeLoc Loc) { 1280 unsigned size = getFullDataSize(); 1281 assert(size == Loc.getFullDataSize()); 1282 1283 // We're potentially copying Expr references here. We don't 1284 // bother retaining them because TypeSourceInfos live forever, so 1285 // as long as the Expr was retained when originally written into 1286 // the TypeLoc, we're okay. 1287 memcpy(Data, Loc.Data, size); 1288 } 1289 1290 SourceRange getLocalSourceRange() const { 1291 if (getTemplateKeywordLoc().isValid()) 1292 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1293 else 1294 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1295 } 1296 1297 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1298 setTemplateKeywordLoc(Loc); 1299 setTemplateNameLoc(Loc); 1300 setLAngleLoc(Loc); 1301 setRAngleLoc(Loc); 1302 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), 1303 getArgInfos(), Loc); 1304 } 1305 1306 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, 1307 const TemplateArgument *Args, 1308 TemplateArgumentLocInfo *ArgInfos, 1309 SourceLocation Loc); 1310 1311 unsigned getExtraLocalDataSize() const { 1312 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1313 } 1314 1315private: 1316 TemplateArgumentLocInfo *getArgInfos() const { 1317 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1318 } 1319}; 1320 1321//===----------------------------------------------------------------------===// 1322// 1323// All of these need proper implementations. 1324// 1325//===----------------------------------------------------------------------===// 1326 1327// FIXME: size expression and attribute locations (or keyword if we 1328// ever fully support altivec syntax). 1329class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1330 VectorTypeLoc, 1331 VectorType> { 1332}; 1333 1334// FIXME: size expression and attribute locations. 1335class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1336 ExtVectorTypeLoc, 1337 ExtVectorType> { 1338}; 1339 1340// FIXME: attribute locations. 1341// For some reason, this isn't a subtype of VectorType. 1342class DependentSizedExtVectorTypeLoc : 1343 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1344 DependentSizedExtVectorTypeLoc, 1345 DependentSizedExtVectorType> { 1346}; 1347 1348// FIXME: location of the '_Complex' keyword. 1349class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1350 ComplexTypeLoc, 1351 ComplexType> { 1352}; 1353 1354struct TypeofLocInfo { 1355 SourceLocation TypeofLoc; 1356 SourceLocation LParenLoc; 1357 SourceLocation RParenLoc; 1358}; 1359 1360struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1361}; 1362 1363struct TypeOfTypeLocInfo : public TypeofLocInfo { 1364 TypeSourceInfo* UnderlyingTInfo; 1365}; 1366 1367template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1368class TypeofLikeTypeLoc 1369 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1370public: 1371 SourceLocation getTypeofLoc() const { 1372 return this->getLocalData()->TypeofLoc; 1373 } 1374 void setTypeofLoc(SourceLocation Loc) { 1375 this->getLocalData()->TypeofLoc = Loc; 1376 } 1377 1378 SourceLocation getLParenLoc() const { 1379 return this->getLocalData()->LParenLoc; 1380 } 1381 void setLParenLoc(SourceLocation Loc) { 1382 this->getLocalData()->LParenLoc = Loc; 1383 } 1384 1385 SourceLocation getRParenLoc() const { 1386 return this->getLocalData()->RParenLoc; 1387 } 1388 void setRParenLoc(SourceLocation Loc) { 1389 this->getLocalData()->RParenLoc = Loc; 1390 } 1391 1392 SourceRange getParensRange() const { 1393 return SourceRange(getLParenLoc(), getRParenLoc()); 1394 } 1395 void setParensRange(SourceRange range) { 1396 setLParenLoc(range.getBegin()); 1397 setRParenLoc(range.getEnd()); 1398 } 1399 1400 SourceRange getLocalSourceRange() const { 1401 return SourceRange(getTypeofLoc(), getRParenLoc()); 1402 } 1403 1404 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1405 setTypeofLoc(Loc); 1406 setLParenLoc(Loc); 1407 setRParenLoc(Loc); 1408 } 1409}; 1410 1411class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1412 TypeOfExprType, 1413 TypeOfExprTypeLocInfo> { 1414public: 1415 Expr* getUnderlyingExpr() const { 1416 return getTypePtr()->getUnderlyingExpr(); 1417 } 1418 // Reimplemented to account for GNU/C++ extension 1419 // typeof unary-expression 1420 // where there are no parentheses. 1421 SourceRange getLocalSourceRange() const; 1422}; 1423 1424class TypeOfTypeLoc 1425 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1426public: 1427 QualType getUnderlyingType() const { 1428 return this->getTypePtr()->getUnderlyingType(); 1429 } 1430 TypeSourceInfo* getUnderlyingTInfo() const { 1431 return this->getLocalData()->UnderlyingTInfo; 1432 } 1433 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1434 this->getLocalData()->UnderlyingTInfo = TI; 1435 } 1436}; 1437 1438// FIXME: location of the 'decltype' and parens. 1439class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1440 DecltypeTypeLoc, 1441 DecltypeType> { 1442public: 1443 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1444}; 1445 1446struct UnaryTransformTypeLocInfo { 1447 // FIXME: While there's only one unary transform right now, future ones may 1448 // need different representations 1449 SourceLocation KWLoc, LParenLoc, RParenLoc; 1450 TypeSourceInfo *UnderlyingTInfo; 1451}; 1452 1453class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1454 UnaryTransformTypeLoc, 1455 UnaryTransformType, 1456 UnaryTransformTypeLocInfo> { 1457public: 1458 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1459 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1460 1461 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1462 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1463 1464 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1465 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1466 1467 TypeSourceInfo* getUnderlyingTInfo() const { 1468 return getLocalData()->UnderlyingTInfo; 1469 } 1470 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1471 getLocalData()->UnderlyingTInfo = TInfo; 1472 } 1473 1474 SourceRange getLocalSourceRange() const { 1475 return SourceRange(getKWLoc(), getRParenLoc()); 1476 } 1477 1478 SourceRange getParensRange() const { 1479 return SourceRange(getLParenLoc(), getRParenLoc()); 1480 } 1481 void setParensRange(SourceRange Range) { 1482 setLParenLoc(Range.getBegin()); 1483 setRParenLoc(Range.getEnd()); 1484 } 1485 1486 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1487 setKWLoc(Loc); 1488 setRParenLoc(Loc); 1489 setLParenLoc(Loc); 1490 } 1491}; 1492 1493class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1494 AutoTypeLoc, 1495 AutoType> { 1496}; 1497 1498struct ElaboratedLocInfo { 1499 SourceLocation ElaboratedKWLoc; 1500 /// \brief Data associated with the nested-name-specifier location. 1501 void *QualifierData; 1502}; 1503 1504class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1505 ElaboratedTypeLoc, 1506 ElaboratedType, 1507 ElaboratedLocInfo> { 1508public: 1509 SourceLocation getElaboratedKeywordLoc() const { 1510 return this->getLocalData()->ElaboratedKWLoc; 1511 } 1512 void setElaboratedKeywordLoc(SourceLocation Loc) { 1513 this->getLocalData()->ElaboratedKWLoc = Loc; 1514 } 1515 1516 NestedNameSpecifierLoc getQualifierLoc() const { 1517 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1518 getLocalData()->QualifierData); 1519 } 1520 1521 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1522 assert(QualifierLoc.getNestedNameSpecifier() 1523 == getTypePtr()->getQualifier() && 1524 "Inconsistent nested-name-specifier pointer"); 1525 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1526 } 1527 1528 SourceRange getLocalSourceRange() const { 1529 if (getElaboratedKeywordLoc().isValid()) 1530 if (getQualifierLoc()) 1531 return SourceRange(getElaboratedKeywordLoc(), 1532 getQualifierLoc().getEndLoc()); 1533 else 1534 return SourceRange(getElaboratedKeywordLoc()); 1535 else 1536 return getQualifierLoc().getSourceRange(); 1537 } 1538 1539 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1540 1541 TypeLoc getNamedTypeLoc() const { 1542 return getInnerTypeLoc(); 1543 } 1544 1545 QualType getInnerType() const { 1546 return getTypePtr()->getNamedType(); 1547 } 1548 1549 void copy(ElaboratedTypeLoc Loc) { 1550 unsigned size = getFullDataSize(); 1551 assert(size == Loc.getFullDataSize()); 1552 memcpy(Data, Loc.Data, size); 1553 } 1554}; 1555 1556// This is exactly the structure of an ElaboratedTypeLoc whose inner 1557// type is some sort of TypeDeclTypeLoc. 1558struct DependentNameLocInfo : ElaboratedLocInfo { 1559 SourceLocation NameLoc; 1560}; 1561 1562class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1563 DependentNameTypeLoc, 1564 DependentNameType, 1565 DependentNameLocInfo> { 1566public: 1567 SourceLocation getElaboratedKeywordLoc() const { 1568 return this->getLocalData()->ElaboratedKWLoc; 1569 } 1570 void setElaboratedKeywordLoc(SourceLocation Loc) { 1571 this->getLocalData()->ElaboratedKWLoc = Loc; 1572 } 1573 1574 NestedNameSpecifierLoc getQualifierLoc() const { 1575 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1576 getLocalData()->QualifierData); 1577 } 1578 1579 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1580 assert(QualifierLoc.getNestedNameSpecifier() 1581 == getTypePtr()->getQualifier() && 1582 "Inconsistent nested-name-specifier pointer"); 1583 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1584 } 1585 1586 SourceLocation getNameLoc() const { 1587 return this->getLocalData()->NameLoc; 1588 } 1589 void setNameLoc(SourceLocation Loc) { 1590 this->getLocalData()->NameLoc = Loc; 1591 } 1592 1593 SourceRange getLocalSourceRange() const { 1594 if (getElaboratedKeywordLoc().isValid()) 1595 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 1596 else 1597 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 1598 } 1599 1600 void copy(DependentNameTypeLoc Loc) { 1601 unsigned size = getFullDataSize(); 1602 assert(size == Loc.getFullDataSize()); 1603 memcpy(Data, Loc.Data, size); 1604 } 1605 1606 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1607}; 1608 1609struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 1610 SourceLocation TemplateKWLoc; 1611 SourceLocation LAngleLoc; 1612 SourceLocation RAngleLoc; 1613 // followed by a TemplateArgumentLocInfo[] 1614}; 1615 1616class DependentTemplateSpecializationTypeLoc : 1617 public ConcreteTypeLoc<UnqualTypeLoc, 1618 DependentTemplateSpecializationTypeLoc, 1619 DependentTemplateSpecializationType, 1620 DependentTemplateSpecializationLocInfo> { 1621public: 1622 SourceLocation getElaboratedKeywordLoc() const { 1623 return this->getLocalData()->ElaboratedKWLoc; 1624 } 1625 void setElaboratedKeywordLoc(SourceLocation Loc) { 1626 this->getLocalData()->ElaboratedKWLoc = Loc; 1627 } 1628 1629 NestedNameSpecifierLoc getQualifierLoc() const { 1630 if (!getLocalData()->QualifierData) 1631 return NestedNameSpecifierLoc(); 1632 1633 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1634 getLocalData()->QualifierData); 1635 } 1636 1637 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1638 if (!QualifierLoc) { 1639 // Even if we have a nested-name-specifier in the dependent 1640 // template specialization type, we won't record the nested-name-specifier 1641 // location information when this type-source location information is 1642 // part of a nested-name-specifier. 1643 getLocalData()->QualifierData = 0; 1644 return; 1645 } 1646 1647 assert(QualifierLoc.getNestedNameSpecifier() 1648 == getTypePtr()->getQualifier() && 1649 "Inconsistent nested-name-specifier pointer"); 1650 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1651 } 1652 1653 SourceLocation getTemplateKeywordLoc() const { 1654 return getLocalData()->TemplateKWLoc; 1655 } 1656 void setTemplateKeywordLoc(SourceLocation Loc) { 1657 getLocalData()->TemplateKWLoc = Loc; 1658 } 1659 1660 SourceLocation getTemplateNameLoc() const { 1661 return this->getLocalData()->NameLoc; 1662 } 1663 void setTemplateNameLoc(SourceLocation Loc) { 1664 this->getLocalData()->NameLoc = Loc; 1665 } 1666 1667 SourceLocation getLAngleLoc() const { 1668 return this->getLocalData()->LAngleLoc; 1669 } 1670 void setLAngleLoc(SourceLocation Loc) { 1671 this->getLocalData()->LAngleLoc = Loc; 1672 } 1673 1674 SourceLocation getRAngleLoc() const { 1675 return this->getLocalData()->RAngleLoc; 1676 } 1677 void setRAngleLoc(SourceLocation Loc) { 1678 this->getLocalData()->RAngleLoc = Loc; 1679 } 1680 1681 unsigned getNumArgs() const { 1682 return getTypePtr()->getNumArgs(); 1683 } 1684 1685 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1686 getArgInfos()[i] = AI; 1687 } 1688 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1689 return getArgInfos()[i]; 1690 } 1691 1692 TemplateArgumentLoc getArgLoc(unsigned i) const { 1693 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1694 } 1695 1696 SourceRange getLocalSourceRange() const { 1697 if (getElaboratedKeywordLoc().isValid()) 1698 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 1699 else if (getQualifierLoc()) 1700 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 1701 else if (getTemplateKeywordLoc().isValid()) 1702 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1703 else 1704 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1705 } 1706 1707 void copy(DependentTemplateSpecializationTypeLoc Loc) { 1708 unsigned size = getFullDataSize(); 1709 assert(size == Loc.getFullDataSize()); 1710 memcpy(Data, Loc.Data, size); 1711 } 1712 1713 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1714 1715 unsigned getExtraLocalDataSize() const { 1716 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1717 } 1718 1719private: 1720 TemplateArgumentLocInfo *getArgInfos() const { 1721 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1722 } 1723}; 1724 1725 1726struct PackExpansionTypeLocInfo { 1727 SourceLocation EllipsisLoc; 1728}; 1729 1730class PackExpansionTypeLoc 1731 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 1732 PackExpansionType, PackExpansionTypeLocInfo> { 1733public: 1734 SourceLocation getEllipsisLoc() const { 1735 return this->getLocalData()->EllipsisLoc; 1736 } 1737 1738 void setEllipsisLoc(SourceLocation Loc) { 1739 this->getLocalData()->EllipsisLoc = Loc; 1740 } 1741 1742 SourceRange getLocalSourceRange() const { 1743 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 1744 } 1745 1746 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1747 setEllipsisLoc(Loc); 1748 } 1749 1750 TypeLoc getPatternLoc() const { 1751 return getInnerTypeLoc(); 1752 } 1753 1754 QualType getInnerType() const { 1755 return this->getTypePtr()->getPattern(); 1756 } 1757}; 1758 1759struct AtomicTypeLocInfo { 1760 SourceLocation KWLoc, LParenLoc, RParenLoc; 1761}; 1762 1763class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 1764 AtomicType, AtomicTypeLocInfo> { 1765public: 1766 TypeLoc getValueLoc() const { 1767 return this->getInnerTypeLoc(); 1768 } 1769 1770 SourceRange getLocalSourceRange() const { 1771 return SourceRange(getKWLoc(), getRParenLoc()); 1772 } 1773 1774 SourceLocation getKWLoc() const { 1775 return this->getLocalData()->KWLoc; 1776 } 1777 void setKWLoc(SourceLocation Loc) { 1778 this->getLocalData()->KWLoc = Loc; 1779 } 1780 1781 SourceLocation getLParenLoc() const { 1782 return this->getLocalData()->LParenLoc; 1783 } 1784 void setLParenLoc(SourceLocation Loc) { 1785 this->getLocalData()->LParenLoc = Loc; 1786 } 1787 1788 SourceLocation getRParenLoc() const { 1789 return this->getLocalData()->RParenLoc; 1790 } 1791 void setRParenLoc(SourceLocation Loc) { 1792 this->getLocalData()->RParenLoc = Loc; 1793 } 1794 1795 SourceRange getParensRange() const { 1796 return SourceRange(getLParenLoc(), getRParenLoc()); 1797 } 1798 void setParensRange(SourceRange Range) { 1799 setLParenLoc(Range.getBegin()); 1800 setRParenLoc(Range.getEnd()); 1801 } 1802 1803 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1804 setKWLoc(Loc); 1805 setLParenLoc(Loc); 1806 setRParenLoc(Loc); 1807 } 1808 1809 QualType getInnerType() const { 1810 return this->getTypePtr()->getValueType(); 1811 } 1812}; 1813 1814 1815} 1816 1817#endif 1818