Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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::ArrayRef(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::ArrayRef(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::ArrayRef(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()->template_arguments().size();
  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()->template_arguments()[i],
  1650.                                getArgLocInfo(i));
  1651.   }
  1652.  
  1653.   SourceLocation getTemplateNameLoc() const {
  1654.     return getLocalData()->NameLoc;
  1655.   }
  1656.  
  1657.   void setTemplateNameLoc(SourceLocation Loc) {
  1658.     getLocalData()->NameLoc = Loc;
  1659.   }
  1660.  
  1661.   /// - Copy the location information from the given info.
  1662.   void copy(TemplateSpecializationTypeLoc Loc) {
  1663.     unsigned size = getFullDataSize();
  1664.     assert(size == Loc.getFullDataSize());
  1665.  
  1666.     // We're potentially copying Expr references here.  We don't
  1667.     // bother retaining them because TypeSourceInfos live forever, so
  1668.     // as long as the Expr was retained when originally written into
  1669.     // the TypeLoc, we're okay.
  1670.     memcpy(Data, Loc.Data, size);
  1671.   }
  1672.  
  1673.   SourceRange getLocalSourceRange() const {
  1674.     if (getTemplateKeywordLoc().isValid())
  1675.       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
  1676.     else
  1677.       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
  1678.   }
  1679.  
  1680.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  1681.     setTemplateKeywordLoc(Loc);
  1682.     setTemplateNameLoc(Loc);
  1683.     setLAngleLoc(Loc);
  1684.     setRAngleLoc(Loc);
  1685.     initializeArgLocs(Context, getTypePtr()->template_arguments(),
  1686.                       getArgInfos(), Loc);
  1687.   }
  1688.  
  1689.   static void initializeArgLocs(ASTContext &Context,
  1690.                                 ArrayRef<TemplateArgument> Args,
  1691.                                 TemplateArgumentLocInfo *ArgInfos,
  1692.                                 SourceLocation Loc);
  1693.  
  1694.   unsigned getExtraLocalDataSize() const {
  1695.     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
  1696.   }
  1697.  
  1698.   unsigned getExtraLocalDataAlignment() const {
  1699.     return alignof(TemplateArgumentLocInfo);
  1700.   }
  1701.  
  1702. private:
  1703.   TemplateArgumentLocInfo *getArgInfos() const {
  1704.     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
  1705.   }
  1706. };
  1707.  
  1708. struct DependentAddressSpaceLocInfo {
  1709.   Expr *ExprOperand;
  1710.   SourceRange OperandParens;
  1711.   SourceLocation AttrLoc;
  1712. };
  1713.  
  1714. class DependentAddressSpaceTypeLoc
  1715.     : public ConcreteTypeLoc<UnqualTypeLoc,
  1716.                              DependentAddressSpaceTypeLoc,
  1717.                              DependentAddressSpaceType,
  1718.                              DependentAddressSpaceLocInfo> {
  1719. public:
  1720.   /// The location of the attribute name, i.e.
  1721.   ///    int * __attribute__((address_space(11)))
  1722.   ///                         ^~~~~~~~~~~~~
  1723.   SourceLocation getAttrNameLoc() const {
  1724.     return getLocalData()->AttrLoc;
  1725.   }
  1726.   void setAttrNameLoc(SourceLocation loc) {
  1727.     getLocalData()->AttrLoc = loc;
  1728.   }
  1729.  
  1730.   /// The attribute's expression operand, if it has one.
  1731.   ///    int * __attribute__((address_space(11)))
  1732.   ///                                       ^~
  1733.   Expr *getAttrExprOperand() const {
  1734.     return getLocalData()->ExprOperand;
  1735.   }
  1736.   void setAttrExprOperand(Expr *e) {
  1737.     getLocalData()->ExprOperand = e;
  1738.   }
  1739.  
  1740.   /// The location of the parentheses around the operand, if there is
  1741.   /// an operand.
  1742.   ///    int * __attribute__((address_space(11)))
  1743.   ///                                      ^  ^
  1744.   SourceRange getAttrOperandParensRange() const {
  1745.     return getLocalData()->OperandParens;
  1746.   }
  1747.   void setAttrOperandParensRange(SourceRange range) {
  1748.     getLocalData()->OperandParens = range;
  1749.   }
  1750.  
  1751.   SourceRange getLocalSourceRange() const {
  1752.     SourceRange range(getAttrNameLoc());
  1753.     range.setEnd(getAttrOperandParensRange().getEnd());
  1754.     return range;
  1755.   }
  1756.  
  1757.   ///  Returns the type before the address space attribute application
  1758.   ///  area.
  1759.   ///    int * __attribute__((address_space(11))) *
  1760.   ///    ^   ^
  1761.   QualType getInnerType() const {
  1762.     return this->getTypePtr()->getPointeeType();
  1763.   }
  1764.  
  1765.   TypeLoc getPointeeTypeLoc() const {
  1766.     return this->getInnerTypeLoc();
  1767.   }
  1768.  
  1769.   void initializeLocal(ASTContext &Context, SourceLocation loc) {
  1770.     setAttrNameLoc(loc);
  1771.     setAttrOperandParensRange(loc);
  1772.     setAttrOperandParensRange(SourceRange(loc));
  1773.     setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
  1774.   }
  1775. };
  1776.  
  1777. //===----------------------------------------------------------------------===//
  1778. //
  1779. //  All of these need proper implementations.
  1780. //
  1781. //===----------------------------------------------------------------------===//
  1782.  
  1783. // FIXME: size expression and attribute locations (or keyword if we
  1784. // ever fully support altivec syntax).
  1785. struct VectorTypeLocInfo {
  1786.   SourceLocation NameLoc;
  1787. };
  1788.  
  1789. class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
  1790.                                              VectorType, VectorTypeLocInfo> {
  1791. public:
  1792.   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
  1793.  
  1794.   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
  1795.  
  1796.   SourceRange getLocalSourceRange() const {
  1797.     return SourceRange(getNameLoc(), getNameLoc());
  1798.   }
  1799.  
  1800.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  1801.     setNameLoc(Loc);
  1802.   }
  1803.  
  1804.   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
  1805.  
  1806.   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
  1807. };
  1808.  
  1809. // FIXME: size expression and attribute locations (or keyword if we
  1810. // ever fully support altivec syntax).
  1811. class DependentVectorTypeLoc
  1812.     : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc,
  1813.                              DependentVectorType, VectorTypeLocInfo> {
  1814. public:
  1815.   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
  1816.  
  1817.   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
  1818.  
  1819.   SourceRange getLocalSourceRange() const {
  1820.     return SourceRange(getNameLoc(), getNameLoc());
  1821.   }
  1822.  
  1823.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  1824.     setNameLoc(Loc);
  1825.   }
  1826.  
  1827.   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
  1828.  
  1829.   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
  1830. };
  1831.  
  1832. // FIXME: size expression and attribute locations.
  1833. class ExtVectorTypeLoc
  1834.     : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc,
  1835.                                        ExtVectorType> {};
  1836.  
  1837. // FIXME: attribute locations.
  1838. // For some reason, this isn't a subtype of VectorType.
  1839. class DependentSizedExtVectorTypeLoc
  1840.     : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc,
  1841.                              DependentSizedExtVectorType, VectorTypeLocInfo> {
  1842. public:
  1843.   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
  1844.  
  1845.   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
  1846.  
  1847.   SourceRange getLocalSourceRange() const {
  1848.     return SourceRange(getNameLoc(), getNameLoc());
  1849.   }
  1850.  
  1851.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  1852.     setNameLoc(Loc);
  1853.   }
  1854.  
  1855.   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
  1856.  
  1857.   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
  1858. };
  1859.  
  1860. struct MatrixTypeLocInfo {
  1861.   SourceLocation AttrLoc;
  1862.   SourceRange OperandParens;
  1863.   Expr *RowOperand;
  1864.   Expr *ColumnOperand;
  1865. };
  1866.  
  1867. class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc,
  1868.                                              MatrixType, MatrixTypeLocInfo> {
  1869. public:
  1870.   /// The location of the attribute name, i.e.
  1871.   ///    float __attribute__((matrix_type(4, 2)))
  1872.   ///                         ^~~~~~~~~~~~~~~~~
  1873.   SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
  1874.   void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; }
  1875.  
  1876.   /// The attribute's row operand, if it has one.
  1877.   ///    float __attribute__((matrix_type(4, 2)))
  1878.   ///                                     ^
  1879.   Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; }
  1880.   void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; }
  1881.  
  1882.   /// The attribute's column operand, if it has one.
  1883.   ///    float __attribute__((matrix_type(4, 2)))
  1884.   ///                                        ^
  1885.   Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; }
  1886.   void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; }
  1887.  
  1888.   /// The location of the parentheses around the operand, if there is
  1889.   /// an operand.
  1890.   ///    float __attribute__((matrix_type(4, 2)))
  1891.   ///                                    ^    ^
  1892.   SourceRange getAttrOperandParensRange() const {
  1893.     return getLocalData()->OperandParens;
  1894.   }
  1895.   void setAttrOperandParensRange(SourceRange range) {
  1896.     getLocalData()->OperandParens = range;
  1897.   }
  1898.  
  1899.   SourceRange getLocalSourceRange() const {
  1900.     SourceRange range(getAttrNameLoc());
  1901.     range.setEnd(getAttrOperandParensRange().getEnd());
  1902.     return range;
  1903.   }
  1904.  
  1905.   void initializeLocal(ASTContext &Context, SourceLocation loc) {
  1906.     setAttrNameLoc(loc);
  1907.     setAttrOperandParensRange(loc);
  1908.     setAttrRowOperand(nullptr);
  1909.     setAttrColumnOperand(nullptr);
  1910.   }
  1911. };
  1912.  
  1913. class ConstantMatrixTypeLoc
  1914.     : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc,
  1915.                                        ConstantMatrixType> {};
  1916.  
  1917. class DependentSizedMatrixTypeLoc
  1918.     : public InheritingConcreteTypeLoc<MatrixTypeLoc,
  1919.                                        DependentSizedMatrixTypeLoc,
  1920.                                        DependentSizedMatrixType> {};
  1921.  
  1922. // FIXME: location of the '_Complex' keyword.
  1923. class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
  1924.                                                         ComplexTypeLoc,
  1925.                                                         ComplexType> {
  1926. };
  1927.  
  1928. struct TypeofLocInfo {
  1929.   SourceLocation TypeofLoc;
  1930.   SourceLocation LParenLoc;
  1931.   SourceLocation RParenLoc;
  1932. };
  1933.  
  1934. struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
  1935. };
  1936.  
  1937. struct TypeOfTypeLocInfo : public TypeofLocInfo {
  1938.   TypeSourceInfo *UnmodifiedTInfo;
  1939. };
  1940.  
  1941. template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
  1942. class TypeofLikeTypeLoc
  1943.   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
  1944. public:
  1945.   SourceLocation getTypeofLoc() const {
  1946.     return this->getLocalData()->TypeofLoc;
  1947.   }
  1948.  
  1949.   void setTypeofLoc(SourceLocation Loc) {
  1950.     this->getLocalData()->TypeofLoc = Loc;
  1951.   }
  1952.  
  1953.   SourceLocation getLParenLoc() const {
  1954.     return this->getLocalData()->LParenLoc;
  1955.   }
  1956.  
  1957.   void setLParenLoc(SourceLocation Loc) {
  1958.     this->getLocalData()->LParenLoc = Loc;
  1959.   }
  1960.  
  1961.   SourceLocation getRParenLoc() const {
  1962.     return this->getLocalData()->RParenLoc;
  1963.   }
  1964.  
  1965.   void setRParenLoc(SourceLocation Loc) {
  1966.     this->getLocalData()->RParenLoc = Loc;
  1967.   }
  1968.  
  1969.   SourceRange getParensRange() const {
  1970.     return SourceRange(getLParenLoc(), getRParenLoc());
  1971.   }
  1972.  
  1973.   void setParensRange(SourceRange range) {
  1974.       setLParenLoc(range.getBegin());
  1975.       setRParenLoc(range.getEnd());
  1976.   }
  1977.  
  1978.   SourceRange getLocalSourceRange() const {
  1979.     return SourceRange(getTypeofLoc(), getRParenLoc());
  1980.   }
  1981.  
  1982.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  1983.     setTypeofLoc(Loc);
  1984.     setLParenLoc(Loc);
  1985.     setRParenLoc(Loc);
  1986.   }
  1987. };
  1988.  
  1989. class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
  1990.                                                    TypeOfExprType,
  1991.                                                    TypeOfExprTypeLocInfo> {
  1992. public:
  1993.   Expr* getUnderlyingExpr() const {
  1994.     return getTypePtr()->getUnderlyingExpr();
  1995.   }
  1996.  
  1997.   // Reimplemented to account for GNU/C++ extension
  1998.   //     typeof unary-expression
  1999.   // where there are no parentheses.
  2000.   SourceRange getLocalSourceRange() const;
  2001. };
  2002.  
  2003. class TypeOfTypeLoc
  2004.   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
  2005. public:
  2006.   QualType getUnmodifiedType() const {
  2007.     return this->getTypePtr()->getUnmodifiedType();
  2008.   }
  2009.  
  2010.   TypeSourceInfo *getUnmodifiedTInfo() const {
  2011.     return this->getLocalData()->UnmodifiedTInfo;
  2012.   }
  2013.  
  2014.   void setUnmodifiedTInfo(TypeSourceInfo *TI) const {
  2015.     this->getLocalData()->UnmodifiedTInfo = TI;
  2016.   }
  2017.  
  2018.   void initializeLocal(ASTContext &Context, SourceLocation Loc);
  2019. };
  2020.  
  2021. // decltype(expression) abc;
  2022. // ~~~~~~~~                  DecltypeLoc
  2023. //                    ~      RParenLoc
  2024. // FIXME: add LParenLoc, it is tricky to support due to the limitation of
  2025. // annotated-decltype token.
  2026. struct DecltypeTypeLocInfo {
  2027.   SourceLocation DecltypeLoc;
  2028.   SourceLocation RParenLoc;
  2029. };
  2030. class DecltypeTypeLoc
  2031.     : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType,
  2032.                              DecltypeTypeLocInfo> {
  2033. public:
  2034.   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
  2035.  
  2036.   SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; }
  2037.   void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; }
  2038.  
  2039.   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
  2040.   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
  2041.  
  2042.   SourceRange getLocalSourceRange() const {
  2043.     return SourceRange(getDecltypeLoc(), getRParenLoc());
  2044.   }
  2045.  
  2046.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  2047.     setDecltypeLoc(Loc);
  2048.     setRParenLoc(Loc);
  2049.   }
  2050. };
  2051.  
  2052. struct UnaryTransformTypeLocInfo {
  2053.   // FIXME: While there's only one unary transform right now, future ones may
  2054.   // need different representations
  2055.   SourceLocation KWLoc, LParenLoc, RParenLoc;
  2056.   TypeSourceInfo *UnderlyingTInfo;
  2057. };
  2058.  
  2059. class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
  2060.                                                     UnaryTransformTypeLoc,
  2061.                                                     UnaryTransformType,
  2062.                                                     UnaryTransformTypeLocInfo> {
  2063. public:
  2064.   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
  2065.   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
  2066.  
  2067.   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
  2068.   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
  2069.  
  2070.   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
  2071.   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
  2072.  
  2073.   TypeSourceInfo* getUnderlyingTInfo() const {
  2074.     return getLocalData()->UnderlyingTInfo;
  2075.   }
  2076.  
  2077.   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
  2078.     getLocalData()->UnderlyingTInfo = TInfo;
  2079.   }
  2080.  
  2081.   SourceRange getLocalSourceRange() const {
  2082.     return SourceRange(getKWLoc(), getRParenLoc());
  2083.   }
  2084.  
  2085.   SourceRange getParensRange() const {
  2086.     return SourceRange(getLParenLoc(), getRParenLoc());
  2087.   }
  2088.  
  2089.   void setParensRange(SourceRange Range) {
  2090.     setLParenLoc(Range.getBegin());
  2091.     setRParenLoc(Range.getEnd());
  2092.   }
  2093.  
  2094.   void initializeLocal(ASTContext &Context, SourceLocation Loc);
  2095. };
  2096.  
  2097. class DeducedTypeLoc
  2098.     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
  2099.                                        DeducedType> {};
  2100.  
  2101. struct AutoTypeLocInfo : TypeSpecLocInfo {
  2102.   NestedNameSpecifierLoc NestedNameSpec;
  2103.   SourceLocation TemplateKWLoc;
  2104.   SourceLocation ConceptNameLoc;
  2105.   NamedDecl *FoundDecl;
  2106.   SourceLocation LAngleLoc;
  2107.   SourceLocation RAngleLoc;
  2108.  
  2109.   // For decltype(auto).
  2110.   SourceLocation RParenLoc;
  2111.  
  2112.   // Followed by a TemplateArgumentLocInfo[]
  2113. };
  2114.  
  2115. class AutoTypeLoc
  2116.     : public ConcreteTypeLoc<DeducedTypeLoc,
  2117.                              AutoTypeLoc,
  2118.                              AutoType,
  2119.                              AutoTypeLocInfo> {
  2120. public:
  2121.   AutoTypeKeyword getAutoKeyword() const {
  2122.     return getTypePtr()->getKeyword();
  2123.   }
  2124.  
  2125.   bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
  2126.   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
  2127.   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
  2128.  
  2129.   bool isConstrained() const {
  2130.     return getTypePtr()->isConstrained();
  2131.   }
  2132.  
  2133.   const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
  2134.     return getLocalData()->NestedNameSpec;
  2135.   }
  2136.  
  2137.   void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
  2138.     getLocalData()->NestedNameSpec = NNS;
  2139.   }
  2140.  
  2141.   SourceLocation getTemplateKWLoc() const {
  2142.     return getLocalData()->TemplateKWLoc;
  2143.   }
  2144.  
  2145.   void setTemplateKWLoc(SourceLocation Loc) {
  2146.     getLocalData()->TemplateKWLoc = Loc;
  2147.   }
  2148.  
  2149.   SourceLocation getConceptNameLoc() const {
  2150.     return getLocalData()->ConceptNameLoc;
  2151.   }
  2152.  
  2153.   void setConceptNameLoc(SourceLocation Loc) {
  2154.     getLocalData()->ConceptNameLoc = Loc;
  2155.   }
  2156.  
  2157.   NamedDecl *getFoundDecl() const {
  2158.     return getLocalData()->FoundDecl;
  2159.   }
  2160.  
  2161.   void setFoundDecl(NamedDecl *D) {
  2162.     getLocalData()->FoundDecl = D;
  2163.   }
  2164.  
  2165.   ConceptDecl *getNamedConcept() const {
  2166.     return getTypePtr()->getTypeConstraintConcept();
  2167.   }
  2168.  
  2169.   DeclarationNameInfo getConceptNameInfo() const;
  2170.  
  2171.   bool hasExplicitTemplateArgs() const {
  2172.     return getLocalData()->LAngleLoc.isValid();
  2173.   }
  2174.  
  2175.   SourceLocation getLAngleLoc() const {
  2176.     return this->getLocalData()->LAngleLoc;
  2177.   }
  2178.  
  2179.   void setLAngleLoc(SourceLocation Loc) {
  2180.     this->getLocalData()->LAngleLoc = Loc;
  2181.   }
  2182.  
  2183.   SourceLocation getRAngleLoc() const {
  2184.     return this->getLocalData()->RAngleLoc;
  2185.   }
  2186.  
  2187.   void setRAngleLoc(SourceLocation Loc) {
  2188.     this->getLocalData()->RAngleLoc = Loc;
  2189.   }
  2190.  
  2191.   unsigned getNumArgs() const {
  2192.     return getTypePtr()->getTypeConstraintArguments().size();
  2193.   }
  2194.  
  2195.   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
  2196.     getArgInfos()[i] = AI;
  2197.   }
  2198.  
  2199.   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
  2200.     return getArgInfos()[i];
  2201.   }
  2202.  
  2203.   TemplateArgumentLoc getArgLoc(unsigned i) const {
  2204.     return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
  2205.                                getArgLocInfo(i));
  2206.   }
  2207.  
  2208.   SourceRange getLocalSourceRange() const {
  2209.     return {isConstrained()
  2210.                 ? (getNestedNameSpecifierLoc()
  2211.                        ? getNestedNameSpecifierLoc().getBeginLoc()
  2212.                        : (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
  2213.                                                        : getConceptNameLoc()))
  2214.                 : getNameLoc(),
  2215.             isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
  2216.   }
  2217.  
  2218.   void copy(AutoTypeLoc Loc) {
  2219.     unsigned size = getFullDataSize();
  2220.     assert(size == Loc.getFullDataSize());
  2221.     memcpy(Data, Loc.Data, size);
  2222.   }
  2223.  
  2224.   void initializeLocal(ASTContext &Context, SourceLocation Loc);
  2225.  
  2226.   unsigned getExtraLocalDataSize() const {
  2227.     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
  2228.   }
  2229.  
  2230.   unsigned getExtraLocalDataAlignment() const {
  2231.     return alignof(TemplateArgumentLocInfo);
  2232.   }
  2233.  
  2234. private:
  2235.   TemplateArgumentLocInfo *getArgInfos() const {
  2236.     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
  2237.   }
  2238. };
  2239.  
  2240. class DeducedTemplateSpecializationTypeLoc
  2241.     : public InheritingConcreteTypeLoc<DeducedTypeLoc,
  2242.                                        DeducedTemplateSpecializationTypeLoc,
  2243.                                        DeducedTemplateSpecializationType> {
  2244. public:
  2245.   SourceLocation getTemplateNameLoc() const {
  2246.     return getNameLoc();
  2247.   }
  2248.  
  2249.   void setTemplateNameLoc(SourceLocation Loc) {
  2250.     setNameLoc(Loc);
  2251.   }
  2252. };
  2253.  
  2254. struct ElaboratedLocInfo {
  2255.   SourceLocation ElaboratedKWLoc;
  2256.  
  2257.   /// Data associated with the nested-name-specifier location.
  2258.   void *QualifierData;
  2259. };
  2260.  
  2261. class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
  2262.                                                  ElaboratedTypeLoc,
  2263.                                                  ElaboratedType,
  2264.                                                  ElaboratedLocInfo> {
  2265. public:
  2266.   SourceLocation getElaboratedKeywordLoc() const {
  2267.     return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation();
  2268.   }
  2269.  
  2270.   void setElaboratedKeywordLoc(SourceLocation Loc) {
  2271.     if (isEmpty()) {
  2272.       assert(Loc.isInvalid());
  2273.       return;
  2274.     }
  2275.     getLocalData()->ElaboratedKWLoc = Loc;
  2276.   }
  2277.  
  2278.   NestedNameSpecifierLoc getQualifierLoc() const {
  2279.     return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
  2280.                                                getLocalData()->QualifierData)
  2281.                       : NestedNameSpecifierLoc();
  2282.   }
  2283.  
  2284.   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
  2285.     assert(QualifierLoc.getNestedNameSpecifier() ==
  2286.                getTypePtr()->getQualifier() &&
  2287.            "Inconsistent nested-name-specifier pointer");
  2288.     if (isEmpty()) {
  2289.       assert(!QualifierLoc.hasQualifier());
  2290.       return;
  2291.     }
  2292.     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
  2293.   }
  2294.  
  2295.   SourceRange getLocalSourceRange() const {
  2296.     if (getElaboratedKeywordLoc().isValid())
  2297.       if (getQualifierLoc())
  2298.         return SourceRange(getElaboratedKeywordLoc(),
  2299.                            getQualifierLoc().getEndLoc());
  2300.       else
  2301.         return SourceRange(getElaboratedKeywordLoc());
  2302.     else
  2303.       return getQualifierLoc().getSourceRange();
  2304.   }
  2305.  
  2306.   void initializeLocal(ASTContext &Context, SourceLocation Loc);
  2307.  
  2308.   TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); }
  2309.  
  2310.   QualType getInnerType() const { return getTypePtr()->getNamedType(); }
  2311.  
  2312.   bool isEmpty() const {
  2313.     return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::ETK_None &&
  2314.            !getTypePtr()->getQualifier();
  2315.   }
  2316.  
  2317.   unsigned getLocalDataAlignment() const {
  2318.     // FIXME: We want to return 1 here in the empty case, but
  2319.     // there are bugs in how alignment is handled in TypeLocs
  2320.     // that prevent this from working.
  2321.     return ConcreteTypeLoc::getLocalDataAlignment();
  2322.   }
  2323.  
  2324.   unsigned getLocalDataSize() const {
  2325.     return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0;
  2326.   }
  2327.  
  2328.   void copy(ElaboratedTypeLoc Loc) {
  2329.     unsigned size = getFullDataSize();
  2330.     assert(size == Loc.getFullDataSize());
  2331.     memcpy(Data, Loc.Data, size);
  2332.   }
  2333. };
  2334.  
  2335. // This is exactly the structure of an ElaboratedTypeLoc whose inner
  2336. // type is some sort of TypeDeclTypeLoc.
  2337. struct DependentNameLocInfo : ElaboratedLocInfo {
  2338.   SourceLocation NameLoc;
  2339. };
  2340.  
  2341. class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
  2342.                                                     DependentNameTypeLoc,
  2343.                                                     DependentNameType,
  2344.                                                     DependentNameLocInfo> {
  2345. public:
  2346.   SourceLocation getElaboratedKeywordLoc() const {
  2347.     return this->getLocalData()->ElaboratedKWLoc;
  2348.   }
  2349.  
  2350.   void setElaboratedKeywordLoc(SourceLocation Loc) {
  2351.     this->getLocalData()->ElaboratedKWLoc = Loc;
  2352.   }
  2353.  
  2354.   NestedNameSpecifierLoc getQualifierLoc() const {
  2355.     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
  2356.                                   getLocalData()->QualifierData);
  2357.   }
  2358.  
  2359.   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
  2360.     assert(QualifierLoc.getNestedNameSpecifier()
  2361.                                             == getTypePtr()->getQualifier() &&
  2362.            "Inconsistent nested-name-specifier pointer");
  2363.     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
  2364.   }
  2365.  
  2366.   SourceLocation getNameLoc() const {
  2367.     return this->getLocalData()->NameLoc;
  2368.   }
  2369.  
  2370.   void setNameLoc(SourceLocation Loc) {
  2371.     this->getLocalData()->NameLoc = Loc;
  2372.   }
  2373.  
  2374.   SourceRange getLocalSourceRange() const {
  2375.     if (getElaboratedKeywordLoc().isValid())
  2376.       return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
  2377.     else
  2378.       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
  2379.   }
  2380.  
  2381.   void copy(DependentNameTypeLoc Loc) {
  2382.     unsigned size = getFullDataSize();
  2383.     assert(size == Loc.getFullDataSize());
  2384.     memcpy(Data, Loc.Data, size);
  2385.   }
  2386.  
  2387.   void initializeLocal(ASTContext &Context, SourceLocation Loc);
  2388. };
  2389.  
  2390. struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
  2391.   SourceLocation TemplateKWLoc;
  2392.   SourceLocation LAngleLoc;
  2393.   SourceLocation RAngleLoc;
  2394.   // followed by a TemplateArgumentLocInfo[]
  2395. };
  2396.  
  2397. class DependentTemplateSpecializationTypeLoc :
  2398.     public ConcreteTypeLoc<UnqualTypeLoc,
  2399.                            DependentTemplateSpecializationTypeLoc,
  2400.                            DependentTemplateSpecializationType,
  2401.                            DependentTemplateSpecializationLocInfo> {
  2402. public:
  2403.   SourceLocation getElaboratedKeywordLoc() const {
  2404.     return this->getLocalData()->ElaboratedKWLoc;
  2405.   }
  2406.  
  2407.   void setElaboratedKeywordLoc(SourceLocation Loc) {
  2408.     this->getLocalData()->ElaboratedKWLoc = Loc;
  2409.   }
  2410.  
  2411.   NestedNameSpecifierLoc getQualifierLoc() const {
  2412.     if (!getLocalData()->QualifierData)
  2413.       return NestedNameSpecifierLoc();
  2414.  
  2415.     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
  2416.                                   getLocalData()->QualifierData);
  2417.   }
  2418.  
  2419.   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
  2420.     if (!QualifierLoc) {
  2421.       // Even if we have a nested-name-specifier in the dependent
  2422.       // template specialization type, we won't record the nested-name-specifier
  2423.       // location information when this type-source location information is
  2424.       // part of a nested-name-specifier.
  2425.       getLocalData()->QualifierData = nullptr;
  2426.       return;
  2427.     }
  2428.  
  2429.     assert(QualifierLoc.getNestedNameSpecifier()
  2430.                                         == getTypePtr()->getQualifier() &&
  2431.            "Inconsistent nested-name-specifier pointer");
  2432.     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
  2433.   }
  2434.  
  2435.   SourceLocation getTemplateKeywordLoc() const {
  2436.     return getLocalData()->TemplateKWLoc;
  2437.   }
  2438.  
  2439.   void setTemplateKeywordLoc(SourceLocation Loc) {
  2440.     getLocalData()->TemplateKWLoc = Loc;
  2441.   }
  2442.  
  2443.   SourceLocation getTemplateNameLoc() const {
  2444.     return this->getLocalData()->NameLoc;
  2445.   }
  2446.  
  2447.   void setTemplateNameLoc(SourceLocation Loc) {
  2448.     this->getLocalData()->NameLoc = Loc;
  2449.   }
  2450.  
  2451.   SourceLocation getLAngleLoc() const {
  2452.     return this->getLocalData()->LAngleLoc;
  2453.   }
  2454.  
  2455.   void setLAngleLoc(SourceLocation Loc) {
  2456.     this->getLocalData()->LAngleLoc = Loc;
  2457.   }
  2458.  
  2459.   SourceLocation getRAngleLoc() const {
  2460.     return this->getLocalData()->RAngleLoc;
  2461.   }
  2462.  
  2463.   void setRAngleLoc(SourceLocation Loc) {
  2464.     this->getLocalData()->RAngleLoc = Loc;
  2465.   }
  2466.  
  2467.   unsigned getNumArgs() const {
  2468.     return getTypePtr()->template_arguments().size();
  2469.   }
  2470.  
  2471.   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
  2472.     getArgInfos()[i] = AI;
  2473.   }
  2474.  
  2475.   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
  2476.     return getArgInfos()[i];
  2477.   }
  2478.  
  2479.   TemplateArgumentLoc getArgLoc(unsigned i) const {
  2480.     return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
  2481.                                getArgLocInfo(i));
  2482.   }
  2483.  
  2484.   SourceRange getLocalSourceRange() const {
  2485.     if (getElaboratedKeywordLoc().isValid())
  2486.       return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
  2487.     else if (getQualifierLoc())
  2488.       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
  2489.     else if (getTemplateKeywordLoc().isValid())
  2490.       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
  2491.     else
  2492.       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
  2493.   }
  2494.  
  2495.   void copy(DependentTemplateSpecializationTypeLoc Loc) {
  2496.     unsigned size = getFullDataSize();
  2497.     assert(size == Loc.getFullDataSize());
  2498.     memcpy(Data, Loc.Data, size);
  2499.   }
  2500.  
  2501.   void initializeLocal(ASTContext &Context, SourceLocation Loc);
  2502.  
  2503.   unsigned getExtraLocalDataSize() const {
  2504.     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
  2505.   }
  2506.  
  2507.   unsigned getExtraLocalDataAlignment() const {
  2508.     return alignof(TemplateArgumentLocInfo);
  2509.   }
  2510.  
  2511. private:
  2512.   TemplateArgumentLocInfo *getArgInfos() const {
  2513.     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
  2514.   }
  2515. };
  2516.  
  2517. struct PackExpansionTypeLocInfo {
  2518.   SourceLocation EllipsisLoc;
  2519. };
  2520.  
  2521. class PackExpansionTypeLoc
  2522.   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
  2523.                            PackExpansionType, PackExpansionTypeLocInfo> {
  2524. public:
  2525.   SourceLocation getEllipsisLoc() const {
  2526.     return this->getLocalData()->EllipsisLoc;
  2527.   }
  2528.  
  2529.   void setEllipsisLoc(SourceLocation Loc) {
  2530.     this->getLocalData()->EllipsisLoc = Loc;
  2531.   }
  2532.  
  2533.   SourceRange getLocalSourceRange() const {
  2534.     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
  2535.   }
  2536.  
  2537.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  2538.     setEllipsisLoc(Loc);
  2539.   }
  2540.  
  2541.   TypeLoc getPatternLoc() const {
  2542.     return getInnerTypeLoc();
  2543.   }
  2544.  
  2545.   QualType getInnerType() const {
  2546.     return this->getTypePtr()->getPattern();
  2547.   }
  2548. };
  2549.  
  2550. struct AtomicTypeLocInfo {
  2551.   SourceLocation KWLoc, LParenLoc, RParenLoc;
  2552. };
  2553.  
  2554. class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
  2555.                                              AtomicType, AtomicTypeLocInfo> {
  2556. public:
  2557.   TypeLoc getValueLoc() const {
  2558.     return this->getInnerTypeLoc();
  2559.   }
  2560.  
  2561.   SourceRange getLocalSourceRange() const {
  2562.     return SourceRange(getKWLoc(), getRParenLoc());
  2563.   }
  2564.  
  2565.   SourceLocation getKWLoc() const {
  2566.     return this->getLocalData()->KWLoc;
  2567.   }
  2568.  
  2569.   void setKWLoc(SourceLocation Loc) {
  2570.     this->getLocalData()->KWLoc = Loc;
  2571.   }
  2572.  
  2573.   SourceLocation getLParenLoc() const {
  2574.     return this->getLocalData()->LParenLoc;
  2575.   }
  2576.  
  2577.   void setLParenLoc(SourceLocation Loc) {
  2578.     this->getLocalData()->LParenLoc = Loc;
  2579.   }
  2580.  
  2581.   SourceLocation getRParenLoc() const {
  2582.     return this->getLocalData()->RParenLoc;
  2583.   }
  2584.  
  2585.   void setRParenLoc(SourceLocation Loc) {
  2586.     this->getLocalData()->RParenLoc = Loc;
  2587.   }
  2588.  
  2589.   SourceRange getParensRange() const {
  2590.     return SourceRange(getLParenLoc(), getRParenLoc());
  2591.   }
  2592.  
  2593.   void setParensRange(SourceRange Range) {
  2594.     setLParenLoc(Range.getBegin());
  2595.     setRParenLoc(Range.getEnd());
  2596.   }
  2597.  
  2598.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  2599.     setKWLoc(Loc);
  2600.     setLParenLoc(Loc);
  2601.     setRParenLoc(Loc);
  2602.   }
  2603.  
  2604.   QualType getInnerType() const {
  2605.     return this->getTypePtr()->getValueType();
  2606.   }
  2607. };
  2608.  
  2609. struct PipeTypeLocInfo {
  2610.   SourceLocation KWLoc;
  2611. };
  2612.  
  2613. class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
  2614.                                            PipeTypeLocInfo> {
  2615. public:
  2616.   TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
  2617.  
  2618.   SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
  2619.  
  2620.   SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
  2621.   void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
  2622.  
  2623.   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
  2624.     setKWLoc(Loc);
  2625.   }
  2626.  
  2627.   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
  2628. };
  2629.  
  2630. template <typename T>
  2631. inline T TypeLoc::getAsAdjusted() const {
  2632.   TypeLoc Cur = *this;
  2633.   while (!T::isKind(Cur)) {
  2634.     if (auto PTL = Cur.getAs<ParenTypeLoc>())
  2635.       Cur = PTL.getInnerLoc();
  2636.     else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
  2637.       Cur = ATL.getModifiedLoc();
  2638.     else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
  2639.       Cur = ATL.getWrappedLoc();
  2640.     else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
  2641.       Cur = ETL.getNamedTypeLoc();
  2642.     else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
  2643.       Cur = ATL.getOriginalLoc();
  2644.     else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
  2645.       Cur = MQL.getInnerLoc();
  2646.     else
  2647.       break;
  2648.   }
  2649.   return Cur.getAs<T>();
  2650. }
  2651. class BitIntTypeLoc final
  2652.     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
  2653.                                        BitIntType> {};
  2654. class DependentBitIntTypeLoc final
  2655.     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
  2656.                                        DependentBitIntType> {};
  2657.  
  2658. class ObjCProtocolLoc {
  2659.   ObjCProtocolDecl *Protocol = nullptr;
  2660.   SourceLocation Loc = SourceLocation();
  2661.  
  2662. public:
  2663.   ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc)
  2664.       : Protocol(protocol), Loc(loc) {}
  2665.   ObjCProtocolDecl *getProtocol() const { return Protocol; }
  2666.   SourceLocation getLocation() const { return Loc; }
  2667.  
  2668.   /// The source range is just the protocol name.
  2669.   SourceRange getSourceRange() const LLVM_READONLY {
  2670.     return SourceRange(Loc, Loc);
  2671.   }
  2672. };
  2673.  
  2674. } // namespace clang
  2675.  
  2676. #endif // LLVM_CLANG_AST_TYPELOC_H
  2677.