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