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