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