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