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