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