TypeLoc.h revision 1de6a6cb485fb58b4fb100282bb3cf298eedacd9
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/// \param Base a class from which to derive 254/// \param Derived the class deriving from this one 255/// \param TypeClass the concrete Type subclass associated with this 256/// location type 257/// \param 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 bool TrailingReturn; 1065}; 1066 1067/// \brief Wrapper for source info for functions. 1068class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1069 FunctionTypeLoc, 1070 FunctionType, 1071 FunctionLocInfo> { 1072public: 1073 SourceLocation getLocalRangeBegin() const { 1074 return getLocalData()->LocalRangeBegin; 1075 } 1076 void setLocalRangeBegin(SourceLocation L) { 1077 getLocalData()->LocalRangeBegin = L; 1078 } 1079 1080 SourceLocation getLocalRangeEnd() const { 1081 return getLocalData()->LocalRangeEnd; 1082 } 1083 void setLocalRangeEnd(SourceLocation L) { 1084 getLocalData()->LocalRangeEnd = L; 1085 } 1086 1087 bool getTrailingReturn() const { 1088 return getLocalData()->TrailingReturn; 1089 } 1090 void setTrailingReturn(bool Trailing) { 1091 getLocalData()->TrailingReturn = Trailing; 1092 } 1093 1094 ArrayRef<ParmVarDecl *> getParams() const { 1095 return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs()); 1096 } 1097 1098 // ParmVarDecls* are stored after Info, one for each argument. 1099 ParmVarDecl **getParmArray() const { 1100 return (ParmVarDecl**) getExtraLocalData(); 1101 } 1102 1103 unsigned getNumArgs() const { 1104 if (isa<FunctionNoProtoType>(getTypePtr())) 1105 return 0; 1106 return cast<FunctionProtoType>(getTypePtr())->getNumArgs(); 1107 } 1108 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } 1109 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1110 1111 TypeLoc getResultLoc() const { 1112 return getInnerTypeLoc(); 1113 } 1114 1115 SourceRange getLocalSourceRange() const { 1116 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1117 } 1118 1119 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1120 setLocalRangeBegin(Loc); 1121 setLocalRangeEnd(Loc); 1122 setTrailingReturn(false); 1123 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) 1124 setArg(i, NULL); 1125 } 1126 1127 /// \brief Returns the size of the type source info data block that is 1128 /// specific to this type. 1129 unsigned getExtraLocalDataSize() const { 1130 return getNumArgs() * sizeof(ParmVarDecl*); 1131 } 1132 1133 QualType getInnerType() const { return getTypePtr()->getResultType(); } 1134}; 1135 1136class FunctionProtoTypeLoc : 1137 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1138 FunctionProtoTypeLoc, 1139 FunctionProtoType> { 1140}; 1141 1142class FunctionNoProtoTypeLoc : 1143 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1144 FunctionNoProtoTypeLoc, 1145 FunctionNoProtoType> { 1146}; 1147 1148 1149struct ArrayLocInfo { 1150 SourceLocation LBracketLoc, RBracketLoc; 1151 Expr *Size; 1152}; 1153 1154/// \brief Wrapper for source info for arrays. 1155class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1156 ArrayTypeLoc, 1157 ArrayType, 1158 ArrayLocInfo> { 1159public: 1160 SourceLocation getLBracketLoc() const { 1161 return getLocalData()->LBracketLoc; 1162 } 1163 void setLBracketLoc(SourceLocation Loc) { 1164 getLocalData()->LBracketLoc = Loc; 1165 } 1166 1167 SourceLocation getRBracketLoc() const { 1168 return getLocalData()->RBracketLoc; 1169 } 1170 void setRBracketLoc(SourceLocation Loc) { 1171 getLocalData()->RBracketLoc = Loc; 1172 } 1173 1174 SourceRange getBracketsRange() const { 1175 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1176 } 1177 1178 Expr *getSizeExpr() const { 1179 return getLocalData()->Size; 1180 } 1181 void setSizeExpr(Expr *Size) { 1182 getLocalData()->Size = Size; 1183 } 1184 1185 TypeLoc getElementLoc() const { 1186 return getInnerTypeLoc(); 1187 } 1188 1189 SourceRange getLocalSourceRange() const { 1190 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1191 } 1192 1193 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1194 setLBracketLoc(Loc); 1195 setRBracketLoc(Loc); 1196 setSizeExpr(NULL); 1197 } 1198 1199 QualType getInnerType() const { return getTypePtr()->getElementType(); } 1200}; 1201 1202class ConstantArrayTypeLoc : 1203 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1204 ConstantArrayTypeLoc, 1205 ConstantArrayType> { 1206}; 1207 1208class IncompleteArrayTypeLoc : 1209 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1210 IncompleteArrayTypeLoc, 1211 IncompleteArrayType> { 1212}; 1213 1214class DependentSizedArrayTypeLoc : 1215 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1216 DependentSizedArrayTypeLoc, 1217 DependentSizedArrayType> { 1218 1219}; 1220 1221class VariableArrayTypeLoc : 1222 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1223 VariableArrayTypeLoc, 1224 VariableArrayType> { 1225}; 1226 1227 1228// Location information for a TemplateName. Rudimentary for now. 1229struct TemplateNameLocInfo { 1230 SourceLocation NameLoc; 1231}; 1232 1233struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1234 SourceLocation TemplateKWLoc; 1235 SourceLocation LAngleLoc; 1236 SourceLocation RAngleLoc; 1237}; 1238 1239class TemplateSpecializationTypeLoc : 1240 public ConcreteTypeLoc<UnqualTypeLoc, 1241 TemplateSpecializationTypeLoc, 1242 TemplateSpecializationType, 1243 TemplateSpecializationLocInfo> { 1244public: 1245 SourceLocation getTemplateKeywordLoc() const { 1246 return getLocalData()->TemplateKWLoc; 1247 } 1248 void setTemplateKeywordLoc(SourceLocation Loc) { 1249 getLocalData()->TemplateKWLoc = Loc; 1250 } 1251 1252 SourceLocation getLAngleLoc() const { 1253 return getLocalData()->LAngleLoc; 1254 } 1255 void setLAngleLoc(SourceLocation Loc) { 1256 getLocalData()->LAngleLoc = Loc; 1257 } 1258 1259 SourceLocation getRAngleLoc() const { 1260 return getLocalData()->RAngleLoc; 1261 } 1262 void setRAngleLoc(SourceLocation Loc) { 1263 getLocalData()->RAngleLoc = Loc; 1264 } 1265 1266 unsigned getNumArgs() const { 1267 return getTypePtr()->getNumArgs(); 1268 } 1269 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1270 getArgInfos()[i] = AI; 1271 } 1272 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1273 return getArgInfos()[i]; 1274 } 1275 1276 TemplateArgumentLoc getArgLoc(unsigned i) const { 1277 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1278 } 1279 1280 SourceLocation getTemplateNameLoc() const { 1281 return getLocalData()->NameLoc; 1282 } 1283 void setTemplateNameLoc(SourceLocation Loc) { 1284 getLocalData()->NameLoc = Loc; 1285 } 1286 1287 /// \brief - Copy the location information from the given info. 1288 void copy(TemplateSpecializationTypeLoc Loc) { 1289 unsigned size = getFullDataSize(); 1290 assert(size == Loc.getFullDataSize()); 1291 1292 // We're potentially copying Expr references here. We don't 1293 // bother retaining them because TypeSourceInfos live forever, so 1294 // as long as the Expr was retained when originally written into 1295 // the TypeLoc, we're okay. 1296 memcpy(Data, Loc.Data, size); 1297 } 1298 1299 SourceRange getLocalSourceRange() const { 1300 if (getTemplateKeywordLoc().isValid()) 1301 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1302 else 1303 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1304 } 1305 1306 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1307 setTemplateKeywordLoc(Loc); 1308 setTemplateNameLoc(Loc); 1309 setLAngleLoc(Loc); 1310 setRAngleLoc(Loc); 1311 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), 1312 getArgInfos(), Loc); 1313 } 1314 1315 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, 1316 const TemplateArgument *Args, 1317 TemplateArgumentLocInfo *ArgInfos, 1318 SourceLocation Loc); 1319 1320 unsigned getExtraLocalDataSize() const { 1321 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1322 } 1323 1324private: 1325 TemplateArgumentLocInfo *getArgInfos() const { 1326 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1327 } 1328}; 1329 1330//===----------------------------------------------------------------------===// 1331// 1332// All of these need proper implementations. 1333// 1334//===----------------------------------------------------------------------===// 1335 1336// FIXME: size expression and attribute locations (or keyword if we 1337// ever fully support altivec syntax). 1338class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1339 VectorTypeLoc, 1340 VectorType> { 1341}; 1342 1343// FIXME: size expression and attribute locations. 1344class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1345 ExtVectorTypeLoc, 1346 ExtVectorType> { 1347}; 1348 1349// FIXME: attribute locations. 1350// For some reason, this isn't a subtype of VectorType. 1351class DependentSizedExtVectorTypeLoc : 1352 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1353 DependentSizedExtVectorTypeLoc, 1354 DependentSizedExtVectorType> { 1355}; 1356 1357// FIXME: location of the '_Complex' keyword. 1358class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1359 ComplexTypeLoc, 1360 ComplexType> { 1361}; 1362 1363struct TypeofLocInfo { 1364 SourceLocation TypeofLoc; 1365 SourceLocation LParenLoc; 1366 SourceLocation RParenLoc; 1367}; 1368 1369struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1370}; 1371 1372struct TypeOfTypeLocInfo : public TypeofLocInfo { 1373 TypeSourceInfo* UnderlyingTInfo; 1374}; 1375 1376template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1377class TypeofLikeTypeLoc 1378 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1379public: 1380 SourceLocation getTypeofLoc() const { 1381 return this->getLocalData()->TypeofLoc; 1382 } 1383 void setTypeofLoc(SourceLocation Loc) { 1384 this->getLocalData()->TypeofLoc = Loc; 1385 } 1386 1387 SourceLocation getLParenLoc() const { 1388 return this->getLocalData()->LParenLoc; 1389 } 1390 void setLParenLoc(SourceLocation Loc) { 1391 this->getLocalData()->LParenLoc = Loc; 1392 } 1393 1394 SourceLocation getRParenLoc() const { 1395 return this->getLocalData()->RParenLoc; 1396 } 1397 void setRParenLoc(SourceLocation Loc) { 1398 this->getLocalData()->RParenLoc = Loc; 1399 } 1400 1401 SourceRange getParensRange() const { 1402 return SourceRange(getLParenLoc(), getRParenLoc()); 1403 } 1404 void setParensRange(SourceRange range) { 1405 setLParenLoc(range.getBegin()); 1406 setRParenLoc(range.getEnd()); 1407 } 1408 1409 SourceRange getLocalSourceRange() const { 1410 return SourceRange(getTypeofLoc(), getRParenLoc()); 1411 } 1412 1413 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1414 setTypeofLoc(Loc); 1415 setLParenLoc(Loc); 1416 setRParenLoc(Loc); 1417 } 1418}; 1419 1420class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1421 TypeOfExprType, 1422 TypeOfExprTypeLocInfo> { 1423public: 1424 Expr* getUnderlyingExpr() const { 1425 return getTypePtr()->getUnderlyingExpr(); 1426 } 1427 // Reimplemented to account for GNU/C++ extension 1428 // typeof unary-expression 1429 // where there are no parentheses. 1430 SourceRange getLocalSourceRange() const; 1431}; 1432 1433class TypeOfTypeLoc 1434 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1435public: 1436 QualType getUnderlyingType() const { 1437 return this->getTypePtr()->getUnderlyingType(); 1438 } 1439 TypeSourceInfo* getUnderlyingTInfo() const { 1440 return this->getLocalData()->UnderlyingTInfo; 1441 } 1442 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1443 this->getLocalData()->UnderlyingTInfo = TI; 1444 } 1445}; 1446 1447// FIXME: location of the 'decltype' and parens. 1448class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1449 DecltypeTypeLoc, 1450 DecltypeType> { 1451public: 1452 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1453}; 1454 1455struct UnaryTransformTypeLocInfo { 1456 // FIXME: While there's only one unary transform right now, future ones may 1457 // need different representations 1458 SourceLocation KWLoc, LParenLoc, RParenLoc; 1459 TypeSourceInfo *UnderlyingTInfo; 1460}; 1461 1462class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1463 UnaryTransformTypeLoc, 1464 UnaryTransformType, 1465 UnaryTransformTypeLocInfo> { 1466public: 1467 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1468 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1469 1470 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1471 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1472 1473 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1474 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1475 1476 TypeSourceInfo* getUnderlyingTInfo() const { 1477 return getLocalData()->UnderlyingTInfo; 1478 } 1479 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1480 getLocalData()->UnderlyingTInfo = TInfo; 1481 } 1482 1483 SourceRange getLocalSourceRange() const { 1484 return SourceRange(getKWLoc(), getRParenLoc()); 1485 } 1486 1487 SourceRange getParensRange() const { 1488 return SourceRange(getLParenLoc(), getRParenLoc()); 1489 } 1490 void setParensRange(SourceRange Range) { 1491 setLParenLoc(Range.getBegin()); 1492 setRParenLoc(Range.getEnd()); 1493 } 1494 1495 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1496 setKWLoc(Loc); 1497 setRParenLoc(Loc); 1498 setLParenLoc(Loc); 1499 } 1500}; 1501 1502class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1503 AutoTypeLoc, 1504 AutoType> { 1505}; 1506 1507struct ElaboratedLocInfo { 1508 SourceLocation ElaboratedKWLoc; 1509 /// \brief Data associated with the nested-name-specifier location. 1510 void *QualifierData; 1511}; 1512 1513class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1514 ElaboratedTypeLoc, 1515 ElaboratedType, 1516 ElaboratedLocInfo> { 1517public: 1518 SourceLocation getElaboratedKeywordLoc() const { 1519 return this->getLocalData()->ElaboratedKWLoc; 1520 } 1521 void setElaboratedKeywordLoc(SourceLocation Loc) { 1522 this->getLocalData()->ElaboratedKWLoc = Loc; 1523 } 1524 1525 NestedNameSpecifierLoc getQualifierLoc() const { 1526 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1527 getLocalData()->QualifierData); 1528 } 1529 1530 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1531 assert(QualifierLoc.getNestedNameSpecifier() 1532 == getTypePtr()->getQualifier() && 1533 "Inconsistent nested-name-specifier pointer"); 1534 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1535 } 1536 1537 SourceRange getLocalSourceRange() const { 1538 if (getElaboratedKeywordLoc().isValid()) 1539 if (getQualifierLoc()) 1540 return SourceRange(getElaboratedKeywordLoc(), 1541 getQualifierLoc().getEndLoc()); 1542 else 1543 return SourceRange(getElaboratedKeywordLoc()); 1544 else 1545 return getQualifierLoc().getSourceRange(); 1546 } 1547 1548 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1549 1550 TypeLoc getNamedTypeLoc() const { 1551 return getInnerTypeLoc(); 1552 } 1553 1554 QualType getInnerType() const { 1555 return getTypePtr()->getNamedType(); 1556 } 1557 1558 void copy(ElaboratedTypeLoc Loc) { 1559 unsigned size = getFullDataSize(); 1560 assert(size == Loc.getFullDataSize()); 1561 memcpy(Data, Loc.Data, size); 1562 } 1563}; 1564 1565// This is exactly the structure of an ElaboratedTypeLoc whose inner 1566// type is some sort of TypeDeclTypeLoc. 1567struct DependentNameLocInfo : ElaboratedLocInfo { 1568 SourceLocation NameLoc; 1569}; 1570 1571class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1572 DependentNameTypeLoc, 1573 DependentNameType, 1574 DependentNameLocInfo> { 1575public: 1576 SourceLocation getElaboratedKeywordLoc() const { 1577 return this->getLocalData()->ElaboratedKWLoc; 1578 } 1579 void setElaboratedKeywordLoc(SourceLocation Loc) { 1580 this->getLocalData()->ElaboratedKWLoc = Loc; 1581 } 1582 1583 NestedNameSpecifierLoc getQualifierLoc() const { 1584 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1585 getLocalData()->QualifierData); 1586 } 1587 1588 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1589 assert(QualifierLoc.getNestedNameSpecifier() 1590 == getTypePtr()->getQualifier() && 1591 "Inconsistent nested-name-specifier pointer"); 1592 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1593 } 1594 1595 SourceLocation getNameLoc() const { 1596 return this->getLocalData()->NameLoc; 1597 } 1598 void setNameLoc(SourceLocation Loc) { 1599 this->getLocalData()->NameLoc = Loc; 1600 } 1601 1602 SourceRange getLocalSourceRange() const { 1603 if (getElaboratedKeywordLoc().isValid()) 1604 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 1605 else 1606 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 1607 } 1608 1609 void copy(DependentNameTypeLoc Loc) { 1610 unsigned size = getFullDataSize(); 1611 assert(size == Loc.getFullDataSize()); 1612 memcpy(Data, Loc.Data, size); 1613 } 1614 1615 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1616}; 1617 1618struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 1619 SourceLocation TemplateKWLoc; 1620 SourceLocation LAngleLoc; 1621 SourceLocation RAngleLoc; 1622 // followed by a TemplateArgumentLocInfo[] 1623}; 1624 1625class DependentTemplateSpecializationTypeLoc : 1626 public ConcreteTypeLoc<UnqualTypeLoc, 1627 DependentTemplateSpecializationTypeLoc, 1628 DependentTemplateSpecializationType, 1629 DependentTemplateSpecializationLocInfo> { 1630public: 1631 SourceLocation getElaboratedKeywordLoc() const { 1632 return this->getLocalData()->ElaboratedKWLoc; 1633 } 1634 void setElaboratedKeywordLoc(SourceLocation Loc) { 1635 this->getLocalData()->ElaboratedKWLoc = Loc; 1636 } 1637 1638 NestedNameSpecifierLoc getQualifierLoc() const { 1639 if (!getLocalData()->QualifierData) 1640 return NestedNameSpecifierLoc(); 1641 1642 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1643 getLocalData()->QualifierData); 1644 } 1645 1646 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1647 if (!QualifierLoc) { 1648 // Even if we have a nested-name-specifier in the dependent 1649 // template specialization type, we won't record the nested-name-specifier 1650 // location information when this type-source location information is 1651 // part of a nested-name-specifier. 1652 getLocalData()->QualifierData = 0; 1653 return; 1654 } 1655 1656 assert(QualifierLoc.getNestedNameSpecifier() 1657 == getTypePtr()->getQualifier() && 1658 "Inconsistent nested-name-specifier pointer"); 1659 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1660 } 1661 1662 SourceLocation getTemplateKeywordLoc() const { 1663 return getLocalData()->TemplateKWLoc; 1664 } 1665 void setTemplateKeywordLoc(SourceLocation Loc) { 1666 getLocalData()->TemplateKWLoc = Loc; 1667 } 1668 1669 SourceLocation getTemplateNameLoc() const { 1670 return this->getLocalData()->NameLoc; 1671 } 1672 void setTemplateNameLoc(SourceLocation Loc) { 1673 this->getLocalData()->NameLoc = Loc; 1674 } 1675 1676 SourceLocation getLAngleLoc() const { 1677 return this->getLocalData()->LAngleLoc; 1678 } 1679 void setLAngleLoc(SourceLocation Loc) { 1680 this->getLocalData()->LAngleLoc = Loc; 1681 } 1682 1683 SourceLocation getRAngleLoc() const { 1684 return this->getLocalData()->RAngleLoc; 1685 } 1686 void setRAngleLoc(SourceLocation Loc) { 1687 this->getLocalData()->RAngleLoc = Loc; 1688 } 1689 1690 unsigned getNumArgs() const { 1691 return getTypePtr()->getNumArgs(); 1692 } 1693 1694 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1695 getArgInfos()[i] = AI; 1696 } 1697 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1698 return getArgInfos()[i]; 1699 } 1700 1701 TemplateArgumentLoc getArgLoc(unsigned i) const { 1702 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1703 } 1704 1705 SourceRange getLocalSourceRange() const { 1706 if (getElaboratedKeywordLoc().isValid()) 1707 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 1708 else if (getQualifierLoc()) 1709 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 1710 else if (getTemplateKeywordLoc().isValid()) 1711 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1712 else 1713 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1714 } 1715 1716 void copy(DependentTemplateSpecializationTypeLoc Loc) { 1717 unsigned size = getFullDataSize(); 1718 assert(size == Loc.getFullDataSize()); 1719 memcpy(Data, Loc.Data, size); 1720 } 1721 1722 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1723 1724 unsigned getExtraLocalDataSize() const { 1725 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1726 } 1727 1728private: 1729 TemplateArgumentLocInfo *getArgInfos() const { 1730 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1731 } 1732}; 1733 1734 1735struct PackExpansionTypeLocInfo { 1736 SourceLocation EllipsisLoc; 1737}; 1738 1739class PackExpansionTypeLoc 1740 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 1741 PackExpansionType, PackExpansionTypeLocInfo> { 1742public: 1743 SourceLocation getEllipsisLoc() const { 1744 return this->getLocalData()->EllipsisLoc; 1745 } 1746 1747 void setEllipsisLoc(SourceLocation Loc) { 1748 this->getLocalData()->EllipsisLoc = Loc; 1749 } 1750 1751 SourceRange getLocalSourceRange() const { 1752 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 1753 } 1754 1755 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1756 setEllipsisLoc(Loc); 1757 } 1758 1759 TypeLoc getPatternLoc() const { 1760 return getInnerTypeLoc(); 1761 } 1762 1763 QualType getInnerType() const { 1764 return this->getTypePtr()->getPattern(); 1765 } 1766}; 1767 1768struct AtomicTypeLocInfo { 1769 SourceLocation KWLoc, LParenLoc, RParenLoc; 1770}; 1771 1772class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 1773 AtomicType, AtomicTypeLocInfo> { 1774public: 1775 TypeLoc getValueLoc() const { 1776 return this->getInnerTypeLoc(); 1777 } 1778 1779 SourceRange getLocalSourceRange() const { 1780 return SourceRange(getKWLoc(), getRParenLoc()); 1781 } 1782 1783 SourceLocation getKWLoc() const { 1784 return this->getLocalData()->KWLoc; 1785 } 1786 void setKWLoc(SourceLocation Loc) { 1787 this->getLocalData()->KWLoc = Loc; 1788 } 1789 1790 SourceLocation getLParenLoc() const { 1791 return this->getLocalData()->LParenLoc; 1792 } 1793 void setLParenLoc(SourceLocation Loc) { 1794 this->getLocalData()->LParenLoc = Loc; 1795 } 1796 1797 SourceLocation getRParenLoc() const { 1798 return this->getLocalData()->RParenLoc; 1799 } 1800 void setRParenLoc(SourceLocation Loc) { 1801 this->getLocalData()->RParenLoc = Loc; 1802 } 1803 1804 SourceRange getParensRange() const { 1805 return SourceRange(getLParenLoc(), getRParenLoc()); 1806 } 1807 void setParensRange(SourceRange Range) { 1808 setLParenLoc(Range.getBegin()); 1809 setRParenLoc(Range.getEnd()); 1810 } 1811 1812 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1813 setKWLoc(Loc); 1814 setLParenLoc(Loc); 1815 setRParenLoc(Loc); 1816 } 1817 1818 QualType getInnerType() const { 1819 return this->getTypePtr()->getValueType(); 1820 } 1821}; 1822 1823 1824} 1825 1826#endif 1827