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