CanonicalType.h revision 264ba48dc98f3f843935a485d5b086f7e0fdc4f1
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.
6950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); }
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to a qualified type.
7250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator QualType() const { return Stored; }
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor  /// \brief Implicit conversion to bool.
75cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor  operator bool() const { return !isNull(); }
76cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor
77e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  bool isNull() const {
78e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.isNull();
79e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  }
80e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
8150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve a canonical type pointer with a different static type,
8250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// upcasting or downcasting as needed.
8350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// The getAs() function is typically used to try to downcast to a
8550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// more specific (canonical) type in the type system. For example:
8650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
8750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
8850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// void f(CanQual<Type> T) {
8950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
9050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///     // look at Ptr's pointee type
9150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   }
9250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// }
9350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
9450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
9550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \returns A proxy pointer to the same type, but with the specified
9650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// static type (@p U). If the dynamic type is not the specified static type
9750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// or a derived class thereof, a NULL canonical type.
9850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U> CanProxy<U> getAs() const;
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Overloaded arrow operator that produces a canonical type
10150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// proxy.
10250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy<T> operator->() const;
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Retrieve all qualifiers.
105a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
1060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
10750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the const/volatile/restrict qualifiers.
108a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Determines whether this type has any qualifiers
111a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isConstQualified() const {
114a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalConstQualified();
11550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
11650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isVolatileQualified() const {
117a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalVolatileQualified();
11850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
11950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isRestrictQualified() const {
120a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalRestrictQualified();
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
123ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// \brief Determines if this canonical type is furthermore
124ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// canonical as a parameter.  The parameter-canonicalization
125ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// process decays arrays to pointers and drops top-level qualifiers.
126ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  bool isCanonicalAsParam() const {
127ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    return Stored.isCanonicalAsParam();
128ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
129ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
13050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the unqualified form of this type.
13150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> getUnqualifiedType() const;
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// \brief Retrieves a version of this type with const applied.
134e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// Note that this does not always yield a canonical type.
135e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  QualType withConst() const {
136e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.withConst();
13750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Determines whether this canonical type is more qualified than
14050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
14150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isMoreQualifiedThan(CanQual<T> Other) const {
14250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isMoreQualifiedThan(Other.Stored);
14350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Determines whether this canonical type is at least as qualified as
14650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
14750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
14850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
14950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief If the canonical type is a reference type, returns the type that
152b890f04174d52e41db19b883244abb17a3254ef1Douglas Gregor  /// it refers to; otherwise, returns the type itself.
15350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<Type> getNonReferenceType() const;
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the internal representation of this canonical type.
15650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Construct a canonical type from its internal representation.
15950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> getFromOpaquePtr(void *Ptr);
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Builds a canonical type from a QualType.
16250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// This routine is inherently unsafe, because it requires the user to
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ensure that the given type is a canonical type with the correct
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // (dynamic) type.
16650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> CreateUnsafe(QualType Other);
167ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
168d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes  void dump() const { Stored.dump(); }
169d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes
170ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
171ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    ID.AddPointer(getAsOpaquePtr());
172ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
17350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
17450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
17550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
17650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator==(CanQual<T> x, CanQual<U> y) {
17750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
17850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
17950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
18150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator!=(CanQual<T> x, CanQual<U> y) {
18250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
18350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
18450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
18650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortypedef CanQual<Type> CanQualType;
18750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
188ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCallinline CanQualType Type::getCanonicalTypeUnqualified() const {
189ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
190ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall}
191ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
1929d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlssoninline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1939d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson                                           CanQualType T) {
1949d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson  DB << static_cast<QualType>(T);
1959d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson  return DB;
1969d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson}
1979d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson
19850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
19950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Internal proxy classes used by canonical types
20050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
20350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQualType Accessor() const {                                           \
20450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorreturn CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
20550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
20650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
20750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
20850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorType Accessor() const { return this->getTypePtr()->Accessor(); }
20950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
21050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Base class of all canonical proxy types, which is responsible for
21150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// storing the underlying canonical type and providing basic conversions.
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
21350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxyBase {
21450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorprotected:
21550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Stored;
2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
21850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the pointer to the underlying Type
21950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  T* getTypePtr() const { return Stored.getTypePtr(); }
2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the underlying pointer.
22250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
22350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// Also provides the ability to use canonical type proxies in a Boolean
2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // context,e.g.,
22550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
22650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
22750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
22850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator const T*() const { return this->Stored.getTypePtr(); }
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Try to convert the given canonical type to a specific structural
23150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// type.
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  template<typename U> CanProxy<U> getAs() const {
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return this->Stored.template getAs<U>();
23450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Type predicates
23950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
24050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
24150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
24250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
24350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
24450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
24550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
24650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
24750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
24850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
24950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
25050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
25150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
25250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
25350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
25450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
25550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
25650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
25750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
25850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
25950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
26050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
26150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
26250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
26350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
26450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
26550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
26650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
26750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
26850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
26950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
27050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
27150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
27250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
27350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
27450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
27550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
27650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
27750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
27850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
27950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the proxy-adaptor type.
28050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
28150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// This arrow operator is used when CanProxyAdaptor has been specialized
28250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// for the given type T. In that case, we reference members of the
28350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
28450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// by the arrow operator in the primary CanProxyAdaptor template.
28550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  const CanProxyAdaptor<T> *operator->() const {
28650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return static_cast<const CanProxyAdaptor<T> *>(this);
28750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
28850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
28950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
29050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Replacable canonical proxy adaptor class that provides the link
29150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// between a canonical type and the accessors of the type.
29250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
29350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxyAdaptor is a replaceable class template that is instantiated
29450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// as part of each canonical proxy type. The primary template merely provides
29550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// redirection to the underlying type (T), e.g., @c PointerType. One can
29650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// provide specializations of this class template for each underlying type
29750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// that provide accessors returning canonical types (@c CanQualType) rather
29850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// than the more typical @c QualType, to propagate the notion of "canonical"
29950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// through the system.
3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
30150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor : CanProxyBase<T> { };
30250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
30350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Canonical proxy type returned when retrieving the members of a
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// canonical type or as the result of the @c CanQual<T>::getAs member
30550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// function.
30650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
30750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxy type mainly exists as a proxy through which operator-> will
3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
30950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type that provides canonical-type access to the fields of the type.
31050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
31150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxy : public CanProxyAdaptor<T> {
31250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
31350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a NULL proxy.
31450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy() { }
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a proxy to the given canonical type.
31750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the stored canonical type.
32050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator CanQual<T>() const { return this->Stored; }
32150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace clang
32450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
32550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace llvm {
3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
32850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
32950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to return smart pointer (proxies?).
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
33150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct simplify_type<const ::clang::CanQual<T> > {
33250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef T* SimpleType;
33350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
33450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Val.getTypePtr();
33550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
33650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
33850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct simplify_type< ::clang::CanQual<T> >
33950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor: public simplify_type<const ::clang::CanQual<T> > {};
34050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
34150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
34250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
34350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass PointerLikeTypeTraits<clang::CanQual<T> > {
34450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
34550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
34650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return P.getAsOpaquePtr();
34750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
34850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
34950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return clang::CanQual<T>::getFromOpaquePtr(P);
35050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3510953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // qualifier information is encoded in the low bits.
35250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  enum { NumLowBitsAvailable = 0 };
35350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
35550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace llvm
35650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
35750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
35950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
36050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical proxy adaptors for canonical type nodes.
36150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
36450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// into an iterator over CanQualTypes.
36550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
36650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanTypeIterator {
36750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  InputIterator Iter;
3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
36950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
37050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanQualType    value_type;
37150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef value_type     reference;
37250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanProxy<Type> pointer;
37350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::difference_type
37450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    difference_type;
37550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::iterator_category
37650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    iterator_category;
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator() : Iter() { }
37950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Input iterator
38250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator*() const {
38350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(*Iter);
38450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  pointer operator->() const;
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator++() {
38950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
39050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
39150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator++(int) {
39450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
39550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
39650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
39750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
40050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter == Y.Iter;
40150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
40250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
40350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter != Y.Iter;
40450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Bidirectional iterator
40750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator--() {
40850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
40950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
41050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator--(int) {
41350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
41450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
41550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
41650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Random access iterator
41950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator[](difference_type n) const {
42050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(Iter[n]);
42150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator+=(difference_type n) {
42450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter += n;
42550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
42650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator-=(difference_type n) {
42950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter -= n;
43050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
43150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
43450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
43550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
43650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
43750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
43850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
43950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
44050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
44150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
44450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X -= n;
44550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
44650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend difference_type operator-(const CanTypeIterator &X,
44950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                   const CanTypeIterator &Y) {
4501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return X - Y;
45150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
45250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
45350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
45550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
45650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
45750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
45850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
46050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
46150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
46250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<BlockPointerType>
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<BlockPointerType> {
46750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
46850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
47250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
47350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<LValueReferenceType>
4771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<LValueReferenceType> {
47850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
47950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
48050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
48150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<RValueReferenceType>
4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<RValueReferenceType> {
48450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
48650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
48750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<MemberPointerType>
4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<MemberPointerType> {
49050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
49250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
49550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
49650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
49850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
4990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
50050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
50150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ConstantArrayType>
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ConstantArrayType> {
50550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
50750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
50950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
51050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
51150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
51250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<IncompleteArrayType>
5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<IncompleteArrayType> {
51550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
51750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
51950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<VariableArrayType>
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<VariableArrayType> {
52450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
52650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getSizeModifier)
5270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
52850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
52950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
53050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
53150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
53250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
53350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
53450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedArrayType>
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedArrayType> {
53750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
53850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
53950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
54050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
54150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
54250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
54350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
54450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedExtVectorType>
5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedExtVectorType> {
54750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
54850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
55050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
55350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
55450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
55550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
55650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
55750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
55850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
55950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
56050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
56150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
56250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
56350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
56450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
56550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
56650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
567264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
56850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
56950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
57050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionNoProtoType>
5721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionNoProtoType> {
57350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
574264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
57550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionProtoType>
5791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionProtoType> {
58050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
581264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
5827177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
58350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQualType getArgType(unsigned i) const {
58450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
58550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
5861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
58850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
5891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
59150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    arg_type_iterator;
5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_begin() const {
59450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
59550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
59650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
59750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_end() const {
59850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_end());
59950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Note: canonical function types never have exception specifications
60250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
60550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
60650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
60750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
60850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
60950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
61050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
61150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
61250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
61350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
61450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
61550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
61650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
61750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
61850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
61950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
62050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
62150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
62250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
62350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
62450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
62550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
6261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace)
62750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
63050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
63150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
63250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
63350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<TemplateTypeParmType>
6371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<TemplateTypeParmType> {
63850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
63950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
64050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
64250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ObjCObjectPointerType>
6461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ObjCObjectPointerType> {
64750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
6481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
64950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getInterfaceType)
65050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
65150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
65250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
65350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
6541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
65650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
65750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
65850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
65950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
66050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
66350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Method and function definitions
66450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
66550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
66650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<T> CanQual<T>::getUnqualifiedType() const {
667a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
66850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
66950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
67050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
67150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<Type> CanQual<T>::getNonReferenceType() const {
67250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
67350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return RefType->getPointeeType();
67450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  else
67550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
67650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
67750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
67850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
67950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
68050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
68150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  Result.Stored.setFromOpaqueValue(Ptr);
6821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert((!Result || Result.Stored.isCanonical())
68350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor         && "Type is not canonical!");
68450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
68550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
68650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
68850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
689467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
69050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
69150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor         "Dynamic type does not meet the static type's requires");
69250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
69350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  Result.Stored = Other;
69450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
69550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
69650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
6971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
6981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename U>
69950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<U> CanQual<T>::getAs() const {
70050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (Stored.isNull())
70150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanProxy<U>();
7021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (isa<U>(Stored.getTypePtr()))
70450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQual<U>::CreateUnsafe(Stored);
7051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<U>();
70750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
70850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
70950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
71050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<T> CanQual<T>::operator->() const {
71150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<T>(*this);
71250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
7151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptypename CanTypeIterator<InputIterator>::pointer
71650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanTypeIterator<InputIterator>::operator->() const {
71750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<Type>(*this);
71850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
72150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
72250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
72350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
724