clang  6.0.0svn
CanonicalType.h
Go to the documentation of this file.
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_CANONICALTYPE_H
16 #define LLVM_CLANG_AST_CANONICALTYPE_H
17 
18 #include "clang/AST/Type.h"
19 #include "clang/Basic/Diagnostic.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/FoldingSet.h"
23 #include "llvm/ADT/iterator.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/PointerLikeTypeTraits.h"
26 #include <cassert>
27 #include <iterator>
28 #include <type_traits>
29 
30 namespace clang {
31 
32 template<typename T> class CanProxy;
33 template<typename T> struct CanProxyAdaptor;
34 class CXXRecordDecl;
35 class EnumDecl;
36 class Expr;
37 class IdentifierInfo;
38 class ObjCInterfaceDecl;
39 class RecordDecl;
40 class TagDecl;
42 
43 //----------------------------------------------------------------------------//
44 // Canonical, qualified type template
45 //----------------------------------------------------------------------------//
46 
47 /// \brief Represents a canonical, potentially-qualified type.
48 ///
49 /// The CanQual template is a lightweight smart pointer that provides access
50 /// to the canonical representation of a type, where all typedefs and other
51 /// syntactic sugar has been eliminated. A CanQualType may also have various
52 /// qualifiers (const, volatile, restrict) attached to it.
53 ///
54 /// The template type parameter @p T is one of the Type classes (PointerType,
55 /// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
56 /// type (or some subclass of that type). The typedef @c CanQualType is just
57 /// a shorthand for @c CanQual<Type>.
58 ///
59 /// An instance of @c CanQual<T> can be implicitly converted to a
60 /// @c CanQual<U> when T is derived from U, which essentially provides an
61 /// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
62 /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
63 /// be implicitly converted to a QualType, but the reverse operation requires
64 /// a call to ASTContext::getCanonicalType().
65 template<typename T = Type>
66 class CanQual {
67  /// \brief The actual, canonical type.
68  QualType Stored;
69 
70 public:
71  /// \brief Constructs a NULL canonical type.
72  CanQual() = default;
73 
74  /// \brief Converting constructor that permits implicit upcasting of
75  /// canonical type pointers.
76  template <typename U>
77  CanQual(const CanQual<U> &Other,
78  typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
79 
80  /// \brief Retrieve the underlying type pointer, which refers to a
81  /// canonical type.
82  ///
83  /// The underlying pointer must not be nullptr.
84  const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
85 
86  /// \brief Retrieve the underlying type pointer, which refers to a
87  /// canonical type, or nullptr.
88  const T *getTypePtrOrNull() const {
89  return cast_or_null<T>(Stored.getTypePtrOrNull());
90  }
91 
92  /// \brief Implicit conversion to a qualified type.
93  operator QualType() const { return Stored; }
94 
95  /// \brief Implicit conversion to bool.
96  explicit operator bool() const { return !isNull(); }
97 
98  bool isNull() const {
99  return Stored.isNull();
100  }
101 
102  SplitQualType split() const { return Stored.split(); }
103 
104  /// \brief Retrieve a canonical type pointer with a different static type,
105  /// upcasting or downcasting as needed.
106  ///
107  /// The getAs() function is typically used to try to downcast to a
108  /// more specific (canonical) type in the type system. For example:
109  ///
110  /// @code
111  /// void f(CanQual<Type> T) {
112  /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
113  /// // look at Ptr's pointee type
114  /// }
115  /// }
116  /// @endcode
117  ///
118  /// \returns A proxy pointer to the same type, but with the specified
119  /// static type (@p U). If the dynamic type is not the specified static type
120  /// or a derived class thereof, a NULL canonical type.
121  template<typename U> CanProxy<U> getAs() const;
122 
123  template<typename U> CanProxy<U> castAs() const;
124 
125  /// \brief Overloaded arrow operator that produces a canonical type
126  /// proxy.
127  CanProxy<T> operator->() const;
128 
129  /// \brief Retrieve all qualifiers.
130  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
131 
132  /// \brief Retrieve the const/volatile/restrict qualifiers.
133  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
134 
135  /// \brief Determines whether this type has any qualifiers
136  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
137 
138  bool isConstQualified() const {
139  return Stored.isLocalConstQualified();
140  }
141 
142  bool isVolatileQualified() const {
143  return Stored.isLocalVolatileQualified();
144  }
145 
146  bool isRestrictQualified() const {
147  return Stored.isLocalRestrictQualified();
148  }
149 
150  /// \brief Determines if this canonical type is furthermore
151  /// canonical as a parameter. The parameter-canonicalization
152  /// process decays arrays to pointers and drops top-level qualifiers.
153  bool isCanonicalAsParam() const {
154  return Stored.isCanonicalAsParam();
155  }
156 
157  /// \brief Retrieve the unqualified form of this type.
159 
160  /// \brief Retrieves a version of this type with const applied.
161  /// Note that this does not always yield a canonical type.
162  QualType withConst() const {
163  return Stored.withConst();
164  }
165 
166  /// \brief Determines whether this canonical type is more qualified than
167  /// the @p Other canonical type.
168  bool isMoreQualifiedThan(CanQual<T> Other) const {
169  return Stored.isMoreQualifiedThan(Other.Stored);
170  }
171 
172  /// \brief Determines whether this canonical type is at least as qualified as
173  /// the @p Other canonical type.
174  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
175  return Stored.isAtLeastAsQualifiedAs(Other.Stored);
176  }
177 
178  /// \brief If the canonical type is a reference type, returns the type that
179  /// it refers to; otherwise, returns the type itself.
181 
182  /// \brief Retrieve the internal representation of this canonical type.
183  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
184 
185  /// \brief Construct a canonical type from its internal representation.
186  static CanQual<T> getFromOpaquePtr(void *Ptr);
187 
188  /// \brief Builds a canonical type from a QualType.
189  ///
190  /// This routine is inherently unsafe, because it requires the user to
191  /// ensure that the given type is a canonical type with the correct
192  // (dynamic) type.
193  static CanQual<T> CreateUnsafe(QualType Other);
194 
195  void dump() const { Stored.dump(); }
196 
197  void Profile(llvm::FoldingSetNodeID &ID) const {
198  ID.AddPointer(getAsOpaquePtr());
199  }
200 };
201 
202 template<typename T, typename U>
203 inline bool operator==(CanQual<T> x, CanQual<U> y) {
204  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
205 }
206 
207 template<typename T, typename U>
208 inline bool operator!=(CanQual<T> x, CanQual<U> y) {
209  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
210 }
211 
212 /// \brief Represents a canonical, potentially-qualified type.
214 
216  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
217 }
218 
220  CanQualType T) {
221  DB << static_cast<QualType>(T);
222  return DB;
223 }
224 
225 //----------------------------------------------------------------------------//
226 // Internal proxy classes used by canonical types
227 //----------------------------------------------------------------------------//
228 
229 #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \
230 CanQualType Accessor() const { \
231 return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
232 }
233 
234 #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
235 Type Accessor() const { return this->getTypePtr()->Accessor(); }
236 
237 /// \brief Base class of all canonical proxy types, which is responsible for
238 /// storing the underlying canonical type and providing basic conversions.
239 template<typename T>
241 protected:
243 
244 public:
245  /// \brief Retrieve the pointer to the underlying Type
246  const T *getTypePtr() const { return Stored.getTypePtr(); }
247 
248  /// \brief Implicit conversion to the underlying pointer.
249  ///
250  /// Also provides the ability to use canonical type proxies in a Boolean
251  // context,e.g.,
252  /// @code
253  /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
254  /// @endcode
255  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
256 
257  /// \brief Try to convert the given canonical type to a specific structural
258  /// type.
259  template<typename U> CanProxy<U> getAs() const {
260  return this->Stored.template getAs<U>();
261  }
262 
264 
265  // Type predicates
266  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
267  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
268  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
269  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
270  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
271  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
274  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
275  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
276  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
277  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
278  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
279  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
280  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
281  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
282  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
283  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
284  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
285  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
286  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
287  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
288  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
289  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
290  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
291  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
292  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
293  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
294  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
295  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
296  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
297  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
298  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
299  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
300  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
301  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
302  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
303  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
304  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
305  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
306  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
307  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
308  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
309  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
310  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
311  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
312  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
313  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
315 
316  /// \brief Retrieve the proxy-adaptor type.
317  ///
318  /// This arrow operator is used when CanProxyAdaptor has been specialized
319  /// for the given type T. In that case, we reference members of the
320  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
321  /// by the arrow operator in the primary CanProxyAdaptor template.
322  const CanProxyAdaptor<T> *operator->() const {
323  return static_cast<const CanProxyAdaptor<T> *>(this);
324  }
325 };
326 
327 /// \brief Replacable canonical proxy adaptor class that provides the link
328 /// between a canonical type and the accessors of the type.
329 ///
330 /// The CanProxyAdaptor is a replaceable class template that is instantiated
331 /// as part of each canonical proxy type. The primary template merely provides
332 /// redirection to the underlying type (T), e.g., @c PointerType. One can
333 /// provide specializations of this class template for each underlying type
334 /// that provide accessors returning canonical types (@c CanQualType) rather
335 /// than the more typical @c QualType, to propagate the notion of "canonical"
336 /// through the system.
337 template<typename T>
338 struct CanProxyAdaptor : CanProxyBase<T> {};
339 
340 /// \brief Canonical proxy type returned when retrieving the members of a
341 /// canonical type or as the result of the @c CanQual<T>::getAs member
342 /// function.
343 ///
344 /// The CanProxy type mainly exists as a proxy through which operator-> will
345 /// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
346 /// type that provides canonical-type access to the fields of the type.
347 template<typename T>
348 class CanProxy : public CanProxyAdaptor<T> {
349 public:
350  /// \brief Build a NULL proxy.
351  CanProxy() = default;
352 
353  /// \brief Build a proxy to the given canonical type.
354  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
355 
356  /// \brief Implicit conversion to the stored canonical type.
357  operator CanQual<T>() const { return this->Stored; }
358 };
359 
360 } // namespace clang
361 
362 namespace llvm {
363 
364 /// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
365 /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
366 /// to return smart pointer (proxies?).
367 template<typename T>
368 struct simplify_type< ::clang::CanQual<T>> {
369  using SimpleType = const T *;
370 
372  return Val.getTypePtr();
373  }
374 };
375 
376 // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
377 template<typename T>
380  return P.getAsOpaquePtr();
381  }
382 
385  }
386 
387  // qualifier information is encoded in the low bits.
388  enum { NumLowBitsAvailable = 0 };
389 };
390 
391 } // namespace llvm
392 
393 namespace clang {
394 
395 //----------------------------------------------------------------------------//
396 // Canonical proxy adaptors for canonical type nodes.
397 //----------------------------------------------------------------------------//
398 
399 /// \brief Iterator adaptor that turns an iterator over canonical QualTypes
400 /// into an iterator over CanQualTypes.
401 template <typename InputIterator>
403  : llvm::iterator_adaptor_base<
404  CanTypeIterator<InputIterator>, InputIterator,
405  typename std::iterator_traits<InputIterator>::iterator_category,
406  CanQualType,
407  typename std::iterator_traits<InputIterator>::difference_type,
408  CanProxy<Type>, CanQualType> {
409  CanTypeIterator() = default;
410  explicit CanTypeIterator(InputIterator Iter)
411  : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
412 
413  CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
414  CanProxy<Type> operator->() const;
415 };
416 
417 template<>
418 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
419  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
420 };
421 
422 template<>
423 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
424  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
425 };
426 
427 template<>
429  : public CanProxyBase<BlockPointerType> {
430  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
431 };
432 
433 template<>
434 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
435  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
436 };
437 
438 template<>
440  : public CanProxyBase<LValueReferenceType> {
441  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
442 };
443 
444 template<>
446  : public CanProxyBase<RValueReferenceType> {
447  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
448 };
449 
450 template<>
452  : public CanProxyBase<MemberPointerType> {
453  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
454  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
455 };
456 
457 // CanProxyAdaptors for arrays are intentionally unimplemented because
458 // they are not safe.
459 template<> struct CanProxyAdaptor<ArrayType>;
460 template<> struct CanProxyAdaptor<ConstantArrayType>;
461 template<> struct CanProxyAdaptor<IncompleteArrayType>;
462 template<> struct CanProxyAdaptor<VariableArrayType>;
463 template<> struct CanProxyAdaptor<DependentSizedArrayType>;
464 
465 template<>
467  : public CanProxyBase<DependentSizedExtVectorType> {
468  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
469  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
471 };
472 
473 template<>
474 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
475  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
476  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
477 };
478 
479 template<>
480 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
481  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
482  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
483 };
484 
485 template<>
486 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
487  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
489 };
490 
491 template<>
493  : public CanProxyBase<FunctionNoProtoType> {
494  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
496 };
497 
498 template<>
500  : public CanProxyBase<FunctionProtoType> {
501  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
503  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
504  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
506  ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
507 
508  CanQualType getParamType(unsigned i) const {
510  }
511 
512  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
513  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
514 
515  using param_type_iterator =
517 
519  return param_type_iterator(this->getTypePtr()->param_type_begin());
520  }
521 
523  return param_type_iterator(this->getTypePtr()->param_type_end());
524  }
525 
526  // Note: canonical function types never have exception specifications
527 };
528 
529 template<>
530 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
532 };
533 
534 template<>
535 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
536  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
538 };
539 
540 template <>
542  : public CanProxyBase<UnaryTransformType> {
546 };
547 
548 template<>
549 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
551  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
552 };
553 
554 template<>
555 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
557  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
558  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
559 };
560 
561 template<>
562 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
564  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
565 };
566 
567 template<>
569  : public CanProxyBase<TemplateTypeParmType> {
570  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
571  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
572  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
575 };
576 
577 template<>
579  : public CanProxyBase<ObjCObjectType> {
582  getInterface)
583  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
584  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
585  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
586  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
587 
588  using qual_iterator = ObjCObjectPointerType::qual_iterator;
589 
590  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
591  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
592  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
593  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
594 };
595 
596 template<>
598  : public CanProxyBase<ObjCObjectPointerType> {
599  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
601  getInterfaceType)
602  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
603  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
604  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
605  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
606 
607  using qual_iterator = ObjCObjectPointerType::qual_iterator;
608 
609  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
610  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
611  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
612  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
613 };
614 
615 //----------------------------------------------------------------------------//
616 // Method and function definitions
617 //----------------------------------------------------------------------------//
618 template<typename T>
620  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
621 }
622 
623 template<typename T>
625  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
626  return RefType->getPointeeType();
627  else
628  return *this;
629 }
630 
631 template<typename T>
634  Result.Stored = QualType::getFromOpaquePtr(Ptr);
635  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
636  Result.Stored.isCanonical()) && "Type is not canonical!");
637  return Result;
638 }
639 
640 template<typename T>
642  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
643  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
644  "Dynamic type does not meet the static type's requires");
646  Result.Stored = Other;
647  return Result;
648 }
649 
650 template<typename T>
651 template<typename U>
653  static_assert(!TypeIsArrayType<T>::value,
654  "ArrayType cannot be used with getAs!");
655 
656  if (Stored.isNull())
657  return CanProxy<U>();
658 
659  if (isa<U>(Stored.getTypePtr()))
660  return CanQual<U>::CreateUnsafe(Stored);
661 
662  return CanProxy<U>();
663 }
664 
665 template<typename T>
666 template<typename U>
668  static_assert(!TypeIsArrayType<U>::value,
669  "ArrayType cannot be used with castAs!");
670 
671  assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
672  return CanQual<U>::CreateUnsafe(Stored);
673 }
674 
675 template<typename T>
677  return CanProxy<T>(*this);
678 }
679 
680 template <typename InputIterator>
682  return CanProxy<Type>(*this);
683 }
684 
685 } // namespace clang
686 
687 #endif // LLVM_CLANG_AST_CANONICALTYPE_H
static CanQual< T > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
Replacable canonical proxy adaptor class that provides the link between a canonical type and the acce...
Definition: CanonicalType.h:33
QualType withConst() const
Retrieves a version of this type with const applied.
static clang::CanQual< T > getFromVoidPointer(void *P)
SplitQualType split() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2285
A (possibly-)qualified type.
Definition: Type.h:653
bool isNull() const
Definition: CanonicalType.h:98
bool operator==(CanQual< T > x, CanQual< U > y)
#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:26
bool isConstQualified() const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3058
CanProxy(CanQual< T > Stored)
Build a proxy to the given canonical type.
C Language Family Type Representation.
StringRef P
CanTypeIterator(InputIterator Iter)
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:195
The base class of the type hierarchy.
Definition: Type.h:1353
void Profile(llvm::FoldingSetNodeID &ID) const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
Canonical proxy type returned when retrieving the members of a canonical type or as the result of the...
Definition: CanonicalType.h:32
QualType withConst() const
Definition: Type.h:818
void dump() const
const T * getTypePtr() const
Retrieve the pointer to the underlying Type.
The collection of all-type qualifiers we support.
Definition: Type.h:152
Qualifiers getQualifiers() const
Retrieve all qualifiers.
const T * getTypePtrOrNull() const
Retrieve the underlying type pointer, which refers to a canonical type, or nullptr.
Definition: CanonicalType.h:88
RecordDecl - Represents a struct/union/class.
Definition: Decl.h:3478
One of these records is kept for each identifier that is lexed.
bool isLocalRestrictQualified() const
Determine whether this particular QualType instance has the "restrict" qualifier set, without looking through typedefs that may have added "restrict" at a different level.
Definition: Type.h:736
Represents a class type in Objective C.
Definition: Type.h:5186
Definition: Format.h:1900
bool isAtLeastAsQualifiedAs(QualType Other) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
Definition: Type.h:5874
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:5739
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2486
bool isRestrictQualified() const
Defines the Diagnostic-related interfaces.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5720
static bool isBooleanType(QualType Ty)
void * getAsOpaquePtr() const
Definition: Type.h:699
Represents an ObjC class declaration.
Definition: DeclObjC.h:1191
static void * getAsVoidPointer(clang::CanQual< T > P)
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Definition: CanonicalType.h:84
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:2876
Represents a K&R-style &#39;int foo()&#39; function, which has no information available about its arguments...
Definition: Type.h:3235
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:955
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3270
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:5864
Expr - This represents one expression.
Definition: Expr.h:106
CanProxy< Type > operator->() const
const FunctionProtoType * T
Declaration of a template type parameter.
bool hasQualifiers() const
Determines whether this type has any qualifiers.
#define bool
Definition: stdbool.h:31
Represents the type decltype(expr) (C++11).
Definition: Type.h:3854
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:592
unsigned getCVRQualifiers() const
Retrieve the const/volatile/restrict qualifiers.
CanProxy< U > getAs() const
Try to convert the given canonical type to a specific structural type.
A unary type transform, which is a type constructed from another.
Definition: Type.h:3897
bool isAtLeastAsQualifiedAs(CanQual< T > Other) const
Determines whether this canonical type is at least as qualified as the Other canonical type...
CanProxy< T > operator->() const
Overloaded arrow operator that produces a canonical type proxy.
static SimpleType getSimplifiedValue(::clang::CanQual< T > Val)
Represents a GCC generic vector type.
Definition: Type.h:2916
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2468
ObjCObjectType::qual_iterator qual_iterator
An iterator over the qualifiers on the object type.
Definition: Type.h:5562
The result type of a method or function.
CanQualType operator*() const
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:719
bool isVolatileQualified() const
static StringRef getIdentifier(const Token &Tok)
CanQualType getCanonicalTypeUnqualified() const
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:5728
CanProxy< U > castAs() const
Encodes a location in the source.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4004
Represents typeof(type), a GCC extension.
Definition: Type.h:3827
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:5386
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2934
static QualType getUnderlyingType(const SubRegion *R)
unsigned getLocalCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers local to this particular QualType instan...
Definition: Type.h:781
Represents a canonical, potentially-qualified type.
Definition: CanonicalType.h:66
CanQual< T > Stored
#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)
static QualType getFromOpaquePtr(const void *Ptr)
Definition: Type.h:701
bool isCanonical() const
Definition: Type.h:5764
bool isLocalVolatileQualified() const
Determine whether this particular QualType instance has the "volatile" qualifier set, without looking through typedefs that may have added "volatile" at a different level.
Definition: Type.h:746
bool isMoreQualifiedThan(CanQual< T > Other) const
Determines whether this canonical type is more qualified than the Other canonical type...
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
Dataflow Directional Tag Classes.
Iterator adaptor that turns an iterator over canonical QualTypes into an iterator over CanQualTypes...
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Definition: Type.h:756
Base class of all canonical proxy types, which is responsible for storing the underlying canonical ty...
EnumDecl - Represents an enum.
Definition: Decl.h:3229
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:2504
CanQual()=default
Constructs a NULL canonical type.
Represents a pointer to an Objective C object.
Definition: Type.h:5442
Pointer to a block type.
Definition: Type.h:2387
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:3978
Complex values, per C99 6.2.5p11.
Definition: Type.h:2225
static CanQual< T > getFromOpaquePtr(void *Ptr)
Construct a canonical type from its internal representation.
std::integral_constant< bool, std::is_same< T, ArrayType >::value||std::is_base_of< ArrayType, T >::value > TypeIsArrayType
Definition: Type.h:6304
CanQual< Type > getNonReferenceType() const
If the canonical type is a reference type, returns the type that it refers to; otherwise, returns the type itself.
ExtVectorType - Extended vector type.
Definition: Type.h:2990
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2421
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
const Type * getTypePtrOrNull() const
Definition: Type.h:5724
bool isCanonicalAsParam() const
Definition: Type.h:5768
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
Definition: DeclCXX.h:299
bool isLocalConstQualified() const
Determine whether this particular QualType instance has the "const" qualifier set, without looking through typedefs that may have added "const" at a different level.
Definition: Type.h:726
param_type_iterator param_type_begin() const
param_type_iterator param_type_end() const
bool operator!=(CanQual< T > x, CanQual< U > y)
static bool isCharType(QualType T)
bool isCanonicalAsParam() const
Determines if this canonical type is furthermore canonical as a parameter.
void dump(const char *s) const
Definition: ASTDumper.cpp:2660
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3083
static QualType getParamType(Sema &SemaRef, ArrayRef< ResultCandidate > Candidates, unsigned N)
Get the type of the Nth parameter from a given set of overload candidates.