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