Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines the CanQual class template, which provides access to
  10. //  canonical types.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_AST_CANONICALTYPE_H
  15. #define LLVM_CLANG_AST_CANONICALTYPE_H
  16.  
  17. #include "clang/AST/Type.h"
  18. #include "clang/Basic/Diagnostic.h"
  19. #include "clang/Basic/SourceLocation.h"
  20. #include "llvm/ADT/ArrayRef.h"
  21. #include "llvm/ADT/FoldingSet.h"
  22. #include "llvm/ADT/iterator.h"
  23. #include "llvm/Support/Casting.h"
  24. #include "llvm/Support/PointerLikeTypeTraits.h"
  25. #include <cassert>
  26. #include <iterator>
  27. #include <type_traits>
  28.  
  29. namespace clang {
  30.  
  31. template<typename T> class CanProxy;
  32. template<typename T> struct CanProxyAdaptor;
  33. class CXXRecordDecl;
  34. class EnumDecl;
  35. class Expr;
  36. class IdentifierInfo;
  37. class ObjCInterfaceDecl;
  38. class RecordDecl;
  39. class TagDecl;
  40. class TemplateTypeParmDecl;
  41.  
  42. //----------------------------------------------------------------------------//
  43. // Canonical, qualified type template
  44. //----------------------------------------------------------------------------//
  45.  
  46. /// Represents a canonical, potentially-qualified type.
  47. ///
  48. /// The CanQual template is a lightweight smart pointer that provides access
  49. /// to the canonical representation of a type, where all typedefs and other
  50. /// syntactic sugar has been eliminated. A CanQualType may also have various
  51. /// qualifiers (const, volatile, restrict) attached to it.
  52. ///
  53. /// The template type parameter @p T is one of the Type classes (PointerType,
  54. /// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
  55. /// type (or some subclass of that type). The typedef @c CanQualType is just
  56. /// a shorthand for @c CanQual<Type>.
  57. ///
  58. /// An instance of @c CanQual<T> can be implicitly converted to a
  59. /// @c CanQual<U> when T is derived from U, which essentially provides an
  60. /// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
  61. /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
  62. /// be implicitly converted to a QualType, but the reverse operation requires
  63. /// a call to ASTContext::getCanonicalType().
  64. template<typename T = Type>
  65. class CanQual {
  66.   /// The actual, canonical type.
  67.   QualType Stored;
  68.  
  69. public:
  70.   /// Constructs a NULL canonical type.
  71.   CanQual() = default;
  72.  
  73.   /// Converting constructor that permits implicit upcasting of
  74.   /// canonical type pointers.
  75.   template <typename U>
  76.   CanQual(const CanQual<U> &Other,
  77.           std::enable_if_t<std::is_base_of<T, U>::value, int> = 0);
  78.  
  79.   /// Retrieve the underlying type pointer, which refers to a
  80.   /// canonical type.
  81.   ///
  82.   /// The underlying pointer must not be nullptr.
  83.   const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
  84.  
  85.   /// Retrieve the underlying type pointer, which refers to a
  86.   /// canonical type, or nullptr.
  87.   const T *getTypePtrOrNull() const {
  88.     return cast_or_null<T>(Stored.getTypePtrOrNull());
  89.   }
  90.  
  91.   /// Implicit conversion to a qualified type.
  92.   operator QualType() const { return Stored; }
  93.  
  94.   /// Implicit conversion to bool.
  95.   explicit operator bool() const { return !isNull(); }
  96.  
  97.   bool isNull() const {
  98.     return Stored.isNull();
  99.   }
  100.  
  101.   SplitQualType split() const { return Stored.split(); }
  102.  
  103.   /// Retrieve a canonical type pointer with a different static type,
  104.   /// upcasting or downcasting as needed.
  105.   ///
  106.   /// The getAs() function is typically used to try to downcast to a
  107.   /// more specific (canonical) type in the type system. For example:
  108.   ///
  109.   /// @code
  110.   /// void f(CanQual<Type> T) {
  111.   ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
  112.   ///     // look at Ptr's pointee type
  113.   ///   }
  114.   /// }
  115.   /// @endcode
  116.   ///
  117.   /// \returns A proxy pointer to the same type, but with the specified
  118.   /// static type (@p U). If the dynamic type is not the specified static type
  119.   /// or a derived class thereof, a NULL canonical type.
  120.   template<typename U> CanProxy<U> getAs() const;
  121.  
  122.   template<typename U> CanProxy<U> castAs() const;
  123.  
  124.   /// Overloaded arrow operator that produces a canonical type
  125.   /// proxy.
  126.   CanProxy<T> operator->() const;
  127.  
  128.   /// Retrieve all qualifiers.
  129.   Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
  130.  
  131.   /// Retrieve the const/volatile/restrict qualifiers.
  132.   unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
  133.  
  134.   /// Determines whether this type has any qualifiers
  135.   bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
  136.  
  137.   bool isConstQualified() const {
  138.     return Stored.isLocalConstQualified();
  139.   }
  140.  
  141.   bool isVolatileQualified() const {
  142.     return Stored.isLocalVolatileQualified();
  143.   }
  144.  
  145.   bool isRestrictQualified() const {
  146.     return Stored.isLocalRestrictQualified();
  147.   }
  148.  
  149.   /// Determines if this canonical type is furthermore
  150.   /// canonical as a parameter.  The parameter-canonicalization
  151.   /// process decays arrays to pointers and drops top-level qualifiers.
  152.   bool isCanonicalAsParam() const {
  153.     return Stored.isCanonicalAsParam();
  154.   }
  155.  
  156.   /// Retrieve the unqualified form of this type.
  157.   CanQual<T> getUnqualifiedType() const;
  158.  
  159.   /// Retrieves a version of this type with const applied.
  160.   /// Note that this does not always yield a canonical type.
  161.   QualType withConst() const {
  162.     return Stored.withConst();
  163.   }
  164.  
  165.   /// Determines whether this canonical type is more qualified than
  166.   /// the @p Other canonical type.
  167.   bool isMoreQualifiedThan(CanQual<T> Other) const {
  168.     return Stored.isMoreQualifiedThan(Other.Stored);
  169.   }
  170.  
  171.   /// Determines whether this canonical type is at least as qualified as
  172.   /// the @p Other canonical type.
  173.   bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
  174.     return Stored.isAtLeastAsQualifiedAs(Other.Stored);
  175.   }
  176.  
  177.   /// If the canonical type is a reference type, returns the type that
  178.   /// it refers to; otherwise, returns the type itself.
  179.   CanQual<Type> getNonReferenceType() const;
  180.  
  181.   /// Retrieve the internal representation of this canonical type.
  182.   void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
  183.  
  184.   /// Construct a canonical type from its internal representation.
  185.   static CanQual<T> getFromOpaquePtr(void *Ptr);
  186.  
  187.   /// Builds a canonical type from a QualType.
  188.   ///
  189.   /// This routine is inherently unsafe, because it requires the user to
  190.   /// ensure that the given type is a canonical type with the correct
  191.   // (dynamic) type.
  192.   static CanQual<T> CreateUnsafe(QualType Other);
  193.  
  194.   void dump() const { Stored.dump(); }
  195.  
  196.   void Profile(llvm::FoldingSetNodeID &ID) const {
  197.     ID.AddPointer(getAsOpaquePtr());
  198.   }
  199. };
  200.  
  201. template<typename T, typename U>
  202. inline bool operator==(CanQual<T> x, CanQual<U> y) {
  203.   return x.getAsOpaquePtr() == y.getAsOpaquePtr();
  204. }
  205.  
  206. template<typename T, typename U>
  207. inline bool operator!=(CanQual<T> x, CanQual<U> y) {
  208.   return x.getAsOpaquePtr() != y.getAsOpaquePtr();
  209. }
  210.  
  211. /// Represents a canonical, potentially-qualified type.
  212. using CanQualType = CanQual<Type>;
  213.  
  214. inline CanQualType Type::getCanonicalTypeUnqualified() const {
  215.   return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
  216. }
  217.  
  218. inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
  219.                                              CanQualType T) {
  220.   DB << static_cast<QualType>(T);
  221.   return DB;
  222. }
  223.  
  224. //----------------------------------------------------------------------------//
  225. // Internal proxy classes used by canonical types
  226. //----------------------------------------------------------------------------//
  227.  
  228. #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
  229. CanQualType Accessor() const {                                           \
  230. return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
  231. }
  232.  
  233. #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
  234. Type Accessor() const { return this->getTypePtr()->Accessor(); }
  235.  
  236. /// Base class of all canonical proxy types, which is responsible for
  237. /// storing the underlying canonical type and providing basic conversions.
  238. template<typename T>
  239. class CanProxyBase {
  240. protected:
  241.   CanQual<T> Stored;
  242.  
  243. public:
  244.   /// Retrieve the pointer to the underlying Type
  245.   const T *getTypePtr() const { return Stored.getTypePtr(); }
  246.  
  247.   /// Implicit conversion to the underlying pointer.
  248.   ///
  249.   /// Also provides the ability to use canonical type proxies in a Boolean
  250.   // context,e.g.,
  251.   /// @code
  252.   ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
  253.   /// @endcode
  254.   operator const T*() const { return this->Stored.getTypePtrOrNull(); }
  255.  
  256.   /// Try to convert the given canonical type to a specific structural
  257.   /// type.
  258.   template<typename U> CanProxy<U> getAs() const {
  259.     return this->Stored.template getAs<U>();
  260.   }
  261.  
  262.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
  263.  
  264.   // Type predicates
  265.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
  266.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
  267.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType)
  268.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType)
  269.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
  270.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
  271.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
  272.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
  273.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
  274.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
  275.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
  276.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
  277.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
  278.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
  279.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
  280.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
  281.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
  282.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
  283.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
  284.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
  285.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
  286.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
  287.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
  288.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
  289.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
  290.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
  291.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
  292.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
  293.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
  294.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
  295.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
  296.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
  297.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
  298.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
  299.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
  300.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
  301.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
  302.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
  303.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
  304.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
  305.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
  306.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
  307.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
  308.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
  309.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
  310.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
  311.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
  312.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
  313.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
  314.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
  315.  
  316.   /// Retrieve the proxy-adaptor type.
  317.   ///
  318.   /// This arrow operator is used when CanProxyAdaptor has been specialized
  319.   /// for the given type T. In that case, we reference members of the
  320.   /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
  321.   /// by the arrow operator in the primary CanProxyAdaptor template.
  322.   const CanProxyAdaptor<T> *operator->() const {
  323.     return static_cast<const CanProxyAdaptor<T> *>(this);
  324.   }
  325. };
  326.  
  327. /// Replaceable canonical proxy adaptor class that provides the link
  328. /// between a canonical type and the accessors of the type.
  329. ///
  330. /// The CanProxyAdaptor is a replaceable class template that is instantiated
  331. /// as part of each canonical proxy type. The primary template merely provides
  332. /// redirection to the underlying type (T), e.g., @c PointerType. One can
  333. /// provide specializations of this class template for each underlying type
  334. /// that provide accessors returning canonical types (@c CanQualType) rather
  335. /// than the more typical @c QualType, to propagate the notion of "canonical"
  336. /// through the system.
  337. template<typename T>
  338. struct CanProxyAdaptor : CanProxyBase<T> {};
  339.  
  340. /// Canonical proxy type returned when retrieving the members of a
  341. /// canonical type or as the result of the @c CanQual<T>::getAs member
  342. /// function.
  343. ///
  344. /// The CanProxy type mainly exists as a proxy through which operator-> will
  345. /// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
  346. /// type that provides canonical-type access to the fields of the type.
  347. template<typename T>
  348. class CanProxy : public CanProxyAdaptor<T> {
  349. public:
  350.   /// Build a NULL proxy.
  351.   CanProxy() = default;
  352.  
  353.   /// Build a proxy to the given canonical type.
  354.   CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
  355.  
  356.   /// Implicit conversion to the stored canonical type.
  357.   operator CanQual<T>() const { return this->Stored; }
  358. };
  359.  
  360. } // namespace clang
  361.  
  362. namespace llvm {
  363.  
  364. /// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
  365. /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
  366. /// to return smart pointer (proxies?).
  367. template<typename T>
  368. struct simplify_type< ::clang::CanQual<T>> {
  369.   using SimpleType = const T *;
  370.  
  371.   static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
  372.     return Val.getTypePtr();
  373.   }
  374. };
  375.  
  376. // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
  377. template<typename T>
  378. struct PointerLikeTypeTraits<clang::CanQual<T>> {
  379.   static void *getAsVoidPointer(clang::CanQual<T> P) {
  380.     return P.getAsOpaquePtr();
  381.   }
  382.  
  383.   static clang::CanQual<T> getFromVoidPointer(void *P) {
  384.     return clang::CanQual<T>::getFromOpaquePtr(P);
  385.   }
  386.  
  387.   // qualifier information is encoded in the low bits.
  388.   static constexpr int NumLowBitsAvailable = 0;
  389. };
  390.  
  391. } // namespace llvm
  392.  
  393. namespace clang {
  394.  
  395. //----------------------------------------------------------------------------//
  396. // Canonical proxy adaptors for canonical type nodes.
  397. //----------------------------------------------------------------------------//
  398.  
  399. /// Iterator adaptor that turns an iterator over canonical QualTypes
  400. /// into an iterator over CanQualTypes.
  401. template <typename InputIterator>
  402. struct CanTypeIterator
  403.     : llvm::iterator_adaptor_base<
  404.           CanTypeIterator<InputIterator>, InputIterator,
  405.           typename std::iterator_traits<InputIterator>::iterator_category,
  406.           CanQualType,
  407.           typename std::iterator_traits<InputIterator>::difference_type,
  408.           CanProxy<Type>, CanQualType> {
  409.   CanTypeIterator() = default;
  410.   explicit CanTypeIterator(InputIterator Iter)
  411.       : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
  412.  
  413.   CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
  414.   CanProxy<Type> operator->() const;
  415. };
  416.  
  417. template<>
  418. struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
  419.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
  420. };
  421.  
  422. template<>
  423. struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
  424.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  425. };
  426.  
  427. template<>
  428. struct CanProxyAdaptor<BlockPointerType>
  429.   : public CanProxyBase<BlockPointerType> {
  430.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  431. };
  432.  
  433. template<>
  434. struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
  435.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  436. };
  437.  
  438. template<>
  439. struct CanProxyAdaptor<LValueReferenceType>
  440.   : public CanProxyBase<LValueReferenceType> {
  441.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  442. };
  443.  
  444. template<>
  445. struct CanProxyAdaptor<RValueReferenceType>
  446.   : public CanProxyBase<RValueReferenceType> {
  447.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  448. };
  449.  
  450. template<>
  451. struct CanProxyAdaptor<MemberPointerType>
  452.   : public CanProxyBase<MemberPointerType> {
  453.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  454.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
  455. };
  456.  
  457. // CanProxyAdaptors for arrays are intentionally unimplemented because
  458. // they are not safe.
  459. template<> struct CanProxyAdaptor<ArrayType>;
  460. template<> struct CanProxyAdaptor<ConstantArrayType>;
  461. template<> struct CanProxyAdaptor<IncompleteArrayType>;
  462. template<> struct CanProxyAdaptor<VariableArrayType>;
  463. template<> struct CanProxyAdaptor<DependentSizedArrayType>;
  464.  
  465. template<>
  466. struct CanProxyAdaptor<DependentSizedExtVectorType>
  467.   : public CanProxyBase<DependentSizedExtVectorType> {
  468.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
  469.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
  470.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
  471. };
  472.  
  473. template<>
  474. struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
  475.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
  476.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
  477. };
  478.  
  479. template<>
  480. struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
  481.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
  482.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
  483. };
  484.  
  485. template<>
  486. struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
  487.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
  488.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
  489. };
  490.  
  491. template<>
  492. struct CanProxyAdaptor<FunctionNoProtoType>
  493.   : public CanProxyBase<FunctionNoProtoType> {
  494.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
  495.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
  496. };
  497.  
  498. template<>
  499. struct CanProxyAdaptor<FunctionProtoType>
  500.   : public CanProxyBase<FunctionProtoType> {
  501.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
  502.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
  503.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
  504.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
  505.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
  506.             ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
  507.  
  508.   CanQualType getParamType(unsigned i) const {
  509.     return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
  510.   }
  511.  
  512.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
  513.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals)
  514.  
  515.   using param_type_iterator =
  516.       CanTypeIterator<FunctionProtoType::param_type_iterator>;
  517.  
  518.   param_type_iterator param_type_begin() const {
  519.     return param_type_iterator(this->getTypePtr()->param_type_begin());
  520.   }
  521.  
  522.   param_type_iterator param_type_end() const {
  523.     return param_type_iterator(this->getTypePtr()->param_type_end());
  524.   }
  525.  
  526.   // Note: canonical function types never have exception specifications
  527. };
  528.  
  529. template<>
  530. struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
  531.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnmodifiedType)
  532. };
  533.  
  534. template<>
  535. struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
  536.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
  537.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
  538. };
  539.  
  540. template <>
  541. struct CanProxyAdaptor<UnaryTransformType>
  542.     : public CanProxyBase<UnaryTransformType> {
  543.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
  544.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
  545.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
  546. };
  547.  
  548. template<>
  549. struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
  550.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
  551.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
  552. };
  553.  
  554. template<>
  555. struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
  556.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
  557.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
  558.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
  559. };
  560.  
  561. template<>
  562. struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
  563.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
  564.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
  565. };
  566.  
  567. template<>
  568. struct CanProxyAdaptor<TemplateTypeParmType>
  569.   : public CanProxyBase<TemplateTypeParmType> {
  570.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
  571.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
  572.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
  573.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
  574.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
  575. };
  576.  
  577. template<>
  578. struct CanProxyAdaptor<ObjCObjectType>
  579.   : public CanProxyBase<ObjCObjectType> {
  580.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
  581.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
  582.                                       getInterface)
  583.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
  584.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
  585.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
  586.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
  587.  
  588.   using qual_iterator = ObjCObjectPointerType::qual_iterator;
  589.  
  590.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
  591.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
  592.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
  593.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
  594. };
  595.  
  596. template<>
  597. struct CanProxyAdaptor<ObjCObjectPointerType>
  598.   : public CanProxyBase<ObjCObjectPointerType> {
  599.   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
  600.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
  601.                                       getInterfaceType)
  602.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
  603.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
  604.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
  605.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
  606.  
  607.   using qual_iterator = ObjCObjectPointerType::qual_iterator;
  608.  
  609.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
  610.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
  611.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
  612.   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
  613. };
  614.  
  615. //----------------------------------------------------------------------------//
  616. // Method and function definitions
  617. //----------------------------------------------------------------------------//
  618. template<typename T>
  619. inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
  620.   return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
  621. }
  622.  
  623. template<typename T>
  624. inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
  625.   if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
  626.     return RefType->getPointeeType();
  627.   else
  628.     return *this;
  629. }
  630.  
  631. template<typename T>
  632. CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
  633.   CanQual<T> Result;
  634.   Result.Stored = QualType::getFromOpaquePtr(Ptr);
  635.   assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
  636.           Result.Stored.isCanonical()) && "Type is not canonical!");
  637.   return Result;
  638. }
  639.  
  640. template<typename T>
  641. CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
  642.   assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
  643.   assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
  644.          "Dynamic type does not meet the static type's requires");
  645.   CanQual<T> Result;
  646.   Result.Stored = Other;
  647.   return Result;
  648. }
  649.  
  650. template<typename T>
  651. template<typename U>
  652. CanProxy<U> CanQual<T>::getAs() const {
  653.   static_assert(!TypeIsArrayType<T>::value,
  654.                 "ArrayType cannot be used with getAs!");
  655.  
  656.   if (Stored.isNull())
  657.     return CanProxy<U>();
  658.  
  659.   if (isa<U>(Stored.getTypePtr()))
  660.     return CanQual<U>::CreateUnsafe(Stored);
  661.  
  662.   return CanProxy<U>();
  663. }
  664.  
  665. template<typename T>
  666. template<typename U>
  667. CanProxy<U> CanQual<T>::castAs() const {
  668.   static_assert(!TypeIsArrayType<U>::value,
  669.                 "ArrayType cannot be used with castAs!");
  670.  
  671.   assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
  672.   return CanQual<U>::CreateUnsafe(Stored);
  673. }
  674.  
  675. template<typename T>
  676. CanProxy<T> CanQual<T>::operator->() const {
  677.   return CanProxy<T>(*this);
  678. }
  679.  
  680. template <typename InputIterator>
  681. CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
  682.   return CanProxy<Type>(*this);
  683. }
  684.  
  685. } // namespace clang
  686.  
  687. #endif // LLVM_CLANG_AST_CANONICALTYPE_H
  688.