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