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