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