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