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