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