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