1 //===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// Defines the clang::TypeLoc interface and its subclasses. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_TYPELOC_H 15 #define LLVM_CLANG_AST_TYPELOC_H 16 17 #include "clang/AST/DeclarationName.h" 18 #include "clang/AST/NestedNameSpecifier.h" 19 #include "clang/AST/TemplateBase.h" 20 #include "clang/AST/Type.h" 21 #include "clang/Basic/LLVM.h" 22 #include "clang/Basic/SourceLocation.h" 23 #include "clang/Basic/Specifiers.h" 24 #include "llvm/ADT/ArrayRef.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/Compiler.h" 27 #include "llvm/Support/MathExtras.h" 28 #include <algorithm> 29 #include <cassert> 30 #include <cstdint> 31 #include <cstring> 32 33 namespace clang { 34 35 class Attr; 36 class ASTContext; 37 class CXXRecordDecl; 38 class ConceptDecl; 39 class Expr; 40 class ObjCInterfaceDecl; 41 class ObjCProtocolDecl; 42 class ObjCTypeParamDecl; 43 class ParmVarDecl; 44 class TemplateTypeParmDecl; 45 class UnqualTypeLoc; 46 class UnresolvedUsingTypenameDecl; 47 48 // Predeclare all the type nodes. 49 #define ABSTRACT_TYPELOC(Class, Base) 50 #define TYPELOC(Class, Base) \ 51 class Class##TypeLoc; 52 #include "clang/AST/TypeLocNodes.def" 53 54 /// Base wrapper for a particular "section" of type source info. 55 /// 56 /// A client should use the TypeLoc subclasses through castAs()/getAs() 57 /// in order to get at the actual information. 58 class TypeLoc { 59 protected: 60 // The correctness of this relies on the property that, for Type *Ty, 61 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 62 const void *Ty = nullptr; 63 void *Data = nullptr; 64 65 public: 66 TypeLoc() = default; 67 TypeLoc(QualType ty, void *opaqueData) 68 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {} 69 TypeLoc(const Type *ty, void *opaqueData) 70 : Ty(ty), Data(opaqueData) {} 71 72 /// Convert to the specified TypeLoc type, asserting that this TypeLoc 73 /// is of the desired type. 74 /// 75 /// \pre T::isKind(*this) 76 template<typename T> 77 T castAs() const { 78 assert(T::isKind(*this)); 79 T t; 80 TypeLoc& tl = t; 81 tl = *this; 82 return t; 83 } 84 85 /// Convert to the specified TypeLoc type, returning a null TypeLoc if 86 /// this TypeLoc is not of the desired type. 87 template<typename T> 88 T getAs() const { 89 if (!T::isKind(*this)) 90 return {}; 91 T t; 92 TypeLoc& tl = t; 93 tl = *this; 94 return t; 95 } 96 97 /// Convert to the specified TypeLoc type, returning a null TypeLoc if 98 /// this TypeLoc is not of the desired type. It will consider type 99 /// adjustments from a type that was written as a T to another type that is 100 /// still canonically a T (ignores parens, attributes, elaborated types, etc). 101 template <typename T> 102 T getAsAdjusted() const; 103 104 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 105 /// except it also defines a Qualified enum that corresponds to the 106 /// QualifiedLoc class. 107 enum TypeLocClass { 108 #define ABSTRACT_TYPE(Class, Base) 109 #define TYPE(Class, Base) \ 110 Class = Type::Class, 111 #include "clang/AST/TypeNodes.inc" 112 Qualified 113 }; 114 115 TypeLocClass getTypeLocClass() const { 116 if (getType().hasLocalQualifiers()) return Qualified; 117 return (TypeLocClass) getType()->getTypeClass(); 118 } 119 120 bool isNull() const { return !Ty; } 121 explicit operator bool() const { return Ty; } 122 123 /// Returns the size of type source info data block for the given type. 124 static unsigned getFullDataSizeForType(QualType Ty); 125 126 /// Returns the alignment of type source info data block for 127 /// the given type. 128 static unsigned getLocalAlignmentForType(QualType Ty); 129 130 /// Get the type for which this source info wrapper provides 131 /// information. 132 QualType getType() const { 133 return QualType::getFromOpaquePtr(Ty); 134 } 135 136 const Type *getTypePtr() const { 137 return QualType::getFromOpaquePtr(Ty).getTypePtr(); 138 } 139 140 /// Get the pointer where source information is stored. 141 void *getOpaqueData() const { 142 return Data; 143 } 144 145 /// Get the begin source location. 146 SourceLocation getBeginLoc() const; 147 148 /// Get the end source location. 149 SourceLocation getEndLoc() const; 150 151 /// Get the full source range. 152 SourceRange getSourceRange() const LLVM_READONLY { 153 return SourceRange(getBeginLoc(), getEndLoc()); 154 } 155 156 157 /// Get the local source range. 158 SourceRange getLocalSourceRange() const { 159 return getLocalSourceRangeImpl(*this); 160 } 161 162 /// Returns the size of the type source info data block. 163 unsigned getFullDataSize() const { 164 return getFullDataSizeForType(getType()); 165 } 166 167 /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 168 /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 169 TypeLoc getNextTypeLoc() const { 170 return getNextTypeLocImpl(*this); 171 } 172 173 /// Skips past any qualifiers, if this is qualified. 174 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 175 176 TypeLoc IgnoreParens() const; 177 178 /// Find a type with the location of an explicit type qualifier. 179 /// 180 /// The result, if non-null, will be one of: 181 /// QualifiedTypeLoc 182 /// AtomicTypeLoc 183 /// AttributedTypeLoc, for those type attributes that behave as qualifiers 184 TypeLoc findExplicitQualifierLoc() const; 185 186 /// Get the typeloc of an AutoType whose type will be deduced for a variable 187 /// with an initializer of this type. This looks through declarators like 188 /// pointer types, but not through decltype or typedefs. 189 AutoTypeLoc getContainedAutoTypeLoc() const; 190 191 /// Initializes this to state that every location in this 192 /// type is the given location. 193 /// 194 /// This method exists to provide a simple transition for code that 195 /// relies on location-less types. 196 void initialize(ASTContext &Context, SourceLocation Loc) const { 197 initializeImpl(Context, *this, Loc); 198 } 199 200 /// Initializes this by copying its information from another 201 /// TypeLoc of the same type. 202 void initializeFullCopy(TypeLoc Other) { 203 assert(getType() == Other.getType()); 204 copy(Other); 205 } 206 207 /// Initializes this by copying its information from another 208 /// TypeLoc of the same type. The given size must be the full data 209 /// size. 210 void initializeFullCopy(TypeLoc Other, unsigned Size) { 211 assert(getType() == Other.getType()); 212 assert(getFullDataSize() == Size); 213 copy(Other); 214 } 215 216 /// Copies the other type loc into this one. 217 void copy(TypeLoc other); 218 219 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 220 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 221 } 222 223 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 224 return !(LHS == RHS); 225 } 226 227 /// Find the location of the nullability specifier (__nonnull, 228 /// __nullable, or __null_unspecifier), if there is one. 229 SourceLocation findNullabilityLoc() const; 230 231 private: 232 static bool isKind(const TypeLoc&) { 233 return true; 234 } 235 236 static void initializeImpl(ASTContext &Context, TypeLoc TL, 237 SourceLocation Loc); 238 static TypeLoc getNextTypeLocImpl(TypeLoc TL); 239 static TypeLoc IgnoreParensImpl(TypeLoc TL); 240 static SourceRange getLocalSourceRangeImpl(TypeLoc TL); 241 }; 242 243 inline TypeSourceInfo::TypeSourceInfo(QualType ty, size_t DataSize) : Ty(ty) { 244 // Init data attached to the object. See getTypeLoc. 245 memset(this + 1, 0, DataSize); 246 } 247 248 /// Return the TypeLoc for a type source info. 249 inline TypeLoc TypeSourceInfo::getTypeLoc() const { 250 // TODO: is this alignment already sufficient? 251 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); 252 } 253 254 /// Wrapper of type source information for a type with 255 /// no direct qualifiers. 256 class UnqualTypeLoc : public TypeLoc { 257 public: 258 UnqualTypeLoc() = default; 259 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 260 261 const Type *getTypePtr() const { 262 return reinterpret_cast<const Type*>(Ty); 263 } 264 265 TypeLocClass getTypeLocClass() const { 266 return (TypeLocClass) getTypePtr()->getTypeClass(); 267 } 268 269 private: 270 friend class TypeLoc; 271 272 static bool isKind(const TypeLoc &TL) { 273 return !TL.getType().hasLocalQualifiers(); 274 } 275 }; 276 277 /// Wrapper of type source information for a type with 278 /// non-trivial direct qualifiers. 279 /// 280 /// Currently, we intentionally do not provide source location for 281 /// type qualifiers. 282 class QualifiedTypeLoc : public TypeLoc { 283 public: 284 SourceRange getLocalSourceRange() const { return {}; } 285 286 UnqualTypeLoc getUnqualifiedLoc() const { 287 unsigned align = 288 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); 289 auto dataInt = reinterpret_cast<uintptr_t>(Data); 290 dataInt = llvm::alignTo(dataInt, align); 291 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt)); 292 } 293 294 /// Initializes the local data of this type source info block to 295 /// provide no information. 296 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 297 // do nothing 298 } 299 300 void copyLocal(TypeLoc other) { 301 // do nothing 302 } 303 304 TypeLoc getNextTypeLoc() const { 305 return getUnqualifiedLoc(); 306 } 307 308 /// Returns the size of the type source info data block that is 309 /// specific to this type. 310 unsigned getLocalDataSize() const { 311 // In fact, we don't currently preserve any location information 312 // for qualifiers. 313 return 0; 314 } 315 316 /// Returns the alignment of the type source info data block that is 317 /// specific to this type. 318 unsigned getLocalDataAlignment() const { 319 // We don't preserve any location information. 320 return 1; 321 } 322 323 private: 324 friend class TypeLoc; 325 326 static bool isKind(const TypeLoc &TL) { 327 return TL.getType().hasLocalQualifiers(); 328 } 329 }; 330 331 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 332 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) 333 return Loc.getUnqualifiedLoc(); 334 return castAs<UnqualTypeLoc>(); 335 } 336 337 /// A metaprogramming base class for TypeLoc classes which correspond 338 /// to a particular Type subclass. It is accepted for a single 339 /// TypeLoc class to correspond to multiple Type classes. 340 /// 341 /// \tparam Base a class from which to derive 342 /// \tparam Derived the class deriving from this one 343 /// \tparam TypeClass the concrete Type subclass associated with this 344 /// location type 345 /// \tparam LocalData the structure type of local location data for 346 /// this type 347 /// 348 /// TypeLocs with non-constant amounts of local data should override 349 /// getExtraLocalDataSize(); getExtraLocalData() will then point to 350 /// this extra memory. 351 /// 352 /// TypeLocs with an inner type should define 353 /// QualType getInnerType() const 354 /// and getInnerTypeLoc() will then point to this inner type's 355 /// location data. 356 /// 357 /// A word about hierarchies: this template is not designed to be 358 /// derived from multiple times in a hierarchy. It is also not 359 /// designed to be used for classes where subtypes might provide 360 /// different amounts of source information. It should be subclassed 361 /// only at the deepest portion of the hierarchy where all children 362 /// have identical source information; if that's an abstract type, 363 /// then further descendents should inherit from 364 /// InheritingConcreteTypeLoc instead. 365 template <class Base, class Derived, class TypeClass, class LocalData> 366 class ConcreteTypeLoc : public Base { 367 friend class TypeLoc; 368 369 const Derived *asDerived() const { 370 return static_cast<const Derived*>(this); 371 } 372 373 static bool isKind(const TypeLoc &TL) { 374 return !TL.getType().hasLocalQualifiers() && 375 Derived::classofType(TL.getTypePtr()); 376 } 377 378 static bool classofType(const Type *Ty) { 379 return TypeClass::classof(Ty); 380 } 381 382 public: 383 unsigned getLocalDataAlignment() const { 384 return std::max(unsigned(alignof(LocalData)), 385 asDerived()->getExtraLocalDataAlignment()); 386 } 387 388 unsigned getLocalDataSize() const { 389 unsigned size = sizeof(LocalData); 390 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 391 size = llvm::alignTo(size, extraAlign); 392 size += asDerived()->getExtraLocalDataSize(); 393 return size; 394 } 395 396 void copyLocal(Derived other) { 397 // Some subclasses have no data to copy. 398 if (asDerived()->getLocalDataSize() == 0) return; 399 400 // Copy the fixed-sized local data. 401 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData)); 402 403 // Copy the variable-sized local data. We need to do this 404 // separately because the padding in the source and the padding in 405 // the destination might be different. 406 memcpy(getExtraLocalData(), other.getExtraLocalData(), 407 asDerived()->getExtraLocalDataSize()); 408 } 409 410 TypeLoc getNextTypeLoc() const { 411 return getNextTypeLoc(asDerived()->getInnerType()); 412 } 413 414 const TypeClass *getTypePtr() const { 415 return cast<TypeClass>(Base::getTypePtr()); 416 } 417 418 protected: 419 unsigned getExtraLocalDataSize() const { 420 return 0; 421 } 422 423 unsigned getExtraLocalDataAlignment() const { 424 return 1; 425 } 426 427 LocalData *getLocalData() const { 428 return static_cast<LocalData*>(Base::Data); 429 } 430 431 /// Gets a pointer past the Info structure; useful for classes with 432 /// local data that can't be captured in the Info (e.g. because it's 433 /// of variable size). 434 void *getExtraLocalData() const { 435 unsigned size = sizeof(LocalData); 436 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 437 size = llvm::alignTo(size, extraAlign); 438 return reinterpret_cast<char *>(Base::Data) + size; 439 } 440 441 void *getNonLocalData() const { 442 auto data = reinterpret_cast<uintptr_t>(Base::Data); 443 data += asDerived()->getLocalDataSize(); 444 data = llvm::alignTo(data, getNextTypeAlign()); 445 return reinterpret_cast<void*>(data); 446 } 447 448 struct HasNoInnerType {}; 449 HasNoInnerType getInnerType() const { return HasNoInnerType(); } 450 451 TypeLoc getInnerTypeLoc() const { 452 return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 453 } 454 455 private: 456 unsigned getInnerTypeSize() const { 457 return getInnerTypeSize(asDerived()->getInnerType()); 458 } 459 460 unsigned getInnerTypeSize(HasNoInnerType _) const { 461 return 0; 462 } 463 464 unsigned getInnerTypeSize(QualType _) const { 465 return getInnerTypeLoc().getFullDataSize(); 466 } 467 468 unsigned getNextTypeAlign() const { 469 return getNextTypeAlign(asDerived()->getInnerType()); 470 } 471 472 unsigned getNextTypeAlign(HasNoInnerType _) const { 473 return 1; 474 } 475 476 unsigned getNextTypeAlign(QualType T) const { 477 return TypeLoc::getLocalAlignmentForType(T); 478 } 479 480 TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; } 481 482 TypeLoc getNextTypeLoc(QualType T) const { 483 return TypeLoc(T, getNonLocalData()); 484 } 485 }; 486 487 /// A metaprogramming class designed for concrete subtypes of abstract 488 /// types where all subtypes share equivalently-structured source 489 /// information. See the note on ConcreteTypeLoc. 490 template <class Base, class Derived, class TypeClass> 491 class InheritingConcreteTypeLoc : public Base { 492 friend class TypeLoc; 493 494 static bool classofType(const Type *Ty) { 495 return TypeClass::classof(Ty); 496 } 497 498 static bool isKind(const TypeLoc &TL) { 499 return !TL.getType().hasLocalQualifiers() && 500 Derived::classofType(TL.getTypePtr()); 501 } 502 static bool isKind(const UnqualTypeLoc &TL) { 503 return Derived::classofType(TL.getTypePtr()); 504 } 505 506 public: 507 const TypeClass *getTypePtr() const { 508 return cast<TypeClass>(Base::getTypePtr()); 509 } 510 }; 511 512 struct TypeSpecLocInfo { 513 SourceLocation NameLoc; 514 }; 515 516 /// A reasonable base class for TypeLocs that correspond to 517 /// types that are written as a type-specifier. 518 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 519 TypeSpecTypeLoc, 520 Type, 521 TypeSpecLocInfo> { 522 public: 523 enum { 524 LocalDataSize = sizeof(TypeSpecLocInfo), 525 LocalDataAlignment = alignof(TypeSpecLocInfo) 526 }; 527 528 SourceLocation getNameLoc() const { 529 return this->getLocalData()->NameLoc; 530 } 531 532 void setNameLoc(SourceLocation Loc) { 533 this->getLocalData()->NameLoc = Loc; 534 } 535 536 SourceRange getLocalSourceRange() const { 537 return SourceRange(getNameLoc(), getNameLoc()); 538 } 539 540 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 541 setNameLoc(Loc); 542 } 543 544 private: 545 friend class TypeLoc; 546 547 static bool isKind(const TypeLoc &TL); 548 }; 549 550 struct BuiltinLocInfo { 551 SourceRange BuiltinRange; 552 }; 553 554 /// Wrapper for source info for builtin types. 555 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 556 BuiltinTypeLoc, 557 BuiltinType, 558 BuiltinLocInfo> { 559 public: 560 SourceLocation getBuiltinLoc() const { 561 return getLocalData()->BuiltinRange.getBegin(); 562 } 563 564 void setBuiltinLoc(SourceLocation Loc) { 565 getLocalData()->BuiltinRange = Loc; 566 } 567 568 void expandBuiltinRange(SourceRange Range) { 569 SourceRange &BuiltinRange = getLocalData()->BuiltinRange; 570 if (!BuiltinRange.getBegin().isValid()) { 571 BuiltinRange = Range; 572 } else { 573 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin())); 574 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd())); 575 } 576 } 577 578 SourceLocation getNameLoc() const { return getBuiltinLoc(); } 579 580 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 581 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 582 } 583 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 584 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 585 } 586 587 bool needsExtraLocalData() const { 588 BuiltinType::Kind bk = getTypePtr()->getKind(); 589 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) || 590 (bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) || 591 bk == BuiltinType::UChar || bk == BuiltinType::SChar; 592 } 593 594 unsigned getExtraLocalDataSize() const { 595 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 596 } 597 598 unsigned getExtraLocalDataAlignment() const { 599 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1; 600 } 601 602 SourceRange getLocalSourceRange() const { 603 return getLocalData()->BuiltinRange; 604 } 605 606 TypeSpecifierSign getWrittenSignSpec() const { 607 if (needsExtraLocalData()) 608 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 609 else 610 return TypeSpecifierSign::Unspecified; 611 } 612 613 bool hasWrittenSignSpec() const { 614 return getWrittenSignSpec() != TypeSpecifierSign::Unspecified; 615 } 616 617 void setWrittenSignSpec(TypeSpecifierSign written) { 618 if (needsExtraLocalData()) 619 getWrittenBuiltinSpecs().Sign = static_cast<unsigned>(written); 620 } 621 622 TypeSpecifierWidth getWrittenWidthSpec() const { 623 if (needsExtraLocalData()) 624 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 625 else 626 return TypeSpecifierWidth::Unspecified; 627 } 628 629 bool hasWrittenWidthSpec() const { 630 return getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified; 631 } 632 633 void setWrittenWidthSpec(TypeSpecifierWidth written) { 634 if (needsExtraLocalData()) 635 getWrittenBuiltinSpecs().Width = static_cast<unsigned>(written); 636 } 637 638 TypeSpecifierType getWrittenTypeSpec() const; 639 640 bool hasWrittenTypeSpec() const { 641 return getWrittenTypeSpec() != TST_unspecified; 642 } 643 644 void setWrittenTypeSpec(TypeSpecifierType written) { 645 if (needsExtraLocalData()) 646 getWrittenBuiltinSpecs().Type = written; 647 } 648 649 bool hasModeAttr() const { 650 if (needsExtraLocalData()) 651 return getWrittenBuiltinSpecs().ModeAttr; 652 else 653 return false; 654 } 655 656 void setModeAttr(bool written) { 657 if (needsExtraLocalData()) 658 getWrittenBuiltinSpecs().ModeAttr = written; 659 } 660 661 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 662 setBuiltinLoc(Loc); 663 if (needsExtraLocalData()) { 664 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 665 wbs.Sign = static_cast<unsigned>(TypeSpecifierSign::Unspecified); 666 wbs.Width = static_cast<unsigned>(TypeSpecifierWidth::Unspecified); 667 wbs.Type = TST_unspecified; 668 wbs.ModeAttr = false; 669 } 670 } 671 }; 672 673 /// Wrapper for source info for types used via transparent aliases. 674 class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 675 UsingTypeLoc, UsingType> { 676 public: 677 QualType getUnderlyingType() const { 678 return getTypePtr()->getUnderlyingType(); 679 } 680 UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); } 681 }; 682 683 /// Wrapper for source info for typedefs. 684 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 685 TypedefTypeLoc, 686 TypedefType> { 687 public: 688 TypedefNameDecl *getTypedefNameDecl() const { 689 return getTypePtr()->getDecl(); 690 } 691 }; 692 693 /// Wrapper for source info for injected class names of class 694 /// templates. 695 class InjectedClassNameTypeLoc : 696 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 697 InjectedClassNameTypeLoc, 698 InjectedClassNameType> { 699 public: 700 CXXRecordDecl *getDecl() const { 701 return getTypePtr()->getDecl(); 702 } 703 }; 704 705 /// Wrapper for source info for unresolved typename using decls. 706 class UnresolvedUsingTypeLoc : 707 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 708 UnresolvedUsingTypeLoc, 709 UnresolvedUsingType> { 710 public: 711 UnresolvedUsingTypenameDecl *getDecl() const { 712 return getTypePtr()->getDecl(); 713 } 714 }; 715 716 /// Wrapper for source info for tag types. Note that this only 717 /// records source info for the name itself; a type written 'struct foo' 718 /// should be represented as an ElaboratedTypeLoc. We currently 719 /// only do that when C++ is enabled because of the expense of 720 /// creating an ElaboratedType node for so many type references in C. 721 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 722 TagTypeLoc, 723 TagType> { 724 public: 725 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 726 727 /// True if the tag was defined in this type specifier. 728 bool isDefinition() const; 729 }; 730 731 /// Wrapper for source info for record types. 732 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 733 RecordTypeLoc, 734 RecordType> { 735 public: 736 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 737 }; 738 739 /// Wrapper for source info for enum types. 740 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 741 EnumTypeLoc, 742 EnumType> { 743 public: 744 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 745 }; 746 747 /// Wrapper for template type parameters. 748 class TemplateTypeParmTypeLoc : 749 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 750 TemplateTypeParmTypeLoc, 751 TemplateTypeParmType> { 752 public: 753 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 754 }; 755 756 struct ObjCTypeParamTypeLocInfo { 757 SourceLocation NameLoc; 758 }; 759 760 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for 761 /// protocol qualifiers are stored after Info. 762 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 763 ObjCTypeParamTypeLoc, 764 ObjCTypeParamType, 765 ObjCTypeParamTypeLocInfo> { 766 // SourceLocations are stored after Info, one for each protocol qualifier. 767 SourceLocation *getProtocolLocArray() const { 768 return (SourceLocation*)this->getExtraLocalData() + 2; 769 } 770 771 public: 772 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); } 773 774 SourceLocation getNameLoc() const { 775 return this->getLocalData()->NameLoc; 776 } 777 778 void setNameLoc(SourceLocation Loc) { 779 this->getLocalData()->NameLoc = Loc; 780 } 781 782 SourceLocation getProtocolLAngleLoc() const { 783 return getNumProtocols() ? 784 *((SourceLocation*)this->getExtraLocalData()) : 785 SourceLocation(); 786 } 787 788 void setProtocolLAngleLoc(SourceLocation Loc) { 789 *((SourceLocation*)this->getExtraLocalData()) = Loc; 790 } 791 792 SourceLocation getProtocolRAngleLoc() const { 793 return getNumProtocols() ? 794 *((SourceLocation*)this->getExtraLocalData() + 1) : 795 SourceLocation(); 796 } 797 798 void setProtocolRAngleLoc(SourceLocation Loc) { 799 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc; 800 } 801 802 unsigned getNumProtocols() const { 803 return this->getTypePtr()->getNumProtocols(); 804 } 805 806 SourceLocation getProtocolLoc(unsigned i) const { 807 assert(i < getNumProtocols() && "Index is out of bounds!"); 808 return getProtocolLocArray()[i]; 809 } 810 811 void setProtocolLoc(unsigned i, SourceLocation Loc) { 812 assert(i < getNumProtocols() && "Index is out of bounds!"); 813 getProtocolLocArray()[i] = Loc; 814 } 815 816 ObjCProtocolDecl *getProtocol(unsigned i) const { 817 assert(i < getNumProtocols() && "Index is out of bounds!"); 818 return *(this->getTypePtr()->qual_begin() + i); 819 } 820 821 ArrayRef<SourceLocation> getProtocolLocs() const { 822 return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols()); 823 } 824 825 void initializeLocal(ASTContext &Context, SourceLocation Loc); 826 827 unsigned getExtraLocalDataSize() const { 828 if (!this->getNumProtocols()) return 0; 829 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc 830 // as well. 831 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ; 832 } 833 834 unsigned getExtraLocalDataAlignment() const { 835 return alignof(SourceLocation); 836 } 837 838 SourceRange getLocalSourceRange() const { 839 SourceLocation start = getNameLoc(); 840 SourceLocation end = getProtocolRAngleLoc(); 841 if (end.isInvalid()) return SourceRange(start, start); 842 return SourceRange(start, end); 843 } 844 }; 845 846 /// Wrapper for substituted template type parameters. 847 class SubstTemplateTypeParmTypeLoc : 848 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 849 SubstTemplateTypeParmTypeLoc, 850 SubstTemplateTypeParmType> { 851 }; 852 853 /// Wrapper for substituted template type parameters. 854 class SubstTemplateTypeParmPackTypeLoc : 855 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 856 SubstTemplateTypeParmPackTypeLoc, 857 SubstTemplateTypeParmPackType> { 858 }; 859 860 struct AttributedLocInfo { 861 const Attr *TypeAttr; 862 }; 863 864 /// Type source information for an attributed type. 865 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 866 AttributedTypeLoc, 867 AttributedType, 868 AttributedLocInfo> { 869 public: 870 attr::Kind getAttrKind() const { 871 return getTypePtr()->getAttrKind(); 872 } 873 874 bool isQualifier() const { 875 return getTypePtr()->isQualifier(); 876 } 877 878 /// The modified type, which is generally canonically different from 879 /// the attribute type. 880 /// int main(int, char**) __attribute__((noreturn)) 881 /// ~~~ ~~~~~~~~~~~~~ 882 TypeLoc getModifiedLoc() const { 883 return getInnerTypeLoc(); 884 } 885 886 /// The type attribute. 887 const Attr *getAttr() const { 888 return getLocalData()->TypeAttr; 889 } 890 void setAttr(const Attr *A) { 891 getLocalData()->TypeAttr = A; 892 } 893 894 template<typename T> const T *getAttrAs() { 895 return dyn_cast_or_null<T>(getAttr()); 896 } 897 898 SourceRange getLocalSourceRange() const; 899 900 void initializeLocal(ASTContext &Context, SourceLocation loc) { 901 setAttr(nullptr); 902 } 903 904 QualType getInnerType() const { 905 return getTypePtr()->getModifiedType(); 906 } 907 }; 908 909 struct BTFTagAttributedLocInfo {}; // Nothing. 910 911 /// Type source information for an btf_tag attributed type. 912 class BTFTagAttributedTypeLoc 913 : public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc, 914 BTFTagAttributedType, BTFTagAttributedLocInfo> { 915 public: 916 TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); } 917 918 /// The btf_type_tag attribute. 919 const BTFTypeTagAttr *getAttr() const { return getTypePtr()->getAttr(); } 920 921 template <typename T> T *getAttrAs() { 922 return dyn_cast_or_null<T>(getAttr()); 923 } 924 925 SourceRange getLocalSourceRange() const; 926 927 void initializeLocal(ASTContext &Context, SourceLocation loc) {} 928 929 QualType getInnerType() const { return getTypePtr()->getWrappedType(); } 930 }; 931 932 struct ObjCObjectTypeLocInfo { 933 SourceLocation TypeArgsLAngleLoc; 934 SourceLocation TypeArgsRAngleLoc; 935 SourceLocation ProtocolLAngleLoc; 936 SourceLocation ProtocolRAngleLoc; 937 bool HasBaseTypeAsWritten; 938 }; 939 940 // A helper class for defining ObjC TypeLocs that can qualified with 941 // protocols. 942 // 943 // TypeClass basically has to be either ObjCInterfaceType or 944 // ObjCObjectPointerType. 945 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 946 ObjCObjectTypeLoc, 947 ObjCObjectType, 948 ObjCObjectTypeLocInfo> { 949 // TypeSourceInfo*'s are stored after Info, one for each type argument. 950 TypeSourceInfo **getTypeArgLocArray() const { 951 return (TypeSourceInfo**)this->getExtraLocalData(); 952 } 953 954 // SourceLocations are stored after the type argument information, one for 955 // each Protocol. 956 SourceLocation *getProtocolLocArray() const { 957 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs()); 958 } 959 960 public: 961 SourceLocation getTypeArgsLAngleLoc() const { 962 return this->getLocalData()->TypeArgsLAngleLoc; 963 } 964 965 void setTypeArgsLAngleLoc(SourceLocation Loc) { 966 this->getLocalData()->TypeArgsLAngleLoc = Loc; 967 } 968 969 SourceLocation getTypeArgsRAngleLoc() const { 970 return this->getLocalData()->TypeArgsRAngleLoc; 971 } 972 973 void setTypeArgsRAngleLoc(SourceLocation Loc) { 974 this->getLocalData()->TypeArgsRAngleLoc = Loc; 975 } 976 977 unsigned getNumTypeArgs() const { 978 return this->getTypePtr()->getTypeArgsAsWritten().size(); 979 } 980 981 TypeSourceInfo *getTypeArgTInfo(unsigned i) const { 982 assert(i < getNumTypeArgs() && "Index is out of bounds!"); 983 return getTypeArgLocArray()[i]; 984 } 985 986 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) { 987 assert(i < getNumTypeArgs() && "Index is out of bounds!"); 988 getTypeArgLocArray()[i] = TInfo; 989 } 990 991 SourceLocation getProtocolLAngleLoc() const { 992 return this->getLocalData()->ProtocolLAngleLoc; 993 } 994 995 void setProtocolLAngleLoc(SourceLocation Loc) { 996 this->getLocalData()->ProtocolLAngleLoc = Loc; 997 } 998 999 SourceLocation getProtocolRAngleLoc() const { 1000 return this->getLocalData()->ProtocolRAngleLoc; 1001 } 1002 1003 void setProtocolRAngleLoc(SourceLocation Loc) { 1004 this->getLocalData()->ProtocolRAngleLoc = Loc; 1005 } 1006 1007 unsigned getNumProtocols() const { 1008 return this->getTypePtr()->getNumProtocols(); 1009 } 1010 1011 SourceLocation getProtocolLoc(unsigned i) const { 1012 assert(i < getNumProtocols() && "Index is out of bounds!"); 1013 return getProtocolLocArray()[i]; 1014 } 1015 1016 void setProtocolLoc(unsigned i, SourceLocation Loc) { 1017 assert(i < getNumProtocols() && "Index is out of bounds!"); 1018 getProtocolLocArray()[i] = Loc; 1019 } 1020 1021 ObjCProtocolDecl *getProtocol(unsigned i) const { 1022 assert(i < getNumProtocols() && "Index is out of bounds!"); 1023 return *(this->getTypePtr()->qual_begin() + i); 1024 } 1025 1026 1027 ArrayRef<SourceLocation> getProtocolLocs() const { 1028 return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols()); 1029 } 1030 1031 bool hasBaseTypeAsWritten() const { 1032 return getLocalData()->HasBaseTypeAsWritten; 1033 } 1034 1035 void setHasBaseTypeAsWritten(bool HasBaseType) { 1036 getLocalData()->HasBaseTypeAsWritten = HasBaseType; 1037 } 1038 1039 TypeLoc getBaseLoc() const { 1040 return getInnerTypeLoc(); 1041 } 1042 1043 SourceRange getLocalSourceRange() const { 1044 SourceLocation start = getTypeArgsLAngleLoc(); 1045 if (start.isInvalid()) 1046 start = getProtocolLAngleLoc(); 1047 SourceLocation end = getProtocolRAngleLoc(); 1048 if (end.isInvalid()) 1049 end = getTypeArgsRAngleLoc(); 1050 return SourceRange(start, end); 1051 } 1052 1053 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1054 1055 unsigned getExtraLocalDataSize() const { 1056 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *) 1057 + this->getNumProtocols() * sizeof(SourceLocation); 1058 } 1059 1060 unsigned getExtraLocalDataAlignment() const { 1061 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *), 1062 "not enough alignment for tail-allocated data"); 1063 return alignof(TypeSourceInfo *); 1064 } 1065 1066 QualType getInnerType() const { 1067 return getTypePtr()->getBaseType(); 1068 } 1069 }; 1070 1071 struct ObjCInterfaceLocInfo { 1072 SourceLocation NameLoc; 1073 SourceLocation NameEndLoc; 1074 }; 1075 1076 /// Wrapper for source info for ObjC interfaces. 1077 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 1078 ObjCInterfaceTypeLoc, 1079 ObjCInterfaceType, 1080 ObjCInterfaceLocInfo> { 1081 public: 1082 ObjCInterfaceDecl *getIFaceDecl() const { 1083 return getTypePtr()->getDecl(); 1084 } 1085 1086 SourceLocation getNameLoc() const { 1087 return getLocalData()->NameLoc; 1088 } 1089 1090 void setNameLoc(SourceLocation Loc) { 1091 getLocalData()->NameLoc = Loc; 1092 } 1093 1094 SourceRange getLocalSourceRange() const { 1095 return SourceRange(getNameLoc(), getNameEndLoc()); 1096 } 1097 1098 SourceLocation getNameEndLoc() const { 1099 return getLocalData()->NameEndLoc; 1100 } 1101 1102 void setNameEndLoc(SourceLocation Loc) { 1103 getLocalData()->NameEndLoc = Loc; 1104 } 1105 1106 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1107 setNameLoc(Loc); 1108 setNameEndLoc(Loc); 1109 } 1110 }; 1111 1112 struct MacroQualifiedLocInfo { 1113 SourceLocation ExpansionLoc; 1114 }; 1115 1116 class MacroQualifiedTypeLoc 1117 : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc, 1118 MacroQualifiedType, MacroQualifiedLocInfo> { 1119 public: 1120 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1121 setExpansionLoc(Loc); 1122 } 1123 1124 TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } 1125 1126 const IdentifierInfo *getMacroIdentifier() const { 1127 return getTypePtr()->getMacroIdentifier(); 1128 } 1129 1130 SourceLocation getExpansionLoc() const { 1131 return this->getLocalData()->ExpansionLoc; 1132 } 1133 1134 void setExpansionLoc(SourceLocation Loc) { 1135 this->getLocalData()->ExpansionLoc = Loc; 1136 } 1137 1138 QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); } 1139 1140 SourceRange getLocalSourceRange() const { 1141 return getInnerLoc().getLocalSourceRange(); 1142 } 1143 }; 1144 1145 struct ParenLocInfo { 1146 SourceLocation LParenLoc; 1147 SourceLocation RParenLoc; 1148 }; 1149 1150 class ParenTypeLoc 1151 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 1152 ParenLocInfo> { 1153 public: 1154 SourceLocation getLParenLoc() const { 1155 return this->getLocalData()->LParenLoc; 1156 } 1157 1158 SourceLocation getRParenLoc() const { 1159 return this->getLocalData()->RParenLoc; 1160 } 1161 1162 void setLParenLoc(SourceLocation Loc) { 1163 this->getLocalData()->LParenLoc = Loc; 1164 } 1165 1166 void setRParenLoc(SourceLocation Loc) { 1167 this->getLocalData()->RParenLoc = Loc; 1168 } 1169 1170 SourceRange getLocalSourceRange() const { 1171 return SourceRange(getLParenLoc(), getRParenLoc()); 1172 } 1173 1174 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1175 setLParenLoc(Loc); 1176 setRParenLoc(Loc); 1177 } 1178 1179 TypeLoc getInnerLoc() const { 1180 return getInnerTypeLoc(); 1181 } 1182 1183 QualType getInnerType() const { 1184 return this->getTypePtr()->getInnerType(); 1185 } 1186 }; 1187 1188 inline TypeLoc TypeLoc::IgnoreParens() const { 1189 if (ParenTypeLoc::isKind(*this)) 1190 return IgnoreParensImpl(*this); 1191 return *this; 1192 } 1193 1194 struct AdjustedLocInfo {}; // Nothing. 1195 1196 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc, 1197 AdjustedType, AdjustedLocInfo> { 1198 public: 1199 TypeLoc getOriginalLoc() const { 1200 return getInnerTypeLoc(); 1201 } 1202 1203 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1204 // do nothing 1205 } 1206 1207 QualType getInnerType() const { 1208 // The inner type is the undecayed type, since that's what we have source 1209 // location information for. 1210 return getTypePtr()->getOriginalType(); 1211 } 1212 1213 SourceRange getLocalSourceRange() const { return {}; } 1214 1215 unsigned getLocalDataSize() const { 1216 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique 1217 // anyway. TypeLocBuilder can't handle data sizes of 1. 1218 return 0; // No data. 1219 } 1220 }; 1221 1222 /// Wrapper for source info for pointers decayed from arrays and 1223 /// functions. 1224 class DecayedTypeLoc : public InheritingConcreteTypeLoc< 1225 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> { 1226 }; 1227 1228 struct PointerLikeLocInfo { 1229 SourceLocation StarLoc; 1230 }; 1231 1232 /// A base class for 1233 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 1234 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 1235 TypeClass, LocalData> { 1236 public: 1237 SourceLocation getSigilLoc() const { 1238 return this->getLocalData()->StarLoc; 1239 } 1240 1241 void setSigilLoc(SourceLocation Loc) { 1242 this->getLocalData()->StarLoc = Loc; 1243 } 1244 1245 TypeLoc getPointeeLoc() const { 1246 return this->getInnerTypeLoc(); 1247 } 1248 1249 SourceRange getLocalSourceRange() const { 1250 return SourceRange(getSigilLoc(), getSigilLoc()); 1251 } 1252 1253 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1254 setSigilLoc(Loc); 1255 } 1256 1257 QualType getInnerType() const { 1258 return this->getTypePtr()->getPointeeType(); 1259 } 1260 }; 1261 1262 /// Wrapper for source info for pointers. 1263 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 1264 PointerType> { 1265 public: 1266 SourceLocation getStarLoc() const { 1267 return getSigilLoc(); 1268 } 1269 1270 void setStarLoc(SourceLocation Loc) { 1271 setSigilLoc(Loc); 1272 } 1273 }; 1274 1275 /// Wrapper for source info for block pointers. 1276 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 1277 BlockPointerType> { 1278 public: 1279 SourceLocation getCaretLoc() const { 1280 return getSigilLoc(); 1281 } 1282 1283 void setCaretLoc(SourceLocation Loc) { 1284 setSigilLoc(Loc); 1285 } 1286 }; 1287 1288 struct MemberPointerLocInfo : public PointerLikeLocInfo { 1289 TypeSourceInfo *ClassTInfo; 1290 }; 1291 1292 /// Wrapper for source info for member pointers. 1293 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 1294 MemberPointerType, 1295 MemberPointerLocInfo> { 1296 public: 1297 SourceLocation getStarLoc() const { 1298 return getSigilLoc(); 1299 } 1300 1301 void setStarLoc(SourceLocation Loc) { 1302 setSigilLoc(Loc); 1303 } 1304 1305 const Type *getClass() const { 1306 return getTypePtr()->getClass(); 1307 } 1308 1309 TypeSourceInfo *getClassTInfo() const { 1310 return getLocalData()->ClassTInfo; 1311 } 1312 1313 void setClassTInfo(TypeSourceInfo* TI) { 1314 getLocalData()->ClassTInfo = TI; 1315 } 1316 1317 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1318 setSigilLoc(Loc); 1319 setClassTInfo(nullptr); 1320 } 1321 1322 SourceRange getLocalSourceRange() const { 1323 if (TypeSourceInfo *TI = getClassTInfo()) 1324 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 1325 else 1326 return SourceRange(getStarLoc()); 1327 } 1328 }; 1329 1330 /// Wraps an ObjCPointerType with source location information. 1331 class ObjCObjectPointerTypeLoc : 1332 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1333 ObjCObjectPointerType> { 1334 public: 1335 SourceLocation getStarLoc() const { 1336 return getSigilLoc(); 1337 } 1338 1339 void setStarLoc(SourceLocation Loc) { 1340 setSigilLoc(Loc); 1341 } 1342 }; 1343 1344 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1345 ReferenceType> { 1346 public: 1347 QualType getInnerType() const { 1348 return getTypePtr()->getPointeeTypeAsWritten(); 1349 } 1350 }; 1351 1352 class LValueReferenceTypeLoc : 1353 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1354 LValueReferenceTypeLoc, 1355 LValueReferenceType> { 1356 public: 1357 SourceLocation getAmpLoc() const { 1358 return getSigilLoc(); 1359 } 1360 1361 void setAmpLoc(SourceLocation Loc) { 1362 setSigilLoc(Loc); 1363 } 1364 }; 1365 1366 class RValueReferenceTypeLoc : 1367 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1368 RValueReferenceTypeLoc, 1369 RValueReferenceType> { 1370 public: 1371 SourceLocation getAmpAmpLoc() const { 1372 return getSigilLoc(); 1373 } 1374 1375 void setAmpAmpLoc(SourceLocation Loc) { 1376 setSigilLoc(Loc); 1377 } 1378 }; 1379 1380 struct FunctionLocInfo { 1381 SourceLocation LocalRangeBegin; 1382 SourceLocation LParenLoc; 1383 SourceLocation RParenLoc; 1384 SourceLocation LocalRangeEnd; 1385 }; 1386 1387 /// Wrapper for source info for functions. 1388 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1389 FunctionTypeLoc, 1390 FunctionType, 1391 FunctionLocInfo> { 1392 bool hasExceptionSpec() const { 1393 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) { 1394 return FPT->hasExceptionSpec(); 1395 } 1396 return false; 1397 } 1398 1399 SourceRange *getExceptionSpecRangePtr() const { 1400 assert(hasExceptionSpec() && "No exception spec range"); 1401 // After the Info comes the ParmVarDecl array, and after that comes the 1402 // exception specification information. 1403 return (SourceRange *)(getParmArray() + getNumParams()); 1404 } 1405 1406 public: 1407 SourceLocation getLocalRangeBegin() const { 1408 return getLocalData()->LocalRangeBegin; 1409 } 1410 1411 void setLocalRangeBegin(SourceLocation L) { 1412 getLocalData()->LocalRangeBegin = L; 1413 } 1414 1415 SourceLocation getLocalRangeEnd() const { 1416 return getLocalData()->LocalRangeEnd; 1417 } 1418 1419 void setLocalRangeEnd(SourceLocation L) { 1420 getLocalData()->LocalRangeEnd = L; 1421 } 1422 1423 SourceLocation getLParenLoc() const { 1424 return this->getLocalData()->LParenLoc; 1425 } 1426 1427 void setLParenLoc(SourceLocation Loc) { 1428 this->getLocalData()->LParenLoc = Loc; 1429 } 1430 1431 SourceLocation getRParenLoc() const { 1432 return this->getLocalData()->RParenLoc; 1433 } 1434 1435 void setRParenLoc(SourceLocation Loc) { 1436 this->getLocalData()->RParenLoc = Loc; 1437 } 1438 1439 SourceRange getParensRange() const { 1440 return SourceRange(getLParenLoc(), getRParenLoc()); 1441 } 1442 1443 SourceRange getExceptionSpecRange() const { 1444 if (hasExceptionSpec()) 1445 return *getExceptionSpecRangePtr(); 1446 return {}; 1447 } 1448 1449 void setExceptionSpecRange(SourceRange R) { 1450 if (hasExceptionSpec()) 1451 *getExceptionSpecRangePtr() = R; 1452 } 1453 1454 ArrayRef<ParmVarDecl *> getParams() const { 1455 return llvm::ArrayRef(getParmArray(), getNumParams()); 1456 } 1457 1458 // ParmVarDecls* are stored after Info, one for each parameter. 1459 ParmVarDecl **getParmArray() const { 1460 return (ParmVarDecl**) getExtraLocalData(); 1461 } 1462 1463 unsigned getNumParams() const { 1464 if (isa<FunctionNoProtoType>(getTypePtr())) 1465 return 0; 1466 return cast<FunctionProtoType>(getTypePtr())->getNumParams(); 1467 } 1468 1469 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; } 1470 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1471 1472 TypeLoc getReturnLoc() const { 1473 return getInnerTypeLoc(); 1474 } 1475 1476 SourceRange getLocalSourceRange() const { 1477 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1478 } 1479 1480 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1481 setLocalRangeBegin(Loc); 1482 setLParenLoc(Loc); 1483 setRParenLoc(Loc); 1484 setLocalRangeEnd(Loc); 1485 for (unsigned i = 0, e = getNumParams(); i != e; ++i) 1486 setParam(i, nullptr); 1487 if (hasExceptionSpec()) 1488 setExceptionSpecRange(Loc); 1489 } 1490 1491 /// Returns the size of the type source info data block that is 1492 /// specific to this type. 1493 unsigned getExtraLocalDataSize() const { 1494 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0; 1495 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize; 1496 } 1497 1498 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); } 1499 1500 QualType getInnerType() const { return getTypePtr()->getReturnType(); } 1501 }; 1502 1503 class FunctionProtoTypeLoc : 1504 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1505 FunctionProtoTypeLoc, 1506 FunctionProtoType> { 1507 }; 1508 1509 class FunctionNoProtoTypeLoc : 1510 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1511 FunctionNoProtoTypeLoc, 1512 FunctionNoProtoType> { 1513 }; 1514 1515 struct ArrayLocInfo { 1516 SourceLocation LBracketLoc, RBracketLoc; 1517 Expr *Size; 1518 }; 1519 1520 /// Wrapper for source info for arrays. 1521 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1522 ArrayTypeLoc, 1523 ArrayType, 1524 ArrayLocInfo> { 1525 public: 1526 SourceLocation getLBracketLoc() const { 1527 return getLocalData()->LBracketLoc; 1528 } 1529 1530 void setLBracketLoc(SourceLocation Loc) { 1531 getLocalData()->LBracketLoc = Loc; 1532 } 1533 1534 SourceLocation getRBracketLoc() const { 1535 return getLocalData()->RBracketLoc; 1536 } 1537 1538 void setRBracketLoc(SourceLocation Loc) { 1539 getLocalData()->RBracketLoc = Loc; 1540 } 1541 1542 SourceRange getBracketsRange() const { 1543 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1544 } 1545 1546 Expr *getSizeExpr() const { 1547 return getLocalData()->Size; 1548 } 1549 1550 void setSizeExpr(Expr *Size) { 1551 getLocalData()->Size = Size; 1552 } 1553 1554 TypeLoc getElementLoc() const { 1555 return getInnerTypeLoc(); 1556 } 1557 1558 SourceRange getLocalSourceRange() const { 1559 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1560 } 1561 1562 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1563 setLBracketLoc(Loc); 1564 setRBracketLoc(Loc); 1565 setSizeExpr(nullptr); 1566 } 1567 1568 QualType getInnerType() const { return getTypePtr()->getElementType(); } 1569 }; 1570 1571 class ConstantArrayTypeLoc : 1572 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1573 ConstantArrayTypeLoc, 1574 ConstantArrayType> { 1575 }; 1576 1577 class IncompleteArrayTypeLoc : 1578 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1579 IncompleteArrayTypeLoc, 1580 IncompleteArrayType> { 1581 }; 1582 1583 class DependentSizedArrayTypeLoc : 1584 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1585 DependentSizedArrayTypeLoc, 1586 DependentSizedArrayType> { 1587 public: 1588 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1589 ArrayTypeLoc::initializeLocal(Context, Loc); 1590 setSizeExpr(getTypePtr()->getSizeExpr()); 1591 } 1592 }; 1593 1594 class VariableArrayTypeLoc : 1595 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1596 VariableArrayTypeLoc, 1597 VariableArrayType> { 1598 }; 1599 1600 // Location information for a TemplateName. Rudimentary for now. 1601 struct TemplateNameLocInfo { 1602 SourceLocation NameLoc; 1603 }; 1604 1605 struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1606 SourceLocation TemplateKWLoc; 1607 SourceLocation LAngleLoc; 1608 SourceLocation RAngleLoc; 1609 }; 1610 1611 class TemplateSpecializationTypeLoc : 1612 public ConcreteTypeLoc<UnqualTypeLoc, 1613 TemplateSpecializationTypeLoc, 1614 TemplateSpecializationType, 1615 TemplateSpecializationLocInfo> { 1616 public: 1617 SourceLocation getTemplateKeywordLoc() const { 1618 return getLocalData()->TemplateKWLoc; 1619 } 1620 1621 void setTemplateKeywordLoc(SourceLocation Loc) { 1622 getLocalData()->TemplateKWLoc = Loc; 1623 } 1624 1625 SourceLocation getLAngleLoc() const { 1626 return getLocalData()->LAngleLoc; 1627 } 1628 1629 void setLAngleLoc(SourceLocation Loc) { 1630 getLocalData()->LAngleLoc = Loc; 1631 } 1632 1633 SourceLocation getRAngleLoc() const { 1634 return getLocalData()->RAngleLoc; 1635 } 1636 1637 void setRAngleLoc(SourceLocation Loc) { 1638 getLocalData()->RAngleLoc = Loc; 1639 } 1640 1641 unsigned getNumArgs() const { 1642 return getTypePtr()->template_arguments().size(); 1643 } 1644 1645 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1646 getArgInfos()[i] = AI; 1647 } 1648 1649 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1650 return getArgInfos()[i]; 1651 } 1652 1653 TemplateArgumentLoc getArgLoc(unsigned i) const { 1654 return TemplateArgumentLoc(getTypePtr()->template_arguments()[i], 1655 getArgLocInfo(i)); 1656 } 1657 1658 SourceLocation getTemplateNameLoc() const { 1659 return getLocalData()->NameLoc; 1660 } 1661 1662 void setTemplateNameLoc(SourceLocation Loc) { 1663 getLocalData()->NameLoc = Loc; 1664 } 1665 1666 /// - Copy the location information from the given info. 1667 void copy(TemplateSpecializationTypeLoc Loc) { 1668 unsigned size = getFullDataSize(); 1669 assert(size == Loc.getFullDataSize()); 1670 1671 // We're potentially copying Expr references here. We don't 1672 // bother retaining them because TypeSourceInfos live forever, so 1673 // as long as the Expr was retained when originally written into 1674 // the TypeLoc, we're okay. 1675 memcpy(Data, Loc.Data, size); 1676 } 1677 1678 SourceRange getLocalSourceRange() const { 1679 if (getTemplateKeywordLoc().isValid()) 1680 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1681 else 1682 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1683 } 1684 1685 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1686 setTemplateKeywordLoc(Loc); 1687 setTemplateNameLoc(Loc); 1688 setLAngleLoc(Loc); 1689 setRAngleLoc(Loc); 1690 initializeArgLocs(Context, getTypePtr()->template_arguments(), 1691 getArgInfos(), Loc); 1692 } 1693 1694 static void initializeArgLocs(ASTContext &Context, 1695 ArrayRef<TemplateArgument> Args, 1696 TemplateArgumentLocInfo *ArgInfos, 1697 SourceLocation Loc); 1698 1699 unsigned getExtraLocalDataSize() const { 1700 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1701 } 1702 1703 unsigned getExtraLocalDataAlignment() const { 1704 return alignof(TemplateArgumentLocInfo); 1705 } 1706 1707 private: 1708 TemplateArgumentLocInfo *getArgInfos() const { 1709 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1710 } 1711 }; 1712 1713 struct DependentAddressSpaceLocInfo { 1714 Expr *ExprOperand; 1715 SourceRange OperandParens; 1716 SourceLocation AttrLoc; 1717 }; 1718 1719 class DependentAddressSpaceTypeLoc 1720 : public ConcreteTypeLoc<UnqualTypeLoc, 1721 DependentAddressSpaceTypeLoc, 1722 DependentAddressSpaceType, 1723 DependentAddressSpaceLocInfo> { 1724 public: 1725 /// The location of the attribute name, i.e. 1726 /// int * __attribute__((address_space(11))) 1727 /// ^~~~~~~~~~~~~ 1728 SourceLocation getAttrNameLoc() const { 1729 return getLocalData()->AttrLoc; 1730 } 1731 void setAttrNameLoc(SourceLocation loc) { 1732 getLocalData()->AttrLoc = loc; 1733 } 1734 1735 /// The attribute's expression operand, if it has one. 1736 /// int * __attribute__((address_space(11))) 1737 /// ^~ 1738 Expr *getAttrExprOperand() const { 1739 return getLocalData()->ExprOperand; 1740 } 1741 void setAttrExprOperand(Expr *e) { 1742 getLocalData()->ExprOperand = e; 1743 } 1744 1745 /// The location of the parentheses around the operand, if there is 1746 /// an operand. 1747 /// int * __attribute__((address_space(11))) 1748 /// ^ ^ 1749 SourceRange getAttrOperandParensRange() const { 1750 return getLocalData()->OperandParens; 1751 } 1752 void setAttrOperandParensRange(SourceRange range) { 1753 getLocalData()->OperandParens = range; 1754 } 1755 1756 SourceRange getLocalSourceRange() const { 1757 SourceRange range(getAttrNameLoc()); 1758 range.setEnd(getAttrOperandParensRange().getEnd()); 1759 return range; 1760 } 1761 1762 /// Returns the type before the address space attribute application 1763 /// area. 1764 /// int * __attribute__((address_space(11))) * 1765 /// ^ ^ 1766 QualType getInnerType() const { 1767 return this->getTypePtr()->getPointeeType(); 1768 } 1769 1770 TypeLoc getPointeeTypeLoc() const { 1771 return this->getInnerTypeLoc(); 1772 } 1773 1774 void initializeLocal(ASTContext &Context, SourceLocation loc) { 1775 setAttrNameLoc(loc); 1776 setAttrOperandParensRange(loc); 1777 setAttrOperandParensRange(SourceRange(loc)); 1778 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr()); 1779 } 1780 }; 1781 1782 //===----------------------------------------------------------------------===// 1783 // 1784 // All of these need proper implementations. 1785 // 1786 //===----------------------------------------------------------------------===// 1787 1788 // FIXME: size expression and attribute locations (or keyword if we 1789 // ever fully support altivec syntax). 1790 struct VectorTypeLocInfo { 1791 SourceLocation NameLoc; 1792 }; 1793 1794 class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc, 1795 VectorType, VectorTypeLocInfo> { 1796 public: 1797 SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } 1798 1799 void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } 1800 1801 SourceRange getLocalSourceRange() const { 1802 return SourceRange(getNameLoc(), getNameLoc()); 1803 } 1804 1805 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1806 setNameLoc(Loc); 1807 } 1808 1809 TypeLoc getElementLoc() const { return getInnerTypeLoc(); } 1810 1811 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 1812 }; 1813 1814 // FIXME: size expression and attribute locations (or keyword if we 1815 // ever fully support altivec syntax). 1816 class DependentVectorTypeLoc 1817 : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc, 1818 DependentVectorType, VectorTypeLocInfo> { 1819 public: 1820 SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } 1821 1822 void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } 1823 1824 SourceRange getLocalSourceRange() const { 1825 return SourceRange(getNameLoc(), getNameLoc()); 1826 } 1827 1828 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1829 setNameLoc(Loc); 1830 } 1831 1832 TypeLoc getElementLoc() const { return getInnerTypeLoc(); } 1833 1834 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 1835 }; 1836 1837 // FIXME: size expression and attribute locations. 1838 class ExtVectorTypeLoc 1839 : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc, 1840 ExtVectorType> {}; 1841 1842 // FIXME: attribute locations. 1843 // For some reason, this isn't a subtype of VectorType. 1844 class DependentSizedExtVectorTypeLoc 1845 : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc, 1846 DependentSizedExtVectorType, VectorTypeLocInfo> { 1847 public: 1848 SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } 1849 1850 void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; } 1851 1852 SourceRange getLocalSourceRange() const { 1853 return SourceRange(getNameLoc(), getNameLoc()); 1854 } 1855 1856 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1857 setNameLoc(Loc); 1858 } 1859 1860 TypeLoc getElementLoc() const { return getInnerTypeLoc(); } 1861 1862 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 1863 }; 1864 1865 struct MatrixTypeLocInfo { 1866 SourceLocation AttrLoc; 1867 SourceRange OperandParens; 1868 Expr *RowOperand; 1869 Expr *ColumnOperand; 1870 }; 1871 1872 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc, 1873 MatrixType, MatrixTypeLocInfo> { 1874 public: 1875 /// The location of the attribute name, i.e. 1876 /// float __attribute__((matrix_type(4, 2))) 1877 /// ^~~~~~~~~~~~~~~~~ 1878 SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; } 1879 void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; } 1880 1881 /// The attribute's row operand, if it has one. 1882 /// float __attribute__((matrix_type(4, 2))) 1883 /// ^ 1884 Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; } 1885 void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; } 1886 1887 /// The attribute's column operand, if it has one. 1888 /// float __attribute__((matrix_type(4, 2))) 1889 /// ^ 1890 Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; } 1891 void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; } 1892 1893 /// The location of the parentheses around the operand, if there is 1894 /// an operand. 1895 /// float __attribute__((matrix_type(4, 2))) 1896 /// ^ ^ 1897 SourceRange getAttrOperandParensRange() const { 1898 return getLocalData()->OperandParens; 1899 } 1900 void setAttrOperandParensRange(SourceRange range) { 1901 getLocalData()->OperandParens = range; 1902 } 1903 1904 SourceRange getLocalSourceRange() const { 1905 SourceRange range(getAttrNameLoc()); 1906 range.setEnd(getAttrOperandParensRange().getEnd()); 1907 return range; 1908 } 1909 1910 void initializeLocal(ASTContext &Context, SourceLocation loc) { 1911 setAttrNameLoc(loc); 1912 setAttrOperandParensRange(loc); 1913 setAttrRowOperand(nullptr); 1914 setAttrColumnOperand(nullptr); 1915 } 1916 }; 1917 1918 class ConstantMatrixTypeLoc 1919 : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc, 1920 ConstantMatrixType> {}; 1921 1922 class DependentSizedMatrixTypeLoc 1923 : public InheritingConcreteTypeLoc<MatrixTypeLoc, 1924 DependentSizedMatrixTypeLoc, 1925 DependentSizedMatrixType> {}; 1926 1927 // FIXME: location of the '_Complex' keyword. 1928 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1929 ComplexTypeLoc, 1930 ComplexType> { 1931 }; 1932 1933 struct TypeofLocInfo { 1934 SourceLocation TypeofLoc; 1935 SourceLocation LParenLoc; 1936 SourceLocation RParenLoc; 1937 }; 1938 1939 struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1940 }; 1941 1942 struct TypeOfTypeLocInfo : public TypeofLocInfo { 1943 TypeSourceInfo *UnmodifiedTInfo; 1944 }; 1945 1946 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1947 class TypeofLikeTypeLoc 1948 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1949 public: 1950 SourceLocation getTypeofLoc() const { 1951 return this->getLocalData()->TypeofLoc; 1952 } 1953 1954 void setTypeofLoc(SourceLocation Loc) { 1955 this->getLocalData()->TypeofLoc = Loc; 1956 } 1957 1958 SourceLocation getLParenLoc() const { 1959 return this->getLocalData()->LParenLoc; 1960 } 1961 1962 void setLParenLoc(SourceLocation Loc) { 1963 this->getLocalData()->LParenLoc = Loc; 1964 } 1965 1966 SourceLocation getRParenLoc() const { 1967 return this->getLocalData()->RParenLoc; 1968 } 1969 1970 void setRParenLoc(SourceLocation Loc) { 1971 this->getLocalData()->RParenLoc = Loc; 1972 } 1973 1974 SourceRange getParensRange() const { 1975 return SourceRange(getLParenLoc(), getRParenLoc()); 1976 } 1977 1978 void setParensRange(SourceRange range) { 1979 setLParenLoc(range.getBegin()); 1980 setRParenLoc(range.getEnd()); 1981 } 1982 1983 SourceRange getLocalSourceRange() const { 1984 return SourceRange(getTypeofLoc(), getRParenLoc()); 1985 } 1986 1987 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1988 setTypeofLoc(Loc); 1989 setLParenLoc(Loc); 1990 setRParenLoc(Loc); 1991 } 1992 }; 1993 1994 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1995 TypeOfExprType, 1996 TypeOfExprTypeLocInfo> { 1997 public: 1998 Expr* getUnderlyingExpr() const { 1999 return getTypePtr()->getUnderlyingExpr(); 2000 } 2001 2002 // Reimplemented to account for GNU/C++ extension 2003 // typeof unary-expression 2004 // where there are no parentheses. 2005 SourceRange getLocalSourceRange() const; 2006 }; 2007 2008 class TypeOfTypeLoc 2009 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 2010 public: 2011 QualType getUnmodifiedType() const { 2012 return this->getTypePtr()->getUnmodifiedType(); 2013 } 2014 2015 TypeSourceInfo *getUnmodifiedTInfo() const { 2016 return this->getLocalData()->UnmodifiedTInfo; 2017 } 2018 2019 void setUnmodifiedTInfo(TypeSourceInfo *TI) const { 2020 this->getLocalData()->UnmodifiedTInfo = TI; 2021 } 2022 2023 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2024 }; 2025 2026 // decltype(expression) abc; 2027 // ~~~~~~~~ DecltypeLoc 2028 // ~ RParenLoc 2029 // FIXME: add LParenLoc, it is tricky to support due to the limitation of 2030 // annotated-decltype token. 2031 struct DecltypeTypeLocInfo { 2032 SourceLocation DecltypeLoc; 2033 SourceLocation RParenLoc; 2034 }; 2035 class DecltypeTypeLoc 2036 : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType, 2037 DecltypeTypeLocInfo> { 2038 public: 2039 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 2040 2041 SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; } 2042 void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; } 2043 2044 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 2045 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 2046 2047 SourceRange getLocalSourceRange() const { 2048 return SourceRange(getDecltypeLoc(), getRParenLoc()); 2049 } 2050 2051 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2052 setDecltypeLoc(Loc); 2053 setRParenLoc(Loc); 2054 } 2055 }; 2056 2057 struct UnaryTransformTypeLocInfo { 2058 // FIXME: While there's only one unary transform right now, future ones may 2059 // need different representations 2060 SourceLocation KWLoc, LParenLoc, RParenLoc; 2061 TypeSourceInfo *UnderlyingTInfo; 2062 }; 2063 2064 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2065 UnaryTransformTypeLoc, 2066 UnaryTransformType, 2067 UnaryTransformTypeLocInfo> { 2068 public: 2069 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 2070 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 2071 2072 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 2073 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 2074 2075 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 2076 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 2077 2078 TypeSourceInfo* getUnderlyingTInfo() const { 2079 return getLocalData()->UnderlyingTInfo; 2080 } 2081 2082 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 2083 getLocalData()->UnderlyingTInfo = TInfo; 2084 } 2085 2086 SourceRange getLocalSourceRange() const { 2087 return SourceRange(getKWLoc(), getRParenLoc()); 2088 } 2089 2090 SourceRange getParensRange() const { 2091 return SourceRange(getLParenLoc(), getRParenLoc()); 2092 } 2093 2094 void setParensRange(SourceRange Range) { 2095 setLParenLoc(Range.getBegin()); 2096 setRParenLoc(Range.getEnd()); 2097 } 2098 2099 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2100 }; 2101 2102 class DeducedTypeLoc 2103 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc, 2104 DeducedType> {}; 2105 2106 struct AutoTypeLocInfo : TypeSpecLocInfo { 2107 NestedNameSpecifierLoc NestedNameSpec; 2108 SourceLocation TemplateKWLoc; 2109 SourceLocation ConceptNameLoc; 2110 NamedDecl *FoundDecl = nullptr; 2111 SourceLocation LAngleLoc; 2112 SourceLocation RAngleLoc; 2113 2114 // For decltype(auto). 2115 SourceLocation RParenLoc; 2116 2117 // Followed by a TemplateArgumentLocInfo[] 2118 }; 2119 2120 class AutoTypeLoc 2121 : public ConcreteTypeLoc<DeducedTypeLoc, 2122 AutoTypeLoc, 2123 AutoType, 2124 AutoTypeLocInfo> { 2125 public: 2126 AutoTypeKeyword getAutoKeyword() const { 2127 return getTypePtr()->getKeyword(); 2128 } 2129 2130 bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); } 2131 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 2132 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 2133 2134 bool isConstrained() const { 2135 return getTypePtr()->isConstrained(); 2136 } 2137 2138 const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { 2139 return getLocalData()->NestedNameSpec; 2140 } 2141 2142 void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 2143 getLocalData()->NestedNameSpec = NNS; 2144 } 2145 2146 SourceLocation getTemplateKWLoc() const { 2147 return getLocalData()->TemplateKWLoc; 2148 } 2149 2150 void setTemplateKWLoc(SourceLocation Loc) { 2151 getLocalData()->TemplateKWLoc = Loc; 2152 } 2153 2154 SourceLocation getConceptNameLoc() const { 2155 return getLocalData()->ConceptNameLoc; 2156 } 2157 2158 void setConceptNameLoc(SourceLocation Loc) { 2159 getLocalData()->ConceptNameLoc = Loc; 2160 } 2161 2162 NamedDecl *getFoundDecl() const { 2163 return getLocalData()->FoundDecl; 2164 } 2165 2166 void setFoundDecl(NamedDecl *D) { 2167 getLocalData()->FoundDecl = D; 2168 } 2169 2170 ConceptDecl *getNamedConcept() const { 2171 return getTypePtr()->getTypeConstraintConcept(); 2172 } 2173 2174 DeclarationNameInfo getConceptNameInfo() const; 2175 2176 bool hasExplicitTemplateArgs() const { 2177 return getLocalData()->LAngleLoc.isValid(); 2178 } 2179 2180 SourceLocation getLAngleLoc() const { 2181 return this->getLocalData()->LAngleLoc; 2182 } 2183 2184 void setLAngleLoc(SourceLocation Loc) { 2185 this->getLocalData()->LAngleLoc = Loc; 2186 } 2187 2188 SourceLocation getRAngleLoc() const { 2189 return this->getLocalData()->RAngleLoc; 2190 } 2191 2192 void setRAngleLoc(SourceLocation Loc) { 2193 this->getLocalData()->RAngleLoc = Loc; 2194 } 2195 2196 unsigned getNumArgs() const { 2197 return getTypePtr()->getTypeConstraintArguments().size(); 2198 } 2199 2200 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2201 getArgInfos()[i] = AI; 2202 } 2203 2204 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2205 return getArgInfos()[i]; 2206 } 2207 2208 TemplateArgumentLoc getArgLoc(unsigned i) const { 2209 return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i], 2210 getArgLocInfo(i)); 2211 } 2212 2213 SourceRange getLocalSourceRange() const { 2214 return {isConstrained() 2215 ? (getNestedNameSpecifierLoc() 2216 ? getNestedNameSpecifierLoc().getBeginLoc() 2217 : (getTemplateKWLoc().isValid() ? getTemplateKWLoc() 2218 : getConceptNameLoc())) 2219 : getNameLoc(), 2220 isDecltypeAuto() ? getRParenLoc() : getNameLoc()}; 2221 } 2222 2223 void copy(AutoTypeLoc Loc) { 2224 unsigned size = getFullDataSize(); 2225 assert(size == Loc.getFullDataSize()); 2226 memcpy(Data, Loc.Data, size); 2227 } 2228 2229 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2230 2231 unsigned getExtraLocalDataSize() const { 2232 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2233 } 2234 2235 unsigned getExtraLocalDataAlignment() const { 2236 return alignof(TemplateArgumentLocInfo); 2237 } 2238 2239 private: 2240 TemplateArgumentLocInfo *getArgInfos() const { 2241 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2242 } 2243 }; 2244 2245 class DeducedTemplateSpecializationTypeLoc 2246 : public InheritingConcreteTypeLoc<DeducedTypeLoc, 2247 DeducedTemplateSpecializationTypeLoc, 2248 DeducedTemplateSpecializationType> { 2249 public: 2250 SourceLocation getTemplateNameLoc() const { 2251 return getNameLoc(); 2252 } 2253 2254 void setTemplateNameLoc(SourceLocation Loc) { 2255 setNameLoc(Loc); 2256 } 2257 }; 2258 2259 struct ElaboratedLocInfo { 2260 SourceLocation ElaboratedKWLoc; 2261 2262 /// Data associated with the nested-name-specifier location. 2263 void *QualifierData; 2264 }; 2265 2266 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2267 ElaboratedTypeLoc, 2268 ElaboratedType, 2269 ElaboratedLocInfo> { 2270 public: 2271 SourceLocation getElaboratedKeywordLoc() const { 2272 return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation(); 2273 } 2274 2275 void setElaboratedKeywordLoc(SourceLocation Loc) { 2276 if (isEmpty()) { 2277 assert(Loc.isInvalid()); 2278 return; 2279 } 2280 getLocalData()->ElaboratedKWLoc = Loc; 2281 } 2282 2283 NestedNameSpecifierLoc getQualifierLoc() const { 2284 return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2285 getLocalData()->QualifierData) 2286 : NestedNameSpecifierLoc(); 2287 } 2288 2289 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2290 assert(QualifierLoc.getNestedNameSpecifier() == 2291 getTypePtr()->getQualifier() && 2292 "Inconsistent nested-name-specifier pointer"); 2293 if (isEmpty()) { 2294 assert(!QualifierLoc.hasQualifier()); 2295 return; 2296 } 2297 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2298 } 2299 2300 SourceRange getLocalSourceRange() const { 2301 if (getElaboratedKeywordLoc().isValid()) 2302 if (getQualifierLoc()) 2303 return SourceRange(getElaboratedKeywordLoc(), 2304 getQualifierLoc().getEndLoc()); 2305 else 2306 return SourceRange(getElaboratedKeywordLoc()); 2307 else 2308 return getQualifierLoc().getSourceRange(); 2309 } 2310 2311 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2312 2313 TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); } 2314 2315 QualType getInnerType() const { return getTypePtr()->getNamedType(); } 2316 2317 bool isEmpty() const { 2318 return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::ETK_None && 2319 !getTypePtr()->getQualifier(); 2320 } 2321 2322 unsigned getLocalDataAlignment() const { 2323 // FIXME: We want to return 1 here in the empty case, but 2324 // there are bugs in how alignment is handled in TypeLocs 2325 // that prevent this from working. 2326 return ConcreteTypeLoc::getLocalDataAlignment(); 2327 } 2328 2329 unsigned getLocalDataSize() const { 2330 return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0; 2331 } 2332 2333 void copy(ElaboratedTypeLoc Loc) { 2334 unsigned size = getFullDataSize(); 2335 assert(size == Loc.getFullDataSize()); 2336 memcpy(Data, Loc.Data, size); 2337 } 2338 }; 2339 2340 // This is exactly the structure of an ElaboratedTypeLoc whose inner 2341 // type is some sort of TypeDeclTypeLoc. 2342 struct DependentNameLocInfo : ElaboratedLocInfo { 2343 SourceLocation NameLoc; 2344 }; 2345 2346 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2347 DependentNameTypeLoc, 2348 DependentNameType, 2349 DependentNameLocInfo> { 2350 public: 2351 SourceLocation getElaboratedKeywordLoc() const { 2352 return this->getLocalData()->ElaboratedKWLoc; 2353 } 2354 2355 void setElaboratedKeywordLoc(SourceLocation Loc) { 2356 this->getLocalData()->ElaboratedKWLoc = Loc; 2357 } 2358 2359 NestedNameSpecifierLoc getQualifierLoc() const { 2360 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2361 getLocalData()->QualifierData); 2362 } 2363 2364 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2365 assert(QualifierLoc.getNestedNameSpecifier() 2366 == getTypePtr()->getQualifier() && 2367 "Inconsistent nested-name-specifier pointer"); 2368 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2369 } 2370 2371 SourceLocation getNameLoc() const { 2372 return this->getLocalData()->NameLoc; 2373 } 2374 2375 void setNameLoc(SourceLocation Loc) { 2376 this->getLocalData()->NameLoc = Loc; 2377 } 2378 2379 SourceRange getLocalSourceRange() const { 2380 if (getElaboratedKeywordLoc().isValid()) 2381 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 2382 else 2383 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 2384 } 2385 2386 void copy(DependentNameTypeLoc Loc) { 2387 unsigned size = getFullDataSize(); 2388 assert(size == Loc.getFullDataSize()); 2389 memcpy(Data, Loc.Data, size); 2390 } 2391 2392 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2393 }; 2394 2395 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 2396 SourceLocation TemplateKWLoc; 2397 SourceLocation LAngleLoc; 2398 SourceLocation RAngleLoc; 2399 // followed by a TemplateArgumentLocInfo[] 2400 }; 2401 2402 class DependentTemplateSpecializationTypeLoc : 2403 public ConcreteTypeLoc<UnqualTypeLoc, 2404 DependentTemplateSpecializationTypeLoc, 2405 DependentTemplateSpecializationType, 2406 DependentTemplateSpecializationLocInfo> { 2407 public: 2408 SourceLocation getElaboratedKeywordLoc() const { 2409 return this->getLocalData()->ElaboratedKWLoc; 2410 } 2411 2412 void setElaboratedKeywordLoc(SourceLocation Loc) { 2413 this->getLocalData()->ElaboratedKWLoc = Loc; 2414 } 2415 2416 NestedNameSpecifierLoc getQualifierLoc() const { 2417 if (!getLocalData()->QualifierData) 2418 return NestedNameSpecifierLoc(); 2419 2420 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2421 getLocalData()->QualifierData); 2422 } 2423 2424 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2425 if (!QualifierLoc) { 2426 // Even if we have a nested-name-specifier in the dependent 2427 // template specialization type, we won't record the nested-name-specifier 2428 // location information when this type-source location information is 2429 // part of a nested-name-specifier. 2430 getLocalData()->QualifierData = nullptr; 2431 return; 2432 } 2433 2434 assert(QualifierLoc.getNestedNameSpecifier() 2435 == getTypePtr()->getQualifier() && 2436 "Inconsistent nested-name-specifier pointer"); 2437 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2438 } 2439 2440 SourceLocation getTemplateKeywordLoc() const { 2441 return getLocalData()->TemplateKWLoc; 2442 } 2443 2444 void setTemplateKeywordLoc(SourceLocation Loc) { 2445 getLocalData()->TemplateKWLoc = Loc; 2446 } 2447 2448 SourceLocation getTemplateNameLoc() const { 2449 return this->getLocalData()->NameLoc; 2450 } 2451 2452 void setTemplateNameLoc(SourceLocation Loc) { 2453 this->getLocalData()->NameLoc = Loc; 2454 } 2455 2456 SourceLocation getLAngleLoc() const { 2457 return this->getLocalData()->LAngleLoc; 2458 } 2459 2460 void setLAngleLoc(SourceLocation Loc) { 2461 this->getLocalData()->LAngleLoc = Loc; 2462 } 2463 2464 SourceLocation getRAngleLoc() const { 2465 return this->getLocalData()->RAngleLoc; 2466 } 2467 2468 void setRAngleLoc(SourceLocation Loc) { 2469 this->getLocalData()->RAngleLoc = Loc; 2470 } 2471 2472 unsigned getNumArgs() const { 2473 return getTypePtr()->template_arguments().size(); 2474 } 2475 2476 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2477 getArgInfos()[i] = AI; 2478 } 2479 2480 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2481 return getArgInfos()[i]; 2482 } 2483 2484 TemplateArgumentLoc getArgLoc(unsigned i) const { 2485 return TemplateArgumentLoc(getTypePtr()->template_arguments()[i], 2486 getArgLocInfo(i)); 2487 } 2488 2489 SourceRange getLocalSourceRange() const { 2490 if (getElaboratedKeywordLoc().isValid()) 2491 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 2492 else if (getQualifierLoc()) 2493 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 2494 else if (getTemplateKeywordLoc().isValid()) 2495 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 2496 else 2497 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 2498 } 2499 2500 void copy(DependentTemplateSpecializationTypeLoc Loc) { 2501 unsigned size = getFullDataSize(); 2502 assert(size == Loc.getFullDataSize()); 2503 memcpy(Data, Loc.Data, size); 2504 } 2505 2506 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2507 2508 unsigned getExtraLocalDataSize() const { 2509 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2510 } 2511 2512 unsigned getExtraLocalDataAlignment() const { 2513 return alignof(TemplateArgumentLocInfo); 2514 } 2515 2516 private: 2517 TemplateArgumentLocInfo *getArgInfos() const { 2518 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2519 } 2520 }; 2521 2522 struct PackExpansionTypeLocInfo { 2523 SourceLocation EllipsisLoc; 2524 }; 2525 2526 class PackExpansionTypeLoc 2527 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 2528 PackExpansionType, PackExpansionTypeLocInfo> { 2529 public: 2530 SourceLocation getEllipsisLoc() const { 2531 return this->getLocalData()->EllipsisLoc; 2532 } 2533 2534 void setEllipsisLoc(SourceLocation Loc) { 2535 this->getLocalData()->EllipsisLoc = Loc; 2536 } 2537 2538 SourceRange getLocalSourceRange() const { 2539 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 2540 } 2541 2542 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2543 setEllipsisLoc(Loc); 2544 } 2545 2546 TypeLoc getPatternLoc() const { 2547 return getInnerTypeLoc(); 2548 } 2549 2550 QualType getInnerType() const { 2551 return this->getTypePtr()->getPattern(); 2552 } 2553 }; 2554 2555 struct AtomicTypeLocInfo { 2556 SourceLocation KWLoc, LParenLoc, RParenLoc; 2557 }; 2558 2559 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 2560 AtomicType, AtomicTypeLocInfo> { 2561 public: 2562 TypeLoc getValueLoc() const { 2563 return this->getInnerTypeLoc(); 2564 } 2565 2566 SourceRange getLocalSourceRange() const { 2567 return SourceRange(getKWLoc(), getRParenLoc()); 2568 } 2569 2570 SourceLocation getKWLoc() const { 2571 return this->getLocalData()->KWLoc; 2572 } 2573 2574 void setKWLoc(SourceLocation Loc) { 2575 this->getLocalData()->KWLoc = Loc; 2576 } 2577 2578 SourceLocation getLParenLoc() const { 2579 return this->getLocalData()->LParenLoc; 2580 } 2581 2582 void setLParenLoc(SourceLocation Loc) { 2583 this->getLocalData()->LParenLoc = Loc; 2584 } 2585 2586 SourceLocation getRParenLoc() const { 2587 return this->getLocalData()->RParenLoc; 2588 } 2589 2590 void setRParenLoc(SourceLocation Loc) { 2591 this->getLocalData()->RParenLoc = Loc; 2592 } 2593 2594 SourceRange getParensRange() const { 2595 return SourceRange(getLParenLoc(), getRParenLoc()); 2596 } 2597 2598 void setParensRange(SourceRange Range) { 2599 setLParenLoc(Range.getBegin()); 2600 setRParenLoc(Range.getEnd()); 2601 } 2602 2603 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2604 setKWLoc(Loc); 2605 setLParenLoc(Loc); 2606 setRParenLoc(Loc); 2607 } 2608 2609 QualType getInnerType() const { 2610 return this->getTypePtr()->getValueType(); 2611 } 2612 }; 2613 2614 struct PipeTypeLocInfo { 2615 SourceLocation KWLoc; 2616 }; 2617 2618 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType, 2619 PipeTypeLocInfo> { 2620 public: 2621 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); } 2622 2623 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); } 2624 2625 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; } 2626 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; } 2627 2628 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2629 setKWLoc(Loc); 2630 } 2631 2632 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 2633 }; 2634 2635 template <typename T> 2636 inline T TypeLoc::getAsAdjusted() const { 2637 TypeLoc Cur = *this; 2638 while (!T::isKind(Cur)) { 2639 if (auto PTL = Cur.getAs<ParenTypeLoc>()) 2640 Cur = PTL.getInnerLoc(); 2641 else if (auto ATL = Cur.getAs<AttributedTypeLoc>()) 2642 Cur = ATL.getModifiedLoc(); 2643 else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>()) 2644 Cur = ATL.getWrappedLoc(); 2645 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>()) 2646 Cur = ETL.getNamedTypeLoc(); 2647 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>()) 2648 Cur = ATL.getOriginalLoc(); 2649 else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>()) 2650 Cur = MQL.getInnerLoc(); 2651 else 2652 break; 2653 } 2654 return Cur.getAs<T>(); 2655 } 2656 class BitIntTypeLoc final 2657 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc, 2658 BitIntType> {}; 2659 class DependentBitIntTypeLoc final 2660 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc, 2661 DependentBitIntType> {}; 2662 2663 class ObjCProtocolLoc { 2664 ObjCProtocolDecl *Protocol = nullptr; 2665 SourceLocation Loc = SourceLocation(); 2666 2667 public: 2668 ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc) 2669 : Protocol(protocol), Loc(loc) {} 2670 ObjCProtocolDecl *getProtocol() const { return Protocol; } 2671 SourceLocation getLocation() const { return Loc; } 2672 2673 /// The source range is just the protocol name. 2674 SourceRange getSourceRange() const LLVM_READONLY { 2675 return SourceRange(Loc, Loc); 2676 } 2677 }; 2678 2679 } // namespace clang 2680 2681 #endif // LLVM_CLANG_AST_TYPELOC_H 2682