CanonicalType.h revision 50d62d1b4a98adbc83de8f8cd1379ea1c25656f7
1//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the CanQual class template, which provides access to 11// canonical types. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H 16#define LLVM_CLANG_AST_CANONICAL_TYPE_H 17 18#include "clang/AST/Type.h" 19#include "llvm/Support/Casting.h" 20#include "llvm/Support/type_traits.h" 21#include <iterator> 22 23namespace clang { 24 25template<typename T> class CanProxy; 26template<typename T> struct CanProxyAdaptor; 27 28//----------------------------------------------------------------------------// 29// Canonical, qualified type template 30//----------------------------------------------------------------------------// 31 32/// \brief Represents a canonical, potentially-qualified type. 33/// 34/// The CanQual template is a lightweight smart pointer that provides access 35/// to the canonical representation of a type, where all typedefs and other 36/// syntactic sugar has been eliminated. A CanQualType may also have various 37/// qualifiers (const, volatile, restrict) attached to it. 38/// 39/// The template type parameter @p T is one of the Type classes (PointerType, 40/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that 41/// type (or some subclass of that type). The typedef @c CanQualType is just 42/// a shorthand for @c CanQual<Type>. 43/// 44/// An instance of @c CanQual<T> can be implicitly converted to a 45/// @c CanQual<U> when T is derived from U, which essentially provides an 46/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be 47/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can 48/// be implicitly converted to a QualType, but the reverse operation requires 49/// a call to ASTContext::getCanonicalType(). 50/// 51/// 52template<typename T = Type> 53class CanQual { 54 /// \brief The actual, canonical type. 55 QualType Stored; 56 57public: 58 /// \brief Constructs a NULL canonical type. 59 CanQual() : Stored() { } 60 61 /// \brief Converting constructor that permits implicit upcasting of 62 /// canonical type pointers. 63 template<typename U> 64 CanQual(const CanQual<U>& Other, 65 typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0); 66 67 /// \brief Implicit conversion to the underlying pointer. 68 /// 69 /// Also provides the ability to use canonical types in a boolean context, 70 /// e.g., 71 /// @code 72 /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... } 73 /// @endcode 74 operator const T*() const { return getTypePtr(); } 75 76 /// \brief Retrieve the underlying type pointer, which refers to a 77 /// canonical type. 78 T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); } 79 80 /// \brief Implicit conversion to a qualified type. 81 operator QualType() const { return Stored; } 82 83 /// \brief Retrieve a canonical type pointer with a different static type, 84 /// upcasting or downcasting as needed. 85 /// 86 /// The getAs() function is typically used to try to downcast to a 87 /// more specific (canonical) type in the type system. For example: 88 /// 89 /// @code 90 /// void f(CanQual<Type> T) { 91 /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { 92 /// // look at Ptr's pointee type 93 /// } 94 /// } 95 /// @endcode 96 /// 97 /// \returns A proxy pointer to the same type, but with the specified 98 /// static type (@p U). If the dynamic type is not the specified static type 99 /// or a derived class thereof, a NULL canonical type. 100 template<typename U> CanProxy<U> getAs() const; 101 102 /// \brief Overloaded arrow operator that produces a canonical type 103 /// proxy. 104 CanProxy<T> operator->() const; 105 106 /// \brief Retrieve the const/volatile/restrict qualifiers. 107 unsigned getCVRQualifiers() const { return Stored.getCVRQualifiers(); } 108 109 /// \brief Set the const/volatile/restrict qualifiers 110 void setCVRQualifiers(unsigned Quals) { Stored.setCVRQualifiers(Quals); } 111 112 bool isConstQualified() const { 113 return (getCVRQualifiers() & QualType::Const) ? true : false; 114 } 115 bool isVolatileQualified() const { 116 return (getCVRQualifiers() & QualType::Volatile) ? true : false; 117 } 118 bool isRestrictQualified() const { 119 return (getCVRQualifiers() & QualType::Restrict) ? true : false; 120 } 121 122 /// \brief Retrieve the unqualified form of this type. 123 CanQual<T> getUnqualifiedType() const; 124 125 CanQual<T> getQualifiedType(unsigned TQs) const { 126 return CanQual<T>::CreateUnsafe(QualType(getTypePtr(), TQs)); 127 } 128 129 /// \brief Determines whether this canonical type is more qualified than 130 /// the @p Other canonical type. 131 bool isMoreQualifiedThan(CanQual<T> Other) const { 132 return Stored.isMoreQualifiedThan(Other.Stored); 133 } 134 135 /// \brief Determines whether this canonical type is at least as qualified as 136 /// the @p Other canonical type. 137 bool isAtLeastAsQualifiedAs(CanQual<T> Other) const { 138 return Stored.isAtLeastAsQualifiedAs(Other.Stored); 139 } 140 141 /// \brief If the canonical type is a reference type, returns the type that 142 /// it refers to; otherwise, 143 CanQual<Type> getNonReferenceType() const; 144 145 /// \brief Retrieve the internal representation of this canonical type. 146 void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); } 147 148 /// \brief Construct a canonical type from its internal representation. 149 static CanQual<T> getFromOpaquePtr(void *Ptr); 150 151 /// \brief Builds a canonical type from a QualType. 152 /// 153 /// This routine is inherently unsafe, because it requires the user to 154 /// ensure that the given type is a canonical type with the correct 155 // (dynamic) type. 156 static CanQual<T> CreateUnsafe(QualType Other); 157}; 158 159template<typename T, typename U> 160inline bool operator==(CanQual<T> x, CanQual<U> y) { 161 return x.getAsOpaquePtr() == y.getAsOpaquePtr(); 162} 163 164template<typename T, typename U> 165inline bool operator!=(CanQual<T> x, CanQual<U> y) { 166 return x.getAsOpaquePtr() != y.getAsOpaquePtr(); 167} 168 169/// \brief Represents a canonical, potentially-qualified type. 170typedef CanQual<Type> CanQualType; 171 172//----------------------------------------------------------------------------// 173// Internal proxy classes used by canonical types 174//----------------------------------------------------------------------------// 175 176#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \ 177CanQualType Accessor() const { \ 178return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \ 179} 180 181#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \ 182Type Accessor() const { return this->getTypePtr()->Accessor(); } 183 184/// \brief Base class of all canonical proxy types, which is responsible for 185/// storing the underlying canonical type and providing basic conversions. 186template<typename T> 187class CanProxyBase { 188protected: 189 CanQual<T> Stored; 190 191public: 192 /// \brief Retrieve the pointer to the underlying Type 193 T* getTypePtr() const { return Stored.getTypePtr(); } 194 195 /// \brief Implicit conversion to the underlying pointer. 196 /// 197 /// Also provides the ability to use canonical type proxies in a Boolean 198 // context,e.g., 199 /// @code 200 /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... } 201 /// @endcode 202 operator const T*() const { return this->Stored.getTypePtr(); } 203 204 /// \brief Try to convert the given canonical type to a specific structural 205 /// type. 206 template<typename U> CanProxy<U> getAs() const { 207 return this->Stored.template getAs<U>(); 208 } 209 210 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass) 211 212 // Type predicates 213 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) 214 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) 215 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) 216 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType) 217 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) 218 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) 219 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType) 220 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType) 221 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType) 222 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType) 223 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType) 224 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType) 225 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType) 226 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType) 227 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType) 228 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType) 229 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType) 230 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType) 231 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType) 232 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType) 233 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType) 234 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType) 235 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType) 236 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType) 237 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType) 238 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType) 239 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType) 240 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) 241 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) 242 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType) 243 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType) 244 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType) 245 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation) 246 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation) 247 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType) 248 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType) 249 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType) 250 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType) 251 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType) 252 253 /// \brief Retrieve the proxy-adaptor type. 254 /// 255 /// This arrow operator is used when CanProxyAdaptor has been specialized 256 /// for the given type T. In that case, we reference members of the 257 /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden 258 /// by the arrow operator in the primary CanProxyAdaptor template. 259 const CanProxyAdaptor<T> *operator->() const { 260 return static_cast<const CanProxyAdaptor<T> *>(this); 261 } 262}; 263 264/// \brief Replacable canonical proxy adaptor class that provides the link 265/// between a canonical type and the accessors of the type. 266/// 267/// The CanProxyAdaptor is a replaceable class template that is instantiated 268/// as part of each canonical proxy type. The primary template merely provides 269/// redirection to the underlying type (T), e.g., @c PointerType. One can 270/// provide specializations of this class template for each underlying type 271/// that provide accessors returning canonical types (@c CanQualType) rather 272/// than the more typical @c QualType, to propagate the notion of "canonical" 273/// through the system. 274template<typename T> 275struct CanProxyAdaptor : CanProxyBase<T> { }; 276 277/// \brief Canonical proxy type returned when retrieving the members of a 278/// canonical type or as the result of the @c CanQual<T>::getAs member 279/// function. 280/// 281/// The CanProxy type mainly exists as a proxy through which operator-> will 282/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy 283/// type that provides canonical-type access to the fields of the type. 284template<typename T> 285class CanProxy : public CanProxyAdaptor<T> { 286public: 287 /// \brief Build a NULL proxy. 288 CanProxy() { } 289 290 /// \brief Build a proxy to the given canonical type. 291 CanProxy(CanQual<T> Stored) { this->Stored = Stored; } 292 293 /// \brief Implicit conversion to the stored canonical type. 294 operator CanQual<T>() const { return this->Stored; } 295}; 296 297} // end namespace clang 298 299namespace llvm { 300 301/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from 302/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. 303/// to return smart pointer (proxies?). 304template<typename T> 305struct simplify_type<const ::clang::CanQual<T> > { 306 typedef T* SimpleType; 307 static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) { 308 return Val.getTypePtr(); 309 } 310}; 311template<typename T> 312struct simplify_type< ::clang::CanQual<T> > 313: public simplify_type<const ::clang::CanQual<T> > {}; 314 315// Teach SmallPtrSet that CanQual<T> is "basically a pointer". 316template<typename T> 317class PointerLikeTypeTraits<clang::CanQual<T> > { 318public: 319 static inline void *getAsVoidPointer(clang::CanQual<T> P) { 320 return P.getAsOpaquePtr(); 321 } 322 static inline clang::CanQual<T> getFromVoidPointer(void *P) { 323 return clang::CanQual<T>::getFromOpaquePtr(P); 324 } 325 // CVR qualifiers go in low bits. 326 enum { NumLowBitsAvailable = 0 }; 327}; 328 329} // end namespace llvm 330 331namespace clang { 332 333//----------------------------------------------------------------------------// 334// Canonical proxy adaptors for canonical type nodes. 335//----------------------------------------------------------------------------// 336 337/// \brief Iterator adaptor that turns an iterator over canonical QualTypes 338/// into an iterator over CanQualTypes. 339template<typename InputIterator> 340class CanTypeIterator { 341 InputIterator Iter; 342 343public: 344 typedef CanQualType value_type; 345 typedef value_type reference; 346 typedef CanProxy<Type> pointer; 347 typedef typename std::iterator_traits<InputIterator>::difference_type 348 difference_type; 349 typedef typename std::iterator_traits<InputIterator>::iterator_category 350 iterator_category; 351 352 CanTypeIterator() : Iter() { } 353 explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { } 354 355 // Input iterator 356 reference operator*() const { 357 return CanQualType::CreateUnsafe(*Iter); 358 } 359 360 pointer operator->() const; 361 362 CanTypeIterator &operator++() { 363 ++Iter; 364 return *this; 365 } 366 367 CanTypeIterator operator++(int) { 368 CanTypeIterator Tmp(*this); 369 ++Iter; 370 return Tmp; 371 } 372 373 friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) { 374 return X.Iter == Y.Iter; 375 } 376 friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) { 377 return X.Iter != Y.Iter; 378 } 379 380 // Bidirectional iterator 381 CanTypeIterator &operator--() { 382 --Iter; 383 return *this; 384 } 385 386 CanTypeIterator operator--(int) { 387 CanTypeIterator Tmp(*this); 388 --Iter; 389 return Tmp; 390 } 391 392 // Random access iterator 393 reference operator[](difference_type n) const { 394 return CanQualType::CreateUnsafe(Iter[n]); 395 } 396 397 CanTypeIterator &operator+=(difference_type n) { 398 Iter += n; 399 return *this; 400 } 401 402 CanTypeIterator &operator-=(difference_type n) { 403 Iter -= n; 404 return *this; 405 } 406 407 friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) { 408 X += n; 409 return X; 410 } 411 412 friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) { 413 X += n; 414 return X; 415 } 416 417 friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) { 418 X -= n; 419 return X; 420 } 421 422 friend difference_type operator-(const CanTypeIterator &X, 423 const CanTypeIterator &Y) { 424 return X - Y; 425 } 426}; 427 428template<> 429struct CanProxyAdaptor<ExtQualType> : public CanProxyBase<ExtQualType> { 430 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type*, getBaseType) 431 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(QualType::GCAttrTypes, getObjCGCAttr) 432 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace) 433}; 434 435template<> 436struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> { 437 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 438}; 439 440template<> 441struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> { 442 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 443}; 444 445template<> 446struct CanProxyAdaptor<BlockPointerType> 447 : public CanProxyBase<BlockPointerType> 448{ 449 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 450}; 451 452template<> 453struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> { 454 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 455}; 456 457template<> 458struct CanProxyAdaptor<LValueReferenceType> 459 : public CanProxyBase<LValueReferenceType> 460{ 461 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 462}; 463 464template<> 465struct CanProxyAdaptor<RValueReferenceType> 466 : public CanProxyBase<RValueReferenceType> 467{ 468 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 469}; 470 471template<> 472struct CanProxyAdaptor<MemberPointerType> 473 : public CanProxyBase<MemberPointerType> 474{ 475 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 476 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass) 477}; 478 479template<> 480struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> { 481 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 482 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 483 getSizeModifier) 484 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier) 485}; 486 487template<> 488struct CanProxyAdaptor<ConstantArrayType> 489 : public CanProxyBase<ConstantArrayType> 490{ 491 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 492 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 493 getSizeModifier) 494 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier) 495 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize) 496}; 497 498template<> 499struct CanProxyAdaptor<ConstantArrayWithExprType> 500 : public CanProxyBase<ConstantArrayWithExprType> 501{ 502 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 503 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 504 getSizeModifier) 505 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier) 506 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize) 507 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) 508 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) 509 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) 510 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) 511}; 512 513template<> 514struct CanProxyAdaptor<ConstantArrayWithoutExprType> 515 : public CanProxyBase<ConstantArrayWithoutExprType> 516{ 517 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 518 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 519 getSizeModifier) 520 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier) 521 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize) 522}; 523 524template<> 525struct CanProxyAdaptor<IncompleteArrayType> 526 : public CanProxyBase<IncompleteArrayType> 527{ 528 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 529 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 530 getSizeModifier) 531 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier) 532}; 533 534template<> 535struct CanProxyAdaptor<VariableArrayType> 536 : public CanProxyBase<VariableArrayType> 537{ 538 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 539 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 540 getSizeModifier) 541 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndexTypeQualifier) 542 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) 543 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) 544 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) 545 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) 546}; 547 548template<> 549struct CanProxyAdaptor<DependentSizedArrayType> 550 : public CanProxyBase<DependentSizedArrayType> 551{ 552 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 553 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) 554 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) 555 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) 556 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) 557}; 558 559template<> 560struct CanProxyAdaptor<DependentSizedExtVectorType> 561 : public CanProxyBase<DependentSizedExtVectorType> 562{ 563 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 564 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr) 565 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc) 566}; 567 568template<> 569struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> { 570 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 571 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) 572}; 573 574template<> 575struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> { 576 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 577 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) 578}; 579 580template<> 581struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> { 582 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) 583}; 584 585template<> 586struct CanProxyAdaptor<FunctionNoProtoType> 587 : public CanProxyBase<FunctionNoProtoType> 588{ 589 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) 590}; 591 592template<> 593struct CanProxyAdaptor<FunctionProtoType> 594 : public CanProxyBase<FunctionProtoType> 595{ 596 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) 597 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs); 598 CanQualType getArgType(unsigned i) const { 599 return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i)); 600 } 601 602 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) 603 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals) 604 605 typedef CanTypeIterator<FunctionProtoType::arg_type_iterator> 606 arg_type_iterator; 607 608 arg_type_iterator arg_type_begin() const { 609 return arg_type_iterator(this->getTypePtr()->arg_type_begin()); 610 } 611 612 arg_type_iterator arg_type_end() const { 613 return arg_type_iterator(this->getTypePtr()->arg_type_end()); 614 } 615 616 // Note: canonical function types never have exception specifications 617}; 618 619template<> 620struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> { 621 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 622}; 623 624template<> 625struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> { 626 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr) 627 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 628}; 629 630template<> 631struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> { 632 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl) 633 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 634}; 635 636template<> 637struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> { 638 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl) 639 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 640 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields) 641 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace) 642}; 643 644template<> 645struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> { 646 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl) 647 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 648}; 649 650template<> 651struct CanProxyAdaptor<TemplateTypeParmType> 652 : public CanProxyBase<TemplateTypeParmType> 653{ 654 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth) 655 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex) 656 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack) 657 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName) 658}; 659 660template<> 661struct CanProxyAdaptor<ObjCObjectPointerType> 662 : public CanProxyBase<ObjCObjectPointerType> 663{ 664 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 665 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *, 666 getInterfaceType) 667 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType) 668 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType) 669 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType) 670 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) 671 672 typedef ObjCObjectPointerType::qual_iterator qual_iterator; 673 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) 674 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) 675 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) 676 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) 677}; 678 679//----------------------------------------------------------------------------// 680// Method and function definitions 681//----------------------------------------------------------------------------// 682template<typename T> 683inline CanQual<T> CanQual<T>::getUnqualifiedType() const { 684 if (CanQual<ExtQualType> EQ = getAs<ExtQualType>()) 685 return CanQual<T>::CreateUnsafe(QualType(EQ->getBaseType(), 0)); 686 return CanQual<T>::CreateUnsafe(QualType(Stored.getTypePtr(), 0)); 687} 688 689template<typename T> 690inline CanQual<Type> CanQual<T>::getNonReferenceType() const { 691 if (CanQual<ReferenceType> RefType = getAs<ReferenceType>()) 692 return RefType->getPointeeType(); 693 else 694 return *this; 695} 696 697template<typename T> 698CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) { 699 CanQual<T> Result; 700 Result.Stored.setFromOpaqueValue(Ptr); 701 assert((!Result || Result.Stored.isCanonical()) 702 && "Type is not canonical!"); 703 return Result; 704} 705 706template<typename T> 707CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) { 708 assert((Other.isNull() || Other->isCanonical()) && "Type is not canonical!"); 709 assert((Other.isNull() || isa<T>(Other.getTypePtr())) && 710 "Dynamic type does not meet the static type's requires"); 711 CanQual<T> Result; 712 Result.Stored = Other; 713 return Result; 714} 715 716template<typename T> 717template<typename U> 718CanProxy<U> CanQual<T>::getAs() const { 719 if (Stored.isNull()) 720 return CanProxy<U>(); 721 722 if (isa<U>(Stored.getTypePtr())) 723 return CanQual<U>::CreateUnsafe(Stored); 724 725 if (const ExtQualType *EQ = Stored->getAs<ExtQualType>()) 726 return CanQual<T>::CreateUnsafe(QualType(EQ->getBaseType(), 0)) 727 .template getAs<U>(); 728 729 return CanProxy<U>(); 730} 731 732template<typename T> 733CanProxy<T> CanQual<T>::operator->() const { 734 return CanProxy<T>(*this); 735} 736 737template<typename InputIterator> 738typename CanTypeIterator<InputIterator>::pointer 739CanTypeIterator<InputIterator>::operator->() const { 740 return CanProxy<Type>(*this); 741} 742 743} 744 745 746#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H 747