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 33namespace clang { 34 35class Attr; 36class ASTContext; 37class CXXRecordDecl; 38class ConceptDecl; 39class Expr; 40class ObjCInterfaceDecl; 41class ObjCProtocolDecl; 42class ObjCTypeParamDecl; 43class ParmVarDecl; 44class TemplateTypeParmDecl; 45class UnqualTypeLoc; 46class 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. 58class TypeLoc { 59protected: 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 65public: 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 231private: 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. 244inline 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. 251class UnqualTypeLoc : public TypeLoc { 252public: 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 264private: 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. 277class QualifiedTypeLoc : public TypeLoc { 278public: 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 318private: 319 friend class TypeLoc; 320 321 static bool isKind(const TypeLoc &TL) { 322 return TL.getType().hasLocalQualifiers(); 323 } 324}; 325 326inline 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. 360template <class Base, class Derived, class TypeClass, class LocalData> 361class 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 377public: 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 413protected: 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 450private: 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. 485template <class Base, class Derived, class TypeClass> 486class 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 501public: 502 const TypeClass *getTypePtr() const { 503 return cast<TypeClass>(Base::getTypePtr()); 504 } 505}; 506 507struct 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. 513class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 514 TypeSpecTypeLoc, 515 Type, 516 TypeSpecLocInfo> { 517public: 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 539private: 540 friend class TypeLoc; 541 542 static bool isKind(const TypeLoc &TL); 543}; 544 545struct BuiltinLocInfo { 546 SourceRange BuiltinRange; 547}; 548 549/// Wrapper for source info for builtin types. 550class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 551 BuiltinTypeLoc, 552 BuiltinType, 553 BuiltinLocInfo> { 554public: 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. 670class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 671 TypedefTypeLoc, 672 TypedefType> { 673public: 674 TypedefNameDecl *getTypedefNameDecl() const { 675 return getTypePtr()->getDecl(); 676 } 677}; 678 679/// Wrapper for source info for injected class names of class 680/// templates. 681class InjectedClassNameTypeLoc : 682 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 683 InjectedClassNameTypeLoc, 684 InjectedClassNameType> { 685public: 686 CXXRecordDecl *getDecl() const { 687 return getTypePtr()->getDecl(); 688 } 689}; 690 691/// Wrapper for source info for unresolved typename using decls. 692class UnresolvedUsingTypeLoc : 693 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 694 UnresolvedUsingTypeLoc, 695 UnresolvedUsingType> { 696public: 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. 707class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 708 TagTypeLoc, 709 TagType> { 710public: 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. 718class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 719 RecordTypeLoc, 720 RecordType> { 721public: 722 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 723}; 724 725/// Wrapper for source info for enum types. 726class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 727 EnumTypeLoc, 728 EnumType> { 729public: 730 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 731}; 732 733/// Wrapper for template type parameters. 734class TemplateTypeParmTypeLoc : 735 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 736 TemplateTypeParmTypeLoc, 737 TemplateTypeParmType> { 738public: 739 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 740}; 741 742struct ObjCTypeParamTypeLocInfo { 743 SourceLocation NameLoc; 744}; 745 746/// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for 747/// protocol qualifiers are stored after Info. 748class 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 757public: 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. 833class SubstTemplateTypeParmTypeLoc : 834 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 835 SubstTemplateTypeParmTypeLoc, 836 SubstTemplateTypeParmType> { 837}; 838 839 /// Wrapper for substituted template type parameters. 840class SubstTemplateTypeParmPackTypeLoc : 841 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 842 SubstTemplateTypeParmPackTypeLoc, 843 SubstTemplateTypeParmPackType> { 844}; 845 846struct AttributedLocInfo { 847 const Attr *TypeAttr; 848}; 849 850/// Type source information for an attributed type. 851class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 852 AttributedTypeLoc, 853 AttributedType, 854 AttributedLocInfo> { 855public: 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 895struct 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. 908class 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 923public: 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 1034struct ObjCInterfaceLocInfo { 1035 SourceLocation NameLoc; 1036 SourceLocation NameEndLoc; 1037}; 1038 1039/// Wrapper for source info for ObjC interfaces. 1040class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 1041 ObjCInterfaceTypeLoc, 1042 ObjCInterfaceType, 1043 ObjCInterfaceLocInfo> { 1044public: 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 1075struct MacroQualifiedLocInfo { 1076 SourceLocation ExpansionLoc; 1077}; 1078 1079class MacroQualifiedTypeLoc 1080 : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc, 1081 MacroQualifiedType, MacroQualifiedLocInfo> { 1082public: 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 1108struct ParenLocInfo { 1109 SourceLocation LParenLoc; 1110 SourceLocation RParenLoc; 1111}; 1112 1113class ParenTypeLoc 1114 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 1115 ParenLocInfo> { 1116public: 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 1151inline TypeLoc TypeLoc::IgnoreParens() const { 1152 if (ParenTypeLoc::isKind(*this)) 1153 return IgnoreParensImpl(*this); 1154 return *this; 1155} 1156 1157struct AdjustedLocInfo {}; // Nothing. 1158 1159class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc, 1160 AdjustedType, AdjustedLocInfo> { 1161public: 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. 1187class DecayedTypeLoc : public InheritingConcreteTypeLoc< 1188 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> { 1189}; 1190 1191struct PointerLikeLocInfo { 1192 SourceLocation StarLoc; 1193}; 1194 1195/// A base class for 1196template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 1197class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 1198 TypeClass, LocalData> { 1199public: 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. 1226class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 1227 PointerType> { 1228public: 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. 1239class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 1240 BlockPointerType> { 1241public: 1242 SourceLocation getCaretLoc() const { 1243 return getSigilLoc(); 1244 } 1245 1246 void setCaretLoc(SourceLocation Loc) { 1247 setSigilLoc(Loc); 1248 } 1249}; 1250 1251struct MemberPointerLocInfo : public PointerLikeLocInfo { 1252 TypeSourceInfo *ClassTInfo; 1253}; 1254 1255/// Wrapper for source info for member pointers. 1256class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 1257 MemberPointerType, 1258 MemberPointerLocInfo> { 1259public: 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. 1294class ObjCObjectPointerTypeLoc : 1295 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1296 ObjCObjectPointerType> { 1297public: 1298 SourceLocation getStarLoc() const { 1299 return getSigilLoc(); 1300 } 1301 1302 void setStarLoc(SourceLocation Loc) { 1303 setSigilLoc(Loc); 1304 } 1305}; 1306 1307class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1308 ReferenceType> { 1309public: 1310 QualType getInnerType() const { 1311 return getTypePtr()->getPointeeTypeAsWritten(); 1312 } 1313}; 1314 1315class LValueReferenceTypeLoc : 1316 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1317 LValueReferenceTypeLoc, 1318 LValueReferenceType> { 1319public: 1320 SourceLocation getAmpLoc() const { 1321 return getSigilLoc(); 1322 } 1323 1324 void setAmpLoc(SourceLocation Loc) { 1325 setSigilLoc(Loc); 1326 } 1327}; 1328 1329class RValueReferenceTypeLoc : 1330 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1331 RValueReferenceTypeLoc, 1332 RValueReferenceType> { 1333public: 1334 SourceLocation getAmpAmpLoc() const { 1335 return getSigilLoc(); 1336 } 1337 1338 void setAmpAmpLoc(SourceLocation Loc) { 1339 setSigilLoc(Loc); 1340 } 1341}; 1342 1343struct FunctionLocInfo { 1344 SourceLocation LocalRangeBegin; 1345 SourceLocation LParenLoc; 1346 SourceLocation RParenLoc; 1347 SourceLocation LocalRangeEnd; 1348}; 1349 1350/// Wrapper for source info for functions. 1351class 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 1369public: 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 1466class FunctionProtoTypeLoc : 1467 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1468 FunctionProtoTypeLoc, 1469 FunctionProtoType> { 1470}; 1471 1472class FunctionNoProtoTypeLoc : 1473 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1474 FunctionNoProtoTypeLoc, 1475 FunctionNoProtoType> { 1476}; 1477 1478struct ArrayLocInfo { 1479 SourceLocation LBracketLoc, RBracketLoc; 1480 Expr *Size; 1481}; 1482 1483/// Wrapper for source info for arrays. 1484class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1485 ArrayTypeLoc, 1486 ArrayType, 1487 ArrayLocInfo> { 1488public: 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 1534class ConstantArrayTypeLoc : 1535 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1536 ConstantArrayTypeLoc, 1537 ConstantArrayType> { 1538}; 1539 1540class IncompleteArrayTypeLoc : 1541 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1542 IncompleteArrayTypeLoc, 1543 IncompleteArrayType> { 1544}; 1545 1546class DependentSizedArrayTypeLoc : 1547 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1548 DependentSizedArrayTypeLoc, 1549 DependentSizedArrayType> { 1550public: 1551 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1552 ArrayTypeLoc::initializeLocal(Context, Loc); 1553 setSizeExpr(getTypePtr()->getSizeExpr()); 1554 } 1555}; 1556 1557class VariableArrayTypeLoc : 1558 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1559 VariableArrayTypeLoc, 1560 VariableArrayType> { 1561}; 1562 1563// Location information for a TemplateName. Rudimentary for now. 1564struct TemplateNameLocInfo { 1565 SourceLocation NameLoc; 1566}; 1567 1568struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1569 SourceLocation TemplateKWLoc; 1570 SourceLocation LAngleLoc; 1571 SourceLocation RAngleLoc; 1572}; 1573 1574class TemplateSpecializationTypeLoc : 1575 public ConcreteTypeLoc<UnqualTypeLoc, 1576 TemplateSpecializationTypeLoc, 1577 TemplateSpecializationType, 1578 TemplateSpecializationLocInfo> { 1579public: 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 1669private: 1670 TemplateArgumentLocInfo *getArgInfos() const { 1671 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1672 } 1673}; 1674 1675struct DependentAddressSpaceLocInfo { 1676 Expr *ExprOperand; 1677 SourceRange OperandParens; 1678 SourceLocation AttrLoc; 1679}; 1680 1681class DependentAddressSpaceTypeLoc 1682 : public ConcreteTypeLoc<UnqualTypeLoc, 1683 DependentAddressSpaceTypeLoc, 1684 DependentAddressSpaceType, 1685 DependentAddressSpaceLocInfo> { 1686public: 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(SourceRange(loc)); 1739 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr()); 1740 } 1741}; 1742 1743//===----------------------------------------------------------------------===// 1744// 1745// All of these need proper implementations. 1746// 1747//===----------------------------------------------------------------------===// 1748 1749// FIXME: size expression and attribute locations (or keyword if we 1750// ever fully support altivec syntax). 1751class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1752 VectorTypeLoc, 1753 VectorType> { 1754}; 1755 1756// FIXME: size expression and attribute locations (or keyword if we 1757// ever fully support altivec syntax). 1758class DependentVectorTypeLoc 1759 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1760 DependentVectorTypeLoc, 1761 DependentVectorType> {}; 1762 1763// FIXME: size expression and attribute locations. 1764class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1765 ExtVectorTypeLoc, 1766 ExtVectorType> { 1767}; 1768 1769// FIXME: attribute locations. 1770// For some reason, this isn't a subtype of VectorType. 1771class DependentSizedExtVectorTypeLoc : 1772 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1773 DependentSizedExtVectorTypeLoc, 1774 DependentSizedExtVectorType> { 1775}; 1776 1777// FIXME: location of the '_Complex' keyword. 1778class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1779 ComplexTypeLoc, 1780 ComplexType> { 1781}; 1782 1783struct TypeofLocInfo { 1784 SourceLocation TypeofLoc; 1785 SourceLocation LParenLoc; 1786 SourceLocation RParenLoc; 1787}; 1788 1789struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1790}; 1791 1792struct TypeOfTypeLocInfo : public TypeofLocInfo { 1793 TypeSourceInfo* UnderlyingTInfo; 1794}; 1795 1796template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1797class TypeofLikeTypeLoc 1798 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1799public: 1800 SourceLocation getTypeofLoc() const { 1801 return this->getLocalData()->TypeofLoc; 1802 } 1803 1804 void setTypeofLoc(SourceLocation Loc) { 1805 this->getLocalData()->TypeofLoc = Loc; 1806 } 1807 1808 SourceLocation getLParenLoc() const { 1809 return this->getLocalData()->LParenLoc; 1810 } 1811 1812 void setLParenLoc(SourceLocation Loc) { 1813 this->getLocalData()->LParenLoc = Loc; 1814 } 1815 1816 SourceLocation getRParenLoc() const { 1817 return this->getLocalData()->RParenLoc; 1818 } 1819 1820 void setRParenLoc(SourceLocation Loc) { 1821 this->getLocalData()->RParenLoc = Loc; 1822 } 1823 1824 SourceRange getParensRange() const { 1825 return SourceRange(getLParenLoc(), getRParenLoc()); 1826 } 1827 1828 void setParensRange(SourceRange range) { 1829 setLParenLoc(range.getBegin()); 1830 setRParenLoc(range.getEnd()); 1831 } 1832 1833 SourceRange getLocalSourceRange() const { 1834 return SourceRange(getTypeofLoc(), getRParenLoc()); 1835 } 1836 1837 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1838 setTypeofLoc(Loc); 1839 setLParenLoc(Loc); 1840 setRParenLoc(Loc); 1841 } 1842}; 1843 1844class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1845 TypeOfExprType, 1846 TypeOfExprTypeLocInfo> { 1847public: 1848 Expr* getUnderlyingExpr() const { 1849 return getTypePtr()->getUnderlyingExpr(); 1850 } 1851 1852 // Reimplemented to account for GNU/C++ extension 1853 // typeof unary-expression 1854 // where there are no parentheses. 1855 SourceRange getLocalSourceRange() const; 1856}; 1857 1858class TypeOfTypeLoc 1859 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1860public: 1861 QualType getUnderlyingType() const { 1862 return this->getTypePtr()->getUnderlyingType(); 1863 } 1864 1865 TypeSourceInfo* getUnderlyingTInfo() const { 1866 return this->getLocalData()->UnderlyingTInfo; 1867 } 1868 1869 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1870 this->getLocalData()->UnderlyingTInfo = TI; 1871 } 1872 1873 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1874}; 1875 1876// FIXME: location of the 'decltype' and parens. 1877class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1878 DecltypeTypeLoc, 1879 DecltypeType> { 1880public: 1881 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1882}; 1883 1884struct UnaryTransformTypeLocInfo { 1885 // FIXME: While there's only one unary transform right now, future ones may 1886 // need different representations 1887 SourceLocation KWLoc, LParenLoc, RParenLoc; 1888 TypeSourceInfo *UnderlyingTInfo; 1889}; 1890 1891class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1892 UnaryTransformTypeLoc, 1893 UnaryTransformType, 1894 UnaryTransformTypeLocInfo> { 1895public: 1896 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1897 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1898 1899 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1900 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1901 1902 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1903 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1904 1905 TypeSourceInfo* getUnderlyingTInfo() const { 1906 return getLocalData()->UnderlyingTInfo; 1907 } 1908 1909 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1910 getLocalData()->UnderlyingTInfo = TInfo; 1911 } 1912 1913 SourceRange getLocalSourceRange() const { 1914 return SourceRange(getKWLoc(), getRParenLoc()); 1915 } 1916 1917 SourceRange getParensRange() const { 1918 return SourceRange(getLParenLoc(), getRParenLoc()); 1919 } 1920 1921 void setParensRange(SourceRange Range) { 1922 setLParenLoc(Range.getBegin()); 1923 setRParenLoc(Range.getEnd()); 1924 } 1925 1926 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1927}; 1928 1929class DeducedTypeLoc 1930 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc, 1931 DeducedType> {}; 1932 1933struct AutoTypeLocInfo : TypeSpecLocInfo { 1934 NestedNameSpecifierLoc NestedNameSpec; 1935 SourceLocation TemplateKWLoc; 1936 SourceLocation ConceptNameLoc; 1937 NamedDecl *FoundDecl; 1938 SourceLocation LAngleLoc; 1939 SourceLocation RAngleLoc; 1940}; 1941 1942class AutoTypeLoc 1943 : public ConcreteTypeLoc<DeducedTypeLoc, 1944 AutoTypeLoc, 1945 AutoType, 1946 AutoTypeLocInfo> { 1947public: 1948 AutoTypeKeyword getAutoKeyword() const { 1949 return getTypePtr()->getKeyword(); 1950 } 1951 1952 bool isConstrained() const { 1953 return getTypePtr()->isConstrained(); 1954 } 1955 1956 const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { 1957 return getLocalData()->NestedNameSpec; 1958 } 1959 1960 void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 1961 getLocalData()->NestedNameSpec = NNS; 1962 } 1963 1964 SourceLocation getTemplateKWLoc() const { 1965 return getLocalData()->TemplateKWLoc; 1966 } 1967 1968 void setTemplateKWLoc(SourceLocation Loc) { 1969 getLocalData()->TemplateKWLoc = Loc; 1970 } 1971 1972 SourceLocation getConceptNameLoc() const { 1973 return getLocalData()->ConceptNameLoc; 1974 } 1975 1976 void setConceptNameLoc(SourceLocation Loc) { 1977 getLocalData()->ConceptNameLoc = Loc; 1978 } 1979 1980 NamedDecl *getFoundDecl() const { 1981 return getLocalData()->FoundDecl; 1982 } 1983 1984 void setFoundDecl(NamedDecl *D) { 1985 getLocalData()->FoundDecl = D; 1986 } 1987 1988 ConceptDecl *getNamedConcept() const { 1989 return getTypePtr()->getTypeConstraintConcept(); 1990 } 1991 1992 DeclarationNameInfo getConceptNameInfo() const; 1993 1994 bool hasExplicitTemplateArgs() const { 1995 return getLocalData()->LAngleLoc.isValid(); 1996 } 1997 1998 SourceLocation getLAngleLoc() const { 1999 return this->getLocalData()->LAngleLoc; 2000 } 2001 2002 void setLAngleLoc(SourceLocation Loc) { 2003 this->getLocalData()->LAngleLoc = Loc; 2004 } 2005 2006 SourceLocation getRAngleLoc() const { 2007 return this->getLocalData()->RAngleLoc; 2008 } 2009 2010 void setRAngleLoc(SourceLocation Loc) { 2011 this->getLocalData()->RAngleLoc = Loc; 2012 } 2013 2014 unsigned getNumArgs() const { 2015 return getTypePtr()->getNumArgs(); 2016 } 2017 2018 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2019 getArgInfos()[i] = AI; 2020 } 2021 2022 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2023 return getArgInfos()[i]; 2024 } 2025 2026 TemplateArgumentLoc getArgLoc(unsigned i) const { 2027 return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i], 2028 getArgLocInfo(i)); 2029 } 2030 2031 SourceRange getLocalSourceRange() const { 2032 return{ 2033 isConstrained() 2034 ? (getNestedNameSpecifierLoc() 2035 ? getNestedNameSpecifierLoc().getBeginLoc() 2036 : (getTemplateKWLoc().isValid() 2037 ? getTemplateKWLoc() 2038 : getConceptNameLoc())) 2039 : getNameLoc(), 2040 getNameLoc() 2041 }; 2042 } 2043 2044 void copy(AutoTypeLoc Loc) { 2045 unsigned size = getFullDataSize(); 2046 assert(size == Loc.getFullDataSize()); 2047 memcpy(Data, Loc.Data, size); 2048 } 2049 2050 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2051 2052 unsigned getExtraLocalDataSize() const { 2053 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2054 } 2055 2056 unsigned getExtraLocalDataAlignment() const { 2057 return alignof(TemplateArgumentLocInfo); 2058 } 2059 2060private: 2061 TemplateArgumentLocInfo *getArgInfos() const { 2062 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2063 } 2064}; 2065 2066class DeducedTemplateSpecializationTypeLoc 2067 : public InheritingConcreteTypeLoc<DeducedTypeLoc, 2068 DeducedTemplateSpecializationTypeLoc, 2069 DeducedTemplateSpecializationType> { 2070public: 2071 SourceLocation getTemplateNameLoc() const { 2072 return getNameLoc(); 2073 } 2074 2075 void setTemplateNameLoc(SourceLocation Loc) { 2076 setNameLoc(Loc); 2077 } 2078}; 2079 2080struct ElaboratedLocInfo { 2081 SourceLocation ElaboratedKWLoc; 2082 2083 /// Data associated with the nested-name-specifier location. 2084 void *QualifierData; 2085}; 2086 2087class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2088 ElaboratedTypeLoc, 2089 ElaboratedType, 2090 ElaboratedLocInfo> { 2091public: 2092 SourceLocation getElaboratedKeywordLoc() const { 2093 return this->getLocalData()->ElaboratedKWLoc; 2094 } 2095 2096 void setElaboratedKeywordLoc(SourceLocation Loc) { 2097 this->getLocalData()->ElaboratedKWLoc = Loc; 2098 } 2099 2100 NestedNameSpecifierLoc getQualifierLoc() const { 2101 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2102 getLocalData()->QualifierData); 2103 } 2104 2105 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2106 assert(QualifierLoc.getNestedNameSpecifier() 2107 == getTypePtr()->getQualifier() && 2108 "Inconsistent nested-name-specifier pointer"); 2109 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2110 } 2111 2112 SourceRange getLocalSourceRange() const { 2113 if (getElaboratedKeywordLoc().isValid()) 2114 if (getQualifierLoc()) 2115 return SourceRange(getElaboratedKeywordLoc(), 2116 getQualifierLoc().getEndLoc()); 2117 else 2118 return SourceRange(getElaboratedKeywordLoc()); 2119 else 2120 return getQualifierLoc().getSourceRange(); 2121 } 2122 2123 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2124 2125 TypeLoc getNamedTypeLoc() const { 2126 return getInnerTypeLoc(); 2127 } 2128 2129 QualType getInnerType() const { 2130 return getTypePtr()->getNamedType(); 2131 } 2132 2133 void copy(ElaboratedTypeLoc Loc) { 2134 unsigned size = getFullDataSize(); 2135 assert(size == Loc.getFullDataSize()); 2136 memcpy(Data, Loc.Data, size); 2137 } 2138}; 2139 2140// This is exactly the structure of an ElaboratedTypeLoc whose inner 2141// type is some sort of TypeDeclTypeLoc. 2142struct DependentNameLocInfo : ElaboratedLocInfo { 2143 SourceLocation NameLoc; 2144}; 2145 2146class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 2147 DependentNameTypeLoc, 2148 DependentNameType, 2149 DependentNameLocInfo> { 2150public: 2151 SourceLocation getElaboratedKeywordLoc() const { 2152 return this->getLocalData()->ElaboratedKWLoc; 2153 } 2154 2155 void setElaboratedKeywordLoc(SourceLocation Loc) { 2156 this->getLocalData()->ElaboratedKWLoc = Loc; 2157 } 2158 2159 NestedNameSpecifierLoc getQualifierLoc() const { 2160 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2161 getLocalData()->QualifierData); 2162 } 2163 2164 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2165 assert(QualifierLoc.getNestedNameSpecifier() 2166 == getTypePtr()->getQualifier() && 2167 "Inconsistent nested-name-specifier pointer"); 2168 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2169 } 2170 2171 SourceLocation getNameLoc() const { 2172 return this->getLocalData()->NameLoc; 2173 } 2174 2175 void setNameLoc(SourceLocation Loc) { 2176 this->getLocalData()->NameLoc = Loc; 2177 } 2178 2179 SourceRange getLocalSourceRange() const { 2180 if (getElaboratedKeywordLoc().isValid()) 2181 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 2182 else 2183 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 2184 } 2185 2186 void copy(DependentNameTypeLoc Loc) { 2187 unsigned size = getFullDataSize(); 2188 assert(size == Loc.getFullDataSize()); 2189 memcpy(Data, Loc.Data, size); 2190 } 2191 2192 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2193}; 2194 2195struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 2196 SourceLocation TemplateKWLoc; 2197 SourceLocation LAngleLoc; 2198 SourceLocation RAngleLoc; 2199 // followed by a TemplateArgumentLocInfo[] 2200}; 2201 2202class DependentTemplateSpecializationTypeLoc : 2203 public ConcreteTypeLoc<UnqualTypeLoc, 2204 DependentTemplateSpecializationTypeLoc, 2205 DependentTemplateSpecializationType, 2206 DependentTemplateSpecializationLocInfo> { 2207public: 2208 SourceLocation getElaboratedKeywordLoc() const { 2209 return this->getLocalData()->ElaboratedKWLoc; 2210 } 2211 2212 void setElaboratedKeywordLoc(SourceLocation Loc) { 2213 this->getLocalData()->ElaboratedKWLoc = Loc; 2214 } 2215 2216 NestedNameSpecifierLoc getQualifierLoc() const { 2217 if (!getLocalData()->QualifierData) 2218 return NestedNameSpecifierLoc(); 2219 2220 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 2221 getLocalData()->QualifierData); 2222 } 2223 2224 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 2225 if (!QualifierLoc) { 2226 // Even if we have a nested-name-specifier in the dependent 2227 // template specialization type, we won't record the nested-name-specifier 2228 // location information when this type-source location information is 2229 // part of a nested-name-specifier. 2230 getLocalData()->QualifierData = nullptr; 2231 return; 2232 } 2233 2234 assert(QualifierLoc.getNestedNameSpecifier() 2235 == getTypePtr()->getQualifier() && 2236 "Inconsistent nested-name-specifier pointer"); 2237 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 2238 } 2239 2240 SourceLocation getTemplateKeywordLoc() const { 2241 return getLocalData()->TemplateKWLoc; 2242 } 2243 2244 void setTemplateKeywordLoc(SourceLocation Loc) { 2245 getLocalData()->TemplateKWLoc = Loc; 2246 } 2247 2248 SourceLocation getTemplateNameLoc() const { 2249 return this->getLocalData()->NameLoc; 2250 } 2251 2252 void setTemplateNameLoc(SourceLocation Loc) { 2253 this->getLocalData()->NameLoc = Loc; 2254 } 2255 2256 SourceLocation getLAngleLoc() const { 2257 return this->getLocalData()->LAngleLoc; 2258 } 2259 2260 void setLAngleLoc(SourceLocation Loc) { 2261 this->getLocalData()->LAngleLoc = Loc; 2262 } 2263 2264 SourceLocation getRAngleLoc() const { 2265 return this->getLocalData()->RAngleLoc; 2266 } 2267 2268 void setRAngleLoc(SourceLocation Loc) { 2269 this->getLocalData()->RAngleLoc = Loc; 2270 } 2271 2272 unsigned getNumArgs() const { 2273 return getTypePtr()->getNumArgs(); 2274 } 2275 2276 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 2277 getArgInfos()[i] = AI; 2278 } 2279 2280 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 2281 return getArgInfos()[i]; 2282 } 2283 2284 TemplateArgumentLoc getArgLoc(unsigned i) const { 2285 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 2286 } 2287 2288 SourceRange getLocalSourceRange() const { 2289 if (getElaboratedKeywordLoc().isValid()) 2290 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 2291 else if (getQualifierLoc()) 2292 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 2293 else if (getTemplateKeywordLoc().isValid()) 2294 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 2295 else 2296 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 2297 } 2298 2299 void copy(DependentTemplateSpecializationTypeLoc Loc) { 2300 unsigned size = getFullDataSize(); 2301 assert(size == Loc.getFullDataSize()); 2302 memcpy(Data, Loc.Data, size); 2303 } 2304 2305 void initializeLocal(ASTContext &Context, SourceLocation Loc); 2306 2307 unsigned getExtraLocalDataSize() const { 2308 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 2309 } 2310 2311 unsigned getExtraLocalDataAlignment() const { 2312 return alignof(TemplateArgumentLocInfo); 2313 } 2314 2315private: 2316 TemplateArgumentLocInfo *getArgInfos() const { 2317 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 2318 } 2319}; 2320 2321struct PackExpansionTypeLocInfo { 2322 SourceLocation EllipsisLoc; 2323}; 2324 2325class PackExpansionTypeLoc 2326 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 2327 PackExpansionType, PackExpansionTypeLocInfo> { 2328public: 2329 SourceLocation getEllipsisLoc() const { 2330 return this->getLocalData()->EllipsisLoc; 2331 } 2332 2333 void setEllipsisLoc(SourceLocation Loc) { 2334 this->getLocalData()->EllipsisLoc = Loc; 2335 } 2336 2337 SourceRange getLocalSourceRange() const { 2338 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 2339 } 2340 2341 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2342 setEllipsisLoc(Loc); 2343 } 2344 2345 TypeLoc getPatternLoc() const { 2346 return getInnerTypeLoc(); 2347 } 2348 2349 QualType getInnerType() const { 2350 return this->getTypePtr()->getPattern(); 2351 } 2352}; 2353 2354struct AtomicTypeLocInfo { 2355 SourceLocation KWLoc, LParenLoc, RParenLoc; 2356}; 2357 2358class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 2359 AtomicType, AtomicTypeLocInfo> { 2360public: 2361 TypeLoc getValueLoc() const { 2362 return this->getInnerTypeLoc(); 2363 } 2364 2365 SourceRange getLocalSourceRange() const { 2366 return SourceRange(getKWLoc(), getRParenLoc()); 2367 } 2368 2369 SourceLocation getKWLoc() const { 2370 return this->getLocalData()->KWLoc; 2371 } 2372 2373 void setKWLoc(SourceLocation Loc) { 2374 this->getLocalData()->KWLoc = Loc; 2375 } 2376 2377 SourceLocation getLParenLoc() const { 2378 return this->getLocalData()->LParenLoc; 2379 } 2380 2381 void setLParenLoc(SourceLocation Loc) { 2382 this->getLocalData()->LParenLoc = Loc; 2383 } 2384 2385 SourceLocation getRParenLoc() const { 2386 return this->getLocalData()->RParenLoc; 2387 } 2388 2389 void setRParenLoc(SourceLocation Loc) { 2390 this->getLocalData()->RParenLoc = Loc; 2391 } 2392 2393 SourceRange getParensRange() const { 2394 return SourceRange(getLParenLoc(), getRParenLoc()); 2395 } 2396 2397 void setParensRange(SourceRange Range) { 2398 setLParenLoc(Range.getBegin()); 2399 setRParenLoc(Range.getEnd()); 2400 } 2401 2402 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2403 setKWLoc(Loc); 2404 setLParenLoc(Loc); 2405 setRParenLoc(Loc); 2406 } 2407 2408 QualType getInnerType() const { 2409 return this->getTypePtr()->getValueType(); 2410 } 2411}; 2412 2413struct PipeTypeLocInfo { 2414 SourceLocation KWLoc; 2415}; 2416 2417class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType, 2418 PipeTypeLocInfo> { 2419public: 2420 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); } 2421 2422 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); } 2423 2424 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; } 2425 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; } 2426 2427 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2428 setKWLoc(Loc); 2429 } 2430 2431 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 2432}; 2433 2434template <typename T> 2435inline T TypeLoc::getAsAdjusted() const { 2436 TypeLoc Cur = *this; 2437 while (!T::isKind(Cur)) { 2438 if (auto PTL = Cur.getAs<ParenTypeLoc>()) 2439 Cur = PTL.getInnerLoc(); 2440 else if (auto ATL = Cur.getAs<AttributedTypeLoc>()) 2441 Cur = ATL.getModifiedLoc(); 2442 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>()) 2443 Cur = ETL.getNamedTypeLoc(); 2444 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>()) 2445 Cur = ATL.getOriginalLoc(); 2446 else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>()) 2447 Cur = MQL.getInnerLoc(); 2448 else 2449 break; 2450 } 2451 return Cur.getAs<T>(); 2452} 2453 2454} // namespace clang 2455 2456#endif // LLVM_CLANG_AST_TYPELOC_H 2457