1 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Defines the clang::TypeLoc interface and its subclasses. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_AST_TYPELOC_H 16 #define LLVM_CLANG_AST_TYPELOC_H 17 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/TemplateBase.h" 20 #include "clang/AST/Type.h" 21 #include "clang/Basic/Specifiers.h" 22 #include "llvm/Support/Compiler.h" 23 24 namespace clang { 25 class ASTContext; 26 class ParmVarDecl; 27 class TypeSourceInfo; 28 class UnqualTypeLoc; 29 30 // Predeclare all the type nodes. 31 #define ABSTRACT_TYPELOC(Class, Base) 32 #define TYPELOC(Class, Base) \ 33 class Class##TypeLoc; 34 #include "clang/AST/TypeLocNodes.def" 35 36 /// \brief Base wrapper for a particular "section" of type source info. 37 /// 38 /// A client should use the TypeLoc subclasses through castAs()/getAs() 39 /// in order to get at the actual information. 40 class TypeLoc { 41 protected: 42 // The correctness of this relies on the property that, for Type *Ty, 43 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 44 const void *Ty; 45 void *Data; 46 47 public: 48 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc 49 /// is of the desired type. 50 /// 51 /// \pre T::isKind(*this) 52 template<typename T> 53 T castAs() const { 54 assert(T::isKind(*this)); 55 T t; 56 TypeLoc& tl = t; 57 tl = *this; 58 return t; 59 } 60 61 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if 62 /// this TypeLoc is not of the desired type. 63 template<typename T> 64 T getAs() const { 65 if (!T::isKind(*this)) 66 return T(); 67 T t; 68 TypeLoc& tl = t; 69 tl = *this; 70 return t; 71 } 72 73 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 74 /// except it also defines a Qualified enum that corresponds to the 75 /// QualifiedLoc class. 76 enum TypeLocClass { 77 #define ABSTRACT_TYPE(Class, Base) 78 #define TYPE(Class, Base) \ 79 Class = Type::Class, 80 #include "clang/AST/TypeNodes.def" 81 Qualified 82 }; 83 84 TypeLoc() : Ty(nullptr), Data(nullptr) { } 85 TypeLoc(QualType ty, void *opaqueData) 86 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { } 87 TypeLoc(const Type *ty, void *opaqueData) 88 : Ty(ty), Data(opaqueData) { } 89 90 TypeLocClass getTypeLocClass() const { 91 if (getType().hasLocalQualifiers()) return Qualified; 92 return (TypeLocClass) getType()->getTypeClass(); 93 } 94 95 bool isNull() const { return !Ty; } 96 explicit operator bool() const { return Ty; } 97 98 /// \brief Returns the size of type source info data block for the given type. 99 static unsigned getFullDataSizeForType(QualType Ty); 100 101 /// \brief Returns the alignment of type source info data block for 102 /// the given type. 103 static unsigned getLocalAlignmentForType(QualType Ty); 104 105 /// \brief Get the type for which this source info wrapper provides 106 /// information. 107 QualType getType() const { 108 return QualType::getFromOpaquePtr(Ty); 109 } 110 111 const Type *getTypePtr() const { 112 return QualType::getFromOpaquePtr(Ty).getTypePtr(); 113 } 114 115 /// \brief Get the pointer where source information is stored. 116 void *getOpaqueData() const { 117 return Data; 118 } 119 120 /// \brief Get the begin source location. 121 SourceLocation getBeginLoc() const; 122 123 /// \brief Get the end source location. 124 SourceLocation getEndLoc() const; 125 126 /// \brief Get the full source range. 127 SourceRange getSourceRange() const LLVM_READONLY { 128 return SourceRange(getBeginLoc(), getEndLoc()); 129 } 130 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } 131 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 132 133 /// \brief Get the local source range. 134 SourceRange getLocalSourceRange() const { 135 return getLocalSourceRangeImpl(*this); 136 } 137 138 /// \brief Returns the size of the type source info data block. 139 unsigned getFullDataSize() const { 140 return getFullDataSizeForType(getType()); 141 } 142 143 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 144 /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 145 TypeLoc getNextTypeLoc() const { 146 return getNextTypeLocImpl(*this); 147 } 148 149 /// \brief Skips past any qualifiers, if this is qualified. 150 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 151 152 TypeLoc IgnoreParens() const; 153 154 /// \brief Find a type with the location of an explicit type qualifier. 155 /// 156 /// The result, if non-null, will be one of: 157 /// QualifiedTypeLoc 158 /// AtomicTypeLoc 159 /// AttributedTypeLoc, for those type attributes that behave as qualifiers 160 TypeLoc findExplicitQualifierLoc() const; 161 162 /// \brief Initializes this to state that every location in this 163 /// type is the given location. 164 /// 165 /// This method exists to provide a simple transition for code that 166 /// relies on location-less types. 167 void initialize(ASTContext &Context, SourceLocation Loc) const { 168 initializeImpl(Context, *this, Loc); 169 } 170 171 /// \brief Initializes this by copying its information from another 172 /// TypeLoc of the same type. 173 void initializeFullCopy(TypeLoc Other) { 174 assert(getType() == Other.getType()); 175 copy(Other); 176 } 177 178 /// \brief Initializes this by copying its information from another 179 /// TypeLoc of the same type. The given size must be the full data 180 /// size. 181 void initializeFullCopy(TypeLoc Other, unsigned Size) { 182 assert(getType() == Other.getType()); 183 assert(getFullDataSize() == Size); 184 copy(Other); 185 } 186 187 /// Copies the other type loc into this one. 188 void copy(TypeLoc other); 189 190 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 191 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 192 } 193 194 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 195 return !(LHS == RHS); 196 } 197 198 /// Find the location of the nullability specifier (__nonnull, 199 /// __nullable, or __null_unspecifier), if there is one. 200 SourceLocation findNullabilityLoc() const; 201 202 private: 203 static bool isKind(const TypeLoc&) { 204 return true; 205 } 206 207 static void initializeImpl(ASTContext &Context, TypeLoc TL, 208 SourceLocation Loc); 209 static TypeLoc getNextTypeLocImpl(TypeLoc TL); 210 static TypeLoc IgnoreParensImpl(TypeLoc TL); 211 static SourceRange getLocalSourceRangeImpl(TypeLoc TL); 212 }; 213 214 /// \brief Return the TypeLoc for a type source info. 215 inline TypeLoc TypeSourceInfo::getTypeLoc() const { 216 // TODO: is this alignment already sufficient? 217 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); 218 } 219 220 /// \brief Wrapper of type source information for a type with 221 /// no direct qualifiers. 222 class UnqualTypeLoc : public TypeLoc { 223 public: 224 UnqualTypeLoc() {} 225 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 226 227 const Type *getTypePtr() const { 228 return reinterpret_cast<const Type*>(Ty); 229 } 230 231 TypeLocClass getTypeLocClass() const { 232 return (TypeLocClass) getTypePtr()->getTypeClass(); 233 } 234 235 private: 236 friend class TypeLoc; 237 static bool isKind(const TypeLoc &TL) { 238 return !TL.getType().hasLocalQualifiers(); 239 } 240 }; 241 242 /// \brief Wrapper of type source information for a type with 243 /// non-trivial direct qualifiers. 244 /// 245 /// Currently, we intentionally do not provide source location for 246 /// type qualifiers. 247 class QualifiedTypeLoc : public TypeLoc { 248 public: 249 SourceRange getLocalSourceRange() const { 250 return SourceRange(); 251 } 252 253 UnqualTypeLoc getUnqualifiedLoc() const { 254 unsigned align = 255 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); 256 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data); 257 dataInt = llvm::alignTo(dataInt, align); 258 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt)); 259 } 260 261 /// Initializes the local data of this type source info block to 262 /// provide no information. 263 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 264 // do nothing 265 } 266 267 void copyLocal(TypeLoc other) { 268 // do nothing 269 } 270 271 TypeLoc getNextTypeLoc() const { 272 return getUnqualifiedLoc(); 273 } 274 275 /// \brief Returns the size of the type source info data block that is 276 /// specific to this type. 277 unsigned getLocalDataSize() const { 278 // In fact, we don't currently preserve any location information 279 // for qualifiers. 280 return 0; 281 } 282 283 /// \brief Returns the alignment of the type source info data block that is 284 /// specific to this type. 285 unsigned getLocalDataAlignment() const { 286 // We don't preserve any location information. 287 return 1; 288 } 289 290 private: 291 friend class TypeLoc; 292 static bool isKind(const TypeLoc &TL) { 293 return TL.getType().hasLocalQualifiers(); 294 } 295 }; 296 297 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 298 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) 299 return Loc.getUnqualifiedLoc(); 300 return castAs<UnqualTypeLoc>(); 301 } 302 303 /// A metaprogramming base class for TypeLoc classes which correspond 304 /// to a particular Type subclass. It is accepted for a single 305 /// TypeLoc class to correspond to multiple Type classes. 306 /// 307 /// \tparam Base a class from which to derive 308 /// \tparam Derived the class deriving from this one 309 /// \tparam TypeClass the concrete Type subclass associated with this 310 /// location type 311 /// \tparam LocalData the structure type of local location data for 312 /// this type 313 /// 314 /// TypeLocs with non-constant amounts of local data should override 315 /// getExtraLocalDataSize(); getExtraLocalData() will then point to 316 /// this extra memory. 317 /// 318 /// TypeLocs with an inner type should define 319 /// QualType getInnerType() const 320 /// and getInnerTypeLoc() will then point to this inner type's 321 /// location data. 322 /// 323 /// A word about hierarchies: this template is not designed to be 324 /// derived from multiple times in a hierarchy. It is also not 325 /// designed to be used for classes where subtypes might provide 326 /// different amounts of source information. It should be subclassed 327 /// only at the deepest portion of the hierarchy where all children 328 /// have identical source information; if that's an abstract type, 329 /// then further descendents should inherit from 330 /// InheritingConcreteTypeLoc instead. 331 template <class Base, class Derived, class TypeClass, class LocalData> 332 class ConcreteTypeLoc : public Base { 333 334 const Derived *asDerived() const { 335 return static_cast<const Derived*>(this); 336 } 337 338 friend class TypeLoc; 339 static bool isKind(const TypeLoc &TL) { 340 return !TL.getType().hasLocalQualifiers() && 341 Derived::classofType(TL.getTypePtr()); 342 } 343 344 static bool classofType(const Type *Ty) { 345 return TypeClass::classof(Ty); 346 } 347 348 public: 349 unsigned getLocalDataAlignment() const { 350 return std::max(llvm::alignOf<LocalData>(), 351 asDerived()->getExtraLocalDataAlignment()); 352 } 353 unsigned getLocalDataSize() const { 354 unsigned size = sizeof(LocalData); 355 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 356 size = llvm::alignTo(size, extraAlign); 357 size += asDerived()->getExtraLocalDataSize(); 358 return size; 359 } 360 361 void copyLocal(Derived other) { 362 // Some subclasses have no data to copy. 363 if (asDerived()->getLocalDataSize() == 0) return; 364 365 // Copy the fixed-sized local data. 366 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData)); 367 368 // Copy the variable-sized local data. We need to do this 369 // separately because the padding in the source and the padding in 370 // the destination might be different. 371 memcpy(getExtraLocalData(), other.getExtraLocalData(), 372 asDerived()->getExtraLocalDataSize()); 373 } 374 375 TypeLoc getNextTypeLoc() const { 376 return getNextTypeLoc(asDerived()->getInnerType()); 377 } 378 379 const TypeClass *getTypePtr() const { 380 return cast<TypeClass>(Base::getTypePtr()); 381 } 382 383 protected: 384 unsigned getExtraLocalDataSize() const { 385 return 0; 386 } 387 388 unsigned getExtraLocalDataAlignment() const { 389 return 1; 390 } 391 392 LocalData *getLocalData() const { 393 return static_cast<LocalData*>(Base::Data); 394 } 395 396 /// Gets a pointer past the Info structure; useful for classes with 397 /// local data that can't be captured in the Info (e.g. because it's 398 /// of variable size). 399 void *getExtraLocalData() const { 400 unsigned size = sizeof(LocalData); 401 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 402 size = llvm::alignTo(size, extraAlign); 403 return reinterpret_cast<char*>(Base::Data) + size; 404 } 405 406 void *getNonLocalData() const { 407 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data); 408 data += asDerived()->getLocalDataSize(); 409 data = llvm::alignTo(data, getNextTypeAlign()); 410 return reinterpret_cast<void*>(data); 411 } 412 413 struct HasNoInnerType {}; 414 HasNoInnerType getInnerType() const { return HasNoInnerType(); } 415 416 TypeLoc getInnerTypeLoc() const { 417 return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 418 } 419 420 private: 421 unsigned getInnerTypeSize() const { 422 return getInnerTypeSize(asDerived()->getInnerType()); 423 } 424 425 unsigned getInnerTypeSize(HasNoInnerType _) const { 426 return 0; 427 } 428 429 unsigned getInnerTypeSize(QualType _) const { 430 return getInnerTypeLoc().getFullDataSize(); 431 } 432 433 unsigned getNextTypeAlign() const { 434 return getNextTypeAlign(asDerived()->getInnerType()); 435 } 436 437 unsigned getNextTypeAlign(HasNoInnerType _) const { 438 return 1; 439 } 440 441 unsigned getNextTypeAlign(QualType T) const { 442 return TypeLoc::getLocalAlignmentForType(T); 443 } 444 445 TypeLoc getNextTypeLoc(HasNoInnerType _) const { 446 return TypeLoc(); 447 } 448 449 TypeLoc getNextTypeLoc(QualType T) const { 450 return TypeLoc(T, getNonLocalData()); 451 } 452 }; 453 454 /// A metaprogramming class designed for concrete subtypes of abstract 455 /// types where all subtypes share equivalently-structured source 456 /// information. See the note on ConcreteTypeLoc. 457 template <class Base, class Derived, class TypeClass> 458 class InheritingConcreteTypeLoc : public Base { 459 friend class TypeLoc; 460 static bool classofType(const Type *Ty) { 461 return TypeClass::classof(Ty); 462 } 463 464 static bool isKind(const TypeLoc &TL) { 465 return !TL.getType().hasLocalQualifiers() && 466 Derived::classofType(TL.getTypePtr()); 467 } 468 static bool isKind(const UnqualTypeLoc &TL) { 469 return Derived::classofType(TL.getTypePtr()); 470 } 471 472 public: 473 const TypeClass *getTypePtr() const { 474 return cast<TypeClass>(Base::getTypePtr()); 475 } 476 }; 477 478 479 struct TypeSpecLocInfo { 480 SourceLocation NameLoc; 481 }; 482 483 /// \brief A reasonable base class for TypeLocs that correspond to 484 /// types that are written as a type-specifier. 485 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 486 TypeSpecTypeLoc, 487 Type, 488 TypeSpecLocInfo> { 489 public: 490 enum { LocalDataSize = sizeof(TypeSpecLocInfo), 491 LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment }; 492 493 SourceLocation getNameLoc() const { 494 return this->getLocalData()->NameLoc; 495 } 496 void setNameLoc(SourceLocation Loc) { 497 this->getLocalData()->NameLoc = Loc; 498 } 499 SourceRange getLocalSourceRange() const { 500 return SourceRange(getNameLoc(), getNameLoc()); 501 } 502 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 503 setNameLoc(Loc); 504 } 505 506 private: 507 friend class TypeLoc; 508 static bool isKind(const TypeLoc &TL); 509 }; 510 511 512 struct BuiltinLocInfo { 513 SourceLocation BuiltinLoc; 514 }; 515 516 /// \brief Wrapper for source info for builtin types. 517 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 518 BuiltinTypeLoc, 519 BuiltinType, 520 BuiltinLocInfo> { 521 public: 522 SourceLocation getBuiltinLoc() const { 523 return getLocalData()->BuiltinLoc; 524 } 525 void setBuiltinLoc(SourceLocation Loc) { 526 getLocalData()->BuiltinLoc = Loc; 527 } 528 529 SourceLocation getNameLoc() const { return getBuiltinLoc(); } 530 531 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 532 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 533 } 534 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 535 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 536 } 537 538 bool needsExtraLocalData() const { 539 BuiltinType::Kind bk = getTypePtr()->getKind(); 540 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) 541 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128) 542 || bk == BuiltinType::UChar 543 || bk == BuiltinType::SChar; 544 } 545 546 unsigned getExtraLocalDataSize() const { 547 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 548 } 549 550 unsigned getExtraLocalDataAlignment() const { 551 return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1; 552 } 553 554 SourceRange getLocalSourceRange() const { 555 return SourceRange(getBuiltinLoc(), getBuiltinLoc()); 556 } 557 558 TypeSpecifierSign getWrittenSignSpec() const { 559 if (needsExtraLocalData()) 560 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 561 else 562 return TSS_unspecified; 563 } 564 bool hasWrittenSignSpec() const { 565 return getWrittenSignSpec() != TSS_unspecified; 566 } 567 void setWrittenSignSpec(TypeSpecifierSign written) { 568 if (needsExtraLocalData()) 569 getWrittenBuiltinSpecs().Sign = written; 570 } 571 572 TypeSpecifierWidth getWrittenWidthSpec() const { 573 if (needsExtraLocalData()) 574 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 575 else 576 return TSW_unspecified; 577 } 578 bool hasWrittenWidthSpec() const { 579 return getWrittenWidthSpec() != TSW_unspecified; 580 } 581 void setWrittenWidthSpec(TypeSpecifierWidth written) { 582 if (needsExtraLocalData()) 583 getWrittenBuiltinSpecs().Width = written; 584 } 585 586 TypeSpecifierType getWrittenTypeSpec() const; 587 bool hasWrittenTypeSpec() const { 588 return getWrittenTypeSpec() != TST_unspecified; 589 } 590 void setWrittenTypeSpec(TypeSpecifierType written) { 591 if (needsExtraLocalData()) 592 getWrittenBuiltinSpecs().Type = written; 593 } 594 595 bool hasModeAttr() const { 596 if (needsExtraLocalData()) 597 return getWrittenBuiltinSpecs().ModeAttr; 598 else 599 return false; 600 } 601 void setModeAttr(bool written) { 602 if (needsExtraLocalData()) 603 getWrittenBuiltinSpecs().ModeAttr = written; 604 } 605 606 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 607 setBuiltinLoc(Loc); 608 if (needsExtraLocalData()) { 609 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 610 wbs.Sign = TSS_unspecified; 611 wbs.Width = TSW_unspecified; 612 wbs.Type = TST_unspecified; 613 wbs.ModeAttr = false; 614 } 615 } 616 }; 617 618 619 /// \brief Wrapper for source info for typedefs. 620 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 621 TypedefTypeLoc, 622 TypedefType> { 623 public: 624 TypedefNameDecl *getTypedefNameDecl() const { 625 return getTypePtr()->getDecl(); 626 } 627 }; 628 629 /// \brief Wrapper for source info for injected class names of class 630 /// templates. 631 class InjectedClassNameTypeLoc : 632 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 633 InjectedClassNameTypeLoc, 634 InjectedClassNameType> { 635 public: 636 CXXRecordDecl *getDecl() const { 637 return getTypePtr()->getDecl(); 638 } 639 }; 640 641 /// \brief Wrapper for source info for unresolved typename using decls. 642 class UnresolvedUsingTypeLoc : 643 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 644 UnresolvedUsingTypeLoc, 645 UnresolvedUsingType> { 646 public: 647 UnresolvedUsingTypenameDecl *getDecl() const { 648 return getTypePtr()->getDecl(); 649 } 650 }; 651 652 /// \brief Wrapper for source info for tag types. Note that this only 653 /// records source info for the name itself; a type written 'struct foo' 654 /// should be represented as an ElaboratedTypeLoc. We currently 655 /// only do that when C++ is enabled because of the expense of 656 /// creating an ElaboratedType node for so many type references in C. 657 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 658 TagTypeLoc, 659 TagType> { 660 public: 661 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 662 663 /// \brief True if the tag was defined in this type specifier. 664 bool isDefinition() const { 665 TagDecl *D = getDecl(); 666 return D->isCompleteDefinition() && 667 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc()); 668 } 669 }; 670 671 /// \brief Wrapper for source info for record types. 672 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 673 RecordTypeLoc, 674 RecordType> { 675 public: 676 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 677 }; 678 679 /// \brief Wrapper for source info for enum types. 680 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 681 EnumTypeLoc, 682 EnumType> { 683 public: 684 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 685 }; 686 687 /// \brief Wrapper for template type parameters. 688 class TemplateTypeParmTypeLoc : 689 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 690 TemplateTypeParmTypeLoc, 691 TemplateTypeParmType> { 692 public: 693 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 694 }; 695 696 /// \brief Wrapper for substituted template type parameters. 697 class SubstTemplateTypeParmTypeLoc : 698 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 699 SubstTemplateTypeParmTypeLoc, 700 SubstTemplateTypeParmType> { 701 }; 702 703 /// \brief Wrapper for substituted template type parameters. 704 class SubstTemplateTypeParmPackTypeLoc : 705 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 706 SubstTemplateTypeParmPackTypeLoc, 707 SubstTemplateTypeParmPackType> { 708 }; 709 710 struct AttributedLocInfo { 711 union { 712 Expr *ExprOperand; 713 714 /// A raw SourceLocation. 715 unsigned EnumOperandLoc; 716 }; 717 718 SourceRange OperandParens; 719 720 SourceLocation AttrLoc; 721 }; 722 723 /// \brief Type source information for an attributed type. 724 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 725 AttributedTypeLoc, 726 AttributedType, 727 AttributedLocInfo> { 728 public: 729 AttributedType::Kind getAttrKind() const { 730 return getTypePtr()->getAttrKind(); 731 } 732 733 bool hasAttrExprOperand() const { 734 return (getAttrKind() >= AttributedType::FirstExprOperandKind && 735 getAttrKind() <= AttributedType::LastExprOperandKind); 736 } 737 738 bool hasAttrEnumOperand() const { 739 return (getAttrKind() >= AttributedType::FirstEnumOperandKind && 740 getAttrKind() <= AttributedType::LastEnumOperandKind); 741 } 742 743 bool hasAttrOperand() const { 744 return hasAttrExprOperand() || hasAttrEnumOperand(); 745 } 746 747 bool isQualifier() const { 748 return getTypePtr()->isQualifier(); 749 } 750 751 /// The modified type, which is generally canonically different from 752 /// the attribute type. 753 /// int main(int, char**) __attribute__((noreturn)) 754 /// ~~~ ~~~~~~~~~~~~~ 755 TypeLoc getModifiedLoc() const { 756 return getInnerTypeLoc(); 757 } 758 759 /// The location of the attribute name, i.e. 760 /// __attribute__((regparm(1000))) 761 /// ^~~~~~~ 762 SourceLocation getAttrNameLoc() const { 763 return getLocalData()->AttrLoc; 764 } 765 void setAttrNameLoc(SourceLocation loc) { 766 getLocalData()->AttrLoc = loc; 767 } 768 769 /// The attribute's expression operand, if it has one. 770 /// void *cur_thread __attribute__((address_space(21))) 771 /// ^~ 772 Expr *getAttrExprOperand() const { 773 assert(hasAttrExprOperand()); 774 return getLocalData()->ExprOperand; 775 } 776 void setAttrExprOperand(Expr *e) { 777 assert(hasAttrExprOperand()); 778 getLocalData()->ExprOperand = e; 779 } 780 781 /// The location of the attribute's enumerated operand, if it has one. 782 /// void * __attribute__((objc_gc(weak))) 783 /// ^~~~ 784 SourceLocation getAttrEnumOperandLoc() const { 785 assert(hasAttrEnumOperand()); 786 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc); 787 } 788 void setAttrEnumOperandLoc(SourceLocation loc) { 789 assert(hasAttrEnumOperand()); 790 getLocalData()->EnumOperandLoc = loc.getRawEncoding(); 791 } 792 793 /// The location of the parentheses around the operand, if there is 794 /// an operand. 795 /// void * __attribute__((objc_gc(weak))) 796 /// ^ ^ 797 SourceRange getAttrOperandParensRange() const { 798 assert(hasAttrOperand()); 799 return getLocalData()->OperandParens; 800 } 801 void setAttrOperandParensRange(SourceRange range) { 802 assert(hasAttrOperand()); 803 getLocalData()->OperandParens = range; 804 } 805 806 SourceRange getLocalSourceRange() const { 807 // Note that this does *not* include the range of the attribute 808 // enclosure, e.g.: 809 // __attribute__((foo(bar))) 810 // ^~~~~~~~~~~~~~~ ~~ 811 // or 812 // [[foo(bar)]] 813 // ^~ ~~ 814 // That enclosure doesn't necessarily belong to a single attribute 815 // anyway. 816 SourceRange range(getAttrNameLoc()); 817 if (hasAttrOperand()) 818 range.setEnd(getAttrOperandParensRange().getEnd()); 819 return range; 820 } 821 822 void initializeLocal(ASTContext &Context, SourceLocation loc) { 823 setAttrNameLoc(loc); 824 if (hasAttrExprOperand()) { 825 setAttrOperandParensRange(SourceRange(loc)); 826 setAttrExprOperand(nullptr); 827 } else if (hasAttrEnumOperand()) { 828 setAttrOperandParensRange(SourceRange(loc)); 829 setAttrEnumOperandLoc(loc); 830 } 831 } 832 833 QualType getInnerType() const { 834 return getTypePtr()->getModifiedType(); 835 } 836 }; 837 838 839 struct ObjCObjectTypeLocInfo { 840 SourceLocation TypeArgsLAngleLoc; 841 SourceLocation TypeArgsRAngleLoc; 842 SourceLocation ProtocolLAngleLoc; 843 SourceLocation ProtocolRAngleLoc; 844 bool HasBaseTypeAsWritten; 845 }; 846 847 // A helper class for defining ObjC TypeLocs that can qualified with 848 // protocols. 849 // 850 // TypeClass basically has to be either ObjCInterfaceType or 851 // ObjCObjectPointerType. 852 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 853 ObjCObjectTypeLoc, 854 ObjCObjectType, 855 ObjCObjectTypeLocInfo> { 856 // TypeSourceInfo*'s are stored after Info, one for each type argument. 857 TypeSourceInfo **getTypeArgLocArray() const { 858 return (TypeSourceInfo**)this->getExtraLocalData(); 859 } 860 861 // SourceLocations are stored after the type argument information, one for 862 // each Protocol. 863 SourceLocation *getProtocolLocArray() const { 864 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs()); 865 } 866 867 public: 868 SourceLocation getTypeArgsLAngleLoc() const { 869 return this->getLocalData()->TypeArgsLAngleLoc; 870 } 871 void setTypeArgsLAngleLoc(SourceLocation Loc) { 872 this->getLocalData()->TypeArgsLAngleLoc = Loc; 873 } 874 875 SourceLocation getTypeArgsRAngleLoc() const { 876 return this->getLocalData()->TypeArgsRAngleLoc; 877 } 878 void setTypeArgsRAngleLoc(SourceLocation Loc) { 879 this->getLocalData()->TypeArgsRAngleLoc = Loc; 880 } 881 882 unsigned getNumTypeArgs() const { 883 return this->getTypePtr()->getTypeArgsAsWritten().size(); 884 } 885 886 TypeSourceInfo *getTypeArgTInfo(unsigned i) const { 887 assert(i < getNumTypeArgs() && "Index is out of bounds!"); 888 return getTypeArgLocArray()[i]; 889 } 890 891 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) { 892 assert(i < getNumTypeArgs() && "Index is out of bounds!"); 893 getTypeArgLocArray()[i] = TInfo; 894 } 895 896 SourceLocation getProtocolLAngleLoc() const { 897 return this->getLocalData()->ProtocolLAngleLoc; 898 } 899 void setProtocolLAngleLoc(SourceLocation Loc) { 900 this->getLocalData()->ProtocolLAngleLoc = Loc; 901 } 902 903 SourceLocation getProtocolRAngleLoc() const { 904 return this->getLocalData()->ProtocolRAngleLoc; 905 } 906 void setProtocolRAngleLoc(SourceLocation Loc) { 907 this->getLocalData()->ProtocolRAngleLoc = Loc; 908 } 909 910 unsigned getNumProtocols() const { 911 return this->getTypePtr()->getNumProtocols(); 912 } 913 914 SourceLocation getProtocolLoc(unsigned i) const { 915 assert(i < getNumProtocols() && "Index is out of bounds!"); 916 return getProtocolLocArray()[i]; 917 } 918 void setProtocolLoc(unsigned i, SourceLocation Loc) { 919 assert(i < getNumProtocols() && "Index is out of bounds!"); 920 getProtocolLocArray()[i] = Loc; 921 } 922 923 ObjCProtocolDecl *getProtocol(unsigned i) const { 924 assert(i < getNumProtocols() && "Index is out of bounds!"); 925 return *(this->getTypePtr()->qual_begin() + i); 926 } 927 928 929 ArrayRef<SourceLocation> getProtocolLocs() const { 930 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols()); 931 } 932 933 bool hasBaseTypeAsWritten() const { 934 return getLocalData()->HasBaseTypeAsWritten; 935 } 936 937 void setHasBaseTypeAsWritten(bool HasBaseType) { 938 getLocalData()->HasBaseTypeAsWritten = HasBaseType; 939 } 940 941 TypeLoc getBaseLoc() const { 942 return getInnerTypeLoc(); 943 } 944 945 SourceRange getLocalSourceRange() const { 946 SourceLocation start = getTypeArgsLAngleLoc(); 947 if (start.isInvalid()) 948 start = getProtocolLAngleLoc(); 949 SourceLocation end = getProtocolRAngleLoc(); 950 if (end.isInvalid()) 951 end = getTypeArgsRAngleLoc(); 952 return SourceRange(start, end); 953 } 954 955 void initializeLocal(ASTContext &Context, SourceLocation Loc); 956 957 unsigned getExtraLocalDataSize() const { 958 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *) 959 + this->getNumProtocols() * sizeof(SourceLocation); 960 } 961 962 unsigned getExtraLocalDataAlignment() const { 963 assert(llvm::alignOf<ObjCObjectTypeLoc>() 964 >= llvm::alignOf<TypeSourceInfo *>() && 965 "not enough alignment for tail-allocated data"); 966 return llvm::alignOf<TypeSourceInfo *>(); 967 } 968 969 QualType getInnerType() const { 970 return getTypePtr()->getBaseType(); 971 } 972 }; 973 974 975 struct ObjCInterfaceLocInfo { 976 SourceLocation NameLoc; 977 SourceLocation NameEndLoc; 978 }; 979 980 /// \brief Wrapper for source info for ObjC interfaces. 981 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 982 ObjCInterfaceTypeLoc, 983 ObjCInterfaceType, 984 ObjCInterfaceLocInfo> { 985 public: 986 ObjCInterfaceDecl *getIFaceDecl() const { 987 return getTypePtr()->getDecl(); 988 } 989 990 SourceLocation getNameLoc() const { 991 return getLocalData()->NameLoc; 992 } 993 994 void setNameLoc(SourceLocation Loc) { 995 getLocalData()->NameLoc = Loc; 996 } 997 998 SourceRange getLocalSourceRange() const { 999 return SourceRange(getNameLoc(), getNameEndLoc()); 1000 } 1001 1002 SourceLocation getNameEndLoc() const { 1003 return getLocalData()->NameEndLoc; 1004 } 1005 1006 void setNameEndLoc(SourceLocation Loc) { 1007 getLocalData()->NameEndLoc = Loc; 1008 } 1009 1010 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1011 setNameLoc(Loc); 1012 setNameEndLoc(Loc); 1013 } 1014 }; 1015 1016 struct ParenLocInfo { 1017 SourceLocation LParenLoc; 1018 SourceLocation RParenLoc; 1019 }; 1020 1021 class ParenTypeLoc 1022 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 1023 ParenLocInfo> { 1024 public: 1025 SourceLocation getLParenLoc() const { 1026 return this->getLocalData()->LParenLoc; 1027 } 1028 SourceLocation getRParenLoc() const { 1029 return this->getLocalData()->RParenLoc; 1030 } 1031 void setLParenLoc(SourceLocation Loc) { 1032 this->getLocalData()->LParenLoc = Loc; 1033 } 1034 void setRParenLoc(SourceLocation Loc) { 1035 this->getLocalData()->RParenLoc = Loc; 1036 } 1037 1038 SourceRange getLocalSourceRange() const { 1039 return SourceRange(getLParenLoc(), getRParenLoc()); 1040 } 1041 1042 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1043 setLParenLoc(Loc); 1044 setRParenLoc(Loc); 1045 } 1046 1047 TypeLoc getInnerLoc() const { 1048 return getInnerTypeLoc(); 1049 } 1050 1051 QualType getInnerType() const { 1052 return this->getTypePtr()->getInnerType(); 1053 } 1054 }; 1055 1056 inline TypeLoc TypeLoc::IgnoreParens() const { 1057 if (ParenTypeLoc::isKind(*this)) 1058 return IgnoreParensImpl(*this); 1059 return *this; 1060 } 1061 1062 1063 struct AdjustedLocInfo { }; // Nothing. 1064 1065 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc, 1066 AdjustedType, AdjustedLocInfo> { 1067 public: 1068 TypeLoc getOriginalLoc() const { 1069 return getInnerTypeLoc(); 1070 } 1071 1072 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1073 // do nothing 1074 } 1075 1076 QualType getInnerType() const { 1077 // The inner type is the undecayed type, since that's what we have source 1078 // location information for. 1079 return getTypePtr()->getOriginalType(); 1080 } 1081 1082 SourceRange getLocalSourceRange() const { 1083 return SourceRange(); 1084 } 1085 1086 unsigned getLocalDataSize() const { 1087 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique 1088 // anyway. TypeLocBuilder can't handle data sizes of 1. 1089 return 0; // No data. 1090 } 1091 }; 1092 1093 /// \brief Wrapper for source info for pointers decayed from arrays and 1094 /// functions. 1095 class DecayedTypeLoc : public InheritingConcreteTypeLoc< 1096 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> { 1097 }; 1098 1099 struct PointerLikeLocInfo { 1100 SourceLocation StarLoc; 1101 }; 1102 1103 /// A base class for 1104 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 1105 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 1106 TypeClass, LocalData> { 1107 public: 1108 SourceLocation getSigilLoc() const { 1109 return this->getLocalData()->StarLoc; 1110 } 1111 void setSigilLoc(SourceLocation Loc) { 1112 this->getLocalData()->StarLoc = Loc; 1113 } 1114 1115 TypeLoc getPointeeLoc() const { 1116 return this->getInnerTypeLoc(); 1117 } 1118 1119 SourceRange getLocalSourceRange() const { 1120 return SourceRange(getSigilLoc(), getSigilLoc()); 1121 } 1122 1123 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1124 setSigilLoc(Loc); 1125 } 1126 1127 QualType getInnerType() const { 1128 return this->getTypePtr()->getPointeeType(); 1129 } 1130 }; 1131 1132 1133 /// \brief Wrapper for source info for pointers. 1134 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 1135 PointerType> { 1136 public: 1137 SourceLocation getStarLoc() const { 1138 return getSigilLoc(); 1139 } 1140 void setStarLoc(SourceLocation Loc) { 1141 setSigilLoc(Loc); 1142 } 1143 }; 1144 1145 1146 /// \brief Wrapper for source info for block pointers. 1147 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 1148 BlockPointerType> { 1149 public: 1150 SourceLocation getCaretLoc() const { 1151 return getSigilLoc(); 1152 } 1153 void setCaretLoc(SourceLocation Loc) { 1154 setSigilLoc(Loc); 1155 } 1156 }; 1157 1158 struct MemberPointerLocInfo : public PointerLikeLocInfo { 1159 TypeSourceInfo *ClassTInfo; 1160 }; 1161 1162 /// \brief Wrapper for source info for member pointers. 1163 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 1164 MemberPointerType, 1165 MemberPointerLocInfo> { 1166 public: 1167 SourceLocation getStarLoc() const { 1168 return getSigilLoc(); 1169 } 1170 void setStarLoc(SourceLocation Loc) { 1171 setSigilLoc(Loc); 1172 } 1173 1174 const Type *getClass() const { 1175 return getTypePtr()->getClass(); 1176 } 1177 TypeSourceInfo *getClassTInfo() const { 1178 return getLocalData()->ClassTInfo; 1179 } 1180 void setClassTInfo(TypeSourceInfo* TI) { 1181 getLocalData()->ClassTInfo = TI; 1182 } 1183 1184 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1185 setSigilLoc(Loc); 1186 setClassTInfo(nullptr); 1187 } 1188 1189 SourceRange getLocalSourceRange() const { 1190 if (TypeSourceInfo *TI = getClassTInfo()) 1191 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 1192 else 1193 return SourceRange(getStarLoc()); 1194 } 1195 }; 1196 1197 /// Wraps an ObjCPointerType with source location information. 1198 class ObjCObjectPointerTypeLoc : 1199 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1200 ObjCObjectPointerType> { 1201 public: 1202 SourceLocation getStarLoc() const { 1203 return getSigilLoc(); 1204 } 1205 1206 void setStarLoc(SourceLocation Loc) { 1207 setSigilLoc(Loc); 1208 } 1209 }; 1210 1211 1212 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1213 ReferenceType> { 1214 public: 1215 QualType getInnerType() const { 1216 return getTypePtr()->getPointeeTypeAsWritten(); 1217 } 1218 }; 1219 1220 class LValueReferenceTypeLoc : 1221 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1222 LValueReferenceTypeLoc, 1223 LValueReferenceType> { 1224 public: 1225 SourceLocation getAmpLoc() const { 1226 return getSigilLoc(); 1227 } 1228 void setAmpLoc(SourceLocation Loc) { 1229 setSigilLoc(Loc); 1230 } 1231 }; 1232 1233 class RValueReferenceTypeLoc : 1234 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1235 RValueReferenceTypeLoc, 1236 RValueReferenceType> { 1237 public: 1238 SourceLocation getAmpAmpLoc() const { 1239 return getSigilLoc(); 1240 } 1241 void setAmpAmpLoc(SourceLocation Loc) { 1242 setSigilLoc(Loc); 1243 } 1244 }; 1245 1246 1247 struct FunctionLocInfo { 1248 SourceLocation LocalRangeBegin; 1249 SourceLocation LParenLoc; 1250 SourceLocation RParenLoc; 1251 SourceLocation LocalRangeEnd; 1252 }; 1253 1254 /// \brief Wrapper for source info for functions. 1255 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1256 FunctionTypeLoc, 1257 FunctionType, 1258 FunctionLocInfo> { 1259 public: 1260 SourceLocation getLocalRangeBegin() const { 1261 return getLocalData()->LocalRangeBegin; 1262 } 1263 void setLocalRangeBegin(SourceLocation L) { 1264 getLocalData()->LocalRangeBegin = L; 1265 } 1266 1267 SourceLocation getLocalRangeEnd() const { 1268 return getLocalData()->LocalRangeEnd; 1269 } 1270 void setLocalRangeEnd(SourceLocation L) { 1271 getLocalData()->LocalRangeEnd = L; 1272 } 1273 1274 SourceLocation getLParenLoc() const { 1275 return this->getLocalData()->LParenLoc; 1276 } 1277 void setLParenLoc(SourceLocation Loc) { 1278 this->getLocalData()->LParenLoc = Loc; 1279 } 1280 1281 SourceLocation getRParenLoc() const { 1282 return this->getLocalData()->RParenLoc; 1283 } 1284 void setRParenLoc(SourceLocation Loc) { 1285 this->getLocalData()->RParenLoc = Loc; 1286 } 1287 1288 SourceRange getParensRange() const { 1289 return SourceRange(getLParenLoc(), getRParenLoc()); 1290 } 1291 1292 ArrayRef<ParmVarDecl *> getParams() const { 1293 return llvm::makeArrayRef(getParmArray(), getNumParams()); 1294 } 1295 1296 // ParmVarDecls* are stored after Info, one for each parameter. 1297 ParmVarDecl **getParmArray() const { 1298 return (ParmVarDecl**) getExtraLocalData(); 1299 } 1300 1301 unsigned getNumParams() const { 1302 if (isa<FunctionNoProtoType>(getTypePtr())) 1303 return 0; 1304 return cast<FunctionProtoType>(getTypePtr())->getNumParams(); 1305 } 1306 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; } 1307 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1308 1309 TypeLoc getReturnLoc() const { 1310 return getInnerTypeLoc(); 1311 } 1312 1313 SourceRange getLocalSourceRange() const { 1314 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1315 } 1316 1317 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1318 setLocalRangeBegin(Loc); 1319 setLParenLoc(Loc); 1320 setRParenLoc(Loc); 1321 setLocalRangeEnd(Loc); 1322 for (unsigned i = 0, e = getNumParams(); i != e; ++i) 1323 setParam(i, nullptr); 1324 } 1325 1326 /// \brief Returns the size of the type source info data block that is 1327 /// specific to this type. 1328 unsigned getExtraLocalDataSize() const { 1329 return getNumParams() * sizeof(ParmVarDecl *); 1330 } 1331 1332 unsigned getExtraLocalDataAlignment() const { 1333 return llvm::alignOf<ParmVarDecl*>(); 1334 } 1335 1336 QualType getInnerType() const { return getTypePtr()->getReturnType(); } 1337 }; 1338 1339 class FunctionProtoTypeLoc : 1340 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1341 FunctionProtoTypeLoc, 1342 FunctionProtoType> { 1343 }; 1344 1345 class FunctionNoProtoTypeLoc : 1346 public InheritingConcreteTypeLoc<FunctionTypeLoc, 1347 FunctionNoProtoTypeLoc, 1348 FunctionNoProtoType> { 1349 }; 1350 1351 1352 struct ArrayLocInfo { 1353 SourceLocation LBracketLoc, RBracketLoc; 1354 Expr *Size; 1355 }; 1356 1357 /// \brief Wrapper for source info for arrays. 1358 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1359 ArrayTypeLoc, 1360 ArrayType, 1361 ArrayLocInfo> { 1362 public: 1363 SourceLocation getLBracketLoc() const { 1364 return getLocalData()->LBracketLoc; 1365 } 1366 void setLBracketLoc(SourceLocation Loc) { 1367 getLocalData()->LBracketLoc = Loc; 1368 } 1369 1370 SourceLocation getRBracketLoc() const { 1371 return getLocalData()->RBracketLoc; 1372 } 1373 void setRBracketLoc(SourceLocation Loc) { 1374 getLocalData()->RBracketLoc = Loc; 1375 } 1376 1377 SourceRange getBracketsRange() const { 1378 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1379 } 1380 1381 Expr *getSizeExpr() const { 1382 return getLocalData()->Size; 1383 } 1384 void setSizeExpr(Expr *Size) { 1385 getLocalData()->Size = Size; 1386 } 1387 1388 TypeLoc getElementLoc() const { 1389 return getInnerTypeLoc(); 1390 } 1391 1392 SourceRange getLocalSourceRange() const { 1393 return SourceRange(getLBracketLoc(), getRBracketLoc()); 1394 } 1395 1396 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1397 setLBracketLoc(Loc); 1398 setRBracketLoc(Loc); 1399 setSizeExpr(nullptr); 1400 } 1401 1402 QualType getInnerType() const { return getTypePtr()->getElementType(); } 1403 }; 1404 1405 class ConstantArrayTypeLoc : 1406 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1407 ConstantArrayTypeLoc, 1408 ConstantArrayType> { 1409 }; 1410 1411 class IncompleteArrayTypeLoc : 1412 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1413 IncompleteArrayTypeLoc, 1414 IncompleteArrayType> { 1415 }; 1416 1417 class DependentSizedArrayTypeLoc : 1418 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1419 DependentSizedArrayTypeLoc, 1420 DependentSizedArrayType> { 1421 1422 }; 1423 1424 class VariableArrayTypeLoc : 1425 public InheritingConcreteTypeLoc<ArrayTypeLoc, 1426 VariableArrayTypeLoc, 1427 VariableArrayType> { 1428 }; 1429 1430 1431 // Location information for a TemplateName. Rudimentary for now. 1432 struct TemplateNameLocInfo { 1433 SourceLocation NameLoc; 1434 }; 1435 1436 struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1437 SourceLocation TemplateKWLoc; 1438 SourceLocation LAngleLoc; 1439 SourceLocation RAngleLoc; 1440 }; 1441 1442 class TemplateSpecializationTypeLoc : 1443 public ConcreteTypeLoc<UnqualTypeLoc, 1444 TemplateSpecializationTypeLoc, 1445 TemplateSpecializationType, 1446 TemplateSpecializationLocInfo> { 1447 public: 1448 SourceLocation getTemplateKeywordLoc() const { 1449 return getLocalData()->TemplateKWLoc; 1450 } 1451 void setTemplateKeywordLoc(SourceLocation Loc) { 1452 getLocalData()->TemplateKWLoc = Loc; 1453 } 1454 1455 SourceLocation getLAngleLoc() const { 1456 return getLocalData()->LAngleLoc; 1457 } 1458 void setLAngleLoc(SourceLocation Loc) { 1459 getLocalData()->LAngleLoc = Loc; 1460 } 1461 1462 SourceLocation getRAngleLoc() const { 1463 return getLocalData()->RAngleLoc; 1464 } 1465 void setRAngleLoc(SourceLocation Loc) { 1466 getLocalData()->RAngleLoc = Loc; 1467 } 1468 1469 unsigned getNumArgs() const { 1470 return getTypePtr()->getNumArgs(); 1471 } 1472 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1473 getArgInfos()[i] = AI; 1474 } 1475 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1476 return getArgInfos()[i]; 1477 } 1478 1479 TemplateArgumentLoc getArgLoc(unsigned i) const { 1480 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1481 } 1482 1483 SourceLocation getTemplateNameLoc() const { 1484 return getLocalData()->NameLoc; 1485 } 1486 void setTemplateNameLoc(SourceLocation Loc) { 1487 getLocalData()->NameLoc = Loc; 1488 } 1489 1490 /// \brief - Copy the location information from the given info. 1491 void copy(TemplateSpecializationTypeLoc Loc) { 1492 unsigned size = getFullDataSize(); 1493 assert(size == Loc.getFullDataSize()); 1494 1495 // We're potentially copying Expr references here. We don't 1496 // bother retaining them because TypeSourceInfos live forever, so 1497 // as long as the Expr was retained when originally written into 1498 // the TypeLoc, we're okay. 1499 memcpy(Data, Loc.Data, size); 1500 } 1501 1502 SourceRange getLocalSourceRange() const { 1503 if (getTemplateKeywordLoc().isValid()) 1504 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1505 else 1506 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1507 } 1508 1509 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1510 setTemplateKeywordLoc(Loc); 1511 setTemplateNameLoc(Loc); 1512 setLAngleLoc(Loc); 1513 setRAngleLoc(Loc); 1514 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), 1515 getArgInfos(), Loc); 1516 } 1517 1518 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, 1519 const TemplateArgument *Args, 1520 TemplateArgumentLocInfo *ArgInfos, 1521 SourceLocation Loc); 1522 1523 unsigned getExtraLocalDataSize() const { 1524 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1525 } 1526 1527 unsigned getExtraLocalDataAlignment() const { 1528 return llvm::alignOf<TemplateArgumentLocInfo>(); 1529 } 1530 1531 private: 1532 TemplateArgumentLocInfo *getArgInfos() const { 1533 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1534 } 1535 }; 1536 1537 //===----------------------------------------------------------------------===// 1538 // 1539 // All of these need proper implementations. 1540 // 1541 //===----------------------------------------------------------------------===// 1542 1543 // FIXME: size expression and attribute locations (or keyword if we 1544 // ever fully support altivec syntax). 1545 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1546 VectorTypeLoc, 1547 VectorType> { 1548 }; 1549 1550 // FIXME: size expression and attribute locations. 1551 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1552 ExtVectorTypeLoc, 1553 ExtVectorType> { 1554 }; 1555 1556 // FIXME: attribute locations. 1557 // For some reason, this isn't a subtype of VectorType. 1558 class DependentSizedExtVectorTypeLoc : 1559 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1560 DependentSizedExtVectorTypeLoc, 1561 DependentSizedExtVectorType> { 1562 }; 1563 1564 // FIXME: location of the '_Complex' keyword. 1565 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1566 ComplexTypeLoc, 1567 ComplexType> { 1568 }; 1569 1570 struct TypeofLocInfo { 1571 SourceLocation TypeofLoc; 1572 SourceLocation LParenLoc; 1573 SourceLocation RParenLoc; 1574 }; 1575 1576 struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1577 }; 1578 1579 struct TypeOfTypeLocInfo : public TypeofLocInfo { 1580 TypeSourceInfo* UnderlyingTInfo; 1581 }; 1582 1583 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1584 class TypeofLikeTypeLoc 1585 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1586 public: 1587 SourceLocation getTypeofLoc() const { 1588 return this->getLocalData()->TypeofLoc; 1589 } 1590 void setTypeofLoc(SourceLocation Loc) { 1591 this->getLocalData()->TypeofLoc = Loc; 1592 } 1593 1594 SourceLocation getLParenLoc() const { 1595 return this->getLocalData()->LParenLoc; 1596 } 1597 void setLParenLoc(SourceLocation Loc) { 1598 this->getLocalData()->LParenLoc = Loc; 1599 } 1600 1601 SourceLocation getRParenLoc() const { 1602 return this->getLocalData()->RParenLoc; 1603 } 1604 void setRParenLoc(SourceLocation Loc) { 1605 this->getLocalData()->RParenLoc = Loc; 1606 } 1607 1608 SourceRange getParensRange() const { 1609 return SourceRange(getLParenLoc(), getRParenLoc()); 1610 } 1611 void setParensRange(SourceRange range) { 1612 setLParenLoc(range.getBegin()); 1613 setRParenLoc(range.getEnd()); 1614 } 1615 1616 SourceRange getLocalSourceRange() const { 1617 return SourceRange(getTypeofLoc(), getRParenLoc()); 1618 } 1619 1620 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1621 setTypeofLoc(Loc); 1622 setLParenLoc(Loc); 1623 setRParenLoc(Loc); 1624 } 1625 }; 1626 1627 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1628 TypeOfExprType, 1629 TypeOfExprTypeLocInfo> { 1630 public: 1631 Expr* getUnderlyingExpr() const { 1632 return getTypePtr()->getUnderlyingExpr(); 1633 } 1634 // Reimplemented to account for GNU/C++ extension 1635 // typeof unary-expression 1636 // where there are no parentheses. 1637 SourceRange getLocalSourceRange() const; 1638 }; 1639 1640 class TypeOfTypeLoc 1641 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1642 public: 1643 QualType getUnderlyingType() const { 1644 return this->getTypePtr()->getUnderlyingType(); 1645 } 1646 TypeSourceInfo* getUnderlyingTInfo() const { 1647 return this->getLocalData()->UnderlyingTInfo; 1648 } 1649 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1650 this->getLocalData()->UnderlyingTInfo = TI; 1651 } 1652 1653 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1654 }; 1655 1656 // FIXME: location of the 'decltype' and parens. 1657 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1658 DecltypeTypeLoc, 1659 DecltypeType> { 1660 public: 1661 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1662 }; 1663 1664 struct UnaryTransformTypeLocInfo { 1665 // FIXME: While there's only one unary transform right now, future ones may 1666 // need different representations 1667 SourceLocation KWLoc, LParenLoc, RParenLoc; 1668 TypeSourceInfo *UnderlyingTInfo; 1669 }; 1670 1671 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1672 UnaryTransformTypeLoc, 1673 UnaryTransformType, 1674 UnaryTransformTypeLocInfo> { 1675 public: 1676 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1677 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1678 1679 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1680 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1681 1682 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1683 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1684 1685 TypeSourceInfo* getUnderlyingTInfo() const { 1686 return getLocalData()->UnderlyingTInfo; 1687 } 1688 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1689 getLocalData()->UnderlyingTInfo = TInfo; 1690 } 1691 1692 SourceRange getLocalSourceRange() const { 1693 return SourceRange(getKWLoc(), getRParenLoc()); 1694 } 1695 1696 SourceRange getParensRange() const { 1697 return SourceRange(getLParenLoc(), getRParenLoc()); 1698 } 1699 void setParensRange(SourceRange Range) { 1700 setLParenLoc(Range.getBegin()); 1701 setRParenLoc(Range.getEnd()); 1702 } 1703 1704 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1705 setKWLoc(Loc); 1706 setRParenLoc(Loc); 1707 setLParenLoc(Loc); 1708 } 1709 }; 1710 1711 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1712 AutoTypeLoc, 1713 AutoType> { 1714 }; 1715 1716 struct ElaboratedLocInfo { 1717 SourceLocation ElaboratedKWLoc; 1718 /// \brief Data associated with the nested-name-specifier location. 1719 void *QualifierData; 1720 }; 1721 1722 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1723 ElaboratedTypeLoc, 1724 ElaboratedType, 1725 ElaboratedLocInfo> { 1726 public: 1727 SourceLocation getElaboratedKeywordLoc() const { 1728 return this->getLocalData()->ElaboratedKWLoc; 1729 } 1730 void setElaboratedKeywordLoc(SourceLocation Loc) { 1731 this->getLocalData()->ElaboratedKWLoc = Loc; 1732 } 1733 1734 NestedNameSpecifierLoc getQualifierLoc() const { 1735 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1736 getLocalData()->QualifierData); 1737 } 1738 1739 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1740 assert(QualifierLoc.getNestedNameSpecifier() 1741 == getTypePtr()->getQualifier() && 1742 "Inconsistent nested-name-specifier pointer"); 1743 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1744 } 1745 1746 SourceRange getLocalSourceRange() const { 1747 if (getElaboratedKeywordLoc().isValid()) 1748 if (getQualifierLoc()) 1749 return SourceRange(getElaboratedKeywordLoc(), 1750 getQualifierLoc().getEndLoc()); 1751 else 1752 return SourceRange(getElaboratedKeywordLoc()); 1753 else 1754 return getQualifierLoc().getSourceRange(); 1755 } 1756 1757 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1758 1759 TypeLoc getNamedTypeLoc() const { 1760 return getInnerTypeLoc(); 1761 } 1762 1763 QualType getInnerType() const { 1764 return getTypePtr()->getNamedType(); 1765 } 1766 1767 void copy(ElaboratedTypeLoc Loc) { 1768 unsigned size = getFullDataSize(); 1769 assert(size == Loc.getFullDataSize()); 1770 memcpy(Data, Loc.Data, size); 1771 } 1772 }; 1773 1774 // This is exactly the structure of an ElaboratedTypeLoc whose inner 1775 // type is some sort of TypeDeclTypeLoc. 1776 struct DependentNameLocInfo : ElaboratedLocInfo { 1777 SourceLocation NameLoc; 1778 }; 1779 1780 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1781 DependentNameTypeLoc, 1782 DependentNameType, 1783 DependentNameLocInfo> { 1784 public: 1785 SourceLocation getElaboratedKeywordLoc() const { 1786 return this->getLocalData()->ElaboratedKWLoc; 1787 } 1788 void setElaboratedKeywordLoc(SourceLocation Loc) { 1789 this->getLocalData()->ElaboratedKWLoc = Loc; 1790 } 1791 1792 NestedNameSpecifierLoc getQualifierLoc() const { 1793 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1794 getLocalData()->QualifierData); 1795 } 1796 1797 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1798 assert(QualifierLoc.getNestedNameSpecifier() 1799 == getTypePtr()->getQualifier() && 1800 "Inconsistent nested-name-specifier pointer"); 1801 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1802 } 1803 1804 SourceLocation getNameLoc() const { 1805 return this->getLocalData()->NameLoc; 1806 } 1807 void setNameLoc(SourceLocation Loc) { 1808 this->getLocalData()->NameLoc = Loc; 1809 } 1810 1811 SourceRange getLocalSourceRange() const { 1812 if (getElaboratedKeywordLoc().isValid()) 1813 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 1814 else 1815 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 1816 } 1817 1818 void copy(DependentNameTypeLoc Loc) { 1819 unsigned size = getFullDataSize(); 1820 assert(size == Loc.getFullDataSize()); 1821 memcpy(Data, Loc.Data, size); 1822 } 1823 1824 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1825 }; 1826 1827 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 1828 SourceLocation TemplateKWLoc; 1829 SourceLocation LAngleLoc; 1830 SourceLocation RAngleLoc; 1831 // followed by a TemplateArgumentLocInfo[] 1832 }; 1833 1834 class DependentTemplateSpecializationTypeLoc : 1835 public ConcreteTypeLoc<UnqualTypeLoc, 1836 DependentTemplateSpecializationTypeLoc, 1837 DependentTemplateSpecializationType, 1838 DependentTemplateSpecializationLocInfo> { 1839 public: 1840 SourceLocation getElaboratedKeywordLoc() const { 1841 return this->getLocalData()->ElaboratedKWLoc; 1842 } 1843 void setElaboratedKeywordLoc(SourceLocation Loc) { 1844 this->getLocalData()->ElaboratedKWLoc = Loc; 1845 } 1846 1847 NestedNameSpecifierLoc getQualifierLoc() const { 1848 if (!getLocalData()->QualifierData) 1849 return NestedNameSpecifierLoc(); 1850 1851 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1852 getLocalData()->QualifierData); 1853 } 1854 1855 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1856 if (!QualifierLoc) { 1857 // Even if we have a nested-name-specifier in the dependent 1858 // template specialization type, we won't record the nested-name-specifier 1859 // location information when this type-source location information is 1860 // part of a nested-name-specifier. 1861 getLocalData()->QualifierData = nullptr; 1862 return; 1863 } 1864 1865 assert(QualifierLoc.getNestedNameSpecifier() 1866 == getTypePtr()->getQualifier() && 1867 "Inconsistent nested-name-specifier pointer"); 1868 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1869 } 1870 1871 SourceLocation getTemplateKeywordLoc() const { 1872 return getLocalData()->TemplateKWLoc; 1873 } 1874 void setTemplateKeywordLoc(SourceLocation Loc) { 1875 getLocalData()->TemplateKWLoc = Loc; 1876 } 1877 1878 SourceLocation getTemplateNameLoc() const { 1879 return this->getLocalData()->NameLoc; 1880 } 1881 void setTemplateNameLoc(SourceLocation Loc) { 1882 this->getLocalData()->NameLoc = Loc; 1883 } 1884 1885 SourceLocation getLAngleLoc() const { 1886 return this->getLocalData()->LAngleLoc; 1887 } 1888 void setLAngleLoc(SourceLocation Loc) { 1889 this->getLocalData()->LAngleLoc = Loc; 1890 } 1891 1892 SourceLocation getRAngleLoc() const { 1893 return this->getLocalData()->RAngleLoc; 1894 } 1895 void setRAngleLoc(SourceLocation Loc) { 1896 this->getLocalData()->RAngleLoc = Loc; 1897 } 1898 1899 unsigned getNumArgs() const { 1900 return getTypePtr()->getNumArgs(); 1901 } 1902 1903 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1904 getArgInfos()[i] = AI; 1905 } 1906 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1907 return getArgInfos()[i]; 1908 } 1909 1910 TemplateArgumentLoc getArgLoc(unsigned i) const { 1911 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1912 } 1913 1914 SourceRange getLocalSourceRange() const { 1915 if (getElaboratedKeywordLoc().isValid()) 1916 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 1917 else if (getQualifierLoc()) 1918 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 1919 else if (getTemplateKeywordLoc().isValid()) 1920 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1921 else 1922 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1923 } 1924 1925 void copy(DependentTemplateSpecializationTypeLoc Loc) { 1926 unsigned size = getFullDataSize(); 1927 assert(size == Loc.getFullDataSize()); 1928 memcpy(Data, Loc.Data, size); 1929 } 1930 1931 void initializeLocal(ASTContext &Context, SourceLocation Loc); 1932 1933 unsigned getExtraLocalDataSize() const { 1934 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1935 } 1936 1937 unsigned getExtraLocalDataAlignment() const { 1938 return llvm::alignOf<TemplateArgumentLocInfo>(); 1939 } 1940 1941 private: 1942 TemplateArgumentLocInfo *getArgInfos() const { 1943 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1944 } 1945 }; 1946 1947 1948 struct PackExpansionTypeLocInfo { 1949 SourceLocation EllipsisLoc; 1950 }; 1951 1952 class PackExpansionTypeLoc 1953 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 1954 PackExpansionType, PackExpansionTypeLocInfo> { 1955 public: 1956 SourceLocation getEllipsisLoc() const { 1957 return this->getLocalData()->EllipsisLoc; 1958 } 1959 1960 void setEllipsisLoc(SourceLocation Loc) { 1961 this->getLocalData()->EllipsisLoc = Loc; 1962 } 1963 1964 SourceRange getLocalSourceRange() const { 1965 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 1966 } 1967 1968 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1969 setEllipsisLoc(Loc); 1970 } 1971 1972 TypeLoc getPatternLoc() const { 1973 return getInnerTypeLoc(); 1974 } 1975 1976 QualType getInnerType() const { 1977 return this->getTypePtr()->getPattern(); 1978 } 1979 }; 1980 1981 struct AtomicTypeLocInfo { 1982 SourceLocation KWLoc, LParenLoc, RParenLoc; 1983 }; 1984 1985 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 1986 AtomicType, AtomicTypeLocInfo> { 1987 public: 1988 TypeLoc getValueLoc() const { 1989 return this->getInnerTypeLoc(); 1990 } 1991 1992 SourceRange getLocalSourceRange() const { 1993 return SourceRange(getKWLoc(), getRParenLoc()); 1994 } 1995 1996 SourceLocation getKWLoc() const { 1997 return this->getLocalData()->KWLoc; 1998 } 1999 void setKWLoc(SourceLocation Loc) { 2000 this->getLocalData()->KWLoc = Loc; 2001 } 2002 2003 SourceLocation getLParenLoc() const { 2004 return this->getLocalData()->LParenLoc; 2005 } 2006 void setLParenLoc(SourceLocation Loc) { 2007 this->getLocalData()->LParenLoc = Loc; 2008 } 2009 2010 SourceLocation getRParenLoc() const { 2011 return this->getLocalData()->RParenLoc; 2012 } 2013 void setRParenLoc(SourceLocation Loc) { 2014 this->getLocalData()->RParenLoc = Loc; 2015 } 2016 2017 SourceRange getParensRange() const { 2018 return SourceRange(getLParenLoc(), getRParenLoc()); 2019 } 2020 void setParensRange(SourceRange Range) { 2021 setLParenLoc(Range.getBegin()); 2022 setRParenLoc(Range.getEnd()); 2023 } 2024 2025 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2026 setKWLoc(Loc); 2027 setLParenLoc(Loc); 2028 setRParenLoc(Loc); 2029 } 2030 2031 QualType getInnerType() const { 2032 return this->getTypePtr()->getValueType(); 2033 } 2034 }; 2035 2036 struct PipeTypeLocInfo { 2037 SourceLocation KWLoc; 2038 }; 2039 2040 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType, 2041 PipeTypeLocInfo> { 2042 public: 2043 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); } 2044 2045 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); } 2046 2047 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; } 2048 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; } 2049 2050 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 2051 setKWLoc(Loc); 2052 } 2053 2054 QualType getInnerType() const { return this->getTypePtr()->getElementType(); } 2055 }; 2056 } 2057 2058 #endif 2059