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_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