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