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 public: 542 CXXRecordDecl *getDecl() const { 543 return getTypePtr()->getDecl(); 544 } 545 }; 546 547 /// \brief Wrapper for source info for unresolved typename using decls. 548 class UnresolvedUsingTypeLoc : 549 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 550 UnresolvedUsingTypeLoc, 551 UnresolvedUsingType> { 552 public: 553 UnresolvedUsingTypenameDecl *getDecl() const { 554 return getTypePtr()->getDecl(); 555 } 556 }; 557 558 /// \brief Wrapper for source info for tag types. Note that this only 559 /// records source info for the name itself; a type written 'struct foo' 560 /// should be represented as an ElaboratedTypeLoc. We currently 561 /// only do that when C++ is enabled because of the expense of 562 /// creating an ElaboratedType node for so many type references in C. 563 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 564 TagTypeLoc, 565 TagType> { 566 public: 567 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 568 569 /// \brief True if the tag was defined in this type specifier. 570 bool isDefinition() const { 571 return getDecl()->isCompleteDefinition() && 572 (getNameLoc().isInvalid() || getNameLoc() == getDecl()->getLocation()); 573 } 574 }; 575 576 /// \brief Wrapper for source info for record types. 577 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 578 RecordTypeLoc, 579 RecordType> { 580 public: 581 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 582 }; 583 584 /// \brief Wrapper for source info for enum types. 585 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 586 EnumTypeLoc, 587 EnumType> { 588 public: 589 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 590 }; 591 592 /// \brief Wrapper for template type parameters. 593 class TemplateTypeParmTypeLoc : 594 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 595 TemplateTypeParmTypeLoc, 596 TemplateTypeParmType> { 597 public: 598 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 599 }; 600 601 /// \brief Wrapper for substituted template type parameters. 602 class SubstTemplateTypeParmTypeLoc : 603 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 604 SubstTemplateTypeParmTypeLoc, 605 SubstTemplateTypeParmType> { 606 }; 607 608 /// \brief Wrapper for substituted template type parameters. 609 class SubstTemplateTypeParmPackTypeLoc : 610 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 611 SubstTemplateTypeParmPackTypeLoc, 612 SubstTemplateTypeParmPackType> { 613 }; 614 615 struct AttributedLocInfo { 616 union { 617 Expr *ExprOperand; 618 619 /// A raw SourceLocation. 620 unsigned EnumOperandLoc; 621 }; 622 623 SourceRange OperandParens; 624 625 SourceLocation AttrLoc; 626 }; 627 628 /// \brief Type source information for an attributed type. 629 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 630 AttributedTypeLoc, 631 AttributedType, 632 AttributedLocInfo> { 633 public: 634 AttributedType::Kind getAttrKind() const { 635 return getTypePtr()->getAttrKind(); 636 } 637 638 bool hasAttrExprOperand() const { 639 return (getAttrKind() >= AttributedType::FirstExprOperandKind && 640 getAttrKind() <= AttributedType::LastExprOperandKind); 641 } 642 643 bool hasAttrEnumOperand() const { 644 return (getAttrKind() >= AttributedType::FirstEnumOperandKind && 645 getAttrKind() <= AttributedType::LastEnumOperandKind); 646 } 647 648 bool hasAttrOperand() const { 649 return hasAttrExprOperand() || hasAttrEnumOperand(); 650 } 651 652 /// The modified type, which is generally canonically different from 653 /// the attribute type. 654 /// int main(int, char**) __attribute__((noreturn)) 655 /// ~~~ ~~~~~~~~~~~~~ 656 TypeLoc getModifiedLoc() const { 657 return getInnerTypeLoc(); 658 } 659 660 /// The location of the attribute name, i.e. 661 /// __attribute__((regparm(1000))) 662 /// ^~~~~~~ 663 SourceLocation getAttrNameLoc() const { 664 return getLocalData()->AttrLoc; 665 } 666 void setAttrNameLoc(SourceLocation loc) { 667 getLocalData()->AttrLoc = loc; 668 } 669 670 /// The attribute's expression operand, if it has one. 671 /// void *cur_thread __attribute__((address_space(21))) 672 /// ^~ 673 Expr *getAttrExprOperand() const { 674 assert(hasAttrExprOperand()); 675 return getLocalData()->ExprOperand; 676 } 677 void setAttrExprOperand(Expr *e) { 678 assert(hasAttrExprOperand()); 679 getLocalData()->ExprOperand = e; 680 } 681 682 /// The location of the attribute's enumerated operand, if it has one. 683 /// void * __attribute__((objc_gc(weak))) 684 /// ^~~~ 685 SourceLocation getAttrEnumOperandLoc() const { 686 assert(hasAttrEnumOperand()); 687 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc); 688 } 689 void setAttrEnumOperandLoc(SourceLocation loc) { 690 assert(hasAttrEnumOperand()); 691 getLocalData()->EnumOperandLoc = loc.getRawEncoding(); 692 } 693 694 /// The location of the parentheses around the operand, if there is 695 /// an operand. 696 /// void * __attribute__((objc_gc(weak))) 697 /// ^ ^ 698 SourceRange getAttrOperandParensRange() const { 699 assert(hasAttrOperand()); 700 return getLocalData()->OperandParens; 701 } 702 void setAttrOperandParensRange(SourceRange range) { 703 assert(hasAttrOperand()); 704 getLocalData()->OperandParens = range; 705 } 706 707 SourceRange getLocalSourceRange() const { 708 // Note that this does *not* include the range of the attribute 709 // enclosure, e.g.: 710 // __attribute__((foo(bar))) 711 // ^~~~~~~~~~~~~~~ ~~ 712 // or 713 // [[foo(bar)]] 714 // ^~ ~~ 715 // That enclosure doesn't necessarily belong to a single attribute 716 // anyway. 717 SourceRange range(getAttrNameLoc()); 718 if (hasAttrOperand()) 719 range.setEnd(getAttrOperandParensRange().getEnd()); 720 return range; 721 } 722 723 void initializeLocal(ASTContext &Context, SourceLocation loc) { 724 setAttrNameLoc(loc); 725 if (hasAttrExprOperand()) { 726 setAttrOperandParensRange(SourceRange(loc)); 727 setAttrExprOperand(0); 728 } else if (hasAttrEnumOperand()) { 729 setAttrOperandParensRange(SourceRange(loc)); 730 setAttrEnumOperandLoc(loc); 731 } 732 } 733 734 QualType getInnerType() const { 735 return getTypePtr()->getModifiedType(); 736 } 737 }; 738 739 740 struct ObjCProtocolListLocInfo { 741 SourceLocation LAngleLoc; 742 SourceLocation RAngleLoc; 743 bool HasBaseTypeAsWritten; 744 }; 745 746 // A helper class for defining ObjC TypeLocs that can qualified with 747 // protocols. 748 // 749 // TypeClass basically has to be either ObjCInterfaceType or 750 // ObjCObjectPointerType. 751 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 752 ObjCObjectTypeLoc, 753 ObjCObjectType, 754 ObjCProtocolListLocInfo> { 755 // SourceLocations are stored after Info, one for each Protocol. 756 SourceLocation *getProtocolLocArray() const { 757 return (SourceLocation*) this->getExtraLocalData(); 758 } 759 760 public: 761 SourceLocation getLAngleLoc() const { 762 return this->getLocalData()->LAngleLoc; 763 } 764 void setLAngleLoc(SourceLocation Loc) { 765 this->getLocalData()->LAngleLoc = Loc; 766 } 767 768 SourceLocation getRAngleLoc() const { 769 return this->getLocalData()->RAngleLoc; 770 } 771 void setRAngleLoc(SourceLocation Loc) { 772 this->getLocalData()->RAngleLoc = Loc; 773 } 774 775 unsigned getNumProtocols() const { 776 return this->getTypePtr()->getNumProtocols(); 777 } 778 779 SourceLocation getProtocolLoc(unsigned i) const { 780 assert(i < getNumProtocols() && "Index is out of bounds!"); 781 return getProtocolLocArray()[i]; 782 } 783 void setProtocolLoc(unsigned i, SourceLocation Loc) { 784 assert(i < getNumProtocols() && "Index is out of bounds!"); 785 getProtocolLocArray()[i] = Loc; 786 } 787 788 ObjCProtocolDecl *getProtocol(unsigned i) const { 789 assert(i < getNumProtocols() && "Index is out of bounds!"); 790 return *(this->getTypePtr()->qual_begin() + i); 791 } 792 793 bool hasBaseTypeAsWritten() const { 794 return getLocalData()->HasBaseTypeAsWritten; 795 } 796 797 void setHasBaseTypeAsWritten(bool HasBaseType) { 798 getLocalData()->HasBaseTypeAsWritten = HasBaseType; 799 } 800 801 TypeLoc getBaseLoc() const { 802 return getInnerTypeLoc(); 803 } 804 805 SourceRange getLocalSourceRange() const { 806 return SourceRange(getLAngleLoc(), getRAngleLoc()); 807 } 808 809 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 810 setHasBaseTypeAsWritten(true); 811 setLAngleLoc(Loc); 812 setRAngleLoc(Loc); 813 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 814 setProtocolLoc(i, Loc); 815 } 816 817 unsigned getExtraLocalDataSize() const { 818 return this->getNumProtocols() * sizeof(SourceLocation); 819 } 820 821 QualType getInnerType() const { 822 return getTypePtr()->getBaseType(); 823 } 824 }; 825 826 827 struct ObjCInterfaceLocInfo { 828 SourceLocation NameLoc; 829 }; 830 831 /// \brief Wrapper for source info for ObjC interfaces. 832 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 833 ObjCInterfaceTypeLoc, 834 ObjCInterfaceType, 835 ObjCInterfaceLocInfo> { 836 public: 837 ObjCInterfaceDecl *getIFaceDecl() const { 838 return getTypePtr()->getDecl(); 839 } 840 841 SourceLocation getNameLoc() const { 842 return getLocalData()->NameLoc; 843 } 844 845 void setNameLoc(SourceLocation Loc) { 846 getLocalData()->NameLoc = Loc; 847 } 848 849 SourceRange getLocalSourceRange() const { 850 return SourceRange(getNameLoc()); 851 } 852 853 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 854 setNameLoc(Loc); 855 } 856 }; 857 858 struct ParenLocInfo { 859 SourceLocation LParenLoc; 860 SourceLocation RParenLoc; 861 }; 862 863 class ParenTypeLoc 864 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 865 ParenLocInfo> { 866 public: 867 SourceLocation getLParenLoc() const { 868 return this->getLocalData()->LParenLoc; 869 } 870 SourceLocation getRParenLoc() const { 871 return this->getLocalData()->RParenLoc; 872 } 873 void setLParenLoc(SourceLocation Loc) { 874 this->getLocalData()->LParenLoc = Loc; 875 } 876 void setRParenLoc(SourceLocation Loc) { 877 this->getLocalData()->RParenLoc = Loc; 878 } 879 880 SourceRange getLocalSourceRange() const { 881 return SourceRange(getLParenLoc(), getRParenLoc()); 882 } 883 884 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 885 setLParenLoc(Loc); 886 setRParenLoc(Loc); 887 } 888 889 TypeLoc getInnerLoc() const { 890 return getInnerTypeLoc(); 891 } 892 893 QualType getInnerType() const { 894 return this->getTypePtr()->getInnerType(); 895 } 896 }; 897 898 899 struct PointerLikeLocInfo { 900 SourceLocation StarLoc; 901 }; 902 903 /// A base class for 904 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 905 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 906 TypeClass, LocalData> { 907 public: 908 SourceLocation getSigilLoc() const { 909 return this->getLocalData()->StarLoc; 910 } 911 void setSigilLoc(SourceLocation Loc) { 912 this->getLocalData()->StarLoc = Loc; 913 } 914 915 TypeLoc getPointeeLoc() const { 916 return this->getInnerTypeLoc(); 917 } 918 919 SourceRange getLocalSourceRange() const { 920 return SourceRange(getSigilLoc(), getSigilLoc()); 921 } 922 923 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 924 setSigilLoc(Loc); 925 } 926 927 QualType getInnerType() const { 928 return this->getTypePtr()->getPointeeType(); 929 } 930 }; 931 932 933 /// \brief Wrapper for source info for pointers. 934 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 935 PointerType> { 936 public: 937 SourceLocation getStarLoc() const { 938 return getSigilLoc(); 939 } 940 void setStarLoc(SourceLocation Loc) { 941 setSigilLoc(Loc); 942 } 943 }; 944 945 946 /// \brief Wrapper for source info for block pointers. 947 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 948 BlockPointerType> { 949 public: 950 SourceLocation getCaretLoc() const { 951 return getSigilLoc(); 952 } 953 void setCaretLoc(SourceLocation Loc) { 954 setSigilLoc(Loc); 955 } 956 }; 957 958 struct MemberPointerLocInfo : public PointerLikeLocInfo { 959 TypeSourceInfo *ClassTInfo; 960 }; 961 962 /// \brief Wrapper for source info for member pointers. 963 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 964 MemberPointerType, 965 MemberPointerLocInfo> { 966 public: 967 SourceLocation getStarLoc() const { 968 return getSigilLoc(); 969 } 970 void setStarLoc(SourceLocation Loc) { 971 setSigilLoc(Loc); 972 } 973 974 const Type *getClass() const { 975 return getTypePtr()->getClass(); 976 } 977 TypeSourceInfo *getClassTInfo() const { 978 return getLocalData()->ClassTInfo; 979 } 980 void setClassTInfo(TypeSourceInfo* TI) { 981 getLocalData()->ClassTInfo = TI; 982 } 983 984 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 985 setSigilLoc(Loc); 986 setClassTInfo(0); 987 } 988 989 SourceRange getLocalSourceRange() const { 990 if (TypeSourceInfo *TI = getClassTInfo()) 991 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 992 else 993 return SourceRange(getStarLoc()); 994 } 995 }; 996 997 /// Wraps an ObjCPointerType with source location information. 998 class ObjCObjectPointerTypeLoc : 999 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1000 ObjCObjectPointerType> { 1001 public: 1002 SourceLocation getStarLoc() const { 1003 return getSigilLoc(); 1004 } 1005 1006 void setStarLoc(SourceLocation Loc) { 1007 setSigilLoc(Loc); 1008 } 1009 }; 1010 1011 1012 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1013 ReferenceType> { 1014 public: 1015 QualType getInnerType() const { 1016 return getTypePtr()->getPointeeTypeAsWritten(); 1017 } 1018 }; 1019 1020 class LValueReferenceTypeLoc : 1021 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1022 LValueReferenceTypeLoc, 1023 LValueReferenceType> { 1024 public: 1025 SourceLocation getAmpLoc() const { 1026 return getSigilLoc(); 1027 } 1028 void setAmpLoc(SourceLocation Loc) { 1029 setSigilLoc(Loc); 1030 } 1031 }; 1032 1033 class RValueReferenceTypeLoc : 1034 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1035 RValueReferenceTypeLoc, 1036 RValueReferenceType> { 1037 public: 1038 SourceLocation getAmpAmpLoc() const { 1039 return getSigilLoc(); 1040 } 1041 void setAmpAmpLoc(SourceLocation Loc) { 1042 setSigilLoc(Loc); 1043 } 1044 }; 1045 1046 1047 struct FunctionLocInfo { 1048 SourceLocation LocalRangeBegin; 1049 SourceLocation LocalRangeEnd; 1050 bool TrailingReturn; 1051 }; 1052 1053 /// \brief Wrapper for source info for functions. 1054 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1055 FunctionTypeLoc, 1056 FunctionType, 1057 FunctionLocInfo> { 1058 public: 1059 SourceLocation getLocalRangeBegin() const { 1060 return getLocalData()->LocalRangeBegin; 1061 } 1062 void setLocalRangeBegin(SourceLocation L) { 1063 getLocalData()->LocalRangeBegin = L; 1064 } 1065 1066 SourceLocation getLocalRangeEnd() const { 1067 return getLocalData()->LocalRangeEnd; 1068 } 1069 void setLocalRangeEnd(SourceLocation L) { 1070 getLocalData()->LocalRangeEnd = L; 1071 } 1072 1073 bool getTrailingReturn() const { 1074 return getLocalData()->TrailingReturn; 1075 } 1076 void setTrailingReturn(bool Trailing) { 1077 getLocalData()->TrailingReturn = Trailing; 1078 } 1079 1080 // ParmVarDecls* are stored after Info, one for each argument. 1081 ParmVarDecl **getParmArray() const { 1082 return (ParmVarDecl**) getExtraLocalData(); 1083 } 1084 1085 unsigned getNumArgs() const { 1086 if (isa<FunctionNoProtoType>(getTypePtr())) 1087 return 0; 1088 return cast<FunctionProtoType>(getTypePtr())->getNumArgs(); 1089 } 1090 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } 1091 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1092 1093 TypeLoc getResultLoc() const { 1094 return getInnerTypeLoc(); 1095 } 1096 1097 SourceRange getLocalSourceRange() const { 1098 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1099 } 1100 1101 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1102 setLocalRangeBegin(Loc); 1103 setLocalRangeEnd(Loc); 1104 setTrailingReturn(false); 1105 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) 1106 setArg(i, NULL); 1107 } 1108 1109 /// \brief Returns the size of the type source info data block that is 1110 /// specific to this type. 1111 unsigned getExtraLocalDataSize() const { 1112 return getNumArgs() * sizeof(ParmVarDecl*); 1113 } 1114 1115 QualType getInnerType() const { return getTypePtr()->getResultType(); } 1116 }; 1117 1118 class FunctionProtoTypeLoc : 1119 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1120 FunctionProtoTypeLoc, 1121 FunctionProtoType> { 1122 }; 1123 1124 class FunctionNoProtoTypeLoc : 1125 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1126 FunctionNoProtoTypeLoc, 1127 FunctionNoProtoType> { 1128 }; 1129 1130 1131 struct ArrayLocInfo { 1132 SourceLocation LBracketLoc, RBracketLoc; 1133 Expr *Size; 1134 }; 1135 1136 /// \brief Wrapper for source info for arrays. 1137 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1138 ArrayTypeLoc, 1139 ArrayType, 1140 ArrayLocInfo> { 1141 public: 1142 SourceLocation getLBracketLoc() const { 1143 return getLocalData()->LBracketLoc; 1144 } 1145 void setLBracketLoc(SourceLocation Loc) { 1146 getLocalData()->LBracketLoc = Loc; 1147 } 1148 1149 SourceLocation getRBracketLoc() const { 1150 return getLocalData()->RBracketLoc; 1151 } 1152 void setRBracketLoc(SourceLocation Loc) { 1153 getLocalData()->RBracketLoc = Loc; 1154 } 1155 1156 SourceRange getBracketsRange() const { 1157 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1158 } 1159 1160 Expr *getSizeExpr() const { 1161 return getLocalData()->Size; 1162 } 1163 void setSizeExpr(Expr *Size) { 1164 getLocalData()->Size = Size; 1165 } 1166 1167 TypeLoc getElementLoc() const { 1168 return getInnerTypeLoc(); 1169 } 1170 1171 SourceRange getLocalSourceRange() const { 1172 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1173 } 1174 1175 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1176 setLBracketLoc(Loc); 1177 setRBracketLoc(Loc); 1178 setSizeExpr(NULL); 1179 } 1180 1181 QualType getInnerType() const { return getTypePtr()->getElementType(); } 1182 }; 1183 1184 class ConstantArrayTypeLoc : 1185 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1186 ConstantArrayTypeLoc, 1187 ConstantArrayType> { 1188 }; 1189 1190 class IncompleteArrayTypeLoc : 1191 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1192 IncompleteArrayTypeLoc, 1193 IncompleteArrayType> { 1194 }; 1195 1196 class DependentSizedArrayTypeLoc : 1197 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1198 DependentSizedArrayTypeLoc, 1199 DependentSizedArrayType> { 1200 1201 }; 1202 1203 class VariableArrayTypeLoc : 1204 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1205 VariableArrayTypeLoc, 1206 VariableArrayType> { 1207 }; 1208 1209 1210 // Location information for a TemplateName. Rudimentary for now. 1211 struct TemplateNameLocInfo { 1212 SourceLocation NameLoc; 1213 }; 1214 1215 struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1216 SourceLocation LAngleLoc; 1217 SourceLocation RAngleLoc; 1218 }; 1219 1220 class TemplateSpecializationTypeLoc : 1221 public ConcreteTypeLoc<UnqualTypeLoc, 1222 TemplateSpecializationTypeLoc, 1223 TemplateSpecializationType, 1224 TemplateSpecializationLocInfo> { 1225 public: 1226 SourceLocation getLAngleLoc() const { 1227 return getLocalData()->LAngleLoc; 1228 } 1229 void setLAngleLoc(SourceLocation Loc) { 1230 getLocalData()->LAngleLoc = Loc; 1231 } 1232 1233 SourceLocation getRAngleLoc() const { 1234 return getLocalData()->RAngleLoc; 1235 } 1236 void setRAngleLoc(SourceLocation Loc) { 1237 getLocalData()->RAngleLoc = Loc; 1238 } 1239 1240 unsigned getNumArgs() const { 1241 return getTypePtr()->getNumArgs(); 1242 } 1243 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1244 getArgInfos()[i] = AI; 1245 } 1246 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1247 return getArgInfos()[i]; 1248 } 1249 1250 TemplateArgumentLoc getArgLoc(unsigned i) const { 1251 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1252 } 1253 1254 SourceLocation getTemplateNameLoc() const { 1255 return getLocalData()->NameLoc; 1256 } 1257 void setTemplateNameLoc(SourceLocation Loc) { 1258 getLocalData()->NameLoc = Loc; 1259 } 1260 1261 /// \brief - Copy the location information from the given info. 1262 void copy(TemplateSpecializationTypeLoc Loc) { 1263 unsigned size = getFullDataSize(); 1264 assert(size == Loc.getFullDataSize()); 1265 1266 // We're potentially copying Expr references here. We don't 1267 // bother retaining them because TypeSourceInfos live forever, so 1268 // as long as the Expr was retained when originally written into 1269 // the TypeLoc, we're okay. 1270 memcpy(Data, Loc.Data, size); 1271 } 1272 1273 SourceRange getLocalSourceRange() const { 1274 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1275 } 1276 1277 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1278 setLAngleLoc(Loc); 1279 setRAngleLoc(Loc); 1280 setTemplateNameLoc(Loc); 1281 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), 1282 getArgInfos(), Loc); 1283 } 1284 1285 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, 1286 const TemplateArgument *Args, 1287 TemplateArgumentLocInfo *ArgInfos, 1288 SourceLocation Loc); 1289 1290 unsigned getExtraLocalDataSize() const { 1291 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1292 } 1293 1294 private: 1295 TemplateArgumentLocInfo *getArgInfos() const { 1296 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1297 } 1298 }; 1299 1300 //===----------------------------------------------------------------------===// 1301 // 1302 // All of these need proper implementations. 1303 // 1304 //===----------------------------------------------------------------------===// 1305 1306 // FIXME: size expression and attribute locations (or keyword if we 1307 // ever fully support altivec syntax). 1308 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1309 VectorTypeLoc, 1310 VectorType> { 1311 }; 1312 1313 // FIXME: size expression and attribute locations. 1314 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1315 ExtVectorTypeLoc, 1316 ExtVectorType> { 1317 }; 1318 1319 // FIXME: attribute locations. 1320 // For some reason, this isn't a subtype of VectorType. 1321 class DependentSizedExtVectorTypeLoc : 1322 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1323 DependentSizedExtVectorTypeLoc, 1324 DependentSizedExtVectorType> { 1325 }; 1326 1327 // FIXME: location of the '_Complex' keyword. 1328 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1329 ComplexTypeLoc, 1330 ComplexType> { 1331 }; 1332 1333 struct TypeofLocInfo { 1334 SourceLocation TypeofLoc; 1335 SourceLocation LParenLoc; 1336 SourceLocation RParenLoc; 1337 }; 1338 1339 struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1340 }; 1341 1342 struct TypeOfTypeLocInfo : public TypeofLocInfo { 1343 TypeSourceInfo* UnderlyingTInfo; 1344 }; 1345 1346 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1347 class TypeofLikeTypeLoc 1348 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1349 public: 1350 SourceLocation getTypeofLoc() const { 1351 return this->getLocalData()->TypeofLoc; 1352 } 1353 void setTypeofLoc(SourceLocation Loc) { 1354 this->getLocalData()->TypeofLoc = Loc; 1355 } 1356 1357 SourceLocation getLParenLoc() const { 1358 return this->getLocalData()->LParenLoc; 1359 } 1360 void setLParenLoc(SourceLocation Loc) { 1361 this->getLocalData()->LParenLoc = Loc; 1362 } 1363 1364 SourceLocation getRParenLoc() const { 1365 return this->getLocalData()->RParenLoc; 1366 } 1367 void setRParenLoc(SourceLocation Loc) { 1368 this->getLocalData()->RParenLoc = Loc; 1369 } 1370 1371 SourceRange getParensRange() const { 1372 return SourceRange(getLParenLoc(), getRParenLoc()); 1373 } 1374 void setParensRange(SourceRange range) { 1375 setLParenLoc(range.getBegin()); 1376 setRParenLoc(range.getEnd()); 1377 } 1378 1379 SourceRange getLocalSourceRange() const { 1380 return SourceRange(getTypeofLoc(), getRParenLoc()); 1381 } 1382 1383 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1384 setTypeofLoc(Loc); 1385 setLParenLoc(Loc); 1386 setRParenLoc(Loc); 1387 } 1388 }; 1389 1390 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1391 TypeOfExprType, 1392 TypeOfExprTypeLocInfo> { 1393 public: 1394 Expr* getUnderlyingExpr() const { 1395 return getTypePtr()->getUnderlyingExpr(); 1396 } 1397 // Reimplemented to account for GNU/C++ extension 1398 // typeof unary-expression 1399 // where there are no parentheses. 1400 SourceRange getLocalSourceRange() const; 1401 }; 1402 1403 class TypeOfTypeLoc 1404 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1405 public: 1406 QualType getUnderlyingType() const { 1407 return this->getTypePtr()->getUnderlyingType(); 1408 } 1409 TypeSourceInfo* getUnderlyingTInfo() const { 1410 return this->getLocalData()->UnderlyingTInfo; 1411 } 1412 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1413 this->getLocalData()->UnderlyingTInfo = TI; 1414 } 1415 }; 1416 1417 // FIXME: location of the 'decltype' and parens. 1418 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1419 DecltypeTypeLoc, 1420 DecltypeType> { 1421 public: 1422 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1423 }; 1424 1425 struct UnaryTransformTypeLocInfo { 1426 // FIXME: While there's only one unary transform right now, future ones may 1427 // need different representations 1428 SourceLocation KWLoc, LParenLoc, RParenLoc; 1429 TypeSourceInfo *UnderlyingTInfo; 1430 }; 1431 1432 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1433 UnaryTransformTypeLoc, 1434 UnaryTransformType, 1435 UnaryTransformTypeLocInfo> { 1436 public: 1437 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1438 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1439 1440 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1441 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1442 1443 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1444 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1445 1446 TypeSourceInfo* getUnderlyingTInfo() const { 1447 return getLocalData()->UnderlyingTInfo; 1448 } 1449 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1450 getLocalData()->UnderlyingTInfo = TInfo; 1451 } 1452 1453 SourceRange getLocalSourceRange() const { 1454 return SourceRange(getKWLoc(), getRParenLoc()); 1455 } 1456 1457 SourceRange getParensRange() const { 1458 return SourceRange(getLParenLoc(), getRParenLoc()); 1459 } 1460 void setParensRange(SourceRange Range) { 1461 setLParenLoc(Range.getBegin()); 1462 setRParenLoc(Range.getEnd()); 1463 } 1464 1465 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1466 setKWLoc(Loc); 1467 setRParenLoc(Loc); 1468 setLParenLoc(Loc); 1469 } 1470 }; 1471 1472 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1473 AutoTypeLoc, 1474 AutoType> { 1475 }; 1476 1477 struct ElaboratedLocInfo { 1478 SourceLocation KeywordLoc; 1479 1480 /// \brief Opaque data pointer used to reconstruct a nested-name-specifier 1481 /// from 1482 void *QualifierData; 1483 }; 1484 1485 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1486 ElaboratedTypeLoc, 1487 ElaboratedType, 1488 ElaboratedLocInfo> { 1489 public: 1490 SourceLocation getKeywordLoc() const { 1491 return this->getLocalData()->KeywordLoc; 1492 } 1493 void setKeywordLoc(SourceLocation Loc) { 1494 this->getLocalData()->KeywordLoc = Loc; 1495 } 1496 1497 NestedNameSpecifierLoc getQualifierLoc() const { 1498 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1499 getLocalData()->QualifierData); 1500 } 1501 1502 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1503 assert(QualifierLoc.getNestedNameSpecifier() 1504 == getTypePtr()->getQualifier() && 1505 "Inconsistent nested-name-specifier pointer"); 1506 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1507 } 1508 1509 SourceRange getLocalSourceRange() const { 1510 if (getKeywordLoc().isValid()) 1511 if (getQualifierLoc()) 1512 return SourceRange(getKeywordLoc(), getQualifierLoc().getEndLoc()); 1513 else 1514 return SourceRange(getKeywordLoc()); 1515 else 1516 return getQualifierLoc().getSourceRange(); 1517 } 1518 1519 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1520 1521 TypeLoc getNamedTypeLoc() const { 1522 return getInnerTypeLoc(); 1523 } 1524 1525 QualType getInnerType() const { 1526 return getTypePtr()->getNamedType(); 1527 } 1528 1529 void copy(ElaboratedTypeLoc Loc) { 1530 unsigned size = getFullDataSize(); 1531 assert(size == Loc.getFullDataSize()); 1532 memcpy(Data, Loc.Data, size); 1533 } 1534 }; 1535 1536 // This is exactly the structure of an ElaboratedTypeLoc whose inner 1537 // type is some sort of TypeDeclTypeLoc. 1538 struct DependentNameLocInfo : ElaboratedLocInfo { 1539 SourceLocation NameLoc; 1540 1541 /// \brief Data associated with the nested-name-specifier location. 1542 void *QualifierData; 1543 }; 1544 1545 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1546 DependentNameTypeLoc, 1547 DependentNameType, 1548 DependentNameLocInfo> { 1549 public: 1550 SourceLocation getKeywordLoc() const { 1551 return this->getLocalData()->KeywordLoc; 1552 } 1553 void setKeywordLoc(SourceLocation Loc) { 1554 this->getLocalData()->KeywordLoc = Loc; 1555 } 1556 1557 NestedNameSpecifierLoc getQualifierLoc() const { 1558 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1559 getLocalData()->QualifierData); 1560 } 1561 1562 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1563 assert(QualifierLoc.getNestedNameSpecifier() 1564 == getTypePtr()->getQualifier() && 1565 "Inconsistent nested-name-specifier pointer"); 1566 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1567 } 1568 1569 SourceLocation getNameLoc() const { 1570 return this->getLocalData()->NameLoc; 1571 } 1572 void setNameLoc(SourceLocation Loc) { 1573 this->getLocalData()->NameLoc = Loc; 1574 } 1575 1576 SourceRange getLocalSourceRange() const { 1577 if (getKeywordLoc().isValid()) 1578 return SourceRange(getKeywordLoc(), getNameLoc()); 1579 else 1580 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 1581 } 1582 1583 void copy(DependentNameTypeLoc Loc) { 1584 unsigned size = getFullDataSize(); 1585 assert(size == Loc.getFullDataSize()); 1586 memcpy(Data, Loc.Data, size); 1587 } 1588 1589 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1590 }; 1591 1592 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 1593 SourceLocation KeywordLoc; 1594 SourceLocation LAngleLoc; 1595 SourceLocation RAngleLoc; 1596 // followed by a TemplateArgumentLocInfo[] 1597 }; 1598 1599 class DependentTemplateSpecializationTypeLoc : 1600 public ConcreteTypeLoc<UnqualTypeLoc, 1601 DependentTemplateSpecializationTypeLoc, 1602 DependentTemplateSpecializationType, 1603 DependentTemplateSpecializationLocInfo> { 1604 public: 1605 SourceLocation getKeywordLoc() const { 1606 return this->getLocalData()->KeywordLoc; 1607 } 1608 void setKeywordLoc(SourceLocation Loc) { 1609 this->getLocalData()->KeywordLoc = Loc; 1610 } 1611 1612 NestedNameSpecifierLoc getQualifierLoc() const { 1613 if (!getLocalData()->QualifierData) 1614 return NestedNameSpecifierLoc(); 1615 1616 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1617 getLocalData()->QualifierData); 1618 } 1619 1620 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1621 if (!QualifierLoc) { 1622 // Even if we have a nested-name-specifier in the dependent 1623 // template specialization type, we won't record the nested-name-specifier 1624 // location information when this type-source location information is 1625 // part of a nested-name-specifier. 1626 getLocalData()->QualifierData = 0; 1627 return; 1628 } 1629 1630 assert(QualifierLoc.getNestedNameSpecifier() 1631 == getTypePtr()->getQualifier() && 1632 "Inconsistent nested-name-specifier pointer"); 1633 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1634 } 1635 1636 SourceLocation getNameLoc() const { 1637 return this->getLocalData()->NameLoc; 1638 } 1639 void setNameLoc(SourceLocation Loc) { 1640 this->getLocalData()->NameLoc = Loc; 1641 } 1642 1643 SourceLocation getLAngleLoc() const { 1644 return this->getLocalData()->LAngleLoc; 1645 } 1646 void setLAngleLoc(SourceLocation Loc) { 1647 this->getLocalData()->LAngleLoc = Loc; 1648 } 1649 1650 SourceLocation getRAngleLoc() const { 1651 return this->getLocalData()->RAngleLoc; 1652 } 1653 void setRAngleLoc(SourceLocation Loc) { 1654 this->getLocalData()->RAngleLoc = Loc; 1655 } 1656 1657 unsigned getNumArgs() const { 1658 return getTypePtr()->getNumArgs(); 1659 } 1660 1661 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1662 getArgInfos()[i] = AI; 1663 } 1664 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1665 return getArgInfos()[i]; 1666 } 1667 1668 TemplateArgumentLoc getArgLoc(unsigned i) const { 1669 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1670 } 1671 1672 SourceRange getLocalSourceRange() const { 1673 if (getKeywordLoc().isValid()) 1674 return SourceRange(getKeywordLoc(), getRAngleLoc()); 1675 else if (getQualifierLoc()) 1676 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 1677 else 1678 return SourceRange(getNameLoc(), getRAngleLoc()); 1679 } 1680 1681 void copy(DependentTemplateSpecializationTypeLoc Loc) { 1682 unsigned size = getFullDataSize(); 1683 assert(size == Loc.getFullDataSize()); 1684 memcpy(Data, Loc.Data, size); 1685 } 1686 1687 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1688 1689 unsigned getExtraLocalDataSize() const { 1690 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1691 } 1692 1693 private: 1694 TemplateArgumentLocInfo *getArgInfos() const { 1695 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1696 } 1697 }; 1698 1699 1700 struct PackExpansionTypeLocInfo { 1701 SourceLocation EllipsisLoc; 1702 }; 1703 1704 class PackExpansionTypeLoc 1705 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 1706 PackExpansionType, PackExpansionTypeLocInfo> { 1707 public: 1708 SourceLocation getEllipsisLoc() const { 1709 return this->getLocalData()->EllipsisLoc; 1710 } 1711 1712 void setEllipsisLoc(SourceLocation Loc) { 1713 this->getLocalData()->EllipsisLoc = Loc; 1714 } 1715 1716 SourceRange getLocalSourceRange() const { 1717 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 1718 } 1719 1720 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1721 setEllipsisLoc(Loc); 1722 } 1723 1724 TypeLoc getPatternLoc() const { 1725 return getInnerTypeLoc(); 1726 } 1727 1728 QualType getInnerType() const { 1729 return this->getTypePtr()->getPattern(); 1730 } 1731 }; 1732 1733 struct AtomicTypeLocInfo { 1734 SourceLocation KWLoc, LParenLoc, RParenLoc; 1735 }; 1736 1737 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 1738 AtomicType, AtomicTypeLocInfo> { 1739 public: 1740 TypeLoc getValueLoc() const { 1741 return this->getInnerTypeLoc(); 1742 } 1743 1744 SourceRange getLocalSourceRange() const { 1745 return SourceRange(getKWLoc(), getRParenLoc()); 1746 } 1747 1748 SourceLocation getKWLoc() const { 1749 return this->getLocalData()->KWLoc; 1750 } 1751 void setKWLoc(SourceLocation Loc) { 1752 this->getLocalData()->KWLoc = Loc; 1753 } 1754 1755 SourceLocation getLParenLoc() const { 1756 return this->getLocalData()->LParenLoc; 1757 } 1758 void setLParenLoc(SourceLocation Loc) { 1759 this->getLocalData()->LParenLoc = Loc; 1760 } 1761 1762 SourceLocation getRParenLoc() const { 1763 return this->getLocalData()->RParenLoc; 1764 } 1765 void setRParenLoc(SourceLocation Loc) { 1766 this->getLocalData()->RParenLoc = Loc; 1767 } 1768 1769 SourceRange getParensRange() const { 1770 return SourceRange(getLParenLoc(), getRParenLoc()); 1771 } 1772 void setParensRange(SourceRange Range) { 1773 setLParenLoc(Range.getBegin()); 1774 setRParenLoc(Range.getEnd()); 1775 } 1776 1777 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1778 setKWLoc(Loc); 1779 setLParenLoc(Loc); 1780 setRParenLoc(Loc); 1781 } 1782 1783 QualType getInnerType() const { 1784 return this->getTypePtr()->getValueType(); 1785 } 1786 }; 1787 1788 1789 } 1790 1791 #endif 1792