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