clang API Documentation

CanonicalType.h
Go to the documentation of this file.
00001 //===-- CanonicalType.h - C Language Family Type Representation -*- 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 CanQual class template, which provides access to
00011 //  canonical types.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
00016 #define LLVM_CLANG_AST_CANONICAL_TYPE_H
00017 
00018 #include "clang/AST/Type.h"
00019 #include "llvm/Support/Casting.h"
00020 #include "llvm/Support/type_traits.h"
00021 #include <iterator>
00022 
00023 namespace clang {
00024 
00025 template<typename T> class CanProxy;
00026 template<typename T> struct CanProxyAdaptor;
00027 
00028 //----------------------------------------------------------------------------//
00029 // Canonical, qualified type template
00030 //----------------------------------------------------------------------------//
00031 
00032 /// \brief Represents a canonical, potentially-qualified type.
00033 ///
00034 /// The CanQual template is a lightweight smart pointer that provides access
00035 /// to the canonical representation of a type, where all typedefs and other
00036 /// syntactic sugar has been eliminated. A CanQualType may also have various
00037 /// qualifiers (const, volatile, restrict) attached to it.
00038 ///
00039 /// The template type parameter @p T is one of the Type classes (PointerType,
00040 /// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
00041 /// type (or some subclass of that type). The typedef @c CanQualType is just
00042 /// a shorthand for @c CanQual<Type>.
00043 ///
00044 /// An instance of @c CanQual<T> can be implicitly converted to a
00045 /// @c CanQual<U> when T is derived from U, which essentially provides an
00046 /// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
00047 /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
00048 /// be implicitly converted to a QualType, but the reverse operation requires
00049 /// a call to ASTContext::getCanonicalType().
00050 ///
00051 ///
00052 template<typename T = Type>
00053 class CanQual {
00054   /// \brief The actual, canonical type.
00055   QualType Stored;
00056 
00057 public:
00058   /// \brief Constructs a NULL canonical type.
00059   CanQual() : Stored() { }
00060 
00061   /// \brief Converting constructor that permits implicit upcasting of
00062   /// canonical type pointers.
00063   template<typename U>
00064   CanQual(const CanQual<U>& Other,
00065           typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
00066 
00067   /// \brief Retrieve the underlying type pointer, which refers to a
00068   /// canonical type.
00069   ///
00070   /// The underlying pointer must not be NULL.
00071   const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
00072 
00073   /// \brief Retrieve the underlying type pointer, which refers to a
00074   /// canonical type, or NULL.
00075   ///
00076   const T *getTypePtrOrNull() const { 
00077     return cast_or_null<T>(Stored.getTypePtrOrNull()); 
00078   }
00079 
00080   /// \brief Implicit conversion to a qualified type.
00081   operator QualType() const { return Stored; }
00082 
00083   /// \brief Implicit conversion to bool.
00084   operator bool() const { return !isNull(); }
00085   
00086   bool isNull() const {
00087     return Stored.isNull();
00088   }
00089 
00090   SplitQualType split() const { return Stored.split(); }
00091 
00092   /// \brief Retrieve a canonical type pointer with a different static type,
00093   /// upcasting or downcasting as needed.
00094   ///
00095   /// The getAs() function is typically used to try to downcast to a
00096   /// more specific (canonical) type in the type system. For example:
00097   ///
00098   /// @code
00099   /// void f(CanQual<Type> T) {
00100   ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
00101   ///     // look at Ptr's pointee type
00102   ///   }
00103   /// }
00104   /// @endcode
00105   ///
00106   /// \returns A proxy pointer to the same type, but with the specified
00107   /// static type (@p U). If the dynamic type is not the specified static type
00108   /// or a derived class thereof, a NULL canonical type.
00109   template<typename U> CanProxy<U> getAs() const;
00110 
00111   template<typename U> CanProxy<U> castAs() const;
00112 
00113   /// \brief Overloaded arrow operator that produces a canonical type
00114   /// proxy.
00115   CanProxy<T> operator->() const;
00116 
00117   /// \brief Retrieve all qualifiers.
00118   Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
00119 
00120   /// \brief Retrieve the const/volatile/restrict qualifiers.
00121   unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
00122 
00123   /// \brief Determines whether this type has any qualifiers
00124   bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
00125 
00126   bool isConstQualified() const {
00127     return Stored.isLocalConstQualified();
00128   }
00129   bool isVolatileQualified() const {
00130     return Stored.isLocalVolatileQualified();
00131   }
00132   bool isRestrictQualified() const {
00133     return Stored.isLocalRestrictQualified();
00134   }
00135 
00136   /// \brief Determines if this canonical type is furthermore
00137   /// canonical as a parameter.  The parameter-canonicalization
00138   /// process decays arrays to pointers and drops top-level qualifiers.
00139   bool isCanonicalAsParam() const {
00140     return Stored.isCanonicalAsParam();
00141   }
00142 
00143   /// \brief Retrieve the unqualified form of this type.
00144   CanQual<T> getUnqualifiedType() const;
00145 
00146   /// \brief Retrieves a version of this type with const applied.
00147   /// Note that this does not always yield a canonical type.
00148   QualType withConst() const {
00149     return Stored.withConst();
00150   }
00151 
00152   /// \brief Determines whether this canonical type is more qualified than
00153   /// the @p Other canonical type.
00154   bool isMoreQualifiedThan(CanQual<T> Other) const {
00155     return Stored.isMoreQualifiedThan(Other.Stored);
00156   }
00157 
00158   /// \brief Determines whether this canonical type is at least as qualified as
00159   /// the @p Other canonical type.
00160   bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
00161     return Stored.isAtLeastAsQualifiedAs(Other.Stored);
00162   }
00163 
00164   /// \brief If the canonical type is a reference type, returns the type that
00165   /// it refers to; otherwise, returns the type itself.
00166   CanQual<Type> getNonReferenceType() const;
00167 
00168   /// \brief Retrieve the internal representation of this canonical type.
00169   void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
00170 
00171   /// \brief Construct a canonical type from its internal representation.
00172   static CanQual<T> getFromOpaquePtr(void *Ptr);
00173 
00174   /// \brief Builds a canonical type from a QualType.
00175   ///
00176   /// This routine is inherently unsafe, because it requires the user to
00177   /// ensure that the given type is a canonical type with the correct
00178   // (dynamic) type.
00179   static CanQual<T> CreateUnsafe(QualType Other);
00180 
00181   void dump() const { Stored.dump(); }
00182 
00183   void Profile(llvm::FoldingSetNodeID &ID) const {
00184     ID.AddPointer(getAsOpaquePtr());
00185   }
00186 };
00187 
00188 template<typename T, typename U>
00189 inline bool operator==(CanQual<T> x, CanQual<U> y) {
00190   return x.getAsOpaquePtr() == y.getAsOpaquePtr();
00191 }
00192 
00193 template<typename T, typename U>
00194 inline bool operator!=(CanQual<T> x, CanQual<U> y) {
00195   return x.getAsOpaquePtr() != y.getAsOpaquePtr();
00196 }
00197 
00198 /// \brief Represents a canonical, potentially-qualified type.
00199 typedef CanQual<Type> CanQualType;
00200 
00201 inline CanQualType Type::getCanonicalTypeUnqualified() const {
00202   return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
00203 }
00204 
00205 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00206                                            CanQualType T) {
00207   DB << static_cast<QualType>(T);
00208   return DB;
00209 }
00210 
00211 //----------------------------------------------------------------------------//
00212 // Internal proxy classes used by canonical types
00213 //----------------------------------------------------------------------------//
00214 
00215 #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
00216 CanQualType Accessor() const {                                           \
00217 return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
00218 }
00219 
00220 #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
00221 Type Accessor() const { return this->getTypePtr()->Accessor(); }
00222 
00223 /// \brief Base class of all canonical proxy types, which is responsible for
00224 /// storing the underlying canonical type and providing basic conversions.
00225 template<typename T>
00226 class CanProxyBase {
00227 protected:
00228   CanQual<T> Stored;
00229 
00230 public:
00231   /// \brief Retrieve the pointer to the underlying Type
00232   const T *getTypePtr() const { return Stored.getTypePtr(); }
00233 
00234   /// \brief Implicit conversion to the underlying pointer.
00235   ///
00236   /// Also provides the ability to use canonical type proxies in a Boolean
00237   // context,e.g.,
00238   /// @code
00239   ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
00240   /// @endcode
00241   operator const T*() const { return this->Stored.getTypePtrOrNull(); }
00242 
00243   /// \brief Try to convert the given canonical type to a specific structural
00244   /// type.
00245   template<typename U> CanProxy<U> getAs() const {
00246     return this->Stored.template getAs<U>();
00247   }
00248 
00249   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
00250 
00251   // Type predicates
00252   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
00253   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
00254   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
00255   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
00256   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
00257   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
00258   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
00259   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
00260   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
00261   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
00262   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
00263   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
00264   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
00265   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
00266   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
00267   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
00268   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
00269   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
00270   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
00271   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
00272   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
00273   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
00274   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
00275   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
00276   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
00277   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
00278   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
00279   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
00280   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
00281   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
00282   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
00283   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
00284   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
00285   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
00286   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
00287   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
00288   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
00289   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
00290   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
00291   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
00292   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
00293   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
00294   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
00295   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
00296   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
00297   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
00298   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
00299   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
00300 
00301   /// \brief Retrieve the proxy-adaptor type.
00302   ///
00303   /// This arrow operator is used when CanProxyAdaptor has been specialized
00304   /// for the given type T. In that case, we reference members of the
00305   /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
00306   /// by the arrow operator in the primary CanProxyAdaptor template.
00307   const CanProxyAdaptor<T> *operator->() const {
00308     return static_cast<const CanProxyAdaptor<T> *>(this);
00309   }
00310 };
00311 
00312 /// \brief Replacable canonical proxy adaptor class that provides the link
00313 /// between a canonical type and the accessors of the type.
00314 ///
00315 /// The CanProxyAdaptor is a replaceable class template that is instantiated
00316 /// as part of each canonical proxy type. The primary template merely provides
00317 /// redirection to the underlying type (T), e.g., @c PointerType. One can
00318 /// provide specializations of this class template for each underlying type
00319 /// that provide accessors returning canonical types (@c CanQualType) rather
00320 /// than the more typical @c QualType, to propagate the notion of "canonical"
00321 /// through the system.
00322 template<typename T>
00323 struct CanProxyAdaptor : CanProxyBase<T> { };
00324 
00325 /// \brief Canonical proxy type returned when retrieving the members of a
00326 /// canonical type or as the result of the @c CanQual<T>::getAs member
00327 /// function.
00328 ///
00329 /// The CanProxy type mainly exists as a proxy through which operator-> will
00330 /// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
00331 /// type that provides canonical-type access to the fields of the type.
00332 template<typename T>
00333 class CanProxy : public CanProxyAdaptor<T> {
00334 public:
00335   /// \brief Build a NULL proxy.
00336   CanProxy() { }
00337 
00338   /// \brief Build a proxy to the given canonical type.
00339   CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
00340 
00341   /// \brief Implicit conversion to the stored canonical type.
00342   operator CanQual<T>() const { return this->Stored; }
00343 };
00344 
00345 } // end namespace clang
00346 
00347 namespace llvm {
00348 
00349 /// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
00350 /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
00351 /// to return smart pointer (proxies?).
00352 template<typename T>
00353 struct simplify_type<const ::clang::CanQual<T> > {
00354   typedef const T *SimpleType;
00355   static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
00356     return Val.getTypePtr();
00357   }
00358 };
00359 template<typename T>
00360 struct simplify_type< ::clang::CanQual<T> >
00361 : public simplify_type<const ::clang::CanQual<T> > {};
00362 
00363 // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
00364 template<typename T>
00365 class PointerLikeTypeTraits<clang::CanQual<T> > {
00366 public:
00367   static inline void *getAsVoidPointer(clang::CanQual<T> P) {
00368     return P.getAsOpaquePtr();
00369   }
00370   static inline clang::CanQual<T> getFromVoidPointer(void *P) {
00371     return clang::CanQual<T>::getFromOpaquePtr(P);
00372   }
00373   // qualifier information is encoded in the low bits.
00374   enum { NumLowBitsAvailable = 0 };
00375 };
00376 
00377 } // end namespace llvm
00378 
00379 namespace clang {
00380 
00381 //----------------------------------------------------------------------------//
00382 // Canonical proxy adaptors for canonical type nodes.
00383 //----------------------------------------------------------------------------//
00384 
00385 /// \brief Iterator adaptor that turns an iterator over canonical QualTypes
00386 /// into an iterator over CanQualTypes.
00387 template<typename InputIterator>
00388 class CanTypeIterator {
00389   InputIterator Iter;
00390 
00391 public:
00392   typedef CanQualType    value_type;
00393   typedef value_type     reference;
00394   typedef CanProxy<Type> pointer;
00395   typedef typename std::iterator_traits<InputIterator>::difference_type
00396     difference_type;
00397   typedef typename std::iterator_traits<InputIterator>::iterator_category
00398     iterator_category;
00399 
00400   CanTypeIterator() : Iter() { }
00401   explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
00402 
00403   // Input iterator
00404   reference operator*() const {
00405     return CanQualType::CreateUnsafe(*Iter);
00406   }
00407 
00408   pointer operator->() const;
00409 
00410   CanTypeIterator &operator++() {
00411     ++Iter;
00412     return *this;
00413   }
00414 
00415   CanTypeIterator operator++(int) {
00416     CanTypeIterator Tmp(*this);
00417     ++Iter;
00418     return Tmp;
00419   }
00420 
00421   friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
00422     return X.Iter == Y.Iter;
00423   }
00424   friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
00425     return X.Iter != Y.Iter;
00426   }
00427 
00428   // Bidirectional iterator
00429   CanTypeIterator &operator--() {
00430     --Iter;
00431     return *this;
00432   }
00433 
00434   CanTypeIterator operator--(int) {
00435     CanTypeIterator Tmp(*this);
00436     --Iter;
00437     return Tmp;
00438   }
00439 
00440   // Random access iterator
00441   reference operator[](difference_type n) const {
00442     return CanQualType::CreateUnsafe(Iter[n]);
00443   }
00444 
00445   CanTypeIterator &operator+=(difference_type n) {
00446     Iter += n;
00447     return *this;
00448   }
00449 
00450   CanTypeIterator &operator-=(difference_type n) {
00451     Iter -= n;
00452     return *this;
00453   }
00454 
00455   friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
00456     X += n;
00457     return X;
00458   }
00459 
00460   friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
00461     X += n;
00462     return X;
00463   }
00464 
00465   friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
00466     X -= n;
00467     return X;
00468   }
00469 
00470   friend difference_type operator-(const CanTypeIterator &X,
00471                                    const CanTypeIterator &Y) {
00472     return X - Y;
00473   }
00474 };
00475 
00476 template<>
00477 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
00478   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00479 };
00480 
00481 template<>
00482 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
00483   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00484 };
00485 
00486 template<>
00487 struct CanProxyAdaptor<BlockPointerType>
00488   : public CanProxyBase<BlockPointerType> {
00489   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00490 };
00491 
00492 template<>
00493 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
00494   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00495 };
00496 
00497 template<>
00498 struct CanProxyAdaptor<LValueReferenceType>
00499   : public CanProxyBase<LValueReferenceType> {
00500   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00501 };
00502 
00503 template<>
00504 struct CanProxyAdaptor<RValueReferenceType>
00505   : public CanProxyBase<RValueReferenceType> {
00506   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00507 };
00508 
00509 template<>
00510 struct CanProxyAdaptor<MemberPointerType>
00511   : public CanProxyBase<MemberPointerType> {
00512   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00513   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
00514 };
00515 
00516 template<>
00517 struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
00518   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00519   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
00520                                       getSizeModifier)
00521   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
00522 };
00523 
00524 template<>
00525 struct CanProxyAdaptor<ConstantArrayType>
00526   : public CanProxyBase<ConstantArrayType> {
00527   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00528   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
00529                                       getSizeModifier)
00530   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
00531   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
00532 };
00533 
00534 template<>
00535 struct CanProxyAdaptor<IncompleteArrayType>
00536   : public CanProxyBase<IncompleteArrayType> {
00537   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00538   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
00539                                       getSizeModifier)
00540   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
00541 };
00542 
00543 template<>
00544 struct CanProxyAdaptor<VariableArrayType>
00545   : public CanProxyBase<VariableArrayType> {
00546   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00547   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
00548                                       getSizeModifier)
00549   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
00550   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
00551   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
00552   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
00553   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
00554 };
00555 
00556 template<>
00557 struct CanProxyAdaptor<DependentSizedArrayType>
00558   : public CanProxyBase<DependentSizedArrayType> {
00559   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00560   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
00561   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
00562   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
00563   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
00564 };
00565 
00566 template<>
00567 struct CanProxyAdaptor<DependentSizedExtVectorType>
00568   : public CanProxyBase<DependentSizedExtVectorType> {
00569   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00570   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
00571   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
00572 };
00573 
00574 template<>
00575 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
00576   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00577   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
00578 };
00579 
00580 template<>
00581 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
00582   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
00583   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
00584 };
00585 
00586 template<>
00587 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
00588   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
00589   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
00590 };
00591 
00592 template<>
00593 struct CanProxyAdaptor<FunctionNoProtoType>
00594   : public CanProxyBase<FunctionNoProtoType> {
00595   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
00596   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
00597 };
00598 
00599 template<>
00600 struct CanProxyAdaptor<FunctionProtoType>
00601   : public CanProxyBase<FunctionProtoType> {
00602   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
00603   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
00604   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
00605   CanQualType getArgType(unsigned i) const {
00606     return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
00607   }
00608 
00609   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
00610   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
00611 
00612   typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
00613     arg_type_iterator;
00614 
00615   arg_type_iterator arg_type_begin() const {
00616     return arg_type_iterator(this->getTypePtr()->arg_type_begin());
00617   }
00618 
00619   arg_type_iterator arg_type_end() const {
00620     return arg_type_iterator(this->getTypePtr()->arg_type_end());
00621   }
00622 
00623   // Note: canonical function types never have exception specifications
00624 };
00625 
00626 template<>
00627 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
00628   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
00629 };
00630 
00631 template<>
00632 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
00633   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
00634   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
00635 };
00636 
00637 template <>
00638 struct CanProxyAdaptor<UnaryTransformType>
00639     : public CanProxyBase<UnaryTransformType> {
00640   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
00641   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
00642   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
00643 };
00644 
00645 template<>
00646 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
00647   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
00648   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
00649 };
00650 
00651 template<>
00652 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
00653   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
00654   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
00655   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
00656 };
00657 
00658 template<>
00659 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
00660   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
00661   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
00662 };
00663 
00664 template<>
00665 struct CanProxyAdaptor<TemplateTypeParmType>
00666   : public CanProxyBase<TemplateTypeParmType> {
00667   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
00668   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
00669   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
00670   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
00671   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
00672 };
00673 
00674 template<>
00675 struct CanProxyAdaptor<ObjCObjectType>
00676   : public CanProxyBase<ObjCObjectType> {
00677   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
00678   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
00679                                       getInterface)
00680   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
00681   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
00682   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
00683   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
00684 
00685   typedef ObjCObjectPointerType::qual_iterator qual_iterator;
00686   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
00687   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
00688   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
00689   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
00690 };
00691 
00692 template<>
00693 struct CanProxyAdaptor<ObjCObjectPointerType>
00694   : public CanProxyBase<ObjCObjectPointerType> {
00695   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
00696   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
00697                                       getInterfaceType)
00698   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
00699   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
00700   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
00701   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
00702 
00703   typedef ObjCObjectPointerType::qual_iterator qual_iterator;
00704   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
00705   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
00706   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
00707   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
00708 };
00709 
00710 //----------------------------------------------------------------------------//
00711 // Method and function definitions
00712 //----------------------------------------------------------------------------//
00713 template<typename T>
00714 inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
00715   return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
00716 }
00717 
00718 template<typename T>
00719 inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
00720   if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
00721     return RefType->getPointeeType();
00722   else
00723     return *this;
00724 }
00725 
00726 template<typename T>
00727 CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
00728   CanQual<T> Result;
00729   Result.Stored = QualType::getFromOpaquePtr(Ptr);
00730   assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
00731           Result.Stored.isCanonical()) && "Type is not canonical!");
00732   return Result;
00733 }
00734 
00735 template<typename T>
00736 CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
00737   assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
00738   assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
00739          "Dynamic type does not meet the static type's requires");
00740   CanQual<T> Result;
00741   Result.Stored = Other;
00742   return Result;
00743 }
00744 
00745 template<typename T>
00746 template<typename U>
00747 CanProxy<U> CanQual<T>::getAs() const {
00748   if (Stored.isNull())
00749     return CanProxy<U>();
00750 
00751   if (isa<U>(Stored.getTypePtr()))
00752     return CanQual<U>::CreateUnsafe(Stored);
00753 
00754   return CanProxy<U>();
00755 }
00756 
00757 template<typename T>
00758 template<typename U>
00759 CanProxy<U> CanQual<T>::castAs() const {
00760   assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
00761   return CanQual<U>::CreateUnsafe(Stored);
00762 }
00763 
00764 template<typename T>
00765 CanProxy<T> CanQual<T>::operator->() const {
00766   return CanProxy<T>(*this);
00767 }
00768 
00769 template<typename InputIterator>
00770 typename CanTypeIterator<InputIterator>::pointer
00771 CanTypeIterator<InputIterator>::operator->() const {
00772   return CanProxy<Type>(*this);
00773 }
00774 
00775 }
00776 
00777 
00778 #endif // LLVM_CLANG_AST_CANONICAL_TYPE_H