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