150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//                     The LLVM Compiler Infrastructure
450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// This file is distributed under the University of Illinois Open Source
650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// License. See LICENSE.TXT for details.
750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//===----------------------------------------------------------------------===//
950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
1050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//  This file defines the CanQual class template, which provides access to
1150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//  canonical types.
1250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//
1350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//===----------------------------------------------------------------------===//
1450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
1550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
1650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_AST_CANONICAL_TYPE_H
1750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
1850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "clang/AST/Type.h"
1950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "llvm/Support/Casting.h"
2050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "llvm/Support/type_traits.h"
2150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include <iterator>
2250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T> class CanProxy;
2650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T> struct CanProxyAdaptor;
2750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
2850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical, qualified type template
3050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
3350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
3450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanQual template is a lightweight smart pointer that provides access
3550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to the canonical representation of a type, where all typedefs and other
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// syntactic sugar has been eliminated. A CanQualType may also have various
3750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// qualifiers (const, volatile, restrict) attached to it.
3850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// The template type parameter @p T is one of the Type classes (PointerType,
4050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
4150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type (or some subclass of that type). The typedef @c CanQualType is just
4250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// a shorthand for @c CanQual<Type>.
4350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// An instance of @c CanQual<T> can be implicitly converted to a
4550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// @c CanQual<U> when T is derived from U, which essentially provides an
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
4850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// be implicitly converted to a QualType, but the reverse operation requires
4950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// a call to ASTContext::getCanonicalType().
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
5250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T = Type>
5350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanQual {
541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The actual, canonical type.
5550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  QualType Stored;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
5850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Constructs a NULL canonical type.
5950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual() : Stored() { }
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Converting constructor that permits implicit upcasting of
6250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// canonical type pointers.
6350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U>
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CanQual(const CanQual<U>& Other,
6550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor          typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the underlying type pointer, which refers to a
6850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// canonical type.
691ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  ///
701ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// The underlying pointer must not be NULL.
71f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
721ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor
731ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// \brief Retrieve the underlying type pointer, which refers to a
741ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  /// canonical type, or NULL.
751ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  ///
76f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtrOrNull() const {
771ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor    return cast_or_null<T>(Stored.getTypePtrOrNull());
781ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  }
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to a qualified type.
8150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator QualType() const { return Stored; }
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor  /// \brief Implicit conversion to bool.
847247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  LLVM_EXPLICIT operator bool() const { return !isNull(); }
85cffecd08f1974dc7cc328bd620b2f69daf442fdaDouglas Gregor
86e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  bool isNull() const {
87e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.isNull();
88e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  }
89e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
90f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  SplitQualType split() const { return Stored.split(); }
91f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall
9250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve a canonical type pointer with a different static type,
9350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// upcasting or downcasting as needed.
9450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// The getAs() function is typically used to try to downcast to a
9650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// more specific (canonical) type in the type system. For example:
9750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
9850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
9950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// void f(CanQual<Type> T) {
10050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
10150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///     // look at Ptr's pointee type
10250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   }
10350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// }
10450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
10550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
10650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \returns A proxy pointer to the same type, but with the specified
10750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// static type (@p U). If the dynamic type is not the specified static type
10850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// or a derived class thereof, a NULL canonical type.
10950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  template<typename U> CanProxy<U> getAs() const;
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11184fa9cd13c2b260937625b6ad7445af7f7648565John McCall  template<typename U> CanProxy<U> castAs() const;
11284fa9cd13c2b260937625b6ad7445af7f7648565John McCall
11350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Overloaded arrow operator that produces a canonical type
11450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// proxy.
11550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy<T> operator->() const;
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Retrieve all qualifiers.
118a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
1190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
12050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the const/volatile/restrict qualifiers.
121a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1230953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Determines whether this type has any qualifiers
124a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isConstQualified() const {
127a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalConstQualified();
12850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
12950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isVolatileQualified() const {
130a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalVolatileQualified();
13150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
13250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isRestrictQualified() const {
133a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor    return Stored.isLocalRestrictQualified();
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// \brief Determines if this canonical type is furthermore
137ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// canonical as a parameter.  The parameter-canonicalization
138ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// process decays arrays to pointers and drops top-level qualifiers.
139ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  bool isCanonicalAsParam() const {
140ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    return Stored.isCanonicalAsParam();
141ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
142ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
14350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the unqualified form of this type.
14450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> getUnqualifiedType() const;
1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
146e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// \brief Retrieves a version of this type with const applied.
147e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  /// Note that this does not always yield a canonical type.
148e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  QualType withConst() const {
149e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall    return Stored.withConst();
15050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Determines whether this canonical type is more qualified than
15350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
15450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isMoreQualifiedThan(CanQual<T> Other) const {
15550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isMoreQualifiedThan(Other.Stored);
15650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Determines whether this canonical type is at least as qualified as
15950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// the @p Other canonical type.
16050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
16150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
16250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief If the canonical type is a reference type, returns the type that
165b890f04174d52e41db19b883244abb17a3254ef1Douglas Gregor  /// it refers to; otherwise, returns the type itself.
16650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<Type> getNonReferenceType() const;
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the internal representation of this canonical type.
16950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Construct a canonical type from its internal representation.
17250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> getFromOpaquePtr(void *Ptr);
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Builds a canonical type from a QualType.
17550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// This routine is inherently unsafe, because it requires the user to
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ensure that the given type is a canonical type with the correct
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // (dynamic) type.
17950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static CanQual<T> CreateUnsafe(QualType Other);
180ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
181d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes  void dump() const { Stored.dump(); }
182d9ab76bbce7b8a563aa847cfcdcd39d8280f11bdNuno Lopes
183ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
184ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    ID.AddPointer(getAsOpaquePtr());
185ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  }
18650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
18750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
18850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
18950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator==(CanQual<T> x, CanQual<U> y) {
19050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
19150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T, typename U>
19450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline bool operator!=(CanQual<T> x, CanQual<U> y) {
19550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
19650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
19750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
19850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Represents a canonical, potentially-qualified type.
19950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortypedef CanQual<Type> CanQualType;
20050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
201ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCallinline CanQualType Type::getCanonicalTypeUnqualified() const {
202ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
203ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall}
204ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
205d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramerinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
206d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                                           CanQualType T) {
207d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  DB << static_cast<QualType>(T);
208d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  return DB;
209d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer}
2109d59ecb4d2c2e8efdb214589753826b662246d82Anders Carlsson
21150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
21250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Internal proxy classes used by canonical types
21350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
21650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQualType Accessor() const {                                           \
21750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorreturn CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
21850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
21950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
22050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
22150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorType Accessor() const { return this->getTypePtr()->Accessor(); }
22250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
22350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Base class of all canonical proxy types, which is responsible for
22450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// storing the underlying canonical type and providing basic conversions.
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
22650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxyBase {
22750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorprotected:
22850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Stored;
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
23150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the pointer to the underlying Type
232f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const T *getTypePtr() const { return Stored.getTypePtr(); }
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the underlying pointer.
23550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
23650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// Also provides the ability to use canonical type proxies in a Boolean
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // context,e.g.,
23850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @code
23950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
24050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// @endcode
2411ab55e9bb87d98bff1d42c7a0ee502c64755d9f5Douglas Gregor  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Try to convert the given canonical type to a specific structural
24450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// type.
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  template<typename U> CanProxy<U> getAs() const {
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return this->Stored.template getAs<U>();
24750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Type predicates
25250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
25350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
25450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
25550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
25650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
25750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
25850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
25950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
26050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
26150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
2622ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
26350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
26450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
26550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
26650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
26750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
26850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
26950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
27050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
27150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
27250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
27350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
27450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
27550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
27650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
27750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
27850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
2796666ed4ed2e2bc13da5ac5d0a4947019137d45beJoao Matos  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
280fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
28150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
28250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
28350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
28450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
28550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
286f4c46193637631fc993d926ff31c7cb18c090d21Sebastian Redl  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
28750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
28850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
289f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
290f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
291f60946222721d9ba3c059563935c17b84703187aDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
2928eee119bf4f1693dde17b8552c1f9f81bf2b681eDouglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
29350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
29450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
29550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
296575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
297575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
29850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
29950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
300f85e193739c953358c865005855253af4f68a497John McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
30150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
30250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Retrieve the proxy-adaptor type.
30350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  ///
30450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// This arrow operator is used when CanProxyAdaptor has been specialized
30550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// for the given type T. In that case, we reference members of the
30650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
30750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// by the arrow operator in the primary CanProxyAdaptor template.
30850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  const CanProxyAdaptor<T> *operator->() const {
30950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return static_cast<const CanProxyAdaptor<T> *>(this);
31050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
31150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
31250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
31350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Replacable canonical proxy adaptor class that provides the link
31450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// between a canonical type and the accessors of the type.
31550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
31650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxyAdaptor is a replaceable class template that is instantiated
31750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// as part of each canonical proxy type. The primary template merely provides
31850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// redirection to the underlying type (T), e.g., @c PointerType. One can
31950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// provide specializations of this class template for each underlying type
32050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// that provide accessors returning canonical types (@c CanQualType) rather
32150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// than the more typical @c QualType, to propagate the notion of "canonical"
32250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// through the system.
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
32450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor : CanProxyBase<T> { };
32550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
32650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// \brief Canonical proxy type returned when retrieving the members of a
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// canonical type or as the result of the @c CanQual<T>::getAs member
32850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// function.
32950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///
33050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// The CanProxy type mainly exists as a proxy through which operator-> will
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
33250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// type that provides canonical-type access to the fields of the type.
33350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
33450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanProxy : public CanProxyAdaptor<T> {
33550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
33650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a NULL proxy.
33750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy() { }
3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Build a proxy to the given canonical type.
34050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  /// \brief Implicit conversion to the stored canonical type.
34350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  operator CanQual<T>() const { return this->Stored; }
34450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace clang
34750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
34850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace llvm {
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
35150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
35250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// to return smart pointer (proxies?).
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
354e81fdb1fdde48d3fa18df56c5797f6b0bc5dfc4aRafael Espindolastruct simplify_type< ::clang::CanQual<T> > {
355f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  typedef const T *SimpleType;
35694cf910ac2d1719c1dfc163bbec3953f12efdf6fRafael Espindola  static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
3574472fc641ea3069463798fb56a04043c28ea2910Douglas Gregor    return Val.getTypePtr();
35850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
35950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
36050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
36150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
36250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
36350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass PointerLikeTypeTraits<clang::CanQual<T> > {
36450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
36550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
36650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return P.getAsOpaquePtr();
36750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
36850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
36950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return clang::CanQual<T>::getFromOpaquePtr(P);
37050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
3710953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // qualifier information is encoded in the low bits.
37250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  enum { NumLowBitsAvailable = 0 };
37350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor} // end namespace llvm
37650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
37750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregornamespace clang {
3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
38050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Canonical proxy adaptors for canonical type nodes.
38150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
38450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor/// into an iterator over CanQualTypes.
38550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
38650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorclass CanTypeIterator {
38750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  InputIterator Iter;
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorpublic:
39050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanQualType    value_type;
39150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef value_type     reference;
39250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef CanProxy<Type> pointer;
39350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::difference_type
39450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    difference_type;
39550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef typename std::iterator_traits<InputIterator>::iterator_category
39650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    iterator_category;
3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator() : Iter() { }
39950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Input iterator
40250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator*() const {
40350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(*Iter);
40450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  pointer operator->() const;
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator++() {
40950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
41050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
41150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator++(int) {
41450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
41550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    ++Iter;
41650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
41750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
42050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter == Y.Iter;
42150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
42250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
42350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X.Iter != Y.Iter;
42450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Bidirectional iterator
42750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator--() {
42850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
42950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
43050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator operator--(int) {
43350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    CanTypeIterator Tmp(*this);
43450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    --Iter;
43550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return Tmp;
43650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Random access iterator
43950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  reference operator[](difference_type n) const {
44050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(Iter[n]);
44150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator+=(difference_type n) {
44450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter += n;
44550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
44650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanTypeIterator &operator-=(difference_type n) {
44950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    Iter -= n;
45050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
45150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
45450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
45550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
45650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
45750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
45850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
45950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X += n;
46050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
46150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
46450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    X -= n;
46550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return X;
46650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend difference_type operator-(const CanTypeIterator &X,
46950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                   const CanTypeIterator &Y) {
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return X - Y;
47150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
47250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
47550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
47650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
47750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
47850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
47950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
48050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
48150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<BlockPointerType>
4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<BlockPointerType> {
48750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
48850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
49150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
49250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
49450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
49550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<LValueReferenceType>
4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<LValueReferenceType> {
49850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
49950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
50050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<RValueReferenceType>
5031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<RValueReferenceType> {
50450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
50550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
50650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
50750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<MemberPointerType>
5091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<MemberPointerType> {
51050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
51150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
51250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5146febf1265b5a5c3025752193caa9714ed523b12dEli Friedman// CanProxyAdaptors for arrays are intentionally unimplemented because
5156febf1265b5a5c3025752193caa9714ed523b12dEli Friedman// they are not safe.
5166febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<ArrayType>;
5176febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<ConstantArrayType>;
5186febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<IncompleteArrayType>;
5196febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<VariableArrayType>;
5206febf1265b5a5c3025752193caa9714ed523b12dEli Friedmantemplate<> struct CanProxyAdaptor<DependentSizedArrayType>;
52150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
52250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<DependentSizedExtVectorType>
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<DependentSizedExtVectorType> {
52550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
52650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
52850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
53150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
53250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
53350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
53450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
53550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
53650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
53750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
53850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
53950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
54050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
54150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
54250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
54350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
54450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
545264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
54650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
54750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
54850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionNoProtoType>
5501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionNoProtoType> {
55150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
552264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
55350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<FunctionProtoType>
5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<FunctionProtoType> {
55850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
559264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
5607177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
56150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQualType getArgType(unsigned i) const {
56250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
56350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
56650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
56950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    arg_type_iterator;
5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_begin() const {
57250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
57350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
57450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
57550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  arg_type_iterator arg_type_end() const {
57650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return arg_type_iterator(this->getTypePtr()->arg_type_end());
57750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  }
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  // Note: canonical function types never have exception specifications
58050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
58350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
58450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
58550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
58650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
58750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
58850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
58950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
59050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
59150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
59250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
593ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunttemplate <>
594ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntstruct CanProxyAdaptor<UnaryTransformType>
595ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt    : public CanProxyBase<UnaryTransformType> {
596ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
597ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
598ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
599ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt};
600ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
60150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
60250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
60350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
60450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
60550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
60650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
60750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
60850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
60950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
61050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
61150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
61250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
61550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorstruct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
61650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
61750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
61850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<TemplateTypeParmType>
6221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<TemplateTypeParmType> {
62350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
62450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
62550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
6264fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
627b7efff4bae117604f442bb6859c844f90b15f3ffChandler Carruth  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
62850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<>
631c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallstruct CanProxyAdaptor<ObjCObjectType>
632c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  : public CanProxyBase<ObjCObjectType> {
633c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
634c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
635c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall                                      getInterface)
636c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
637c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
638c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
639c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
640c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
641c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
642c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
643c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
644c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
645c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
646c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall};
647c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
648c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCalltemplate<>
6491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct CanProxyAdaptor<ObjCObjectPointerType>
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public CanProxyBase<ObjCObjectPointerType> {
65150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
65350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor                                      getInterfaceType)
65450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
65550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
65650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
65750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
6581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
66050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
66150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
66250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
66350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
66450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor};
6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
66750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor// Method and function definitions
66850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor//----------------------------------------------------------------------------//
66950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
67050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<T> CanQual<T>::getUnqualifiedType() const {
671a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
67250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
67350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
67450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
67550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregorinline CanQual<Type> CanQual<T>::getNonReferenceType() const {
67650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
67750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return RefType->getPointeeType();
67850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  else
67950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return *this;
68050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
68150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
68250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
68350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
68450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
685f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  Result.Stored = QualType::getFromOpaquePtr(Ptr);
686f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
687f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor          Result.Stored.isCanonical()) && "Type is not canonical!");
68850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
68950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
69050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
69250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
693467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
69450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
69550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor         "Dynamic type does not meet the static type's requires");
69650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  CanQual<T> Result;
69750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  Result.Stored = Other;
69850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return Result;
69950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
70050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
7011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename T>
7021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<typename U>
70350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<U> CanQual<T>::getAs() const {
7046febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  ArrayType_cannot_be_used_with_getAs<U> at;
7056febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  (void)at;
7066febf1265b5a5c3025752193caa9714ed523b12dEli Friedman
70750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (Stored.isNull())
70850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanProxy<U>();
7091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  if (isa<U>(Stored.getTypePtr()))
71150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return CanQual<U>::CreateUnsafe(Stored);
7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<U>();
71450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
71550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
71650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename T>
71784fa9cd13c2b260937625b6ad7445af7f7648565John McCalltemplate<typename U>
71884fa9cd13c2b260937625b6ad7445af7f7648565John McCallCanProxy<U> CanQual<T>::castAs() const {
7196febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  ArrayType_cannot_be_used_with_getAs<U> at;
7206febf1265b5a5c3025752193caa9714ed523b12dEli Friedman  (void)at;
7216febf1265b5a5c3025752193caa9714ed523b12dEli Friedman
72284fa9cd13c2b260937625b6ad7445af7f7648565John McCall  assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
72384fa9cd13c2b260937625b6ad7445af7f7648565John McCall  return CanQual<U>::CreateUnsafe(Stored);
72484fa9cd13c2b260937625b6ad7445af7f7648565John McCall}
72584fa9cd13c2b260937625b6ad7445af7f7648565John McCall
72684fa9cd13c2b260937625b6ad7445af7f7648565John McCalltemplate<typename T>
72750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanProxy<T> CanQual<T>::operator->() const {
72850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<T>(*this);
72950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregortemplate<typename InputIterator>
7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptypename CanTypeIterator<InputIterator>::pointer
73350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas GregorCanTypeIterator<InputIterator>::operator->() const {
73450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  return CanProxy<Type>(*this);
73550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
7361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73750d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor}
73850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
73950d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
74050d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
741