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 <iterator>
2150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T> class CanProxy;
2550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T> struct CanProxyAdaptor;
2650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical, qualified type template
2950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
3250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
3350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanQual template is a lightweight smart pointer that provides access
3450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to the canonical representation of a type, where all typedefs and other
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// syntactic sugar has been eliminated. A CanQualType may also have various
3650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// qualifiers (const, volatile, restrict) attached to it.
3750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// The template type parameter @p T is one of the Type classes (PointerType,
3950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
4050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type (or some subclass of that type). The typedef @c CanQualType is just
4150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// a shorthand for @c CanQual<Type>.
4250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// An instance of @c CanQual<T> can be implicitly converted to a
4450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// @c CanQual<U> when T is derived from U, which essentially provides an
451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
4750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// be implicitly converted to a QualType, but the reverse operation requires
4850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// a call to ASTContext::getCanonicalType().
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
5150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T = Type>
5250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanQual {
531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The actual, canonical type.
5450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  QualType Stored;
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
5750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Constructs a NULL canonical type.
5850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual() : Stored() { }
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Converting constructor that permits implicit upcasting of
6150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// canonical type pointers.
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template <typename U>
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CanQual(const CanQual<U> &Other,
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the underlying type pointer, which refers to a
6750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// canonical type.
681ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  ///
691ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// The underlying pointer must not be NULL.
70f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
711ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor
721ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// \brief Retrieve the underlying type pointer, which refers to a
731ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// canonical type, or NULL.
741ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  ///
75f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtrOrNull() const {
761ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor    return cast_or_null<T>(Stored.getTypePtrOrNull());
771ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  }
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to a qualified type.
8050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator QualType() const { return Stored; }
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor  /// \brief Implicit conversion to bool.
837247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  LLVM_EXPLICIT operator bool() const { return !isNull(); }
84cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor
85e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  bool isNull() const {
86e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.isNull();
87e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  }
88e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
89f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  SplitQualType split() const { return Stored.split(); }
90f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall
9150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve a canonical type pointer with a different static type,
9250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// upcasting or downcasting as needed.
9350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// The getAs() function is typically used to try to downcast to a
9550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// more specific (canonical) type in the type system. For example:
9650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
9750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
9850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// void f(CanQual<Type> T) {
9950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
10050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///     // look at Ptr's pointee type
10150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   }
10250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// }
10350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
10450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
10550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \returns A proxy pointer to the same type, but with the specified
10650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// static type (@p U). If the dynamic type is not the specified static type
10750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// or a derived class thereof, a NULL canonical type.
10850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U> CanProxy<U> getAs() const;
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11084fa9cd13c2b260937625b6ad7445af7f7648565John McCall  template<typename U> CanProxy<U> castAs() const;
11184fa9cd13c2b260937625b6ad7445af7f7648565John McCall
11250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Overloaded arrow operator that produces a canonical type
11350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// proxy.
11450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy<T> operator->() const;
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Retrieve all qualifiers.
117a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
1180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
11950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the const/volatile/restrict qualifiers.
120a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Determines whether this type has any qualifiers
123a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isConstQualified() const {
126a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalConstQualified();
12750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
12850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isVolatileQualified() const {
129a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalVolatileQualified();
13050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
13150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isRestrictQualified() const {
132a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalRestrictQualified();
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
135ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// \brief Determines if this canonical type is furthermore
136ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// canonical as a parameter.  The parameter-canonicalization
137ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// process decays arrays to pointers and drops top-level qualifiers.
138ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  bool isCanonicalAsParam() const {
139ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    return Stored.isCanonicalAsParam();
140ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
141ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
14250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the unqualified form of this type.
14350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> getUnqualifiedType() const;
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
145e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// \brief Retrieves a version of this type with const applied.
146e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// Note that this does not always yield a canonical type.
147e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  QualType withConst() const {
148e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.withConst();
14950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Determines whether this canonical type is more qualified than
15250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isMoreQualifiedThan(CanQual<T> Other) const {
15450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isMoreQualifiedThan(Other.Stored);
15550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Determines whether this canonical type is at least as qualified as
15850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
16050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
16150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief If the canonical type is a reference type, returns the type that
164b890f04174d52e41db19b883244abb17a3254ef1Douglas Gregor  /// it refers to; otherwise, returns the type itself.
16550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<Type> getNonReferenceType() const;
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the internal representation of this canonical type.
16850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Construct a canonical type from its internal representation.
17150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> getFromOpaquePtr(void *Ptr);
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Builds a canonical type from a QualType.
17450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// This routine is inherently unsafe, because it requires the user to
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ensure that the given type is a canonical type with the correct
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // (dynamic) type.
17850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> CreateUnsafe(QualType Other);
179ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
180d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes  void dump() const { Stored.dump(); }
181d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes
182ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
183ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    ID.AddPointer(getAsOpaquePtr());
184ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
18550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
18650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
18850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator==(CanQual<T> x, CanQual<U> y) {
18950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
19050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
19350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator!=(CanQual<T> x, CanQual<U> y) {
19450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
19550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
19850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortypedef CanQual<Type> CanQualType;
19950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
200ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCallinline CanQualType Type::getCanonicalTypeUnqualified() const {
201ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
202ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall}
203ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
204d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramerinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
205d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                                           CanQualType T) {
206d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  DB << static_cast<QualType>(T);
207d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  return DB;
208d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer}
2099d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson
21050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
21150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Internal proxy classes used by canonical types
21250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
21550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQualType Accessor() const {                                           \
21650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorreturn CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
21750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
21850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
21950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
22050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorType Accessor() const { return this->getTypePtr()->Accessor(); }
22150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
22250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Base class of all canonical proxy types, which is responsible for
22350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// storing the underlying canonical type and providing basic conversions.
2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
22550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxyBase {
22650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorprotected:
22750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Stored;
2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
23050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the pointer to the underlying Type
231f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtr() const { return Stored.getTypePtr(); }
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the underlying pointer.
23450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
23550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// Also provides the ability to use canonical type proxies in a Boolean
2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // context,e.g.,
23750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
23850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
23950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
2401ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Try to convert the given canonical type to a specific structural
24350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// type.
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  template<typename U> CanProxy<U> getAs() const {
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return this->Stored.template getAs<U>();
24650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Type predicates
25150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
25250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
25350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
25450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
25550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
25650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
25750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
25850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
25950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
26050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
2612ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
26250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
26350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
26450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
26550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
26650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
26750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
26850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
26950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
27050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
27150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
27250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
27350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
27450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
27550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
27650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
27750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
2786666ed4ed2e2bc13da5ac5d0a4947019137d45beJoao Matos  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
279fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
28050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
28150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
28250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
28350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
28450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
285f4c46193637631fc993d926ff31c7cb18c090d21Sebastian Redl  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
28650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
28750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
288f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
289f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
290f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
2918eee119bf4f1693dde17b8552c1f9f81bf2b681eDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
29250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
29350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
29450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
295575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
296575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
29750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
29850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
299f85e193739c953358c865005855253af4f68a497John McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
30050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
30150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the proxy-adaptor type.
30250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
30350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// This arrow operator is used when CanProxyAdaptor has been specialized
30450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// for the given type T. In that case, we reference members of the
30550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
30650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// by the arrow operator in the primary CanProxyAdaptor template.
30750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  const CanProxyAdaptor<T> *operator->() const {
30850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return static_cast<const CanProxyAdaptor<T> *>(this);
30950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
31050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
31150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
31250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Replacable canonical proxy adaptor class that provides the link
31350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// between a canonical type and the accessors of the type.
31450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
31550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxyAdaptor is a replaceable class template that is instantiated
31650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// as part of each canonical proxy type. The primary template merely provides
31750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// redirection to the underlying type (T), e.g., @c PointerType. One can
31850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// provide specializations of this class template for each underlying type
31950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// that provide accessors returning canonical types (@c CanQualType) rather
32050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// than the more typical @c QualType, to propagate the notion of "canonical"
32150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// through the system.
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
32350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor : CanProxyBase<T> { };
32450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
32550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Canonical proxy type returned when retrieving the members of a
3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// canonical type or as the result of the @c CanQual<T>::getAs member
32750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// function.
32850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
32950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxy type mainly exists as a proxy through which operator-> will
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
33150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type that provides canonical-type access to the fields of the type.
33250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
33350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxy : public CanProxyAdaptor<T> {
33450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
33550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a NULL proxy.
33650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy() { }
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a proxy to the given canonical type.
33950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the stored canonical type.
34250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator CanQual<T>() const { return this->Stored; }
34350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace clang
34650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
34750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace llvm {
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
35050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
35150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to return smart pointer (proxies?).
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
353e81fdb1fdde48d3fa18df56c5797f6b0bc5dfc4aRafael Espindolastruct simplify_type< ::clang::CanQual<T> > {
354f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  typedef const T *SimpleType;
35594cf910ac2d1719c1dfc163bbec3953f12efdf6fRafael Espindola  static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
3564472fc641ea3069463798fb56a04043c28ea2910Douglas Gregor    return Val.getTypePtr();
35750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
35850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
35950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
36050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
36150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
36250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass PointerLikeTypeTraits<clang::CanQual<T> > {
36350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
36450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
36550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return P.getAsOpaquePtr();
36650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
36750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
36850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return clang::CanQual<T>::getFromOpaquePtr(P);
36950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // qualifier information is encoded in the low bits.
37150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  enum { NumLowBitsAvailable = 0 };
37250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace llvm
37550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
37650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
37950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical proxy adaptors for canonical type nodes.
38050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
38350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// into an iterator over CanQualTypes.
38450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
38550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanTypeIterator {
38650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  InputIterator Iter;
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
38950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanQualType    value_type;
39050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef value_type     reference;
39150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanProxy<Type> pointer;
39250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::difference_type
39350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    difference_type;
39450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::iterator_category
39550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    iterator_category;
3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator() : Iter() { }
39850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Input iterator
40150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator*() const {
40250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(*Iter);
40350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  pointer operator->() const;
4061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
41950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter == Y.Iter;
42050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
42150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
42250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter != Y.Iter;
42350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Bidirectional iterator
42650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator--() {
42750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
42850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
42950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator--(int) {
43250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
43350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
43450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
43550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Random access iterator
43850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator[](difference_type n) const {
43950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(Iter[n]);
44050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator+=(difference_type n) {
44350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter += n;
44450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
44550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator-=(difference_type n) {
44850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter -= n;
44950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
45050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
45350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
45550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
45650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
45850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
46050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
46350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X -= n;
46450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
46550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend difference_type operator-(const CanTypeIterator &X,
46850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                   const CanTypeIterator &Y) {
4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return X - Y;
47050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
47150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
47550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
47650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
48050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<BlockPointerType>
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<BlockPointerType> {
48650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
49050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
49150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
49450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<LValueReferenceType>
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<LValueReferenceType> {
49750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<RValueReferenceType>
5021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<RValueReferenceType> {
50350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
50450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
50550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<MemberPointerType>
5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<MemberPointerType> {
50950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
51050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
51150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5136febf1265b5a5c3025752193caa9714ed523b12dEli Friedman// CanProxyAdaptors for arrays are intentionally unimplemented because
5146febf1265b5a5c3025752193caa9714ed523b12dEli Friedman// they are not safe.
5156febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<ArrayType>;
5166febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<ConstantArrayType>;
5176febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<IncompleteArrayType>;
5186febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<VariableArrayType>;
5196febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<DependentSizedArrayType>;
52050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
52150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedExtVectorType>
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedExtVectorType> {
52450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
52550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
52750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
53050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
53150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
53250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
53350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
53450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
53550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
53650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
53750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
53850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
53950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
54050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
54150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
54250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
544264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
54550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
54650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
54750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionNoProtoType>
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionNoProtoType> {
550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
551264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
55250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionProtoType>
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionProtoType> {
557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
558264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CanQualType getParamType(unsigned i) const {
561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
56250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
56550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_type_iterator;
5691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_type_iterator param_type_begin() const {
571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return param_type_iterator(this->getTypePtr()->param_type_begin());
57250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
57350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_type_iterator param_type_end() const {
575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return param_type_iterator(this->getTypePtr()->param_type_end());
57650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Note: canonical function types never have exception specifications
57950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
58250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
58350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
58450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
58550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
58650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
58750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
58850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
58950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
59050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
59150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
592ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunttemplate <>
593ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntstruct CanProxyAdaptor<UnaryTransformType>
594ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt    : public CanProxyBase<UnaryTransformType> {
595ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
596ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
597ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
598ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt};
599ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
60050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
60150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
60250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
60350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
60450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
60550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
60650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
60750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
60850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
60950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
61050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
61150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
61450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
61550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
61650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
61750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<TemplateTypeParmType>
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<TemplateTypeParmType> {
62250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
62350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
62450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
6254fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
626b7efff4bae117604f442bb6859c844f90b15f3ffChandler Carruth  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
62750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
630c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallstruct CanProxyAdaptor<ObjCObjectType>
631c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  : public CanProxyBase<ObjCObjectType> {
632c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
633c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
634c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                                      getInterface)
635c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
636c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
637c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
638c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
639c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
640c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
641c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
642c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
643c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
644c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
645c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall};
646c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
647c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCalltemplate<>
6481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ObjCObjectPointerType>
6491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ObjCObjectPointerType> {
65050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
65250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getInterfaceType)
65350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
65450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
65550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
65650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
6571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
65950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
66050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
66150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
66250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
66350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
66650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Method and function definitions
66750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
66850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
66950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<T> CanQual<T>::getUnqualifiedType() const {
670a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
67150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
67250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
67350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
67450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<Type> CanQual<T>::getNonReferenceType() const {
67550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
67650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return RefType->getPointeeType();
67750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  else
67850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
67950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
68050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
68150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
68250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
68350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
684f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  Result.Stored = QualType::getFromOpaquePtr(Ptr);
685f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
686f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          Result.Stored.isCanonical()) && "Type is not canonical!");
68750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
68850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
68950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
69150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
692467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
69350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
69450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor         "Dynamic type does not meet the static type's requires");
69550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
69650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  Result.Stored = Other;
69750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
69850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
69950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
7011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename U>
70250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<U> CanQual<T>::getAs() const {
7036febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  ArrayType_cannot_be_used_with_getAs<U> at;
7046febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  (void)at;
7056febf1265b5a5c3025752193caa9714ed523b12dEli Friedman
70650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (Stored.isNull())
70750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanProxy<U>();
7081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (isa<U>(Stored.getTypePtr()))
71050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQual<U>::CreateUnsafe(Stored);
7111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<U>();
71350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
71450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
71550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
71684fa9cd13c2b260937625b6ad7445af7f7648565John McCalltemplate<typename U>
71784fa9cd13c2b260937625b6ad7445af7f7648565John McCallCanProxy<U> CanQual<T>::castAs() const {
7186febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  ArrayType_cannot_be_used_with_getAs<U> at;
7196febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  (void)at;
7206febf1265b5a5c3025752193caa9714ed523b12dEli Friedman
72184fa9cd13c2b260937625b6ad7445af7f7648565John McCall  assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
72284fa9cd13c2b260937625b6ad7445af7f7648565John McCall  return CanQual<U>::CreateUnsafe(Stored);
72384fa9cd13c2b260937625b6ad7445af7f7648565John McCall}
72484fa9cd13c2b260937625b6ad7445af7f7648565John McCall
72584fa9cd13c2b260937625b6ad7445af7f7648565John McCalltemplate<typename T>
72650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<T> CanQual<T>::operator->() const {
72750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<T>(*this);
72850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptypename CanTypeIterator<InputIterator>::pointer
73250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanTypeIterator<InputIterator>::operator->() const {
73350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<Type>(*this);
73450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
73750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
73850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
73950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
740