• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 namespace clang {
24 
25 template<typename T> class CanProxy;
26 template<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 ///
52 template<typename T = Type>
53 class CanQual {
54   /// \brief The actual, canonical type.
55   QualType Stored;
56 
57 public:
58   /// \brief Constructs a NULL canonical type.
CanQual()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.
getTypePtr()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   ///
getTypePtrOrNull()76   const T *getTypePtrOrNull() const {
77     return cast_or_null<T>(Stored.getTypePtrOrNull());
78   }
79 
80   /// \brief Implicit conversion to a qualified type.
QualType()81   operator QualType() const { return Stored; }
82 
83   /// \brief Implicit conversion to bool.
84   operator bool() const { return !isNull(); }
85 
isNull()86   bool isNull() const {
87     return Stored.isNull();
88   }
89 
split()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   template<typename U> CanProxy<U> castAs() const;
112 
113   /// \brief Overloaded arrow operator that produces a canonical type
114   /// proxy.
115   CanProxy<T> operator->() const;
116 
117   /// \brief Retrieve all qualifiers.
getQualifiers()118   Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
119 
120   /// \brief Retrieve the const/volatile/restrict qualifiers.
getCVRQualifiers()121   unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
122 
123   /// \brief Determines whether this type has any qualifiers
hasQualifiers()124   bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
125 
isConstQualified()126   bool isConstQualified() const {
127     return Stored.isLocalConstQualified();
128   }
isVolatileQualified()129   bool isVolatileQualified() const {
130     return Stored.isLocalVolatileQualified();
131   }
isRestrictQualified()132   bool isRestrictQualified() const {
133     return Stored.isLocalRestrictQualified();
134   }
135 
136   /// \brief Determines if this canonical type is furthermore
137   /// canonical as a parameter.  The parameter-canonicalization
138   /// process decays arrays to pointers and drops top-level qualifiers.
isCanonicalAsParam()139   bool isCanonicalAsParam() const {
140     return Stored.isCanonicalAsParam();
141   }
142 
143   /// \brief Retrieve the unqualified form of this type.
144   CanQual<T> getUnqualifiedType() const;
145 
146   /// \brief Retrieves a version of this type with const applied.
147   /// Note that this does not always yield a canonical type.
withConst()148   QualType withConst() const {
149     return Stored.withConst();
150   }
151 
152   /// \brief Determines whether this canonical type is more qualified than
153   /// the @p Other canonical type.
isMoreQualifiedThan(CanQual<T> Other)154   bool isMoreQualifiedThan(CanQual<T> Other) const {
155     return Stored.isMoreQualifiedThan(Other.Stored);
156   }
157 
158   /// \brief Determines whether this canonical type is at least as qualified as
159   /// the @p Other canonical type.
isAtLeastAsQualifiedAs(CanQual<T> Other)160   bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
161     return Stored.isAtLeastAsQualifiedAs(Other.Stored);
162   }
163 
164   /// \brief If the canonical type is a reference type, returns the type that
165   /// it refers to; otherwise, returns the type itself.
166   CanQual<Type> getNonReferenceType() const;
167 
168   /// \brief Retrieve the internal representation of this canonical type.
getAsOpaquePtr()169   void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
170 
171   /// \brief Construct a canonical type from its internal representation.
172   static CanQual<T> getFromOpaquePtr(void *Ptr);
173 
174   /// \brief Builds a canonical type from a QualType.
175   ///
176   /// This routine is inherently unsafe, because it requires the user to
177   /// ensure that the given type is a canonical type with the correct
178   // (dynamic) type.
179   static CanQual<T> CreateUnsafe(QualType Other);
180 
dump()181   void dump() const { Stored.dump(); }
182 
Profile(llvm::FoldingSetNodeID & ID)183   void Profile(llvm::FoldingSetNodeID &ID) const {
184     ID.AddPointer(getAsOpaquePtr());
185   }
186 };
187 
188 template<typename T, typename U>
189 inline bool operator==(CanQual<T> x, CanQual<U> y) {
190   return x.getAsOpaquePtr() == y.getAsOpaquePtr();
191 }
192 
193 template<typename T, typename U>
194 inline bool operator!=(CanQual<T> x, CanQual<U> y) {
195   return x.getAsOpaquePtr() != y.getAsOpaquePtr();
196 }
197 
198 /// \brief Represents a canonical, potentially-qualified type.
199 typedef CanQual<Type> CanQualType;
200 
getCanonicalTypeUnqualified()201 inline CanQualType Type::getCanonicalTypeUnqualified() const {
202   return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
203 }
204 
205 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
206                                            CanQualType T) {
207   DB << static_cast<QualType>(T);
208   return DB;
209 }
210 
211 //----------------------------------------------------------------------------//
212 // Internal proxy classes used by canonical types
213 //----------------------------------------------------------------------------//
214 
215 #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
216 CanQualType Accessor() const {                                           \
217 return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
218 }
219 
220 #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
221 Type Accessor() const { return this->getTypePtr()->Accessor(); }
222 
223 /// \brief Base class of all canonical proxy types, which is responsible for
224 /// storing the underlying canonical type and providing basic conversions.
225 template<typename T>
226 class CanProxyBase {
227 protected:
228   CanQual<T> Stored;
229 
230 public:
231   /// \brief Retrieve the pointer to the underlying Type
getTypePtr()232   const T *getTypePtr() const { return Stored.getTypePtr(); }
233 
234   /// \brief Implicit conversion to the underlying pointer.
235   ///
236   /// Also provides the ability to use canonical type proxies in a Boolean
237   // context,e.g.,
238   /// @code
239   ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
240   /// @endcode
241   operator const T*() const { return this->Stored.getTypePtrOrNull(); }
242 
243   /// \brief Try to convert the given canonical type to a specific structural
244   /// type.
getAs()245   template<typename U> CanProxy<U> getAs() const {
246     return this->Stored.template getAs<U>();
247   }
248 
249   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
250 
251   // Type predicates
252   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
253   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
254   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
255   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
256   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
257   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
258   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
259   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
260   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
261   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
262   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
263   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
264   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
265   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
266   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
267   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
268   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
269   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
270   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
271   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
272   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
273   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
274   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
275   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
276   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
277   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
278   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
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.
322 template<typename T>
323 struct 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.
332 template<typename T>
333 class CanProxy : public CanProxyAdaptor<T> {
334 public:
335   /// \brief Build a NULL proxy.
CanProxy()336   CanProxy() { }
337 
338   /// \brief Build a proxy to the given canonical type.
CanProxy(CanQual<T> Stored)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 
347 namespace 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?).
352 template<typename T>
353 struct simplify_type<const ::clang::CanQual<T> > {
354   typedef const T *SimpleType;
355   static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
356     return Val.getTypePtr();
357   }
358 };
359 template<typename T>
360 struct simplify_type< ::clang::CanQual<T> >
361 : public simplify_type<const ::clang::CanQual<T> > {};
362 
363 // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
364 template<typename T>
365 class PointerLikeTypeTraits<clang::CanQual<T> > {
366 public:
367   static inline void *getAsVoidPointer(clang::CanQual<T> P) {
368     return P.getAsOpaquePtr();
369   }
370   static inline clang::CanQual<T> getFromVoidPointer(void *P) {
371     return clang::CanQual<T>::getFromOpaquePtr(P);
372   }
373   // qualifier information is encoded in the low bits.
374   enum { NumLowBitsAvailable = 0 };
375 };
376 
377 } // end namespace llvm
378 
379 namespace clang {
380 
381 //----------------------------------------------------------------------------//
382 // Canonical proxy adaptors for canonical type nodes.
383 //----------------------------------------------------------------------------//
384 
385 /// \brief Iterator adaptor that turns an iterator over canonical QualTypes
386 /// into an iterator over CanQualTypes.
387 template<typename InputIterator>
388 class CanTypeIterator {
389   InputIterator Iter;
390 
391 public:
392   typedef CanQualType    value_type;
393   typedef value_type     reference;
394   typedef CanProxy<Type> pointer;
395   typedef typename std::iterator_traits<InputIterator>::difference_type
396     difference_type;
397   typedef typename std::iterator_traits<InputIterator>::iterator_category
398     iterator_category;
399 
400   CanTypeIterator() : Iter() { }
401   explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
402 
403   // Input iterator
404   reference operator*() const {
405     return CanQualType::CreateUnsafe(*Iter);
406   }
407 
408   pointer operator->() const;
409 
410   CanTypeIterator &operator++() {
411     ++Iter;
412     return *this;
413   }
414 
415   CanTypeIterator operator++(int) {
416     CanTypeIterator Tmp(*this);
417     ++Iter;
418     return Tmp;
419   }
420 
421   friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
422     return X.Iter == Y.Iter;
423   }
424   friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
425     return X.Iter != Y.Iter;
426   }
427 
428   // Bidirectional iterator
429   CanTypeIterator &operator--() {
430     --Iter;
431     return *this;
432   }
433 
434   CanTypeIterator operator--(int) {
435     CanTypeIterator Tmp(*this);
436     --Iter;
437     return Tmp;
438   }
439 
440   // Random access iterator
441   reference operator[](difference_type n) const {
442     return CanQualType::CreateUnsafe(Iter[n]);
443   }
444 
445   CanTypeIterator &operator+=(difference_type n) {
446     Iter += n;
447     return *this;
448   }
449 
450   CanTypeIterator &operator-=(difference_type n) {
451     Iter -= n;
452     return *this;
453   }
454 
455   friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
456     X += n;
457     return X;
458   }
459 
460   friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
461     X += n;
462     return X;
463   }
464 
465   friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
466     X -= n;
467     return X;
468   }
469 
470   friend difference_type operator-(const CanTypeIterator &X,
471                                    const CanTypeIterator &Y) {
472     return X - Y;
473   }
474 };
475 
476 template<>
477 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
478   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
479 };
480 
481 template<>
482 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
483   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
484 };
485 
486 template<>
487 struct CanProxyAdaptor<BlockPointerType>
488   : public CanProxyBase<BlockPointerType> {
489   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
490 };
491 
492 template<>
493 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
494   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
495 };
496 
497 template<>
498 struct CanProxyAdaptor<LValueReferenceType>
499   : public CanProxyBase<LValueReferenceType> {
500   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
501 };
502 
503 template<>
504 struct CanProxyAdaptor<RValueReferenceType>
505   : public CanProxyBase<RValueReferenceType> {
506   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
507 };
508 
509 template<>
510 struct CanProxyAdaptor<MemberPointerType>
511   : public CanProxyBase<MemberPointerType> {
512   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
513   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
514 };
515 
516 template<>
517 struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
518   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
519   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
520                                       getSizeModifier)
521   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
522 };
523 
524 template<>
525 struct CanProxyAdaptor<ConstantArrayType>
526   : public CanProxyBase<ConstantArrayType> {
527   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
528   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
529                                       getSizeModifier)
530   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
531   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
532 };
533 
534 template<>
535 struct CanProxyAdaptor<IncompleteArrayType>
536   : public CanProxyBase<IncompleteArrayType> {
537   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
538   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
539                                       getSizeModifier)
540   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
541 };
542 
543 template<>
544 struct CanProxyAdaptor<VariableArrayType>
545   : public CanProxyBase<VariableArrayType> {
546   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
547   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
548                                       getSizeModifier)
549   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
550   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
551   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
552   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
553   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
554 };
555 
556 template<>
557 struct CanProxyAdaptor<DependentSizedArrayType>
558   : public CanProxyBase<DependentSizedArrayType> {
559   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
560   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
561   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
562   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
563   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
564 };
565 
566 template<>
567 struct CanProxyAdaptor<DependentSizedExtVectorType>
568   : public CanProxyBase<DependentSizedExtVectorType> {
569   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
570   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
571   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
572 };
573 
574 template<>
575 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
576   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
577   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
578 };
579 
580 template<>
581 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
582   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
583   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
584 };
585 
586 template<>
587 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
588   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
589   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
590 };
591 
592 template<>
593 struct CanProxyAdaptor<FunctionNoProtoType>
594   : public CanProxyBase<FunctionNoProtoType> {
595   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
596   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
597 };
598 
599 template<>
600 struct CanProxyAdaptor<FunctionProtoType>
601   : public CanProxyBase<FunctionProtoType> {
602   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
603   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
604   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
605   CanQualType getArgType(unsigned i) const {
606     return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
607   }
608 
609   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
610   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
611 
612   typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
613     arg_type_iterator;
614 
615   arg_type_iterator arg_type_begin() const {
616     return arg_type_iterator(this->getTypePtr()->arg_type_begin());
617   }
618 
619   arg_type_iterator arg_type_end() const {
620     return arg_type_iterator(this->getTypePtr()->arg_type_end());
621   }
622 
623   // Note: canonical function types never have exception specifications
624 };
625 
626 template<>
627 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
628   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
629 };
630 
631 template<>
632 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
633   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
634   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
635 };
636 
637 template <>
638 struct CanProxyAdaptor<UnaryTransformType>
639     : public CanProxyBase<UnaryTransformType> {
640   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
641   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
642   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
643 };
644 
645 template<>
646 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
647   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
648   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
649 };
650 
651 template<>
652 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
653   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
654   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
655   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
656 };
657 
658 template<>
659 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
660   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
661   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
662 };
663 
664 template<>
665 struct CanProxyAdaptor<TemplateTypeParmType>
666   : public CanProxyBase<TemplateTypeParmType> {
667   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
668   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
669   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
670   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
671   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
672 };
673 
674 template<>
675 struct CanProxyAdaptor<ObjCObjectType>
676   : public CanProxyBase<ObjCObjectType> {
677   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
678   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
679                                       getInterface)
680   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
681   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
682   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
683   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
684 
685   typedef ObjCObjectPointerType::qual_iterator qual_iterator;
686   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
687   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
688   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
689   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
690 };
691 
692 template<>
693 struct CanProxyAdaptor<ObjCObjectPointerType>
694   : public CanProxyBase<ObjCObjectPointerType> {
695   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
696   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
697                                       getInterfaceType)
698   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
699   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
700   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
701   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
702 
703   typedef ObjCObjectPointerType::qual_iterator qual_iterator;
704   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
705   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
706   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
707   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
708 };
709 
710 //----------------------------------------------------------------------------//
711 // Method and function definitions
712 //----------------------------------------------------------------------------//
713 template<typename T>
714 inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
715   return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
716 }
717 
718 template<typename T>
719 inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
720   if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
721     return RefType->getPointeeType();
722   else
723     return *this;
724 }
725 
726 template<typename T>
727 CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
728   CanQual<T> Result;
729   Result.Stored = QualType::getFromOpaquePtr(Ptr);
730   assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
731           Result.Stored.isCanonical()) && "Type is not canonical!");
732   return Result;
733 }
734 
735 template<typename T>
736 CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
737   assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
738   assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
739          "Dynamic type does not meet the static type's requires");
740   CanQual<T> Result;
741   Result.Stored = Other;
742   return Result;
743 }
744 
745 template<typename T>
746 template<typename U>
747 CanProxy<U> CanQual<T>::getAs() const {
748   if (Stored.isNull())
749     return CanProxy<U>();
750 
751   if (isa<U>(Stored.getTypePtr()))
752     return CanQual<U>::CreateUnsafe(Stored);
753 
754   return CanProxy<U>();
755 }
756 
757 template<typename T>
758 template<typename U>
759 CanProxy<U> CanQual<T>::castAs() const {
760   assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
761   return CanQual<U>::CreateUnsafe(Stored);
762 }
763 
764 template<typename T>
765 CanProxy<T> CanQual<T>::operator->() const {
766   return CanProxy<T>(*this);
767 }
768 
769 template<typename InputIterator>
770 typename CanTypeIterator<InputIterator>::pointer
771 CanTypeIterator<InputIterator>::operator->() const {
772   return CanProxy<Type>(*this);
773 }
774 
775 }
776 
777 
778 #endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
779