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