CanonicalType.h revision 7af19b817ba964ac560b50c1ed6183235f699789
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 "clang/Basic/Diagnostic.h" 20#include "llvm/Support/Casting.h" 21#include "llvm/Support/type_traits.h" 22#include <iterator> 23 24namespace clang { 25 26template<typename T> class CanProxy; 27template<typename T> struct CanProxyAdaptor; 28 29//----------------------------------------------------------------------------// 30// Canonical, qualified type template 31//----------------------------------------------------------------------------// 32 33/// \brief Represents a canonical, potentially-qualified type. 34/// 35/// The CanQual template is a lightweight smart pointer that provides access 36/// to the canonical representation of a type, where all typedefs and other 37/// syntactic sugar has been eliminated. A CanQualType may also have various 38/// qualifiers (const, volatile, restrict) attached to it. 39/// 40/// The template type parameter @p T is one of the Type classes (PointerType, 41/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that 42/// type (or some subclass of that type). The typedef @c CanQualType is just 43/// a shorthand for @c CanQual<Type>. 44/// 45/// An instance of @c CanQual<T> can be implicitly converted to a 46/// @c CanQual<U> when T is derived from U, which essentially provides an 47/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be 48/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can 49/// be implicitly converted to a QualType, but the reverse operation requires 50/// a call to ASTContext::getCanonicalType(). 51/// 52/// 53template<typename T = Type> 54class CanQual { 55 /// \brief The actual, canonical type. 56 QualType Stored; 57 58public: 59 /// \brief Constructs a NULL canonical type. 60 CanQual() : Stored() { } 61 62 /// \brief Converting constructor that permits implicit upcasting of 63 /// canonical type pointers. 64 template<typename U> 65 CanQual(const CanQual<U>& Other, 66 typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0); 67 68 /// \brief Retrieve the underlying type pointer, which refers to a 69 /// canonical type. 70 /// 71 /// The underlying pointer must not be NULL. 72 const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); } 73 74 /// \brief Retrieve the underlying type pointer, which refers to a 75 /// canonical type, or NULL. 76 /// 77 const T *getTypePtrOrNull() const { 78 return cast_or_null<T>(Stored.getTypePtrOrNull()); 79 } 80 81 /// \brief Implicit conversion to a qualified type. 82 operator QualType() const { return Stored; } 83 84 /// \brief Implicit conversion to bool. 85 operator bool() const { return !isNull(); } 86 87 bool isNull() const { 88 return Stored.isNull(); 89 } 90 91 SplitQualType split() const { return Stored.split(); } 92 93 /// \brief Retrieve a canonical type pointer with a different static type, 94 /// upcasting or downcasting as needed. 95 /// 96 /// The getAs() function is typically used to try to downcast to a 97 /// more specific (canonical) type in the type system. For example: 98 /// 99 /// @code 100 /// void f(CanQual<Type> T) { 101 /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { 102 /// // look at Ptr's pointee type 103 /// } 104 /// } 105 /// @endcode 106 /// 107 /// \returns A proxy pointer to the same type, but with the specified 108 /// static type (@p U). If the dynamic type is not the specified static type 109 /// or a derived class thereof, a NULL canonical type. 110 template<typename U> CanProxy<U> getAs() 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 187template<typename T, typename U> 188inline bool operator==(CanQual<T> x, CanQual<U> y) { 189 return x.getAsOpaquePtr() == y.getAsOpaquePtr(); 190} 191 192template<typename T, typename U> 193inline bool operator!=(CanQual<T> x, CanQual<U> y) { 194 return x.getAsOpaquePtr() != y.getAsOpaquePtr(); 195} 196 197/// \brief Represents a canonical, potentially-qualified type. 198typedef CanQual<Type> CanQualType; 199 200inline CanQualType Type::getCanonicalTypeUnqualified() const { 201 return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); 202} 203 204inline 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) \ 215CanQualType Accessor() const { \ 216return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \ 217} 218 219#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \ 220Type 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. 224template<typename T> 225class CanProxyBase { 226protected: 227 CanQual<T> Stored; 228 229public: 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, isStructureOrClassType) 279 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) 280 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) 281 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType) 282 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType) 283 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType) 284 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType) 285 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation) 286 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation) 287 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation) 288 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation) 289 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation) 290 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation) 291 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType) 292 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType) 293 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType) 294 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType) 295 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType) 296 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType) 297 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType) 298 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl) 299 300 /// \brief Retrieve the proxy-adaptor type. 301 /// 302 /// This arrow operator is used when CanProxyAdaptor has been specialized 303 /// for the given type T. In that case, we reference members of the 304 /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden 305 /// by the arrow operator in the primary CanProxyAdaptor template. 306 const CanProxyAdaptor<T> *operator->() const { 307 return static_cast<const CanProxyAdaptor<T> *>(this); 308 } 309}; 310 311/// \brief Replacable canonical proxy adaptor class that provides the link 312/// between a canonical type and the accessors of the type. 313/// 314/// The CanProxyAdaptor is a replaceable class template that is instantiated 315/// as part of each canonical proxy type. The primary template merely provides 316/// redirection to the underlying type (T), e.g., @c PointerType. One can 317/// provide specializations of this class template for each underlying type 318/// that provide accessors returning canonical types (@c CanQualType) rather 319/// than the more typical @c QualType, to propagate the notion of "canonical" 320/// through the system. 321template<typename T> 322struct CanProxyAdaptor : CanProxyBase<T> { }; 323 324/// \brief Canonical proxy type returned when retrieving the members of a 325/// canonical type or as the result of the @c CanQual<T>::getAs member 326/// function. 327/// 328/// The CanProxy type mainly exists as a proxy through which operator-> will 329/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy 330/// type that provides canonical-type access to the fields of the type. 331template<typename T> 332class CanProxy : public CanProxyAdaptor<T> { 333public: 334 /// \brief Build a NULL proxy. 335 CanProxy() { } 336 337 /// \brief Build a proxy to the given canonical type. 338 CanProxy(CanQual<T> Stored) { this->Stored = Stored; } 339 340 /// \brief Implicit conversion to the stored canonical type. 341 operator CanQual<T>() const { return this->Stored; } 342}; 343 344} // end namespace clang 345 346namespace llvm { 347 348/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from 349/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. 350/// to return smart pointer (proxies?). 351template<typename T> 352struct simplify_type<const ::clang::CanQual<T> > { 353 typedef const T *SimpleType; 354 static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) { 355 return Val.getTypePtr(); 356 } 357}; 358template<typename T> 359struct simplify_type< ::clang::CanQual<T> > 360: public simplify_type<const ::clang::CanQual<T> > {}; 361 362// Teach SmallPtrSet that CanQual<T> is "basically a pointer". 363template<typename T> 364class PointerLikeTypeTraits<clang::CanQual<T> > { 365public: 366 static inline void *getAsVoidPointer(clang::CanQual<T> P) { 367 return P.getAsOpaquePtr(); 368 } 369 static inline clang::CanQual<T> getFromVoidPointer(void *P) { 370 return clang::CanQual<T>::getFromOpaquePtr(P); 371 } 372 // qualifier information is encoded in the low bits. 373 enum { NumLowBitsAvailable = 0 }; 374}; 375 376} // end namespace llvm 377 378namespace clang { 379 380//----------------------------------------------------------------------------// 381// Canonical proxy adaptors for canonical type nodes. 382//----------------------------------------------------------------------------// 383 384/// \brief Iterator adaptor that turns an iterator over canonical QualTypes 385/// into an iterator over CanQualTypes. 386template<typename InputIterator> 387class CanTypeIterator { 388 InputIterator Iter; 389 390public: 391 typedef CanQualType value_type; 392 typedef value_type reference; 393 typedef CanProxy<Type> pointer; 394 typedef typename std::iterator_traits<InputIterator>::difference_type 395 difference_type; 396 typedef typename std::iterator_traits<InputIterator>::iterator_category 397 iterator_category; 398 399 CanTypeIterator() : Iter() { } 400 explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { } 401 402 // Input iterator 403 reference operator*() const { 404 return CanQualType::CreateUnsafe(*Iter); 405 } 406 407 pointer operator->() const; 408 409 CanTypeIterator &operator++() { 410 ++Iter; 411 return *this; 412 } 413 414 CanTypeIterator operator++(int) { 415 CanTypeIterator Tmp(*this); 416 ++Iter; 417 return Tmp; 418 } 419 420 friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) { 421 return X.Iter == Y.Iter; 422 } 423 friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) { 424 return X.Iter != Y.Iter; 425 } 426 427 // Bidirectional iterator 428 CanTypeIterator &operator--() { 429 --Iter; 430 return *this; 431 } 432 433 CanTypeIterator operator--(int) { 434 CanTypeIterator Tmp(*this); 435 --Iter; 436 return Tmp; 437 } 438 439 // Random access iterator 440 reference operator[](difference_type n) const { 441 return CanQualType::CreateUnsafe(Iter[n]); 442 } 443 444 CanTypeIterator &operator+=(difference_type n) { 445 Iter += n; 446 return *this; 447 } 448 449 CanTypeIterator &operator-=(difference_type n) { 450 Iter -= n; 451 return *this; 452 } 453 454 friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) { 455 X += n; 456 return X; 457 } 458 459 friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) { 460 X += n; 461 return X; 462 } 463 464 friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) { 465 X -= n; 466 return X; 467 } 468 469 friend difference_type operator-(const CanTypeIterator &X, 470 const CanTypeIterator &Y) { 471 return X - Y; 472 } 473}; 474 475template<> 476struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> { 477 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 478}; 479 480template<> 481struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> { 482 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 483}; 484 485template<> 486struct CanProxyAdaptor<BlockPointerType> 487 : public CanProxyBase<BlockPointerType> { 488 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 489}; 490 491template<> 492struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> { 493 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 494}; 495 496template<> 497struct CanProxyAdaptor<LValueReferenceType> 498 : public CanProxyBase<LValueReferenceType> { 499 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 500}; 501 502template<> 503struct CanProxyAdaptor<RValueReferenceType> 504 : public CanProxyBase<RValueReferenceType> { 505 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 506}; 507 508template<> 509struct CanProxyAdaptor<MemberPointerType> 510 : public CanProxyBase<MemberPointerType> { 511 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 512 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass) 513}; 514 515template<> 516struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> { 517 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 518 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 519 getSizeModifier) 520 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) 521}; 522 523template<> 524struct CanProxyAdaptor<ConstantArrayType> 525 : public CanProxyBase<ConstantArrayType> { 526 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 527 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 528 getSizeModifier) 529 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) 530 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize) 531}; 532 533template<> 534struct CanProxyAdaptor<IncompleteArrayType> 535 : public CanProxyBase<IncompleteArrayType> { 536 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 537 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 538 getSizeModifier) 539 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) 540}; 541 542template<> 543struct CanProxyAdaptor<VariableArrayType> 544 : public CanProxyBase<VariableArrayType> { 545 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 546 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, 547 getSizeModifier) 548 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) 549 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) 550 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) 551 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) 552 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) 553}; 554 555template<> 556struct CanProxyAdaptor<DependentSizedArrayType> 557 : public CanProxyBase<DependentSizedArrayType> { 558 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 559 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) 560 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) 561 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) 562 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) 563}; 564 565template<> 566struct CanProxyAdaptor<DependentSizedExtVectorType> 567 : public CanProxyBase<DependentSizedExtVectorType> { 568 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 569 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr) 570 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc) 571}; 572 573template<> 574struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> { 575 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 576 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) 577}; 578 579template<> 580struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> { 581 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 582 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) 583}; 584 585template<> 586struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> { 587 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) 588 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) 589}; 590 591template<> 592struct CanProxyAdaptor<FunctionNoProtoType> 593 : public CanProxyBase<FunctionNoProtoType> { 594 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) 595 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) 596}; 597 598template<> 599struct CanProxyAdaptor<FunctionProtoType> 600 : public CanProxyBase<FunctionProtoType> { 601 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) 602 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) 603 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs) 604 CanQualType getArgType(unsigned i) const { 605 return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i)); 606 } 607 608 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) 609 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals) 610 611 typedef CanTypeIterator<FunctionProtoType::arg_type_iterator> 612 arg_type_iterator; 613 614 arg_type_iterator arg_type_begin() const { 615 return arg_type_iterator(this->getTypePtr()->arg_type_begin()); 616 } 617 618 arg_type_iterator arg_type_end() const { 619 return arg_type_iterator(this->getTypePtr()->arg_type_end()); 620 } 621 622 // Note: canonical function types never have exception specifications 623}; 624 625template<> 626struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> { 627 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 628}; 629 630template<> 631struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> { 632 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr) 633 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 634}; 635 636template <> 637struct CanProxyAdaptor<UnaryTransformType> 638 : public CanProxyBase<UnaryTransformType> { 639 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) 640 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 641 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind) 642}; 643 644template<> 645struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> { 646 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl) 647 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 648}; 649 650template<> 651struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> { 652 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl) 653 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 654 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields) 655}; 656 657template<> 658struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> { 659 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl) 660 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 661}; 662 663template<> 664struct CanProxyAdaptor<TemplateTypeParmType> 665 : public CanProxyBase<TemplateTypeParmType> { 666 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth) 667 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex) 668 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack) 669 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl) 670 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier) 671}; 672 673template<> 674struct CanProxyAdaptor<ObjCObjectType> 675 : public CanProxyBase<ObjCObjectType> { 676 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) 677 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *, 678 getInterface) 679 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId) 680 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass) 681 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) 682 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) 683 684 typedef ObjCObjectPointerType::qual_iterator qual_iterator; 685 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) 686 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) 687 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) 688 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) 689}; 690 691template<> 692struct CanProxyAdaptor<ObjCObjectPointerType> 693 : public CanProxyBase<ObjCObjectPointerType> { 694 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 695 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *, 696 getInterfaceType) 697 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType) 698 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType) 699 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType) 700 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) 701 702 typedef ObjCObjectPointerType::qual_iterator qual_iterator; 703 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) 704 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) 705 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) 706 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) 707}; 708 709//----------------------------------------------------------------------------// 710// Method and function definitions 711//----------------------------------------------------------------------------// 712template<typename T> 713inline CanQual<T> CanQual<T>::getUnqualifiedType() const { 714 return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType()); 715} 716 717template<typename T> 718inline CanQual<Type> CanQual<T>::getNonReferenceType() const { 719 if (CanQual<ReferenceType> RefType = getAs<ReferenceType>()) 720 return RefType->getPointeeType(); 721 else 722 return *this; 723} 724 725template<typename T> 726CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) { 727 CanQual<T> Result; 728 Result.Stored = QualType::getFromOpaquePtr(Ptr); 729 assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 || 730 Result.Stored.isCanonical()) && "Type is not canonical!"); 731 return Result; 732} 733 734template<typename T> 735CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) { 736 assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!"); 737 assert((Other.isNull() || isa<T>(Other.getTypePtr())) && 738 "Dynamic type does not meet the static type's requires"); 739 CanQual<T> Result; 740 Result.Stored = Other; 741 return Result; 742} 743 744template<typename T> 745template<typename U> 746CanProxy<U> CanQual<T>::getAs() const { 747 if (Stored.isNull()) 748 return CanProxy<U>(); 749 750 if (isa<U>(Stored.getTypePtr())) 751 return CanQual<U>::CreateUnsafe(Stored); 752 753 return CanProxy<U>(); 754} 755 756template<typename T> 757CanProxy<T> CanQual<T>::operator->() const { 758 return CanProxy<T>(*this); 759} 760 761template<typename InputIterator> 762typename CanTypeIterator<InputIterator>::pointer 763CanTypeIterator<InputIterator>::operator->() const { 764 return CanProxy<Type>(*this); 765} 766 767} 768 769 770#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H 771