CanonicalType.h revision 4fb86f8c4585e53c21c847ad3de9e3b2de123cd9
150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//                     The LLVM Compiler Infrastructure
450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// This file is distributed under the University of Illinois Open Source
650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// License. See LICENSE.TXT for details.
750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//===----------------------------------------------------------------------===//
950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
1050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//  This file defines the CanQual class template, which provides access to
1150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//  canonical types.
1250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
1350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//===----------------------------------------------------------------------===//
1450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
1550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
1650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_AST_CANONICAL_TYPE_H
1750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
1850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "clang/AST/Type.h"
1950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "llvm/Support/Casting.h"
2050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "llvm/Support/type_traits.h"
2150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include <iterator>
2250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T> class CanProxy;
2650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T> struct CanProxyAdaptor;
2750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical, qualified type template
3050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
3350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
3450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanQual template is a lightweight smart pointer that provides access
3550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to the canonical representation of a type, where all typedefs and other
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// syntactic sugar has been eliminated. A CanQualType may also have various
3750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// qualifiers (const, volatile, restrict) attached to it.
3850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// The template type parameter @p T is one of the Type classes (PointerType,
4050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
4150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type (or some subclass of that type). The typedef @c CanQualType is just
4250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// a shorthand for @c CanQual<Type>.
4350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// An instance of @c CanQual<T> can be implicitly converted to a
4550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// @c CanQual<U> when T is derived from U, which essentially provides an
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
4850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// be implicitly converted to a QualType, but the reverse operation requires
4950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// a call to ASTContext::getCanonicalType().
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
5250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T = Type>
5350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanQual {
541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The actual, canonical type.
5550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  QualType Stored;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
5850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Constructs a NULL canonical type.
5950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual() : Stored() { }
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Converting constructor that permits implicit upcasting of
6250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// canonical type pointers.
6350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U>
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CanQual(const CanQual<U>& Other,
6550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor          typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the underlying type pointer, which refers to a
6850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// canonical type.
691ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  ///
701ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// The underlying pointer must not be NULL.
71f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
721ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor
731ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// \brief Retrieve the underlying type pointer, which refers to a
741ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// canonical type, or NULL.
751ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  ///
76f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtrOrNull() const {
771ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor    return cast_or_null<T>(Stored.getTypePtrOrNull());
781ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  }
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to a qualified type.
8150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator QualType() const { return Stored; }
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor  /// \brief Implicit conversion to bool.
84cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor  operator bool() const { return !isNull(); }
85cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor
86e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  bool isNull() const {
87e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.isNull();
88e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  }
89e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
90f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  SplitQualType split() const { return Stored.split(); }
91f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall
9250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve a canonical type pointer with a different static type,
9350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// upcasting or downcasting as needed.
9450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// The getAs() function is typically used to try to downcast to a
9650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// more specific (canonical) type in the type system. For example:
9750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
9850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
9950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// void f(CanQual<Type> T) {
10050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
10150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///     // look at Ptr's pointee type
10250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   }
10350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// }
10450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
10550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
10650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \returns A proxy pointer to the same type, but with the specified
10750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// static type (@p U). If the dynamic type is not the specified static type
10850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// or a derived class thereof, a NULL canonical type.
10950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U> CanProxy<U> getAs() const;
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Overloaded arrow operator that produces a canonical type
11250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// proxy.
11350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy<T> operator->() const;
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Retrieve all qualifiers.
116a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
1170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
11850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the const/volatile/restrict qualifiers.
119a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Determines whether this type has any qualifiers
122a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isConstQualified() const {
125a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalConstQualified();
12650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
12750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isVolatileQualified() const {
128a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalVolatileQualified();
12950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
13050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isRestrictQualified() const {
131a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalRestrictQualified();
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
134ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// \brief Determines if this canonical type is furthermore
135ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// canonical as a parameter.  The parameter-canonicalization
136ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// process decays arrays to pointers and drops top-level qualifiers.
137ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  bool isCanonicalAsParam() const {
138ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    return Stored.isCanonicalAsParam();
139ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
140ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
14150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the unqualified form of this type.
14250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> getUnqualifiedType() const;
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
144e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// \brief Retrieves a version of this type with const applied.
145e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// Note that this does not always yield a canonical type.
146e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  QualType withConst() const {
147e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.withConst();
14850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Determines whether this canonical type is more qualified than
15150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isMoreQualifiedThan(CanQual<T> Other) const {
15350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isMoreQualifiedThan(Other.Stored);
15450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Determines whether this canonical type is at least as qualified as
15750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
15950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
16050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief If the canonical type is a reference type, returns the type that
163b890f04174d52e41db19b883244abb17a3254ef1Douglas Gregor  /// it refers to; otherwise, returns the type itself.
16450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<Type> getNonReferenceType() const;
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the internal representation of this canonical type.
16750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Construct a canonical type from its internal representation.
17050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> getFromOpaquePtr(void *Ptr);
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Builds a canonical type from a QualType.
17350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// This routine is inherently unsafe, because it requires the user to
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ensure that the given type is a canonical type with the correct
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // (dynamic) type.
17750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> CreateUnsafe(QualType Other);
178ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
179d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes  void dump() const { Stored.dump(); }
180d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes
181ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
182ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    ID.AddPointer(getAsOpaquePtr());
183ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
18450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
18550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
18750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator==(CanQual<T> x, CanQual<U> y) {
18850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
18950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
19250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator!=(CanQual<T> x, CanQual<U> y) {
19350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
19450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
19750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortypedef CanQual<Type> CanQualType;
19850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
199ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCallinline CanQualType Type::getCanonicalTypeUnqualified() const {
200ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
201ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall}
202ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
2039d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlssoninline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
2049d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson                                           CanQualType T) {
2059d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson  DB << static_cast<QualType>(T);
2069d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson  return DB;
2079d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson}
2089d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson
20950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
21050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Internal proxy classes used by canonical types
21150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
21450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQualType Accessor() const {                                           \
21550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorreturn CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
21650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
21750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
21850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
21950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorType Accessor() const { return this->getTypePtr()->Accessor(); }
22050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
22150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Base class of all canonical proxy types, which is responsible for
22250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// storing the underlying canonical type and providing basic conversions.
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
22450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxyBase {
22550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorprotected:
22650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Stored;
2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
22950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the pointer to the underlying Type
230f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtr() const { return Stored.getTypePtr(); }
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the underlying pointer.
23350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
23450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// Also provides the ability to use canonical type proxies in a Boolean
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // context,e.g.,
23650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
23750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
23850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
2391ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Try to convert the given canonical type to a specific structural
24250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// type.
2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  template<typename U> CanProxy<U> getAs() const {
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return this->Stored.template getAs<U>();
24550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Type predicates
25050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
25150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
25250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
25350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
25450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
25550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
25650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
25750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
25850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
25950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
26050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
2612ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
26250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
26350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
26450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
26550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
26650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
26750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
26850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
26950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
27050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
27150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
27250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
27350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
27450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
27550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
27650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
27750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
278fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
27950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
28050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
28150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
28250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
28350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
284f4c46193637631fc993d926ff31c7cb18c090d21Sebastian Redl  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
28550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
28650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
287f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
288f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
289f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
2908eee119bf4f1693dde17b8552c1f9f81bf2b681eDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
29150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
29250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
29350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
29450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
29550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
29650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
29750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the proxy-adaptor type.
29850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
29950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// This arrow operator is used when CanProxyAdaptor has been specialized
30050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// for the given type T. In that case, we reference members of the
30150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
30250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// by the arrow operator in the primary CanProxyAdaptor template.
30350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  const CanProxyAdaptor<T> *operator->() const {
30450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return static_cast<const CanProxyAdaptor<T> *>(this);
30550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
30650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
30750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
30850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Replacable canonical proxy adaptor class that provides the link
30950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// between a canonical type and the accessors of the type.
31050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
31150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxyAdaptor is a replaceable class template that is instantiated
31250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// as part of each canonical proxy type. The primary template merely provides
31350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// redirection to the underlying type (T), e.g., @c PointerType. One can
31450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// provide specializations of this class template for each underlying type
31550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// that provide accessors returning canonical types (@c CanQualType) rather
31650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// than the more typical @c QualType, to propagate the notion of "canonical"
31750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// through the system.
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
31950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor : CanProxyBase<T> { };
32050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
32150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Canonical proxy type returned when retrieving the members of a
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// canonical type or as the result of the @c CanQual<T>::getAs member
32350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// function.
32450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
32550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxy type mainly exists as a proxy through which operator-> will
3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
32750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type that provides canonical-type access to the fields of the type.
32850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
32950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxy : public CanProxyAdaptor<T> {
33050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
33150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a NULL proxy.
33250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy() { }
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a proxy to the given canonical type.
33550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the stored canonical type.
33850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator CanQual<T>() const { return this->Stored; }
33950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace clang
34250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
34350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace llvm {
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
34650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
34750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to return smart pointer (proxies?).
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
34950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct simplify_type<const ::clang::CanQual<T> > {
350f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  typedef const T *SimpleType;
35150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
3524472fc641ea3069463798fb56a04043c28ea2910Douglas Gregor    return Val.getTypePtr();
35350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
35450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
35650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct simplify_type< ::clang::CanQual<T> >
35750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor: public simplify_type<const ::clang::CanQual<T> > {};
35850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
35950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
36050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
36150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass PointerLikeTypeTraits<clang::CanQual<T> > {
36250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
36350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
36450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return P.getAsOpaquePtr();
36550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
36650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
36750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return clang::CanQual<T>::getFromOpaquePtr(P);
36850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // qualifier information is encoded in the low bits.
37050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  enum { NumLowBitsAvailable = 0 };
37150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace llvm
37450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
37550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
37850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical proxy adaptors for canonical type nodes.
37950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
38250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// into an iterator over CanQualTypes.
38350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
38450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanTypeIterator {
38550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  InputIterator Iter;
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
38850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanQualType    value_type;
38950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef value_type     reference;
39050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanProxy<Type> pointer;
39150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::difference_type
39250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    difference_type;
39350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::iterator_category
39450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    iterator_category;
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator() : Iter() { }
39750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Input iterator
40050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator*() const {
40150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(*Iter);
40250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  pointer operator->() const;
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator++() {
40750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
40850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
40950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator++(int) {
41250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
41350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
41450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
41550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
41850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter == Y.Iter;
41950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
42050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
42150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter != Y.Iter;
42250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Bidirectional iterator
42550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator--() {
42650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
42750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
42850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator--(int) {
43150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
43250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
43350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
43450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Random access iterator
43750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator[](difference_type n) const {
43850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(Iter[n]);
43950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator+=(difference_type n) {
44250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter += n;
44350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
44450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator-=(difference_type n) {
44750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter -= n;
44850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
44950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
45250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
45450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
45550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
45750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
45950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
46250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X -= n;
46350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
46450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend difference_type operator-(const CanTypeIterator &X,
46750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                   const CanTypeIterator &Y) {
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return X - Y;
46950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
47050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
47450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
47550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
47950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<BlockPointerType>
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<BlockPointerType> {
48550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
48950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
49050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
49350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<LValueReferenceType>
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<LValueReferenceType> {
49650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
49950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<RValueReferenceType>
5011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<RValueReferenceType> {
50250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
50350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
50450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<MemberPointerType>
5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<MemberPointerType> {
50850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
50950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
51050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
51250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
51350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
51450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
51650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
51850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
51950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
52050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ConstantArrayType>
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ConstantArrayType> {
52350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
52550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
52750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
52850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
52950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
53050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<IncompleteArrayType>
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<IncompleteArrayType> {
53350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
53550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
53750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<VariableArrayType>
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<VariableArrayType> {
54250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
54450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5450953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
54650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
54750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
54850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
54950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
55050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
55150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
55250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedArrayType>
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedArrayType> {
55550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
55650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
55750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
55850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
55950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
56050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
56150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
56250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedExtVectorType>
5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedExtVectorType> {
56550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
56650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
56850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
57150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
57250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
57350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
57450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
57550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
57650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
57750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
57850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
57950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
58050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
58150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
58250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
58350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
58450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
585264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
58650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
58750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
58850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionNoProtoType>
5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionNoProtoType> {
59150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
592264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
59350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionProtoType>
5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionProtoType> {
59850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
599264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
6007177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
60150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQualType getArgType(unsigned i) const {
60250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
60350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
60650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
60950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    arg_type_iterator;
6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_begin() const {
61250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
61350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
61450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
61550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_end() const {
61650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_end());
61750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
6181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Note: canonical function types never have exception specifications
62050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
62350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
62450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
62550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
62650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
62750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
62850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
62950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
63050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
63150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
63250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
63350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
63450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
63550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
63650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
63750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
63850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
63950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
64050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
64150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
64250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
64350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
64450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
64750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
64850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
64950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
65050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
6531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<TemplateTypeParmType>
6541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<TemplateTypeParmType> {
65550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
65650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
65750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
6584fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
659efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
66050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
663c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallstruct CanProxyAdaptor<ObjCObjectType>
664c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  : public CanProxyBase<ObjCObjectType> {
665c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
666c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
667c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                                      getInterface)
668c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
669c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
670c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
671c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
672c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
673c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
674c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
675c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
676c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
677c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
678c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall};
679c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
680c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCalltemplate<>
6811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ObjCObjectPointerType>
6821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ObjCObjectPointerType> {
68350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
6841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
68550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getInterfaceType)
68650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
68750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
68850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
68950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
69250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
69350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
69450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
69550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
69650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
69950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Method and function definitions
70050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
70150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
70250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<T> CanQual<T>::getUnqualifiedType() const {
703a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
70450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
70550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
70650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
70750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<Type> CanQual<T>::getNonReferenceType() const {
70850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
70950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return RefType->getPointeeType();
71050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  else
71150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
71250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
71350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
71450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
71550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
71650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
717f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  Result.Stored = QualType::getFromOpaquePtr(Ptr);
718f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
719f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          Result.Stored.isCanonical()) && "Type is not canonical!");
72050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
72150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
72250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
72450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
725467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
72650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
72750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor         "Dynamic type does not meet the static type's requires");
72850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
72950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  Result.Stored = Other;
73050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
73150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
73250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
7341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename U>
73550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<U> CanQual<T>::getAs() const {
73650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (Stored.isNull())
73750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanProxy<U>();
7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (isa<U>(Stored.getTypePtr()))
74050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQual<U>::CreateUnsafe(Stored);
7411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<U>();
74350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
74450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
74550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
74650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<T> CanQual<T>::operator->() const {
74750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<T>(*this);
74850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
75050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
7511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptypename CanTypeIterator<InputIterator>::pointer
75250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanTypeIterator<InputIterator>::operator->() const {
75350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<Type>(*this);
75450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
75650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
75750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
75850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
75950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
760