Home | History | Annotate | Line # | Download | only in AST
      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, isPromotableIntegerType)
    309   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
    310   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
    311   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
    312   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
    313   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
    314   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
    315   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
    316 
    317   /// Retrieve the proxy-adaptor type.
    318   ///
    319   /// This arrow operator is used when CanProxyAdaptor has been specialized
    320   /// for the given type T. In that case, we reference members of the
    321   /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
    322   /// by the arrow operator in the primary CanProxyAdaptor template.
    323   const CanProxyAdaptor<T> *operator->() const {
    324     return static_cast<const CanProxyAdaptor<T> *>(this);
    325   }
    326 };
    327 
    328 /// Replaceable canonical proxy adaptor class that provides the link
    329 /// between a canonical type and the accessors of the type.
    330 ///
    331 /// The CanProxyAdaptor is a replaceable class template that is instantiated
    332 /// as part of each canonical proxy type. The primary template merely provides
    333 /// redirection to the underlying type (T), e.g., @c PointerType. One can
    334 /// provide specializations of this class template for each underlying type
    335 /// that provide accessors returning canonical types (@c CanQualType) rather
    336 /// than the more typical @c QualType, to propagate the notion of "canonical"
    337 /// through the system.
    338 template<typename T>
    339 struct CanProxyAdaptor : CanProxyBase<T> {};
    340 
    341 /// Canonical proxy type returned when retrieving the members of a
    342 /// canonical type or as the result of the @c CanQual<T>::getAs member
    343 /// function.
    344 ///
    345 /// The CanProxy type mainly exists as a proxy through which operator-> will
    346 /// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
    347 /// type that provides canonical-type access to the fields of the type.
    348 template<typename T>
    349 class CanProxy : public CanProxyAdaptor<T> {
    350 public:
    351   /// Build a NULL proxy.
    352   CanProxy() = default;
    353 
    354   /// Build a proxy to the given canonical type.
    355   CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
    356 
    357   /// Implicit conversion to the stored canonical type.
    358   operator CanQual<T>() const { return this->Stored; }
    359 };
    360 
    361 } // namespace clang
    362 
    363 namespace llvm {
    364 
    365 /// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
    366 /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
    367 /// to return smart pointer (proxies?).
    368 template<typename T>
    369 struct simplify_type< ::clang::CanQual<T>> {
    370   using SimpleType = const T *;
    371 
    372   static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
    373     return Val.getTypePtr();
    374   }
    375 };
    376 
    377 // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
    378 template<typename T>
    379 struct PointerLikeTypeTraits<clang::CanQual<T>> {
    380   static void *getAsVoidPointer(clang::CanQual<T> P) {
    381     return P.getAsOpaquePtr();
    382   }
    383 
    384   static clang::CanQual<T> getFromVoidPointer(void *P) {
    385     return clang::CanQual<T>::getFromOpaquePtr(P);
    386   }
    387 
    388   // qualifier information is encoded in the low bits.
    389   static constexpr int NumLowBitsAvailable = 0;
    390 };
    391 
    392 } // namespace llvm
    393 
    394 namespace clang {
    395 
    396 //----------------------------------------------------------------------------//
    397 // Canonical proxy adaptors for canonical type nodes.
    398 //----------------------------------------------------------------------------//
    399 
    400 /// Iterator adaptor that turns an iterator over canonical QualTypes
    401 /// into an iterator over CanQualTypes.
    402 template <typename InputIterator>
    403 struct CanTypeIterator
    404     : llvm::iterator_adaptor_base<
    405           CanTypeIterator<InputIterator>, InputIterator,
    406           typename std::iterator_traits<InputIterator>::iterator_category,
    407           CanQualType,
    408           typename std::iterator_traits<InputIterator>::difference_type,
    409           CanProxy<Type>, CanQualType> {
    410   CanTypeIterator() = default;
    411   explicit CanTypeIterator(InputIterator Iter)
    412       : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
    413 
    414   CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
    415   CanProxy<Type> operator->() const;
    416 };
    417 
    418 template<>
    419 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
    420   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
    421 };
    422 
    423 template<>
    424 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
    425   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    426 };
    427 
    428 template<>
    429 struct CanProxyAdaptor<BlockPointerType>
    430   : public CanProxyBase<BlockPointerType> {
    431   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    432 };
    433 
    434 template<>
    435 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
    436   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    437 };
    438 
    439 template<>
    440 struct CanProxyAdaptor<LValueReferenceType>
    441   : public CanProxyBase<LValueReferenceType> {
    442   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    443 };
    444 
    445 template<>
    446 struct CanProxyAdaptor<RValueReferenceType>
    447   : public CanProxyBase<RValueReferenceType> {
    448   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    449 };
    450 
    451 template<>
    452 struct CanProxyAdaptor<MemberPointerType>
    453   : public CanProxyBase<MemberPointerType> {
    454   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    455   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
    456 };
    457 
    458 // CanProxyAdaptors for arrays are intentionally unimplemented because
    459 // they are not safe.
    460 template<> struct CanProxyAdaptor<ArrayType>;
    461 template<> struct CanProxyAdaptor<ConstantArrayType>;
    462 template<> struct CanProxyAdaptor<IncompleteArrayType>;
    463 template<> struct CanProxyAdaptor<VariableArrayType>;
    464 template<> struct CanProxyAdaptor<DependentSizedArrayType>;
    465 
    466 template<>
    467 struct CanProxyAdaptor<DependentSizedExtVectorType>
    468   : public CanProxyBase<DependentSizedExtVectorType> {
    469   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
    470   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
    471   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
    472 };
    473 
    474 template<>
    475 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
    476   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
    477   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
    478 };
    479 
    480 template<>
    481 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
    482   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
    483   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
    484 };
    485 
    486 template<>
    487 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
    488   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
    489   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
    490 };
    491 
    492 template<>
    493 struct CanProxyAdaptor<FunctionNoProtoType>
    494   : public CanProxyBase<FunctionNoProtoType> {
    495   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
    496   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
    497 };
    498 
    499 template<>
    500 struct CanProxyAdaptor<FunctionProtoType>
    501   : public CanProxyBase<FunctionProtoType> {
    502   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
    503   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
    504   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
    505   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
    506   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
    507             ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
    508 
    509   CanQualType getParamType(unsigned i) const {
    510     return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
    511   }
    512 
    513   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
    514   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals)
    515 
    516   using param_type_iterator =
    517       CanTypeIterator<FunctionProtoType::param_type_iterator>;
    518 
    519   param_type_iterator param_type_begin() const {
    520     return param_type_iterator(this->getTypePtr()->param_type_begin());
    521   }
    522 
    523   param_type_iterator param_type_end() const {
    524     return param_type_iterator(this->getTypePtr()->param_type_end());
    525   }
    526 
    527   // Note: canonical function types never have exception specifications
    528 };
    529 
    530 template<>
    531 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
    532   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
    533 };
    534 
    535 template<>
    536 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
    537   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
    538   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
    539 };
    540 
    541 template <>
    542 struct CanProxyAdaptor<UnaryTransformType>
    543     : public CanProxyBase<UnaryTransformType> {
    544   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
    545   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
    546   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
    547 };
    548 
    549 template<>
    550 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
    551   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
    552   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
    553 };
    554 
    555 template<>
    556 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
    557   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
    558   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
    559   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
    560 };
    561 
    562 template<>
    563 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
    564   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
    565   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
    566 };
    567 
    568 template<>
    569 struct CanProxyAdaptor<TemplateTypeParmType>
    570   : public CanProxyBase<TemplateTypeParmType> {
    571   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
    572   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
    573   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
    574   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
    575   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
    576 };
    577 
    578 template<>
    579 struct CanProxyAdaptor<ObjCObjectType>
    580   : public CanProxyBase<ObjCObjectType> {
    581   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
    582   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
    583                                       getInterface)
    584   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
    585   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
    586   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
    587   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
    588 
    589   using qual_iterator = ObjCObjectPointerType::qual_iterator;
    590 
    591   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
    592   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
    593   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
    594   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
    595 };
    596 
    597 template<>
    598 struct CanProxyAdaptor<ObjCObjectPointerType>
    599   : public CanProxyBase<ObjCObjectPointerType> {
    600   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
    601   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
    602                                       getInterfaceType)
    603   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
    604   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
    605   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
    606   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
    607 
    608   using qual_iterator = ObjCObjectPointerType::qual_iterator;
    609 
    610   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
    611   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
    612   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
    613   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
    614 };
    615 
    616 //----------------------------------------------------------------------------//
    617 // Method and function definitions
    618 //----------------------------------------------------------------------------//
    619 template<typename T>
    620 inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
    621   return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
    622 }
    623 
    624 template<typename T>
    625 inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
    626   if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
    627     return RefType->getPointeeType();
    628   else
    629     return *this;
    630 }
    631 
    632 template<typename T>
    633 CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
    634   CanQual<T> Result;
    635   Result.Stored = QualType::getFromOpaquePtr(Ptr);
    636   assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
    637           Result.Stored.isCanonical()) && "Type is not canonical!");
    638   return Result;
    639 }
    640 
    641 template<typename T>
    642 CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
    643   assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
    644   assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
    645          "Dynamic type does not meet the static type's requires");
    646   CanQual<T> Result;
    647   Result.Stored = Other;
    648   return Result;
    649 }
    650 
    651 template<typename T>
    652 template<typename U>
    653 CanProxy<U> CanQual<T>::getAs() const {
    654   static_assert(!TypeIsArrayType<T>::value,
    655                 "ArrayType cannot be used with getAs!");
    656 
    657   if (Stored.isNull())
    658     return CanProxy<U>();
    659 
    660   if (isa<U>(Stored.getTypePtr()))
    661     return CanQual<U>::CreateUnsafe(Stored);
    662 
    663   return CanProxy<U>();
    664 }
    665 
    666 template<typename T>
    667 template<typename U>
    668 CanProxy<U> CanQual<T>::castAs() const {
    669   static_assert(!TypeIsArrayType<U>::value,
    670                 "ArrayType cannot be used with castAs!");
    671 
    672   assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
    673   return CanQual<U>::CreateUnsafe(Stored);
    674 }
    675 
    676 template<typename T>
    677 CanProxy<T> CanQual<T>::operator->() const {
    678   return CanProxy<T>(*this);
    679 }
    680 
    681 template <typename InputIterator>
    682 CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
    683   return CanProxy<Type>(*this);
    684 }
    685 
    686 } // namespace clang
    687 
    688 #endif // LLVM_CLANG_AST_CANONICALTYPE_H
    689