Type.h revision e1b31fedbc006e6e4071bbb4f74c6116b56cfa9f
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
55f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file was developed by Chris Lattner and is distributed under
65f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// the University of Illinois Open Source License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file defines the Type interface and subclasses.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_AST_TYPE_H
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_AST_TYPE_H
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/Casting.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/FoldingSet.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::isa;
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::cast;
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::cast_or_null;
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::dyn_cast;
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::dyn_cast_or_null;
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class ASTContext;
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Type;
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class TypedefDecl;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class TagDecl;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class RecordDecl;
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class EnumDecl;
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Expr;
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class SourceLocation;
353acb13805673d47be95829bd5a4b1707952c0b6fChris Lattner  class PointerType;
36251dcaf8616c6f04051e214f35cadb7de42aef7eBill Wendling  class ReferenceType;
373acb13805673d47be95829bd5a4b1707952c0b6fChris Lattner  class VectorType;
38700204c74b455746752e851b25565ebf932f5340Steve Naroff  class ArrayType;
39dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  class RecordType;
407064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  class TagType;
417064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  class FunctionType;
427064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  class OCUVectorType;
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// their own: instead each reference to a type stores the qualifiers.  This
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// greatly reduces the number of nodes we need to allocate for types (for
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// example we only need one for 'int', 'const int', 'volatile int',
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const volatile int', etc).
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// As an added efficiency bonus, instead of making this a pair, we just store
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the three bits we care about in the low bits of the pointer.  To handle the
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// packing/unpacking, we make QualType be a simple wrapper class that acts like
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// a smart pointer.
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass QualType {
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  uintptr_t ThePtr;
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum TQ {   // NOTE: These flags must be kept in sync with DeclSpec::TQ.
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Const    = 0x1,
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Restrict = 0x2,
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Volatile = 0x4,
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CVRFlags = Const|Restrict|Volatile
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType() : ThePtr(0) {}
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType(Type *Ptr, unsigned Quals) {
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert((Quals & ~CVRFlags) == 0 && "Invalid type qualifiers!");
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ThePtr = reinterpret_cast<uintptr_t>(Ptr);
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert((ThePtr & CVRFlags) == 0 && "Type pointer not 8-byte aligned?");
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ThePtr |= Quals;
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static QualType getFromOpaquePtr(void *Ptr) {
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    QualType T;
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    T.ThePtr = reinterpret_cast<uintptr_t>(Ptr);
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T;
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getQualifiers() const {
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr & CVRFlags;
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Type *getTypePtr() const {
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return reinterpret_cast<Type*>(ThePtr & ~CVRFlags);
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *getAsOpaquePtr() const {
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return reinterpret_cast<void*>(ThePtr);
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Type &operator*() const {
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return *getTypePtr();
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Type *operator->() const {
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return getTypePtr();
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isNull - Return true if this QualType doesn't point to a type yet.
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isNull() const {
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr == 0;
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isConstQualified() const {
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr & Const;
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isVolatileQualified() const {
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr & Volatile;
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isRestrictQualified() const {
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr & Restrict;
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getQualifiedType(unsigned TQs) const {
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(getTypePtr(), TQs);
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getUnqualifiedType() const {
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(getTypePtr(), 0);
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// operator==/!= - Indicate whether the specified types and qualifiers are
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// identical.
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool operator==(const QualType &RHS) const {
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr == RHS.ThePtr;
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool operator!=(const QualType &RHS) const {
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ThePtr != RHS.ThePtr;
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::string getAsString() const {
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string S;
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    getAsStringInternal(S);
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return S;
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void getAsStringInternal(std::string &Str) const;
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void dump(const char *s = 0) const;
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getCanonicalType - Return the canonical version of this type, with the
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// appropriate type qualifiers on it.
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  inline QualType getCanonicalType() const;
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end clang.
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace llvm {
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// to a specific Type class.
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencertemplate<> struct simplify_type<const ::clang::QualType> {
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef ::clang::Type* SimpleType;
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Val.getTypePtr();
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencertemplate<> struct simplify_type< ::clang::QualType>
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  : public simplify_type<const ::clang::QualType> {};
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Type - This is the base class of the type hierarchy.  A central concept
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// with types is that each type always has a canonical type.  A canonical type
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is the type with any typedef names stripped out of it or the types it
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// references.  For example, consider:
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///  typedef int  foo;
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///  typedef foo* bar;
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///    'int *'    'foo *'    'bar'
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// There will be a Type object created for 'int'.  Since int is canonical, its
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// canonicaltype pointer points to itself.  There is also a Type for 'foo' (a
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// TypeNameType).  Its CanonicalType pointer points to the 'int' Type.  Next
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// there is a PointerType that represents 'int*', which, like 'int', is
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// canonical.  Finally, there is a PointerType type for 'foo*' whose canonical
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type is 'int*', and there is a TypeNameType for 'bar', whose canonical type
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is also 'int*'.
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Non-canonical types are useful for emitting diagnostics, without losing
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// information about typedefs being used.  Canonical types are useful for type
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// comparisons (they allow by-pointer equality tests) and useful for reasoning
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// about whether something has a particular form (e.g. is a function type),
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// because they implicitly, recursively, strip all typedefs out of a type.
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Types, once created, are immutable.
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass Type {
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum TypeClass {
19073322924127c873c13101b705dd823f5539ffa5fSteve Naroff    Builtin, Complex, Pointer, Reference, Array, Vector, OCUVector,
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FunctionNoProto, FunctionProto,
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    TypeName, Tagged
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType CanonicalType;
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Note that this should stay at the end of the ivars for Type so that
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// subclasses can pack their bitfields into the same word.
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypeClass TC : 4;
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Type(TypeClass tc, QualType Canonical)
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : CanonicalType(Canonical.isNull() ? QualType(this,0) : Canonical), TC(tc){}
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual ~Type();
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;
2068b9023ba35a86838789e2c9034a6128728c547aaChris Lattnerpublic:
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypeClass getTypeClass() const { return TC; }
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCanonical() const { return CanonicalType.getTypePtr() == this; }
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// object types, function types, and incomplete types.
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isObjectType - types that fully describe objects. An object is a region
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// of memory that can be examined and stored into (H&S).
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isObjectType() const;
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isIncompleteType - Return true if this is an incomplete type.
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// A type that can describe objects, but which lacks information needed to
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// routine will need to determine if the size is actually required.
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isIncompleteType() const;
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Helper methods to distinguish type categories. All type predicates
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// operate on the canonical type, ignoring typedefs.
2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Floating point categories.
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isComplexType() const;      // C99 6.2.5p11 (complex)
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isFloatingType() const;     // C99 6.2.5p11 (real floating + complex)
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isRealType() const;         // C99 6.2.5p17 (real floating + integer)
2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isArithmeticType() const;   // C99 6.2.5p18 (integer + floating)
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Vector types
2367a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  const VectorType *isVectorType() const; // GCC vector type.
2377064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  const OCUVectorType *isOCUVectorType() const; // OCU vector type.
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2397064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  /// Derived types (C99 6.2.5p20).
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isDerivedType() const;
2417064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  const FunctionType *isFunctionType() const;
2427a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  const PointerType *isPointerType() const;
243251dcaf8616c6f04051e214f35cadb7de42aef7eBill Wendling  const ReferenceType *isReferenceType() const;
244700204c74b455746752e851b25565ebf932f5340Steve Naroff  const ArrayType *isArrayType() const;
245dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  const RecordType *isRecordType() const;
2467064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  const TagType *isStructureType() const;
2477064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  const TagType *isUnionType() const;
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isVoidType() const;         // C99 6.2.5p19
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isAggregateType() const;    // C99 6.2.5p21 (arrays, structures)
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// More type predicates useful for type checking/promotion
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isSignedIntegerType - Return true if this is an integer type that is
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// signed, according to C99 6.2.5p4.
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isSignedIntegerType() const;
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isUnsignedIntegerType - Return true if this is an integer type that is
2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// unsigned, according to C99 6.2.5p6. Note that this returns true for _Bool.
2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isUnsignedIntegerType() const;
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isConstantSizeType - Return true if this is not a variable sized type,
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// according to the rules of C99 6.7.5p3.  If Loc is non-null, it is set to
2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the location of the subexpression that makes it a vla type.  It is not
2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// legal to call this on incomplete types.
268590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner  bool isConstantSizeType(ASTContext &Ctx, SourceLocation *Loc = 0) const;
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Compatibility predicates used to check assignment expressions.
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool pointerTypesAreCompatible(QualType, QualType);  // C99 6.7.5.1p2
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getCanonicalTypeInternal() const { return CanonicalType; }
2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class QualType;
2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const = 0;
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *) { return true; }
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// BuiltinType - This class is used for builtin types like 'int'.  Builtin
2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// types are always canonical and have a literal name field.
2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass BuiltinType : public Type {
2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum Kind {
2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Void,
2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Bool,     // This is bool and/or _Bool.
2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Char_U,   // This is 'char' for targets where char is unsigned.
2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UChar,    // This is explicitly qualified unsigned char.
2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UShort,
2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UInt,
2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ULong,
2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ULongLong,
3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Char_S,   // This is 'char' for targets where char is signed.
3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SChar,    // This is explicitly qualified signed char.
3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Short,
3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Int,
3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Long,
3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    LongLong,
3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Float, Double, LongDouble
3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Kind TypeKind;
3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  BuiltinType(Kind K) : Type(Builtin, QualType()), TypeKind(K) {}
3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Kind getKind() const { return TypeKind; }
3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *getName() const;
3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const BuiltinType *) { return true; }
3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ComplexType - C99 6.2.5p11 - Complex values.  This supports the C99 complex
3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// types (_Complex float etc) as well as the GCC integer complex extensions.
3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass ComplexType : public Type, public llvm::FoldingSetNode {
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ElementType;
3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ComplexType(QualType Element, QualType CanonicalPtr) :
3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type(Complex, CanonicalPtr), ElementType(Element) {
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getElementType() const { return ElementType; }
3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getElementType());
3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(Element.getAsOpaquePtr());
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const ComplexType *) { return true; }
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// PointerType - C99 6.7.5.1 - Pointer Declarators.
3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass PointerType : public Type, public llvm::FoldingSetNode {
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType PointeeType;
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PointerType(QualType Pointee, QualType CanonicalPtr) :
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type(Pointer, CanonicalPtr), PointeeType(Pointee) {
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getPointeeType() const { return PointeeType; }
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getPointeeType());
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(Pointee.getAsOpaquePtr());
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const PointerType *) { return true; }
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ReferenceType - C++ 8.3.2 - Reference Declarators.
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass ReferenceType : public Type, public llvm::FoldingSetNode {
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ReferenceeType;
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ReferenceType(QualType Referencee, QualType CanonicalRef) :
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type(Reference, CanonicalRef), ReferenceeType(Referencee) {
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getReferenceeType() const { return ReferenceeType; }
3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getReferenceeType());
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(Referencee.getAsOpaquePtr());
3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Reference; }
3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const ReferenceType *) { return true; }
3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ArrayType - C99 6.7.5.2 - Array Declarators.
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass ArrayType : public Type, public llvm::FoldingSetNode {
4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// an array with a static size (e.g. int X[static 4]), or with a star size
4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// (e.g. int X[*]).
4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum ArraySizeModifier {
4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Normal, Static, Star
4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NOTE: These fields are packed into the bitfields space in the Type class.
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ArraySizeModifier SizeModifier : 2;
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// IndexTypeQuals - Capture qualifiers in declarations like:
4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 'int X[static restrict 4]'.
4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned IndexTypeQuals : 3;
4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ElementType - The element type of the array.
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ElementType;
4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SizeExpr - The size is either a constant or assignment expression (for
4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Variable Length Arrays). VLA's are only permitted within a function block.
4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Expr *SizeExpr;
4255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ArrayType(QualType et, ArraySizeModifier sm, unsigned tq, QualType can,
4275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            Expr *e)
4285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et),
4295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SizeExpr(e) {}
4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
4315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
4325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getElementType() const { return ElementType; }
4345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ArraySizeModifier getSizeModifier() const { return SizeModifier; }
4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
4368b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  Expr *getSizeExpr() const { return SizeExpr; }
4375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
4395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType(),
4428b9023ba35a86838789e2c9034a6128728c547aaChris Lattner            getSizeExpr());
4435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID,
4455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                      ArraySizeModifier SizeModifier,
4465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                      unsigned IndexTypeQuals, QualType ElementType,
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                      Expr *SizeExpr) {
4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddInteger(SizeModifier);
4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddInteger(IndexTypeQuals);
4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ElementType.getAsOpaquePtr());
4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(SizeExpr);
4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Array; }
4555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const ArrayType *) { return true; }
4565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
45873322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// VectorType - GCC generic vector type. This type is created using
45973322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// __attribute__((vector_size(n)), where "n" specifies the vector size in
46073322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// bytes. Since the constructor takes the number of vector elements, the
46173322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// client is responsible for converting the size into the number of elements.
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass VectorType : public Type, public llvm::FoldingSetNode {
46373322924127c873c13101b705dd823f5539ffa5fSteve Naroffprotected:
4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ElementType - The element type of the vector.
4655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ElementType;
4665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NumElements - The number of elements in the vector.
4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumElements;
4695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
47073322924127c873c13101b705dd823f5539ffa5fSteve Naroff  VectorType(QualType vecType, unsigned nElements, QualType canonType) :
47173322924127c873c13101b705dd823f5539ffa5fSteve Naroff    Type(Vector, canonType), ElementType(vecType), NumElements(nElements) {}
47273322924127c873c13101b705dd823f5539ffa5fSteve Naroff  VectorType(TypeClass tc, QualType vecType, unsigned nElements,
47373322924127c873c13101b705dd823f5539ffa5fSteve Naroff    QualType canonType) : Type(tc, canonType), ElementType(vecType),
47473322924127c873c13101b705dd823f5539ffa5fSteve Naroff    NumElements(nElements) {}
4755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
4765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getElementType() const { return ElementType; }
4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getNumElements() const { return NumElements; }
4805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
48473322924127c873c13101b705dd823f5539ffa5fSteve Naroff    Profile(ID, getElementType(), getNumElements(), getTypeClass());
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
48673322924127c873c13101b705dd823f5539ffa5fSteve Naroff  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
48773322924127c873c13101b705dd823f5539ffa5fSteve Naroff                      unsigned NumElements, TypeClass TypeClass) {
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ElementType.getAsOpaquePtr());
4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddInteger(NumElements);
49073322924127c873c13101b705dd823f5539ffa5fSteve Naroff    ID.AddInteger(TypeClass);
49173322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
49273322924127c873c13101b705dd823f5539ffa5fSteve Naroff  static bool classof(const Type *T) {
49373322924127c873c13101b705dd823f5539ffa5fSteve Naroff    return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector;
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const VectorType *) { return true; }
4965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
49873322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// OCUVectorType - Extended vector type. This type is created using
49973322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// __attribute__((ocu_vector_type(n)), where "n" is the number of elements.
50073322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// Unlike vector_size, ocu_vector_type is only allowed on typedef's.
50173322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// This class will enable syntactic extensions, like C++ style initializers.
50273322924127c873c13101b705dd823f5539ffa5fSteve Naroffclass OCUVectorType : public VectorType {
50373322924127c873c13101b705dd823f5539ffa5fSteve Naroff  OCUVectorType(QualType vecType, unsigned nElements, QualType canonType) :
50473322924127c873c13101b705dd823f5539ffa5fSteve Naroff    VectorType(OCUVector, vecType, nElements, canonType) {}
50573322924127c873c13101b705dd823f5539ffa5fSteve Naroff  friend class ASTContext;  // ASTContext creates these.
50673322924127c873c13101b705dd823f5539ffa5fSteve Naroffpublic:
507e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  bool isPointAccessor(const char c) const {
508e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    return c == 'x' || c == 'y' || c == 'z' || c == 'w';
509e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
510e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  bool isColorAccessor(const char c) const {
511e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    return c == 'r' || c == 'g' || c == 'b' || c == 'a';
512e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
513e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  bool isTextureAccessor(const char c) const {
514e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    return c == 's' || c == 't' || c == 'p' || c == 'q';
515e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  };
516e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  bool isAccessorWithinNumElements(const char c) const {
517e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    switch (NumElements) {
518e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff      default: assert(0 && "Illegal number of elements");
519e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff      case 2: return c == 'x' || c == 'y' ||
520e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff                     c == 'r' || c == 'g' ||
521e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff                     c == 's' || c == 't';
522e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff      case 3: return c == 'x' || c == 'y' || c == 'z' ||
523e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff                     c == 'r' || c == 'g' || c == 'b' ||
524e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff                     c == 's' || c == 't' || c == 'p';
525e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff      case 4: return isPointAccessor(c) || isColorAccessor(c) ||
526e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff                     isTextureAccessor(c);
527e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    }
528e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
5297064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  static bool classof(const Type *T) {
5307064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector;
5317064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  }
53273322924127c873c13101b705dd823f5539ffa5fSteve Naroff  static bool classof(const VectorType *T) {
53373322924127c873c13101b705dd823f5539ffa5fSteve Naroff    return T->getTypeClass() == OCUVector;
53473322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
53573322924127c873c13101b705dd823f5539ffa5fSteve Naroff  static bool classof(const OCUVectorType *) { return true; }
53673322924127c873c13101b705dd823f5539ffa5fSteve Naroff};
53773322924127c873c13101b705dd823f5539ffa5fSteve Naroff
5385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
5395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// class of FunctionTypeNoProto and FunctionTypeProto.
5405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
5415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FunctionType : public Type {
5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SubClassData - This field is owned by the subclass, put here to pack
5435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tightly with the ivars in Type.
5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool SubClassData : 1;
5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // The type returned by the function.
5475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ResultType;
5485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
5495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionType(TypeClass tc, QualType res, bool SubclassInfo,QualType Canonical)
5505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : Type(tc, Canonical), SubClassData(SubclassInfo), ResultType(res) {}
5515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool getSubClassData() const { return SubClassData; }
5525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
5535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getResultType() const { return ResultType; }
5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) {
5585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getTypeClass() == FunctionNoProto ||
5595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           T->getTypeClass() == FunctionProto;
5605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const FunctionType *) { return true; }
5625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
5635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FunctionTypeNoProto - Represents a K&R-style 'int foo()' function, which has
5655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// no information available about its arguments.
5665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode {
5675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeNoProto(QualType Result, QualType Canonical)
5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : FunctionType(FunctionNoProto, Result, false, Canonical) {}
5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
5705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // No additional state past what FunctionType provides.
5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getResultType());
5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType) {
5795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ResultType.getAsOpaquePtr());
5805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) {
5835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getTypeClass() == FunctionNoProto;
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const FunctionTypeNoProto *) { return true; }
5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
5875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FunctionTypeProto - Represents a prototype with argument type info, e.g.
5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// arguments, not as having a single void argument.
5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeProto(QualType Result, QualType *ArgArray, unsigned numArgs,
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    bool isVariadic, QualType Canonical)
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : FunctionType(FunctionProto, Result, isVariadic, Canonical),
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      NumArgs(numArgs) {
596942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    // Fill in the trailing argument array.
597942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    QualType *ArgInfo = reinterpret_cast<QualType *>(this+1);;
5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    for (unsigned i = 0; i != numArgs; ++i)
5995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ArgInfo[i] = ArgArray[i];
6005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NumArgs - The number of arguments this function has, not counting '...'.
6035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumArgs;
6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
605942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  /// ArgInfo - There is an variable size array after the class in memory that
606942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  /// holds the argument types.
6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
6085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getNumArgs() const { return NumArgs; }
6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getArgType(unsigned i) const {
6115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(i < NumArgs && "Invalid argument number!");
612942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    return arg_type_begin()[i];
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isVariadic() const { return getSubClassData(); }
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef const QualType *arg_type_iterator;
618942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  arg_type_iterator arg_type_begin() const {
619942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    return reinterpret_cast<const QualType *>(this+1);
620942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  }
621942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
6225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
6245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) {
6265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getTypeClass() == FunctionProto;
6275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const FunctionTypeProto *) { return true; }
6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID);
6315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
632942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner                      arg_type_iterator ArgTys, unsigned NumArgs,
633942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner                      bool isVariadic);
6345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TypedefType : public Type {
6385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypedefDecl *Decl;
6395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypedefType(TypedefDecl *D, QualType can) : Type(TypeName, can), Decl(D) {
6405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(!isa<TypedefType>(can) && "Invalid canonical type");
6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypedefDecl *getDecl() const { return Decl; }
646a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
647a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
648a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// potentially looking through *all* consequtive typedefs.  This returns the
649a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// sum of the type qualifiers, so if you have:
650a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  ///   typedef const int A;
651a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  ///   typedef volatile A B;
652a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// looking through the typedefs for B will give you "const volatile A".
653a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  QualType LookThroughTypedefs() const;
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == TypeName; }
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const TypedefType *) { return true; }
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TagType : public Type {
6635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TagDecl *Decl;
6645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TagType(TagDecl *D, QualType can) : Type(Tagged, can), Decl(D) {}
6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
6665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TagDecl *getDecl() const { return Decl; }
6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getAsStringInternal(std::string &InnerString) const;
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Tagged; }
6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const TagType *) { return true; }
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// to detect TagType objects of structs/unions/classes.
6785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass RecordType : public TagType {
6795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  RecordType(); // DO NOT IMPLEMENT
6805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
682dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  const RecordDecl *getDecl() {
6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
6845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
685dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  RecordDecl *getDecl() const {
6865d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
6875d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  }
6885d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner
6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: This predicate is a helper to QualType/Type. It needs to
6905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // recursively check all fields for const-ness. If any field is declared
6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // const, it needs to return false.
6925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool hasConstFields() const { return false; }
6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T);
6955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const RecordType *) { return true; }
6965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ...
7005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// TODO: When we support C++, we should have types for uses of template with
7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// default parameters.  We should be able to distinguish source use of
7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 'std::vector<int>' from 'std::vector<int, std::allocator<int> >'. Though they
7045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// specify the same type, we want to print the default argument only if
7055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// specified in the source code.
7065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getCanonicalType - Return the canonical version of this type, with the
7085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// appropriate type qualifiers on it.
7095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerinline QualType QualType::getCanonicalType() const {
7105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(getTypePtr()->getCanonicalTypeInternal().getTypePtr(),
7115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                  getQualifiers() |
7125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                  getTypePtr()->getCanonicalTypeInternal().getQualifiers());
7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
718