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