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