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