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