clang API Documentation
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