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 public:
    542   CXXRecordDecl *getDecl() const {
    543     return getTypePtr()->getDecl();
    544   }
    545 };
    546 
    547 /// \brief Wrapper for source info for unresolved typename using decls.
    548 class UnresolvedUsingTypeLoc :
    549     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
    550                                      UnresolvedUsingTypeLoc,
    551                                      UnresolvedUsingType> {
    552 public:
    553   UnresolvedUsingTypenameDecl *getDecl() const {
    554     return getTypePtr()->getDecl();
    555   }
    556 };
    557 
    558 /// \brief Wrapper for source info for tag types.  Note that this only
    559 /// records source info for the name itself; a type written 'struct foo'
    560 /// should be represented as an ElaboratedTypeLoc.  We currently
    561 /// only do that when C++ is enabled because of the expense of
    562 /// creating an ElaboratedType node for so many type references in C.
    563 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
    564                                                     TagTypeLoc,
    565                                                     TagType> {
    566 public:
    567   TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
    568 
    569   /// \brief True if the tag was defined in this type specifier.
    570   bool isDefinition() const {
    571     return getDecl()->isCompleteDefinition() &&
    572          (getNameLoc().isInvalid() || getNameLoc() == getDecl()->getLocation());
    573   }
    574 };
    575 
    576 /// \brief Wrapper for source info for record types.
    577 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
    578                                                        RecordTypeLoc,
    579                                                        RecordType> {
    580 public:
    581   RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
    582 };
    583 
    584 /// \brief Wrapper for source info for enum types.
    585 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
    586                                                      EnumTypeLoc,
    587                                                      EnumType> {
    588 public:
    589   EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
    590 };
    591 
    592 /// \brief Wrapper for template type parameters.
    593 class TemplateTypeParmTypeLoc :
    594     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
    595                                      TemplateTypeParmTypeLoc,
    596                                      TemplateTypeParmType> {
    597 public:
    598   TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
    599 };
    600 
    601 /// \brief Wrapper for substituted template type parameters.
    602 class SubstTemplateTypeParmTypeLoc :
    603     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
    604                                      SubstTemplateTypeParmTypeLoc,
    605                                      SubstTemplateTypeParmType> {
    606 };
    607 
    608   /// \brief Wrapper for substituted template type parameters.
    609 class SubstTemplateTypeParmPackTypeLoc :
    610     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
    611                                      SubstTemplateTypeParmPackTypeLoc,
    612                                      SubstTemplateTypeParmPackType> {
    613 };
    614 
    615 struct AttributedLocInfo {
    616   union {
    617     Expr *ExprOperand;
    618 
    619     /// A raw SourceLocation.
    620     unsigned EnumOperandLoc;
    621   };
    622 
    623   SourceRange OperandParens;
    624 
    625   SourceLocation AttrLoc;
    626 };
    627 
    628 /// \brief Type source information for an attributed type.
    629 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
    630                                                  AttributedTypeLoc,
    631                                                  AttributedType,
    632                                                  AttributedLocInfo> {
    633 public:
    634   AttributedType::Kind getAttrKind() const {
    635     return getTypePtr()->getAttrKind();
    636   }
    637 
    638   bool hasAttrExprOperand() const {
    639     return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
    640             getAttrKind() <= AttributedType::LastExprOperandKind);
    641   }
    642 
    643   bool hasAttrEnumOperand() const {
    644     return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
    645             getAttrKind() <= AttributedType::LastEnumOperandKind);
    646   }
    647 
    648   bool hasAttrOperand() const {
    649     return hasAttrExprOperand() || hasAttrEnumOperand();
    650   }
    651 
    652   /// The modified type, which is generally canonically different from
    653   /// the attribute type.
    654   ///    int main(int, char**) __attribute__((noreturn))
    655   ///    ~~~     ~~~~~~~~~~~~~
    656   TypeLoc getModifiedLoc() const {
    657     return getInnerTypeLoc();
    658   }
    659 
    660   /// The location of the attribute name, i.e.
    661   ///    __attribute__((regparm(1000)))
    662   ///                   ^~~~~~~
    663   SourceLocation getAttrNameLoc() const {
    664     return getLocalData()->AttrLoc;
    665   }
    666   void setAttrNameLoc(SourceLocation loc) {
    667     getLocalData()->AttrLoc = loc;
    668   }
    669 
    670   /// The attribute's expression operand, if it has one.
    671   ///    void *cur_thread __attribute__((address_space(21)))
    672   ///                                                  ^~
    673   Expr *getAttrExprOperand() const {
    674     assert(hasAttrExprOperand());
    675     return getLocalData()->ExprOperand;
    676   }
    677   void setAttrExprOperand(Expr *e) {
    678     assert(hasAttrExprOperand());
    679     getLocalData()->ExprOperand = e;
    680   }
    681 
    682   /// The location of the attribute's enumerated operand, if it has one.
    683   ///    void * __attribute__((objc_gc(weak)))
    684   ///                                  ^~~~
    685   SourceLocation getAttrEnumOperandLoc() const {
    686     assert(hasAttrEnumOperand());
    687     return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
    688   }
    689   void setAttrEnumOperandLoc(SourceLocation loc) {
    690     assert(hasAttrEnumOperand());
    691     getLocalData()->EnumOperandLoc = loc.getRawEncoding();
    692   }
    693 
    694   /// The location of the parentheses around the operand, if there is
    695   /// an operand.
    696   ///    void * __attribute__((objc_gc(weak)))
    697   ///                                 ^    ^
    698   SourceRange getAttrOperandParensRange() const {
    699     assert(hasAttrOperand());
    700     return getLocalData()->OperandParens;
    701   }
    702   void setAttrOperandParensRange(SourceRange range) {
    703     assert(hasAttrOperand());
    704     getLocalData()->OperandParens = range;
    705   }
    706 
    707   SourceRange getLocalSourceRange() const {
    708     // Note that this does *not* include the range of the attribute
    709     // enclosure, e.g.:
    710     //    __attribute__((foo(bar)))
    711     //    ^~~~~~~~~~~~~~~        ~~
    712     // or
    713     //    [[foo(bar)]]
    714     //    ^~        ~~
    715     // That enclosure doesn't necessarily belong to a single attribute
    716     // anyway.
    717     SourceRange range(getAttrNameLoc());
    718     if (hasAttrOperand())
    719       range.setEnd(getAttrOperandParensRange().getEnd());
    720     return range;
    721   }
    722 
    723   void initializeLocal(ASTContext &Context, SourceLocation loc) {
    724     setAttrNameLoc(loc);
    725     if (hasAttrExprOperand()) {
    726       setAttrOperandParensRange(SourceRange(loc));
    727       setAttrExprOperand(0);
    728     } else if (hasAttrEnumOperand()) {
    729       setAttrOperandParensRange(SourceRange(loc));
    730       setAttrEnumOperandLoc(loc);
    731     }
    732   }
    733 
    734   QualType getInnerType() const {
    735     return getTypePtr()->getModifiedType();
    736   }
    737 };
    738 
    739 
    740 struct ObjCProtocolListLocInfo {
    741   SourceLocation LAngleLoc;
    742   SourceLocation RAngleLoc;
    743   bool HasBaseTypeAsWritten;
    744 };
    745 
    746 // A helper class for defining ObjC TypeLocs that can qualified with
    747 // protocols.
    748 //
    749 // TypeClass basically has to be either ObjCInterfaceType or
    750 // ObjCObjectPointerType.
    751 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
    752                                                  ObjCObjectTypeLoc,
    753                                                  ObjCObjectType,
    754                                                  ObjCProtocolListLocInfo> {
    755   // SourceLocations are stored after Info, one for each Protocol.
    756   SourceLocation *getProtocolLocArray() const {
    757     return (SourceLocation*) this->getExtraLocalData();
    758   }
    759 
    760 public:
    761   SourceLocation getLAngleLoc() const {
    762     return this->getLocalData()->LAngleLoc;
    763   }
    764   void setLAngleLoc(SourceLocation Loc) {
    765     this->getLocalData()->LAngleLoc = Loc;
    766   }
    767 
    768   SourceLocation getRAngleLoc() const {
    769     return this->getLocalData()->RAngleLoc;
    770   }
    771   void setRAngleLoc(SourceLocation Loc) {
    772     this->getLocalData()->RAngleLoc = Loc;
    773   }
    774 
    775   unsigned getNumProtocols() const {
    776     return this->getTypePtr()->getNumProtocols();
    777   }
    778 
    779   SourceLocation getProtocolLoc(unsigned i) const {
    780     assert(i < getNumProtocols() && "Index is out of bounds!");
    781     return getProtocolLocArray()[i];
    782   }
    783   void setProtocolLoc(unsigned i, SourceLocation Loc) {
    784     assert(i < getNumProtocols() && "Index is out of bounds!");
    785     getProtocolLocArray()[i] = Loc;
    786   }
    787 
    788   ObjCProtocolDecl *getProtocol(unsigned i) const {
    789     assert(i < getNumProtocols() && "Index is out of bounds!");
    790     return *(this->getTypePtr()->qual_begin() + i);
    791   }
    792 
    793   bool hasBaseTypeAsWritten() const {
    794     return getLocalData()->HasBaseTypeAsWritten;
    795   }
    796 
    797   void setHasBaseTypeAsWritten(bool HasBaseType) {
    798     getLocalData()->HasBaseTypeAsWritten = HasBaseType;
    799   }
    800 
    801   TypeLoc getBaseLoc() const {
    802     return getInnerTypeLoc();
    803   }
    804 
    805   SourceRange getLocalSourceRange() const {
    806     return SourceRange(getLAngleLoc(), getRAngleLoc());
    807   }
    808 
    809   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
    810     setHasBaseTypeAsWritten(true);
    811     setLAngleLoc(Loc);
    812     setRAngleLoc(Loc);
    813     for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
    814       setProtocolLoc(i, Loc);
    815   }
    816 
    817   unsigned getExtraLocalDataSize() const {
    818     return this->getNumProtocols() * sizeof(SourceLocation);
    819   }
    820 
    821   QualType getInnerType() const {
    822     return getTypePtr()->getBaseType();
    823   }
    824 };
    825 
    826 
    827 struct ObjCInterfaceLocInfo {
    828   SourceLocation NameLoc;
    829 };
    830 
    831 /// \brief Wrapper for source info for ObjC interfaces.
    832 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
    833                                                     ObjCInterfaceTypeLoc,
    834                                                     ObjCInterfaceType,
    835                                                     ObjCInterfaceLocInfo> {
    836 public:
    837   ObjCInterfaceDecl *getIFaceDecl() const {
    838     return getTypePtr()->getDecl();
    839   }
    840 
    841   SourceLocation getNameLoc() const {
    842     return getLocalData()->NameLoc;
    843   }
    844 
    845   void setNameLoc(SourceLocation Loc) {
    846     getLocalData()->NameLoc = Loc;
    847   }
    848 
    849   SourceRange getLocalSourceRange() const {
    850     return SourceRange(getNameLoc());
    851   }
    852 
    853   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
    854     setNameLoc(Loc);
    855   }
    856 };
    857 
    858 struct ParenLocInfo {
    859   SourceLocation LParenLoc;
    860   SourceLocation RParenLoc;
    861 };
    862 
    863 class ParenTypeLoc
    864   : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
    865                            ParenLocInfo> {
    866 public:
    867   SourceLocation getLParenLoc() const {
    868     return this->getLocalData()->LParenLoc;
    869   }
    870   SourceLocation getRParenLoc() const {
    871     return this->getLocalData()->RParenLoc;
    872   }
    873   void setLParenLoc(SourceLocation Loc) {
    874     this->getLocalData()->LParenLoc = Loc;
    875   }
    876   void setRParenLoc(SourceLocation Loc) {
    877     this->getLocalData()->RParenLoc = Loc;
    878   }
    879 
    880   SourceRange getLocalSourceRange() const {
    881     return SourceRange(getLParenLoc(), getRParenLoc());
    882   }
    883 
    884   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
    885     setLParenLoc(Loc);
    886     setRParenLoc(Loc);
    887   }
    888 
    889   TypeLoc getInnerLoc() const {
    890     return getInnerTypeLoc();
    891   }
    892 
    893   QualType getInnerType() const {
    894     return this->getTypePtr()->getInnerType();
    895   }
    896 };
    897 
    898 
    899 struct PointerLikeLocInfo {
    900   SourceLocation StarLoc;
    901 };
    902 
    903 /// A base class for
    904 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
    905 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
    906                                                   TypeClass, LocalData> {
    907 public:
    908   SourceLocation getSigilLoc() const {
    909     return this->getLocalData()->StarLoc;
    910   }
    911   void setSigilLoc(SourceLocation Loc) {
    912     this->getLocalData()->StarLoc = Loc;
    913   }
    914 
    915   TypeLoc getPointeeLoc() const {
    916     return this->getInnerTypeLoc();
    917   }
    918 
    919   SourceRange getLocalSourceRange() const {
    920     return SourceRange(getSigilLoc(), getSigilLoc());
    921   }
    922 
    923   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
    924     setSigilLoc(Loc);
    925   }
    926 
    927   QualType getInnerType() const {
    928     return this->getTypePtr()->getPointeeType();
    929   }
    930 };
    931 
    932 
    933 /// \brief Wrapper for source info for pointers.
    934 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
    935                                                  PointerType> {
    936 public:
    937   SourceLocation getStarLoc() const {
    938     return getSigilLoc();
    939   }
    940   void setStarLoc(SourceLocation Loc) {
    941     setSigilLoc(Loc);
    942   }
    943 };
    944 
    945 
    946 /// \brief Wrapper for source info for block pointers.
    947 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
    948                                                       BlockPointerType> {
    949 public:
    950   SourceLocation getCaretLoc() const {
    951     return getSigilLoc();
    952   }
    953   void setCaretLoc(SourceLocation Loc) {
    954     setSigilLoc(Loc);
    955   }
    956 };
    957 
    958 struct MemberPointerLocInfo : public PointerLikeLocInfo {
    959   TypeSourceInfo *ClassTInfo;
    960 };
    961 
    962 /// \brief Wrapper for source info for member pointers.
    963 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
    964                                                        MemberPointerType,
    965                                                        MemberPointerLocInfo> {
    966 public:
    967   SourceLocation getStarLoc() const {
    968     return getSigilLoc();
    969   }
    970   void setStarLoc(SourceLocation Loc) {
    971     setSigilLoc(Loc);
    972   }
    973 
    974   const Type *getClass() const {
    975     return getTypePtr()->getClass();
    976   }
    977   TypeSourceInfo *getClassTInfo() const {
    978     return getLocalData()->ClassTInfo;
    979   }
    980   void setClassTInfo(TypeSourceInfo* TI) {
    981     getLocalData()->ClassTInfo = TI;
    982   }
    983 
    984   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
    985     setSigilLoc(Loc);
    986     setClassTInfo(0);
    987   }
    988 
    989   SourceRange getLocalSourceRange() const {
    990     if (TypeSourceInfo *TI = getClassTInfo())
    991       return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
    992     else
    993       return SourceRange(getStarLoc());
    994   }
    995 };
    996 
    997 /// Wraps an ObjCPointerType with source location information.
    998 class ObjCObjectPointerTypeLoc :
    999     public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
   1000                               ObjCObjectPointerType> {
   1001 public:
   1002   SourceLocation getStarLoc() const {
   1003     return getSigilLoc();
   1004   }
   1005 
   1006   void setStarLoc(SourceLocation Loc) {
   1007     setSigilLoc(Loc);
   1008   }
   1009 };
   1010 
   1011 
   1012 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
   1013                                                    ReferenceType> {
   1014 public:
   1015   QualType getInnerType() const {
   1016     return getTypePtr()->getPointeeTypeAsWritten();
   1017   }
   1018 };
   1019 
   1020 class LValueReferenceTypeLoc :
   1021     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
   1022                                      LValueReferenceTypeLoc,
   1023                                      LValueReferenceType> {
   1024 public:
   1025   SourceLocation getAmpLoc() const {
   1026     return getSigilLoc();
   1027   }
   1028   void setAmpLoc(SourceLocation Loc) {
   1029     setSigilLoc(Loc);
   1030   }
   1031 };
   1032 
   1033 class RValueReferenceTypeLoc :
   1034     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
   1035                                      RValueReferenceTypeLoc,
   1036                                      RValueReferenceType> {
   1037 public:
   1038   SourceLocation getAmpAmpLoc() const {
   1039     return getSigilLoc();
   1040   }
   1041   void setAmpAmpLoc(SourceLocation Loc) {
   1042     setSigilLoc(Loc);
   1043   }
   1044 };
   1045 
   1046 
   1047 struct FunctionLocInfo {
   1048   SourceLocation LocalRangeBegin;
   1049   SourceLocation LocalRangeEnd;
   1050   bool TrailingReturn;
   1051 };
   1052 
   1053 /// \brief Wrapper for source info for functions.
   1054 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
   1055                                                FunctionTypeLoc,
   1056                                                FunctionType,
   1057                                                FunctionLocInfo> {
   1058 public:
   1059   SourceLocation getLocalRangeBegin() const {
   1060     return getLocalData()->LocalRangeBegin;
   1061   }
   1062   void setLocalRangeBegin(SourceLocation L) {
   1063     getLocalData()->LocalRangeBegin = L;
   1064   }
   1065 
   1066   SourceLocation getLocalRangeEnd() const {
   1067     return getLocalData()->LocalRangeEnd;
   1068   }
   1069   void setLocalRangeEnd(SourceLocation L) {
   1070     getLocalData()->LocalRangeEnd = L;
   1071   }
   1072 
   1073   bool getTrailingReturn() const {
   1074     return getLocalData()->TrailingReturn;
   1075   }
   1076   void setTrailingReturn(bool Trailing) {
   1077     getLocalData()->TrailingReturn = Trailing;
   1078   }
   1079 
   1080   // ParmVarDecls* are stored after Info, one for each argument.
   1081   ParmVarDecl **getParmArray() const {
   1082     return (ParmVarDecl**) getExtraLocalData();
   1083   }
   1084 
   1085   unsigned getNumArgs() const {
   1086     if (isa<FunctionNoProtoType>(getTypePtr()))
   1087       return 0;
   1088     return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
   1089   }
   1090   ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
   1091   void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
   1092 
   1093   TypeLoc getResultLoc() const {
   1094     return getInnerTypeLoc();
   1095   }
   1096 
   1097   SourceRange getLocalSourceRange() const {
   1098     return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
   1099   }
   1100 
   1101   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1102     setLocalRangeBegin(Loc);
   1103     setLocalRangeEnd(Loc);
   1104     setTrailingReturn(false);
   1105     for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
   1106       setArg(i, NULL);
   1107   }
   1108 
   1109   /// \brief Returns the size of the type source info data block that is
   1110   /// specific to this type.
   1111   unsigned getExtraLocalDataSize() const {
   1112     return getNumArgs() * sizeof(ParmVarDecl*);
   1113   }
   1114 
   1115   QualType getInnerType() const { return getTypePtr()->getResultType(); }
   1116 };
   1117 
   1118 class FunctionProtoTypeLoc :
   1119     public InheritingConcreteTypeLoc<FunctionTypeLoc,
   1120                                      FunctionProtoTypeLoc,
   1121                                      FunctionProtoType> {
   1122 };
   1123 
   1124 class FunctionNoProtoTypeLoc :
   1125     public InheritingConcreteTypeLoc<FunctionTypeLoc,
   1126                                      FunctionNoProtoTypeLoc,
   1127                                      FunctionNoProtoType> {
   1128 };
   1129 
   1130 
   1131 struct ArrayLocInfo {
   1132   SourceLocation LBracketLoc, RBracketLoc;
   1133   Expr *Size;
   1134 };
   1135 
   1136 /// \brief Wrapper for source info for arrays.
   1137 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
   1138                                             ArrayTypeLoc,
   1139                                             ArrayType,
   1140                                             ArrayLocInfo> {
   1141 public:
   1142   SourceLocation getLBracketLoc() const {
   1143     return getLocalData()->LBracketLoc;
   1144   }
   1145   void setLBracketLoc(SourceLocation Loc) {
   1146     getLocalData()->LBracketLoc = Loc;
   1147   }
   1148 
   1149   SourceLocation getRBracketLoc() const {
   1150     return getLocalData()->RBracketLoc;
   1151   }
   1152   void setRBracketLoc(SourceLocation Loc) {
   1153     getLocalData()->RBracketLoc = Loc;
   1154   }
   1155 
   1156   SourceRange getBracketsRange() const {
   1157     return SourceRange(getLBracketLoc(), getRBracketLoc());
   1158   }
   1159 
   1160   Expr *getSizeExpr() const {
   1161     return getLocalData()->Size;
   1162   }
   1163   void setSizeExpr(Expr *Size) {
   1164     getLocalData()->Size = Size;
   1165   }
   1166 
   1167   TypeLoc getElementLoc() const {
   1168     return getInnerTypeLoc();
   1169   }
   1170 
   1171   SourceRange getLocalSourceRange() const {
   1172     return SourceRange(getLBracketLoc(), getRBracketLoc());
   1173   }
   1174 
   1175   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1176     setLBracketLoc(Loc);
   1177     setRBracketLoc(Loc);
   1178     setSizeExpr(NULL);
   1179   }
   1180 
   1181   QualType getInnerType() const { return getTypePtr()->getElementType(); }
   1182 };
   1183 
   1184 class ConstantArrayTypeLoc :
   1185     public InheritingConcreteTypeLoc<ArrayTypeLoc,
   1186                                      ConstantArrayTypeLoc,
   1187                                      ConstantArrayType> {
   1188 };
   1189 
   1190 class IncompleteArrayTypeLoc :
   1191     public InheritingConcreteTypeLoc<ArrayTypeLoc,
   1192                                      IncompleteArrayTypeLoc,
   1193                                      IncompleteArrayType> {
   1194 };
   1195 
   1196 class DependentSizedArrayTypeLoc :
   1197     public InheritingConcreteTypeLoc<ArrayTypeLoc,
   1198                                      DependentSizedArrayTypeLoc,
   1199                                      DependentSizedArrayType> {
   1200 
   1201 };
   1202 
   1203 class VariableArrayTypeLoc :
   1204     public InheritingConcreteTypeLoc<ArrayTypeLoc,
   1205                                      VariableArrayTypeLoc,
   1206                                      VariableArrayType> {
   1207 };
   1208 
   1209 
   1210 // Location information for a TemplateName.  Rudimentary for now.
   1211 struct TemplateNameLocInfo {
   1212   SourceLocation NameLoc;
   1213 };
   1214 
   1215 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
   1216   SourceLocation LAngleLoc;
   1217   SourceLocation RAngleLoc;
   1218 };
   1219 
   1220 class TemplateSpecializationTypeLoc :
   1221     public ConcreteTypeLoc<UnqualTypeLoc,
   1222                            TemplateSpecializationTypeLoc,
   1223                            TemplateSpecializationType,
   1224                            TemplateSpecializationLocInfo> {
   1225 public:
   1226   SourceLocation getLAngleLoc() const {
   1227     return getLocalData()->LAngleLoc;
   1228   }
   1229   void setLAngleLoc(SourceLocation Loc) {
   1230     getLocalData()->LAngleLoc = Loc;
   1231   }
   1232 
   1233   SourceLocation getRAngleLoc() const {
   1234     return getLocalData()->RAngleLoc;
   1235   }
   1236   void setRAngleLoc(SourceLocation Loc) {
   1237     getLocalData()->RAngleLoc = Loc;
   1238   }
   1239 
   1240   unsigned getNumArgs() const {
   1241     return getTypePtr()->getNumArgs();
   1242   }
   1243   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
   1244     getArgInfos()[i] = AI;
   1245   }
   1246   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
   1247     return getArgInfos()[i];
   1248   }
   1249 
   1250   TemplateArgumentLoc getArgLoc(unsigned i) const {
   1251     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
   1252   }
   1253 
   1254   SourceLocation getTemplateNameLoc() const {
   1255     return getLocalData()->NameLoc;
   1256   }
   1257   void setTemplateNameLoc(SourceLocation Loc) {
   1258     getLocalData()->NameLoc = Loc;
   1259   }
   1260 
   1261   /// \brief - Copy the location information from the given info.
   1262   void copy(TemplateSpecializationTypeLoc Loc) {
   1263     unsigned size = getFullDataSize();
   1264     assert(size == Loc.getFullDataSize());
   1265 
   1266     // We're potentially copying Expr references here.  We don't
   1267     // bother retaining them because TypeSourceInfos live forever, so
   1268     // as long as the Expr was retained when originally written into
   1269     // the TypeLoc, we're okay.
   1270     memcpy(Data, Loc.Data, size);
   1271   }
   1272 
   1273   SourceRange getLocalSourceRange() const {
   1274     return SourceRange(getTemplateNameLoc(), getRAngleLoc());
   1275   }
   1276 
   1277   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1278     setLAngleLoc(Loc);
   1279     setRAngleLoc(Loc);
   1280     setTemplateNameLoc(Loc);
   1281     initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
   1282                       getArgInfos(), Loc);
   1283   }
   1284 
   1285   static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
   1286                                 const TemplateArgument *Args,
   1287                                 TemplateArgumentLocInfo *ArgInfos,
   1288                                 SourceLocation Loc);
   1289 
   1290   unsigned getExtraLocalDataSize() const {
   1291     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
   1292   }
   1293 
   1294 private:
   1295   TemplateArgumentLocInfo *getArgInfos() const {
   1296     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
   1297   }
   1298 };
   1299 
   1300 //===----------------------------------------------------------------------===//
   1301 //
   1302 //  All of these need proper implementations.
   1303 //
   1304 //===----------------------------------------------------------------------===//
   1305 
   1306 // FIXME: size expression and attribute locations (or keyword if we
   1307 // ever fully support altivec syntax).
   1308 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
   1309                                                        VectorTypeLoc,
   1310                                                        VectorType> {
   1311 };
   1312 
   1313 // FIXME: size expression and attribute locations.
   1314 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
   1315                                                           ExtVectorTypeLoc,
   1316                                                           ExtVectorType> {
   1317 };
   1318 
   1319 // FIXME: attribute locations.
   1320 // For some reason, this isn't a subtype of VectorType.
   1321 class DependentSizedExtVectorTypeLoc :
   1322     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
   1323                                      DependentSizedExtVectorTypeLoc,
   1324                                      DependentSizedExtVectorType> {
   1325 };
   1326 
   1327 // FIXME: location of the '_Complex' keyword.
   1328 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
   1329                                                         ComplexTypeLoc,
   1330                                                         ComplexType> {
   1331 };
   1332 
   1333 struct TypeofLocInfo {
   1334   SourceLocation TypeofLoc;
   1335   SourceLocation LParenLoc;
   1336   SourceLocation RParenLoc;
   1337 };
   1338 
   1339 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
   1340 };
   1341 
   1342 struct TypeOfTypeLocInfo : public TypeofLocInfo {
   1343   TypeSourceInfo* UnderlyingTInfo;
   1344 };
   1345 
   1346 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
   1347 class TypeofLikeTypeLoc
   1348   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
   1349 public:
   1350   SourceLocation getTypeofLoc() const {
   1351     return this->getLocalData()->TypeofLoc;
   1352   }
   1353   void setTypeofLoc(SourceLocation Loc) {
   1354     this->getLocalData()->TypeofLoc = Loc;
   1355   }
   1356 
   1357   SourceLocation getLParenLoc() const {
   1358     return this->getLocalData()->LParenLoc;
   1359   }
   1360   void setLParenLoc(SourceLocation Loc) {
   1361     this->getLocalData()->LParenLoc = Loc;
   1362   }
   1363 
   1364   SourceLocation getRParenLoc() const {
   1365     return this->getLocalData()->RParenLoc;
   1366   }
   1367   void setRParenLoc(SourceLocation Loc) {
   1368     this->getLocalData()->RParenLoc = Loc;
   1369   }
   1370 
   1371   SourceRange getParensRange() const {
   1372     return SourceRange(getLParenLoc(), getRParenLoc());
   1373   }
   1374   void setParensRange(SourceRange range) {
   1375       setLParenLoc(range.getBegin());
   1376       setRParenLoc(range.getEnd());
   1377   }
   1378 
   1379   SourceRange getLocalSourceRange() const {
   1380     return SourceRange(getTypeofLoc(), getRParenLoc());
   1381   }
   1382 
   1383   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1384     setTypeofLoc(Loc);
   1385     setLParenLoc(Loc);
   1386     setRParenLoc(Loc);
   1387   }
   1388 };
   1389 
   1390 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
   1391                                                    TypeOfExprType,
   1392                                                    TypeOfExprTypeLocInfo> {
   1393 public:
   1394   Expr* getUnderlyingExpr() const {
   1395     return getTypePtr()->getUnderlyingExpr();
   1396   }
   1397   // Reimplemented to account for GNU/C++ extension
   1398   //     typeof unary-expression
   1399   // where there are no parentheses.
   1400   SourceRange getLocalSourceRange() const;
   1401 };
   1402 
   1403 class TypeOfTypeLoc
   1404   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
   1405 public:
   1406   QualType getUnderlyingType() const {
   1407     return this->getTypePtr()->getUnderlyingType();
   1408   }
   1409   TypeSourceInfo* getUnderlyingTInfo() const {
   1410     return this->getLocalData()->UnderlyingTInfo;
   1411   }
   1412   void setUnderlyingTInfo(TypeSourceInfo* TI) const {
   1413     this->getLocalData()->UnderlyingTInfo = TI;
   1414   }
   1415 };
   1416 
   1417 // FIXME: location of the 'decltype' and parens.
   1418 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
   1419                                                          DecltypeTypeLoc,
   1420                                                          DecltypeType> {
   1421 public:
   1422   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
   1423 };
   1424 
   1425 struct UnaryTransformTypeLocInfo {
   1426   // FIXME: While there's only one unary transform right now, future ones may
   1427   // need different representations
   1428   SourceLocation KWLoc, LParenLoc, RParenLoc;
   1429   TypeSourceInfo *UnderlyingTInfo;
   1430 };
   1431 
   1432 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
   1433                                                     UnaryTransformTypeLoc,
   1434                                                     UnaryTransformType,
   1435                                                     UnaryTransformTypeLocInfo> {
   1436 public:
   1437   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
   1438   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
   1439 
   1440   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
   1441   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
   1442 
   1443   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
   1444   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
   1445 
   1446   TypeSourceInfo* getUnderlyingTInfo() const {
   1447     return getLocalData()->UnderlyingTInfo;
   1448   }
   1449   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
   1450     getLocalData()->UnderlyingTInfo = TInfo;
   1451   }
   1452 
   1453   SourceRange getLocalSourceRange() const {
   1454     return SourceRange(getKWLoc(), getRParenLoc());
   1455   }
   1456 
   1457   SourceRange getParensRange() const {
   1458     return SourceRange(getLParenLoc(), getRParenLoc());
   1459   }
   1460   void setParensRange(SourceRange Range) {
   1461     setLParenLoc(Range.getBegin());
   1462     setRParenLoc(Range.getEnd());
   1463   }
   1464 
   1465   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1466     setKWLoc(Loc);
   1467     setRParenLoc(Loc);
   1468     setLParenLoc(Loc);
   1469   }
   1470 };
   1471 
   1472 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
   1473                                                         AutoTypeLoc,
   1474                                                         AutoType> {
   1475 };
   1476 
   1477 struct ElaboratedLocInfo {
   1478   SourceLocation KeywordLoc;
   1479 
   1480   /// \brief Opaque data pointer used to reconstruct a nested-name-specifier
   1481   /// from
   1482   void *QualifierData;
   1483 };
   1484 
   1485 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
   1486                                                  ElaboratedTypeLoc,
   1487                                                  ElaboratedType,
   1488                                                  ElaboratedLocInfo> {
   1489 public:
   1490   SourceLocation getKeywordLoc() const {
   1491     return this->getLocalData()->KeywordLoc;
   1492   }
   1493   void setKeywordLoc(SourceLocation Loc) {
   1494     this->getLocalData()->KeywordLoc = Loc;
   1495   }
   1496 
   1497   NestedNameSpecifierLoc getQualifierLoc() const {
   1498     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
   1499                                   getLocalData()->QualifierData);
   1500   }
   1501 
   1502   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
   1503     assert(QualifierLoc.getNestedNameSpecifier()
   1504                                             == getTypePtr()->getQualifier() &&
   1505            "Inconsistent nested-name-specifier pointer");
   1506     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
   1507   }
   1508 
   1509   SourceRange getLocalSourceRange() const {
   1510     if (getKeywordLoc().isValid())
   1511       if (getQualifierLoc())
   1512         return SourceRange(getKeywordLoc(), getQualifierLoc().getEndLoc());
   1513       else
   1514         return SourceRange(getKeywordLoc());
   1515     else
   1516       return getQualifierLoc().getSourceRange();
   1517   }
   1518 
   1519   void initializeLocal(ASTContext &Context, SourceLocation Loc);
   1520 
   1521   TypeLoc getNamedTypeLoc() const {
   1522     return getInnerTypeLoc();
   1523   }
   1524 
   1525   QualType getInnerType() const {
   1526     return getTypePtr()->getNamedType();
   1527   }
   1528 
   1529   void copy(ElaboratedTypeLoc Loc) {
   1530     unsigned size = getFullDataSize();
   1531     assert(size == Loc.getFullDataSize());
   1532     memcpy(Data, Loc.Data, size);
   1533   }
   1534 };
   1535 
   1536 // This is exactly the structure of an ElaboratedTypeLoc whose inner
   1537 // type is some sort of TypeDeclTypeLoc.
   1538 struct DependentNameLocInfo : ElaboratedLocInfo {
   1539   SourceLocation NameLoc;
   1540 
   1541   /// \brief Data associated with the nested-name-specifier location.
   1542   void *QualifierData;
   1543 };
   1544 
   1545 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
   1546                                                     DependentNameTypeLoc,
   1547                                                     DependentNameType,
   1548                                                     DependentNameLocInfo> {
   1549 public:
   1550   SourceLocation getKeywordLoc() const {
   1551     return this->getLocalData()->KeywordLoc;
   1552   }
   1553   void setKeywordLoc(SourceLocation Loc) {
   1554     this->getLocalData()->KeywordLoc = Loc;
   1555   }
   1556 
   1557   NestedNameSpecifierLoc getQualifierLoc() const {
   1558     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
   1559                                   getLocalData()->QualifierData);
   1560   }
   1561 
   1562   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
   1563     assert(QualifierLoc.getNestedNameSpecifier()
   1564                                             == getTypePtr()->getQualifier() &&
   1565            "Inconsistent nested-name-specifier pointer");
   1566     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
   1567   }
   1568 
   1569   SourceLocation getNameLoc() const {
   1570     return this->getLocalData()->NameLoc;
   1571   }
   1572   void setNameLoc(SourceLocation Loc) {
   1573     this->getLocalData()->NameLoc = Loc;
   1574   }
   1575 
   1576   SourceRange getLocalSourceRange() const {
   1577     if (getKeywordLoc().isValid())
   1578       return SourceRange(getKeywordLoc(), getNameLoc());
   1579     else
   1580       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
   1581   }
   1582 
   1583   void copy(DependentNameTypeLoc Loc) {
   1584     unsigned size = getFullDataSize();
   1585     assert(size == Loc.getFullDataSize());
   1586     memcpy(Data, Loc.Data, size);
   1587   }
   1588 
   1589   void initializeLocal(ASTContext &Context, SourceLocation Loc);
   1590 };
   1591 
   1592 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
   1593   SourceLocation KeywordLoc;
   1594   SourceLocation LAngleLoc;
   1595   SourceLocation RAngleLoc;
   1596   // followed by a TemplateArgumentLocInfo[]
   1597 };
   1598 
   1599 class DependentTemplateSpecializationTypeLoc :
   1600     public ConcreteTypeLoc<UnqualTypeLoc,
   1601                            DependentTemplateSpecializationTypeLoc,
   1602                            DependentTemplateSpecializationType,
   1603                            DependentTemplateSpecializationLocInfo> {
   1604 public:
   1605   SourceLocation getKeywordLoc() const {
   1606     return this->getLocalData()->KeywordLoc;
   1607   }
   1608   void setKeywordLoc(SourceLocation Loc) {
   1609     this->getLocalData()->KeywordLoc = Loc;
   1610   }
   1611 
   1612   NestedNameSpecifierLoc getQualifierLoc() const {
   1613     if (!getLocalData()->QualifierData)
   1614       return NestedNameSpecifierLoc();
   1615 
   1616     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
   1617                                   getLocalData()->QualifierData);
   1618   }
   1619 
   1620   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
   1621     if (!QualifierLoc) {
   1622       // Even if we have a nested-name-specifier in the dependent
   1623       // template specialization type, we won't record the nested-name-specifier
   1624       // location information when this type-source location information is
   1625       // part of a nested-name-specifier.
   1626       getLocalData()->QualifierData = 0;
   1627       return;
   1628     }
   1629 
   1630     assert(QualifierLoc.getNestedNameSpecifier()
   1631                                         == getTypePtr()->getQualifier() &&
   1632            "Inconsistent nested-name-specifier pointer");
   1633     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
   1634   }
   1635 
   1636   SourceLocation getNameLoc() const {
   1637     return this->getLocalData()->NameLoc;
   1638   }
   1639   void setNameLoc(SourceLocation Loc) {
   1640     this->getLocalData()->NameLoc = Loc;
   1641   }
   1642 
   1643   SourceLocation getLAngleLoc() const {
   1644     return this->getLocalData()->LAngleLoc;
   1645   }
   1646   void setLAngleLoc(SourceLocation Loc) {
   1647     this->getLocalData()->LAngleLoc = Loc;
   1648   }
   1649 
   1650   SourceLocation getRAngleLoc() const {
   1651     return this->getLocalData()->RAngleLoc;
   1652   }
   1653   void setRAngleLoc(SourceLocation Loc) {
   1654     this->getLocalData()->RAngleLoc = Loc;
   1655   }
   1656 
   1657   unsigned getNumArgs() const {
   1658     return getTypePtr()->getNumArgs();
   1659   }
   1660 
   1661   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
   1662     getArgInfos()[i] = AI;
   1663   }
   1664   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
   1665     return getArgInfos()[i];
   1666   }
   1667 
   1668   TemplateArgumentLoc getArgLoc(unsigned i) const {
   1669     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
   1670   }
   1671 
   1672   SourceRange getLocalSourceRange() const {
   1673     if (getKeywordLoc().isValid())
   1674       return SourceRange(getKeywordLoc(), getRAngleLoc());
   1675     else if (getQualifierLoc())
   1676       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
   1677     else
   1678       return SourceRange(getNameLoc(), getRAngleLoc());
   1679   }
   1680 
   1681   void copy(DependentTemplateSpecializationTypeLoc Loc) {
   1682     unsigned size = getFullDataSize();
   1683     assert(size == Loc.getFullDataSize());
   1684     memcpy(Data, Loc.Data, size);
   1685   }
   1686 
   1687   void initializeLocal(ASTContext &Context, SourceLocation Loc);
   1688 
   1689   unsigned getExtraLocalDataSize() const {
   1690     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
   1691   }
   1692 
   1693 private:
   1694   TemplateArgumentLocInfo *getArgInfos() const {
   1695     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
   1696   }
   1697 };
   1698 
   1699 
   1700 struct PackExpansionTypeLocInfo {
   1701   SourceLocation EllipsisLoc;
   1702 };
   1703 
   1704 class PackExpansionTypeLoc
   1705   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
   1706                            PackExpansionType, PackExpansionTypeLocInfo> {
   1707 public:
   1708   SourceLocation getEllipsisLoc() const {
   1709     return this->getLocalData()->EllipsisLoc;
   1710   }
   1711 
   1712   void setEllipsisLoc(SourceLocation Loc) {
   1713     this->getLocalData()->EllipsisLoc = Loc;
   1714   }
   1715 
   1716   SourceRange getLocalSourceRange() const {
   1717     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
   1718   }
   1719 
   1720   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1721     setEllipsisLoc(Loc);
   1722   }
   1723 
   1724   TypeLoc getPatternLoc() const {
   1725     return getInnerTypeLoc();
   1726   }
   1727 
   1728   QualType getInnerType() const {
   1729     return this->getTypePtr()->getPattern();
   1730   }
   1731 };
   1732 
   1733 struct AtomicTypeLocInfo {
   1734   SourceLocation KWLoc, LParenLoc, RParenLoc;
   1735 };
   1736 
   1737 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
   1738                                              AtomicType, AtomicTypeLocInfo> {
   1739 public:
   1740   TypeLoc getValueLoc() const {
   1741     return this->getInnerTypeLoc();
   1742   }
   1743 
   1744   SourceRange getLocalSourceRange() const {
   1745     return SourceRange(getKWLoc(), getRParenLoc());
   1746   }
   1747 
   1748   SourceLocation getKWLoc() const {
   1749     return this->getLocalData()->KWLoc;
   1750   }
   1751   void setKWLoc(SourceLocation Loc) {
   1752     this->getLocalData()->KWLoc = Loc;
   1753   }
   1754 
   1755   SourceLocation getLParenLoc() const {
   1756     return this->getLocalData()->LParenLoc;
   1757   }
   1758   void setLParenLoc(SourceLocation Loc) {
   1759     this->getLocalData()->LParenLoc = Loc;
   1760   }
   1761 
   1762   SourceLocation getRParenLoc() const {
   1763     return this->getLocalData()->RParenLoc;
   1764   }
   1765   void setRParenLoc(SourceLocation Loc) {
   1766     this->getLocalData()->RParenLoc = Loc;
   1767   }
   1768 
   1769   SourceRange getParensRange() const {
   1770     return SourceRange(getLParenLoc(), getRParenLoc());
   1771   }
   1772   void setParensRange(SourceRange Range) {
   1773     setLParenLoc(Range.getBegin());
   1774     setRParenLoc(Range.getEnd());
   1775   }
   1776 
   1777   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
   1778     setKWLoc(Loc);
   1779     setLParenLoc(Loc);
   1780     setRParenLoc(Loc);
   1781   }
   1782 
   1783   QualType getInnerType() const {
   1784     return this->getTypePtr()->getValueType();
   1785   }
   1786 };
   1787 
   1788 
   1789 }
   1790 
   1791 #endif
   1792