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