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 TSS_unspecified; 607 } 608 609 bool hasWrittenSignSpec() const { 610 return getWrittenSignSpec() != TSS_unspecified; 611 } 612 613 void setWrittenSignSpec(TypeSpecifierSign written) { 614 if (needsExtraLocalData()) 615 getWrittenBuiltinSpecs().Sign = written; 616 } 617 618 TypeSpecifierWidth getWrittenWidthSpec() const { 619 if (needsExtraLocalData()) 620 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 621 else 622 return TSW_unspecified; 623 } 624 625 bool hasWrittenWidthSpec() const { 626 return getWrittenWidthSpec() != TSW_unspecified; 627 } 628 629 void setWrittenWidthSpec(TypeSpecifierWidth written) { 630 if (needsExtraLocalData()) 631 getWrittenBuiltinSpecs().Width = 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 = TSS_unspecified; 662 wbs.Width = TSW_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 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1753 VectorTypeLoc, 1754 VectorType> { 1755 }; 1756 1757 // FIXME: size expression and attribute locations (or keyword if we 1758 // ever fully support altivec syntax). 1759 class DependentVectorTypeLoc 1760 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1761 DependentVectorTypeLoc, 1762 DependentVectorType> {}; 1763 1764 // FIXME: size expression and attribute locations. 1765 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1766 ExtVectorTypeLoc, 1767 ExtVectorType> { 1768 }; 1769 1770 // FIXME: attribute locations. 1771 // For some reason, this isn't a subtype of VectorType. 1772 class DependentSizedExtVectorTypeLoc : 1773 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1774 DependentSizedExtVectorTypeLoc, 1775 DependentSizedExtVectorType> { 1776 }; 1777 1778 struct MatrixTypeLocInfo { 1779 SourceLocation AttrLoc; 1780 SourceRange OperandParens; 1781 Expr *RowOperand; 1782 Expr *ColumnOperand; 1783 }; 1784 1785 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc, 1786 MatrixType, MatrixTypeLocInfo> { 1787 public: 1788 /// The location of the attribute name, i.e. 1789 /// float __attribute__((matrix_type(4, 2))) 1790 /// ^~~~~~~~~~~~~~~~~ 1791 SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; } 1792 void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; } 1793 1794 /// The attribute's row operand, if it has one. 1795 /// float __attribute__((matrix_type(4, 2))) 1796 /// ^ 1797 Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; } 1798 void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; } 1799 1800 /// The attribute's column operand, if it has one. 1801 /// float __attribute__((matrix_type(4, 2))) 1802 /// ^ 1803 Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; } 1804 void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; } 1805 1806 /// The location of the parentheses around the operand, if there is 1807 /// an operand. 1808 /// float __attribute__((matrix_type(4, 2))) 1809 /// ^ ^ 1810 SourceRange getAttrOperandParensRange() const { 1811 return getLocalData()->OperandParens; 1812 } 1813 void setAttrOperandParensRange(SourceRange range) { 1814 getLocalData()->OperandParens = range; 1815 } 1816 1817 SourceRange getLocalSourceRange() const { 1818 SourceRange range(getAttrNameLoc()); 1819 range.setEnd(getAttrOperandParensRange().getEnd()); 1820 return range; 1821 } 1822 1823 void initializeLocal(ASTContext &Context, SourceLocation loc) { 1824 setAttrNameLoc(loc); 1825 setAttrOperandParensRange(loc); 1826 setAttrRowOperand(nullptr); 1827 setAttrColumnOperand(nullptr); 1828 } 1829 }; 1830 1831 class ConstantMatrixTypeLoc 1832 : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc, 1833 ConstantMatrixType> {}; 1834 1835 class DependentSizedMatrixTypeLoc 1836 : public InheritingConcreteTypeLoc<MatrixTypeLoc, 1837 DependentSizedMatrixTypeLoc, 1838 DependentSizedMatrixType> {}; 1839 1840 // FIXME: location of the '_Complex' keyword. 1841 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1842 ComplexTypeLoc, 1843 ComplexType> { 1844 }; 1845 1846 struct TypeofLocInfo { 1847 SourceLocation TypeofLoc; 1848 SourceLocation LParenLoc; 1849 SourceLocation RParenLoc; 1850 }; 1851 1852 struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1853 }; 1854 1855 struct TypeOfTypeLocInfo : public TypeofLocInfo { 1856 TypeSourceInfo* UnderlyingTInfo; 1857 }; 1858 1859 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1860 class TypeofLikeTypeLoc 1861 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1862 public: 1863 SourceLocation getTypeofLoc() const { 1864 return this->getLocalData()->TypeofLoc; 1865 } 1866 1867 void setTypeofLoc(SourceLocation Loc) { 1868 this->getLocalData()->TypeofLoc = Loc; 1869 } 1870 1871 SourceLocation getLParenLoc() const { 1872 return this->getLocalData()->LParenLoc; 1873 } 1874 1875 void setLParenLoc(SourceLocation Loc) { 1876 this->getLocalData()->LParenLoc = Loc; 1877 } 1878 1879 SourceLocation getRParenLoc() const { 1880 return this->getLocalData()->RParenLoc; 1881 } 1882 1883 void setRParenLoc(SourceLocation Loc) { 1884 this->getLocalData()->RParenLoc = Loc; 1885 } 1886 1887 SourceRange getParensRange() const { 1888 return SourceRange(getLParenLoc(), getRParenLoc()); 1889 } 1890 1891 void setParensRange(SourceRange range) { 1892 setLParenLoc(range.getBegin()); 1893 setRParenLoc(range.getEnd()); 1894 } 1895 1896 SourceRange getLocalSourceRange() const { 1897 return SourceRange(getTypeofLoc(), getRParenLoc()); 1898 } 1899 1900 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1901 setTypeofLoc(Loc); 1902 setLParenLoc(Loc); 1903 setRParenLoc(Loc); 1904 } 1905 }; 1906 1907 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1908 TypeOfExprType, 1909 TypeOfExprTypeLocInfo> { 1910 public: 1911 Expr* getUnderlyingExpr() const { 1912 return getTypePtr()->getUnderlyingExpr(); 1913 } 1914 1915 // Reimplemented to account for GNU/C++ extension 1916 // typeof unary-expression 1917 // where there are no parentheses. 1918 SourceRange getLocalSourceRange() const; 1919 }; 1920 1921 class TypeOfTypeLoc 1922 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1923 public: 1924 QualType getUnderlyingType() const { 1925 return this->getTypePtr()->getUnderlyingType(); 1926 } 1927 1928 TypeSourceInfo* getUnderlyingTInfo() const { 1929 return this->getLocalData()->UnderlyingTInfo; 1930 } 1931 1932 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1933 this->getLocalData()->UnderlyingTInfo = TI; 1934 } 1935 1936 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1937 }; 1938 1939 // FIXME: location of the 'decltype' and parens. 1940 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1941 DecltypeTypeLoc, 1942 DecltypeType> { 1943 public: 1944 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1945 }; 1946 1947 struct UnaryTransformTypeLocInfo { 1948 // FIXME: While there's only one unary transform right now, future ones may 1949 // need different representations 1950 SourceLocation KWLoc, LParenLoc, RParenLoc; 1951 TypeSourceInfo *UnderlyingTInfo; 1952 }; 1953 1954 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1955 UnaryTransformTypeLoc, 1956 UnaryTransformType, 1957 UnaryTransformTypeLocInfo> { 1958 public: 1959 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1960 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1961 1962 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1963 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1964 1965 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1966 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1967 1968 TypeSourceInfo* getUnderlyingTInfo() const { 1969 return getLocalData()->UnderlyingTInfo; 1970 } 1971 1972 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1973 getLocalData()->UnderlyingTInfo = TInfo; 1974 } 1975 1976 SourceRange getLocalSourceRange() const { 1977 return SourceRange(getKWLoc(), getRParenLoc()); 1978 } 1979 1980 SourceRange getParensRange() const { 1981 return SourceRange(getLParenLoc(), getRParenLoc()); 1982 } 1983 1984 void setParensRange(SourceRange Range) { 1985 setLParenLoc(Range.getBegin()); 1986 setRParenLoc(Range.getEnd()); 1987 } 1988 1989 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1990 }; 1991 1992 class DeducedTypeLoc 1993 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc, 1994 DeducedType> {}; 1995 1996 struct AutoTypeLocInfo : TypeSpecLocInfo { 1997 NestedNameSpecifierLoc NestedNameSpec; 1998 SourceLocation TemplateKWLoc; 1999 SourceLocation ConceptNameLoc; 2000 NamedDecl *FoundDecl; 2001 SourceLocation LAngleLoc; 2002 SourceLocation RAngleLoc; 2003 }; 2004 2005 class AutoTypeLoc 2006 : public ConcreteTypeLoc<DeducedTypeLoc, 2007 AutoTypeLoc, 2008 AutoType, 2009 AutoTypeLocInfo> { 2010 public: 2011 AutoTypeKeyword getAutoKeyword() const { 2012 return getTypePtr()->getKeyword(); 2013 } 2014 2015 bool isConstrained() const { 2016 return getTypePtr()->isConstrained(); 2017 } 2018 2019 const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { 2020 return getLocalData()->NestedNameSpec; 2021 } 2022 2023 void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 2024 getLocalData()->NestedNameSpec = NNS; 2025 } 2026 2027 SourceLocation getTemplateKWLoc() const { 2028 return getLocalData()->TemplateKWLoc; 2029 } 2030 2031 void setTemplateKWLoc(SourceLocation Loc) { 2032 getLocalData()->TemplateKWLoc = Loc; 2033 } 2034 2035 SourceLocation getConceptNameLoc() const { 2036 return getLocalData()->ConceptNameLoc; 2037 } 2038 2039 void setConceptNameLoc(SourceLocation Loc) { 2040 getLocalData()->ConceptNameLoc = Loc; 2041 } 2042 2043 NamedDecl *getFoundDecl() const { 2044 return getLocalData()->FoundDecl; 2045 } 2046 2047 void setFoundDecl(NamedDecl *D) { 2048 getLocalData()->FoundDecl = D; 2049 } 2050 2051 ConceptDecl *getNamedConcept() const { 2052 return getTypePtr()->getTypeConstraintConcept(); 2053 } 2054 2055 DeclarationNameInfo getConceptNameInfo() const; 2056 2057 bool hasExplicitTemplateArgs() const { 2058 return getLocalData()->LAngleLoc.isValid(); 2059 } 2060 2061 SourceLocation getLAngleLoc() const { 2062 return this->getLocalData()->LAngleLoc; 2063 } 2064 2065 void setLAngleLoc(SourceLocation Loc) { 2066 this->getLocalData()->LAngleLoc = Loc; 2067 } 2068 2069 SourceLocation getRAngleLoc() const { 2070 return this->getLocalData()->RAngleLoc; 2071 } 2072 2073 void setRAngleLoc(SourceLocation Loc) { 2074 this->getLocalData()->RAngleLoc = Loc; 2075 } 2076 2077 unsigned getNumArgs() const { 2078 return getTypePtr()->getNumArgs(); 2079 } 2080 2081 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2082 getArgInfos()[i] = AI; 2083 } 2084 2085 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2086 return getArgInfos()[i]; 2087 } 2088 2089 TemplateArgumentLoc getArgLoc(unsigned i) const { 2090 return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i], 2091 getArgLocInfo(i)); 2092 } 2093 2094 SourceRange getLocalSourceRange() const { 2095 return{ 2096 isConstrained() 2097 ? (getNestedNameSpecifierLoc() 2098 ? getNestedNameSpecifierLoc().getBeginLoc() 2099 : (getTemplateKWLoc().isValid() 2100 ? getTemplateKWLoc() 2101 : getConceptNameLoc())) 2102 : getNameLoc(), 2103 getNameLoc() 2104 }; 2105 } 2106 2107 void copy(AutoTypeLoc Loc) { 2108 unsigned size = getFullDataSize(); 2109 assert(size == Loc.getFullDataSize()); 2110 memcpy(Data, Loc.Data, size); 2111 } 2112 2113 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2114 2115 unsigned getExtraLocalDataSize() const { 2116 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2117 } 2118 2119 unsigned getExtraLocalDataAlignment() const { 2120 return alignof(TemplateArgumentLocInfo); 2121 } 2122 2123 private: 2124 TemplateArgumentLocInfo *getArgInfos() const { 2125 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2126 } 2127 }; 2128 2129 class DeducedTemplateSpecializationTypeLoc 2130 : public InheritingConcreteTypeLoc<DeducedTypeLoc, 2131 DeducedTemplateSpecializationTypeLoc, 2132 DeducedTemplateSpecializationType> { 2133 public: 2134 SourceLocation getTemplateNameLoc() const { 2135 return getNameLoc(); 2136 } 2137 2138 void setTemplateNameLoc(SourceLocation Loc) { 2139 setNameLoc(Loc); 2140 } 2141 }; 2142 2143 struct ElaboratedLocInfo { 2144 SourceLocation ElaboratedKWLoc; 2145 2146 /// Data associated with the nested-name-specifier location. 2147 void *QualifierData; 2148 }; 2149 2150 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2151 ElaboratedTypeLoc, 2152 ElaboratedType, 2153 ElaboratedLocInfo> { 2154 public: 2155 SourceLocation getElaboratedKeywordLoc() const { 2156 return this->getLocalData()->ElaboratedKWLoc; 2157 } 2158 2159 void setElaboratedKeywordLoc(SourceLocation Loc) { 2160 this->getLocalData()->ElaboratedKWLoc = Loc; 2161 } 2162 2163 NestedNameSpecifierLoc getQualifierLoc() const { 2164 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2165 getLocalData()->QualifierData); 2166 } 2167 2168 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2169 assert(QualifierLoc.getNestedNameSpecifier() 2170 == getTypePtr()->getQualifier() && 2171 "Inconsistent nested-name-specifier pointer"); 2172 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2173 } 2174 2175 SourceRange getLocalSourceRange() const { 2176 if (getElaboratedKeywordLoc().isValid()) 2177 if (getQualifierLoc()) 2178 return SourceRange(getElaboratedKeywordLoc(), 2179 getQualifierLoc().getEndLoc()); 2180 else 2181 return SourceRange(getElaboratedKeywordLoc()); 2182 else 2183 return getQualifierLoc().getSourceRange(); 2184 } 2185 2186 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2187 2188 TypeLoc getNamedTypeLoc() const { 2189 return getInnerTypeLoc(); 2190 } 2191 2192 QualType getInnerType() const { 2193 return getTypePtr()->getNamedType(); 2194 } 2195 2196 void copy(ElaboratedTypeLoc Loc) { 2197 unsigned size = getFullDataSize(); 2198 assert(size == Loc.getFullDataSize()); 2199 memcpy(Data, Loc.Data, size); 2200 } 2201 }; 2202 2203 // This is exactly the structure of an ElaboratedTypeLoc whose inner 2204 // type is some sort of TypeDeclTypeLoc. 2205 struct DependentNameLocInfo : ElaboratedLocInfo { 2206 SourceLocation NameLoc; 2207 }; 2208 2209 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2210 DependentNameTypeLoc, 2211 DependentNameType, 2212 DependentNameLocInfo> { 2213 public: 2214 SourceLocation getElaboratedKeywordLoc() const { 2215 return this->getLocalData()->ElaboratedKWLoc; 2216 } 2217 2218 void setElaboratedKeywordLoc(SourceLocation Loc) { 2219 this->getLocalData()->ElaboratedKWLoc = Loc; 2220 } 2221 2222 NestedNameSpecifierLoc getQualifierLoc() const { 2223 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2224 getLocalData()->QualifierData); 2225 } 2226 2227 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2228 assert(QualifierLoc.getNestedNameSpecifier() 2229 == getTypePtr()->getQualifier() && 2230 "Inconsistent nested-name-specifier pointer"); 2231 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2232 } 2233 2234 SourceLocation getNameLoc() const { 2235 return this->getLocalData()->NameLoc; 2236 } 2237 2238 void setNameLoc(SourceLocation Loc) { 2239 this->getLocalData()->NameLoc = Loc; 2240 } 2241 2242 SourceRange getLocalSourceRange() const { 2243 if (getElaboratedKeywordLoc().isValid()) 2244 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 2245 else 2246 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 2247 } 2248 2249 void copy(DependentNameTypeLoc Loc) { 2250 unsigned size = getFullDataSize(); 2251 assert(size == Loc.getFullDataSize()); 2252 memcpy(Data, Loc.Data, size); 2253 } 2254 2255 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2256 }; 2257 2258 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 2259 SourceLocation TemplateKWLoc; 2260 SourceLocation LAngleLoc; 2261 SourceLocation RAngleLoc; 2262 // followed by a TemplateArgumentLocInfo[] 2263 }; 2264 2265 class DependentTemplateSpecializationTypeLoc : 2266 public ConcreteTypeLoc<UnqualTypeLoc, 2267 DependentTemplateSpecializationTypeLoc, 2268 DependentTemplateSpecializationType, 2269 DependentTemplateSpecializationLocInfo> { 2270 public: 2271 SourceLocation getElaboratedKeywordLoc() const { 2272 return this->getLocalData()->ElaboratedKWLoc; 2273 } 2274 2275 void setElaboratedKeywordLoc(SourceLocation Loc) { 2276 this->getLocalData()->ElaboratedKWLoc = Loc; 2277 } 2278 2279 NestedNameSpecifierLoc getQualifierLoc() const { 2280 if (!getLocalData()->QualifierData) 2281 return NestedNameSpecifierLoc(); 2282 2283 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2284 getLocalData()->QualifierData); 2285 } 2286 2287 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2288 if (!QualifierLoc) { 2289 // Even if we have a nested-name-specifier in the dependent 2290 // template specialization type, we won't record the nested-name-specifier 2291 // location information when this type-source location information is 2292 // part of a nested-name-specifier. 2293 getLocalData()->QualifierData = nullptr; 2294 return; 2295 } 2296 2297 assert(QualifierLoc.getNestedNameSpecifier() 2298 == getTypePtr()->getQualifier() && 2299 "Inconsistent nested-name-specifier pointer"); 2300 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2301 } 2302 2303 SourceLocation getTemplateKeywordLoc() const { 2304 return getLocalData()->TemplateKWLoc; 2305 } 2306 2307 void setTemplateKeywordLoc(SourceLocation Loc) { 2308 getLocalData()->TemplateKWLoc = Loc; 2309 } 2310 2311 SourceLocation getTemplateNameLoc() const { 2312 return this->getLocalData()->NameLoc; 2313 } 2314 2315 void setTemplateNameLoc(SourceLocation Loc) { 2316 this->getLocalData()->NameLoc = Loc; 2317 } 2318 2319 SourceLocation getLAngleLoc() const { 2320 return this->getLocalData()->LAngleLoc; 2321 } 2322 2323 void setLAngleLoc(SourceLocation Loc) { 2324 this->getLocalData()->LAngleLoc = Loc; 2325 } 2326 2327 SourceLocation getRAngleLoc() const { 2328 return this->getLocalData()->RAngleLoc; 2329 } 2330 2331 void setRAngleLoc(SourceLocation Loc) { 2332 this->getLocalData()->RAngleLoc = Loc; 2333 } 2334 2335 unsigned getNumArgs() const { 2336 return getTypePtr()->getNumArgs(); 2337 } 2338 2339 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2340 getArgInfos()[i] = AI; 2341 } 2342 2343 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2344 return getArgInfos()[i]; 2345 } 2346 2347 TemplateArgumentLoc getArgLoc(unsigned i) const { 2348 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 2349 } 2350 2351 SourceRange getLocalSourceRange() const { 2352 if (getElaboratedKeywordLoc().isValid()) 2353 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 2354 else if (getQualifierLoc()) 2355 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 2356 else if (getTemplateKeywordLoc().isValid()) 2357 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 2358 else 2359 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 2360 } 2361 2362 void copy(DependentTemplateSpecializationTypeLoc Loc) { 2363 unsigned size = getFullDataSize(); 2364 assert(size == Loc.getFullDataSize()); 2365 memcpy(Data, Loc.Data, size); 2366 } 2367 2368 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2369 2370 unsigned getExtraLocalDataSize() const { 2371 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2372 } 2373 2374 unsigned getExtraLocalDataAlignment() const { 2375 return alignof(TemplateArgumentLocInfo); 2376 } 2377 2378 private: 2379 TemplateArgumentLocInfo *getArgInfos() const { 2380 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2381 } 2382 }; 2383 2384 struct PackExpansionTypeLocInfo { 2385 SourceLocation EllipsisLoc; 2386 }; 2387 2388 class PackExpansionTypeLoc 2389 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 2390 PackExpansionType, PackExpansionTypeLocInfo> { 2391 public: 2392 SourceLocation getEllipsisLoc() const { 2393 return this->getLocalData()->EllipsisLoc; 2394 } 2395 2396 void setEllipsisLoc(SourceLocation Loc) { 2397 this->getLocalData()->EllipsisLoc = Loc; 2398 } 2399 2400 SourceRange getLocalSourceRange() const { 2401 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 2402 } 2403 2404 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2405 setEllipsisLoc(Loc); 2406 } 2407 2408 TypeLoc getPatternLoc() const { 2409 return getInnerTypeLoc(); 2410 } 2411 2412 QualType getInnerType() const { 2413 return this->getTypePtr()->getPattern(); 2414 } 2415 }; 2416 2417 struct AtomicTypeLocInfo { 2418 SourceLocation KWLoc, LParenLoc, RParenLoc; 2419 }; 2420 2421 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 2422 AtomicType, AtomicTypeLocInfo> { 2423 public: 2424 TypeLoc getValueLoc() const { 2425 return this->getInnerTypeLoc(); 2426 } 2427 2428 SourceRange getLocalSourceRange() const { 2429 return SourceRange(getKWLoc(), getRParenLoc()); 2430 } 2431 2432 SourceLocation getKWLoc() const { 2433 return this->getLocalData()->KWLoc; 2434 } 2435 2436 void setKWLoc(SourceLocation Loc) { 2437 this->getLocalData()->KWLoc = Loc; 2438 } 2439 2440 SourceLocation getLParenLoc() const { 2441 return this->getLocalData()->LParenLoc; 2442 } 2443 2444 void setLParenLoc(SourceLocation Loc) { 2445 this->getLocalData()->LParenLoc = Loc; 2446 } 2447 2448 SourceLocation getRParenLoc() const { 2449 return this->getLocalData()->RParenLoc; 2450 } 2451 2452 void setRParenLoc(SourceLocation Loc) { 2453 this->getLocalData()->RParenLoc = Loc; 2454 } 2455 2456 SourceRange getParensRange() const { 2457 return SourceRange(getLParenLoc(), getRParenLoc()); 2458 } 2459 2460 void setParensRange(SourceRange Range) { 2461 setLParenLoc(Range.getBegin()); 2462 setRParenLoc(Range.getEnd()); 2463 } 2464 2465 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2466 setKWLoc(Loc); 2467 setLParenLoc(Loc); 2468 setRParenLoc(Loc); 2469 } 2470 2471 QualType getInnerType() const { 2472 return this->getTypePtr()->getValueType(); 2473 } 2474 }; 2475 2476 struct PipeTypeLocInfo { 2477 SourceLocation KWLoc; 2478 }; 2479 2480 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType, 2481 PipeTypeLocInfo> { 2482 public: 2483 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); } 2484 2485 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); } 2486 2487 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; } 2488 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; } 2489 2490 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2491 setKWLoc(Loc); 2492 } 2493 2494 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 2495 }; 2496 2497 template <typename T> 2498 inline T TypeLoc::getAsAdjusted() const { 2499 TypeLoc Cur = *this; 2500 while (!T::isKind(Cur)) { 2501 if (auto PTL = Cur.getAs<ParenTypeLoc>()) 2502 Cur = PTL.getInnerLoc(); 2503 else if (auto ATL = Cur.getAs<AttributedTypeLoc>()) 2504 Cur = ATL.getModifiedLoc(); 2505 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>()) 2506 Cur = ETL.getNamedTypeLoc(); 2507 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>()) 2508 Cur = ATL.getOriginalLoc(); 2509 else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>()) 2510 Cur = MQL.getInnerLoc(); 2511 else 2512 break; 2513 } 2514 return Cur.getAs<T>(); 2515 } 2516 class ExtIntTypeLoc final 2517 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc, 2518 ExtIntType> {}; 2519 class DependentExtIntTypeLoc final 2520 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc, 2521 DependentExtIntType> {}; 2522 2523 } // namespace clang 2524 2525 #endif // LLVM_CLANG_AST_TYPELOC_H 2526