clang  9.0.0svn
CanonicalType.h
Go to the documentation of this file.
1 //===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the CanQual class template, which provides access to
10 // canonical types.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_CANONICALTYPE_H
15 #define LLVM_CLANG_AST_CANONICALTYPE_H
16 
17 #include "clang/AST/Type.h"
18 #include "clang/Basic/Diagnostic.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/FoldingSet.h"
22 #include "llvm/ADT/iterator.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/PointerLikeTypeTraits.h"
25 #include <cassert>
26 #include <iterator>
27 #include <type_traits>
28 
29 namespace clang {
30 
31 template<typename T> class CanProxy;
32 template<typename T> struct CanProxyAdaptor;
33 class CXXRecordDecl;
34 class EnumDecl;
35 class Expr;
36 class IdentifierInfo;
37 class ObjCInterfaceDecl;
38 class RecordDecl;
39 class TagDecl;
41 
42 //----------------------------------------------------------------------------//
43 // Canonical, qualified type template
44 //----------------------------------------------------------------------------//
45 
46 /// Represents a canonical, potentially-qualified type.
47 ///
48 /// The CanQual template is a lightweight smart pointer that provides access
49 /// to the canonical representation of a type, where all typedefs and other
50 /// syntactic sugar has been eliminated. A CanQualType may also have various
51 /// qualifiers (const, volatile, restrict) attached to it.
52 ///
53 /// The template type parameter @p T is one of the Type classes (PointerType,
54 /// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
55 /// type (or some subclass of that type). The typedef @c CanQualType is just
56 /// a shorthand for @c CanQual<Type>.
57 ///
58 /// An instance of @c CanQual<T> can be implicitly converted to a
59 /// @c CanQual<U> when T is derived from U, which essentially provides an
60 /// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
61 /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
62 /// be implicitly converted to a QualType, but the reverse operation requires
63 /// a call to ASTContext::getCanonicalType().
64 template<typename T = Type>
65 class CanQual {
66  /// The actual, canonical type.
67  QualType Stored;
68 
69 public:
70  /// Constructs a NULL canonical type.
71  CanQual() = default;
72 
73  /// Converting constructor that permits implicit upcasting of
74  /// canonical type pointers.
75  template <typename U>
76  CanQual(const CanQual<U> &Other,
77  typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
78 
79  /// Retrieve the underlying type pointer, which refers to a
80  /// canonical type.
81  ///
82  /// The underlying pointer must not be nullptr.
83  const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
84 
85  /// Retrieve the underlying type pointer, which refers to a
86  /// canonical type, or nullptr.
87  const T *getTypePtrOrNull() const {
88  return cast_or_null<T>(Stored.getTypePtrOrNull());
89  }
90 
91  /// Implicit conversion to a qualified type.
92  operator QualType() const { return Stored; }
93 
94  /// Implicit conversion to bool.
95  explicit operator bool() const { return !isNull(); }
96 
97  bool isNull() const {
98  return Stored.isNull();
99  }
100 
101  SplitQualType split() const { return Stored.split(); }
102 
103  /// Retrieve a canonical type pointer with a different static type,
104  /// upcasting or downcasting as needed.
105  ///
106  /// The getAs() function is typically used to try to downcast to a
107  /// more specific (canonical) type in the type system. For example:
108  ///
109  /// @code
110  /// void f(CanQual<Type> T) {
111  /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
112  /// // look at Ptr's pointee type
113  /// }
114  /// }
115  /// @endcode
116  ///
117  /// \returns A proxy pointer to the same type, but with the specified
118  /// static type (@p U). If the dynamic type is not the specified static type
119  /// or a derived class thereof, a NULL canonical type.
120  template<typename U> CanProxy<U> getAs() const;
121 
122  template<typename U> CanProxy<U> castAs() const;
123 
124  /// Overloaded arrow operator that produces a canonical type
125  /// proxy.
126  CanProxy<T> operator->() const;
127 
128  /// Retrieve all qualifiers.
129  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
130 
131  /// Retrieve the const/volatile/restrict qualifiers.
132  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
133 
134  /// Determines whether this type has any qualifiers
135  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
136 
137  bool isConstQualified() const {
138  return Stored.isLocalConstQualified();
139  }
140 
141  bool isVolatileQualified() const {
142  return Stored.isLocalVolatileQualified();
143  }
144 
145  bool isRestrictQualified() const {
146  return Stored.isLocalRestrictQualified();
147  }
148 
149  /// Determines if this canonical type is furthermore
150  /// canonical as a parameter. The parameter-canonicalization
151  /// process decays arrays to pointers and drops top-level qualifiers.
152  bool isCanonicalAsParam() const {
153  return Stored.isCanonicalAsParam();
154  }
155 
156  /// Retrieve the unqualified form of this type.
158 
159  /// Retrieves a version of this type with const applied.
160  /// Note that this does not always yield a canonical type.
161  QualType withConst() const {
162  return Stored.withConst();
163  }
164 
165  /// Determines whether this canonical type is more qualified than
166  /// the @p Other canonical type.
167  bool isMoreQualifiedThan(CanQual<T> Other) const {
168  return Stored.isMoreQualifiedThan(Other.Stored);
169  }
170 
171  /// Determines whether this canonical type is at least as qualified as
172  /// the @p Other canonical type.
173  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
174  return Stored.isAtLeastAsQualifiedAs(Other.Stored);
175  }
176 
177  /// If the canonical type is a reference type, returns the type that
178  /// it refers to; otherwise, returns the type itself.
180 
181  /// Retrieve the internal representation of this canonical type.
182  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
183 
184  /// Construct a canonical type from its internal representation.
185  static CanQual<T> getFromOpaquePtr(void *Ptr);
186 
187  /// Builds a canonical type from a QualType.
188  ///
189  /// This routine is inherently unsafe, because it requires the user to
190  /// ensure that the given type is a canonical type with the correct
191  // (dynamic) type.
192  static CanQual<T> CreateUnsafe(QualType Other);
193 
194  void dump() const { Stored.dump(); }
195 
196  void Profile(llvm::FoldingSetNodeID &ID) const {
197  ID.AddPointer(getAsOpaquePtr());
198  }
199 };
200 
201 template<typename T, typename U>
202 inline bool operator==(CanQual<T> x, CanQual<U> y) {
203  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
204 }
205 
206 template<typename T, typename U>
207 inline bool operator!=(CanQual<T> x, CanQual<U> y) {
208  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
209 }
210 
211 /// Represents a canonical, potentially-qualified type.
213 
215  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
216 }
217 
219  CanQualType T) {
220  DB << static_cast<QualType>(T);
221  return DB;
222 }
223 
224 //----------------------------------------------------------------------------//
225 // Internal proxy classes used by canonical types
226 //----------------------------------------------------------------------------//
227 
228 #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \
229 CanQualType Accessor() const { \
230 return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
231 }
232 
233 #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
234 Type Accessor() const { return this->getTypePtr()->Accessor(); }
235 
236 /// Base class of all canonical proxy types, which is responsible for
237 /// storing the underlying canonical type and providing basic conversions.
238 template<typename T>
240 protected:
242 
243 public:
244  /// Retrieve the pointer to the underlying Type
245  const T *getTypePtr() const { return Stored.getTypePtr(); }
246 
247  /// Implicit conversion to the underlying pointer.
248  ///
249  /// Also provides the ability to use canonical type proxies in a Boolean
250  // context,e.g.,
251  /// @code
252  /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
253  /// @endcode
254  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
255 
256  /// Try to convert the given canonical type to a specific structural
257  /// type.
258  template<typename U> CanProxy<U> getAs() const {
259  return this->Stored.template getAs<U>();
260  }
261 
263 
264  // Type predicates
265  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
266  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
267  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
268  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
269  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
270  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
273  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
274  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
275  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
276  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
277  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
278  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
279  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
280  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
281  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
282  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
283  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
284  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
285  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
286  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
287  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
288  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
289  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
290  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
291  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
292  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
293  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
294  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
295  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
296  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
297  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
298  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
299  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
300  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
301  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
302  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
303  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
304  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
305  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
306  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
307  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
308  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
309  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
310  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
311  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
312  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
314 
315  /// Retrieve the proxy-adaptor type.
316  ///
317  /// This arrow operator is used when CanProxyAdaptor has been specialized
318  /// for the given type T. In that case, we reference members of the
319  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
320  /// by the arrow operator in the primary CanProxyAdaptor template.
321  const CanProxyAdaptor<T> *operator->() const {
322  return static_cast<const CanProxyAdaptor<T> *>(this);
323  }
324 };
325 
326 /// Replaceable canonical proxy adaptor class that provides the link
327 /// between a canonical type and the accessors of the type.
328 ///
329 /// The CanProxyAdaptor is a replaceable class template that is instantiated
330 /// as part of each canonical proxy type. The primary template merely provides
331 /// redirection to the underlying type (T), e.g., @c PointerType. One can
332 /// provide specializations of this class template for each underlying type
333 /// that provide accessors returning canonical types (@c CanQualType) rather
334 /// than the more typical @c QualType, to propagate the notion of "canonical"
335 /// through the system.
336 template<typename T>
337 struct CanProxyAdaptor : CanProxyBase<T> {};
338 
339 /// Canonical proxy type returned when retrieving the members of a
340 /// canonical type or as the result of the @c CanQual<T>::getAs member
341 /// function.
342 ///
343 /// The CanProxy type mainly exists as a proxy through which operator-> will
344 /// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
345 /// type that provides canonical-type access to the fields of the type.
346 template<typename T>
347 class CanProxy : public CanProxyAdaptor<T> {
348 public:
349  /// Build a NULL proxy.
350  CanProxy() = default;
351 
352  /// Build a proxy to the given canonical type.
353  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
354 
355  /// Implicit conversion to the stored canonical type.
356  operator CanQual<T>() const { return this->Stored; }
357 };
358 
359 } // namespace clang
360 
361 namespace llvm {
362 
363 /// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
364 /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
365 /// to return smart pointer (proxies?).
366 template<typename T>
367 struct simplify_type< ::clang::CanQual<T>> {
368  using SimpleType = const T *;
369 
371  return Val.getTypePtr();
372  }
373 };
374 
375 // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
376 template<typename T>
379  return P.getAsOpaquePtr();
380  }
381 
384  }
385 
386  // qualifier information is encoded in the low bits.
387  enum { NumLowBitsAvailable = 0 };
388 };
389 
390 } // namespace llvm
391 
392 namespace clang {
393 
394 //----------------------------------------------------------------------------//
395 // Canonical proxy adaptors for canonical type nodes.
396 //----------------------------------------------------------------------------//
397 
398 /// Iterator adaptor that turns an iterator over canonical QualTypes
399 /// into an iterator over CanQualTypes.
400 template <typename InputIterator>
402  : llvm::iterator_adaptor_base<
403  CanTypeIterator<InputIterator>, InputIterator,
404  typename std::iterator_traits<InputIterator>::iterator_category,
405  CanQualType,
406  typename std::iterator_traits<InputIterator>::difference_type,
407  CanProxy<Type>, CanQualType> {
408  CanTypeIterator() = default;
409  explicit CanTypeIterator(InputIterator Iter)
410  : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
411 
412  CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
413  CanProxy<Type> operator->() const;
414 };
415 
416 template<>
417 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
418  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
419 };
420 
421 template<>
422 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
423  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
424 };
425 
426 template<>
428  : public CanProxyBase<BlockPointerType> {
429  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
430 };
431 
432 template<>
433 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
434  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
435 };
436 
437 template<>
439  : public CanProxyBase<LValueReferenceType> {
440  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
441 };
442 
443 template<>
445  : public CanProxyBase<RValueReferenceType> {
446  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
447 };
448 
449 template<>
451  : public CanProxyBase<MemberPointerType> {
452  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
453  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
454 };
455 
456 // CanProxyAdaptors for arrays are intentionally unimplemented because
457 // they are not safe.
458 template<> struct CanProxyAdaptor<ArrayType>;
459 template<> struct CanProxyAdaptor<ConstantArrayType>;
460 template<> struct CanProxyAdaptor<IncompleteArrayType>;
461 template<> struct CanProxyAdaptor<VariableArrayType>;
462 template<> struct CanProxyAdaptor<DependentSizedArrayType>;
463 
464 template<>
466  : public CanProxyBase<DependentSizedExtVectorType> {
467  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
468  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
470 };
471 
472 template<>
473 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
474  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
475  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
476 };
477 
478 template<>
479 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
480  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
481  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
482 };
483 
484 template<>
485 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
486  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
488 };
489 
490 template<>
492  : public CanProxyBase<FunctionNoProtoType> {
493  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
495 };
496 
497 template<>
499  : public CanProxyBase<FunctionProtoType> {
500  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
502  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
503  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
505  ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
506 
507  CanQualType getParamType(unsigned i) const {
509  }
510 
511  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
513 
514  using param_type_iterator =
516 
518  return param_type_iterator(this->getTypePtr()->param_type_begin());
519  }
520 
522  return param_type_iterator(this->getTypePtr()->param_type_end());
523  }
524 
525  // Note: canonical function types never have exception specifications
526 };
527 
528 template<>
529 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
531 };
532 
533 template<>
534 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
535  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
537 };
538 
539 template <>
541  : public CanProxyBase<UnaryTransformType> {
545 };
546 
547 template<>
548 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
550  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
551 };
552 
553 template<>
554 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
556  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
557  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
558 };
559 
560 template<>
561 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
563  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
564 };
565 
566 template<>
568  : public CanProxyBase<TemplateTypeParmType> {
569  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
570  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
571  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
574 };
575 
576 template<>
578  : public CanProxyBase<ObjCObjectType> {
581  getInterface)
582  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
583  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
584  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
585  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
586 
587  using qual_iterator = ObjCObjectPointerType::qual_iterator;
588 
589  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
590  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
591  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
592  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
593 };
594 
595 template<>
597  : public CanProxyBase<ObjCObjectPointerType> {
598  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
600  getInterfaceType)
601  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
602  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
603  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
604  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
605 
606  using qual_iterator = ObjCObjectPointerType::qual_iterator;
607 
608  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
609  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
610  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
611  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
612 };
613 
614 //----------------------------------------------------------------------------//
615 // Method and function definitions
616 //----------------------------------------------------------------------------//
617 template<typename T>
619  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
620 }
621 
622 template<typename T>
624  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
625  return RefType->getPointeeType();
626  else
627  return *this;
628 }
629 
630 template<typename T>
633  Result.Stored = QualType::getFromOpaquePtr(Ptr);
634  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
635  Result.Stored.isCanonical()) && "Type is not canonical!");
636  return Result;
637 }
638 
639 template<typename T>
641  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
642  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
643  "Dynamic type does not meet the static type's requires");
645  Result.Stored = Other;
646  return Result;
647 }
648 
649 template<typename T>
650 template<typename U>
652  static_assert(!TypeIsArrayType<T>::value,
653  "ArrayType cannot be used with getAs!");
654 
655  if (Stored.isNull())
656  return CanProxy<U>();
657 
658  if (isa<U>(Stored.getTypePtr()))
659  return CanQual<U>::CreateUnsafe(Stored);
660 
661  return CanProxy<U>();
662 }
663 
664 template<typename T>
665 template<typename U>
667  static_assert(!TypeIsArrayType<U>::value,
668  "ArrayType cannot be used with castAs!");
669 
670  assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
671  return CanQual<U>::CreateUnsafe(Stored);
672 }
673 
674 template<typename T>
676  return CanProxy<T>(*this);
677 }
678 
679 template <typename InputIterator>
681  return CanProxy<Type>(*this);
682 }
683 
684 } // namespace clang
685 
686 #endif // LLVM_CLANG_AST_CANONICALTYPE_H
static CanQual< T > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
Replaceable canonical proxy adaptor class that provides the link between a canonical type and the acc...
Definition: CanonicalType.h:32
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:2549
A (possibly-)qualified type.
Definition: Type.h:639
bool isNull() const
Definition: CanonicalType.h:97
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:29
bool isConstQualified() const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3367
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:335
The base class of the type hierarchy.
Definition: Type.h:1414
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:31
QualType withConst() const
Definition: Type.h:811
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:137
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:87
Represents a struct/union/class.
Definition: Decl.h:3592
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:721
Represents a class type in Objective C.
Definition: Type.h:5550
Definition: Format.h:2222
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:6238
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:6103
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2750
bool isRestrictQualified() const
Defines the Diagnostic-related interfaces.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6084
static bool isBooleanType(QualType Ty)
void * getAsOpaquePtr() const
Definition: Type.h:684
Represents an ObjC class declaration.
Definition: DeclObjC.h:1171
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:83
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3140
Represents a K&R-style &#39;int foo()&#39; function, which has no information available about its arguments...
Definition: Type.h:3662
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1044
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3699
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:6228
This represents one expression.
Definition: Expr.h:108
CanProxy< Type > operator->() const
Declaration of a template type parameter.
bool hasQualifiers() const
Determines whether this type has any qualifiers.
#define bool
Definition: stdbool.h:15
Represents the type decltype(expr) (C++11).
Definition: Type.h:4258
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:578
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:4301
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:3180
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2732
ObjCObjectType::qual_iterator qual_iterator
An iterator over the qualifiers on the object type.
Definition: Type.h:5926
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:704
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:6092
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:4408
Represents typeof(type), a GCC extension.
Definition: Type.h:4231
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:5750
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3063
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:766
Represents a canonical, potentially-qualified type.
Definition: CanonicalType.h:65
CanQual< T > Stored
#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)
static QualType getFromOpaquePtr(const void *Ptr)
Definition: Type.h:686
bool isCanonical() const
Definition: Type.h:6128
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:731
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:741
Base class of all canonical proxy types, which is responsible for storing the underlying canonical ty...
Represents an enum.
Definition: Decl.h:3325
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:2768
CanQual()=default
Constructs a NULL canonical type.
Represents a pointer to an Objective C object.
Definition: Type.h:5806
Pointer to a block type.
Definition: Type.h:2651
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4382
Complex values, per C99 6.2.5p11.
Definition: Type.h:2489
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:6765
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:3299
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2685
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
const Type * getTypePtrOrNull() const
Definition: Type.h:6088
bool isCanonicalAsParam() const
Definition: Type.h:6132
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:711
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:200
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3478
static QualType getParamType(Sema &SemaRef, ArrayRef< ResultCandidate > Candidates, unsigned N)
Get the type of the Nth parameter from a given set of overload candidates.