TypeLoc.h revision ef012445d431eb51de6ce033e117106624a1dc73
1//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the TypeLoc interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_TYPELOC_H 15#define LLVM_CLANG_AST_TYPELOC_H 16 17#include "clang/AST/Type.h" 18#include "clang/AST/Decl.h" 19#include "clang/AST/TemplateBase.h" 20#include "clang/Basic/Specifiers.h" 21 22namespace clang { 23 class ParmVarDecl; 24 class TypeSourceInfo; 25 class UnqualTypeLoc; 26 27// Predeclare all the type nodes. 28#define ABSTRACT_TYPELOC(Class, Base) 29#define TYPELOC(Class, Base) \ 30 class Class##TypeLoc; 31#include "clang/AST/TypeLocNodes.def" 32 33/// \brief Base wrapper for a particular "section" of type source info. 34/// 35/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to 36/// get at the actual information. 37class TypeLoc { 38protected: 39 // The correctness of this relies on the property that, for Type *Ty, 40 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 41 void *Ty; 42 void *Data; 43 44public: 45 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 46 /// except it also defines a Qualified enum that corresponds to the 47 /// QualifiedLoc class. 48 enum TypeLocClass { 49#define ABSTRACT_TYPE(Class, Base) 50#define TYPE(Class, Base) \ 51 Class = Type::Class, 52#include "clang/AST/TypeNodes.def" 53 Qualified 54 }; 55 56 TypeLoc() : Ty(0), Data(0) { } 57 TypeLoc(QualType ty, void *opaqueData) 58 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { } 59 TypeLoc(Type *ty, void *opaqueData) 60 : Ty(ty), Data(opaqueData) { } 61 62 TypeLocClass getTypeLocClass() const { 63 if (getType().hasLocalQualifiers()) return Qualified; 64 return (TypeLocClass) getType()->getTypeClass(); 65 } 66 67 bool isNull() const { return !Ty; } 68 operator bool() const { return Ty; } 69 70 /// \brief Returns the size of type source info data block for the given type. 71 static unsigned getFullDataSizeForType(QualType Ty); 72 73 /// \brief Get the type for which this source info wrapper provides 74 /// information. 75 QualType getType() const { 76 return QualType::getFromOpaquePtr(Ty); 77 } 78 79 Type *getTypePtr() const { 80 return QualType::getFromOpaquePtr(Ty).getTypePtr(); 81 } 82 83 /// \brief Get the pointer where source information is stored. 84 void *getOpaqueData() const { 85 return Data; 86 } 87 88 /// \brief Get the full source range. 89 SourceRange getFullSourceRange() const { 90 SourceLocation End = getSourceRange().getEnd(); 91 TypeLoc Cur = *this; 92 while (true) { 93 TypeLoc Next = Cur.getNextTypeLoc(); 94 if (Next.isNull()) break; 95 Cur = Next; 96 } 97 return SourceRange(Cur.getSourceRange().getBegin(), End); 98 } 99 100 /// \brief Get the local source range. 101 SourceRange getSourceRange() const { 102 return getSourceRangeImpl(*this); 103 } 104 105 /// \brief Returns the size of the type source info data block. 106 unsigned getFullDataSize() const { 107 return getFullDataSizeForType(getType()); 108 } 109 110 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 111 /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 112 TypeLoc getNextTypeLoc() const { 113 return getNextTypeLocImpl(*this); 114 } 115 116 /// \brief Skips past any qualifiers, if this is qualified. 117 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 118 119 /// \brief Initializes this to state that every location in this 120 /// type is the given location. 121 /// 122 /// This method exists to provide a simple transition for code that 123 /// relies on location-less types. 124 void initialize(SourceLocation Loc) const { 125 initializeImpl(*this, Loc); 126 } 127 128 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 129 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 130 } 131 132 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 133 return !(LHS == RHS); 134 } 135 136 static bool classof(const TypeLoc *TL) { return true; } 137 138private: 139 static void initializeImpl(TypeLoc TL, SourceLocation Loc); 140 static TypeLoc getNextTypeLocImpl(TypeLoc TL); 141 static SourceRange getSourceRangeImpl(TypeLoc TL); 142}; 143 144/// \brief Return the TypeLoc for a type source info. 145inline TypeLoc TypeSourceInfo::getTypeLoc() const { 146 return TypeLoc(Ty, (void*)(this + 1)); 147} 148 149/// \brief Wrapper of type source information for a type with 150/// no direct quqlaifiers. 151class UnqualTypeLoc : public TypeLoc { 152public: 153 UnqualTypeLoc() {} 154 UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 155 156 Type *getTypePtr() const { 157 return reinterpret_cast<Type*>(Ty); 158 } 159 160 TypeLocClass getTypeLocClass() const { 161 return (TypeLocClass) getTypePtr()->getTypeClass(); 162 } 163 164 static bool classof(const TypeLoc *TL) { 165 return !TL->getType().hasLocalQualifiers(); 166 } 167 static bool classof(const UnqualTypeLoc *TL) { return true; } 168}; 169 170/// \brief Wrapper of type source information for a type with 171/// non-trivial direct qualifiers. 172/// 173/// Currently, we intentionally do not provide source location for 174/// type qualifiers. 175class QualifiedTypeLoc : public TypeLoc { 176public: 177 SourceRange getSourceRange() const { 178 return SourceRange(); 179 } 180 181 UnqualTypeLoc getUnqualifiedLoc() const { 182 return UnqualTypeLoc(getTypePtr(), Data); 183 } 184 185 /// Initializes the local data of this type source info block to 186 /// provide no information. 187 void initializeLocal(SourceLocation Loc) { 188 // do nothing 189 } 190 191 TypeLoc getNextTypeLoc() const { 192 return getUnqualifiedLoc(); 193 } 194 195 /// \brief Returns the size of the type source info data block that is 196 /// specific to this type. 197 unsigned getLocalDataSize() const { 198 // In fact, we don't currently preserve any location information 199 // for qualifiers. 200 return 0; 201 } 202 203 /// \brief Returns the size of the type source info data block. 204 unsigned getFullDataSize() const { 205 return getLocalDataSize() + 206 getFullDataSizeForType(getType().getLocalUnqualifiedType()); 207 } 208 209 static bool classof(const TypeLoc *TL) { 210 return TL->getType().hasLocalQualifiers(); 211 } 212 static bool classof(const QualifiedTypeLoc *TL) { return true; } 213}; 214 215inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 216 if (isa<QualifiedTypeLoc>(this)) 217 return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc(); 218 return cast<UnqualTypeLoc>(*this); 219} 220 221/// A metaprogramming base class for TypeLoc classes which correspond 222/// to a particular Type subclass. It is accepted for a single 223/// TypeLoc class to correspond to multiple Type classes. 224/// 225/// \param Base a class from which to derive 226/// \param Derived the class deriving from this one 227/// \param TypeClass the concrete Type subclass associated with this 228/// location type 229/// \param LocalData the structure type of local location data for 230/// this type 231/// 232/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or 233/// else the world will end. 234/// 235/// TypeLocs with non-constant amounts of local data should override 236/// getExtraLocalDataSize(); getExtraLocalData() will then point to 237/// this extra memory. 238/// 239/// TypeLocs with an inner type should define 240/// QualType getInnerType() const 241/// and getInnerTypeLoc() will then point to this inner type's 242/// location data. 243/// 244/// A word about hierarchies: this template is not designed to be 245/// derived from multiple times in a hierarchy. It is also not 246/// designed to be used for classes where subtypes might provide 247/// different amounts of source information. It should be subclassed 248/// only at the deepest portion of the hierarchy where all children 249/// have identical source information; if that's an abstract type, 250/// then further descendents should inherit from 251/// InheritingConcreteTypeLoc instead. 252template <class Base, class Derived, class TypeClass, class LocalData> 253class ConcreteTypeLoc : public Base { 254 255 const Derived *asDerived() const { 256 return static_cast<const Derived*>(this); 257 } 258 259public: 260 unsigned getLocalDataSize() const { 261 return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); 262 } 263 // Give a default implementation that's useful for leaf types. 264 unsigned getFullDataSize() const { 265 return asDerived()->getLocalDataSize() + getInnerTypeSize(); 266 } 267 268 static bool classofType(const Type *Ty) { 269 return TypeClass::classof(Ty); 270 } 271 272 static bool classof(const TypeLoc *TL) { 273 return Derived::classofType(TL->getTypePtr()); 274 } 275 static bool classof(const UnqualTypeLoc *TL) { 276 return Derived::classofType(TL->getTypePtr()); 277 } 278 static bool classof(const Derived *TL) { 279 return true; 280 } 281 282 TypeLoc getNextTypeLoc() const { 283 return getNextTypeLoc(asDerived()->getInnerType()); 284 } 285 286 TypeClass *getTypePtr() const { 287 return cast<TypeClass>(Base::getTypePtr()); 288 } 289 290protected: 291 unsigned getExtraLocalDataSize() const { 292 return 0; 293 } 294 295 LocalData *getLocalData() const { 296 return static_cast<LocalData*>(Base::Data); 297 } 298 299 /// Gets a pointer past the Info structure; useful for classes with 300 /// local data that can't be captured in the Info (e.g. because it's 301 /// of variable size). 302 void *getExtraLocalData() const { 303 return getLocalData() + 1; 304 } 305 306 void *getNonLocalData() const { 307 return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize(); 308 } 309 310 struct HasNoInnerType {}; 311 HasNoInnerType getInnerType() const { return HasNoInnerType(); } 312 313 TypeLoc getInnerTypeLoc() const { 314 return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 315 } 316 317private: 318 unsigned getInnerTypeSize() const { 319 return getInnerTypeSize(asDerived()->getInnerType()); 320 } 321 322 unsigned getInnerTypeSize(HasNoInnerType _) const { 323 return 0; 324 } 325 326 unsigned getInnerTypeSize(QualType _) const { 327 return getInnerTypeLoc().getFullDataSize(); 328 } 329 330 TypeLoc getNextTypeLoc(HasNoInnerType _) const { 331 return TypeLoc(); 332 } 333 334 TypeLoc getNextTypeLoc(QualType T) const { 335 return TypeLoc(T, getNonLocalData()); 336 } 337}; 338 339/// A metaprogramming class designed for concrete subtypes of abstract 340/// types where all subtypes share equivalently-structured source 341/// information. See the note on ConcreteTypeLoc. 342template <class Base, class Derived, class TypeClass> 343class InheritingConcreteTypeLoc : public Base { 344public: 345 static bool classof(const TypeLoc *TL) { 346 return Derived::classofType(TL->getTypePtr()); 347 } 348 static bool classof(const UnqualTypeLoc *TL) { 349 return Derived::classofType(TL->getTypePtr()); 350 } 351 static bool classof(const Derived *TL) { 352 return true; 353 } 354 355 TypeClass *getTypePtr() const { 356 return cast<TypeClass>(Base::getTypePtr()); 357 } 358}; 359 360 361struct TypeSpecLocInfo { 362 SourceLocation NameLoc; 363}; 364 365/// \brief A reasonable base class for TypeLocs that correspond to 366/// types that are written as a type-specifier. 367class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 368 TypeSpecTypeLoc, 369 Type, 370 TypeSpecLocInfo> { 371public: 372 enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; 373 374 SourceLocation getNameLoc() const { 375 return this->getLocalData()->NameLoc; 376 } 377 void setNameLoc(SourceLocation Loc) { 378 this->getLocalData()->NameLoc = Loc; 379 } 380 SourceRange getSourceRange() const { 381 return SourceRange(getNameLoc(), getNameLoc()); 382 } 383 void initializeLocal(SourceLocation Loc) { 384 setNameLoc(Loc); 385 } 386 387 static bool classof(const TypeLoc *TL); 388 static bool classof(const TypeSpecTypeLoc *TL) { return true; } 389}; 390 391 392struct BuiltinLocInfo { 393 SourceLocation BuiltinLoc; 394}; 395 396/// \brief Wrapper for source info for builtin types. 397class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 398 BuiltinTypeLoc, 399 BuiltinType, 400 BuiltinLocInfo> { 401public: 402 enum { LocalDataSize = sizeof(BuiltinLocInfo) }; 403 404 SourceLocation getBuiltinLoc() const { 405 return getLocalData()->BuiltinLoc; 406 } 407 void setBuiltinLoc(SourceLocation Loc) { 408 getLocalData()->BuiltinLoc = Loc; 409 } 410 411 SourceLocation getNameLoc() const { return getBuiltinLoc(); } 412 413 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 414 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 415 } 416 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 417 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 418 } 419 420 bool needsExtraLocalData() const { 421 BuiltinType::Kind bk = getTypePtr()->getKind(); 422 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) 423 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) 424 || bk == BuiltinType::UChar 425 || bk == BuiltinType::SChar; 426 } 427 428 unsigned getExtraLocalDataSize() const { 429 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 430 } 431 432 SourceRange getSourceRange() const { 433 return SourceRange(getBuiltinLoc(), getBuiltinLoc()); 434 } 435 436 TypeSpecifierSign getWrittenSignSpec() const { 437 if (needsExtraLocalData()) 438 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 439 else 440 return TSS_unspecified; 441 } 442 bool hasWrittenSignSpec() const { 443 return getWrittenSignSpec() != TSS_unspecified; 444 } 445 void setWrittenSignSpec(TypeSpecifierSign written) { 446 if (needsExtraLocalData()) 447 getWrittenBuiltinSpecs().Sign = written; 448 } 449 450 TypeSpecifierWidth getWrittenWidthSpec() const { 451 if (needsExtraLocalData()) 452 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 453 else 454 return TSW_unspecified; 455 } 456 bool hasWrittenWidthSpec() const { 457 return getWrittenWidthSpec() != TSW_unspecified; 458 } 459 void setWrittenWidthSpec(TypeSpecifierWidth written) { 460 if (needsExtraLocalData()) 461 getWrittenBuiltinSpecs().Width = written; 462 } 463 464 TypeSpecifierType getWrittenTypeSpec() const; 465 bool hasWrittenTypeSpec() const { 466 return getWrittenTypeSpec() != TST_unspecified; 467 } 468 void setWrittenTypeSpec(TypeSpecifierType written) { 469 if (needsExtraLocalData()) 470 getWrittenBuiltinSpecs().Type = written; 471 } 472 473 bool hasModeAttr() const { 474 if (needsExtraLocalData()) 475 return getWrittenBuiltinSpecs().ModeAttr; 476 else 477 return false; 478 } 479 void setModeAttr(bool written) { 480 if (needsExtraLocalData()) 481 getWrittenBuiltinSpecs().ModeAttr = written; 482 } 483 484 void initializeLocal(SourceLocation Loc) { 485 setBuiltinLoc(Loc); 486 if (needsExtraLocalData()) { 487 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 488 wbs.Sign = TSS_unspecified; 489 wbs.Width = TSW_unspecified; 490 wbs.Type = TST_unspecified; 491 wbs.ModeAttr = false; 492 } 493 } 494}; 495 496 497/// \brief Wrapper for source info for typedefs. 498class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 499 TypedefTypeLoc, 500 TypedefType> { 501public: 502 TypedefDecl *getTypedefDecl() const { 503 return getTypePtr()->getDecl(); 504 } 505}; 506 507/// \brief Wrapper for source info for injected class names of class 508/// templates. 509class InjectedClassNameTypeLoc : 510 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 511 InjectedClassNameTypeLoc, 512 InjectedClassNameType> { 513}; 514 515/// \brief Wrapper for source info for unresolved typename using decls. 516class UnresolvedUsingTypeLoc : 517 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 518 UnresolvedUsingTypeLoc, 519 UnresolvedUsingType> { 520public: 521 UnresolvedUsingTypenameDecl *getDecl() const { 522 return getTypePtr()->getDecl(); 523 } 524}; 525 526/// \brief Wrapper for source info for tag types. Note that this only 527/// records source info for the name itself; a type written 'struct foo' 528/// should be represented as an ElaboratedTypeLoc. We currently 529/// only do that when C++ is enabled because of the expense of 530/// creating an ElaboratedType node for so many type references in C. 531class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 532 TagTypeLoc, 533 TagType> { 534public: 535 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 536}; 537 538/// \brief Wrapper for source info for record types. 539class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 540 RecordTypeLoc, 541 RecordType> { 542public: 543 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 544}; 545 546/// \brief Wrapper for source info for enum types. 547class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 548 EnumTypeLoc, 549 EnumType> { 550public: 551 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 552}; 553 554/// \brief Wrapper for template type parameters. 555class TemplateTypeParmTypeLoc : 556 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 557 TemplateTypeParmTypeLoc, 558 TemplateTypeParmType> { 559}; 560 561/// \brief Wrapper for substituted template type parameters. 562class SubstTemplateTypeParmTypeLoc : 563 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 564 SubstTemplateTypeParmTypeLoc, 565 SubstTemplateTypeParmType> { 566}; 567 568 569struct ObjCProtocolListLocInfo { 570 SourceLocation LAngleLoc; 571 SourceLocation RAngleLoc; 572}; 573 574// A helper class for defining ObjC TypeLocs that can qualified with 575// protocols. 576// 577// TypeClass basically has to be either ObjCInterfaceType or 578// ObjCObjectPointerType. 579template <class Derived, class TypeClass, class LocalData> 580class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 581 Derived, 582 TypeClass, 583 LocalData> { 584 // SourceLocations are stored after Info, one for each Protocol. 585 SourceLocation *getProtocolLocArray() const { 586 return (SourceLocation*) this->getExtraLocalData(); 587 } 588 589protected: 590 void initializeLocalBase(SourceLocation Loc) { 591 setLAngleLoc(Loc); 592 setRAngleLoc(Loc); 593 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 594 setProtocolLoc(i, Loc); 595 } 596 597public: 598 SourceLocation getLAngleLoc() const { 599 return this->getLocalData()->LAngleLoc; 600 } 601 void setLAngleLoc(SourceLocation Loc) { 602 this->getLocalData()->LAngleLoc = Loc; 603 } 604 605 SourceLocation getRAngleLoc() const { 606 return this->getLocalData()->RAngleLoc; 607 } 608 void setRAngleLoc(SourceLocation Loc) { 609 this->getLocalData()->RAngleLoc = Loc; 610 } 611 612 unsigned getNumProtocols() const { 613 return this->getTypePtr()->getNumProtocols(); 614 } 615 616 SourceLocation getProtocolLoc(unsigned i) const { 617 assert(i < getNumProtocols() && "Index is out of bounds!"); 618 return getProtocolLocArray()[i]; 619 } 620 void setProtocolLoc(unsigned i, SourceLocation Loc) { 621 assert(i < getNumProtocols() && "Index is out of bounds!"); 622 getProtocolLocArray()[i] = Loc; 623 } 624 625 ObjCProtocolDecl *getProtocol(unsigned i) const { 626 assert(i < getNumProtocols() && "Index is out of bounds!"); 627 return *(this->getTypePtr()->qual_begin() + i); 628 } 629 630 SourceRange getSourceRange() const { 631 return SourceRange(getLAngleLoc(), getRAngleLoc()); 632 } 633 634 void initializeLocal(SourceLocation Loc) { 635 initializeLocalBase(Loc); 636 } 637 638 unsigned getExtraLocalDataSize() const { 639 return this->getNumProtocols() * sizeof(SourceLocation); 640 } 641}; 642 643 644struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo { 645 SourceLocation NameLoc; 646}; 647 648/// \brief Wrapper for source info for ObjC interfaces. 649class ObjCInterfaceTypeLoc : 650 public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc, 651 ObjCInterfaceType, 652 ObjCInterfaceLocInfo> { 653public: 654 ObjCInterfaceDecl *getIFaceDecl() const { 655 return getTypePtr()->getDecl(); 656 } 657 658 SourceLocation getNameLoc() const { 659 return getLocalData()->NameLoc; 660 } 661 662 void setNameLoc(SourceLocation Loc) { 663 getLocalData()->NameLoc = Loc; 664 } 665 666 SourceRange getSourceRange() const { 667 if (getNumProtocols()) 668 return SourceRange(getNameLoc(), getRAngleLoc()); 669 else 670 return SourceRange(getNameLoc(), getNameLoc()); 671 } 672 673 void initializeLocal(SourceLocation Loc) { 674 initializeLocalBase(Loc); 675 setNameLoc(Loc); 676 } 677}; 678 679 680struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo { 681 SourceLocation StarLoc; 682 bool HasProtocols; 683 bool HasBaseType; 684}; 685 686/// Wraps an ObjCPointerType with source location information. Note 687/// that not all ObjCPointerTypes actually have a star location; nor 688/// are protocol locations necessarily written in the source just 689/// because they're present on the type. 690class ObjCObjectPointerTypeLoc : 691 public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc, 692 ObjCObjectPointerType, 693 ObjCObjectPointerLocInfo> { 694public: 695 bool hasProtocolsAsWritten() const { 696 return getLocalData()->HasProtocols; 697 } 698 699 void setHasProtocolsAsWritten(bool HasProtocols) { 700 getLocalData()->HasProtocols = HasProtocols; 701 } 702 703 bool hasBaseTypeAsWritten() const { 704 return getLocalData()->HasBaseType; 705 } 706 707 void setHasBaseTypeAsWritten(bool HasBaseType) { 708 getLocalData()->HasBaseType = HasBaseType; 709 } 710 711 SourceLocation getStarLoc() const { 712 return getLocalData()->StarLoc; 713 } 714 715 void setStarLoc(SourceLocation Loc) { 716 getLocalData()->StarLoc = Loc; 717 } 718 719 SourceRange getSourceRange() const { 720 // Being written with protocols is incompatible with being written 721 // with a star. 722 if (hasProtocolsAsWritten()) 723 return SourceRange(getLAngleLoc(), getRAngleLoc()); 724 else 725 return SourceRange(getStarLoc(), getStarLoc()); 726 } 727 728 void initializeLocal(SourceLocation Loc) { 729 initializeLocalBase(Loc); 730 setHasProtocolsAsWritten(false); 731 setHasBaseTypeAsWritten(false); 732 setStarLoc(Loc); 733 } 734 735 TypeLoc getBaseTypeLoc() const { 736 return getInnerTypeLoc(); 737 } 738 739 QualType getInnerType() const { 740 return getTypePtr()->getPointeeType(); 741 } 742}; 743 744 745struct PointerLikeLocInfo { 746 SourceLocation StarLoc; 747}; 748 749/// A base class for 750template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 751class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 752 TypeClass, LocalData> { 753public: 754 SourceLocation getSigilLoc() const { 755 return this->getLocalData()->StarLoc; 756 } 757 void setSigilLoc(SourceLocation Loc) { 758 this->getLocalData()->StarLoc = Loc; 759 } 760 761 TypeLoc getPointeeLoc() const { 762 return this->getInnerTypeLoc(); 763 } 764 765 SourceRange getSourceRange() const { 766 return SourceRange(getSigilLoc(), getSigilLoc()); 767 } 768 769 void initializeLocal(SourceLocation Loc) { 770 setSigilLoc(Loc); 771 } 772 773 QualType getInnerType() const { 774 return this->getTypePtr()->getPointeeType(); 775 } 776}; 777 778 779/// \brief Wrapper for source info for pointers. 780class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 781 PointerType> { 782public: 783 SourceLocation getStarLoc() const { 784 return getSigilLoc(); 785 } 786 void setStarLoc(SourceLocation Loc) { 787 setSigilLoc(Loc); 788 } 789}; 790 791 792/// \brief Wrapper for source info for block pointers. 793class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 794 BlockPointerType> { 795public: 796 SourceLocation getCaretLoc() const { 797 return getSigilLoc(); 798 } 799 void setCaretLoc(SourceLocation Loc) { 800 setSigilLoc(Loc); 801 } 802}; 803 804 805/// \brief Wrapper for source info for member pointers. 806class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 807 MemberPointerType> { 808public: 809 SourceLocation getStarLoc() const { 810 return getSigilLoc(); 811 } 812 void setStarLoc(SourceLocation Loc) { 813 setSigilLoc(Loc); 814 } 815}; 816 817 818class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 819 ReferenceType> { 820public: 821 QualType getInnerType() const { 822 return getTypePtr()->getPointeeTypeAsWritten(); 823 } 824}; 825 826class LValueReferenceTypeLoc : 827 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 828 LValueReferenceTypeLoc, 829 LValueReferenceType> { 830public: 831 SourceLocation getAmpLoc() const { 832 return getSigilLoc(); 833 } 834 void setAmpLoc(SourceLocation Loc) { 835 setSigilLoc(Loc); 836 } 837}; 838 839class RValueReferenceTypeLoc : 840 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 841 RValueReferenceTypeLoc, 842 RValueReferenceType> { 843public: 844 SourceLocation getAmpAmpLoc() const { 845 return getSigilLoc(); 846 } 847 void setAmpAmpLoc(SourceLocation Loc) { 848 setSigilLoc(Loc); 849 } 850}; 851 852 853struct FunctionLocInfo { 854 SourceLocation LParenLoc, RParenLoc; 855}; 856 857/// \brief Wrapper for source info for functions. 858class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 859 FunctionTypeLoc, 860 FunctionType, 861 FunctionLocInfo> { 862 // ParmVarDecls* are stored after Info, one for each argument. 863 ParmVarDecl **getParmArray() const { 864 return (ParmVarDecl**) getExtraLocalData(); 865 } 866 867public: 868 SourceLocation getLParenLoc() const { 869 return getLocalData()->LParenLoc; 870 } 871 void setLParenLoc(SourceLocation Loc) { 872 getLocalData()->LParenLoc = Loc; 873 } 874 875 SourceLocation getRParenLoc() const { 876 return getLocalData()->RParenLoc; 877 } 878 void setRParenLoc(SourceLocation Loc) { 879 getLocalData()->RParenLoc = Loc; 880 } 881 882 unsigned getNumArgs() const { 883 if (isa<FunctionNoProtoType>(getTypePtr())) 884 return 0; 885 return cast<FunctionProtoType>(getTypePtr())->getNumArgs(); 886 } 887 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } 888 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 889 890 TypeLoc getResultLoc() const { 891 return getInnerTypeLoc(); 892 } 893 894 SourceRange getSourceRange() const { 895 return SourceRange(getLParenLoc(), getRParenLoc()); 896 } 897 898 void initializeLocal(SourceLocation Loc) { 899 setLParenLoc(Loc); 900 setRParenLoc(Loc); 901 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) 902 setArg(i, NULL); 903 } 904 905 /// \brief Returns the size of the type source info data block that is 906 /// specific to this type. 907 unsigned getExtraLocalDataSize() const { 908 return getNumArgs() * sizeof(ParmVarDecl*); 909 } 910 911 QualType getInnerType() const { return getTypePtr()->getResultType(); } 912}; 913 914class FunctionProtoTypeLoc : 915 public InheritingConcreteTypeLoc<FunctionTypeLoc, 916 FunctionProtoTypeLoc, 917 FunctionProtoType> { 918}; 919 920class FunctionNoProtoTypeLoc : 921 public InheritingConcreteTypeLoc<FunctionTypeLoc, 922 FunctionNoProtoTypeLoc, 923 FunctionNoProtoType> { 924}; 925 926 927struct ArrayLocInfo { 928 SourceLocation LBracketLoc, RBracketLoc; 929 Expr *Size; 930}; 931 932/// \brief Wrapper for source info for arrays. 933class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 934 ArrayTypeLoc, 935 ArrayType, 936 ArrayLocInfo> { 937public: 938 SourceLocation getLBracketLoc() const { 939 return getLocalData()->LBracketLoc; 940 } 941 void setLBracketLoc(SourceLocation Loc) { 942 getLocalData()->LBracketLoc = Loc; 943 } 944 945 SourceLocation getRBracketLoc() const { 946 return getLocalData()->RBracketLoc; 947 } 948 void setRBracketLoc(SourceLocation Loc) { 949 getLocalData()->RBracketLoc = Loc; 950 } 951 952 SourceRange getBracketsRange() const { 953 return SourceRange(getLBracketLoc(), getRBracketLoc()); 954 } 955 956 Expr *getSizeExpr() const { 957 return getLocalData()->Size; 958 } 959 void setSizeExpr(Expr *Size) { 960 getLocalData()->Size = Size; 961 } 962 963 TypeLoc getElementLoc() const { 964 return getInnerTypeLoc(); 965 } 966 967 SourceRange getSourceRange() const { 968 return SourceRange(getLBracketLoc(), getRBracketLoc()); 969 } 970 971 void initializeLocal(SourceLocation Loc) { 972 setLBracketLoc(Loc); 973 setRBracketLoc(Loc); 974 setSizeExpr(NULL); 975 } 976 977 QualType getInnerType() const { return getTypePtr()->getElementType(); } 978}; 979 980class ConstantArrayTypeLoc : 981 public InheritingConcreteTypeLoc<ArrayTypeLoc, 982 ConstantArrayTypeLoc, 983 ConstantArrayType> { 984}; 985 986class IncompleteArrayTypeLoc : 987 public InheritingConcreteTypeLoc<ArrayTypeLoc, 988 IncompleteArrayTypeLoc, 989 IncompleteArrayType> { 990}; 991 992class DependentSizedArrayTypeLoc : 993 public InheritingConcreteTypeLoc<ArrayTypeLoc, 994 DependentSizedArrayTypeLoc, 995 DependentSizedArrayType> { 996 997}; 998 999class VariableArrayTypeLoc : 1000 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1001 VariableArrayTypeLoc, 1002 VariableArrayType> { 1003}; 1004 1005 1006// Location information for a TemplateName. Rudimentary for now. 1007struct TemplateNameLocInfo { 1008 SourceLocation NameLoc; 1009}; 1010 1011struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1012 SourceLocation LAngleLoc; 1013 SourceLocation RAngleLoc; 1014}; 1015 1016class TemplateSpecializationTypeLoc : 1017 public ConcreteTypeLoc<UnqualTypeLoc, 1018 TemplateSpecializationTypeLoc, 1019 TemplateSpecializationType, 1020 TemplateSpecializationLocInfo> { 1021public: 1022 SourceLocation getLAngleLoc() const { 1023 return getLocalData()->LAngleLoc; 1024 } 1025 void setLAngleLoc(SourceLocation Loc) { 1026 getLocalData()->LAngleLoc = Loc; 1027 } 1028 1029 SourceLocation getRAngleLoc() const { 1030 return getLocalData()->RAngleLoc; 1031 } 1032 void setRAngleLoc(SourceLocation Loc) { 1033 getLocalData()->RAngleLoc = Loc; 1034 } 1035 1036 unsigned getNumArgs() const { 1037 return getTypePtr()->getNumArgs(); 1038 } 1039 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1040#ifndef NDEBUG 1041 AI.validateForArgument(getTypePtr()->getArg(i)); 1042#endif 1043 getArgInfos()[i] = AI; 1044 } 1045 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1046 return getArgInfos()[i]; 1047 } 1048 1049 TemplateArgumentLoc getArgLoc(unsigned i) const { 1050 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1051 } 1052 1053 SourceLocation getTemplateNameLoc() const { 1054 return getLocalData()->NameLoc; 1055 } 1056 void setTemplateNameLoc(SourceLocation Loc) { 1057 getLocalData()->NameLoc = Loc; 1058 } 1059 1060 /// \brief - Copy the location information from the given info. 1061 void copy(TemplateSpecializationTypeLoc Loc) { 1062 unsigned size = getFullDataSize(); 1063 assert(size == Loc.getFullDataSize()); 1064 1065 // We're potentially copying Expr references here. We don't 1066 // bother retaining them because TypeSourceInfos live forever, so 1067 // as long as the Expr was retained when originally written into 1068 // the TypeLoc, we're okay. 1069 memcpy(Data, Loc.Data, size); 1070 } 1071 1072 SourceRange getSourceRange() const { 1073 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1074 } 1075 1076 void initializeLocal(SourceLocation Loc) { 1077 setLAngleLoc(Loc); 1078 setRAngleLoc(Loc); 1079 setTemplateNameLoc(Loc); 1080 1081 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) { 1082 TemplateArgumentLocInfo Info; 1083#ifndef NDEBUG 1084 // If asserts are enabled, be sure to initialize the argument 1085 // loc with the right kind of pointer. 1086 switch (getTypePtr()->getArg(i).getKind()) { 1087 case TemplateArgument::Expression: 1088 case TemplateArgument::Declaration: 1089 Info = TemplateArgumentLocInfo((Expr*) 0); 1090 break; 1091 1092 case TemplateArgument::Type: 1093 Info = TemplateArgumentLocInfo((TypeSourceInfo*) 0); 1094 break; 1095 1096 case TemplateArgument::Template: 1097 Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation()); 1098 break; 1099 1100 case TemplateArgument::Integral: 1101 case TemplateArgument::Pack: 1102 case TemplateArgument::Null: 1103 // K_None is fine. 1104 break; 1105 } 1106#endif 1107 getArgInfos()[i] = Info; 1108 } 1109 } 1110 1111 unsigned getExtraLocalDataSize() const { 1112 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1113 } 1114 1115private: 1116 TemplateArgumentLocInfo *getArgInfos() const { 1117 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1118 } 1119}; 1120 1121//===----------------------------------------------------------------------===// 1122// 1123// All of these need proper implementations. 1124// 1125//===----------------------------------------------------------------------===// 1126 1127// FIXME: size expression and attribute locations (or keyword if we 1128// ever fully support altivec syntax). 1129class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1130 VectorTypeLoc, 1131 VectorType> { 1132}; 1133 1134// FIXME: size expression and attribute locations. 1135class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1136 ExtVectorTypeLoc, 1137 ExtVectorType> { 1138}; 1139 1140// FIXME: attribute locations. 1141// For some reason, this isn't a subtype of VectorType. 1142class DependentSizedExtVectorTypeLoc : 1143 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1144 DependentSizedExtVectorTypeLoc, 1145 DependentSizedExtVectorType> { 1146}; 1147 1148// FIXME: location of the '_Complex' keyword. 1149class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1150 ComplexTypeLoc, 1151 ComplexType> { 1152}; 1153 1154struct TypeofLocInfo { 1155 SourceLocation TypeofLoc; 1156 SourceLocation LParenLoc; 1157 SourceLocation RParenLoc; 1158}; 1159 1160struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1161}; 1162 1163struct TypeOfTypeLocInfo : public TypeofLocInfo { 1164 TypeSourceInfo* UnderlyingTInfo; 1165}; 1166 1167template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1168class TypeofLikeTypeLoc 1169 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1170public: 1171 SourceLocation getTypeofLoc() const { 1172 return this->getLocalData()->TypeofLoc; 1173 } 1174 void setTypeofLoc(SourceLocation Loc) { 1175 this->getLocalData()->TypeofLoc = Loc; 1176 } 1177 1178 SourceLocation getLParenLoc() const { 1179 return this->getLocalData()->LParenLoc; 1180 } 1181 void setLParenLoc(SourceLocation Loc) { 1182 this->getLocalData()->LParenLoc = Loc; 1183 } 1184 1185 SourceLocation getRParenLoc() const { 1186 return this->getLocalData()->RParenLoc; 1187 } 1188 void setRParenLoc(SourceLocation Loc) { 1189 this->getLocalData()->RParenLoc = Loc; 1190 } 1191 1192 SourceRange getParensRange() const { 1193 return SourceRange(getLParenLoc(), getRParenLoc()); 1194 } 1195 void setParensRange(SourceRange range) { 1196 setLParenLoc(range.getBegin()); 1197 setRParenLoc(range.getEnd()); 1198 } 1199 1200 SourceRange getSourceRange() const { 1201 return SourceRange(getTypeofLoc(), getRParenLoc()); 1202 } 1203 1204 void initializeLocal(SourceLocation Loc) { 1205 setTypeofLoc(Loc); 1206 setLParenLoc(Loc); 1207 setRParenLoc(Loc); 1208 } 1209}; 1210 1211class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1212 TypeOfExprType, 1213 TypeOfExprTypeLocInfo> { 1214public: 1215 Expr* getUnderlyingExpr() const { 1216 return getTypePtr()->getUnderlyingExpr(); 1217 } 1218 // Reimplemented to account for GNU/C++ extension 1219 // typeof unary-expression 1220 // where there are no parentheses. 1221 SourceRange getSourceRange() const; 1222}; 1223 1224class TypeOfTypeLoc 1225 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1226public: 1227 QualType getUnderlyingType() const { 1228 return this->getTypePtr()->getUnderlyingType(); 1229 } 1230 TypeSourceInfo* getUnderlyingTInfo() const { 1231 return this->getLocalData()->UnderlyingTInfo; 1232 } 1233 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1234 this->getLocalData()->UnderlyingTInfo = TI; 1235 } 1236}; 1237 1238// FIXME: location of the 'decltype' and parens. 1239class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1240 DecltypeTypeLoc, 1241 DecltypeType> { 1242}; 1243 1244// FIXME: locations for the nested name specifier should be put in 1245// NestedNameSpecifier 1246struct ElaboratedLocInfo { 1247 SourceLocation KeywordLoc; 1248}; 1249 1250class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1251 ElaboratedTypeLoc, 1252 ElaboratedType, 1253 ElaboratedLocInfo> { 1254public: 1255 SourceLocation getKeywordLoc() const { 1256 return this->getLocalData()->KeywordLoc; 1257 } 1258 void setKeywordLoc(SourceLocation Loc) { 1259 this->getLocalData()->KeywordLoc = Loc; 1260 } 1261 1262 SourceRange getSourceRange() const { 1263 return SourceRange(getKeywordLoc(), getKeywordLoc()); 1264 } 1265 1266 void initializeLocal(SourceLocation Loc) { 1267 setKeywordLoc(Loc); 1268 } 1269 1270 TypeLoc getNamedTypeLoc() const { 1271 return getInnerTypeLoc(); 1272 } 1273 1274 QualType getInnerType() const { 1275 return getTypePtr()->getNamedType(); 1276 } 1277}; 1278 1279// FIXME: locations for the nested name specifier should be put in 1280// NestedNameSpecifier 1281struct DependentNameLocInfo { 1282 SourceLocation KeywordLoc; 1283 SourceLocation NameLoc; 1284}; 1285 1286class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1287 DependentNameTypeLoc, 1288 DependentNameType, 1289 DependentNameLocInfo> { 1290public: 1291 SourceLocation getKeywordLoc() const { 1292 return this->getLocalData()->KeywordLoc; 1293 } 1294 void setKeywordLoc(SourceLocation Loc) { 1295 this->getLocalData()->KeywordLoc = Loc; 1296 } 1297 1298 SourceLocation getNameLoc() const { 1299 return this->getLocalData()->NameLoc; 1300 } 1301 void setNameLoc(SourceLocation Loc) { 1302 this->getLocalData()->NameLoc = Loc; 1303 } 1304 1305 SourceRange getSourceRange() const { 1306 return SourceRange(getKeywordLoc(), getNameLoc()); 1307 } 1308 1309 void initializeLocal(SourceLocation Loc) { 1310 setKeywordLoc(Loc); 1311 setNameLoc(Loc); 1312 } 1313}; 1314 1315} 1316 1317#endif 1318