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