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