CanonicalType.h revision 4472fc641ea3069463798fb56a04043c28ea2910
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.
711ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  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  ///
761ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  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
9050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve a canonical type pointer with a different static type,
9150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// upcasting or downcasting as needed.
9250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// The getAs() function is typically used to try to downcast to a
9450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// more specific (canonical) type in the type system. For example:
9550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
9650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
9750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// void f(CanQual<Type> T) {
9850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
9950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///     // look at Ptr's pointee type
10050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   }
10150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// }
10250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
10350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
10450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \returns A proxy pointer to the same type, but with the specified
10550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// static type (@p U). If the dynamic type is not the specified static type
10650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// or a derived class thereof, a NULL canonical type.
10750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U> CanProxy<U> getAs() const;
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Overloaded arrow operator that produces a canonical type
11050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// proxy.
11150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy<T> operator->() const;
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Retrieve all qualifiers.
114a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
1150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
11650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the const/volatile/restrict qualifiers.
117a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Determines whether this type has any qualifiers
120a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isConstQualified() const {
123a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalConstQualified();
12450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
12550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isVolatileQualified() const {
126a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalVolatileQualified();
12750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
12850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isRestrictQualified() const {
129a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalRestrictQualified();
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
132ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// \brief Determines if this canonical type is furthermore
133ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// canonical as a parameter.  The parameter-canonicalization
134ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// process decays arrays to pointers and drops top-level qualifiers.
135ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  bool isCanonicalAsParam() const {
136ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    return Stored.isCanonicalAsParam();
137ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
138ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
13950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the unqualified form of this type.
14050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> getUnqualifiedType() const;
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// \brief Retrieves a version of this type with const applied.
143e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// Note that this does not always yield a canonical type.
144e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  QualType withConst() const {
145e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.withConst();
14650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Determines whether this canonical type is more qualified than
14950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isMoreQualifiedThan(CanQual<T> Other) const {
15150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isMoreQualifiedThan(Other.Stored);
15250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Determines whether this canonical type is at least as qualified as
15550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
15750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
15850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief If the canonical type is a reference type, returns the type that
161b890f04174d52e41db19b883244abb17a3254ef1Douglas Gregor  /// it refers to; otherwise, returns the type itself.
16250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<Type> getNonReferenceType() const;
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the internal representation of this canonical type.
16550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Construct a canonical type from its internal representation.
16850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> getFromOpaquePtr(void *Ptr);
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Builds a canonical type from a QualType.
17150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// This routine is inherently unsafe, because it requires the user to
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ensure that the given type is a canonical type with the correct
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // (dynamic) type.
17550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> CreateUnsafe(QualType Other);
176ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
177d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes  void dump() const { Stored.dump(); }
178d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes
179ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
180ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    ID.AddPointer(getAsOpaquePtr());
181ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
18250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
18350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
18550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator==(CanQual<T> x, CanQual<U> y) {
18650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
18750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
18850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
19050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator!=(CanQual<T> x, CanQual<U> y) {
19150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
19250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
19550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortypedef CanQual<Type> CanQualType;
19650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
197ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCallinline CanQualType Type::getCanonicalTypeUnqualified() const {
198ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
199ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall}
200ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
2019d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlssoninline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
2029d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson                                           CanQualType T) {
2039d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson  DB << static_cast<QualType>(T);
2049d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson  return DB;
2059d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson}
2069d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson
20750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
20850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Internal proxy classes used by canonical types
20950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
21250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQualType Accessor() const {                                           \
21350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorreturn CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
21450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
21550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
21650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
21750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorType Accessor() const { return this->getTypePtr()->Accessor(); }
21850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
21950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Base class of all canonical proxy types, which is responsible for
22050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// storing the underlying canonical type and providing basic conversions.
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
22250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxyBase {
22350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorprotected:
22450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Stored;
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
22750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the pointer to the underlying Type
22850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  T* getTypePtr() const { return Stored.getTypePtr(); }
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the underlying pointer.
23150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
23250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// Also provides the ability to use canonical type proxies in a Boolean
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // context,e.g.,
23450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
23550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
23650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
2371ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Try to convert the given canonical type to a specific structural
24050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// type.
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  template<typename U> CanProxy<U> getAs() const {
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return this->Stored.template getAs<U>();
24350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Type predicates
24850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
24950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
25050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
25150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
25250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
25350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
25450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
25550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
25650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
25750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
25850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
2592ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
26050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
26150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
26250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
26350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
26450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
26550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
26650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
26750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
26850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
26950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
27050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
27150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
27250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
27350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
27450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
27550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
276fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
27750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
27850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
27950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
28050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
28150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
282f4c46193637631fc993d926ff31c7cb18c090d21Sebastian Redl  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
28350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
28450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
285f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
286f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
287f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
2888eee119bf4f1693dde17b8552c1f9f81bf2b681eDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
28950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
29050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
29150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
29250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
29350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
29450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
29550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the proxy-adaptor type.
29650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
29750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// This arrow operator is used when CanProxyAdaptor has been specialized
29850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// for the given type T. In that case, we reference members of the
29950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
30050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// by the arrow operator in the primary CanProxyAdaptor template.
30150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  const CanProxyAdaptor<T> *operator->() const {
30250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return static_cast<const CanProxyAdaptor<T> *>(this);
30350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
30450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
30550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
30650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Replacable canonical proxy adaptor class that provides the link
30750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// between a canonical type and the accessors of the type.
30850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
30950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxyAdaptor is a replaceable class template that is instantiated
31050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// as part of each canonical proxy type. The primary template merely provides
31150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// redirection to the underlying type (T), e.g., @c PointerType. One can
31250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// provide specializations of this class template for each underlying type
31350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// that provide accessors returning canonical types (@c CanQualType) rather
31450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// than the more typical @c QualType, to propagate the notion of "canonical"
31550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// through the system.
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
31750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor : CanProxyBase<T> { };
31850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
31950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Canonical proxy type returned when retrieving the members of a
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// canonical type or as the result of the @c CanQual<T>::getAs member
32150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// function.
32250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
32350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxy type mainly exists as a proxy through which operator-> will
3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
32550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type that provides canonical-type access to the fields of the type.
32650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
32750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxy : public CanProxyAdaptor<T> {
32850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
32950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a NULL proxy.
33050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy() { }
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a proxy to the given canonical type.
33350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the stored canonical type.
33650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator CanQual<T>() const { return this->Stored; }
33750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace clang
34050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
34150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace llvm {
3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
34450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
34550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to return smart pointer (proxies?).
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
34750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct simplify_type<const ::clang::CanQual<T> > {
34850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef T* SimpleType;
34950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
3504472fc641ea3069463798fb56a04043c28ea2910Douglas Gregor    return Val.getTypePtr();
35150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
35250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
35450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct simplify_type< ::clang::CanQual<T> >
35550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor: public simplify_type<const ::clang::CanQual<T> > {};
35650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
35750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
35850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
35950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass PointerLikeTypeTraits<clang::CanQual<T> > {
36050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
36150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
36250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return P.getAsOpaquePtr();
36350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
36450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
36550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return clang::CanQual<T>::getFromOpaquePtr(P);
36650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3670953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // qualifier information is encoded in the low bits.
36850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  enum { NumLowBitsAvailable = 0 };
36950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace llvm
37250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
37350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
37650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical proxy adaptors for canonical type nodes.
37750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
38050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// into an iterator over CanQualTypes.
38150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
38250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanTypeIterator {
38350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  InputIterator Iter;
3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
38650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanQualType    value_type;
38750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef value_type     reference;
38850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanProxy<Type> pointer;
38950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::difference_type
39050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    difference_type;
39150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::iterator_category
39250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    iterator_category;
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator() : Iter() { }
39550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Input iterator
39850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator*() const {
39950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(*Iter);
40050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  pointer operator->() const;
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator++() {
40550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
40650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
40750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator++(int) {
41050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
41150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
41250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
41350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
41650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter == Y.Iter;
41750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
41850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
41950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter != Y.Iter;
42050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Bidirectional iterator
42350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator--() {
42450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
42550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
42650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator--(int) {
42950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
43050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
43150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
43250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Random access iterator
43550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator[](difference_type n) const {
43650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(Iter[n]);
43750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator+=(difference_type n) {
44050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter += n;
44150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
44250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator-=(difference_type n) {
44550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter -= n;
44650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
44750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
45050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
45250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
45350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
45550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
45750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
46050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X -= n;
46150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
46250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend difference_type operator-(const CanTypeIterator &X,
46550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                   const CanTypeIterator &Y) {
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return X - Y;
46750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
46850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
46950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
47250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
47350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
47750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
47850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<BlockPointerType>
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<BlockPointerType> {
48350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
48750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
48850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
49150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<LValueReferenceType>
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<LValueReferenceType> {
49450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
49750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<RValueReferenceType>
4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<RValueReferenceType> {
50050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
50150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
50250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<MemberPointerType>
5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<MemberPointerType> {
50650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
50750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
50850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
51050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
51150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
51250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
51450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
51650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
51750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
51850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ConstantArrayType>
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ConstantArrayType> {
52150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
52350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5240953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
52550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
52650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
52750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
52850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<IncompleteArrayType>
5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<IncompleteArrayType> {
53150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
53350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5340953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
53550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<VariableArrayType>
5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<VariableArrayType> {
54050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
54250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5430953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
54450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
54550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
54650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
54750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
54850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
54950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
55050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedArrayType>
5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedArrayType> {
55350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
55450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
55550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
55650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
55750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
55850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
55950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
56050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedExtVectorType>
5621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedExtVectorType> {
56350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
56450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
5651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
56650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
56950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
57050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
57150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
57250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
57350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
57450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
57550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
57650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
57750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
57850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
57950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
58050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
58150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
58250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
583264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
58450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
58550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
58650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionNoProtoType>
5881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionNoProtoType> {
58950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
590264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
59150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionProtoType>
5951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionProtoType> {
59650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
597264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
5987177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
59950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQualType getArgType(unsigned i) const {
60050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
60150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
60450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
60750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    arg_type_iterator;
6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_begin() const {
61050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
61150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
61250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
61350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_end() const {
61450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_end());
61550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
6161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Note: canonical function types never have exception specifications
61850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
62150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
62250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
62350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
62450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
62550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
62650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
62750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
62850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
62950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
63050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
63150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
63250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
63350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
63450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
63550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
63650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
63750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
63850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
63950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
64050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
64150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace)
64350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
64650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
64750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
64850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
64950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<TemplateTypeParmType>
6531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<TemplateTypeParmType> {
65450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
65550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
65650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
657efed5c832de630715dd42211dd3b2aab5dd97a1bDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
65850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
661c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallstruct CanProxyAdaptor<ObjCObjectType>
662c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  : public CanProxyBase<ObjCObjectType> {
663c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
664c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
665c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                                      getInterface)
666c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
667c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
668c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
669c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
670c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
671c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
672c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
673c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
674c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
675c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
676c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall};
677c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
678c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCalltemplate<>
6791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ObjCObjectPointerType>
6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ObjCObjectPointerType> {
68150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
6821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
68350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getInterfaceType)
68450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
68550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
68650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
68750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
6881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
69050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
69150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
69250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
69350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
69450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
69750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Method and function definitions
69850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
69950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
70050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<T> CanQual<T>::getUnqualifiedType() const {
701a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
70250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
70350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
70450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
70550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<Type> CanQual<T>::getNonReferenceType() const {
70650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
70750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return RefType->getPointeeType();
70850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  else
70950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
71050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
71150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
71250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
71350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
71450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
715f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  Result.Stored = QualType::getFromOpaquePtr(Ptr);
716f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
717f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          Result.Stored.isCanonical()) && "Type is not canonical!");
71850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
71950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
72050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
72250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
723467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
72450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
72550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor         "Dynamic type does not meet the static type's requires");
72650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
72750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  Result.Stored = Other;
72850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
72950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
73050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename U>
73350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<U> CanQual<T>::getAs() const {
73450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (Stored.isNull())
73550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanProxy<U>();
7361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (isa<U>(Stored.getTypePtr()))
73850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQual<U>::CreateUnsafe(Stored);
7391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<U>();
74150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
74250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
74350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
74450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<T> CanQual<T>::operator->() const {
74550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<T>(*this);
74650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptypename CanTypeIterator<InputIterator>::pointer
75050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanTypeIterator<InputIterator>::operator->() const {
75150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<Type>(*this);
75250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
75450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
75550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
75650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
75750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
758