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