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