clang API Documentation

TypeLoc.h
Go to the documentation of this file.
00001 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the TypeLoc interface and subclasses.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_TYPELOC_H
00015 #define LLVM_CLANG_AST_TYPELOC_H
00016 
00017 #include "clang/AST/Type.h"
00018 #include "clang/AST/Decl.h"
00019 #include "clang/AST/TemplateBase.h"
00020 #include "clang/Basic/Specifiers.h"
00021 #include "llvm/Support/Compiler.h"
00022 
00023 namespace clang {
00024   class ASTContext;
00025   class ParmVarDecl;
00026   class TypeSourceInfo;
00027   class UnqualTypeLoc;
00028 
00029 // Predeclare all the type nodes.
00030 #define ABSTRACT_TYPELOC(Class, Base)
00031 #define TYPELOC(Class, Base) \
00032   class Class##TypeLoc;
00033 #include "clang/AST/TypeLocNodes.def"
00034 
00035 /// \brief Base wrapper for a particular "section" of type source info.
00036 ///
00037 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
00038 /// get at the actual information.
00039 class TypeLoc {
00040 protected:
00041   // The correctness of this relies on the property that, for Type *Ty,
00042   //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
00043   const void *Ty;
00044   void *Data;
00045 
00046 public:
00047   /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
00048   /// except it also defines a Qualified enum that corresponds to the
00049   /// QualifiedLoc class.
00050   enum TypeLocClass {
00051 #define ABSTRACT_TYPE(Class, Base)
00052 #define TYPE(Class, Base) \
00053     Class = Type::Class,
00054 #include "clang/AST/TypeNodes.def"
00055     Qualified
00056   };
00057 
00058   TypeLoc() : Ty(0), Data(0) { }
00059   TypeLoc(QualType ty, void *opaqueData)
00060     : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
00061   TypeLoc(const Type *ty, void *opaqueData)
00062     : Ty(ty), Data(opaqueData) { }
00063 
00064   TypeLocClass getTypeLocClass() const {
00065     if (getType().hasLocalQualifiers()) return Qualified;
00066     return (TypeLocClass) getType()->getTypeClass();
00067   }
00068 
00069   bool isNull() const { return !Ty; }
00070   operator bool() const { return Ty; }
00071 
00072   /// \brief Returns the size of type source info data block for the given type.
00073   static unsigned getFullDataSizeForType(QualType Ty);
00074 
00075   /// \brief Get the type for which this source info wrapper provides
00076   /// information.
00077   QualType getType() const {
00078     return QualType::getFromOpaquePtr(Ty);
00079   }
00080 
00081   const Type *getTypePtr() const {
00082     return QualType::getFromOpaquePtr(Ty).getTypePtr();
00083   }
00084 
00085   /// \brief Get the pointer where source information is stored.
00086   void *getOpaqueData() const {
00087     return Data;
00088   }
00089 
00090   /// \brief Get the begin source location.
00091   SourceLocation getBeginLoc() const;
00092 
00093   /// \brief Get the end source location.
00094   SourceLocation getEndLoc() const;
00095 
00096   /// \brief Get the full source range.
00097   SourceRange getSourceRange() const LLVM_READONLY {
00098     return SourceRange(getBeginLoc(), getEndLoc());
00099   }
00100   SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
00101   SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
00102 
00103   /// \brief Get the local source range.
00104   SourceRange getLocalSourceRange() const {
00105     return getLocalSourceRangeImpl(*this);
00106   }
00107 
00108   /// \brief Returns the size of the type source info data block.
00109   unsigned getFullDataSize() const {
00110     return getFullDataSizeForType(getType());
00111   }
00112 
00113   /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
00114   /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
00115   TypeLoc getNextTypeLoc() const {
00116     return getNextTypeLocImpl(*this);
00117   }
00118 
00119   /// \brief Skips past any qualifiers, if this is qualified.
00120   UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
00121 
00122   TypeLoc IgnoreParens() const {
00123     if (isa<ParenTypeLoc>(this))
00124       return IgnoreParensImpl(*this);
00125     return *this;
00126   }
00127 
00128   /// \brief Initializes this to state that every location in this
00129   /// type is the given location.
00130   ///
00131   /// This method exists to provide a simple transition for code that
00132   /// relies on location-less types.
00133   void initialize(ASTContext &Context, SourceLocation Loc) const {
00134     initializeImpl(Context, *this, Loc);
00135   }
00136 
00137   /// \brief Initializes this by copying its information from another
00138   /// TypeLoc of the same type.
00139   void initializeFullCopy(TypeLoc Other) const {
00140     assert(getType() == Other.getType());
00141     size_t Size = getFullDataSize();
00142     memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
00143   }
00144 
00145   /// \brief Initializes this by copying its information from another
00146   /// TypeLoc of the same type.  The given size must be the full data
00147   /// size.
00148   void initializeFullCopy(TypeLoc Other, unsigned Size) const {
00149     assert(getType() == Other.getType());
00150     assert(getFullDataSize() == Size);
00151     memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
00152   }
00153 
00154   friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
00155     return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
00156   }
00157 
00158   friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
00159     return !(LHS == RHS);
00160   }
00161 
00162   static bool classof(const TypeLoc *TL) { return true; }
00163 
00164 private:
00165   static void initializeImpl(ASTContext &Context, TypeLoc TL,
00166                              SourceLocation Loc);
00167   static TypeLoc getNextTypeLocImpl(TypeLoc TL);
00168   static TypeLoc IgnoreParensImpl(TypeLoc TL);
00169   static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
00170 };
00171 
00172 /// \brief Return the TypeLoc for a type source info.
00173 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
00174   return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
00175 }
00176 
00177 /// \brief Wrapper of type source information for a type with
00178 /// no direct qualifiers.
00179 class UnqualTypeLoc : public TypeLoc {
00180 public:
00181   UnqualTypeLoc() {}
00182   UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
00183 
00184   const Type *getTypePtr() const {
00185     return reinterpret_cast<const Type*>(Ty);
00186   }
00187 
00188   TypeLocClass getTypeLocClass() const {
00189     return (TypeLocClass) getTypePtr()->getTypeClass();
00190   }
00191 
00192   static bool classof(const TypeLoc *TL) {
00193     return !TL->getType().hasLocalQualifiers();
00194   }
00195   static bool classof(const UnqualTypeLoc *TL) { return true; }
00196 };
00197 
00198 /// \brief Wrapper of type source information for a type with
00199 /// non-trivial direct qualifiers.
00200 ///
00201 /// Currently, we intentionally do not provide source location for
00202 /// type qualifiers.
00203 class QualifiedTypeLoc : public TypeLoc {
00204 public:
00205   SourceRange getLocalSourceRange() const {
00206     return SourceRange();
00207   }
00208 
00209   UnqualTypeLoc getUnqualifiedLoc() const {
00210     return UnqualTypeLoc(getTypePtr(), Data);
00211   }
00212 
00213   /// Initializes the local data of this type source info block to
00214   /// provide no information.
00215   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00216     // do nothing
00217   }
00218 
00219   TypeLoc getNextTypeLoc() const {
00220     return getUnqualifiedLoc();
00221   }
00222 
00223   /// \brief Returns the size of the type source info data block that is
00224   /// specific to this type.
00225   unsigned getLocalDataSize() const {
00226     // In fact, we don't currently preserve any location information
00227     // for qualifiers.
00228     return 0;
00229   }
00230 
00231   /// \brief Returns the size of the type source info data block.
00232   unsigned getFullDataSize() const {
00233     return getLocalDataSize() +
00234       getFullDataSizeForType(getType().getLocalUnqualifiedType());
00235   }
00236 
00237   static bool classof(const TypeLoc *TL) {
00238     return TL->getType().hasLocalQualifiers();
00239   }
00240   static bool classof(const QualifiedTypeLoc *TL) { return true; }
00241 };
00242 
00243 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
00244   if (isa<QualifiedTypeLoc>(this))
00245     return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
00246   return cast<UnqualTypeLoc>(*this);
00247 }
00248 
00249 /// A metaprogramming base class for TypeLoc classes which correspond
00250 /// to a particular Type subclass.  It is accepted for a single
00251 /// TypeLoc class to correspond to multiple Type classes.
00252 ///
00253 /// \param Base a class from which to derive
00254 /// \param Derived the class deriving from this one
00255 /// \param TypeClass the concrete Type subclass associated with this
00256 ///   location type
00257 /// \param LocalData the structure type of local location data for
00258 ///   this type
00259 ///
00260 /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
00261 /// else the world will end.
00262 ///
00263 /// TypeLocs with non-constant amounts of local data should override
00264 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
00265 /// this extra memory.
00266 ///
00267 /// TypeLocs with an inner type should define
00268 ///   QualType getInnerType() const
00269 /// and getInnerTypeLoc() will then point to this inner type's
00270 /// location data.
00271 ///
00272 /// A word about hierarchies: this template is not designed to be
00273 /// derived from multiple times in a hierarchy.  It is also not
00274 /// designed to be used for classes where subtypes might provide
00275 /// different amounts of source information.  It should be subclassed
00276 /// only at the deepest portion of the hierarchy where all children
00277 /// have identical source information; if that's an abstract type,
00278 /// then further descendents should inherit from
00279 /// InheritingConcreteTypeLoc instead.
00280 template <class Base, class Derived, class TypeClass, class LocalData>
00281 class ConcreteTypeLoc : public Base {
00282 
00283   const Derived *asDerived() const {
00284     return static_cast<const Derived*>(this);
00285   }
00286 
00287 public:
00288   unsigned getLocalDataSize() const {
00289     return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
00290   }
00291   // Give a default implementation that's useful for leaf types.
00292   unsigned getFullDataSize() const {
00293     return asDerived()->getLocalDataSize() + getInnerTypeSize();
00294   }
00295 
00296   static bool classofType(const Type *Ty) {
00297     return TypeClass::classof(Ty);
00298   }
00299 
00300   static bool classof(const TypeLoc *TL) {
00301     return Derived::classofType(TL->getTypePtr());
00302   }
00303   static bool classof(const UnqualTypeLoc *TL) {
00304     return Derived::classofType(TL->getTypePtr());
00305   }
00306   static bool classof(const Derived *TL) {
00307     return true;
00308   }
00309 
00310   TypeLoc getNextTypeLoc() const {
00311     return getNextTypeLoc(asDerived()->getInnerType());
00312   }
00313 
00314   const TypeClass *getTypePtr() const {
00315     return cast<TypeClass>(Base::getTypePtr());
00316   }
00317 
00318 protected:
00319   unsigned getExtraLocalDataSize() const {
00320     return 0;
00321   }
00322 
00323   LocalData *getLocalData() const {
00324     return static_cast<LocalData*>(Base::Data);
00325   }
00326 
00327   /// Gets a pointer past the Info structure; useful for classes with
00328   /// local data that can't be captured in the Info (e.g. because it's
00329   /// of variable size).
00330   void *getExtraLocalData() const {
00331     return getLocalData() + 1;
00332   }
00333 
00334   void *getNonLocalData() const {
00335     return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
00336   }
00337 
00338   struct HasNoInnerType {};
00339   HasNoInnerType getInnerType() const { return HasNoInnerType(); }
00340 
00341   TypeLoc getInnerTypeLoc() const {
00342     return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
00343   }
00344 
00345 private:
00346   unsigned getInnerTypeSize() const {
00347     return getInnerTypeSize(asDerived()->getInnerType());
00348   }
00349 
00350   unsigned getInnerTypeSize(HasNoInnerType _) const {
00351     return 0;
00352   }
00353 
00354   unsigned getInnerTypeSize(QualType _) const {
00355     return getInnerTypeLoc().getFullDataSize();
00356   }
00357 
00358   TypeLoc getNextTypeLoc(HasNoInnerType _) const {
00359     return TypeLoc();
00360   }
00361 
00362   TypeLoc getNextTypeLoc(QualType T) const {
00363     return TypeLoc(T, getNonLocalData());
00364   }
00365 };
00366 
00367 /// A metaprogramming class designed for concrete subtypes of abstract
00368 /// types where all subtypes share equivalently-structured source
00369 /// information.  See the note on ConcreteTypeLoc.
00370 template <class Base, class Derived, class TypeClass>
00371 class InheritingConcreteTypeLoc : public Base {
00372 public:
00373   static bool classofType(const Type *Ty) {
00374     return TypeClass::classof(Ty);
00375   }
00376 
00377   static bool classof(const TypeLoc *TL) {
00378     return Derived::classofType(TL->getTypePtr());
00379   }
00380   static bool classof(const UnqualTypeLoc *TL) {
00381     return Derived::classofType(TL->getTypePtr());
00382   }
00383   static bool classof(const Derived *TL) {
00384     return true;
00385   }
00386 
00387   const TypeClass *getTypePtr() const {
00388     return cast<TypeClass>(Base::getTypePtr());
00389   }
00390 };
00391 
00392 
00393 struct TypeSpecLocInfo {
00394   SourceLocation NameLoc;
00395 };
00396 
00397 /// \brief A reasonable base class for TypeLocs that correspond to
00398 /// types that are written as a type-specifier.
00399 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
00400                                                TypeSpecTypeLoc,
00401                                                Type,
00402                                                TypeSpecLocInfo> {
00403 public:
00404   enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
00405 
00406   SourceLocation getNameLoc() const {
00407     return this->getLocalData()->NameLoc;
00408   }
00409   void setNameLoc(SourceLocation Loc) {
00410     this->getLocalData()->NameLoc = Loc;
00411   }
00412   SourceRange getLocalSourceRange() const {
00413     return SourceRange(getNameLoc(), getNameLoc());
00414   }
00415   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00416     setNameLoc(Loc);
00417   }
00418 
00419   static bool classof(const TypeLoc *TL);
00420   static bool classof(const TypeSpecTypeLoc *TL) { return true; }
00421 };
00422 
00423 
00424 struct BuiltinLocInfo {
00425   SourceLocation BuiltinLoc;
00426 };
00427 
00428 /// \brief Wrapper for source info for builtin types.
00429 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
00430                                               BuiltinTypeLoc,
00431                                               BuiltinType,
00432                                               BuiltinLocInfo> {
00433 public:
00434   enum { LocalDataSize = sizeof(BuiltinLocInfo) };
00435 
00436   SourceLocation getBuiltinLoc() const {
00437     return getLocalData()->BuiltinLoc;
00438   }
00439   void setBuiltinLoc(SourceLocation Loc) {
00440     getLocalData()->BuiltinLoc = Loc;
00441   }
00442 
00443   SourceLocation getNameLoc() const { return getBuiltinLoc(); }
00444 
00445   WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
00446     return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
00447   }
00448   const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
00449     return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
00450   }
00451 
00452   bool needsExtraLocalData() const {
00453     BuiltinType::Kind bk = getTypePtr()->getKind();
00454     return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
00455       || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
00456       || bk == BuiltinType::UChar
00457       || bk == BuiltinType::SChar;
00458   }
00459 
00460   unsigned getExtraLocalDataSize() const {
00461     return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
00462   }
00463 
00464   SourceRange getLocalSourceRange() const {
00465     return SourceRange(getBuiltinLoc(), getBuiltinLoc());
00466   }
00467 
00468   TypeSpecifierSign getWrittenSignSpec() const {
00469     if (needsExtraLocalData())
00470       return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
00471     else
00472       return TSS_unspecified;
00473   }
00474   bool hasWrittenSignSpec() const {
00475     return getWrittenSignSpec() != TSS_unspecified;
00476   }
00477   void setWrittenSignSpec(TypeSpecifierSign written) {
00478     if (needsExtraLocalData())
00479       getWrittenBuiltinSpecs().Sign = written;
00480   }
00481 
00482   TypeSpecifierWidth getWrittenWidthSpec() const {
00483     if (needsExtraLocalData())
00484       return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
00485     else
00486       return TSW_unspecified;
00487   }
00488   bool hasWrittenWidthSpec() const {
00489     return getWrittenWidthSpec() != TSW_unspecified;
00490   }
00491   void setWrittenWidthSpec(TypeSpecifierWidth written) {
00492     if (needsExtraLocalData())
00493       getWrittenBuiltinSpecs().Width = written;
00494   }
00495 
00496   TypeSpecifierType getWrittenTypeSpec() const;
00497   bool hasWrittenTypeSpec() const {
00498     return getWrittenTypeSpec() != TST_unspecified;
00499   }
00500   void setWrittenTypeSpec(TypeSpecifierType written) {
00501     if (needsExtraLocalData())
00502       getWrittenBuiltinSpecs().Type = written;
00503   }
00504 
00505   bool hasModeAttr() const {
00506     if (needsExtraLocalData())
00507       return getWrittenBuiltinSpecs().ModeAttr;
00508     else
00509       return false;
00510   }
00511   void setModeAttr(bool written) {
00512     if (needsExtraLocalData())
00513       getWrittenBuiltinSpecs().ModeAttr = written;
00514   }
00515 
00516   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00517     setBuiltinLoc(Loc);
00518     if (needsExtraLocalData()) {
00519       WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
00520       wbs.Sign = TSS_unspecified;
00521       wbs.Width = TSW_unspecified;
00522       wbs.Type = TST_unspecified;
00523       wbs.ModeAttr = false;
00524     }
00525   }
00526 };
00527 
00528 
00529 /// \brief Wrapper for source info for typedefs.
00530 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00531                                                         TypedefTypeLoc,
00532                                                         TypedefType> {
00533 public:
00534   TypedefNameDecl *getTypedefNameDecl() const {
00535     return getTypePtr()->getDecl();
00536   }
00537 };
00538 
00539 /// \brief Wrapper for source info for injected class names of class
00540 /// templates.
00541 class InjectedClassNameTypeLoc :
00542     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00543                                      InjectedClassNameTypeLoc,
00544                                      InjectedClassNameType> {
00545 public:
00546   CXXRecordDecl *getDecl() const {
00547     return getTypePtr()->getDecl();
00548   }
00549 };
00550 
00551 /// \brief Wrapper for source info for unresolved typename using decls.
00552 class UnresolvedUsingTypeLoc :
00553     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00554                                      UnresolvedUsingTypeLoc,
00555                                      UnresolvedUsingType> {
00556 public:
00557   UnresolvedUsingTypenameDecl *getDecl() const {
00558     return getTypePtr()->getDecl();
00559   }
00560 };
00561 
00562 /// \brief Wrapper for source info for tag types.  Note that this only
00563 /// records source info for the name itself; a type written 'struct foo'
00564 /// should be represented as an ElaboratedTypeLoc.  We currently
00565 /// only do that when C++ is enabled because of the expense of
00566 /// creating an ElaboratedType node for so many type references in C.
00567 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00568                                                     TagTypeLoc,
00569                                                     TagType> {
00570 public:
00571   TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
00572 
00573   /// \brief True if the tag was defined in this type specifier.
00574   bool isDefinition() const {
00575     TagDecl *D = getDecl();
00576     return D->isCompleteDefinition() &&
00577          (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
00578   }
00579 };
00580 
00581 /// \brief Wrapper for source info for record types.
00582 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
00583                                                        RecordTypeLoc,
00584                                                        RecordType> {
00585 public:
00586   RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
00587 };
00588 
00589 /// \brief Wrapper for source info for enum types.
00590 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
00591                                                      EnumTypeLoc,
00592                                                      EnumType> {
00593 public:
00594   EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
00595 };
00596 
00597 /// \brief Wrapper for template type parameters.
00598 class TemplateTypeParmTypeLoc :
00599     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00600                                      TemplateTypeParmTypeLoc,
00601                                      TemplateTypeParmType> {
00602 public:
00603   TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
00604 };
00605 
00606 /// \brief Wrapper for substituted template type parameters.
00607 class SubstTemplateTypeParmTypeLoc :
00608     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00609                                      SubstTemplateTypeParmTypeLoc,
00610                                      SubstTemplateTypeParmType> {
00611 };
00612 
00613   /// \brief Wrapper for substituted template type parameters.
00614 class SubstTemplateTypeParmPackTypeLoc :
00615     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
00616                                      SubstTemplateTypeParmPackTypeLoc,
00617                                      SubstTemplateTypeParmPackType> {
00618 };
00619 
00620 struct AttributedLocInfo {
00621   union {
00622     Expr *ExprOperand;
00623 
00624     /// A raw SourceLocation.
00625     unsigned EnumOperandLoc;
00626   };
00627 
00628   SourceRange OperandParens;
00629 
00630   SourceLocation AttrLoc;
00631 };
00632 
00633 /// \brief Type source information for an attributed type.
00634 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
00635                                                  AttributedTypeLoc,
00636                                                  AttributedType,
00637                                                  AttributedLocInfo> {
00638 public:
00639   AttributedType::Kind getAttrKind() const {
00640     return getTypePtr()->getAttrKind();
00641   }
00642 
00643   bool hasAttrExprOperand() const {
00644     return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
00645             getAttrKind() <= AttributedType::LastExprOperandKind);
00646   }
00647 
00648   bool hasAttrEnumOperand() const {
00649     return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
00650             getAttrKind() <= AttributedType::LastEnumOperandKind);
00651   }
00652 
00653   bool hasAttrOperand() const {
00654     return hasAttrExprOperand() || hasAttrEnumOperand();
00655   }
00656 
00657   /// The modified type, which is generally canonically different from
00658   /// the attribute type.
00659   ///    int main(int, char**) __attribute__((noreturn))
00660   ///    ~~~     ~~~~~~~~~~~~~
00661   TypeLoc getModifiedLoc() const {
00662     return getInnerTypeLoc();
00663   }
00664 
00665   /// The location of the attribute name, i.e.
00666   ///    __attribute__((regparm(1000)))
00667   ///                   ^~~~~~~
00668   SourceLocation getAttrNameLoc() const {
00669     return getLocalData()->AttrLoc;
00670   }
00671   void setAttrNameLoc(SourceLocation loc) {
00672     getLocalData()->AttrLoc = loc;
00673   }
00674 
00675   /// The attribute's expression operand, if it has one.
00676   ///    void *cur_thread __attribute__((address_space(21)))
00677   ///                                                  ^~
00678   Expr *getAttrExprOperand() const {
00679     assert(hasAttrExprOperand());
00680     return getLocalData()->ExprOperand;
00681   }
00682   void setAttrExprOperand(Expr *e) {
00683     assert(hasAttrExprOperand());
00684     getLocalData()->ExprOperand = e;
00685   }
00686 
00687   /// The location of the attribute's enumerated operand, if it has one.
00688   ///    void * __attribute__((objc_gc(weak)))
00689   ///                                  ^~~~
00690   SourceLocation getAttrEnumOperandLoc() const {
00691     assert(hasAttrEnumOperand());
00692     return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
00693   }
00694   void setAttrEnumOperandLoc(SourceLocation loc) {
00695     assert(hasAttrEnumOperand());
00696     getLocalData()->EnumOperandLoc = loc.getRawEncoding();
00697   }
00698 
00699   /// The location of the parentheses around the operand, if there is
00700   /// an operand.
00701   ///    void * __attribute__((objc_gc(weak)))
00702   ///                                 ^    ^
00703   SourceRange getAttrOperandParensRange() const {
00704     assert(hasAttrOperand());
00705     return getLocalData()->OperandParens;
00706   }
00707   void setAttrOperandParensRange(SourceRange range) {
00708     assert(hasAttrOperand());
00709     getLocalData()->OperandParens = range;
00710   }
00711 
00712   SourceRange getLocalSourceRange() const {
00713     // Note that this does *not* include the range of the attribute
00714     // enclosure, e.g.:
00715     //    __attribute__((foo(bar)))
00716     //    ^~~~~~~~~~~~~~~        ~~
00717     // or
00718     //    [[foo(bar)]]
00719     //    ^~        ~~
00720     // That enclosure doesn't necessarily belong to a single attribute
00721     // anyway.
00722     SourceRange range(getAttrNameLoc());
00723     if (hasAttrOperand())
00724       range.setEnd(getAttrOperandParensRange().getEnd());
00725     return range;
00726   }
00727 
00728   void initializeLocal(ASTContext &Context, SourceLocation loc) {
00729     setAttrNameLoc(loc);
00730     if (hasAttrExprOperand()) {
00731       setAttrOperandParensRange(SourceRange(loc));
00732       setAttrExprOperand(0);
00733     } else if (hasAttrEnumOperand()) {
00734       setAttrOperandParensRange(SourceRange(loc));
00735       setAttrEnumOperandLoc(loc);
00736     }
00737   }
00738 
00739   QualType getInnerType() const {
00740     return getTypePtr()->getModifiedType();
00741   }
00742 };
00743 
00744 
00745 struct ObjCProtocolListLocInfo {
00746   SourceLocation LAngleLoc;
00747   SourceLocation RAngleLoc;
00748   bool HasBaseTypeAsWritten;
00749 };
00750 
00751 // A helper class for defining ObjC TypeLocs that can qualified with
00752 // protocols.
00753 //
00754 // TypeClass basically has to be either ObjCInterfaceType or
00755 // ObjCObjectPointerType.
00756 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
00757                                                  ObjCObjectTypeLoc,
00758                                                  ObjCObjectType,
00759                                                  ObjCProtocolListLocInfo> {
00760   // SourceLocations are stored after Info, one for each Protocol.
00761   SourceLocation *getProtocolLocArray() const {
00762     return (SourceLocation*) this->getExtraLocalData();
00763   }
00764 
00765 public:
00766   SourceLocation getLAngleLoc() const {
00767     return this->getLocalData()->LAngleLoc;
00768   }
00769   void setLAngleLoc(SourceLocation Loc) {
00770     this->getLocalData()->LAngleLoc = Loc;
00771   }
00772 
00773   SourceLocation getRAngleLoc() const {
00774     return this->getLocalData()->RAngleLoc;
00775   }
00776   void setRAngleLoc(SourceLocation Loc) {
00777     this->getLocalData()->RAngleLoc = Loc;
00778   }
00779 
00780   unsigned getNumProtocols() const {
00781     return this->getTypePtr()->getNumProtocols();
00782   }
00783 
00784   SourceLocation getProtocolLoc(unsigned i) const {
00785     assert(i < getNumProtocols() && "Index is out of bounds!");
00786     return getProtocolLocArray()[i];
00787   }
00788   void setProtocolLoc(unsigned i, SourceLocation Loc) {
00789     assert(i < getNumProtocols() && "Index is out of bounds!");
00790     getProtocolLocArray()[i] = Loc;
00791   }
00792 
00793   ObjCProtocolDecl *getProtocol(unsigned i) const {
00794     assert(i < getNumProtocols() && "Index is out of bounds!");
00795     return *(this->getTypePtr()->qual_begin() + i);
00796   }
00797 
00798   bool hasBaseTypeAsWritten() const {
00799     return getLocalData()->HasBaseTypeAsWritten;
00800   }
00801 
00802   void setHasBaseTypeAsWritten(bool HasBaseType) {
00803     getLocalData()->HasBaseTypeAsWritten = HasBaseType;
00804   }
00805 
00806   TypeLoc getBaseLoc() const {
00807     return getInnerTypeLoc();
00808   }
00809 
00810   SourceRange getLocalSourceRange() const {
00811     return SourceRange(getLAngleLoc(), getRAngleLoc());
00812   }
00813 
00814   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00815     setHasBaseTypeAsWritten(true);
00816     setLAngleLoc(Loc);
00817     setRAngleLoc(Loc);
00818     for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
00819       setProtocolLoc(i, Loc);
00820   }
00821 
00822   unsigned getExtraLocalDataSize() const {
00823     return this->getNumProtocols() * sizeof(SourceLocation);
00824   }
00825 
00826   QualType getInnerType() const {
00827     return getTypePtr()->getBaseType();
00828   }
00829 };
00830 
00831 
00832 struct ObjCInterfaceLocInfo {
00833   SourceLocation NameLoc;
00834   SourceLocation NameEndLoc;
00835 };
00836 
00837 /// \brief Wrapper for source info for ObjC interfaces.
00838 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
00839                                                     ObjCInterfaceTypeLoc,
00840                                                     ObjCInterfaceType,
00841                                                     ObjCInterfaceLocInfo> {
00842 public:
00843   ObjCInterfaceDecl *getIFaceDecl() const {
00844     return getTypePtr()->getDecl();
00845   }
00846 
00847   SourceLocation getNameLoc() const {
00848     return getLocalData()->NameLoc;
00849   }
00850 
00851   void setNameLoc(SourceLocation Loc) {
00852     getLocalData()->NameLoc = Loc;
00853   }
00854                                                     
00855   SourceRange getLocalSourceRange() const {
00856     return SourceRange(getNameLoc(), getNameEndLoc());
00857   }
00858   
00859   SourceLocation getNameEndLoc() const {
00860     return getLocalData()->NameEndLoc;
00861   }
00862 
00863   void setNameEndLoc(SourceLocation Loc) {
00864     getLocalData()->NameEndLoc = Loc;
00865   }
00866 
00867   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00868     setNameLoc(Loc);
00869   }
00870 };
00871 
00872 struct ParenLocInfo {
00873   SourceLocation LParenLoc;
00874   SourceLocation RParenLoc;
00875 };
00876 
00877 class ParenTypeLoc
00878   : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
00879                            ParenLocInfo> {
00880 public:
00881   SourceLocation getLParenLoc() const {
00882     return this->getLocalData()->LParenLoc;
00883   }
00884   SourceLocation getRParenLoc() const {
00885     return this->getLocalData()->RParenLoc;
00886   }
00887   void setLParenLoc(SourceLocation Loc) {
00888     this->getLocalData()->LParenLoc = Loc;
00889   }
00890   void setRParenLoc(SourceLocation Loc) {
00891     this->getLocalData()->RParenLoc = Loc;
00892   }
00893 
00894   SourceRange getLocalSourceRange() const {
00895     return SourceRange(getLParenLoc(), getRParenLoc());
00896   }
00897 
00898   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00899     setLParenLoc(Loc);
00900     setRParenLoc(Loc);
00901   }
00902 
00903   TypeLoc getInnerLoc() const {
00904     return getInnerTypeLoc();
00905   }
00906 
00907   QualType getInnerType() const {
00908     return this->getTypePtr()->getInnerType();
00909   }
00910 };
00911 
00912 
00913 struct PointerLikeLocInfo {
00914   SourceLocation StarLoc;
00915 };
00916 
00917 /// A base class for
00918 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
00919 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
00920                                                   TypeClass, LocalData> {
00921 public:
00922   SourceLocation getSigilLoc() const {
00923     return this->getLocalData()->StarLoc;
00924   }
00925   void setSigilLoc(SourceLocation Loc) {
00926     this->getLocalData()->StarLoc = Loc;
00927   }
00928 
00929   TypeLoc getPointeeLoc() const {
00930     return this->getInnerTypeLoc();
00931   }
00932 
00933   SourceRange getLocalSourceRange() const {
00934     return SourceRange(getSigilLoc(), getSigilLoc());
00935   }
00936 
00937   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00938     setSigilLoc(Loc);
00939   }
00940 
00941   QualType getInnerType() const {
00942     return this->getTypePtr()->getPointeeType();
00943   }
00944 };
00945 
00946 
00947 /// \brief Wrapper for source info for pointers.
00948 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
00949                                                  PointerType> {
00950 public:
00951   SourceLocation getStarLoc() const {
00952     return getSigilLoc();
00953   }
00954   void setStarLoc(SourceLocation Loc) {
00955     setSigilLoc(Loc);
00956   }
00957 };
00958 
00959 
00960 /// \brief Wrapper for source info for block pointers.
00961 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
00962                                                       BlockPointerType> {
00963 public:
00964   SourceLocation getCaretLoc() const {
00965     return getSigilLoc();
00966   }
00967   void setCaretLoc(SourceLocation Loc) {
00968     setSigilLoc(Loc);
00969   }
00970 };
00971 
00972 struct MemberPointerLocInfo : public PointerLikeLocInfo {
00973   TypeSourceInfo *ClassTInfo;
00974 };
00975 
00976 /// \brief Wrapper for source info for member pointers.
00977 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
00978                                                        MemberPointerType,
00979                                                        MemberPointerLocInfo> {
00980 public:
00981   SourceLocation getStarLoc() const {
00982     return getSigilLoc();
00983   }
00984   void setStarLoc(SourceLocation Loc) {
00985     setSigilLoc(Loc);
00986   }
00987 
00988   const Type *getClass() const {
00989     return getTypePtr()->getClass();
00990   }
00991   TypeSourceInfo *getClassTInfo() const {
00992     return getLocalData()->ClassTInfo;
00993   }
00994   void setClassTInfo(TypeSourceInfo* TI) {
00995     getLocalData()->ClassTInfo = TI;
00996   }
00997 
00998   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
00999     setSigilLoc(Loc);
01000     setClassTInfo(0);
01001   }
01002 
01003   SourceRange getLocalSourceRange() const {
01004     if (TypeSourceInfo *TI = getClassTInfo())
01005       return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
01006     else
01007       return SourceRange(getStarLoc());
01008   }
01009 };
01010 
01011 /// Wraps an ObjCPointerType with source location information.
01012 class ObjCObjectPointerTypeLoc :
01013     public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
01014                               ObjCObjectPointerType> {
01015 public:
01016   SourceLocation getStarLoc() const {
01017     return getSigilLoc();
01018   }
01019 
01020   void setStarLoc(SourceLocation Loc) {
01021     setSigilLoc(Loc);
01022   }
01023 };
01024 
01025 
01026 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
01027                                                    ReferenceType> {
01028 public:
01029   QualType getInnerType() const {
01030     return getTypePtr()->getPointeeTypeAsWritten();
01031   }
01032 };
01033 
01034 class LValueReferenceTypeLoc :
01035     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
01036                                      LValueReferenceTypeLoc,
01037                                      LValueReferenceType> {
01038 public:
01039   SourceLocation getAmpLoc() const {
01040     return getSigilLoc();
01041   }
01042   void setAmpLoc(SourceLocation Loc) {
01043     setSigilLoc(Loc);
01044   }
01045 };
01046 
01047 class RValueReferenceTypeLoc :
01048     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
01049                                      RValueReferenceTypeLoc,
01050                                      RValueReferenceType> {
01051 public:
01052   SourceLocation getAmpAmpLoc() const {
01053     return getSigilLoc();
01054   }
01055   void setAmpAmpLoc(SourceLocation Loc) {
01056     setSigilLoc(Loc);
01057   }
01058 };
01059 
01060 
01061 struct FunctionLocInfo {
01062   SourceLocation LocalRangeBegin;
01063   SourceLocation LocalRangeEnd;
01064   bool TrailingReturn;
01065 };
01066 
01067 /// \brief Wrapper for source info for functions.
01068 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
01069                                                FunctionTypeLoc,
01070                                                FunctionType,
01071                                                FunctionLocInfo> {
01072 public:
01073   SourceLocation getLocalRangeBegin() const {
01074     return getLocalData()->LocalRangeBegin;
01075   }
01076   void setLocalRangeBegin(SourceLocation L) {
01077     getLocalData()->LocalRangeBegin = L;
01078   }
01079 
01080   SourceLocation getLocalRangeEnd() const {
01081     return getLocalData()->LocalRangeEnd;
01082   }
01083   void setLocalRangeEnd(SourceLocation L) {
01084     getLocalData()->LocalRangeEnd = L;
01085   }
01086 
01087   bool getTrailingReturn() const {
01088     return getLocalData()->TrailingReturn;
01089   }
01090   void setTrailingReturn(bool Trailing) {
01091     getLocalData()->TrailingReturn = Trailing;
01092   }
01093 
01094   ArrayRef<ParmVarDecl *> getParams() const {
01095     return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
01096   }
01097 
01098   // ParmVarDecls* are stored after Info, one for each argument.
01099   ParmVarDecl **getParmArray() const {
01100     return (ParmVarDecl**) getExtraLocalData();
01101   }
01102 
01103   unsigned getNumArgs() const {
01104     if (isa<FunctionNoProtoType>(getTypePtr()))
01105       return 0;
01106     return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
01107   }
01108   ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
01109   void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
01110 
01111   TypeLoc getResultLoc() const {
01112     return getInnerTypeLoc();
01113   }
01114 
01115   SourceRange getLocalSourceRange() const {
01116     return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
01117   }
01118 
01119   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01120     setLocalRangeBegin(Loc);
01121     setLocalRangeEnd(Loc);
01122     setTrailingReturn(false);
01123     for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
01124       setArg(i, NULL);
01125   }
01126 
01127   /// \brief Returns the size of the type source info data block that is
01128   /// specific to this type.
01129   unsigned getExtraLocalDataSize() const {
01130     return getNumArgs() * sizeof(ParmVarDecl*);
01131   }
01132 
01133   QualType getInnerType() const { return getTypePtr()->getResultType(); }
01134 };
01135 
01136 class FunctionProtoTypeLoc :
01137     public InheritingConcreteTypeLoc<FunctionTypeLoc,
01138                                      FunctionProtoTypeLoc,
01139                                      FunctionProtoType> {
01140 };
01141 
01142 class FunctionNoProtoTypeLoc :
01143     public InheritingConcreteTypeLoc<FunctionTypeLoc,
01144                                      FunctionNoProtoTypeLoc,
01145                                      FunctionNoProtoType> {
01146 };
01147 
01148 
01149 struct ArrayLocInfo {
01150   SourceLocation LBracketLoc, RBracketLoc;
01151   Expr *Size;
01152 };
01153 
01154 /// \brief Wrapper for source info for arrays.
01155 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
01156                                             ArrayTypeLoc,
01157                                             ArrayType,
01158                                             ArrayLocInfo> {
01159 public:
01160   SourceLocation getLBracketLoc() const {
01161     return getLocalData()->LBracketLoc;
01162   }
01163   void setLBracketLoc(SourceLocation Loc) {
01164     getLocalData()->LBracketLoc = Loc;
01165   }
01166 
01167   SourceLocation getRBracketLoc() const {
01168     return getLocalData()->RBracketLoc;
01169   }
01170   void setRBracketLoc(SourceLocation Loc) {
01171     getLocalData()->RBracketLoc = Loc;
01172   }
01173 
01174   SourceRange getBracketsRange() const {
01175     return SourceRange(getLBracketLoc(), getRBracketLoc());
01176   }
01177 
01178   Expr *getSizeExpr() const {
01179     return getLocalData()->Size;
01180   }
01181   void setSizeExpr(Expr *Size) {
01182     getLocalData()->Size = Size;
01183   }
01184 
01185   TypeLoc getElementLoc() const {
01186     return getInnerTypeLoc();
01187   }
01188 
01189   SourceRange getLocalSourceRange() const {
01190     return SourceRange(getLBracketLoc(), getRBracketLoc());
01191   }
01192 
01193   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01194     setLBracketLoc(Loc);
01195     setRBracketLoc(Loc);
01196     setSizeExpr(NULL);
01197   }
01198 
01199   QualType getInnerType() const { return getTypePtr()->getElementType(); }
01200 };
01201 
01202 class ConstantArrayTypeLoc :
01203     public InheritingConcreteTypeLoc<ArrayTypeLoc,
01204                                      ConstantArrayTypeLoc,
01205                                      ConstantArrayType> {
01206 };
01207 
01208 class IncompleteArrayTypeLoc :
01209     public InheritingConcreteTypeLoc<ArrayTypeLoc,
01210                                      IncompleteArrayTypeLoc,
01211                                      IncompleteArrayType> {
01212 };
01213 
01214 class DependentSizedArrayTypeLoc :
01215     public InheritingConcreteTypeLoc<ArrayTypeLoc,
01216                                      DependentSizedArrayTypeLoc,
01217                                      DependentSizedArrayType> {
01218 
01219 };
01220 
01221 class VariableArrayTypeLoc :
01222     public InheritingConcreteTypeLoc<ArrayTypeLoc,
01223                                      VariableArrayTypeLoc,
01224                                      VariableArrayType> {
01225 };
01226 
01227 
01228 // Location information for a TemplateName.  Rudimentary for now.
01229 struct TemplateNameLocInfo {
01230   SourceLocation NameLoc;
01231 };
01232 
01233 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
01234   SourceLocation TemplateKWLoc;
01235   SourceLocation LAngleLoc;
01236   SourceLocation RAngleLoc;
01237 };
01238 
01239 class TemplateSpecializationTypeLoc :
01240     public ConcreteTypeLoc<UnqualTypeLoc,
01241                            TemplateSpecializationTypeLoc,
01242                            TemplateSpecializationType,
01243                            TemplateSpecializationLocInfo> {
01244 public:
01245   SourceLocation getTemplateKeywordLoc() const {
01246     return getLocalData()->TemplateKWLoc;
01247   }
01248   void setTemplateKeywordLoc(SourceLocation Loc) {
01249     getLocalData()->TemplateKWLoc = Loc;
01250   }
01251 
01252   SourceLocation getLAngleLoc() const {
01253     return getLocalData()->LAngleLoc;
01254   }
01255   void setLAngleLoc(SourceLocation Loc) {
01256     getLocalData()->LAngleLoc = Loc;
01257   }
01258 
01259   SourceLocation getRAngleLoc() const {
01260     return getLocalData()->RAngleLoc;
01261   }
01262   void setRAngleLoc(SourceLocation Loc) {
01263     getLocalData()->RAngleLoc = Loc;
01264   }
01265 
01266   unsigned getNumArgs() const {
01267     return getTypePtr()->getNumArgs();
01268   }
01269   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
01270     getArgInfos()[i] = AI;
01271   }
01272   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
01273     return getArgInfos()[i];
01274   }
01275 
01276   TemplateArgumentLoc getArgLoc(unsigned i) const {
01277     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
01278   }
01279 
01280   SourceLocation getTemplateNameLoc() const {
01281     return getLocalData()->NameLoc;
01282   }
01283   void setTemplateNameLoc(SourceLocation Loc) {
01284     getLocalData()->NameLoc = Loc;
01285   }
01286 
01287   /// \brief - Copy the location information from the given info.
01288   void copy(TemplateSpecializationTypeLoc Loc) {
01289     unsigned size = getFullDataSize();
01290     assert(size == Loc.getFullDataSize());
01291 
01292     // We're potentially copying Expr references here.  We don't
01293     // bother retaining them because TypeSourceInfos live forever, so
01294     // as long as the Expr was retained when originally written into
01295     // the TypeLoc, we're okay.
01296     memcpy(Data, Loc.Data, size);
01297   }
01298 
01299   SourceRange getLocalSourceRange() const {
01300     if (getTemplateKeywordLoc().isValid())
01301       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
01302     else
01303       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
01304   }
01305 
01306   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01307     setTemplateKeywordLoc(Loc);
01308     setTemplateNameLoc(Loc);
01309     setLAngleLoc(Loc);
01310     setRAngleLoc(Loc);
01311     initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
01312                       getArgInfos(), Loc);
01313   }
01314 
01315   static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
01316                                 const TemplateArgument *Args,
01317                                 TemplateArgumentLocInfo *ArgInfos,
01318                                 SourceLocation Loc);
01319 
01320   unsigned getExtraLocalDataSize() const {
01321     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
01322   }
01323 
01324 private:
01325   TemplateArgumentLocInfo *getArgInfos() const {
01326     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
01327   }
01328 };
01329 
01330 //===----------------------------------------------------------------------===//
01331 //
01332 //  All of these need proper implementations.
01333 //
01334 //===----------------------------------------------------------------------===//
01335 
01336 // FIXME: size expression and attribute locations (or keyword if we
01337 // ever fully support altivec syntax).
01338 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
01339                                                        VectorTypeLoc,
01340                                                        VectorType> {
01341 };
01342 
01343 // FIXME: size expression and attribute locations.
01344 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
01345                                                           ExtVectorTypeLoc,
01346                                                           ExtVectorType> {
01347 };
01348 
01349 // FIXME: attribute locations.
01350 // For some reason, this isn't a subtype of VectorType.
01351 class DependentSizedExtVectorTypeLoc :
01352     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
01353                                      DependentSizedExtVectorTypeLoc,
01354                                      DependentSizedExtVectorType> {
01355 };
01356 
01357 // FIXME: location of the '_Complex' keyword.
01358 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
01359                                                         ComplexTypeLoc,
01360                                                         ComplexType> {
01361 };
01362 
01363 struct TypeofLocInfo {
01364   SourceLocation TypeofLoc;
01365   SourceLocation LParenLoc;
01366   SourceLocation RParenLoc;
01367 };
01368 
01369 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
01370 };
01371 
01372 struct TypeOfTypeLocInfo : public TypeofLocInfo {
01373   TypeSourceInfo* UnderlyingTInfo;
01374 };
01375 
01376 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
01377 class TypeofLikeTypeLoc
01378   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
01379 public:
01380   SourceLocation getTypeofLoc() const {
01381     return this->getLocalData()->TypeofLoc;
01382   }
01383   void setTypeofLoc(SourceLocation Loc) {
01384     this->getLocalData()->TypeofLoc = Loc;
01385   }
01386 
01387   SourceLocation getLParenLoc() const {
01388     return this->getLocalData()->LParenLoc;
01389   }
01390   void setLParenLoc(SourceLocation Loc) {
01391     this->getLocalData()->LParenLoc = Loc;
01392   }
01393 
01394   SourceLocation getRParenLoc() const {
01395     return this->getLocalData()->RParenLoc;
01396   }
01397   void setRParenLoc(SourceLocation Loc) {
01398     this->getLocalData()->RParenLoc = Loc;
01399   }
01400 
01401   SourceRange getParensRange() const {
01402     return SourceRange(getLParenLoc(), getRParenLoc());
01403   }
01404   void setParensRange(SourceRange range) {
01405       setLParenLoc(range.getBegin());
01406       setRParenLoc(range.getEnd());
01407   }
01408 
01409   SourceRange getLocalSourceRange() const {
01410     return SourceRange(getTypeofLoc(), getRParenLoc());
01411   }
01412 
01413   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01414     setTypeofLoc(Loc);
01415     setLParenLoc(Loc);
01416     setRParenLoc(Loc);
01417   }
01418 };
01419 
01420 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
01421                                                    TypeOfExprType,
01422                                                    TypeOfExprTypeLocInfo> {
01423 public:
01424   Expr* getUnderlyingExpr() const {
01425     return getTypePtr()->getUnderlyingExpr();
01426   }
01427   // Reimplemented to account for GNU/C++ extension
01428   //     typeof unary-expression
01429   // where there are no parentheses.
01430   SourceRange getLocalSourceRange() const;
01431 };
01432 
01433 class TypeOfTypeLoc
01434   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
01435 public:
01436   QualType getUnderlyingType() const {
01437     return this->getTypePtr()->getUnderlyingType();
01438   }
01439   TypeSourceInfo* getUnderlyingTInfo() const {
01440     return this->getLocalData()->UnderlyingTInfo;
01441   }
01442   void setUnderlyingTInfo(TypeSourceInfo* TI) const {
01443     this->getLocalData()->UnderlyingTInfo = TI;
01444   }
01445 };
01446 
01447 // FIXME: location of the 'decltype' and parens.
01448 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
01449                                                          DecltypeTypeLoc,
01450                                                          DecltypeType> {
01451 public:
01452   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
01453 };
01454 
01455 struct UnaryTransformTypeLocInfo {
01456   // FIXME: While there's only one unary transform right now, future ones may
01457   // need different representations
01458   SourceLocation KWLoc, LParenLoc, RParenLoc;
01459   TypeSourceInfo *UnderlyingTInfo;
01460 };
01461 
01462 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
01463                                                     UnaryTransformTypeLoc,
01464                                                     UnaryTransformType,
01465                                                     UnaryTransformTypeLocInfo> {
01466 public:
01467   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
01468   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
01469 
01470   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
01471   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
01472 
01473   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
01474   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
01475 
01476   TypeSourceInfo* getUnderlyingTInfo() const {
01477     return getLocalData()->UnderlyingTInfo;
01478   }
01479   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
01480     getLocalData()->UnderlyingTInfo = TInfo;
01481   }
01482 
01483   SourceRange getLocalSourceRange() const {
01484     return SourceRange(getKWLoc(), getRParenLoc());
01485   }
01486 
01487   SourceRange getParensRange() const {
01488     return SourceRange(getLParenLoc(), getRParenLoc());
01489   }
01490   void setParensRange(SourceRange Range) {
01491     setLParenLoc(Range.getBegin());
01492     setRParenLoc(Range.getEnd());
01493   }
01494 
01495   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01496     setKWLoc(Loc);
01497     setRParenLoc(Loc);
01498     setLParenLoc(Loc);
01499   }
01500 };
01501 
01502 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
01503                                                         AutoTypeLoc,
01504                                                         AutoType> {
01505 };
01506 
01507 struct ElaboratedLocInfo {
01508   SourceLocation ElaboratedKWLoc;
01509   /// \brief Data associated with the nested-name-specifier location.
01510   void *QualifierData;
01511 };
01512 
01513 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
01514                                                  ElaboratedTypeLoc,
01515                                                  ElaboratedType,
01516                                                  ElaboratedLocInfo> {
01517 public:
01518   SourceLocation getElaboratedKeywordLoc() const {
01519     return this->getLocalData()->ElaboratedKWLoc;
01520   }
01521   void setElaboratedKeywordLoc(SourceLocation Loc) {
01522     this->getLocalData()->ElaboratedKWLoc = Loc;
01523   }
01524 
01525   NestedNameSpecifierLoc getQualifierLoc() const {
01526     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
01527                                   getLocalData()->QualifierData);
01528   }
01529 
01530   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
01531     assert(QualifierLoc.getNestedNameSpecifier()
01532                                             == getTypePtr()->getQualifier() &&
01533            "Inconsistent nested-name-specifier pointer");
01534     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
01535   }
01536 
01537   SourceRange getLocalSourceRange() const {
01538     if (getElaboratedKeywordLoc().isValid())
01539       if (getQualifierLoc())
01540         return SourceRange(getElaboratedKeywordLoc(),
01541                            getQualifierLoc().getEndLoc());
01542       else
01543         return SourceRange(getElaboratedKeywordLoc());
01544     else
01545       return getQualifierLoc().getSourceRange();
01546   }
01547 
01548   void initializeLocal(ASTContext &Context, SourceLocation Loc);
01549 
01550   TypeLoc getNamedTypeLoc() const {
01551     return getInnerTypeLoc();
01552   }
01553 
01554   QualType getInnerType() const {
01555     return getTypePtr()->getNamedType();
01556   }
01557 
01558   void copy(ElaboratedTypeLoc Loc) {
01559     unsigned size = getFullDataSize();
01560     assert(size == Loc.getFullDataSize());
01561     memcpy(Data, Loc.Data, size);
01562   }
01563 };
01564 
01565 // This is exactly the structure of an ElaboratedTypeLoc whose inner
01566 // type is some sort of TypeDeclTypeLoc.
01567 struct DependentNameLocInfo : ElaboratedLocInfo {
01568   SourceLocation NameLoc;
01569 };
01570 
01571 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
01572                                                     DependentNameTypeLoc,
01573                                                     DependentNameType,
01574                                                     DependentNameLocInfo> {
01575 public:
01576   SourceLocation getElaboratedKeywordLoc() const {
01577     return this->getLocalData()->ElaboratedKWLoc;
01578   }
01579   void setElaboratedKeywordLoc(SourceLocation Loc) {
01580     this->getLocalData()->ElaboratedKWLoc = Loc;
01581   }
01582 
01583   NestedNameSpecifierLoc getQualifierLoc() const {
01584     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
01585                                   getLocalData()->QualifierData);
01586   }
01587 
01588   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
01589     assert(QualifierLoc.getNestedNameSpecifier()
01590                                             == getTypePtr()->getQualifier() &&
01591            "Inconsistent nested-name-specifier pointer");
01592     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
01593   }
01594 
01595   SourceLocation getNameLoc() const {
01596     return this->getLocalData()->NameLoc;
01597   }
01598   void setNameLoc(SourceLocation Loc) {
01599     this->getLocalData()->NameLoc = Loc;
01600   }
01601 
01602   SourceRange getLocalSourceRange() const {
01603     if (getElaboratedKeywordLoc().isValid())
01604       return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
01605     else
01606       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
01607   }
01608 
01609   void copy(DependentNameTypeLoc Loc) {
01610     unsigned size = getFullDataSize();
01611     assert(size == Loc.getFullDataSize());
01612     memcpy(Data, Loc.Data, size);
01613   }
01614 
01615   void initializeLocal(ASTContext &Context, SourceLocation Loc);
01616 };
01617 
01618 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
01619   SourceLocation TemplateKWLoc;
01620   SourceLocation LAngleLoc;
01621   SourceLocation RAngleLoc;
01622   // followed by a TemplateArgumentLocInfo[]
01623 };
01624 
01625 class DependentTemplateSpecializationTypeLoc :
01626     public ConcreteTypeLoc<UnqualTypeLoc,
01627                            DependentTemplateSpecializationTypeLoc,
01628                            DependentTemplateSpecializationType,
01629                            DependentTemplateSpecializationLocInfo> {
01630 public:
01631   SourceLocation getElaboratedKeywordLoc() const {
01632     return this->getLocalData()->ElaboratedKWLoc;
01633   }
01634   void setElaboratedKeywordLoc(SourceLocation Loc) {
01635     this->getLocalData()->ElaboratedKWLoc = Loc;
01636   }
01637 
01638   NestedNameSpecifierLoc getQualifierLoc() const {
01639     if (!getLocalData()->QualifierData)
01640       return NestedNameSpecifierLoc();
01641 
01642     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
01643                                   getLocalData()->QualifierData);
01644   }
01645 
01646   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
01647     if (!QualifierLoc) {
01648       // Even if we have a nested-name-specifier in the dependent
01649       // template specialization type, we won't record the nested-name-specifier
01650       // location information when this type-source location information is
01651       // part of a nested-name-specifier.
01652       getLocalData()->QualifierData = 0;
01653       return;
01654     }
01655 
01656     assert(QualifierLoc.getNestedNameSpecifier()
01657                                         == getTypePtr()->getQualifier() &&
01658            "Inconsistent nested-name-specifier pointer");
01659     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
01660   }
01661 
01662   SourceLocation getTemplateKeywordLoc() const {
01663     return getLocalData()->TemplateKWLoc;
01664   }
01665   void setTemplateKeywordLoc(SourceLocation Loc) {
01666     getLocalData()->TemplateKWLoc = Loc;
01667   }
01668 
01669   SourceLocation getTemplateNameLoc() const {
01670     return this->getLocalData()->NameLoc;
01671   }
01672   void setTemplateNameLoc(SourceLocation Loc) {
01673     this->getLocalData()->NameLoc = Loc;
01674   }
01675 
01676   SourceLocation getLAngleLoc() const {
01677     return this->getLocalData()->LAngleLoc;
01678   }
01679   void setLAngleLoc(SourceLocation Loc) {
01680     this->getLocalData()->LAngleLoc = Loc;
01681   }
01682 
01683   SourceLocation getRAngleLoc() const {
01684     return this->getLocalData()->RAngleLoc;
01685   }
01686   void setRAngleLoc(SourceLocation Loc) {
01687     this->getLocalData()->RAngleLoc = Loc;
01688   }
01689 
01690   unsigned getNumArgs() const {
01691     return getTypePtr()->getNumArgs();
01692   }
01693 
01694   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
01695     getArgInfos()[i] = AI;
01696   }
01697   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
01698     return getArgInfos()[i];
01699   }
01700 
01701   TemplateArgumentLoc getArgLoc(unsigned i) const {
01702     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
01703   }
01704 
01705   SourceRange getLocalSourceRange() const {
01706     if (getElaboratedKeywordLoc().isValid())
01707       return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
01708     else if (getQualifierLoc())
01709       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
01710     else if (getTemplateKeywordLoc().isValid())
01711       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
01712     else
01713       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
01714   }
01715 
01716   void copy(DependentTemplateSpecializationTypeLoc Loc) {
01717     unsigned size = getFullDataSize();
01718     assert(size == Loc.getFullDataSize());
01719     memcpy(Data, Loc.Data, size);
01720   }
01721 
01722   void initializeLocal(ASTContext &Context, SourceLocation Loc);
01723 
01724   unsigned getExtraLocalDataSize() const {
01725     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
01726   }
01727 
01728 private:
01729   TemplateArgumentLocInfo *getArgInfos() const {
01730     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
01731   }
01732 };
01733 
01734 
01735 struct PackExpansionTypeLocInfo {
01736   SourceLocation EllipsisLoc;
01737 };
01738 
01739 class PackExpansionTypeLoc
01740   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
01741                            PackExpansionType, PackExpansionTypeLocInfo> {
01742 public:
01743   SourceLocation getEllipsisLoc() const {
01744     return this->getLocalData()->EllipsisLoc;
01745   }
01746 
01747   void setEllipsisLoc(SourceLocation Loc) {
01748     this->getLocalData()->EllipsisLoc = Loc;
01749   }
01750 
01751   SourceRange getLocalSourceRange() const {
01752     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
01753   }
01754 
01755   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01756     setEllipsisLoc(Loc);
01757   }
01758 
01759   TypeLoc getPatternLoc() const {
01760     return getInnerTypeLoc();
01761   }
01762 
01763   QualType getInnerType() const {
01764     return this->getTypePtr()->getPattern();
01765   }
01766 };
01767 
01768 struct AtomicTypeLocInfo {
01769   SourceLocation KWLoc, LParenLoc, RParenLoc;
01770 };
01771 
01772 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
01773                                              AtomicType, AtomicTypeLocInfo> {
01774 public:
01775   TypeLoc getValueLoc() const {
01776     return this->getInnerTypeLoc();
01777   }
01778 
01779   SourceRange getLocalSourceRange() const {
01780     return SourceRange(getKWLoc(), getRParenLoc());
01781   }
01782 
01783   SourceLocation getKWLoc() const {
01784     return this->getLocalData()->KWLoc;
01785   }
01786   void setKWLoc(SourceLocation Loc) {
01787     this->getLocalData()->KWLoc = Loc;
01788   }
01789 
01790   SourceLocation getLParenLoc() const {
01791     return this->getLocalData()->LParenLoc;
01792   }
01793   void setLParenLoc(SourceLocation Loc) {
01794     this->getLocalData()->LParenLoc = Loc;
01795   }
01796 
01797   SourceLocation getRParenLoc() const {
01798     return this->getLocalData()->RParenLoc;
01799   }
01800   void setRParenLoc(SourceLocation Loc) {
01801     this->getLocalData()->RParenLoc = Loc;
01802   }
01803 
01804   SourceRange getParensRange() const {
01805     return SourceRange(getLParenLoc(), getRParenLoc());
01806   }
01807   void setParensRange(SourceRange Range) {
01808     setLParenLoc(Range.getBegin());
01809     setRParenLoc(Range.getEnd());
01810   }
01811 
01812   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
01813     setKWLoc(Loc);
01814     setLParenLoc(Loc);
01815     setRParenLoc(Loc);
01816   }
01817 
01818   QualType getInnerType() const {
01819     return this->getTypePtr()->getValueType();
01820   }
01821 };
01822 
01823 
01824 }
01825 
01826 #endif