Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:46

0001 //===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file
0010 /// Defines the clang::TypeLoc interface and its subclasses.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_AST_TYPELOC_H
0015 #define LLVM_CLANG_AST_TYPELOC_H
0016 
0017 #include "clang/AST/ASTConcept.h"
0018 #include "clang/AST/DeclarationName.h"
0019 #include "clang/AST/NestedNameSpecifier.h"
0020 #include "clang/AST/TemplateBase.h"
0021 #include "clang/AST/Type.h"
0022 #include "clang/Basic/LLVM.h"
0023 #include "clang/Basic/SourceLocation.h"
0024 #include "clang/Basic/Specifiers.h"
0025 #include "llvm/ADT/ArrayRef.h"
0026 #include "llvm/Support/Casting.h"
0027 #include "llvm/Support/Compiler.h"
0028 #include "llvm/Support/MathExtras.h"
0029 #include <algorithm>
0030 #include <cassert>
0031 #include <cstdint>
0032 #include <cstring>
0033 
0034 namespace clang {
0035 
0036 class Attr;
0037 class ASTContext;
0038 class CXXRecordDecl;
0039 class ConceptDecl;
0040 class Expr;
0041 class ObjCInterfaceDecl;
0042 class ObjCProtocolDecl;
0043 class ObjCTypeParamDecl;
0044 class ParmVarDecl;
0045 class TemplateTypeParmDecl;
0046 class UnqualTypeLoc;
0047 class UnresolvedUsingTypenameDecl;
0048 
0049 // Predeclare all the type nodes.
0050 #define ABSTRACT_TYPELOC(Class, Base)
0051 #define TYPELOC(Class, Base) \
0052   class Class##TypeLoc;
0053 #include "clang/AST/TypeLocNodes.def"
0054 
0055 /// Base wrapper for a particular "section" of type source info.
0056 ///
0057 /// A client should use the TypeLoc subclasses through castAs()/getAs()
0058 /// in order to get at the actual information.
0059 class TypeLoc {
0060 protected:
0061   // The correctness of this relies on the property that, for Type *Ty,
0062   //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
0063   const void *Ty = nullptr;
0064   void *Data = nullptr;
0065 
0066 public:
0067   TypeLoc() = default;
0068   TypeLoc(QualType ty, void *opaqueData)
0069       : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
0070   TypeLoc(const Type *ty, void *opaqueData)
0071       : Ty(ty), Data(opaqueData) {}
0072 
0073   /// Convert to the specified TypeLoc type, asserting that this TypeLoc
0074   /// is of the desired type.
0075   ///
0076   /// \pre T::isKind(*this)
0077   template<typename T>
0078   T castAs() const {
0079     assert(T::isKind(*this));
0080     T t;
0081     TypeLoc& tl = t;
0082     tl = *this;
0083     return t;
0084   }
0085 
0086   /// Convert to the specified TypeLoc type, returning a null TypeLoc if
0087   /// this TypeLoc is not of the desired type.
0088   template<typename T>
0089   T getAs() const {
0090     if (!T::isKind(*this))
0091       return {};
0092     T t;
0093     TypeLoc& tl = t;
0094     tl = *this;
0095     return t;
0096   }
0097 
0098   /// Convert to the specified TypeLoc type, returning a null TypeLoc if
0099   /// this TypeLoc is not of the desired type. It will consider type
0100   /// adjustments from a type that was written as a T to another type that is
0101   /// still canonically a T (ignores parens, attributes, elaborated types, etc).
0102   template <typename T>
0103   T getAsAdjusted() const;
0104 
0105   /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
0106   /// except it also defines a Qualified enum that corresponds to the
0107   /// QualifiedLoc class.
0108   enum TypeLocClass {
0109 #define ABSTRACT_TYPE(Class, Base)
0110 #define TYPE(Class, Base) \
0111     Class = Type::Class,
0112 #include "clang/AST/TypeNodes.inc"
0113     Qualified
0114   };
0115 
0116   TypeLocClass getTypeLocClass() const {
0117     if (getType().hasLocalQualifiers()) return Qualified;
0118     return (TypeLocClass) getType()->getTypeClass();
0119   }
0120 
0121   bool isNull() const { return !Ty; }
0122   explicit operator bool() const { return Ty; }
0123 
0124   /// Returns the size of type source info data block for the given type.
0125   static unsigned getFullDataSizeForType(QualType Ty);
0126 
0127   /// Returns the alignment of type source info data block for
0128   /// the given type.
0129   static unsigned getLocalAlignmentForType(QualType Ty);
0130 
0131   /// Get the type for which this source info wrapper provides
0132   /// information.
0133   QualType getType() const {
0134     return QualType::getFromOpaquePtr(Ty);
0135   }
0136 
0137   const Type *getTypePtr() const {
0138     return QualType::getFromOpaquePtr(Ty).getTypePtr();
0139   }
0140 
0141   /// Get the pointer where source information is stored.
0142   void *getOpaqueData() const {
0143     return Data;
0144   }
0145 
0146   /// Get the begin source location.
0147   SourceLocation getBeginLoc() const;
0148 
0149   /// Get the end source location.
0150   SourceLocation getEndLoc() const;
0151 
0152   /// Get the full source range.
0153   SourceRange getSourceRange() const LLVM_READONLY {
0154     return SourceRange(getBeginLoc(), getEndLoc());
0155   }
0156 
0157 
0158   /// Get the local source range.
0159   SourceRange getLocalSourceRange() const {
0160     return getLocalSourceRangeImpl(*this);
0161   }
0162 
0163   /// Returns the size of the type source info data block.
0164   unsigned getFullDataSize() const {
0165     return getFullDataSizeForType(getType());
0166   }
0167 
0168   /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
0169   /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
0170   TypeLoc getNextTypeLoc() const {
0171     return getNextTypeLocImpl(*this);
0172   }
0173 
0174   /// Skips past any qualifiers, if this is qualified.
0175   UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
0176 
0177   TypeLoc IgnoreParens() const;
0178 
0179   /// Find a type with the location of an explicit type qualifier.
0180   ///
0181   /// The result, if non-null, will be one of:
0182   ///   QualifiedTypeLoc
0183   ///   AtomicTypeLoc
0184   ///   AttributedTypeLoc, for those type attributes that behave as qualifiers
0185   TypeLoc findExplicitQualifierLoc() const;
0186 
0187   /// Get the typeloc of an AutoType whose type will be deduced for a variable
0188   /// with an initializer of this type. This looks through declarators like
0189   /// pointer types, but not through decltype or typedefs.
0190   AutoTypeLoc getContainedAutoTypeLoc() const;
0191 
0192   /// Get the SourceLocation of the template keyword (if any).
0193   SourceLocation getTemplateKeywordLoc() const;
0194 
0195   /// Initializes this to state that every location in this
0196   /// type is the given location.
0197   ///
0198   /// This method exists to provide a simple transition for code that
0199   /// relies on location-less types.
0200   void initialize(ASTContext &Context, SourceLocation Loc) const {
0201     initializeImpl(Context, *this, Loc);
0202   }
0203 
0204   /// Initializes this by copying its information from another
0205   /// TypeLoc of the same type.
0206   void initializeFullCopy(TypeLoc Other) {
0207     assert(getType() == Other.getType());
0208     copy(Other);
0209   }
0210 
0211   /// Initializes this by copying its information from another
0212   /// TypeLoc of the same type.  The given size must be the full data
0213   /// size.
0214   void initializeFullCopy(TypeLoc Other, unsigned Size) {
0215     assert(getType() == Other.getType());
0216     assert(getFullDataSize() == Size);
0217     copy(Other);
0218   }
0219 
0220   /// Copies the other type loc into this one.
0221   void copy(TypeLoc other);
0222 
0223   friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
0224     return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
0225   }
0226 
0227   friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
0228     return !(LHS == RHS);
0229   }
0230 
0231   /// Find the location of the nullability specifier (__nonnull,
0232   /// __nullable, or __null_unspecifier), if there is one.
0233   SourceLocation findNullabilityLoc() const;
0234 
0235   void dump() const;
0236   void dump(llvm::raw_ostream &, const ASTContext &) const;
0237 
0238 private:
0239   static bool isKind(const TypeLoc&) {
0240     return true;
0241   }
0242 
0243   static void initializeImpl(ASTContext &Context, TypeLoc TL,
0244                              SourceLocation Loc);
0245   static TypeLoc getNextTypeLocImpl(TypeLoc TL);
0246   static TypeLoc IgnoreParensImpl(TypeLoc TL);
0247   static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
0248 };
0249 
0250 inline TypeSourceInfo::TypeSourceInfo(QualType ty, size_t DataSize) : Ty(ty) {
0251   // Init data attached to the object. See getTypeLoc.
0252   memset(static_cast<void *>(this + 1), 0, DataSize);
0253 }
0254 
0255 /// Return the TypeLoc for a type source info.
0256 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
0257   // TODO: is this alignment already sufficient?
0258   return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
0259 }
0260 
0261 /// Wrapper of type source information for a type with
0262 /// no direct qualifiers.
0263 class UnqualTypeLoc : public TypeLoc {
0264 public:
0265   UnqualTypeLoc() = default;
0266   UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
0267 
0268   const Type *getTypePtr() const {
0269     return reinterpret_cast<const Type*>(Ty);
0270   }
0271 
0272   TypeLocClass getTypeLocClass() const {
0273     return (TypeLocClass) getTypePtr()->getTypeClass();
0274   }
0275 
0276 private:
0277   friend class TypeLoc;
0278 
0279   static bool isKind(const TypeLoc &TL) {
0280     return !TL.getType().hasLocalQualifiers();
0281   }
0282 };
0283 
0284 /// Wrapper of type source information for a type with
0285 /// non-trivial direct qualifiers.
0286 ///
0287 /// Currently, we intentionally do not provide source location for
0288 /// type qualifiers.
0289 class QualifiedTypeLoc : public TypeLoc {
0290 public:
0291   SourceRange getLocalSourceRange() const { return {}; }
0292 
0293   UnqualTypeLoc getUnqualifiedLoc() const {
0294     unsigned align =
0295         TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
0296     auto dataInt = reinterpret_cast<uintptr_t>(Data);
0297     dataInt = llvm::alignTo(dataInt, align);
0298     return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
0299   }
0300 
0301   /// Initializes the local data of this type source info block to
0302   /// provide no information.
0303   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
0304     // do nothing
0305   }
0306 
0307   void copyLocal(TypeLoc other) {
0308     // do nothing
0309   }
0310 
0311   TypeLoc getNextTypeLoc() const {
0312     return getUnqualifiedLoc();
0313   }
0314 
0315   /// Returns the size of the type source info data block that is
0316   /// specific to this type.
0317   unsigned getLocalDataSize() const {
0318     // In fact, we don't currently preserve any location information
0319     // for qualifiers.
0320     return 0;
0321   }
0322 
0323   /// Returns the alignment of the type source info data block that is
0324   /// specific to this type.
0325   unsigned getLocalDataAlignment() const {
0326     // We don't preserve any location information.
0327     return 1;
0328   }
0329 
0330 private:
0331   friend class TypeLoc;
0332 
0333   static bool isKind(const TypeLoc &TL) {
0334     return TL.getType().hasLocalQualifiers();
0335   }
0336 };
0337 
0338 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
0339   if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
0340     return Loc.getUnqualifiedLoc();
0341   return castAs<UnqualTypeLoc>();
0342 }
0343 
0344 /// A metaprogramming base class for TypeLoc classes which correspond
0345 /// to a particular Type subclass.  It is accepted for a single
0346 /// TypeLoc class to correspond to multiple Type classes.
0347 ///
0348 /// \tparam Base a class from which to derive
0349 /// \tparam Derived the class deriving from this one
0350 /// \tparam TypeClass the concrete Type subclass associated with this
0351 ///   location type
0352 /// \tparam LocalData the structure type of local location data for
0353 ///   this type
0354 ///
0355 /// TypeLocs with non-constant amounts of local data should override
0356 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
0357 /// this extra memory.
0358 ///
0359 /// TypeLocs with an inner type should define
0360 ///   QualType getInnerType() const
0361 /// and getInnerTypeLoc() will then point to this inner type's
0362 /// location data.
0363 ///
0364 /// A word about hierarchies: this template is not designed to be
0365 /// derived from multiple times in a hierarchy.  It is also not
0366 /// designed to be used for classes where subtypes might provide
0367 /// different amounts of source information.  It should be subclassed
0368 /// only at the deepest portion of the hierarchy where all children
0369 /// have identical source information; if that's an abstract type,
0370 /// then further descendents should inherit from
0371 /// InheritingConcreteTypeLoc instead.
0372 template <class Base, class Derived, class TypeClass, class LocalData>
0373 class ConcreteTypeLoc : public Base {
0374   friend class TypeLoc;
0375 
0376   const Derived *asDerived() const {
0377     return static_cast<const Derived*>(this);
0378   }
0379 
0380   static bool isKind(const TypeLoc &TL) {
0381     return !TL.getType().hasLocalQualifiers() &&
0382            Derived::classofType(TL.getTypePtr());
0383   }
0384 
0385   static bool classofType(const Type *Ty) {
0386     return TypeClass::classof(Ty);
0387   }
0388 
0389 public:
0390   unsigned getLocalDataAlignment() const {
0391     return std::max(unsigned(alignof(LocalData)),
0392                     asDerived()->getExtraLocalDataAlignment());
0393   }
0394 
0395   unsigned getLocalDataSize() const {
0396     unsigned size = sizeof(LocalData);
0397     unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
0398     size = llvm::alignTo(size, extraAlign);
0399     size += asDerived()->getExtraLocalDataSize();
0400     size = llvm::alignTo(size, asDerived()->getLocalDataAlignment());
0401     return size;
0402   }
0403 
0404   void copyLocal(Derived other) {
0405     // Some subclasses have no data to copy.
0406     if (asDerived()->getLocalDataSize() == 0) return;
0407 
0408     // Copy the fixed-sized local data.
0409     memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
0410 
0411     // Copy the variable-sized local data. We need to do this
0412     // separately because the padding in the source and the padding in
0413     // the destination might be different.
0414     memcpy(getExtraLocalData(), other.getExtraLocalData(),
0415            asDerived()->getExtraLocalDataSize());
0416   }
0417 
0418   TypeLoc getNextTypeLoc() const {
0419     return getNextTypeLoc(asDerived()->getInnerType());
0420   }
0421 
0422   const TypeClass *getTypePtr() const {
0423     return cast<TypeClass>(Base::getTypePtr());
0424   }
0425 
0426 protected:
0427   unsigned getExtraLocalDataSize() const {
0428     return 0;
0429   }
0430 
0431   unsigned getExtraLocalDataAlignment() const {
0432     return 1;
0433   }
0434 
0435   LocalData *getLocalData() const {
0436     return static_cast<LocalData*>(Base::Data);
0437   }
0438 
0439   /// Gets a pointer past the Info structure; useful for classes with
0440   /// local data that can't be captured in the Info (e.g. because it's
0441   /// of variable size).
0442   void *getExtraLocalData() const {
0443     unsigned size = sizeof(LocalData);
0444     unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
0445     size = llvm::alignTo(size, extraAlign);
0446     return reinterpret_cast<char *>(Base::Data) + size;
0447   }
0448 
0449   void *getNonLocalData() const {
0450     auto data = reinterpret_cast<uintptr_t>(Base::Data);
0451     data += asDerived()->getLocalDataSize();
0452     data = llvm::alignTo(data, getNextTypeAlign());
0453     return reinterpret_cast<void*>(data);
0454   }
0455 
0456   struct HasNoInnerType {};
0457   HasNoInnerType getInnerType() const { return HasNoInnerType(); }
0458 
0459   TypeLoc getInnerTypeLoc() const {
0460     return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
0461   }
0462 
0463 private:
0464   unsigned getInnerTypeSize() const {
0465     return getInnerTypeSize(asDerived()->getInnerType());
0466   }
0467 
0468   unsigned getInnerTypeSize(HasNoInnerType _) const {
0469     return 0;
0470   }
0471 
0472   unsigned getInnerTypeSize(QualType _) const {
0473     return getInnerTypeLoc().getFullDataSize();
0474   }
0475 
0476   unsigned getNextTypeAlign() const {
0477     return getNextTypeAlign(asDerived()->getInnerType());
0478   }
0479 
0480   unsigned getNextTypeAlign(HasNoInnerType _) const {
0481     return 1;
0482   }
0483 
0484   unsigned getNextTypeAlign(QualType T) const {
0485     return TypeLoc::getLocalAlignmentForType(T);
0486   }
0487 
0488   TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
0489 
0490   TypeLoc getNextTypeLoc(QualType T) const {
0491     return TypeLoc(T, getNonLocalData());
0492   }
0493 };
0494 
0495 /// A metaprogramming class designed for concrete subtypes of abstract
0496 /// types where all subtypes share equivalently-structured source
0497 /// information.  See the note on ConcreteTypeLoc.
0498 template <class Base, class Derived, class TypeClass>
0499 class InheritingConcreteTypeLoc : public Base {
0500   friend class TypeLoc;
0501 
0502   static bool classofType(const Type *Ty) {
0503     return TypeClass::classof(Ty);
0504   }
0505 
0506   static bool isKind(const TypeLoc &TL) {
0507     return !TL.getType().hasLocalQualifiers() &&
0508            Derived::classofType(TL.getTypePtr());
0509   }
0510   static bool isKind(const UnqualTypeLoc &TL) {
0511     return Derived::classofType(TL.getTypePtr());
0512   }
0513 
0514 public:
0515   const TypeClass *getTypePtr() const {
0516     return cast<TypeClass>(Base::getTypePtr());
0517   }
0518 };
0519 
0520 struct TypeSpecLocInfo {
0521   SourceLocation NameLoc;
0522 };
0523 
0524 /// A reasonable base class for TypeLocs that correspond to
0525 /// types that are written as a type-specifier.
0526 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
0527                                                TypeSpecTypeLoc,
0528                                                Type,
0529                                                TypeSpecLocInfo> {
0530 public:
0531   enum {
0532     LocalDataSize = sizeof(TypeSpecLocInfo),
0533     LocalDataAlignment = alignof(TypeSpecLocInfo)
0534   };
0535 
0536   SourceLocation getNameLoc() const {
0537     return this->getLocalData()->NameLoc;
0538   }
0539 
0540   void setNameLoc(SourceLocation Loc) {
0541     this->getLocalData()->NameLoc = Loc;
0542   }
0543 
0544   SourceRange getLocalSourceRange() const {
0545     return SourceRange(getNameLoc(), getNameLoc());
0546   }
0547 
0548   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
0549     setNameLoc(Loc);
0550   }
0551 
0552 private:
0553   friend class TypeLoc;
0554 
0555   static bool isKind(const TypeLoc &TL);
0556 };
0557 
0558 struct BuiltinLocInfo {
0559   SourceRange BuiltinRange;
0560 };
0561 
0562 /// Wrapper for source info for builtin types.
0563 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
0564                                               BuiltinTypeLoc,
0565                                               BuiltinType,
0566                                               BuiltinLocInfo> {
0567 public:
0568   SourceLocation getBuiltinLoc() const {
0569     return getLocalData()->BuiltinRange.getBegin();
0570   }
0571 
0572   void setBuiltinLoc(SourceLocation Loc) {
0573     getLocalData()->BuiltinRange = Loc;
0574   }
0575 
0576   void expandBuiltinRange(SourceRange Range) {
0577     SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
0578     if (!BuiltinRange.getBegin().isValid()) {
0579       BuiltinRange = Range;
0580     } else {
0581       BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
0582       BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
0583     }
0584   }
0585 
0586   SourceLocation getNameLoc() const { return getBuiltinLoc(); }
0587 
0588   WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
0589     return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
0590   }
0591   const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
0592     return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
0593   }
0594 
0595   bool needsExtraLocalData() const {
0596     BuiltinType::Kind bk = getTypePtr()->getKind();
0597     return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) ||
0598            (bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) ||
0599            bk == BuiltinType::UChar || bk == BuiltinType::SChar;
0600   }
0601 
0602   unsigned getExtraLocalDataSize() const {
0603     return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
0604   }
0605 
0606   unsigned getExtraLocalDataAlignment() const {
0607     return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
0608   }
0609 
0610   SourceRange getLocalSourceRange() const {
0611     return getLocalData()->BuiltinRange;
0612   }
0613 
0614   TypeSpecifierSign getWrittenSignSpec() const {
0615     if (needsExtraLocalData())
0616       return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
0617     else
0618       return TypeSpecifierSign::Unspecified;
0619   }
0620 
0621   bool hasWrittenSignSpec() const {
0622     return getWrittenSignSpec() != TypeSpecifierSign::Unspecified;
0623   }
0624 
0625   void setWrittenSignSpec(TypeSpecifierSign written) {
0626     if (needsExtraLocalData())
0627       getWrittenBuiltinSpecs().Sign = static_cast<unsigned>(written);
0628   }
0629 
0630   TypeSpecifierWidth getWrittenWidthSpec() const {
0631     if (needsExtraLocalData())
0632       return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
0633     else
0634       return TypeSpecifierWidth::Unspecified;
0635   }
0636 
0637   bool hasWrittenWidthSpec() const {
0638     return getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified;
0639   }
0640 
0641   void setWrittenWidthSpec(TypeSpecifierWidth written) {
0642     if (needsExtraLocalData())
0643       getWrittenBuiltinSpecs().Width = static_cast<unsigned>(written);
0644   }
0645 
0646   TypeSpecifierType getWrittenTypeSpec() const;
0647 
0648   bool hasWrittenTypeSpec() const {
0649     return getWrittenTypeSpec() != TST_unspecified;
0650   }
0651 
0652   void setWrittenTypeSpec(TypeSpecifierType written) {
0653     if (needsExtraLocalData())
0654       getWrittenBuiltinSpecs().Type = written;
0655   }
0656 
0657   bool hasModeAttr() const {
0658     if (needsExtraLocalData())
0659       return getWrittenBuiltinSpecs().ModeAttr;
0660     else
0661       return false;
0662   }
0663 
0664   void setModeAttr(bool written) {
0665     if (needsExtraLocalData())
0666       getWrittenBuiltinSpecs().ModeAttr = written;
0667   }
0668 
0669   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
0670     setBuiltinLoc(Loc);
0671     if (needsExtraLocalData()) {
0672       WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
0673       wbs.Sign = static_cast<unsigned>(TypeSpecifierSign::Unspecified);
0674       wbs.Width = static_cast<unsigned>(TypeSpecifierWidth::Unspecified);
0675       wbs.Type = TST_unspecified;
0676       wbs.ModeAttr = false;
0677     }
0678   }
0679 };
0680 
0681 /// Wrapper for source info for types used via transparent aliases.
0682 class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0683                                                       UsingTypeLoc, UsingType> {
0684 public:
0685   QualType getUnderlyingType() const {
0686     return getTypePtr()->getUnderlyingType();
0687   }
0688   UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); }
0689 };
0690 
0691 /// Wrapper for source info for typedefs.
0692 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0693                                                         TypedefTypeLoc,
0694                                                         TypedefType> {
0695 public:
0696   TypedefNameDecl *getTypedefNameDecl() const {
0697     return getTypePtr()->getDecl();
0698   }
0699 };
0700 
0701 /// Wrapper for source info for injected class names of class
0702 /// templates.
0703 class InjectedClassNameTypeLoc :
0704     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0705                                      InjectedClassNameTypeLoc,
0706                                      InjectedClassNameType> {
0707 public:
0708   CXXRecordDecl *getDecl() const {
0709     return getTypePtr()->getDecl();
0710   }
0711 };
0712 
0713 /// Wrapper for source info for unresolved typename using decls.
0714 class UnresolvedUsingTypeLoc :
0715     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0716                                      UnresolvedUsingTypeLoc,
0717                                      UnresolvedUsingType> {
0718 public:
0719   UnresolvedUsingTypenameDecl *getDecl() const {
0720     return getTypePtr()->getDecl();
0721   }
0722 };
0723 
0724 /// Wrapper for source info for tag types.  Note that this only
0725 /// records source info for the name itself; a type written 'struct foo'
0726 /// should be represented as an ElaboratedTypeLoc.  We currently
0727 /// only do that when C++ is enabled because of the expense of
0728 /// creating an ElaboratedType node for so many type references in C.
0729 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0730                                                     TagTypeLoc,
0731                                                     TagType> {
0732 public:
0733   TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
0734 
0735   /// True if the tag was defined in this type specifier.
0736   bool isDefinition() const;
0737 };
0738 
0739 /// Wrapper for source info for record types.
0740 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
0741                                                        RecordTypeLoc,
0742                                                        RecordType> {
0743 public:
0744   RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
0745 };
0746 
0747 /// Wrapper for source info for enum types.
0748 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
0749                                                      EnumTypeLoc,
0750                                                      EnumType> {
0751 public:
0752   EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
0753 };
0754 
0755 /// Wrapper for template type parameters.
0756 class TemplateTypeParmTypeLoc :
0757     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0758                                      TemplateTypeParmTypeLoc,
0759                                      TemplateTypeParmType> {
0760 public:
0761   TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
0762 };
0763 
0764 struct ObjCTypeParamTypeLocInfo {
0765   SourceLocation NameLoc;
0766 };
0767 
0768 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
0769 /// protocol qualifiers are stored after Info.
0770 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
0771                                      ObjCTypeParamTypeLoc,
0772                                      ObjCTypeParamType,
0773                                      ObjCTypeParamTypeLocInfo> {
0774   // SourceLocations are stored after Info, one for each protocol qualifier.
0775   SourceLocation *getProtocolLocArray() const {
0776     return (SourceLocation*)this->getExtraLocalData() + 2;
0777   }
0778 
0779 public:
0780   ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
0781 
0782   SourceLocation getNameLoc() const {
0783     return this->getLocalData()->NameLoc;
0784   }
0785 
0786   void setNameLoc(SourceLocation Loc) {
0787     this->getLocalData()->NameLoc = Loc;
0788   }
0789 
0790   SourceLocation getProtocolLAngleLoc() const {
0791     return getNumProtocols()  ?
0792       *((SourceLocation*)this->getExtraLocalData()) :
0793       SourceLocation();
0794   }
0795 
0796   void setProtocolLAngleLoc(SourceLocation Loc) {
0797     *((SourceLocation*)this->getExtraLocalData()) = Loc;
0798   }
0799 
0800   SourceLocation getProtocolRAngleLoc() const {
0801     return getNumProtocols()  ?
0802       *((SourceLocation*)this->getExtraLocalData() + 1) :
0803       SourceLocation();
0804   }
0805 
0806   void setProtocolRAngleLoc(SourceLocation Loc) {
0807     *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
0808   }
0809 
0810   unsigned getNumProtocols() const {
0811     return this->getTypePtr()->getNumProtocols();
0812   }
0813 
0814   SourceLocation getProtocolLoc(unsigned i) const {
0815     assert(i < getNumProtocols() && "Index is out of bounds!");
0816     return getProtocolLocArray()[i];
0817   }
0818 
0819   void setProtocolLoc(unsigned i, SourceLocation Loc) {
0820     assert(i < getNumProtocols() && "Index is out of bounds!");
0821     getProtocolLocArray()[i] = Loc;
0822   }
0823 
0824   ObjCProtocolDecl *getProtocol(unsigned i) const {
0825     assert(i < getNumProtocols() && "Index is out of bounds!");
0826     return *(this->getTypePtr()->qual_begin() + i);
0827   }
0828 
0829   ArrayRef<SourceLocation> getProtocolLocs() const {
0830     return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols());
0831   }
0832 
0833   void initializeLocal(ASTContext &Context, SourceLocation Loc);
0834 
0835   unsigned getExtraLocalDataSize() const {
0836     if (!this->getNumProtocols()) return 0;
0837     // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
0838     // as well.
0839     return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
0840   }
0841 
0842   unsigned getExtraLocalDataAlignment() const {
0843     return alignof(SourceLocation);
0844   }
0845 
0846   SourceRange getLocalSourceRange() const {
0847     SourceLocation start = getNameLoc();
0848     SourceLocation end = getProtocolRAngleLoc();
0849     if (end.isInvalid()) return SourceRange(start, start);
0850     return SourceRange(start, end);
0851   }
0852 };
0853 
0854 /// Wrapper for substituted template type parameters.
0855 class SubstTemplateTypeParmTypeLoc :
0856     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0857                                      SubstTemplateTypeParmTypeLoc,
0858                                      SubstTemplateTypeParmType> {
0859 };
0860 
0861   /// Wrapper for substituted template type parameters.
0862 class SubstTemplateTypeParmPackTypeLoc :
0863     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
0864                                      SubstTemplateTypeParmPackTypeLoc,
0865                                      SubstTemplateTypeParmPackType> {
0866 };
0867 
0868 struct AttributedLocInfo {
0869   const Attr *TypeAttr;
0870 };
0871 
0872 /// Type source information for an attributed type.
0873 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
0874                                                  AttributedTypeLoc,
0875                                                  AttributedType,
0876                                                  AttributedLocInfo> {
0877 public:
0878   attr::Kind getAttrKind() const {
0879     return getTypePtr()->getAttrKind();
0880   }
0881 
0882   bool isQualifier() const {
0883     return getTypePtr()->isQualifier();
0884   }
0885 
0886   /// The modified type, which is generally canonically different from
0887   /// the attribute type.
0888   ///    int main(int, char**) __attribute__((noreturn))
0889   ///    ~~~     ~~~~~~~~~~~~~
0890   TypeLoc getModifiedLoc() const {
0891     return getInnerTypeLoc();
0892   }
0893 
0894   TypeLoc getEquivalentTypeLoc() const {
0895     return TypeLoc(getTypePtr()->getEquivalentType(), getNonLocalData());
0896   }
0897 
0898   /// The type attribute.
0899   const Attr *getAttr() const {
0900     return getLocalData()->TypeAttr;
0901   }
0902   void setAttr(const Attr *A) {
0903     getLocalData()->TypeAttr = A;
0904   }
0905 
0906   template<typename T> const T *getAttrAs() {
0907     return dyn_cast_or_null<T>(getAttr());
0908   }
0909 
0910   SourceRange getLocalSourceRange() const;
0911 
0912   void initializeLocal(ASTContext &Context, SourceLocation loc) {
0913     setAttr(nullptr);
0914   }
0915 
0916   QualType getInnerType() const {
0917     return getTypePtr()->getModifiedType();
0918   }
0919 };
0920 
0921 struct BTFTagAttributedLocInfo {}; // Nothing.
0922 
0923 /// Type source information for an btf_tag attributed type.
0924 class BTFTagAttributedTypeLoc
0925     : public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc,
0926                              BTFTagAttributedType, BTFTagAttributedLocInfo> {
0927 public:
0928   TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
0929 
0930   /// The btf_type_tag attribute.
0931   const BTFTypeTagAttr *getAttr() const { return getTypePtr()->getAttr(); }
0932 
0933   template <typename T> T *getAttrAs() {
0934     return dyn_cast_or_null<T>(getAttr());
0935   }
0936 
0937   SourceRange getLocalSourceRange() const;
0938 
0939   void initializeLocal(ASTContext &Context, SourceLocation loc) {}
0940 
0941   QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
0942 };
0943 
0944 struct HLSLAttributedResourceLocInfo {
0945   SourceRange Range;
0946   TypeSourceInfo *ContainedTyInfo;
0947 };
0948 
0949 /// Type source information for HLSL attributed resource type.
0950 class HLSLAttributedResourceTypeLoc
0951     : public ConcreteTypeLoc<UnqualTypeLoc, HLSLAttributedResourceTypeLoc,
0952                              HLSLAttributedResourceType,
0953                              HLSLAttributedResourceLocInfo> {
0954 public:
0955   TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
0956 
0957   TypeSourceInfo *getContainedTypeSourceInfo() const {
0958     return getLocalData()->ContainedTyInfo;
0959   }
0960   void setContainedTypeSourceInfo(TypeSourceInfo *TSI) const {
0961     getLocalData()->ContainedTyInfo = TSI;
0962   }
0963 
0964   void setSourceRange(const SourceRange &R) { getLocalData()->Range = R; }
0965   SourceRange getLocalSourceRange() const { return getLocalData()->Range; }
0966   void initializeLocal(ASTContext &Context, SourceLocation loc) {
0967     setSourceRange(SourceRange());
0968   }
0969   QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
0970   unsigned getLocalDataSize() const {
0971     return sizeof(HLSLAttributedResourceLocInfo);
0972   }
0973 };
0974 
0975 struct ObjCObjectTypeLocInfo {
0976   SourceLocation TypeArgsLAngleLoc;
0977   SourceLocation TypeArgsRAngleLoc;
0978   SourceLocation ProtocolLAngleLoc;
0979   SourceLocation ProtocolRAngleLoc;
0980   bool HasBaseTypeAsWritten;
0981 };
0982 
0983 // A helper class for defining ObjC TypeLocs that can qualified with
0984 // protocols.
0985 //
0986 // TypeClass basically has to be either ObjCInterfaceType or
0987 // ObjCObjectPointerType.
0988 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
0989                                                  ObjCObjectTypeLoc,
0990                                                  ObjCObjectType,
0991                                                  ObjCObjectTypeLocInfo> {
0992   // TypeSourceInfo*'s are stored after Info, one for each type argument.
0993   TypeSourceInfo **getTypeArgLocArray() const {
0994     return (TypeSourceInfo**)this->getExtraLocalData();
0995   }
0996 
0997   // SourceLocations are stored after the type argument information, one for
0998   // each Protocol.
0999   SourceLocation *getProtocolLocArray() const {
1000     return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
1001   }
1002 
1003 public:
1004   SourceLocation getTypeArgsLAngleLoc() const {
1005     return this->getLocalData()->TypeArgsLAngleLoc;
1006   }
1007 
1008   void setTypeArgsLAngleLoc(SourceLocation Loc) {
1009     this->getLocalData()->TypeArgsLAngleLoc = Loc;
1010   }
1011 
1012   SourceLocation getTypeArgsRAngleLoc() const {
1013     return this->getLocalData()->TypeArgsRAngleLoc;
1014   }
1015 
1016   void setTypeArgsRAngleLoc(SourceLocation Loc) {
1017     this->getLocalData()->TypeArgsRAngleLoc = Loc;
1018   }
1019 
1020   unsigned getNumTypeArgs() const {
1021     return this->getTypePtr()->getTypeArgsAsWritten().size();
1022   }
1023 
1024   TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
1025     assert(i < getNumTypeArgs() && "Index is out of bounds!");
1026     return getTypeArgLocArray()[i];
1027   }
1028 
1029   void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
1030     assert(i < getNumTypeArgs() && "Index is out of bounds!");
1031     getTypeArgLocArray()[i] = TInfo;
1032   }
1033 
1034   SourceLocation getProtocolLAngleLoc() const {
1035     return this->getLocalData()->ProtocolLAngleLoc;
1036   }
1037 
1038   void setProtocolLAngleLoc(SourceLocation Loc) {
1039     this->getLocalData()->ProtocolLAngleLoc = Loc;
1040   }
1041 
1042   SourceLocation getProtocolRAngleLoc() const {
1043     return this->getLocalData()->ProtocolRAngleLoc;
1044   }
1045 
1046   void setProtocolRAngleLoc(SourceLocation Loc) {
1047     this->getLocalData()->ProtocolRAngleLoc = Loc;
1048   }
1049 
1050   unsigned getNumProtocols() const {
1051     return this->getTypePtr()->getNumProtocols();
1052   }
1053 
1054   SourceLocation getProtocolLoc(unsigned i) const {
1055     assert(i < getNumProtocols() && "Index is out of bounds!");
1056     return getProtocolLocArray()[i];
1057   }
1058 
1059   void setProtocolLoc(unsigned i, SourceLocation Loc) {
1060     assert(i < getNumProtocols() && "Index is out of bounds!");
1061     getProtocolLocArray()[i] = Loc;
1062   }
1063 
1064   ObjCProtocolDecl *getProtocol(unsigned i) const {
1065     assert(i < getNumProtocols() && "Index is out of bounds!");
1066     return *(this->getTypePtr()->qual_begin() + i);
1067   }
1068 
1069 
1070   ArrayRef<SourceLocation> getProtocolLocs() const {
1071     return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols());
1072   }
1073 
1074   bool hasBaseTypeAsWritten() const {
1075     return getLocalData()->HasBaseTypeAsWritten;
1076   }
1077 
1078   void setHasBaseTypeAsWritten(bool HasBaseType) {
1079     getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1080   }
1081 
1082   TypeLoc getBaseLoc() const {
1083     return getInnerTypeLoc();
1084   }
1085 
1086   SourceRange getLocalSourceRange() const {
1087     SourceLocation start = getTypeArgsLAngleLoc();
1088     if (start.isInvalid())
1089       start = getProtocolLAngleLoc();
1090     SourceLocation end = getProtocolRAngleLoc();
1091     if (end.isInvalid())
1092       end = getTypeArgsRAngleLoc();
1093     return SourceRange(start, end);
1094   }
1095 
1096   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1097 
1098   unsigned getExtraLocalDataSize() const {
1099     return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1100          + this->getNumProtocols() * sizeof(SourceLocation);
1101   }
1102 
1103   unsigned getExtraLocalDataAlignment() const {
1104     static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1105                   "not enough alignment for tail-allocated data");
1106     return alignof(TypeSourceInfo *);
1107   }
1108 
1109   QualType getInnerType() const {
1110     return getTypePtr()->getBaseType();
1111   }
1112 };
1113 
1114 struct ObjCInterfaceLocInfo {
1115   SourceLocation NameLoc;
1116   SourceLocation NameEndLoc;
1117 };
1118 
1119 /// Wrapper for source info for ObjC interfaces.
1120 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1121                                                     ObjCInterfaceTypeLoc,
1122                                                     ObjCInterfaceType,
1123                                                     ObjCInterfaceLocInfo> {
1124 public:
1125   ObjCInterfaceDecl *getIFaceDecl() const {
1126     return getTypePtr()->getDecl();
1127   }
1128 
1129   SourceLocation getNameLoc() const {
1130     return getLocalData()->NameLoc;
1131   }
1132 
1133   void setNameLoc(SourceLocation Loc) {
1134     getLocalData()->NameLoc = Loc;
1135   }
1136 
1137   SourceRange getLocalSourceRange() const {
1138     return SourceRange(getNameLoc(), getNameEndLoc());
1139   }
1140 
1141   SourceLocation getNameEndLoc() const {
1142     return getLocalData()->NameEndLoc;
1143   }
1144 
1145   void setNameEndLoc(SourceLocation Loc) {
1146     getLocalData()->NameEndLoc = Loc;
1147   }
1148 
1149   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1150     setNameLoc(Loc);
1151     setNameEndLoc(Loc);
1152   }
1153 };
1154 
1155 struct BoundsAttributedLocInfo {};
1156 class BoundsAttributedTypeLoc
1157     : public ConcreteTypeLoc<UnqualTypeLoc, BoundsAttributedTypeLoc,
1158                              BoundsAttributedType, BoundsAttributedLocInfo> {
1159 public:
1160   TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1161   QualType getInnerType() const { return getTypePtr()->desugar(); }
1162   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1163     // nothing to do
1164   }
1165   // LocalData is empty and TypeLocBuilder doesn't handle DataSize 1.
1166   unsigned getLocalDataSize() const { return 0; }
1167 };
1168 
1169 class CountAttributedTypeLoc final
1170     : public InheritingConcreteTypeLoc<BoundsAttributedTypeLoc,
1171                                        CountAttributedTypeLoc,
1172                                        CountAttributedType> {
1173 public:
1174   Expr *getCountExpr() const { return getTypePtr()->getCountExpr(); }
1175   bool isCountInBytes() const { return getTypePtr()->isCountInBytes(); }
1176   bool isOrNull() const { return getTypePtr()->isOrNull(); }
1177 
1178   SourceRange getLocalSourceRange() const;
1179 };
1180 
1181 struct MacroQualifiedLocInfo {
1182   SourceLocation ExpansionLoc;
1183 };
1184 
1185 class MacroQualifiedTypeLoc
1186     : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
1187                              MacroQualifiedType, MacroQualifiedLocInfo> {
1188 public:
1189   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1190     setExpansionLoc(Loc);
1191   }
1192 
1193   TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1194 
1195   const IdentifierInfo *getMacroIdentifier() const {
1196     return getTypePtr()->getMacroIdentifier();
1197   }
1198 
1199   SourceLocation getExpansionLoc() const {
1200     return this->getLocalData()->ExpansionLoc;
1201   }
1202 
1203   void setExpansionLoc(SourceLocation Loc) {
1204     this->getLocalData()->ExpansionLoc = Loc;
1205   }
1206 
1207   QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); }
1208 
1209   SourceRange getLocalSourceRange() const {
1210     return getInnerLoc().getLocalSourceRange();
1211   }
1212 };
1213 
1214 struct ParenLocInfo {
1215   SourceLocation LParenLoc;
1216   SourceLocation RParenLoc;
1217 };
1218 
1219 class ParenTypeLoc
1220   : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1221                            ParenLocInfo> {
1222 public:
1223   SourceLocation getLParenLoc() const {
1224     return this->getLocalData()->LParenLoc;
1225   }
1226 
1227   SourceLocation getRParenLoc() const {
1228     return this->getLocalData()->RParenLoc;
1229   }
1230 
1231   void setLParenLoc(SourceLocation Loc) {
1232     this->getLocalData()->LParenLoc = Loc;
1233   }
1234 
1235   void setRParenLoc(SourceLocation Loc) {
1236     this->getLocalData()->RParenLoc = Loc;
1237   }
1238 
1239   SourceRange getLocalSourceRange() const {
1240     return SourceRange(getLParenLoc(), getRParenLoc());
1241   }
1242 
1243   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1244     setLParenLoc(Loc);
1245     setRParenLoc(Loc);
1246   }
1247 
1248   TypeLoc getInnerLoc() const {
1249     return getInnerTypeLoc();
1250   }
1251 
1252   QualType getInnerType() const {
1253     return this->getTypePtr()->getInnerType();
1254   }
1255 };
1256 
1257 inline TypeLoc TypeLoc::IgnoreParens() const {
1258   if (ParenTypeLoc::isKind(*this))
1259     return IgnoreParensImpl(*this);
1260   return *this;
1261 }
1262 
1263 struct AdjustedLocInfo {}; // Nothing.
1264 
1265 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1266                                                AdjustedType, AdjustedLocInfo> {
1267 public:
1268   TypeLoc getOriginalLoc() const {
1269     return getInnerTypeLoc();
1270   }
1271 
1272   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1273     // do nothing
1274   }
1275 
1276   QualType getInnerType() const {
1277     // The inner type is the undecayed type, since that's what we have source
1278     // location information for.
1279     return getTypePtr()->getOriginalType();
1280   }
1281 
1282   SourceRange getLocalSourceRange() const { return {}; }
1283 
1284   unsigned getLocalDataSize() const {
1285     // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1286     // anyway.  TypeLocBuilder can't handle data sizes of 1.
1287     return 0;  // No data.
1288   }
1289 };
1290 
1291 /// Wrapper for source info for pointers decayed from arrays and
1292 /// functions.
1293 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1294                            AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1295 };
1296 
1297 struct PointerLikeLocInfo {
1298   SourceLocation StarLoc;
1299 };
1300 
1301 /// A base class for
1302 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1303 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1304                                                   TypeClass, LocalData> {
1305 public:
1306   SourceLocation getSigilLoc() const {
1307     return this->getLocalData()->StarLoc;
1308   }
1309 
1310   void setSigilLoc(SourceLocation Loc) {
1311     this->getLocalData()->StarLoc = Loc;
1312   }
1313 
1314   TypeLoc getPointeeLoc() const {
1315     return this->getInnerTypeLoc();
1316   }
1317 
1318   SourceRange getLocalSourceRange() const {
1319     return SourceRange(getSigilLoc(), getSigilLoc());
1320   }
1321 
1322   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1323     setSigilLoc(Loc);
1324   }
1325 
1326   QualType getInnerType() const {
1327     return this->getTypePtr()->getPointeeType();
1328   }
1329 };
1330 
1331 /// Wrapper for source info for pointers.
1332 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1333                                                  PointerType> {
1334 public:
1335   SourceLocation getStarLoc() const {
1336     return getSigilLoc();
1337   }
1338 
1339   void setStarLoc(SourceLocation Loc) {
1340     setSigilLoc(Loc);
1341   }
1342 };
1343 
1344 /// Wrapper for source info for block pointers.
1345 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1346                                                       BlockPointerType> {
1347 public:
1348   SourceLocation getCaretLoc() const {
1349     return getSigilLoc();
1350   }
1351 
1352   void setCaretLoc(SourceLocation Loc) {
1353     setSigilLoc(Loc);
1354   }
1355 };
1356 
1357 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1358   TypeSourceInfo *ClassTInfo;
1359 };
1360 
1361 /// Wrapper for source info for member pointers.
1362 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1363                                                        MemberPointerType,
1364                                                        MemberPointerLocInfo> {
1365 public:
1366   SourceLocation getStarLoc() const {
1367     return getSigilLoc();
1368   }
1369 
1370   void setStarLoc(SourceLocation Loc) {
1371     setSigilLoc(Loc);
1372   }
1373 
1374   const Type *getClass() const {
1375     return getTypePtr()->getClass();
1376   }
1377 
1378   TypeSourceInfo *getClassTInfo() const {
1379     return getLocalData()->ClassTInfo;
1380   }
1381 
1382   void setClassTInfo(TypeSourceInfo* TI) {
1383     getLocalData()->ClassTInfo = TI;
1384   }
1385 
1386   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1387     setSigilLoc(Loc);
1388     setClassTInfo(nullptr);
1389   }
1390 
1391   SourceRange getLocalSourceRange() const {
1392     if (TypeSourceInfo *TI = getClassTInfo())
1393       return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1394     else
1395       return SourceRange(getStarLoc());
1396   }
1397 };
1398 
1399 /// Wraps an ObjCPointerType with source location information.
1400 class ObjCObjectPointerTypeLoc :
1401     public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1402                               ObjCObjectPointerType> {
1403 public:
1404   SourceLocation getStarLoc() const {
1405     return getSigilLoc();
1406   }
1407 
1408   void setStarLoc(SourceLocation Loc) {
1409     setSigilLoc(Loc);
1410   }
1411 };
1412 
1413 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1414                                                    ReferenceType> {
1415 public:
1416   QualType getInnerType() const {
1417     return getTypePtr()->getPointeeTypeAsWritten();
1418   }
1419 };
1420 
1421 class LValueReferenceTypeLoc :
1422     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1423                                      LValueReferenceTypeLoc,
1424                                      LValueReferenceType> {
1425 public:
1426   SourceLocation getAmpLoc() const {
1427     return getSigilLoc();
1428   }
1429 
1430   void setAmpLoc(SourceLocation Loc) {
1431     setSigilLoc(Loc);
1432   }
1433 };
1434 
1435 class RValueReferenceTypeLoc :
1436     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1437                                      RValueReferenceTypeLoc,
1438                                      RValueReferenceType> {
1439 public:
1440   SourceLocation getAmpAmpLoc() const {
1441     return getSigilLoc();
1442   }
1443 
1444   void setAmpAmpLoc(SourceLocation Loc) {
1445     setSigilLoc(Loc);
1446   }
1447 };
1448 
1449 struct FunctionLocInfo {
1450   SourceLocation LocalRangeBegin;
1451   SourceLocation LParenLoc;
1452   SourceLocation RParenLoc;
1453   SourceLocation LocalRangeEnd;
1454 };
1455 
1456 /// Wrapper for source info for functions.
1457 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1458                                                FunctionTypeLoc,
1459                                                FunctionType,
1460                                                FunctionLocInfo> {
1461   bool hasExceptionSpec() const {
1462     if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1463       return FPT->hasExceptionSpec();
1464     }
1465     return false;
1466   }
1467 
1468   SourceRange *getExceptionSpecRangePtr() const {
1469     assert(hasExceptionSpec() && "No exception spec range");
1470     // After the Info comes the ParmVarDecl array, and after that comes the
1471     // exception specification information.
1472     return (SourceRange *)(getParmArray() + getNumParams());
1473   }
1474 
1475 public:
1476   SourceLocation getLocalRangeBegin() const {
1477     return getLocalData()->LocalRangeBegin;
1478   }
1479 
1480   void setLocalRangeBegin(SourceLocation L) {
1481     getLocalData()->LocalRangeBegin = L;
1482   }
1483 
1484   SourceLocation getLocalRangeEnd() const {
1485     return getLocalData()->LocalRangeEnd;
1486   }
1487 
1488   void setLocalRangeEnd(SourceLocation L) {
1489     getLocalData()->LocalRangeEnd = L;
1490   }
1491 
1492   SourceLocation getLParenLoc() const {
1493     return this->getLocalData()->LParenLoc;
1494   }
1495 
1496   void setLParenLoc(SourceLocation Loc) {
1497     this->getLocalData()->LParenLoc = Loc;
1498   }
1499 
1500   SourceLocation getRParenLoc() const {
1501     return this->getLocalData()->RParenLoc;
1502   }
1503 
1504   void setRParenLoc(SourceLocation Loc) {
1505     this->getLocalData()->RParenLoc = Loc;
1506   }
1507 
1508   SourceRange getParensRange() const {
1509     return SourceRange(getLParenLoc(), getRParenLoc());
1510   }
1511 
1512   SourceRange getExceptionSpecRange() const {
1513     if (hasExceptionSpec())
1514       return *getExceptionSpecRangePtr();
1515     return {};
1516   }
1517 
1518   void setExceptionSpecRange(SourceRange R) {
1519     if (hasExceptionSpec())
1520       *getExceptionSpecRangePtr() = R;
1521   }
1522 
1523   ArrayRef<ParmVarDecl *> getParams() const {
1524     return llvm::ArrayRef(getParmArray(), getNumParams());
1525   }
1526 
1527   // ParmVarDecls* are stored after Info, one for each parameter.
1528   ParmVarDecl **getParmArray() const {
1529     return (ParmVarDecl**) getExtraLocalData();
1530   }
1531 
1532   unsigned getNumParams() const {
1533     if (isa<FunctionNoProtoType>(getTypePtr()))
1534       return 0;
1535     return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1536   }
1537 
1538   ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1539   void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1540 
1541   TypeLoc getReturnLoc() const {
1542     return getInnerTypeLoc();
1543   }
1544 
1545   SourceRange getLocalSourceRange() const {
1546     return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1547   }
1548 
1549   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1550     setLocalRangeBegin(Loc);
1551     setLParenLoc(Loc);
1552     setRParenLoc(Loc);
1553     setLocalRangeEnd(Loc);
1554     for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1555       setParam(i, nullptr);
1556     if (hasExceptionSpec())
1557       setExceptionSpecRange(Loc);
1558   }
1559 
1560   /// Returns the size of the type source info data block that is
1561   /// specific to this type.
1562   unsigned getExtraLocalDataSize() const {
1563     unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1564     return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1565   }
1566 
1567   unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1568 
1569   QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1570 };
1571 
1572 class FunctionProtoTypeLoc :
1573     public InheritingConcreteTypeLoc<FunctionTypeLoc,
1574                                      FunctionProtoTypeLoc,
1575                                      FunctionProtoType> {
1576 };
1577 
1578 class FunctionNoProtoTypeLoc :
1579     public InheritingConcreteTypeLoc<FunctionTypeLoc,
1580                                      FunctionNoProtoTypeLoc,
1581                                      FunctionNoProtoType> {
1582 };
1583 
1584 struct ArrayLocInfo {
1585   SourceLocation LBracketLoc, RBracketLoc;
1586   Expr *Size;
1587 };
1588 
1589 /// Wrapper for source info for arrays.
1590 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1591                                             ArrayTypeLoc,
1592                                             ArrayType,
1593                                             ArrayLocInfo> {
1594 public:
1595   SourceLocation getLBracketLoc() const {
1596     return getLocalData()->LBracketLoc;
1597   }
1598 
1599   void setLBracketLoc(SourceLocation Loc) {
1600     getLocalData()->LBracketLoc = Loc;
1601   }
1602 
1603   SourceLocation getRBracketLoc() const {
1604     return getLocalData()->RBracketLoc;
1605   }
1606 
1607   void setRBracketLoc(SourceLocation Loc) {
1608     getLocalData()->RBracketLoc = Loc;
1609   }
1610 
1611   SourceRange getBracketsRange() const {
1612     return SourceRange(getLBracketLoc(), getRBracketLoc());
1613   }
1614 
1615   Expr *getSizeExpr() const {
1616     return getLocalData()->Size;
1617   }
1618 
1619   void setSizeExpr(Expr *Size) {
1620     getLocalData()->Size = Size;
1621   }
1622 
1623   TypeLoc getElementLoc() const {
1624     return getInnerTypeLoc();
1625   }
1626 
1627   SourceRange getLocalSourceRange() const {
1628     return SourceRange(getLBracketLoc(), getRBracketLoc());
1629   }
1630 
1631   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1632     setLBracketLoc(Loc);
1633     setRBracketLoc(Loc);
1634     setSizeExpr(nullptr);
1635   }
1636 
1637   QualType getInnerType() const { return getTypePtr()->getElementType(); }
1638 };
1639 
1640 class ConstantArrayTypeLoc :
1641     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1642                                      ConstantArrayTypeLoc,
1643                                      ConstantArrayType> {
1644 };
1645 
1646 /// Wrapper for source info for array parameter types.
1647 class ArrayParameterTypeLoc
1648     : public InheritingConcreteTypeLoc<
1649           ConstantArrayTypeLoc, ArrayParameterTypeLoc, ArrayParameterType> {};
1650 
1651 class IncompleteArrayTypeLoc :
1652     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1653                                      IncompleteArrayTypeLoc,
1654                                      IncompleteArrayType> {
1655 };
1656 
1657 class DependentSizedArrayTypeLoc :
1658     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1659                                      DependentSizedArrayTypeLoc,
1660                                      DependentSizedArrayType> {
1661 public:
1662   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1663     ArrayTypeLoc::initializeLocal(Context, Loc);
1664     setSizeExpr(getTypePtr()->getSizeExpr());
1665   }
1666 };
1667 
1668 class VariableArrayTypeLoc :
1669     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1670                                      VariableArrayTypeLoc,
1671                                      VariableArrayType> {
1672 };
1673 
1674 // Location information for a TemplateName.  Rudimentary for now.
1675 struct TemplateNameLocInfo {
1676   SourceLocation NameLoc;
1677 };
1678 
1679 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1680   SourceLocation TemplateKWLoc;
1681   SourceLocation LAngleLoc;
1682   SourceLocation RAngleLoc;
1683 };
1684 
1685 class TemplateSpecializationTypeLoc :
1686     public ConcreteTypeLoc<UnqualTypeLoc,
1687                            TemplateSpecializationTypeLoc,
1688                            TemplateSpecializationType,
1689                            TemplateSpecializationLocInfo> {
1690 public:
1691   SourceLocation getTemplateKeywordLoc() const {
1692     return getLocalData()->TemplateKWLoc;
1693   }
1694 
1695   void setTemplateKeywordLoc(SourceLocation Loc) {
1696     getLocalData()->TemplateKWLoc = Loc;
1697   }
1698 
1699   SourceLocation getLAngleLoc() const {
1700     return getLocalData()->LAngleLoc;
1701   }
1702 
1703   void setLAngleLoc(SourceLocation Loc) {
1704     getLocalData()->LAngleLoc = Loc;
1705   }
1706 
1707   SourceLocation getRAngleLoc() const {
1708     return getLocalData()->RAngleLoc;
1709   }
1710 
1711   void setRAngleLoc(SourceLocation Loc) {
1712     getLocalData()->RAngleLoc = Loc;
1713   }
1714 
1715   unsigned getNumArgs() const {
1716     return getTypePtr()->template_arguments().size();
1717   }
1718 
1719   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1720     getArgInfos()[i] = AI;
1721   }
1722 
1723   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1724     return getArgInfos()[i];
1725   }
1726 
1727   TemplateArgumentLoc getArgLoc(unsigned i) const {
1728     return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
1729                                getArgLocInfo(i));
1730   }
1731 
1732   SourceLocation getTemplateNameLoc() const {
1733     return getLocalData()->NameLoc;
1734   }
1735 
1736   void setTemplateNameLoc(SourceLocation Loc) {
1737     getLocalData()->NameLoc = Loc;
1738   }
1739 
1740   /// - Copy the location information from the given info.
1741   void copy(TemplateSpecializationTypeLoc Loc) {
1742     unsigned size = getFullDataSize();
1743     assert(size == Loc.getFullDataSize());
1744 
1745     // We're potentially copying Expr references here.  We don't
1746     // bother retaining them because TypeSourceInfos live forever, so
1747     // as long as the Expr was retained when originally written into
1748     // the TypeLoc, we're okay.
1749     memcpy(Data, Loc.Data, size);
1750   }
1751 
1752   SourceRange getLocalSourceRange() const {
1753     if (getTemplateKeywordLoc().isValid())
1754       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1755     else
1756       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1757   }
1758 
1759   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1760     setTemplateKeywordLoc(SourceLocation());
1761     setTemplateNameLoc(Loc);
1762     setLAngleLoc(Loc);
1763     setRAngleLoc(Loc);
1764     initializeArgLocs(Context, getTypePtr()->template_arguments(),
1765                       getArgInfos(), Loc);
1766   }
1767 
1768   static void initializeArgLocs(ASTContext &Context,
1769                                 ArrayRef<TemplateArgument> Args,
1770                                 TemplateArgumentLocInfo *ArgInfos,
1771                                 SourceLocation Loc);
1772 
1773   unsigned getExtraLocalDataSize() const {
1774     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1775   }
1776 
1777   unsigned getExtraLocalDataAlignment() const {
1778     return alignof(TemplateArgumentLocInfo);
1779   }
1780 
1781 private:
1782   TemplateArgumentLocInfo *getArgInfos() const {
1783     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1784   }
1785 };
1786 
1787 struct DependentAddressSpaceLocInfo {
1788   Expr *ExprOperand;
1789   SourceRange OperandParens;
1790   SourceLocation AttrLoc;
1791 };
1792 
1793 class DependentAddressSpaceTypeLoc
1794     : public ConcreteTypeLoc<UnqualTypeLoc,
1795                              DependentAddressSpaceTypeLoc,
1796                              DependentAddressSpaceType,
1797                              DependentAddressSpaceLocInfo> {
1798 public:
1799   /// The location of the attribute name, i.e.
1800   ///    int * __attribute__((address_space(11)))
1801   ///                         ^~~~~~~~~~~~~
1802   SourceLocation getAttrNameLoc() const {
1803     return getLocalData()->AttrLoc;
1804   }
1805   void setAttrNameLoc(SourceLocation loc) {
1806     getLocalData()->AttrLoc = loc;
1807   }
1808 
1809   /// The attribute's expression operand, if it has one.
1810   ///    int * __attribute__((address_space(11)))
1811   ///                                       ^~
1812   Expr *getAttrExprOperand() const {
1813     return getLocalData()->ExprOperand;
1814   }
1815   void setAttrExprOperand(Expr *e) {
1816     getLocalData()->ExprOperand = e;
1817   }
1818 
1819   /// The location of the parentheses around the operand, if there is
1820   /// an operand.
1821   ///    int * __attribute__((address_space(11)))
1822   ///                                      ^  ^
1823   SourceRange getAttrOperandParensRange() const {
1824     return getLocalData()->OperandParens;
1825   }
1826   void setAttrOperandParensRange(SourceRange range) {
1827     getLocalData()->OperandParens = range;
1828   }
1829 
1830   SourceRange getLocalSourceRange() const {
1831     SourceRange range(getAttrNameLoc());
1832     range.setEnd(getAttrOperandParensRange().getEnd());
1833     return range;
1834   }
1835 
1836   ///  Returns the type before the address space attribute application
1837   ///  area.
1838   ///    int * __attribute__((address_space(11))) *
1839   ///    ^   ^
1840   QualType getInnerType() const {
1841     return this->getTypePtr()->getPointeeType();
1842   }
1843 
1844   TypeLoc getPointeeTypeLoc() const {
1845     return this->getInnerTypeLoc();
1846   }
1847 
1848   void initializeLocal(ASTContext &Context, SourceLocation loc) {
1849     setAttrNameLoc(loc);
1850     setAttrOperandParensRange(loc);
1851     setAttrOperandParensRange(SourceRange(loc));
1852     setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1853   }
1854 };
1855 
1856 //===----------------------------------------------------------------------===//
1857 //
1858 //  All of these need proper implementations.
1859 //
1860 //===----------------------------------------------------------------------===//
1861 
1862 // FIXME: size expression and attribute locations (or keyword if we
1863 // ever fully support altivec syntax).
1864 struct VectorTypeLocInfo {
1865   SourceLocation NameLoc;
1866 };
1867 
1868 class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
1869                                              VectorType, VectorTypeLocInfo> {
1870 public:
1871   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1872 
1873   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1874 
1875   SourceRange getLocalSourceRange() const {
1876     return SourceRange(getNameLoc(), getNameLoc());
1877   }
1878 
1879   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1880     setNameLoc(Loc);
1881   }
1882 
1883   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1884 
1885   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1886 };
1887 
1888 // FIXME: size expression and attribute locations (or keyword if we
1889 // ever fully support altivec syntax).
1890 class DependentVectorTypeLoc
1891     : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc,
1892                              DependentVectorType, VectorTypeLocInfo> {
1893 public:
1894   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1895 
1896   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1897 
1898   SourceRange getLocalSourceRange() const {
1899     return SourceRange(getNameLoc(), getNameLoc());
1900   }
1901 
1902   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1903     setNameLoc(Loc);
1904   }
1905 
1906   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1907 
1908   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1909 };
1910 
1911 // FIXME: size expression and attribute locations.
1912 class ExtVectorTypeLoc
1913     : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc,
1914                                        ExtVectorType> {};
1915 
1916 // FIXME: attribute locations.
1917 // For some reason, this isn't a subtype of VectorType.
1918 class DependentSizedExtVectorTypeLoc
1919     : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc,
1920                              DependentSizedExtVectorType, VectorTypeLocInfo> {
1921 public:
1922   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1923 
1924   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1925 
1926   SourceRange getLocalSourceRange() const {
1927     return SourceRange(getNameLoc(), getNameLoc());
1928   }
1929 
1930   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1931     setNameLoc(Loc);
1932   }
1933 
1934   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1935 
1936   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1937 };
1938 
1939 struct MatrixTypeLocInfo {
1940   SourceLocation AttrLoc;
1941   SourceRange OperandParens;
1942   Expr *RowOperand;
1943   Expr *ColumnOperand;
1944 };
1945 
1946 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc,
1947                                              MatrixType, MatrixTypeLocInfo> {
1948 public:
1949   /// The location of the attribute name, i.e.
1950   ///    float __attribute__((matrix_type(4, 2)))
1951   ///                         ^~~~~~~~~~~~~~~~~
1952   SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
1953   void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; }
1954 
1955   /// The attribute's row operand, if it has one.
1956   ///    float __attribute__((matrix_type(4, 2)))
1957   ///                                     ^
1958   Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; }
1959   void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; }
1960 
1961   /// The attribute's column operand, if it has one.
1962   ///    float __attribute__((matrix_type(4, 2)))
1963   ///                                        ^
1964   Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; }
1965   void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; }
1966 
1967   /// The location of the parentheses around the operand, if there is
1968   /// an operand.
1969   ///    float __attribute__((matrix_type(4, 2)))
1970   ///                                    ^    ^
1971   SourceRange getAttrOperandParensRange() const {
1972     return getLocalData()->OperandParens;
1973   }
1974   void setAttrOperandParensRange(SourceRange range) {
1975     getLocalData()->OperandParens = range;
1976   }
1977 
1978   SourceRange getLocalSourceRange() const {
1979     SourceRange range(getAttrNameLoc());
1980     range.setEnd(getAttrOperandParensRange().getEnd());
1981     return range;
1982   }
1983 
1984   void initializeLocal(ASTContext &Context, SourceLocation loc) {
1985     setAttrNameLoc(loc);
1986     setAttrOperandParensRange(loc);
1987     setAttrRowOperand(nullptr);
1988     setAttrColumnOperand(nullptr);
1989   }
1990 };
1991 
1992 class ConstantMatrixTypeLoc
1993     : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc,
1994                                        ConstantMatrixType> {};
1995 
1996 class DependentSizedMatrixTypeLoc
1997     : public InheritingConcreteTypeLoc<MatrixTypeLoc,
1998                                        DependentSizedMatrixTypeLoc,
1999                                        DependentSizedMatrixType> {};
2000 
2001 // FIXME: location of the '_Complex' keyword.
2002 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
2003                                                         ComplexTypeLoc,
2004                                                         ComplexType> {
2005 };
2006 
2007 struct TypeofLocInfo {
2008   SourceLocation TypeofLoc;
2009   SourceLocation LParenLoc;
2010   SourceLocation RParenLoc;
2011 };
2012 
2013 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
2014 };
2015 
2016 struct TypeOfTypeLocInfo : public TypeofLocInfo {
2017   TypeSourceInfo *UnmodifiedTInfo;
2018 };
2019 
2020 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
2021 class TypeofLikeTypeLoc
2022   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
2023 public:
2024   SourceLocation getTypeofLoc() const {
2025     return this->getLocalData()->TypeofLoc;
2026   }
2027 
2028   void setTypeofLoc(SourceLocation Loc) {
2029     this->getLocalData()->TypeofLoc = Loc;
2030   }
2031 
2032   SourceLocation getLParenLoc() const {
2033     return this->getLocalData()->LParenLoc;
2034   }
2035 
2036   void setLParenLoc(SourceLocation Loc) {
2037     this->getLocalData()->LParenLoc = Loc;
2038   }
2039 
2040   SourceLocation getRParenLoc() const {
2041     return this->getLocalData()->RParenLoc;
2042   }
2043 
2044   void setRParenLoc(SourceLocation Loc) {
2045     this->getLocalData()->RParenLoc = Loc;
2046   }
2047 
2048   SourceRange getParensRange() const {
2049     return SourceRange(getLParenLoc(), getRParenLoc());
2050   }
2051 
2052   void setParensRange(SourceRange range) {
2053       setLParenLoc(range.getBegin());
2054       setRParenLoc(range.getEnd());
2055   }
2056 
2057   SourceRange getLocalSourceRange() const {
2058     return SourceRange(getTypeofLoc(), getRParenLoc());
2059   }
2060 
2061   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2062     setTypeofLoc(Loc);
2063     setLParenLoc(Loc);
2064     setRParenLoc(Loc);
2065   }
2066 };
2067 
2068 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
2069                                                    TypeOfExprType,
2070                                                    TypeOfExprTypeLocInfo> {
2071 public:
2072   Expr* getUnderlyingExpr() const {
2073     return getTypePtr()->getUnderlyingExpr();
2074   }
2075 
2076   // Reimplemented to account for GNU/C++ extension
2077   //     typeof unary-expression
2078   // where there are no parentheses.
2079   SourceRange getLocalSourceRange() const;
2080 };
2081 
2082 class TypeOfTypeLoc
2083   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
2084 public:
2085   QualType getUnmodifiedType() const {
2086     return this->getTypePtr()->getUnmodifiedType();
2087   }
2088 
2089   TypeSourceInfo *getUnmodifiedTInfo() const {
2090     return this->getLocalData()->UnmodifiedTInfo;
2091   }
2092 
2093   void setUnmodifiedTInfo(TypeSourceInfo *TI) const {
2094     this->getLocalData()->UnmodifiedTInfo = TI;
2095   }
2096 
2097   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2098 };
2099 
2100 // decltype(expression) abc;
2101 // ~~~~~~~~                  DecltypeLoc
2102 //                    ~      RParenLoc
2103 // FIXME: add LParenLoc, it is tricky to support due to the limitation of
2104 // annotated-decltype token.
2105 struct DecltypeTypeLocInfo {
2106   SourceLocation DecltypeLoc;
2107   SourceLocation RParenLoc;
2108 };
2109 class DecltypeTypeLoc
2110     : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType,
2111                              DecltypeTypeLocInfo> {
2112 public:
2113   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
2114 
2115   SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; }
2116   void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; }
2117 
2118   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2119   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2120 
2121   SourceRange getLocalSourceRange() const {
2122     return SourceRange(getDecltypeLoc(), getRParenLoc());
2123   }
2124 
2125   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2126     setDecltypeLoc(Loc);
2127     setRParenLoc(Loc);
2128   }
2129 };
2130 
2131 struct PackIndexingTypeLocInfo {
2132   SourceLocation EllipsisLoc;
2133 };
2134 
2135 class PackIndexingTypeLoc
2136     : public ConcreteTypeLoc<UnqualTypeLoc, PackIndexingTypeLoc,
2137                              PackIndexingType, PackIndexingTypeLocInfo> {
2138 
2139 public:
2140   Expr *getIndexExpr() const { return getTypePtr()->getIndexExpr(); }
2141   QualType getPattern() const { return getTypePtr()->getPattern(); }
2142 
2143   SourceLocation getEllipsisLoc() const { return getLocalData()->EllipsisLoc; }
2144   void setEllipsisLoc(SourceLocation Loc) { getLocalData()->EllipsisLoc = Loc; }
2145 
2146   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2147     setEllipsisLoc(Loc);
2148   }
2149 
2150   TypeLoc getPatternLoc() const { return getInnerTypeLoc(); }
2151 
2152   QualType getInnerType() const { return this->getTypePtr()->getPattern(); }
2153 
2154   SourceRange getLocalSourceRange() const {
2155     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2156   }
2157 };
2158 
2159 struct UnaryTransformTypeLocInfo {
2160   // FIXME: While there's only one unary transform right now, future ones may
2161   // need different representations
2162   SourceLocation KWLoc, LParenLoc, RParenLoc;
2163   TypeSourceInfo *UnderlyingTInfo;
2164 };
2165 
2166 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2167                                                     UnaryTransformTypeLoc,
2168                                                     UnaryTransformType,
2169                                                     UnaryTransformTypeLocInfo> {
2170 public:
2171   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
2172   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
2173 
2174   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
2175   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
2176 
2177   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2178   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2179 
2180   TypeSourceInfo* getUnderlyingTInfo() const {
2181     return getLocalData()->UnderlyingTInfo;
2182   }
2183 
2184   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
2185     getLocalData()->UnderlyingTInfo = TInfo;
2186   }
2187 
2188   SourceRange getLocalSourceRange() const {
2189     return SourceRange(getKWLoc(), getRParenLoc());
2190   }
2191 
2192   SourceRange getParensRange() const {
2193     return SourceRange(getLParenLoc(), getRParenLoc());
2194   }
2195 
2196   void setParensRange(SourceRange Range) {
2197     setLParenLoc(Range.getBegin());
2198     setRParenLoc(Range.getEnd());
2199   }
2200 
2201   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2202 };
2203 
2204 class DeducedTypeLoc
2205     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
2206                                        DeducedType> {};
2207 
2208 struct AutoTypeLocInfo : TypeSpecLocInfo {
2209   // For decltype(auto).
2210   SourceLocation RParenLoc;
2211 
2212   ConceptReference *CR = nullptr;
2213 };
2214 
2215 class AutoTypeLoc
2216     : public ConcreteTypeLoc<DeducedTypeLoc,
2217                              AutoTypeLoc,
2218                              AutoType,
2219                              AutoTypeLocInfo> {
2220 public:
2221   AutoTypeKeyword getAutoKeyword() const {
2222     return getTypePtr()->getKeyword();
2223   }
2224 
2225   bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
2226   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2227   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2228 
2229   bool isConstrained() const {
2230     return getTypePtr()->isConstrained();
2231   }
2232 
2233   void setConceptReference(ConceptReference *CR) { getLocalData()->CR = CR; }
2234 
2235   ConceptReference *getConceptReference() const { return getLocalData()->CR; }
2236 
2237   // FIXME: Several of the following functions can be removed. Instead the
2238   // caller can directly work with the ConceptReference.
2239   const NestedNameSpecifierLoc getNestedNameSpecifierLoc() const {
2240     if (const auto *CR = getConceptReference())
2241       return CR->getNestedNameSpecifierLoc();
2242     return NestedNameSpecifierLoc();
2243   }
2244 
2245   SourceLocation getTemplateKWLoc() const {
2246     if (const auto *CR = getConceptReference())
2247       return CR->getTemplateKWLoc();
2248     return SourceLocation();
2249   }
2250 
2251   SourceLocation getConceptNameLoc() const {
2252     if (const auto *CR = getConceptReference())
2253       return CR->getConceptNameLoc();
2254     return SourceLocation();
2255   }
2256 
2257   NamedDecl *getFoundDecl() const {
2258     if (const auto *CR = getConceptReference())
2259       return CR->getFoundDecl();
2260     return nullptr;
2261   }
2262 
2263   ConceptDecl *getNamedConcept() const {
2264     if (const auto *CR = getConceptReference())
2265       return CR->getNamedConcept();
2266     return nullptr;
2267   }
2268 
2269   DeclarationNameInfo getConceptNameInfo() const {
2270     return getConceptReference()->getConceptNameInfo();
2271   }
2272 
2273   bool hasExplicitTemplateArgs() const {
2274     return (getConceptReference() &&
2275             getConceptReference()->getTemplateArgsAsWritten() &&
2276             getConceptReference()
2277                 ->getTemplateArgsAsWritten()
2278                 ->getLAngleLoc()
2279                 .isValid());
2280   }
2281 
2282   SourceLocation getLAngleLoc() const {
2283     if (const auto *CR = getConceptReference())
2284       if (const auto *TAAW = CR->getTemplateArgsAsWritten())
2285         return TAAW->getLAngleLoc();
2286     return SourceLocation();
2287   }
2288 
2289   SourceLocation getRAngleLoc() const {
2290     if (const auto *CR = getConceptReference())
2291       if (const auto *TAAW = CR->getTemplateArgsAsWritten())
2292         return TAAW->getRAngleLoc();
2293     return SourceLocation();
2294   }
2295 
2296   unsigned getNumArgs() const {
2297     return getTypePtr()->getTypeConstraintArguments().size();
2298   }
2299 
2300   TemplateArgumentLoc getArgLoc(unsigned i) const {
2301     const auto *CR = getConceptReference();
2302     assert(CR && "No ConceptReference");
2303     return CR->getTemplateArgsAsWritten()->getTemplateArgs()[i];
2304   }
2305 
2306   SourceRange getLocalSourceRange() const {
2307     return {isConstrained()
2308                 ? (getNestedNameSpecifierLoc()
2309                        ? getNestedNameSpecifierLoc().getBeginLoc()
2310                        : (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
2311                                                        : getConceptNameLoc()))
2312                 : getNameLoc(),
2313             isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
2314   }
2315 
2316   void copy(AutoTypeLoc Loc) {
2317     unsigned size = getFullDataSize();
2318     assert(size == Loc.getFullDataSize());
2319     memcpy(Data, Loc.Data, size);
2320   }
2321 
2322   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2323 };
2324 
2325 class DeducedTemplateSpecializationTypeLoc
2326     : public InheritingConcreteTypeLoc<DeducedTypeLoc,
2327                                        DeducedTemplateSpecializationTypeLoc,
2328                                        DeducedTemplateSpecializationType> {
2329 public:
2330   SourceLocation getTemplateNameLoc() const {
2331     return getNameLoc();
2332   }
2333 
2334   void setTemplateNameLoc(SourceLocation Loc) {
2335     setNameLoc(Loc);
2336   }
2337 };
2338 
2339 struct ElaboratedLocInfo {
2340   SourceLocation ElaboratedKWLoc;
2341 
2342   /// Data associated with the nested-name-specifier location.
2343   void *QualifierData;
2344 };
2345 
2346 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2347                                                  ElaboratedTypeLoc,
2348                                                  ElaboratedType,
2349                                                  ElaboratedLocInfo> {
2350 public:
2351   SourceLocation getElaboratedKeywordLoc() const {
2352     return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation();
2353   }
2354 
2355   void setElaboratedKeywordLoc(SourceLocation Loc) {
2356     if (isEmpty()) {
2357       assert(Loc.isInvalid());
2358       return;
2359     }
2360     getLocalData()->ElaboratedKWLoc = Loc;
2361   }
2362 
2363   NestedNameSpecifierLoc getQualifierLoc() const {
2364     return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2365                                                getLocalData()->QualifierData)
2366                       : NestedNameSpecifierLoc();
2367   }
2368 
2369   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2370     assert(QualifierLoc.getNestedNameSpecifier() ==
2371                getTypePtr()->getQualifier() &&
2372            "Inconsistent nested-name-specifier pointer");
2373     if (isEmpty()) {
2374       assert(!QualifierLoc.hasQualifier());
2375       return;
2376     }
2377     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2378   }
2379 
2380   SourceRange getLocalSourceRange() const {
2381     if (getElaboratedKeywordLoc().isValid())
2382       if (getQualifierLoc())
2383         return SourceRange(getElaboratedKeywordLoc(),
2384                            getQualifierLoc().getEndLoc());
2385       else
2386         return SourceRange(getElaboratedKeywordLoc());
2387     else
2388       return getQualifierLoc().getSourceRange();
2389   }
2390 
2391   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2392 
2393   TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); }
2394 
2395   QualType getInnerType() const { return getTypePtr()->getNamedType(); }
2396 
2397   bool isEmpty() const {
2398     return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::None &&
2399            !getTypePtr()->getQualifier();
2400   }
2401 
2402   unsigned getLocalDataAlignment() const {
2403     // FIXME: We want to return 1 here in the empty case, but
2404     // there are bugs in how alignment is handled in TypeLocs
2405     // that prevent this from working.
2406     return ConcreteTypeLoc::getLocalDataAlignment();
2407   }
2408 
2409   unsigned getLocalDataSize() const {
2410     return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0;
2411   }
2412 
2413   void copy(ElaboratedTypeLoc Loc) {
2414     unsigned size = getFullDataSize();
2415     assert(size == Loc.getFullDataSize());
2416     memcpy(Data, Loc.Data, size);
2417   }
2418 };
2419 
2420 // This is exactly the structure of an ElaboratedTypeLoc whose inner
2421 // type is some sort of TypeDeclTypeLoc.
2422 struct DependentNameLocInfo : ElaboratedLocInfo {
2423   SourceLocation NameLoc;
2424 };
2425 
2426 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2427                                                     DependentNameTypeLoc,
2428                                                     DependentNameType,
2429                                                     DependentNameLocInfo> {
2430 public:
2431   SourceLocation getElaboratedKeywordLoc() const {
2432     return this->getLocalData()->ElaboratedKWLoc;
2433   }
2434 
2435   void setElaboratedKeywordLoc(SourceLocation Loc) {
2436     this->getLocalData()->ElaboratedKWLoc = Loc;
2437   }
2438 
2439   NestedNameSpecifierLoc getQualifierLoc() const {
2440     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2441                                   getLocalData()->QualifierData);
2442   }
2443 
2444   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2445     assert(QualifierLoc.getNestedNameSpecifier()
2446                                             == getTypePtr()->getQualifier() &&
2447            "Inconsistent nested-name-specifier pointer");
2448     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2449   }
2450 
2451   SourceLocation getNameLoc() const {
2452     return this->getLocalData()->NameLoc;
2453   }
2454 
2455   void setNameLoc(SourceLocation Loc) {
2456     this->getLocalData()->NameLoc = Loc;
2457   }
2458 
2459   SourceRange getLocalSourceRange() const {
2460     if (getElaboratedKeywordLoc().isValid())
2461       return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2462     else
2463       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2464   }
2465 
2466   void copy(DependentNameTypeLoc Loc) {
2467     unsigned size = getFullDataSize();
2468     assert(size == Loc.getFullDataSize());
2469     memcpy(Data, Loc.Data, size);
2470   }
2471 
2472   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2473 };
2474 
2475 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2476   SourceLocation TemplateKWLoc;
2477   SourceLocation LAngleLoc;
2478   SourceLocation RAngleLoc;
2479   // followed by a TemplateArgumentLocInfo[]
2480 };
2481 
2482 class DependentTemplateSpecializationTypeLoc :
2483     public ConcreteTypeLoc<UnqualTypeLoc,
2484                            DependentTemplateSpecializationTypeLoc,
2485                            DependentTemplateSpecializationType,
2486                            DependentTemplateSpecializationLocInfo> {
2487 public:
2488   SourceLocation getElaboratedKeywordLoc() const {
2489     return this->getLocalData()->ElaboratedKWLoc;
2490   }
2491 
2492   void setElaboratedKeywordLoc(SourceLocation Loc) {
2493     this->getLocalData()->ElaboratedKWLoc = Loc;
2494   }
2495 
2496   NestedNameSpecifierLoc getQualifierLoc() const {
2497     if (!getLocalData()->QualifierData)
2498       return NestedNameSpecifierLoc();
2499 
2500     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2501                                   getLocalData()->QualifierData);
2502   }
2503 
2504   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2505     if (!QualifierLoc) {
2506       // Even if we have a nested-name-specifier in the dependent
2507       // template specialization type, we won't record the nested-name-specifier
2508       // location information when this type-source location information is
2509       // part of a nested-name-specifier.
2510       getLocalData()->QualifierData = nullptr;
2511       return;
2512     }
2513 
2514     assert(QualifierLoc.getNestedNameSpecifier()
2515                                         == getTypePtr()->getQualifier() &&
2516            "Inconsistent nested-name-specifier pointer");
2517     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2518   }
2519 
2520   SourceLocation getTemplateKeywordLoc() const {
2521     return getLocalData()->TemplateKWLoc;
2522   }
2523 
2524   void setTemplateKeywordLoc(SourceLocation Loc) {
2525     getLocalData()->TemplateKWLoc = Loc;
2526   }
2527 
2528   SourceLocation getTemplateNameLoc() const {
2529     return this->getLocalData()->NameLoc;
2530   }
2531 
2532   void setTemplateNameLoc(SourceLocation Loc) {
2533     this->getLocalData()->NameLoc = Loc;
2534   }
2535 
2536   SourceLocation getLAngleLoc() const {
2537     return this->getLocalData()->LAngleLoc;
2538   }
2539 
2540   void setLAngleLoc(SourceLocation Loc) {
2541     this->getLocalData()->LAngleLoc = Loc;
2542   }
2543 
2544   SourceLocation getRAngleLoc() const {
2545     return this->getLocalData()->RAngleLoc;
2546   }
2547 
2548   void setRAngleLoc(SourceLocation Loc) {
2549     this->getLocalData()->RAngleLoc = Loc;
2550   }
2551 
2552   unsigned getNumArgs() const {
2553     return getTypePtr()->template_arguments().size();
2554   }
2555 
2556   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2557     getArgInfos()[i] = AI;
2558   }
2559 
2560   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2561     return getArgInfos()[i];
2562   }
2563 
2564   TemplateArgumentLoc getArgLoc(unsigned i) const {
2565     return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
2566                                getArgLocInfo(i));
2567   }
2568 
2569   SourceRange getLocalSourceRange() const {
2570     if (getElaboratedKeywordLoc().isValid())
2571       return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2572     else if (getQualifierLoc())
2573       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2574     else if (getTemplateKeywordLoc().isValid())
2575       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2576     else
2577       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2578   }
2579 
2580   void copy(DependentTemplateSpecializationTypeLoc Loc) {
2581     unsigned size = getFullDataSize();
2582     assert(size == Loc.getFullDataSize());
2583     memcpy(Data, Loc.Data, size);
2584   }
2585 
2586   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2587 
2588   unsigned getExtraLocalDataSize() const {
2589     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2590   }
2591 
2592   unsigned getExtraLocalDataAlignment() const {
2593     return alignof(TemplateArgumentLocInfo);
2594   }
2595 
2596 private:
2597   TemplateArgumentLocInfo *getArgInfos() const {
2598     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2599   }
2600 };
2601 
2602 struct PackExpansionTypeLocInfo {
2603   SourceLocation EllipsisLoc;
2604 };
2605 
2606 class PackExpansionTypeLoc
2607   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2608                            PackExpansionType, PackExpansionTypeLocInfo> {
2609 public:
2610   SourceLocation getEllipsisLoc() const {
2611     return this->getLocalData()->EllipsisLoc;
2612   }
2613 
2614   void setEllipsisLoc(SourceLocation Loc) {
2615     this->getLocalData()->EllipsisLoc = Loc;
2616   }
2617 
2618   SourceRange getLocalSourceRange() const {
2619     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2620   }
2621 
2622   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2623     setEllipsisLoc(Loc);
2624   }
2625 
2626   TypeLoc getPatternLoc() const {
2627     return getInnerTypeLoc();
2628   }
2629 
2630   QualType getInnerType() const {
2631     return this->getTypePtr()->getPattern();
2632   }
2633 };
2634 
2635 struct AtomicTypeLocInfo {
2636   SourceLocation KWLoc, LParenLoc, RParenLoc;
2637 };
2638 
2639 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2640                                              AtomicType, AtomicTypeLocInfo> {
2641 public:
2642   TypeLoc getValueLoc() const {
2643     return this->getInnerTypeLoc();
2644   }
2645 
2646   SourceRange getLocalSourceRange() const {
2647     return SourceRange(getKWLoc(), getRParenLoc());
2648   }
2649 
2650   SourceLocation getKWLoc() const {
2651     return this->getLocalData()->KWLoc;
2652   }
2653 
2654   void setKWLoc(SourceLocation Loc) {
2655     this->getLocalData()->KWLoc = Loc;
2656   }
2657 
2658   SourceLocation getLParenLoc() const {
2659     return this->getLocalData()->LParenLoc;
2660   }
2661 
2662   void setLParenLoc(SourceLocation Loc) {
2663     this->getLocalData()->LParenLoc = Loc;
2664   }
2665 
2666   SourceLocation getRParenLoc() const {
2667     return this->getLocalData()->RParenLoc;
2668   }
2669 
2670   void setRParenLoc(SourceLocation Loc) {
2671     this->getLocalData()->RParenLoc = Loc;
2672   }
2673 
2674   SourceRange getParensRange() const {
2675     return SourceRange(getLParenLoc(), getRParenLoc());
2676   }
2677 
2678   void setParensRange(SourceRange Range) {
2679     setLParenLoc(Range.getBegin());
2680     setRParenLoc(Range.getEnd());
2681   }
2682 
2683   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2684     setKWLoc(Loc);
2685     setLParenLoc(Loc);
2686     setRParenLoc(Loc);
2687   }
2688 
2689   QualType getInnerType() const {
2690     return this->getTypePtr()->getValueType();
2691   }
2692 };
2693 
2694 struct PipeTypeLocInfo {
2695   SourceLocation KWLoc;
2696 };
2697 
2698 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2699                                            PipeTypeLocInfo> {
2700 public:
2701   TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2702 
2703   SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2704 
2705   SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2706   void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2707 
2708   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2709     setKWLoc(Loc);
2710   }
2711 
2712   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2713 };
2714 
2715 template <typename T>
2716 inline T TypeLoc::getAsAdjusted() const {
2717   TypeLoc Cur = *this;
2718   while (!T::isKind(Cur)) {
2719     if (auto PTL = Cur.getAs<ParenTypeLoc>())
2720       Cur = PTL.getInnerLoc();
2721     else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2722       Cur = ATL.getModifiedLoc();
2723     else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
2724       Cur = ATL.getWrappedLoc();
2725     else if (auto ATL = Cur.getAs<HLSLAttributedResourceTypeLoc>())
2726       Cur = ATL.getWrappedLoc();
2727     else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2728       Cur = ETL.getNamedTypeLoc();
2729     else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2730       Cur = ATL.getOriginalLoc();
2731     else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2732       Cur = MQL.getInnerLoc();
2733     else
2734       break;
2735   }
2736   return Cur.getAs<T>();
2737 }
2738 class BitIntTypeLoc final
2739     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
2740                                        BitIntType> {};
2741 class DependentBitIntTypeLoc final
2742     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
2743                                        DependentBitIntType> {};
2744 
2745 class ObjCProtocolLoc {
2746   ObjCProtocolDecl *Protocol = nullptr;
2747   SourceLocation Loc = SourceLocation();
2748 
2749 public:
2750   ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc)
2751       : Protocol(protocol), Loc(loc) {}
2752   ObjCProtocolDecl *getProtocol() const { return Protocol; }
2753   SourceLocation getLocation() const { return Loc; }
2754 
2755   /// The source range is just the protocol name.
2756   SourceRange getSourceRange() const LLVM_READONLY {
2757     return SourceRange(Loc, Loc);
2758   }
2759 };
2760 
2761 } // namespace clang
2762 
2763 #endif // LLVM_CLANG_AST_TYPELOC_H