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