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