Type.h revision 54e14c4db764c0636160d26c5bbf491637c83a76
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// 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
1722caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner#include "clang/Basic/Diagnostic.h"
181734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "clang/Basic/IdentifierTable.h"
19e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#include "clang/AST/NestedNameSpecifier.h"
207532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor#include "clang/AST/TemplateName.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/Casting.h"
2250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "llvm/Support/type_traits.h"
23fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff#include "llvm/ADT/APSInt.h"
245cf243a883872441d73ca49cea7e20de5802629bChris Lattner#include "llvm/ADT/FoldingSet.h"
255cf243a883872441d73ca49cea7e20de5802629bChris Lattner#include "llvm/ADT/PointerIntPair.h"
261734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor#include "llvm/ADT/PointerUnion.h"
277532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::isa;
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::cast;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::cast_or_null;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::dyn_cast;
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::dyn_cast_or_null;
336b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCallnamespace clang {
346b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall  enum {
356b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall    TypeAlignmentInBits = 3,
366b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall    TypeAlignment = 1 << TypeAlignmentInBits
376b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall  };
386b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall  class Type; class ExtQuals;
396b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall}
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
414e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattnernamespace llvm {
424e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner  template <typename T>
43daae940507f2e93c6fa12e8062fa958e34cc2d1cChris Lattner  class PointerLikeTypeTraits;
44bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner  template<>
45bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner  class PointerLikeTypeTraits< ::clang::Type*> {
46bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner  public:
47bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner    static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
48bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner    static inline ::clang::Type *getFromVoidPointer(void *P) {
49bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner      return static_cast< ::clang::Type*>(P);
50bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner    }
516b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
52bfadf55ba5b736b13cc3e0fbc2b184569bc9f304Chris Lattner  };
530953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  template<>
540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  class PointerLikeTypeTraits< ::clang::ExtQuals*> {
550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  public:
560953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return static_cast< ::clang::ExtQuals*>(P);
590953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    }
606b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
610953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  };
624e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner}
634e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class ASTContext;
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class TypedefDecl;
6755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  class TemplateDecl;
6872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  class TemplateTypeParmDecl;
69aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  class NonTypeTemplateParmDecl;
707532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  class TemplateTemplateParmDecl;
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class TagDecl;
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class RecordDecl;
7349aa7ff1245abd03e6e998e01302df31e4c6f8f6Argyrios Kyrtzidis  class CXXRecordDecl;
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class EnumDecl;
7521d50e12c3c412d8457071dc419363b7a7e8b855Ted Kremenek  class FieldDecl;
76a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  class ObjCInterfaceDecl;
77a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  class ObjCProtocolDecl;
78a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  class ObjCMethodDecl;
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Expr;
80b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek  class Stmt;
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class SourceLocation;
8292866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  class StmtIteratorBase;
8340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  class TemplateArgument;
84e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  class QualifiedNameType;
853b4ea54acf01f72f6eb74d96689dda86d950228fDaniel Dunbar  struct PrintingPolicy;
8672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor
8772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  // Provide forward declarations for all of the *Type classes
8872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor#define TYPE(Class, Base) class Class##Type;
8972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor#include "clang/AST/TypeNodes.def"
90f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// Qualifiers - The collection of all-type qualifiers we support.
920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// Clang supports five independent qualifiers:
930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// * C99: const, volatile, and restrict
940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// * Embedded C (TR18037): address spaces
950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// * Objective C: the GC attributes (none, weak, or strong)
960953e767ff7817f97b3ab20896b229891eeff45bJohn McCallclass Qualifiers {
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Const    = 0x1,
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Restrict = 0x2,
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Volatile = 0x4,
1020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    CVRMask = Const | Volatile | Restrict
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  enum GC {
106d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian    GCNone = 0,
107d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian    Weak,
108d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian    Strong
109d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian  };
110efadb7768e7c7418185f5a4010ecd8b21ca9731bJohn McCall
1110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  enum {
1120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    /// The maximum supported address space number.
1130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    /// 24 bits should be enough for anyone.
1140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    MaxAddressSpace = 0xffffffu,
1150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    /// The width of the "fast" qualifier mask.
1170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    FastWidth = 2,
1180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    /// The fast qualifier mask.
1200953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    FastMask = (1 << FastWidth) - 1
1210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  };
1220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1230953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers() : Mask(0) {}
1240953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1250953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static Qualifiers fromFastMask(unsigned Mask) {
1260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers Qs;
1270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qs.addFastQualifiers(Mask);
1280953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Qs;
1290953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1300953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1310953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static Qualifiers fromCVRMask(unsigned CVR) {
1320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers Qs;
1330953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qs.addCVRQualifiers(CVR);
1340953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Qs;
1350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1370953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Deserialize qualifiers from an opaque representation.
1380953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static Qualifiers fromOpaqueValue(unsigned opaque) {
1390953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers Qs;
1400953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qs.Mask = opaque;
1410953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Qs;
1420953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1430953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1440953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Serialize these qualifiers into an opaque representation.
1450953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getAsOpaqueValue() const {
1460953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Mask;
1470953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1480953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1490953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasConst() const { return Mask & Const; }
1500953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setConst(bool flag) {
1510953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~Const) | (flag ? Const : 0);
1520953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1530953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeConst() { Mask &= ~Const; }
1540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addConst() { Mask |= Const; }
1550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1560953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasVolatile() const { return Mask & Volatile; }
1570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setVolatile(bool flag) {
1580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
1590953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1600953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeVolatile() { Mask &= ~Volatile; }
1610953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addVolatile() { Mask |= Volatile; }
1620953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1630953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasRestrict() const { return Mask & Restrict; }
1640953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setRestrict(bool flag) {
1650953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
1660953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1670953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeRestrict() { Mask &= ~Restrict; }
1680953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addRestrict() { Mask |= Restrict; }
1690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasCVRQualifiers() const { return getCVRQualifiers(); }
1710953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getCVRQualifiers() const { return Mask & CVRMask; }
1720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setCVRQualifiers(unsigned mask) {
1730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
1740953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~CVRMask) | mask;
1750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1760953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeCVRQualifiers(unsigned mask) {
1770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
1780953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask &= ~mask;
1790953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeCVRQualifiers() {
1810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    removeCVRQualifiers(CVRMask);
1820953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1830953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addCVRQualifiers(unsigned mask) {
1840953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
1850953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask |= mask;
1860953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1870953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1880953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
1890953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
1900953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setObjCGCAttr(GC type) {
1910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
1920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
1940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addObjCGCAttr(GC type) {
1950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(type);
1960953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    setObjCGCAttr(type);
1970953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
1980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
2000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
2010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setAddressSpace(unsigned space) {
2020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(space <= MaxAddressSpace);
2030953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~AddressSpaceMask)
2040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall         | (((uint32_t) space) << AddressSpaceShift);
2050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeAddressSpace() { setAddressSpace(0); }
2070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addAddressSpace(unsigned space) {
2080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(space);
2090953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    setAddressSpace(space);
2100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Fast qualifiers are those that can be allocated directly
2130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // on a QualType object.
2140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasFastQualifiers() const { return getFastQualifiers(); }
2150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getFastQualifiers() const { return Mask & FastMask; }
2160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setFastQualifiers(unsigned mask) {
2170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
2180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask = (Mask & ~FastMask) | mask;
2190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2200953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeFastQualifiers(unsigned mask) {
2210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
2220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask &= ~mask;
2230953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2240953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeFastQualifiers() {
2250953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    removeFastQualifiers(FastMask);
2260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addFastQualifiers(unsigned mask) {
2280953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
2290953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Mask |= mask;
2300953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2310953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// hasNonFastQualifiers - Return true if the set contains any
2330953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// qualifiers which require an ExtQuals node to be allocated.
2340953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
2350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers getNonFastQualifiers() const {
2360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers Quals = *this;
2370953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Quals.setFastQualifiers(0);
2380953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Quals;
2390953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2400953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2410953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// hasQualifiers - Return true if the set contains any qualifiers.
2420953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasQualifiers() const { return Mask; }
2430953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool empty() const { return !Mask; }
2440953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2450953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// \brief Add the qualifiers from the given set to this set.
2460953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addQualifiers(Qualifiers Q) {
2470953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    // If the other set doesn't have any non-boolean qualifiers, just
2480953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    // bit-or it in.
2490953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (!(Q.Mask & ~CVRMask))
2500953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      Mask |= Q.Mask;
2510953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    else {
2520953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      Mask |= (Q.Mask & CVRMask);
2530953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      if (Q.hasAddressSpace())
2540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        addAddressSpace(Q.getAddressSpace());
2550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      if (Q.hasObjCGCAttr())
2560953e767ff7817f97b3ab20896b229891eeff45bJohn McCall        addObjCGCAttr(Q.getObjCGCAttr());
2570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    }
2580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2590953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2600953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
2610953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
2620953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2630953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  operator bool() const { return hasQualifiers(); }
2640953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2650953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers &operator+=(Qualifiers R) {
2660953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    addQualifiers(R);
2670953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return *this;
2680953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Union two qualifier sets.  If an enumerated qualifier appears
2710953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // in both sets, use the one from the right.
2720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
2730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    L += R;
2740953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return L;
2750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2760953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  std::string getAsString() const;
2780953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  std::string getAsString(const PrintingPolicy &Policy) const {
2790953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    std::string Buffer;
2800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    getAsStringInternal(Buffer, Policy);
2810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Buffer;
2820953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2830953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const;
2840953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2850953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
2860953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    ID.AddInteger(Mask);
2870953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
2880953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2890953e767ff7817f97b3ab20896b229891eeff45bJohn McCallprivate:
2900953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // bits:     |0 1 2|3 .. 4|5  ..  31|
2920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //           |C R V|GCAttr|AddrSpace|
2930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  uint32_t Mask;
2940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static const uint32_t GCAttrMask = 0x18;
2960953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static const uint32_t GCAttrShift = 3;
2970953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static const uint32_t AddressSpaceMask = ~(CVRMask | GCAttrMask);
2980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static const uint32_t AddressSpaceShift = 5;
2990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall};
3000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// ExtQuals - We can encode up to three bits in the low bits of a
3030953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// type pointer, but there are many more type qualifiers that we want
3040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// to be able to apply to an arbitrary type.  Therefore we have this
3050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// struct, intended to be heap-allocated and used by QualType to
3060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// store qualifiers.
3070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall///
3080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// The current design tags the 'const' and 'restrict' qualifiers in
3090953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// two low bits on the QualType pointer; a third bit records whether
3100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// the pointer is an ExtQuals node.  'const' was chosen because it is
3110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// orders of magnitude more common than the other two qualifiers, in
3120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// both library and user code.  It's relatively rare to see
3130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// 'restrict' in user code, but many standard C headers are saturated
3140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// with 'restrict' declarations, so that representing them efficiently
3150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// is a critical goal of this representation.
3160953e767ff7817f97b3ab20896b229891eeff45bJohn McCallclass ExtQuals : public llvm::FoldingSetNode {
3170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // NOTE: changing the fast qualifiers should be straightforward as
3180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // long as you don't make 'const' non-fast.
3190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // 1. Qualifiers:
3200953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //    a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
3210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //       Fast qualifiers must occupy the low-order bits.
3220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //    b) Update Qualifiers::FastWidth and FastMask.
3230953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // 2. QualType:
3240953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //    a) Update is{Volatile,Restrict}Qualified(), defined inline.
3250953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //    b) Update remove{Volatile,Restrict}, defined near the end of
3260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //       this header.
3270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // 3. ASTContext:
3280953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  //    a) Update get{Volatile,Restrict}Type.
3290953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3300953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Context - the context to which this set belongs.  We save this
3310953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// here so that QualifierCollector can use it to reapply extended
3320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// qualifiers to an arbitrary type without requiring a context to
3330953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// be pushed through every single API dealing with qualifiers.
3340953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  ASTContext& Context;
3350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// BaseType - the underlying type that this qualifies
3370953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const Type *BaseType;
3380953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3390953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Quals - the immutable set of qualifiers applied by this
3400953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// node;  always contains extended qualifiers.
3410953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers Quals;
3420953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3430953e767ff7817f97b3ab20896b229891eeff45bJohn McCallpublic:
3440953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  ExtQuals(ASTContext& Context, const Type *Base, Qualifiers Quals)
3450953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    : Context(Context), BaseType(Base), Quals(Quals)
3460953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  {
3470953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(Quals.hasNonFastQualifiers()
3480953e767ff7817f97b3ab20896b229891eeff45bJohn McCall           && "ExtQuals created with no fast qualifiers");
3490953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!Quals.hasFastQualifiers()
3500953e767ff7817f97b3ab20896b229891eeff45bJohn McCall           && "ExtQuals created with fast qualifiers");
3510953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
3520953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3530953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers getQualifiers() const { return Quals; }
3540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasVolatile() const { return Quals.hasVolatile(); }
3560953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
3580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
3590953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3600953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
3610953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
3620953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3630953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const Type *getBaseType() const { return BaseType; }
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3650953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  ASTContext &getContext() const { return Context; }
3660953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3670953e767ff7817f97b3ab20896b229891eeff45bJohn McCallpublic:
3680953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void Profile(llvm::FoldingSetNodeID &ID) const {
3690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Profile(ID, getBaseType(), Quals);
3700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
3710953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  static void Profile(llvm::FoldingSetNodeID &ID,
3720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall                      const Type *BaseType,
3730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall                      Qualifiers Quals) {
3740953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
3750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    ID.AddPointer(BaseType);
3760953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Quals.Profile(ID);
3770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
3780953e767ff7817f97b3ab20896b229891eeff45bJohn McCall};
3790953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// QualType - For efficiency, we don't store CV-qualified types as nodes on
3820953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// their own: instead each reference to a type stores the qualifiers.  This
3830953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// greatly reduces the number of nodes we need to allocate for types (for
3840953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// example we only need one for 'int', 'const int', 'volatile int',
3850953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// 'const volatile int', etc).
3860953e767ff7817f97b3ab20896b229891eeff45bJohn McCall///
3870953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// As an added efficiency bonus, instead of making this a pair, we
3880953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// just store the two bits we care about in the low bits of the
3890953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// pointer.  To handle the packing/unpacking, we make QualType be a
3900953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// simple wrapper class that acts like a smart pointer.  A third bit
3910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// indicates whether there are extended qualifiers present, in which
3920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// case the pointer points to a special structure.
3930953e767ff7817f97b3ab20896b229891eeff45bJohn McCallclass QualType {
3940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Thankfully, these are efficiently composable.
3950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
3960953e767ff7817f97b3ab20896b229891eeff45bJohn McCall                       Qualifiers::FastWidth> Value;
3970953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
3980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasExtQuals() const {
3990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Value.getPointer().is<const ExtQuals*>();
4000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const ExtQuals *getExtQualsUnsafe() const {
4030953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Value.getPointer().get<const ExtQuals*>();
4040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const Type *getTypePtrUnsafe() const {
4070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Value.getPointer().get<const Type*>();
4080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4090953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  friend class QualifierCollector;
4110953e767ff7817f97b3ab20896b229891eeff45bJohn McCallpublic:
4125cf243a883872441d73ca49cea7e20de5802629bChris Lattner  QualType() {}
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4145cf243a883872441d73ca49cea7e20de5802629bChris Lattner  QualType(const Type *Ptr, unsigned Quals)
4150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    : Value(Ptr, Quals) {}
4160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType(const ExtQuals *Ptr, unsigned Quals)
4170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    : Value(Ptr, Quals) {}
4180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getFastQualifiers() const { return Value.getInt(); }
4200953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Retrieves a pointer to the underlying (unqualified) type.
4230953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// This should really return a const Type, but it's not worth
4240953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// changing all the users right now.
4250953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Type *getTypePtr() const {
4260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (hasNonFastQualifiers())
4270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
4280953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return const_cast<Type*>(getTypePtrUnsafe());
4290953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4315cf243a883872441d73ca49cea7e20de5802629bChris Lattner  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
4325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static QualType getFromOpaquePtr(void *Ptr) {
4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    QualType T;
4345cf243a883872441d73ca49cea7e20de5802629bChris Lattner    T.Value.setFromOpaqueValue(Ptr);
4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T;
4365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Type &operator*() const {
4395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return *getTypePtr();
4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Type *operator->() const {
4435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return getTypePtr();
4445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
446467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  bool isCanonical() const;
44754e14c4db764c0636160d26c5bbf491637c83a76John McCall  bool isCanonicalAsParam() const;
448467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall
4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isNull - Return true if this QualType doesn't point to a type yet.
4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isNull() const {
4510953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Value.getPointer().isNull();
4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isConstQualified() const {
4550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return (getFastQualifiers() & Qualifiers::Const);
4560953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool isRestrictQualified() const {
4580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return (getFastQualifiers() & Qualifiers::Restrict);
4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isVolatileQualified() const {
4610953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return (hasNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4630953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4640953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Determines whether this type has any direct qualifiers.
4650953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasQualifiers() const {
4660953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return getFastQualifiers() || hasNonFastQualifiers();
4670953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4680953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  bool hasNonFastQualifiers() const {
4700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return hasExtQuals();
4710953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Retrieves the set of qualifiers belonging to this type.
4740953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers getQualifiers() const {
4750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qualifiers Quals;
4760953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (hasNonFastQualifiers())
4770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      Quals = getExtQualsUnsafe()->getQualifiers();
4780953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Quals.addFastQualifiers(getFastQualifiers());
4790953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Quals;
4800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
4810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4820953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Retrieves the CVR qualifiers of this type.
4830953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getCVRQualifiers() const {
4840953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    unsigned CVR = getFastQualifiers();
4850953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (isVolatileQualified()) CVR |= Qualifiers::Volatile;
4860953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return CVR;
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
488b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes
489bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isConstant(ASTContext& Ctx) const {
490bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall    return QualType::isConstant(*this, Ctx);
491bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  }
4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Don't promise in the API that anything besides 'const' can be
4940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // easily added.
4950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
4960953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// addConst - add the specified type qualifier to this QualType.
4970953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addConst() {
4980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    addFastQualifiers(Qualifiers::Const);
4990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
5000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType withConst() const {
5010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return withFastQualifiers(Qualifiers::Const);
5020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
5030953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
5040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void addFastQualifiers(unsigned TQs) {
5050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(TQs & ~Qualifiers::FastMask)
5060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall           && "non-fast qualifier bits set in mask!");
5070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Value.setInt(Value.getInt() | TQs);
5080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
5090953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
5100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeConst();
5110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeVolatile();
5120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeRestrict();
5130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeCVRQualifiers(unsigned Mask);
5140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
5150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeFastQualifiers() { Value.setInt(0); }
5160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void removeFastQualifiers(unsigned Mask) {
5170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
5180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Value.setInt(Value.getInt() & ~Mask);
5190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Creates a type with the given qualifiers in addition to any
5220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // qualifiers already on this type.
5230953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType withFastQualifiers(unsigned TQs) const {
5240953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    QualType T = *this;
5250953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    T.addFastQualifiers(TQs);
5260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return T;
5270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
5281c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta
5290953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Creates a type with exactly the given fast qualifiers, removing
5300953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // any existing fast qualifiers.
5310953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType withExactFastQualifiers(unsigned TQs) const {
5320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return withoutFastQualifiers().withFastQualifiers(TQs);
5335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5340953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
5350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Removes fast qualifiers, but leaves any extended qualifiers in place.
5360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType withoutFastQualifiers() const {
5370953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    QualType T = *this;
5380953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    T.removeFastQualifiers();
5390953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return T;
540c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  }
541971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis
5420953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType getUnqualifiedType() const { return QualType(getTypePtr(), 0); }
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
544e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  bool isMoreQualifiedThan(QualType Other) const;
545e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  bool isAtLeastAsQualifiedAs(QualType Other) const;
546e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  QualType getNonReferenceType() const;
5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5482fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  /// getDesugaredType - Return the specified type with any "sugar" removed from
5492fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
5502fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  /// the type is already concrete, it returns it unmodified.  This is similar
5512fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  /// to getting the canonical type, but it doesn't remove *all* typedefs.  For
5522fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
5532fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  /// concrete.
5540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  ///
5550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Qualifiers are left in place.
556bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType getDesugaredType() const {
557bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall    return QualType::getDesugaredType(*this);
558bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  }
55998cd599ee8a9b259ed7388ee2921a20d97658864Douglas Gregor
5605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// operator==/!= - Indicate whether the specified types and qualifiers are
5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// identical.
56250d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator==(const QualType &LHS, const QualType &RHS) {
56350d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return LHS.Value == RHS.Value;
5645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
56550d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor  friend bool operator!=(const QualType &LHS, const QualType &RHS) {
56650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    return LHS.Value != RHS.Value;
5675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
568d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  std::string getAsString() const;
569d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor
570d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  std::string getAsString(const PrintingPolicy &Policy) const {
5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string S;
572d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    getAsStringInternal(S, Policy);
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return S;
5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
575e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void getAsStringInternal(std::string &Str,
576e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                           const PrintingPolicy &Policy) const;
5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
578c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  void dump(const char *s) const;
579c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  void dump() const;
5801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5813f2dcb1ca8bd2d5d3ccc5c80f4ab06f949d88a89Ted Kremenek  void Profile(llvm::FoldingSetNodeID &ID) const {
5823f2dcb1ca8bd2d5d3ccc5c80f4ab06f949d88a89Ted Kremenek    ID.AddPointer(getAsOpaquePtr());
5833f2dcb1ca8bd2d5d3ccc5c80f4ab06f949d88a89Ted Kremenek  }
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
585ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  /// getAddressSpace - Return the address space of this type.
586ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  inline unsigned getAddressSpace() const;
5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
588d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian  /// GCAttrTypesAttr - Returns gc attribute of this type.
5890953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  inline Qualifiers::GC getObjCGCAttr() const;
590f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian
591f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian  /// isObjCGCWeak true when Type is objc's weak.
592f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian  bool isObjCGCWeak() const {
5930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return getObjCGCAttr() == Qualifiers::Weak;
594f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian  }
595f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian
596f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian  /// isObjCGCStrong true when Type is objc's strong.
597f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian  bool isObjCGCStrong() const {
5980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return getObjCGCAttr() == Qualifiers::Strong;
599f6123ca578eb8aabb76ecce7df6857482017f502Fariborz Jahanian  }
6002455636163fdd18581d7fdae816433f886d88213Mike Stump
601ae92140b542d5c1c096e39e74e59526184819b30Mike Stump  /// getNoReturnAttr - Returns true if the type has the noreturn attribute,
602ae92140b542d5c1c096e39e74e59526184819b30Mike Stump  /// false otherwise.
6032455636163fdd18581d7fdae816433f886d88213Mike Stump  bool getNoReturnAttr() const;
604bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
605bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCallprivate:
606bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  // These methods are implemented in a separate translation unit;
607bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  // "static"-ize them to avoid creating temporary QualTypes in the
608bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  // caller.
609bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  static bool isConstant(QualType T, ASTContext& Ctx);
610bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  static QualType getDesugaredType(QualType T);
6115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end clang.
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace llvm {
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// to a specific Type class.
6185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencertemplate<> struct simplify_type<const ::clang::QualType> {
6195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef ::clang::Type* SimpleType;
6205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
6215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Val.getTypePtr();
6225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencertemplate<> struct simplify_type< ::clang::QualType>
6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  : public simplify_type<const ::clang::QualType> {};
6261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6274e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner// Teach SmallPtrSet that QualType is "basically a pointer".
6284e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattnertemplate<>
629daae940507f2e93c6fa12e8062fa958e34cc2d1cChris Lattnerclass PointerLikeTypeTraits<clang::QualType> {
6304e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattnerpublic:
6314e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner  static inline void *getAsVoidPointer(clang::QualType P) {
6324e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner    return P.getAsOpaquePtr();
6334e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner  }
6344e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner  static inline clang::QualType getFromVoidPointer(void *P) {
6354e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner    return clang::QualType::getFromOpaquePtr(P);
6364e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner  }
6370953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Various qualifiers go in low bits.
6380eda3b31a672ea486fa92b9bc49a2c91be856b53Chris Lattner  enum { NumLowBitsAvailable = 0 };
6394e7072872e8e2ed76a4c6933424bffa253896e7eChris Lattner};
6401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64173af669633e13c813f80cd15ecf3e6414778aee4Ted Kremenek} // end namespace llvm
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Type - This is the base class of the type hierarchy.  A central concept
6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// with types is that each type always has a canonical type.  A canonical type
6475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is the type with any typedef names stripped out of it or the types it
6485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// references.  For example, consider:
6495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///  typedef int  foo;
6515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///  typedef foo* bar;
6525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///    'int *'    'foo *'    'bar'
6535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// There will be a Type object created for 'int'.  Since int is canonical, its
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// canonicaltype pointer points to itself.  There is also a Type for 'foo' (a
65672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor/// TypedefType).  Its CanonicalType pointer points to the 'int' Type.  Next
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// there is a PointerType that represents 'int*', which, like 'int', is
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// canonical.  Finally, there is a PointerType type for 'foo*' whose canonical
65972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is also 'int*'.
6615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Non-canonical types are useful for emitting diagnostics, without losing
6635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// information about typedefs being used.  Canonical types are useful for type
6645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// comparisons (they allow by-pointer equality tests) and useful for reasoning
6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// about whether something has a particular form (e.g. is a function type),
6665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// because they implicitly, recursively, strip all typedefs out of a type.
6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Types, once created, are immutable.
6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass Type {
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum TypeClass {
67372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor#define TYPE(Class, Base) Class,
67472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor#define ABSTRACT_TYPE(Class, Base)
67572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor#include "clang/AST/TypeNodes.def"
67672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    TagFirst = Record, TagLast = Enum
6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
6781bb8a45f7386a23871598d05141a07af03067925Argyrios Kyrtzidis
6791bb8a45f7386a23871598d05141a07af03067925Argyrios Kyrtzidisprotected:
6801bb8a45f7386a23871598d05141a07af03067925Argyrios Kyrtzidis  enum { TypeClassBitSize = 6 };
6811bb8a45f7386a23871598d05141a07af03067925Argyrios Kyrtzidis
6825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType CanonicalType;
6845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
685898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
686898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  bool Dependent : 1;
687898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
6885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Note that this should stay at the end of the ivars for Type so that
6905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// subclasses can pack their bitfields into the same word.
6911bb8a45f7386a23871598d05141a07af03067925Argyrios Kyrtzidis  unsigned TC : TypeClassBitSize;
692898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
69316ff705a594697f98b9473f9b7e7d378f331fe4bChris Lattner  Type(const Type&);           // DO NOT IMPLEMENT.
69416ff705a594697f98b9473f9b7e7d378f331fe4bChris Lattner  void operator=(const Type&); // DO NOT IMPLEMENT.
6955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
696124dd7b5777e29ecac006822bd4d4623f0dc4264Hartmut Kaiser  // silence VC++ warning C4355: 'this' : used in base member initializer list
697124dd7b5777e29ecac006822bd4d4623f0dc4264Hartmut Kaiser  Type *this_() { return this; }
698898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  Type(TypeClass tc, QualType Canonical, bool dependent)
699f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
700898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      Dependent(dependent), TC(tc) {}
701898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  virtual ~Type() {}
7024b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek  virtual void Destroy(ASTContext& C);
7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;
7041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7058b9023ba35a86838789e2c9034a6128728c547aaChris Lattnerpublic:
706a8ae51f79d35b7c1822ba4a086176b4a8c862862Hartmut Kaiser  TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
708467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  bool isCanonicalUnqualified() const {
709467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall    return CanonicalType.getTypePtr() == this;
710467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  }
7115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// object types, function types, and incomplete types.
7141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
715bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  /// \brief Determines whether the type describes an object in memory.
716bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  ///
717bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  /// Note that this definition of object type corresponds to the C++
718bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  /// definition of object type, which includes incomplete types, as
719bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  /// opposed to the C definition (which does not include incomplete
720bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  /// types).
7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isObjectType() const;
7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isIncompleteType - Return true if this is an incomplete type.
7245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// A type that can describe objects, but which lacks information needed to
7255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
7261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// routine will need to determine if the size is actually required.
7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isIncompleteType() const;
728d805bec0fbb98aa10abbb41bfdcb2e2fab1bac96Chris Lattner
729d805bec0fbb98aa10abbb41bfdcb2e2fab1bac96Chris Lattner  /// isIncompleteOrObjectType - Return true if this is an incomplete or object
730d805bec0fbb98aa10abbb41bfdcb2e2fab1bac96Chris Lattner  /// type, in other words, not a function type.
731d805bec0fbb98aa10abbb41bfdcb2e2fab1bac96Chris Lattner  bool isIncompleteOrObjectType() const {
732d805bec0fbb98aa10abbb41bfdcb2e2fab1bac96Chris Lattner    return !isFunctionType();
733d805bec0fbb98aa10abbb41bfdcb2e2fab1bac96Chris Lattner  }
73464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
73564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
73664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  bool isPODType() const;
73764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
738d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff  /// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
739d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff  /// types that have a non-constant expression. This does not include "[]".
740d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff  bool isVariablyModifiedType() const;
7411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Helper methods to distinguish type categories. All type predicates
743ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  /// operate on the canonical type, ignoring typedefs and qualifiers.
744e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar
745e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar  /// isSpecificBuiltinType - Test for a particular builtin type.
746e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar  bool isSpecificBuiltinType(unsigned K) const;
7471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74896d2c438f5c9ada8229f7f2ac049d2e9957bc954Steve Naroff  /// isIntegerType() does *not* include complex integers (a GCC extension).
74996d2c438f5c9ada8229f7f2ac049d2e9957bc954Steve Naroff  /// isComplexIntegerType() can be used to test for complex integers.
7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
75113b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  bool isEnumeralType() const;
75213b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  bool isBooleanType() const;
75313b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  bool isCharType() const;
75477a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor  bool isWideCharType() const;
75533e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  bool isIntegralType() const;
7561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Floating point categories.
7585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
75902f62a9fedbc370fba081303399410a3afdde29fSteve Naroff  /// isComplexType() does *not* include complex integers (a GCC extension).
76002f62a9fedbc370fba081303399410a3afdde29fSteve Naroff  /// isComplexIntegerType() can be used to test for complex integers.
7615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isComplexType() const;      // C99 6.2.5p11 (complex)
762f23d364084d1aabea688222780d6fc1dd8c7f78cChris Lattner  bool isAnyComplexType() const;   // C99 6.2.5p11 (complex) + Complex Int.
7635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isFloatingType() const;     // C99 6.2.5p11 (real floating + complex)
7645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isRealType() const;         // C99 6.2.5p17 (real floating + integer)
7655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isArithmeticType() const;   // C99 6.2.5p18 (integer + floating)
766c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  bool isVoidType() const;         // C99 6.2.5p19
767c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  bool isDerivedType() const;      // C99 6.2.5p20
768c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
769d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor  bool isAggregateType() const;
7701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
771c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  // Type Predicates: Check to see if this type is structurally the specified
772ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // type, ignoring typedefs and qualifiers.
773c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  bool isFunctionType() const;
774183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
775183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
776befee48ff2a1dab236c5700f00ecca1cfdcd5837Chris Lattner  bool isPointerType() const;
77758f9f2c884af6b72d036b746a016d8031d31cb7aSteve Naroff  bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
7785618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  bool isBlockPointerType() const;
7797154a77e7c1f23418342d3b72836ab504aa7821eSteve Naroff  bool isVoidPointerType() const;
780a1d9fdea79ba7bbd71862b9f9f78f5f117331fc7Chris Lattner  bool isReferenceType() const;
7817c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  bool isLValueReferenceType() const;
7827c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  bool isRValueReferenceType() const;
783bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  bool isFunctionPointerType() const;
784f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  bool isMemberPointerType() const;
785f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  bool isMemberFunctionPointerType() const;
786c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  bool isArrayType() const;
787c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  bool isConstantArrayType() const;
788c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  bool isIncompleteArrayType() const;
789c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  bool isVariableArrayType() const;
790898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  bool isDependentSizedArrayType() const;
791c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  bool isRecordType() const;
7921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isClassType() const;
7931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isStructureType() const;
7944cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  bool isUnionType() const;
795368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner  bool isComplexIntegerType() const;            // GCC _Complex integer type.
796368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner  bool isVectorType() const;                    // GCC vector type.
797213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  bool isExtVectorType() const;                 // Extended vector type.
798d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  bool isObjCObjectPointerType() const;         // Pointer to *any* ObjC object.
79914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // FIXME: change this to 'raw' interface type, so we can used 'interface' type
80014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // for the common case.
801368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner  bool isObjCInterfaceType() const;             // NSString or NSString<foo>
802368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner  bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
803368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner  bool isObjCQualifiedIdType() const;           // id<foo>
804470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff  bool isObjCQualifiedClassType() const;        // Class<foo>
80514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  bool isObjCIdType() const;                    // id
80614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  bool isObjCClassType() const;                 // Class
807de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  bool isObjCBuiltinType() const;               // 'id' or 'Class'
80872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  bool isTemplateTypeParmType() const;          // C++ template type parameter
8096e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  bool isNullPtrType() const;                   // C++0x nullptr_t
810898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
811898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// isDependentType - Whether this type is a dependent type, meaning
8121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// that its definition somehow depends on a template parameter
813898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// (C++ [temp.dep.type]).
814898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  bool isDependentType() const { return Dependent; }
815063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  bool isOverloadableType() const;
81672c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
8178958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar  /// hasPointerRepresentation - Whether this type is represented
8188958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar  /// natively as a pointer; this includes pointers, references, block
8198958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar  /// pointers, and Objective-C interface, qualified id, and qualified
8206e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  /// interface types, as well as nullptr_t.
8218958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar  bool hasPointerRepresentation() const;
8228958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar
823820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  /// hasObjCPointerRepresentation - Whether this type can represent
824820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian  /// an objective pointer type for the purpose of GC'ability
8251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool hasObjCPointerRepresentation() const;
826820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian
827c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  // Type Checking Functions: Check to see if this type is structurally the
828f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  // specified type, ignoring typedefs and qualifiers, and return a pointer to
829f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  // the best type we can.
830769c9cfc6e06bd9d8ffe7a4397b939f19b0e4dc3Ted Kremenek  const RecordType *getAsStructureType() const;
831898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// NOTE: getAs*ArrayType are methods on ASTContext.
832c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  const RecordType *getAsUnionType() const;
8334cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
83414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // The following is a convenience method that returns an ObjCObjectPointerType
83514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // for object declared using an interface.
83614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
83714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
838c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
839a91d6a6619a91d0ca7102d8ab5678d855f04d850Fariborz Jahanian  const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
8401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8411a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  // Member-template getAs<specific type>'.  This scheme will eventually
8421a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  // replace the specific getAsXXXX methods above.
843183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  //
844183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  // There are some specializations of this member template listed
845183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  // immediately following this class.
8461a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  template <typename T> const T *getAs() const;
8471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8482b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
8492b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  /// interface, return the interface type, otherwise return null.
8502b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
8512b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner
852c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  /// getArrayElementTypeNoTypeQual - If this is an array type, return the
853c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  /// element type of the array, potentially with type qualifiers missing.
854c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  /// This method should never be used when type qualifiers are meaningful.
855c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  const Type *getArrayElementTypeNoTypeQual() const;
8561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
857f8910df57799256c1897a8610dc52685729ae90eSteve Naroff  /// getPointeeType - If this is a pointer, ObjC object pointer, or block
858f8910df57799256c1897a8610dc52685729ae90eSteve Naroff  /// pointer, this returns the respective pointee.
85914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  QualType getPointeeType() const;
8601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
861bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// getUnqualifiedDesugaredType() - Return the specified type with
862bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// any "sugar" removed from the type, removing any typedefs,
863bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// typeofs, etc., as well as any qualifiers.
864bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  const Type *getUnqualifiedDesugaredType() const;
8651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// More type predicates useful for type checking/promotion
8675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
8685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isSignedIntegerType - Return true if this is an integer type that is
870d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner  /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
871d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner  /// an enum decl which has a signed representation, or a vector of signed
872d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner  /// integer element type.
8735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isSignedIntegerType() const;
8745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isUnsignedIntegerType - Return true if this is an integer type that is
876d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner  /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
877d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner  /// decl which has an unsigned representation, or a vector of unsigned integer
878d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner  /// element type.
8795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isUnsignedIntegerType() const;
880d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
8815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isConstantSizeType - Return true if this is not a variable sized type,
8829bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner  /// according to the rules of C99 6.7.5p3.  It is not legal to call this on
8839bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner  /// incomplete types.
8843c2b3170041f69a92904e3bab9b6d654eaf260acEli Friedman  bool isConstantSizeType() const;
885c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
88622b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  /// isSpecifierType - Returns true if this type can be represented by some
88722b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  /// set of type specifiers.
88822b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  bool isSpecifierType() const;
88922b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
890cd01f17358dc8ef19338c0e2321138dd0a6160d9Argyrios Kyrtzidis  const char *getTypeClassName() const;
891cd01f17358dc8ef19338c0e2321138dd0a6160d9Argyrios Kyrtzidis
8925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getCanonicalTypeInternal() const { return CanonicalType; }
893c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  void dump() const;
8941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
895f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const = 0;
8965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *) { return true; }
8975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
899183700f494ec9b6701b6efe82bcb25f4c79ba561John McCalltemplate <> inline const TypedefType *Type::getAs() const {
900183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return dyn_cast<TypedefType>(this);
901183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall}
902183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall
903183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall// We can do canonical leaf types faster, because we don't have to
904183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall// worry about preserving child type decoration.
905183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall#define TYPE(Class, Base)
906183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall#define LEAF_TYPE(Class) \
907183700f494ec9b6701b6efe82bcb25f4c79ba561John McCalltemplate <> inline const Class##Type *Type::getAs() const { \
9080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  return dyn_cast<Class##Type>(CanonicalType); \
909183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall}
910183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall#include "clang/AST/TypeNodes.def"
911183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall
912183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall
9135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// BuiltinType - This class is used for builtin types like 'int'.  Builtin
9145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// types are always canonical and have a literal name field.
9155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass BuiltinType : public Type {
9165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
9175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum Kind {
9185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Void,
9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Bool,     // This is bool and/or _Bool.
9215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Char_U,   // This is 'char' for targets where char is unsigned.
9225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UChar,    // This is explicitly qualified unsigned char.
923f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith    Char16,   // This is 'char16_t' for C++.
924f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith    Char32,   // This is 'char32_t' for C++.
9255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UShort,
9265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UInt,
9275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ULong,
9285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ULongLong,
9292df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner    UInt128,  // __uint128_t
9301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Char_S,   // This is 'char' for targets where char is signed.
9325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SChar,    // This is explicitly qualified signed char.
9332ff9b4c7c8fed9233a0b8de2e9507368c451aab6Argyrios Kyrtzidis    WChar,    // This is 'wchar_t' for C++.
9345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Short,
9355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Int,
9365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Long,
9375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    LongLong,
9382df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner    Int128,   // __int128_t
9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9408e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor    Float, Double, LongDouble,
9418e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor
9426e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl    NullPtr,  // This is the type of C++0x 'nullptr'.
9436e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl
944898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    Overload,  // This represents the type of an overloaded function declaration.
945e89d15944dd3be750a09805ad21222d2fa9321faAnders Carlsson    Dependent, // This represents the type of a type-dependent expression.
9461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
947de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    UndeducedAuto, // In C++0x, this represents the type of an auto variable
948e89d15944dd3be750a09805ad21222d2fa9321faAnders Carlsson                   // that has not been deduced yet.
949de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    ObjCId,    // This represents the ObjC 'id' type.
950de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    ObjCClass  // This represents the ObjC 'Class' type.
9515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
9525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
9535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Kind TypeKind;
9545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
9551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  BuiltinType(Kind K)
9561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
957898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      TypeKind(K) {}
9581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Kind getKind() const { return TypeKind; }
960e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  const char *getName(const LangOptions &LO) const;
9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
962bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
963bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
964bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
9651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
966f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
9671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
9695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const BuiltinType *) { return true; }
9705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
9715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
972f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman/// FixedWidthIntType - Used for arbitrary width types that we either don't
973f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman/// want to or can't map to named integer types.  These always have a lower
974f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman/// integer rank than builtin types of the same width.
975f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedmanclass FixedWidthIntType : public Type {
976f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedmanprivate:
977f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  unsigned Width;
978f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  bool Signed;
979f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedmanpublic:
980f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  FixedWidthIntType(unsigned W, bool S) : Type(FixedWidthInt, QualType(), false),
981f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman                                          Width(W), Signed(S) {}
9821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
983f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  unsigned getWidth() const { return Width; }
984f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  bool isSigned() const { return Signed; }
985f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  const char *getName() const;
9861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
987bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
988bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
989bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
9901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
991f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
9921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
993f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  static bool classof(const Type *T) { return T->getTypeClass() == FixedWidthInt; }
994f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  static bool classof(const FixedWidthIntType *) { return true; }
995f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman};
996f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
9975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ComplexType - C99 6.2.5p11 - Complex values.  This supports the C99 complex
9985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// types (_Complex float etc) as well as the GCC integer complex extensions.
9995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
10005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass ComplexType : public Type, public llvm::FoldingSetNode {
10015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ElementType;
10025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ComplexType(QualType Element, QualType CanonicalPtr) :
10031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Type(Complex, CanonicalPtr, Element->isDependentType()),
1004898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    ElementType(Element) {
10055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
10075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
10085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getElementType() const { return ElementType; }
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1011f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
10121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1013bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1014bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1015bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
10165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
10175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getElementType());
10185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
10205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(Element.getAsOpaquePtr());
10215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
10245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const ComplexType *) { return true; }
10255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
10265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
102768694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar/// PointerType - C99 6.7.5.1 - Pointer Declarators.
1028bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner///
102968694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbarclass PointerType : public Type, public llvm::FoldingSetNode {
1030bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  QualType PointeeType;
10315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PointerType(QualType Pointee, QualType CanonicalPtr) :
103368694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar    Type(Pointer, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) {
10345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
10365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
10371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1039f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104168694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar  QualType getPointeeType() const { return PointeeType; }
104268694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar
1043bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1044bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1045bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
10465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
10475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Profile(ID, getPointeeType());
10485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
10505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(Pointee.getAsOpaquePtr());
10515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
10545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const PointerType *) { return true; }
10555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
10565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10575618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff/// BlockPointerType - pointer to a block type.
10585618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff/// This type is to represent types syntactically represented as
10595618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff/// "void (^)(int)", etc. Pointee is required to always be a function type.
10605618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff///
10615618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroffclass BlockPointerType : public Type, public llvm::FoldingSetNode {
10625618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  QualType PointeeType;  // Block is some kind of pointer type
10635618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  BlockPointerType(QualType Pointee, QualType CanonicalCls) :
10641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Type(BlockPointer, CanonicalCls, Pointee->isDependentType()),
1065898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    PointeeType(Pointee) {
10665618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  }
10675618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  friend class ASTContext;  // ASTContext creates these.
10685618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroffpublic:
10691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10705618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  // Get the pointee type. Pointee is required to always be a function type.
10715618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  QualType getPointeeType() const { return PointeeType; }
10725618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
10731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1074f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
10751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1076bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1077bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1078bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
10795618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  void Profile(llvm::FoldingSetNodeID &ID) {
10805618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff      Profile(ID, getPointeeType());
10815618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  }
10825618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
10835618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff      ID.AddPointer(Pointee.getAsOpaquePtr());
10845618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  }
10851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
10871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == BlockPointer;
10885618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  }
10895618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  static bool classof(const BlockPointerType *) { return true; }
10905618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff};
10915618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
10927c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl/// ReferenceType - Base for LValueReferenceType and RValueReferenceType
10935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
109468694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbarclass ReferenceType : public Type, public llvm::FoldingSetNode {
109568694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar  QualType PointeeType;
109668694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar
109754e14c4db764c0636160d26c5bbf491637c83a76John McCall  /// True if the type was originally spelled with an lvalue sigil.
109854e14c4db764c0636160d26c5bbf491637c83a76John McCall  /// This is never true of rvalue references but can also be false
109954e14c4db764c0636160d26c5bbf491637c83a76John McCall  /// on lvalue references because of C++0x [dcl.typedef]p9,
110054e14c4db764c0636160d26c5bbf491637c83a76John McCall  /// as follows:
110154e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///
110254e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///   typedef int &ref;    // lvalue, spelled lvalue
110354e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///   typedef int &&rvref; // rvalue
110454e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///   ref &a;              // lvalue, inner ref, spelled lvalue
110554e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///   ref &&a;             // lvalue, inner ref
110654e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///   rvref &a;            // lvalue, inner ref, spelled lvalue
110754e14c4db764c0636160d26c5bbf491637c83a76John McCall  ///   rvref &&a;           // rvalue, inner ref
110854e14c4db764c0636160d26c5bbf491637c83a76John McCall  bool SpelledAsLValue;
110954e14c4db764c0636160d26c5bbf491637c83a76John McCall
111054e14c4db764c0636160d26c5bbf491637c83a76John McCall  /// True if the inner type is a reference type.  This only happens
111154e14c4db764c0636160d26c5bbf491637c83a76John McCall  /// in non-canonical forms.
111254e14c4db764c0636160d26c5bbf491637c83a76John McCall  bool InnerRef;
111354e14c4db764c0636160d26c5bbf491637c83a76John McCall
11147c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlprotected:
111554e14c4db764c0636160d26c5bbf491637c83a76John McCall  ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
111654e14c4db764c0636160d26c5bbf491637c83a76John McCall                bool SpelledAsLValue) :
11177c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    Type(tc, CanonicalRef, Referencee->isDependentType()),
111854e14c4db764c0636160d26c5bbf491637c83a76John McCall    PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
111954e14c4db764c0636160d26c5bbf491637c83a76John McCall    InnerRef(Referencee->isReferenceType()) {
11205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
112254e14c4db764c0636160d26c5bbf491637c83a76John McCall  bool isSpelledAsLValue() const { return SpelledAsLValue; }
112354e14c4db764c0636160d26c5bbf491637c83a76John McCall
112454e14c4db764c0636160d26c5bbf491637c83a76John McCall  QualType getPointeeTypeAsWritten() const { return PointeeType; }
112554e14c4db764c0636160d26c5bbf491637c83a76John McCall  QualType getPointeeType() const {
112654e14c4db764c0636160d26c5bbf491637c83a76John McCall    // FIXME: this might strip inner qualifiers; okay?
112754e14c4db764c0636160d26c5bbf491637c83a76John McCall    const ReferenceType *T = this;
112854e14c4db764c0636160d26c5bbf491637c83a76John McCall    while (T->InnerRef)
112954e14c4db764c0636160d26c5bbf491637c83a76John McCall      T = T->PointeeType->getAs<ReferenceType>();
113054e14c4db764c0636160d26c5bbf491637c83a76John McCall    return T->PointeeType;
113154e14c4db764c0636160d26c5bbf491637c83a76John McCall  }
113268694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar
11335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
113454e14c4db764c0636160d26c5bbf491637c83a76John McCall    Profile(ID, PointeeType, SpelledAsLValue);
11355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
113654e14c4db764c0636160d26c5bbf491637c83a76John McCall  static void Profile(llvm::FoldingSetNodeID &ID,
113754e14c4db764c0636160d26c5bbf491637c83a76John McCall                      QualType Referencee,
113854e14c4db764c0636160d26c5bbf491637c83a76John McCall                      bool SpelledAsLValue) {
11395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(Referencee.getAsOpaquePtr());
114054e14c4db764c0636160d26c5bbf491637c83a76John McCall    ID.AddBoolean(SpelledAsLValue);
11415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11437c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  static bool classof(const Type *T) {
11447c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return T->getTypeClass() == LValueReference ||
11457c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl           T->getTypeClass() == RValueReference;
11467c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  }
11475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const ReferenceType *) { return true; }
11487c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl};
11497c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
11507c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
11517c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl///
11527c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlclass LValueReferenceType : public ReferenceType {
115354e14c4db764c0636160d26c5bbf491637c83a76John McCall  LValueReferenceType(QualType Referencee, QualType CanonicalRef,
115454e14c4db764c0636160d26c5bbf491637c83a76John McCall                      bool SpelledAsLValue) :
115554e14c4db764c0636160d26c5bbf491637c83a76John McCall    ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
115654e14c4db764c0636160d26c5bbf491637c83a76John McCall  {}
11577c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  friend class ASTContext; // ASTContext creates these
11587c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlpublic:
11591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1160f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
11617c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1162bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1163bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1164bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
11657c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  static bool classof(const Type *T) {
11667c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return T->getTypeClass() == LValueReference;
11677c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  }
11687c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  static bool classof(const LValueReferenceType *) { return true; }
11697c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl};
11707c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
11717c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference
11727c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl///
11737c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlclass RValueReferenceType : public ReferenceType {
11747c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
117554e14c4db764c0636160d26c5bbf491637c83a76John McCall    ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
11767c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  }
11777c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  friend class ASTContext; // ASTContext creates these
11787c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlpublic:
11791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1180f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
11817c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1182bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1183bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1184bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
11857c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  static bool classof(const Type *T) {
11867c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return T->getTypeClass() == RValueReference;
11877c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  }
11887c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  static bool classof(const RValueReferenceType *) { return true; }
1189f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl};
1190f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1191f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl/// MemberPointerType - C++ 8.3.3 - Pointers to members
1192f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl///
1193f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlclass MemberPointerType : public Type, public llvm::FoldingSetNode {
1194f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  QualType PointeeType;
1195f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  /// The class of which the pointee is a member. Must ultimately be a
1196f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  /// RecordType, but could be a typedef or a template parameter too.
1197f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  const Type *Class;
1198f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1199f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
1200f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    Type(MemberPointer, CanonicalPtr,
1201f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl         Cls->isDependentType() || Pointee->isDependentType()),
1202f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    PointeeType(Pointee), Class(Cls) {
1203f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  }
1204f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  friend class ASTContext; // ASTContext creates these.
1205f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlpublic:
1206f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1207f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  QualType getPointeeType() const { return PointeeType; }
1208f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1209f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  const Type *getClass() const { return Class; }
1210f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
12111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1212f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
1213f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1214bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1215bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1216bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
1217f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  void Profile(llvm::FoldingSetNodeID &ID) {
1218f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    Profile(ID, getPointeeType(), getClass());
1219f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  }
1220f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
1221f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl                      const Type *Class) {
1222f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    ID.AddPointer(Pointee.getAsOpaquePtr());
1223f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    ID.AddPointer(Class);
1224f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  }
1225f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1226f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  static bool classof(const Type *T) {
1227f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    return T->getTypeClass() == MemberPointer;
1228f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  }
1229f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  static bool classof(const MemberPointerType *) { return true; }
12305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
12315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ArrayType - C99 6.7.5.2 - Array Declarators.
12335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
12342e7d352dbec06755105237afba183492d31d03cbTed Kremenekclass ArrayType : public Type, public llvm::FoldingSetNode {
12355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
12365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
1237898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// an array with a static size (e.g. int X[static 4]), or an array
1238898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// with a star size (e.g. int X[*]).
1239898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// 'static' is only allowed on function parameters.
12405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum ArraySizeModifier {
12415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Normal, Static, Star
12425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
12435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
1244fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  /// ElementType - The element type of the array.
1245fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  QualType ElementType;
12461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1247ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
1248c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  /// NOTE: These fields are packed into the bitfields space in the Type class.
1249ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned SizeModifier : 2;
12501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1251c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  /// IndexTypeQuals - Capture qualifiers in declarations like:
1252c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  /// 'int X[static restrict 4]'. For function parameters only.
1253c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  unsigned IndexTypeQuals : 3;
12541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1255fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroffprotected:
1256898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  // C++ [temp.dep.type]p1:
1257898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  //   A type is dependent if it is...
1258898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  //     - an array type constructed from any dependent type or whose
1259898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  //       size is specified by a constant expression that is
1260898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  //       value-dependent,
1261c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  ArrayType(TypeClass tc, QualType et, QualType can,
1262c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff            ArraySizeModifier sm, unsigned tq)
1263898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    : Type(tc, can, et->isDependentType() || tc == DependentSizedArray),
1264898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
1265898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1266fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  friend class ASTContext;  // ASTContext creates these.
1267fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroffpublic:
1268fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  QualType getElementType() const { return ElementType; }
1269ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  ArraySizeModifier getSizeModifier() const {
1270ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek    return ArraySizeModifier(SizeModifier);
1271ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
12720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qualifiers getIndexTypeQualifiers() const {
12730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return Qualifiers::fromCVRMask(IndexTypeQuals);
12740953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
12750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1277fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  static bool classof(const Type *T) {
1278fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    return T->getTypeClass() == ConstantArray ||
1279c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman           T->getTypeClass() == VariableArray ||
1280898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor           T->getTypeClass() == IncompleteArray ||
1281898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor           T->getTypeClass() == DependentSizedArray;
1282fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  }
1283fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  static bool classof(const ArrayType *) { return true; }
1284fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff};
1285fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
12867e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor/// ConstantArrayType - This class represents the canonical version of
12877e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor/// C arrays with a specified constant size.  For example, the canonical
12887e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element
12897e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor/// type is 'int' and the size is 404.
12902e7d352dbec06755105237afba183492d31d03cbTed Kremenekclass ConstantArrayType : public ArrayType {
1291fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  llvm::APInt Size; // Allows us to unique the type.
12921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12930be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner  ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
1294c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                    ArraySizeModifier sm, unsigned tq)
12957e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    : ArrayType(ConstantArray, et, can, sm, tq),
12967e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor      Size(size) {}
12977e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregorprotected:
12987e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  ConstantArrayType(TypeClass tc, QualType et, QualType can,
12997e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor                    const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
13007e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    : ArrayType(tc, et, can, sm, tq), Size(size) {}
1301fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  friend class ASTContext;  // ASTContext creates these.
1302fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroffpublic:
1303c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  const llvm::APInt &getSize() const { return Size; }
13041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1305f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1307bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1308bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1309bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
1310fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  void Profile(llvm::FoldingSetNodeID &ID) {
13111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Profile(ID, getElementType(), getSize(),
13120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall            getSizeModifier(), getIndexTypeCVRQualifiers());
1313fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  }
1314fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
13150be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner                      const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
13160be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner                      unsigned TypeQuals) {
1317fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    ID.AddPointer(ET.getAsOpaquePtr());
1318fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    ID.AddInteger(ArraySize.getZExtValue());
13190be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner    ID.AddInteger(SizeMod);
13200be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner    ID.AddInteger(TypeQuals);
1321fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  }
13227e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  static bool classof(const Type *T) {
132346a617a792bfab0d9b1e057371ea3b9540802226John McCall    return T->getTypeClass() == ConstantArray;
1324fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  }
1325fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  static bool classof(const ConstantArrayType *) { return true; }
1326fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff};
1327fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
1328da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// IncompleteArrayType - This class represents C arrays with an unspecified
1329da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// size.  For example 'int A[]' has an IncompleteArrayType where the element
1330da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// type is 'int' and the size is unspecified.
1331c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedmanclass IncompleteArrayType : public ArrayType {
13327e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor
1333c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  IncompleteArrayType(QualType et, QualType can,
13347e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor                      ArraySizeModifier sm, unsigned tq)
1335c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    : ArrayType(IncompleteArray, et, can, sm, tq) {}
1336c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  friend class ASTContext;  // ASTContext creates these.
1337c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedmanpublic:
13381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1339f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
1340c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
1341bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1342bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1343bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
13441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
13451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == IncompleteArray;
1346c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  }
1347c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  static bool classof(const IncompleteArrayType *) { return true; }
13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1349c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  friend class StmtIteratorBase;
13501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1351c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  void Profile(llvm::FoldingSetNodeID &ID) {
13520953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Profile(ID, getElementType(), getSizeModifier(),
13530953e767ff7817f97b3ab20896b229891eeff45bJohn McCall            getIndexTypeCVRQualifiers());
1354c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  }
13551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13560be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
13570be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner                      ArraySizeModifier SizeMod, unsigned TypeQuals) {
1358c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    ID.AddPointer(ET.getAsOpaquePtr());
13590be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner    ID.AddInteger(SizeMod);
13600be2ef2321b1283ead38ebeb83b451335d90e0feChris Lattner    ID.AddInteger(TypeQuals);
1361c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  }
1362c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman};
1363c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
1364da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// VariableArrayType - This class represents C arrays with a specified size
1365da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// which is not an integer-constant-expression.  For example, 'int s[x+foo()]'.
1366da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// Since the size expression is an arbitrary expression, we store it as such.
1367da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner///
1368da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
1369da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// should not be: two lexically equivalent variable array types could mean
1370da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// different things, for example, these variables do not have the same type
1371da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// dynamically:
1372da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner///
1373da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// void foo(int x) {
1374da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner///   int Y[x];
1375da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner///   ++x;
1376da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner///   int Z[x];
1377da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner/// }
1378da2d71a50fe724c881b148fcc2c05a5e9b56e3a5Chris Lattner///
13792e7d352dbec06755105237afba183492d31d03cbTed Kremenekclass VariableArrayType : public ArrayType {
13801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// SizeExpr - An assignment expression. VLA's are only permitted within
13811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// a function block.
1382b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek  Stmt *SizeExpr;
13837e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  /// Brackets - The left and right array brackets.
13847e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceRange Brackets;
13857e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor
1386c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  VariableArrayType(QualType et, QualType can, Expr *e,
13877e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor                    ArraySizeModifier sm, unsigned tq,
13887e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor                    SourceRange brackets)
13897e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    : ArrayType(VariableArray, et, can, sm, tq),
13907e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor      SizeExpr((Stmt*) e), Brackets(brackets) {}
13915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
13924b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek  virtual void Destroy(ASTContext& C);
13934b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek
13945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Expr *getSizeExpr() const {
1396b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek    // We use C-style casts instead of cast<> here because we do not wish
1397b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek    // to have a dependency of Type.h on Stmt.h/Expr.h.
1398b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek    return (Expr*) SizeExpr;
1399b3064041583eb134fbf56906728bf752bc65b572Ted Kremenek  }
14007e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceRange getBracketsRange() const { return Brackets; }
14017e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
14027e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
14031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1405f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
14061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1407bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1408bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1409bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
14101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
14111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == VariableArray;
14125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1413fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  static bool classof(const VariableArrayType *) { return true; }
14141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
141592866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  friend class StmtIteratorBase;
14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14172bd24ba6d10f8c811c8e2a57c8397e07082ba497Ted Kremenek  void Profile(llvm::FoldingSetNodeID &ID) {
1418bc5e150b6d94cf131f7d01bc715571b741c5b408Chris Lattner    assert(0 && "Cannnot unique VariableArrayTypes.");
14192bd24ba6d10f8c811c8e2a57c8397e07082ba497Ted Kremenek  }
14205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
14215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1422898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// DependentSizedArrayType - This type represents an array type in
1423898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// C++ whose size is a value-dependent expression. For example:
1424898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// @code
14251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<typename T, int Size>
1426898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// class array {
1427898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor///   T data[Size];
1428898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// };
1429898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// @endcode
1430898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// For these types, we won't actually know what the array bound is
1431898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// until template instantiation occurs, at which point this will
1432898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// become either a ConstantArrayType or a VariableArrayType.
1433898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorclass DependentSizedArrayType : public ArrayType {
143404d4beee4b86af20a9e4457023d3925cab8f9908Douglas Gregor  ASTContext &Context;
14351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1436898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// SizeExpr - An assignment expression that will instantiate to the
1437898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// size of the array.
1438898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  Stmt *SizeExpr;
14397e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  /// Brackets - The left and right array brackets.
14407e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceRange Brackets;
14411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DependentSizedArrayType(ASTContext &Context, QualType et, QualType can,
144304d4beee4b86af20a9e4457023d3925cab8f9908Douglas Gregor                          Expr *e, ArraySizeModifier sm, unsigned tq,
14447e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor                          SourceRange brackets)
14457e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    : ArrayType(DependentSizedArray, et, can, sm, tq),
144604d4beee4b86af20a9e4457023d3925cab8f9908Douglas Gregor      Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
1447898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  friend class ASTContext;  // ASTContext creates these.
1448898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  virtual void Destroy(ASTContext& C);
1449898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1450898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorpublic:
14511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Expr *getSizeExpr() const {
1452898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    // We use C-style casts instead of cast<> here because we do not wish
1453898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    // to have a dependency of Type.h on Stmt.h/Expr.h.
1454898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    return (Expr*) SizeExpr;
1455898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
14567e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceRange getBracketsRange() const { return Brackets; }
14577e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
14587e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
14591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1461f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
14621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1463bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1464bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1465bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
14661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
14671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == DependentSizedArray;
1468898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
1469898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  static bool classof(const DependentSizedArrayType *) { return true; }
14701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1471898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  friend class StmtIteratorBase;
14721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1474898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
14751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Profile(ID, Context, getElementType(),
14760953e767ff7817f97b3ab20896b229891eeff45bJohn McCall            getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
1477898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
14781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
14801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                      QualType ET, ArraySizeModifier SizeMod,
148104d4beee4b86af20a9e4457023d3925cab8f9908Douglas Gregor                      unsigned TypeQuals, Expr *E);
1482898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor};
1483898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1484f6ddb737cb882ffbf0b75a9abd50b930cc2b9068Douglas Gregor/// DependentSizedExtVectorType - This type represent an extended vector type
14859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor/// where either the type or size is dependent. For example:
14869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor/// @code
14879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor/// template<typename T, int Size>
14889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor/// class vector {
14899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor///   typedef T __attribute__((ext_vector_type(Size))) type;
14909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor/// }
14919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor/// @endcode
14922ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregorclass DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
14932ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor  ASTContext &Context;
14949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *SizeExpr;
14959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  /// ElementType - The element type of the array.
14969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  QualType ElementType;
14979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  SourceLocation loc;
14981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DependentSizedExtVectorType(ASTContext &Context, QualType ElementType,
15002ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor                              QualType can, Expr *SizeExpr, SourceLocation loc)
15011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Type (DependentSizedExtVector, can, true),
15021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
15032ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor      loc(loc) {}
15049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  friend class ASTContext;
15059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  virtual void Destroy(ASTContext& C);
15069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
15079cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorpublic:
15082ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor  Expr *getSizeExpr() const { return SizeExpr; }
15099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  QualType getElementType() const { return ElementType; }
15109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  SourceLocation getAttributeLoc() const { return loc; }
15119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1513f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
15141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1515bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1516bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1517bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
15181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == DependentSizedExtVector;
15209cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  }
15211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const DependentSizedExtVectorType *) { return true; }
15222ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor
15232ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
15242ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor    Profile(ID, Context, getElementType(), getSizeExpr());
15252ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor  }
15261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15272ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
15282ec09f1dc123e1942ed756e8ee4fef86451eac9eDouglas Gregor                      QualType ElementType, Expr *SizeExpr);
15299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor};
15301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
153273322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// VectorType - GCC generic vector type. This type is created using
15331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// __attribute__((vector_size(n)), where "n" specifies the vector size in
15341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// bytes. Since the constructor takes the number of vector elements, the
153573322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// client is responsible for converting the size into the number of elements.
15365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass VectorType : public Type, public llvm::FoldingSetNode {
153773322924127c873c13101b705dd823f5539ffa5fSteve Naroffprotected:
15385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ElementType - The element type of the vector.
15395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ElementType;
15401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NumElements - The number of elements in the vector.
15425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumElements;
15431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
154473322924127c873c13101b705dd823f5539ffa5fSteve Naroff  VectorType(QualType vecType, unsigned nElements, QualType canonType) :
15451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Type(Vector, canonType, vecType->isDependentType()),
15461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ElementType(vecType), NumElements(nElements) {}
15471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  VectorType(TypeClass tc, QualType vecType, unsigned nElements,
15481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump             QualType canonType)
15491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
15501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      NumElements(nElements) {}
15515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
15525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
15531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getElementType() const { return ElementType; }
15551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned getNumElements() const { return NumElements; }
15565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
15571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1558f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
15591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1560bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1561bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1562bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
15635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
156473322924127c873c13101b705dd823f5539ffa5fSteve Naroff    Profile(ID, getElementType(), getNumElements(), getTypeClass());
15655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
15661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
156773322924127c873c13101b705dd823f5539ffa5fSteve Naroff                      unsigned NumElements, TypeClass TypeClass) {
15685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ElementType.getAsOpaquePtr());
15695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddInteger(NumElements);
157073322924127c873c13101b705dd823f5539ffa5fSteve Naroff    ID.AddInteger(TypeClass);
157173322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
15721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
15731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
15745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
15755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const VectorType *) { return true; }
15765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
15775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1578213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman/// ExtVectorType - Extended vector type. This type is created using
1579213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
1580213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
1581fcac0fff877a461bc5d5a57e6c6727a4c819d95aSteve Naroff/// class enables syntactic extensions, like Vector Components for accessing
1582fcac0fff877a461bc5d5a57e6c6727a4c819d95aSteve Naroff/// points, colors, and textures (modeled after OpenGL Shading Language).
1583213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begemanclass ExtVectorType : public VectorType {
1584213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
15851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    VectorType(ExtVector, vecType, nElements, canonType) {}
158673322924127c873c13101b705dd823f5539ffa5fSteve Naroff  friend class ASTContext;  // ASTContext creates these.
158773322924127c873c13101b705dd823f5539ffa5fSteve Naroffpublic:
158888dca0464804b8b26ae605f89784c927e8493dddChris Lattner  static int getPointAccessorIdx(char c) {
158988dca0464804b8b26ae605f89784c927e8493dddChris Lattner    switch (c) {
159088dca0464804b8b26ae605f89784c927e8493dddChris Lattner    default: return -1;
159188dca0464804b8b26ae605f89784c927e8493dddChris Lattner    case 'x': return 0;
159288dca0464804b8b26ae605f89784c927e8493dddChris Lattner    case 'y': return 1;
159388dca0464804b8b26ae605f89784c927e8493dddChris Lattner    case 'z': return 2;
159488dca0464804b8b26ae605f89784c927e8493dddChris Lattner    case 'w': return 3;
159588dca0464804b8b26ae605f89784c927e8493dddChris Lattner    }
1596e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
1597353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman  static int getNumericAccessorIdx(char c) {
159888dca0464804b8b26ae605f89784c927e8493dddChris Lattner    switch (c) {
1599353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      default: return -1;
1600353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '0': return 0;
1601353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '1': return 1;
1602353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '2': return 2;
1603353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '3': return 3;
1604353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '4': return 4;
1605353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '5': return 5;
1606353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '6': return 6;
1607353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '7': return 7;
1608353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '8': return 8;
1609353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case '9': return 9;
1610131f4658249b2a7d2d7e30fe07e84c484f79ef99Nate Begeman      case 'A':
1611353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case 'a': return 10;
1612131f4658249b2a7d2d7e30fe07e84c484f79ef99Nate Begeman      case 'B':
1613353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case 'b': return 11;
1614131f4658249b2a7d2d7e30fe07e84c484f79ef99Nate Begeman      case 'C':
1615353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case 'c': return 12;
1616131f4658249b2a7d2d7e30fe07e84c484f79ef99Nate Begeman      case 'D':
1617353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case 'd': return 13;
1618131f4658249b2a7d2d7e30fe07e84c484f79ef99Nate Begeman      case 'E':
1619353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case 'e': return 14;
1620131f4658249b2a7d2d7e30fe07e84c484f79ef99Nate Begeman      case 'F':
1621353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman      case 'f': return 15;
162288dca0464804b8b26ae605f89784c927e8493dddChris Lattner    }
1623e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
16241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1625b8f849da3cedee2f61ad98389115ddd04e439d60Chris Lattner  static int getAccessorIdx(char c) {
1626b8f849da3cedee2f61ad98389115ddd04e439d60Chris Lattner    if (int idx = getPointAccessorIdx(c)+1) return idx-1;
1627353417af9d254d4fd0eb7d0a3ff71c4d8594ac58Nate Begeman    return getNumericAccessorIdx(c);
1628b8f849da3cedee2f61ad98389115ddd04e439d60Chris Lattner  }
16291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
163088dca0464804b8b26ae605f89784c927e8493dddChris Lattner  bool isAccessorWithinNumElements(char c) const {
1631b8f849da3cedee2f61ad98389115ddd04e439d60Chris Lattner    if (int idx = getAccessorIdx(c)+1)
163288dca0464804b8b26ae605f89784c927e8493dddChris Lattner      return unsigned(idx-1) < NumElements;
163388dca0464804b8b26ae605f89784c927e8493dddChris Lattner    return false;
1634e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
16351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1636f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
163731a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff
1638bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1639bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1640bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
16411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
16421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == ExtVector;
164373322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
1644213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  static bool classof(const ExtVectorType *) { return true; }
164573322924127c873c13101b705dd823f5539ffa5fSteve Naroff};
164673322924127c873c13101b705dd823f5539ffa5fSteve Naroff
16475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
164872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor/// class of FunctionNoProtoType and FunctionProtoType.
16495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
16505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FunctionType : public Type {
16515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SubClassData - This field is owned by the subclass, put here to pack
16525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tightly with the ivars in Type.
16535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool SubClassData : 1;
1654971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis
165572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  /// TypeQuals - Used only by FunctionProtoType, put here to pack with the
1656971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  /// other bitfields.
165772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  /// The qualifiers are part of FunctionProtoType because...
1658971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  ///
1659971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  /// C++ 8.3.5p4: The return type, the parameter type list and the
1660971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  /// cv-qualifier-seq, [...], are part of the function type.
1661971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  ///
1662971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  unsigned TypeQuals : 3;
16632455636163fdd18581d7fdae816433f886d88213Mike Stump
16642455636163fdd18581d7fdae816433f886d88213Mike Stump  /// NoReturn - Indicates if the function type is attribute noreturn.
16652455636163fdd18581d7fdae816433f886d88213Mike Stump  unsigned NoReturn : 1;
16661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // The type returned by the function.
16685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType ResultType;
16695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
1670971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
16712455636163fdd18581d7fdae816433f886d88213Mike Stump               unsigned typeQuals, QualType Canonical, bool Dependent,
16722455636163fdd18581d7fdae816433f886d88213Mike Stump               bool noReturn = false)
1673898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    : Type(tc, Canonical, Dependent),
16742455636163fdd18581d7fdae816433f886d88213Mike Stump      SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn),
16752455636163fdd18581d7fdae816433f886d88213Mike Stump      ResultType(res) {}
16765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool getSubClassData() const { return SubClassData; }
1677971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  unsigned getTypeQuals() const { return TypeQuals; }
16785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
16791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getResultType() const { return ResultType; }
16812455636163fdd18581d7fdae816433f886d88213Mike Stump  bool getNoReturnAttr() const { return NoReturn; }
16825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
16835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) {
16845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getTypeClass() == FunctionNoProto ||
16855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           T->getTypeClass() == FunctionProto;
16865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
16875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const FunctionType *) { return true; }
16885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
16895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
169072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
16915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// no information available about its arguments.
169272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorclass FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
16932455636163fdd18581d7fdae816433f886d88213Mike Stump  FunctionNoProtoType(QualType Result, QualType Canonical,
16942455636163fdd18581d7fdae816433f886d88213Mike Stump                      bool NoReturn = false)
16951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : FunctionType(FunctionNoProto, Result, false, 0, Canonical,
16962455636163fdd18581d7fdae816433f886d88213Mike Stump                   /*Dependent=*/false, NoReturn) {}
16975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
16985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
16995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // No additional state past what FunctionType provides.
17001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1702f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
17035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1704bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1705bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1706bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
17075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID) {
17082455636163fdd18581d7fdae816433f886d88213Mike Stump    Profile(ID, getResultType(), getNoReturnAttr());
17095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
17102455636163fdd18581d7fdae816433f886d88213Mike Stump  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
17112455636163fdd18581d7fdae816433f886d88213Mike Stump                      bool NoReturn) {
17122455636163fdd18581d7fdae816433f886d88213Mike Stump    ID.AddInteger(NoReturn);
17135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ResultType.getAsOpaquePtr());
17145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
17151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) {
17175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getTypeClass() == FunctionNoProto;
17185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
171972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const FunctionNoProtoType *) { return true; }
17205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
17215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
172272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor/// FunctionProtoType - Represents a prototype with argument type info, e.g.
17235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
1724465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl/// arguments, not as having a single void argument. Such a type can have an
1725465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl/// exception specification, but this specification is not part of the canonical
1726465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl/// type.
172772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorclass FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
1728898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// hasAnyDependentType - Determine whether there are any dependent
1729898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  /// types within the arguments passed in.
1730898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) {
1731898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    for (unsigned Idx = 0; Idx < numArgs; ++Idx)
1732898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      if (ArgArray[Idx]->isDependentType())
17334b4218f48fef71a179c5a8287dae281580faf52fNate Begeman    return true;
1734898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1735898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    return false;
1736898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
1737898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
173872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
1739465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                    bool isVariadic, unsigned typeQuals, bool hasExs,
1740465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                    bool hasAnyExs, const QualType *ExArray,
17412455636163fdd18581d7fdae816433f886d88213Mike Stump                    unsigned numExs, QualType Canonical, bool NoReturn)
1742898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
17431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                   (Result->isDependentType() ||
17442455636163fdd18581d7fdae816433f886d88213Mike Stump                    hasAnyDependentType(ArgArray, numArgs)), NoReturn),
1745465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs),
1746465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      AnyExceptionSpec(hasAnyExs) {
1747942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    // Fill in the trailing argument array.
1748465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    QualType *ArgInfo = reinterpret_cast<QualType*>(this+1);
17495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    for (unsigned i = 0; i != numArgs; ++i)
17505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ArgInfo[i] = ArgArray[i];
1751465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    // Fill in the exception array.
1752465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    QualType *Ex = ArgInfo + numArgs;
1753465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    for (unsigned i = 0; i != numExs; ++i)
1754465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      Ex[i] = ExArray[i];
17555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1756465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
17575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NumArgs - The number of arguments this function has, not counting '...'.
1758465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  unsigned NumArgs : 20;
1759465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1760465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  /// NumExceptions - The number of types in the exception spec, if any.
1761465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  unsigned NumExceptions : 10;
1762465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1763465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  /// HasExceptionSpec - Whether this function has an exception spec at all.
1764465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  bool HasExceptionSpec : 1;
1765465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1766465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  /// AnyExceptionSpec - Whether this function has a throw(...) spec.
1767465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  bool AnyExceptionSpec : 1;
1768465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1769942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  /// ArgInfo - There is an variable size array after the class in memory that
1770942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  /// holds the argument types.
1771465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1772465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  /// Exceptions - There is another variable size array after ArgInfo that
1773465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  /// holds the exception types.
1774465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
17755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
17764b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek
17775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
17785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getNumArgs() const { return NumArgs; }
17795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType getArgType(unsigned i) const {
17805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(i < NumArgs && "Invalid argument number!");
1781942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    return arg_type_begin()[i];
17825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1783465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1784465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  bool hasExceptionSpec() const { return HasExceptionSpec; }
1785465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  bool hasAnyExceptionSpec() const { return AnyExceptionSpec; }
1786465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  unsigned getNumExceptions() const { return NumExceptions; }
1787465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  QualType getExceptionType(unsigned i) const {
1788465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    assert(i < NumExceptions && "Invalid exception number!");
1789465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    return exception_begin()[i];
1790465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  }
17911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool hasEmptyExceptionSpec() const {
17921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return hasExceptionSpec() && !hasAnyExceptionSpec() &&
1793a12823f6c0ec9e0e644a9d0ee153e973f49c63fcAnders Carlsson      getNumExceptions() == 0;
1794d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
1795465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
17965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isVariadic() const { return getSubClassData(); }
1797971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
17981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef const QualType *arg_type_iterator;
1800942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  arg_type_iterator arg_type_begin() const {
1801942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    return reinterpret_cast<const QualType *>(this+1);
1802942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  }
1803942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
1804465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
1805465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  typedef const QualType *exception_iterator;
1806465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  exception_iterator exception_begin() const {
1807465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    // exceptions begin where arguments end
1808465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    return arg_type_end();
1809465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  }
1810465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  exception_iterator exception_end() const {
1811465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    return exception_begin() + NumExceptions;
1812465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  }
1813465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
18141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1815f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
18165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1817bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1818bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1819bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
18205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Type *T) {
18215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getTypeClass() == FunctionProto;
18225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
182372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const FunctionProtoType *) { return true; }
1824465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
18255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID);
18265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
1827942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner                      arg_type_iterator ArgTys, unsigned NumArgs,
1828465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                      bool isVariadic, unsigned TypeQuals,
1829465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                      bool hasExceptionSpec, bool anyExceptionSpec,
18302455636163fdd18581d7fdae816433f886d88213Mike Stump                      unsigned NumExceptions, exception_iterator Exs,
18312455636163fdd18581d7fdae816433f886d88213Mike Stump                      bool NoReturn);
18325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
18335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TypedefType : public Type {
18365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypedefDecl *Decl;
1837c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanianprotected:
18381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TypedefType(TypeClass tc, TypedefDecl *D, QualType can)
1839898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    : Type(tc, can, can->isDependentType()), Decl(D) {
18405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(!isa<TypedefType>(can) && "Invalid canonical type");
18415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
18425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  friend class ASTContext;  // ASTContext creates these.
18435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
18441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypedefDecl *getDecl() const { return Decl; }
18461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1847a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
1848fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  /// potentially looking through *all* consecutive typedefs.  This returns the
1849a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// sum of the type qualifiers, so if you have:
1850a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  ///   typedef const int A;
1851a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  ///   typedef volatile A B;
1852a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// looking through the typedefs for B will give you "const volatile A".
1853a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  QualType LookThroughTypedefs() const;
18541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1855bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return true; }
1856bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const;
1857bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
18581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1859f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
18605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
186172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
18625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const TypedefType *) { return true; }
18635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
18645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
186572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor/// TypeOfExprType (GCC extension).
186672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorclass TypeOfExprType : public Type {
1867d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  Expr *TOExpr;
18681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1869b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregorprotected:
1870dd0257c77719a13d4acd513df40b04300cbfc871Douglas Gregor  TypeOfExprType(Expr *E, QualType can = QualType());
1871d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  friend class ASTContext;  // ASTContext creates these.
1872d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroffpublic:
1873d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  Expr *getUnderlyingExpr() const { return TOExpr; }
18741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1875bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Remove a single level of sugar.
1876bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const;
1877bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
1878bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Returns whether this type directly provides sugar.
1879bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return true; }
1880bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
18811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1882f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
1883d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
188472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
188572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const TypeOfExprType *) { return true; }
1886d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff};
1887d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
18881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Subclass of TypeOfExprType that is used for canonical, dependent
18891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// typeof(expr) types.
18901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass DependentTypeOfExprType
1891b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor  : public TypeOfExprType, public llvm::FoldingSetNode {
1892b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor  ASTContext &Context;
18931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1894b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregorpublic:
18951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DependentTypeOfExprType(ASTContext &Context, Expr *E)
1896b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor    : TypeOfExprType(E), Context(Context) { }
18971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1898bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1899bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1900bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
1901b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
1902b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor    Profile(ID, Context, getUnderlyingExpr());
1903b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor  }
19041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1905b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
1906b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor                      Expr *E);
1907b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor};
19081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1909d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff/// TypeOfType (GCC extension).
1910d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroffclass TypeOfType : public Type {
1911d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  QualType TOType;
19121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TypeOfType(QualType T, QualType can)
191372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    : Type(TypeOf, can, T->isDependentType()), TOType(T) {
1914d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff    assert(!isa<TypedefType>(can) && "Invalid canonical type");
1915d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  }
1916d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  friend class ASTContext;  // ASTContext creates these.
1917d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroffpublic:
1918d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  QualType getUnderlyingType() const { return TOType; }
19191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1920bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Remove a single level of sugar.
1921bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return getUnderlyingType(); }
1922bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
1923bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Returns whether this type directly provides sugar.
1924bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return true; }
1925bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
19261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1927f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
1928d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
192972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
1930d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  static bool classof(const TypeOfType *) { return true; }
1931d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff};
19325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1933395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson/// DecltypeType (C++0x)
1934395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlssonclass DecltypeType : public Type {
1935395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  Expr *E;
19361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1937563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  // FIXME: We could get rid of UnderlyingType if we wanted to: We would have to
1938563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  // Move getDesugaredType to ASTContext so that it can call getDecltypeForExpr
1939563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  // from it.
1940563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  QualType UnderlyingType;
19411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19429d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregorprotected:
1943563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
1944395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  friend class ASTContext;  // ASTContext creates these.
1945395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlssonpublic:
1946395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  Expr *getUnderlyingExpr() const { return E; }
1947563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  QualType getUnderlyingType() const { return UnderlyingType; }
1948563a03b1338d31c2462def43253a722bc885d384Anders Carlsson
1949bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Remove a single level of sugar.
1950bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return getUnderlyingType(); }
1951bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
1952bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Returns whether this type directly provides sugar.
1953bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return !isDependentType(); }
1954bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
19551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
1956395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson                                   const PrintingPolicy &Policy) const;
19571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1958395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
1959395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  static bool classof(const DecltypeType *) { return true; }
1960395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson};
19611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Subclass of DecltypeType that is used for canonical, dependent
19631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// C++0x decltype types.
19649d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregorclass DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
19659d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor  ASTContext &Context;
19661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19679d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregorpublic:
19689d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor  DependentDecltypeType(ASTContext &Context, Expr *E);
19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1970bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
1971bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
1972bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
19739d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
19749d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor    Profile(ID, Context, getUnderlyingExpr());
19759d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor  }
19761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19779d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
19781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                      Expr *E);
19799d702ae1cd5cfa19d884cbef77e1df99395138bbDouglas Gregor};
19801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TagType : public Type {
19820b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  /// Stores the TagDecl associated with this type. The decl will
19830b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  /// point to the TagDecl that actually defines the entity (or is a
19840b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  /// definition in progress), if there is such a definition. The
19850b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  /// single-bit value will be non-zero when this tag is in the
19860b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  /// process of being defined.
1987fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  mutable llvm::PointerIntPair<TagDecl *, 1> decl;
19884b7c98378ae0c1a3635f0b7756848b4a9923f8bcTed Kremenek  friend class ASTContext;
19890b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  friend class TagDecl;
19902ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor
19912ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregorprotected:
19927da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  TagType(TypeClass TC, TagDecl *D, QualType can);
19932ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor
19941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
19950b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  TagDecl *getDecl() const { return decl.getPointer(); }
19961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19970b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  /// @brief Determines whether this type is in the process of being
19981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// defined.
19990b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  bool isBeingDefined() const { return decl.getInt(); }
20000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
20010b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor
20021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
2003f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
2004e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
20051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
200672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
200772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  }
20085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const TagType *) { return true; }
200972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const RecordType *) { return true; }
201072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  static bool classof(const EnumType *) { return true; }
20115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
20125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
20135edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
20145edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner/// to detect TagType objects of structs/unions/classes.
20155edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattnerclass RecordType : public TagType {
201649aa7ff1245abd03e6e998e01302df31e4c6f8f6Argyrios Kyrtzidisprotected:
2017509447e7cb9c24a9f2bd149fe95030050b088622Argyrios Kyrtzidis  explicit RecordType(RecordDecl *D)
201872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    : TagType(Record, reinterpret_cast<TagDecl*>(D), QualType()) { }
201972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  explicit RecordType(TypeClass TC, RecordDecl *D)
202072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    : TagType(TC, reinterpret_cast<TagDecl*>(D), QualType()) { }
20212ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor  friend class ASTContext;   // ASTContext creates these.
20225edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattnerpublic:
20231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20245edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  RecordDecl *getDecl() const {
20255edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
20265edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  }
20271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // FIXME: This predicate is a helper to QualType/Type. It needs to
20295edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  // recursively check all fields for const-ness. If any field is declared
20301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // const, it needs to return false.
20315edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  bool hasConstFields() const { return false; }
20325edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner
20335edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  // FIXME: RecordType needs to check when it is created that all fields are in
20345edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  // the same address space, and return that.
20355edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  unsigned getAddressSpace() const { return 0; }
20361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2037bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
2038bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
2039bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
20402daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  static bool classof(const TagType *T);
20412daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  static bool classof(const Type *T) {
20422daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner    return isa<TagType>(T) && classof(cast<TagType>(T));
20432daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  }
20445edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  static bool classof(const RecordType *) { return true; }
20455edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner};
20465edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner
20475edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
20485edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner/// to detect TagType objects of enums.
20495edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattnerclass EnumType : public TagType {
2050509447e7cb9c24a9f2bd149fe95030050b088622Argyrios Kyrtzidis  explicit EnumType(EnumDecl *D)
205172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    : TagType(Enum, reinterpret_cast<TagDecl*>(D), QualType()) { }
20522ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor  friend class ASTContext;   // ASTContext creates these.
20535edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattnerpublic:
20541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20555edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  EnumDecl *getDecl() const {
20565edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner    return reinterpret_cast<EnumDecl*>(TagType::getDecl());
20575edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  }
20581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2059bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
2060bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
2061bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
20622daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  static bool classof(const TagType *T);
20632daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  static bool classof(const Type *T) {
20642daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner    return isa<TagType>(T) && classof(cast<TagType>(T));
20652daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  }
20665edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner  static bool classof(const EnumType *) { return true; }
20675edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner};
20685edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner
20697da2431c23ef1ee8acb114e39692246e1801afc2John McCall/// ElaboratedType - A non-canonical type used to represents uses of
20707da2431c23ef1ee8acb114e39692246e1801afc2John McCall/// elaborated type specifiers in C++.  For example:
20717da2431c23ef1ee8acb114e39692246e1801afc2John McCall///
20727da2431c23ef1ee8acb114e39692246e1801afc2John McCall///   void foo(union MyUnion);
20737da2431c23ef1ee8acb114e39692246e1801afc2John McCall///            ^^^^^^^^^^^^^
20747da2431c23ef1ee8acb114e39692246e1801afc2John McCall///
20757da2431c23ef1ee8acb114e39692246e1801afc2John McCall/// At the moment, for efficiency we do not create elaborated types in
20767da2431c23ef1ee8acb114e39692246e1801afc2John McCall/// C, since outside of typedefs all references to structs would
20777da2431c23ef1ee8acb114e39692246e1801afc2John McCall/// necessarily be elaborated.
20787da2431c23ef1ee8acb114e39692246e1801afc2John McCallclass ElaboratedType : public Type, public llvm::FoldingSetNode {
20797da2431c23ef1ee8acb114e39692246e1801afc2John McCallpublic:
20807da2431c23ef1ee8acb114e39692246e1801afc2John McCall  enum TagKind {
20817da2431c23ef1ee8acb114e39692246e1801afc2John McCall    TK_struct,
20827da2431c23ef1ee8acb114e39692246e1801afc2John McCall    TK_union,
20837da2431c23ef1ee8acb114e39692246e1801afc2John McCall    TK_class,
20847da2431c23ef1ee8acb114e39692246e1801afc2John McCall    TK_enum
20857da2431c23ef1ee8acb114e39692246e1801afc2John McCall  };
20867da2431c23ef1ee8acb114e39692246e1801afc2John McCall
20877da2431c23ef1ee8acb114e39692246e1801afc2John McCallprivate:
20887da2431c23ef1ee8acb114e39692246e1801afc2John McCall  /// The tag that was used in this elaborated type specifier.
20897da2431c23ef1ee8acb114e39692246e1801afc2John McCall  TagKind Tag;
20907da2431c23ef1ee8acb114e39692246e1801afc2John McCall
20917da2431c23ef1ee8acb114e39692246e1801afc2John McCall  /// The underlying type.
20927da2431c23ef1ee8acb114e39692246e1801afc2John McCall  QualType UnderlyingType;
20937da2431c23ef1ee8acb114e39692246e1801afc2John McCall
20947da2431c23ef1ee8acb114e39692246e1801afc2John McCall  explicit ElaboratedType(QualType Ty, TagKind Tag, QualType Canon)
20957da2431c23ef1ee8acb114e39692246e1801afc2John McCall    : Type(Elaborated, Canon, Canon->isDependentType()),
20967da2431c23ef1ee8acb114e39692246e1801afc2John McCall      Tag(Tag), UnderlyingType(Ty) { }
20977da2431c23ef1ee8acb114e39692246e1801afc2John McCall  friend class ASTContext;   // ASTContext creates these.
20987da2431c23ef1ee8acb114e39692246e1801afc2John McCall
20997da2431c23ef1ee8acb114e39692246e1801afc2John McCallpublic:
21007da2431c23ef1ee8acb114e39692246e1801afc2John McCall  TagKind getTagKind() const { return Tag; }
21017da2431c23ef1ee8acb114e39692246e1801afc2John McCall  QualType getUnderlyingType() const { return UnderlyingType; }
21027da2431c23ef1ee8acb114e39692246e1801afc2John McCall
2103bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Remove a single level of sugar.
2104bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return getUnderlyingType(); }
2105bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
2106bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Returns whether this type directly provides sugar.
2107bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return true; }
2108bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
21097da2431c23ef1ee8acb114e39692246e1801afc2John McCall  static const char *getNameForTagKind(TagKind Kind) {
21107da2431c23ef1ee8acb114e39692246e1801afc2John McCall    switch (Kind) {
21117da2431c23ef1ee8acb114e39692246e1801afc2John McCall    default: assert(0 && "Unknown TagKind!");
21127da2431c23ef1ee8acb114e39692246e1801afc2John McCall    case TK_struct: return "struct";
21137da2431c23ef1ee8acb114e39692246e1801afc2John McCall    case TK_union:  return "union";
21147da2431c23ef1ee8acb114e39692246e1801afc2John McCall    case TK_class:  return "class";
21157da2431c23ef1ee8acb114e39692246e1801afc2John McCall    case TK_enum:   return "enum";
21167da2431c23ef1ee8acb114e39692246e1801afc2John McCall    }
21177da2431c23ef1ee8acb114e39692246e1801afc2John McCall  }
21187da2431c23ef1ee8acb114e39692246e1801afc2John McCall
21191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
21207da2431c23ef1ee8acb114e39692246e1801afc2John McCall                                   const PrintingPolicy &Policy) const;
21217da2431c23ef1ee8acb114e39692246e1801afc2John McCall
21227da2431c23ef1ee8acb114e39692246e1801afc2John McCall  void Profile(llvm::FoldingSetNodeID &ID) {
21237da2431c23ef1ee8acb114e39692246e1801afc2John McCall    Profile(ID, getUnderlyingType(), getTagKind());
21247da2431c23ef1ee8acb114e39692246e1801afc2John McCall  }
21257da2431c23ef1ee8acb114e39692246e1801afc2John McCall  static void Profile(llvm::FoldingSetNodeID &ID, QualType T, TagKind Tag) {
21267da2431c23ef1ee8acb114e39692246e1801afc2John McCall    ID.AddPointer(T.getAsOpaquePtr());
21277da2431c23ef1ee8acb114e39692246e1801afc2John McCall    ID.AddInteger(Tag);
21287da2431c23ef1ee8acb114e39692246e1801afc2John McCall  }
21297da2431c23ef1ee8acb114e39692246e1801afc2John McCall
21307da2431c23ef1ee8acb114e39692246e1801afc2John McCall  static bool classof(const ElaboratedType*) { return true; }
21317da2431c23ef1ee8acb114e39692246e1801afc2John McCall  static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
21327da2431c23ef1ee8acb114e39692246e1801afc2John McCall};
21337da2431c23ef1ee8acb114e39692246e1801afc2John McCall
2134fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregorclass TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
213576e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson  unsigned Depth : 15;
2136fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  unsigned Index : 16;
213776e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson  unsigned ParameterPack : 1;
2138fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  IdentifierInfo *Name;
213972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
21401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N,
21411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       QualType Canon)
2142fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    : Type(TemplateTypeParm, Canon, /*Dependent=*/true),
214376e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson      Depth(D), Index(I), ParameterPack(PP), Name(N) { }
214472c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
21451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TemplateTypeParmType(unsigned D, unsigned I, bool PP)
2146fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true),
214776e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson      Depth(D), Index(I), ParameterPack(PP), Name(0) { }
214872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
2149fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  friend class ASTContext;  // ASTContext creates these
215072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
2151fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregorpublic:
2152fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  unsigned getDepth() const { return Depth; }
2153fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  unsigned getIndex() const { return Index; }
215476e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson  bool isParameterPack() const { return ParameterPack; }
2155fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  IdentifierInfo *getName() const { return Name; }
21561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
2158f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
21595edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner
2160bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
2161bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
2162bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
2163fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
216476e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson    Profile(ID, Depth, Index, ParameterPack, Name);
2165fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  }
2166fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
21671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
21681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                      unsigned Index, bool ParameterPack,
216976e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson                      IdentifierInfo *Name) {
2170fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    ID.AddInteger(Depth);
2171fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    ID.AddInteger(Index);
217276e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson    ID.AddBoolean(ParameterPack);
2173fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    ID.AddPointer(Name);
2174fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  }
2175fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
21761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
21771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == TemplateTypeParm;
217872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  }
217972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  static bool classof(const TemplateTypeParmType *T) { return true; }
218072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor};
2181fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
218249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall/// \brief Represents the result of substituting a type for a template
218349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall/// type parameter.
218449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall///
218549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall/// Within an instantiated template, all template type parameters have
218649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall/// been replaced with these.  They are used solely to record that a
218749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall/// type was originally written as a template type parameter;
218849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall/// therefore they are never canonical.
218949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCallclass SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
219049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  // The original type parameter.
219149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  const TemplateTypeParmType *Replaced;
219249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
219349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
219449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType()),
219549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall      Replaced(Param) { }
219649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
219749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  friend class ASTContext;
219849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
219949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCallpublic:
220049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  IdentifierInfo *getName() const { return Replaced->getName(); }
220149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
220249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  /// Gets the template parameter that was substituted for.
220349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  const TemplateTypeParmType *getReplacedParameter() const {
220449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    return Replaced;
220549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
220649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
220749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  /// Gets the type that was substituted for the template
220849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  /// parameter.
220949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  QualType getReplacementType() const {
221049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    return getCanonicalTypeInternal();
221149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
221249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
221349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  virtual void getAsStringInternal(std::string &InnerString,
221449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall                                   const PrintingPolicy &Policy) const;
221549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
221649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  bool isSugared() const { return true; }
221749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  QualType desugar() const { return getReplacementType(); }
221849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
221949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  void Profile(llvm::FoldingSetNodeID &ID) {
222049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    Profile(ID, getReplacedParameter(), getReplacementType());
222149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
222249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  static void Profile(llvm::FoldingSetNodeID &ID,
222349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall                      const TemplateTypeParmType *Replaced,
222449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall                      QualType Replacement) {
222549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    ID.AddPointer(Replaced);
222649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    ID.AddPointer(Replacement.getAsOpaquePtr());
222749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
222849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
222949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  static bool classof(const Type *T) {
223049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    return T->getTypeClass() == SubstTemplateTypeParm;
223149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
223249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  static bool classof(const SubstTemplateTypeParmType *T) { return true; }
223349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall};
223449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
22357532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// \brief Represents the type of a template specialization as written
22367532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// in the source code.
223755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor///
22387532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// Template specialization types represent the syntactic form of a
22397532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// template-id that refers to a type, e.g., @c vector<int>. Some
22407532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// template specialization types are syntactic sugar, whose canonical
22417532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// type will point to some other type node that represents the
22427532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// instantiation or class template specialization. For example, a
224355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor/// class template specialization type of @c vector<int> will refer to
22441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// a tag type for the instantiation
224555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor/// @c std::vector<int, std::allocator<int>>.
22467532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor///
22477532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// Other template specialization types, for which the template name
22487532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// is dependent, may be canonical types. These types are always
22497532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor/// dependent.
22501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateSpecializationType
225155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  : public Type, public llvm::FoldingSetNode {
225255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
2253828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor  // FIXME: Currently needed for profiling expressions; can we avoid this?
2254828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor  ASTContext &Context;
22551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2256828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    /// \brief The name of the template being specialized.
22577532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  TemplateName Template;
225855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
225940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief - The number of template arguments named in this class
226040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// template specialization.
226155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  unsigned NumArgs;
226255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
2263828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor  TemplateSpecializationType(ASTContext &Context,
2264828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor                             TemplateName T,
22657532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                             const TemplateArgument *Args,
22667532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                             unsigned NumArgs, QualType Canon);
226755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
22685908e9f25bc9a334c99c095e0b1e6a515445be2dDouglas Gregor  virtual void Destroy(ASTContext& C);
22695908e9f25bc9a334c99c095e0b1e6a515445be2dDouglas Gregor
227055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  friend class ASTContext;  // ASTContext creates these
227155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
227255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregorpublic:
227340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Determine whether any of the given template arguments are
227440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// dependent.
227540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  static bool anyDependentTemplateArguments(const TemplateArgument *Args,
22761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                            unsigned NumArgs);
227740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
2278df667e71b1daadeacb230cf94fc717843f1a138aDouglas Gregor  /// \brief Print a template argument list, including the '<' and '>'
2279df667e71b1daadeacb230cf94fc717843f1a138aDouglas Gregor  /// enclosing the template arguments.
2280df667e71b1daadeacb230cf94fc717843f1a138aDouglas Gregor  static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
2281d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                               unsigned NumArgs,
2282d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                               const PrintingPolicy &Policy);
2283df667e71b1daadeacb230cf94fc717843f1a138aDouglas Gregor
228440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  typedef const TemplateArgument * iterator;
228540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
228640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  iterator begin() const { return getArgs(); }
228740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  iterator end() const;
228840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
22897532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  /// \brief Retrieve the name of the template that we are specializing.
22907532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  TemplateName getTemplateName() const { return Template; }
229155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
229240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Retrieve the template arguments.
22931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument *getArgs() const {
229440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return reinterpret_cast<const TemplateArgument *>(this + 1);
229540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
229640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
229740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  /// \brief Retrieve the number of template arguments.
229855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  unsigned getNumArgs() const { return NumArgs; }
229955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
230055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  /// \brief Retrieve a specific template argument as a type.
230155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  /// \precondition @c isArgType(Arg)
230240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  const TemplateArgument &getArg(unsigned Idx) const;
230355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
23041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
2305f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
230655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
2307bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return !isDependentType(); }
2308bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return getCanonicalTypeInternal(); }
2309bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
231055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
2311828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, Template, getArgs(), NumArgs, Context);
231255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  }
231355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
23147532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
2315828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor                      const TemplateArgument *Args, unsigned NumArgs,
2316828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor                      ASTContext &Context);
231755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
23181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
23191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == TemplateSpecialization;
232055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  }
23217532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  static bool classof(const TemplateSpecializationType *T) { return true; }
232255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor};
232355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
2324e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor/// \brief Represents a type that was referred to via a qualified
2325e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor/// name, e.g., N::M::type.
2326e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor///
2327e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor/// This type is used to keep track of a type name as written in the
2328119057adf21237d53dcd490cec9700dca2465e3eDouglas Gregor/// source code, including any nested-name-specifiers. The type itself
2329119057adf21237d53dcd490cec9700dca2465e3eDouglas Gregor/// is always "sugar", used to express what was written in the source
2330119057adf21237d53dcd490cec9700dca2465e3eDouglas Gregor/// code but containing no additional semantic information.
2331e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorclass QualifiedNameType : public Type, public llvm::FoldingSetNode {
2332ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The nested name specifier containing the qualifier.
2333ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier *NNS;
2334e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2335e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  /// \brief The type that this qualified name refers to.
2336e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  QualType NamedType;
2337e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2338ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  QualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType,
2339ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                    QualType CanonType)
2340ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    : Type(QualifiedName, CanonType, NamedType->isDependentType()),
2341ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      NNS(NNS), NamedType(NamedType) { }
2342e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2343e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  friend class ASTContext;  // ASTContext creates these
2344e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2345e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorpublic:
2346ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the qualification on this type.
2347ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier *getQualifier() const { return NNS; }
2348e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2349e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  /// \brief Retrieve the type named by the qualified-id.
2350e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  QualType getNamedType() const { return NamedType; }
2351e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2352bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Remove a single level of sugar.
2353bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return getNamedType(); }
2354bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
2355bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  /// \brief Returns whether this type directly provides sugar.
2356bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return true; }
2357bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
23581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
2359f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
2360e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2361e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
2362ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    Profile(ID, NNS, NamedType);
2363e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
2364e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2365ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
2366ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                      QualType NamedType) {
2367ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    ID.AddPointer(NNS);
2368ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    NamedType.Profile(ID);
2369ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
2370e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
23711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
23721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == QualifiedName;
2373e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
2374e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  static bool classof(const QualifiedNameType *T) { return true; }
2375e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor};
2376e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
2377d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// \brief Represents a 'typename' specifier that names a type within
2378d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// a dependent type, e.g., "typename T::type".
2379d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor///
2380d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// TypenameType has a very similar structure to QualifiedNameType,
2381d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// which also involves a nested-name-specifier following by a type,
2382d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// and (FIXME!) both can even be prefixed by the 'typename'
2383d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// keyword. However, the two types serve very different roles:
2384d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// QualifiedNameType is a non-semantic type that serves only as sugar
2385d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// to show how a particular type was written in the source
2386d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// code. TypenameType, on the other hand, only occurs when the
2387d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// nested-name-specifier is dependent, such that we cannot resolve
2388d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor/// the actual type until after instantiation.
2389d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorclass TypenameType : public Type, public llvm::FoldingSetNode {
2390d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief The nested name specifier containing the qualifier.
2391d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  NestedNameSpecifier *NNS;
2392d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
23931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef llvm::PointerUnion<const IdentifierInfo *,
23941734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                             const TemplateSpecializationType *> NameType;
23951734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
2396d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief The type that this typename specifier refers to.
23971734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NameType Name;
2398d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
2399d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  TypenameType(NestedNameSpecifier *NNS, const IdentifierInfo *Name,
2400d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor               QualType CanonType)
24011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Type(Typename, CanonType, true), NNS(NNS), Name(Name) {
24021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(NNS->isDependent() &&
2403d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor           "TypenameType requires a dependent nested-name-specifier");
2404d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  }
2405d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
24061734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  TypenameType(NestedNameSpecifier *NNS, const TemplateSpecializationType *Ty,
24071734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor               QualType CanonType)
24081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Type(Typename, CanonType, true), NNS(NNS), Name(Ty) {
24091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(NNS->isDependent() &&
24101734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor           "TypenameType requires a dependent nested-name-specifier");
24111734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
24121734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
2413d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  friend class ASTContext;  // ASTContext creates these
2414d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
2415d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorpublic:
2416d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief Retrieve the qualification on this type.
2417d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  NestedNameSpecifier *getQualifier() const { return NNS; }
2418d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
24191734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// \brief Retrieve the type named by the typename specifier as an
24201734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// identifier.
24211734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  ///
24221734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// This routine will return a non-NULL identifier pointer when the
24231734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// form of the original typename was terminated by an identifier,
24241734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// e.g., "typename T::type".
24251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const IdentifierInfo *getIdentifier() const {
24261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Name.dyn_cast<const IdentifierInfo *>();
24271734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
24281734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
24291734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// \brief Retrieve the type named by the typename specifier as a
24301734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// type specialization.
24311734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  const TemplateSpecializationType *getTemplateId() const {
24321734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return Name.dyn_cast<const TemplateSpecializationType *>();
24331734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  }
2434d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
24351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
2436f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
2437d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
2438bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
2439bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
2440bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
2441d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
2442d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    Profile(ID, NNS, Name);
2443d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  }
2444d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
2445d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
24461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                      NameType Name) {
2447d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    ID.AddPointer(NNS);
24481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Name.getOpaqueValue());
2449d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  }
2450d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
24511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
24521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == Typename;
2453d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  }
2454d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  static bool classof(const TypenameType *T) { return true; }
2455d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor};
2456d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
2457fb7701df5401fa1f5b3396d269fb33e731a00089Chris Lattner/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
2458fb7701df5401fa1f5b3396d269fb33e731a00089Chris Lattner/// object oriented design.  They basically correspond to C++ classes.  There
2459fb7701df5401fa1f5b3396d269fb33e731a00089Chris Lattner/// are two kinds of interface types, normal interfaces like "NSString" and
2460fb7701df5401fa1f5b3396d269fb33e731a00089Chris Lattner/// qualified interfaces, which are qualified with a protocol list like
2461c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff/// "NSString<NSCopyable, NSAmazing>".
2462c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroffclass ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
2463a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *Decl;
2464c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
2465c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  // List of protocols for this protocol conforming object type
2466c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  // List is sorted on protocol name. No protocol is enterred more than once.
2467c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
2468c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
246954e14c4db764c0636160d26c5bbf491637c83a76John McCall  ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
24701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    ObjCProtocolDecl **Protos, unsigned NumP) :
247154e14c4db764c0636160d26c5bbf491637c83a76John McCall    Type(ObjCInterface, Canonical, /*Dependent=*/false),
2472c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    Decl(D), Protocols(Protos, Protos+NumP) { }
24733536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  friend class ASTContext;  // ASTContext creates these.
24743536b443bc50d58a79f14fca9b6842541a434854Steve Naroffpublic:
2475a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getDecl() const { return Decl; }
24761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2477c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  /// getNumProtocols - Return the number of qualifying protocols in this
2478c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  /// interface type, or 0 if there are none.
2479c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  unsigned getNumProtocols() const { return Protocols.size(); }
248014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
2481fb7701df5401fa1f5b3396d269fb33e731a00089Chris Lattner  /// qual_iterator and friends: this provides access to the (potentially empty)
2482c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  /// list of protocols qualifying this interface.
2483fb7701df5401fa1f5b3396d269fb33e731a00089Chris Lattner  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
2484c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  qual_iterator qual_begin() const { return Protocols.begin(); }
2485c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  qual_iterator qual_end() const   { return Protocols.end(); }
2486c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  bool qual_empty() const { return Protocols.size() == 0; }
24871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
2489f8910df57799256c1897a8610dc52685729ae90eSteve Naroff                                   const PrintingPolicy &Policy) const;
24901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2491bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
2492bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
2493bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
2494c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  void Profile(llvm::FoldingSetNodeID &ID);
24951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void Profile(llvm::FoldingSetNodeID &ID,
2496c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff                      const ObjCInterfaceDecl *Decl,
2497c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff                      ObjCProtocolDecl **protocols, unsigned NumProtocols);
24981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
25001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == ObjCInterface;
25013536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  }
2502a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCInterfaceType *) { return true; }
25033536b443bc50d58a79f14fca9b6842541a434854Steve Naroff};
25043536b443bc50d58a79f14fca9b6842541a434854Steve Naroff
250514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>',
250614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff/// and 'Interface <p> *'.
250714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff///
250814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff/// Duplicate protocols are removed and protocol list is canonicalized to be in
250914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff/// alphabetical order.
251014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroffclass ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
2511f6265efe7e35fb0fba315da6391368aeee1e57c9Steve Naroff  QualType PointeeType; // A builtin or interface type.
25121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
251314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // List of protocols for this protocol conforming object type
251414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // List is sorted on protocol name. No protocol is entered more than once.
251514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
251614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
251754e14c4db764c0636160d26c5bbf491637c83a76John McCall  ObjCObjectPointerType(QualType Canonical, QualType T,
251854e14c4db764c0636160d26c5bbf491637c83a76John McCall                        ObjCProtocolDecl **Protos, unsigned NumP) :
251954e14c4db764c0636160d26c5bbf491637c83a76John McCall    Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
252014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    PointeeType(T), Protocols(Protos, Protos+NumP) { }
252114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  friend class ASTContext;  // ASTContext creates these.
25221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
252314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroffpublic:
25248f16756441450ed9fb39316e47d107fc2a1ef35bSteve Naroff  // Get the pointee type. Pointee will either be:
25258f16756441450ed9fb39316e47d107fc2a1ef35bSteve Naroff  // - a built-in type (for 'id' and 'Class').
25268f16756441450ed9fb39316e47d107fc2a1ef35bSteve Naroff  // - an interface type (for user-defined types).
25278f16756441450ed9fb39316e47d107fc2a1ef35bSteve Naroff  // - a TypedefType whose canonical type is an interface (as in 'T' below).
25288f16756441450ed9fb39316e47d107fc2a1ef35bSteve Naroff  //   For example: typedef NSObject T; T *var;
252914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  QualType getPointeeType() const { return PointeeType; }
253014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
25311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const ObjCInterfaceType *getInterfaceType() const {
2532183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    return PointeeType->getAs<ObjCInterfaceType>();
253314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
2534de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  /// getInterfaceDecl - returns an interface decl for user-defined types.
253514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  ObjCInterfaceDecl *getInterfaceDecl() const {
2536de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    return getInterfaceType() ? getInterfaceType()->getDecl() : 0;
253714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
2538de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  /// isObjCIdType - true for "id".
253914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  bool isObjCIdType() const {
25401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
2541de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff           !Protocols.size();
254214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
2543de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  /// isObjCClassType - true for "Class".
254414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  bool isObjCClassType() const {
25451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
2546de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff           !Protocols.size();
2547de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  }
2548de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  /// isObjCQualifiedIdType - true for "id <p>".
25491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isObjCQualifiedIdType() const {
25501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
25511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump           Protocols.size();
2552de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  }
2553de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  /// isObjCQualifiedClassType - true for "Class <p>".
2554470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff  bool isObjCQualifiedClassType() const {
25551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
2556de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff           Protocols.size();
255714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
255814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  /// qual_iterator and friends: this provides access to the (potentially empty)
255914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  /// list of protocols qualifying this interface.
256014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
256114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
256214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  qual_iterator qual_begin() const { return Protocols.begin(); }
256314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  qual_iterator qual_end() const   { return Protocols.end(); }
256414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  bool qual_empty() const { return Protocols.size() == 0; }
256514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
256614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  /// getNumProtocols - Return the number of qualifying protocols in this
256714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  /// interface type, or 0 if there are none.
256814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  unsigned getNumProtocols() const { return Protocols.size(); }
256914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
2570bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  bool isSugared() const { return false; }
2571bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  QualType desugar() const { return QualType(this, 0); }
2572bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall
257314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  void Profile(llvm::FoldingSetNodeID &ID);
257414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
257514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff                      ObjCProtocolDecl **protocols, unsigned NumProtocols);
25761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void getAsStringInternal(std::string &InnerString,
257714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff                                   const PrintingPolicy &Policy) const;
25781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Type *T) {
25791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return T->getTypeClass() == ObjCObjectPointer;
258014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
258114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  static bool classof(const ObjCObjectPointerType *) { return true; }
258214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff};
25831bb8a45f7386a23871598d05141a07af03067925Argyrios Kyrtzidis
25840953e767ff7817f97b3ab20896b229891eeff45bJohn McCall/// A qualifier set is used to build a set of qualifiers.
25850953e767ff7817f97b3ab20896b229891eeff45bJohn McCallclass QualifierCollector : public Qualifiers {
25860953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  ASTContext *Context;
25870953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
25880953e767ff7817f97b3ab20896b229891eeff45bJohn McCallpublic:
25890953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualifierCollector(Qualifiers Qs = Qualifiers())
25900953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    : Qualifiers(Qs), Context(0) {}
25910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualifierCollector(ASTContext &Context, Qualifiers Qs = Qualifiers())
25920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    : Qualifiers(Qs), Context(&Context) {}
25930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
25940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void setContext(ASTContext &C) { Context = &C; }
25950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
25960953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Collect any qualifiers on the given type and return an
25970953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// unqualified type.
25980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const Type *strip(QualType QT) {
25990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    addFastQualifiers(QT.getFastQualifiers());
26000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (QT.hasNonFastQualifiers()) {
26010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      const ExtQuals *EQ = QT.getExtQualsUnsafe();
26020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      Context = &EQ->getContext();
26030953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      addQualifiers(EQ->getQualifiers());
26040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return EQ->getBaseType();
26050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    }
26060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return QT.getTypePtrUnsafe();
26070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
26080953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26090953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Apply the collected qualifiers to the given type.
26100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType apply(QualType QT) const;
26110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Apply the collected qualifiers to the given type.
26130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualType apply(const Type* T) const;
26140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall};
26160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26170953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2618611c1fff195d32df97706e0920c92468b2509900Chris Lattner// Inline function definitions.
26195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2620467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCallinline bool QualType::isCanonical() const {
2621467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  const Type *T = getTypePtr();
2622467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  if (hasQualifiers())
2623467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall    return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
2624467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall  return T->isCanonicalUnqualified();
2625467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall}
2626467b27b9a24bdc823218ad1ad0e37673b6cc1e83John McCall
262754e14c4db764c0636160d26c5bbf491637c83a76John McCallinline bool QualType::isCanonicalAsParam() const {
262854e14c4db764c0636160d26c5bbf491637c83a76John McCall  if (hasQualifiers()) return false;
262954e14c4db764c0636160d26c5bbf491637c83a76John McCall  const Type *T = getTypePtr();
263054e14c4db764c0636160d26c5bbf491637c83a76John McCall  return T->isCanonicalUnqualified() &&
263154e14c4db764c0636160d26c5bbf491637c83a76John McCall           !isa<FunctionType>(T) && !isa<ArrayType>(T);
263254e14c4db764c0636160d26c5bbf491637c83a76John McCall}
263354e14c4db764c0636160d26c5bbf491637c83a76John McCall
26340953e767ff7817f97b3ab20896b229891eeff45bJohn McCallinline void QualType::removeConst() {
26350953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  removeFastQualifiers(Qualifiers::Const);
26360953e767ff7817f97b3ab20896b229891eeff45bJohn McCall}
26370953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26380953e767ff7817f97b3ab20896b229891eeff45bJohn McCallinline void QualType::removeRestrict() {
26390953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  removeFastQualifiers(Qualifiers::Restrict);
26400953e767ff7817f97b3ab20896b229891eeff45bJohn McCall}
26410953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26420953e767ff7817f97b3ab20896b229891eeff45bJohn McCallinline void QualType::removeVolatile() {
26430953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualifierCollector Qc;
26440953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const Type *Ty = Qc.strip(*this);
26450953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (Qc.hasVolatile()) {
26460953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    Qc.removeVolatile();
26470953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    *this = Qc.apply(Ty);
26480953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
26490953e767ff7817f97b3ab20896b229891eeff45bJohn McCall}
26500953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26510953e767ff7817f97b3ab20896b229891eeff45bJohn McCallinline void QualType::removeCVRQualifiers(unsigned Mask) {
26526b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall  assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
26530953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // Fast path: we don't need to touch the slow qualifiers.
26550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (!(Mask & ~Qualifiers::FastMask)) {
26560953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    removeFastQualifiers(Mask);
26570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return;
26580953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
26590953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26600953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  QualifierCollector Qc;
26610953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  const Type *Ty = Qc.strip(*this);
26620953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  Qc.removeCVRQualifiers(Mask);
26630953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  *this = Qc.apply(Ty);
2664ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb}
2665ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
2666ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb/// getAddressSpace - Return the address space of this type.
2667ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lambinline unsigned QualType::getAddressSpace() const {
26680953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (hasNonFastQualifiers()) {
26690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    const ExtQuals *EQ = getExtQualsUnsafe();
26700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (EQ->hasAddressSpace())
26710953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return EQ->getAddressSpace();
26720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
26730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26744243a94b43ef6207938f3023dfcfb804dd545363Chris Lattner  QualType CT = getTypePtr()->getCanonicalTypeInternal();
26750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (CT.hasNonFastQualifiers()) {
26760953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    const ExtQuals *EQ = CT.getExtQualsUnsafe();
26770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (EQ->hasAddressSpace())
26780953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return EQ->getAddressSpace();
26790953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
26800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
26814243a94b43ef6207938f3023dfcfb804dd545363Chris Lattner  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
2682c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return AT->getElementType().getAddressSpace();
26834243a94b43ef6207938f3023dfcfb804dd545363Chris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(CT))
26848e7dafec4b70303dfaff95151cd06bfc5532720cNate Begeman    return RT->getAddressSpace();
2685ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  return 0;
2686ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb}
2687611c1fff195d32df97706e0920c92468b2509900Chris Lattner
2688d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian/// getObjCGCAttr - Return the gc attribute of this type.
26890953e767ff7817f97b3ab20896b229891eeff45bJohn McCallinline Qualifiers::GC QualType::getObjCGCAttr() const {
26900953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (hasNonFastQualifiers()) {
26910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    const ExtQuals *EQ = getExtQualsUnsafe();
26920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (EQ->hasObjCGCAttr())
26930953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return EQ->getObjCGCAttr();
26940953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
26950953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2696d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian  QualType CT = getTypePtr()->getCanonicalTypeInternal();
26970953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (CT.hasNonFastQualifiers()) {
26980953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    const ExtQuals *EQ = CT.getExtQualsUnsafe();
26990953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    if (EQ->hasObjCGCAttr())
27000953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      return EQ->getObjCGCAttr();
27010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
27020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
2703d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
2704d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian      return AT->getElementType().getObjCGCAttr();
2705183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (const ObjCObjectPointerType *PT = CT->getAs<ObjCObjectPointerType>())
27061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return PT->getPointeeType().getObjCGCAttr();
2707ac423ba85bb59cc7cc1d43081b20d7e8d40355ffFariborz Jahanian  // We most look at all pointer types, not just pointer to interface types.
2708ac423ba85bb59cc7cc1d43081b20d7e8d40355ffFariborz Jahanian  if (const PointerType *PT = CT->getAs<PointerType>())
27091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return PT->getPointeeType().getObjCGCAttr();
27100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  return Qualifiers::GCNone;
2711d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian}
27122455636163fdd18581d7fdae816433f886d88213Mike Stump
2713ae92140b542d5c1c096e39e74e59526184819b30Mike Stump  /// getNoReturnAttr - Returns true if the type has the noreturn attribute,
2714ae92140b542d5c1c096e39e74e59526184819b30Mike Stump  /// false otherwise.
27152455636163fdd18581d7fdae816433f886d88213Mike Stumpinline bool QualType::getNoReturnAttr() const {
27162455636163fdd18581d7fdae816433f886d88213Mike Stump  QualType CT = getTypePtr()->getCanonicalTypeInternal();
27176217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType *PT = getTypePtr()->getAs<PointerType>()) {
2718183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
27192455636163fdd18581d7fdae816433f886d88213Mike Stump      return FT->getNoReturnAttr();
2720183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  } else if (const FunctionType *FT = getTypePtr()->getAs<FunctionType>())
27212455636163fdd18581d7fdae816433f886d88213Mike Stump    return FT->getNoReturnAttr();
27222455636163fdd18581d7fdae816433f886d88213Mike Stump
27232455636163fdd18581d7fdae816433f886d88213Mike Stump  return false;
27242455636163fdd18581d7fdae816433f886d88213Mike Stump}
27251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2726e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// isMoreQualifiedThan - Determine whether this type is more
2727e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// qualified than the Other type. For example, "const volatile int"
2728e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// is more qualified than "const int", "volatile int", and
2729e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// "int". However, it is not more qualified than "const volatile
2730e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// int".
2731e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregorinline bool QualType::isMoreQualifiedThan(QualType Other) const {
27320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // FIXME: work on arbitrary qualifiers
2733e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  unsigned MyQuals = this->getCVRQualifiers();
2734e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  unsigned OtherQuals = Other.getCVRQualifiers();
2735ecca7536488e425417dcb005c39cc15ae1947aabChris Lattner  if (getAddressSpace() != Other.getAddressSpace())
2736ecca7536488e425417dcb005c39cc15ae1947aabChris Lattner    return false;
2737e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals;
2738e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor}
2739e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor
2740e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// isAtLeastAsQualifiedAs - Determine whether this type is at last
2741e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// as qualified as the Other type. For example, "const volatile
2742e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// int" is at least as qualified as "const int", "volatile int",
2743e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// "int", and "const volatile int".
2744e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregorinline bool QualType::isAtLeastAsQualifiedAs(QualType Other) const {
27450953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // FIXME: work on arbitrary qualifiers
2746e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  unsigned MyQuals = this->getCVRQualifiers();
2747e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  unsigned OtherQuals = Other.getCVRQualifiers();
2748ecca7536488e425417dcb005c39cc15ae1947aabChris Lattner  if (getAddressSpace() != Other.getAddressSpace())
2749ecca7536488e425417dcb005c39cc15ae1947aabChris Lattner    return false;
2750e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  return (MyQuals | OtherQuals) == MyQuals;
2751e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor}
2752e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor
2753e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// getNonReferenceType - If Type is a reference type (e.g., const
2754e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// int&), returns the type that the reference refers to ("const
2755e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// int"). Otherwise, returns the type itself. This routine is used
2756e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor/// throughout Sema to implement C++ 5p6:
2757e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor///
2758e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor///   If an expression initially has the type "reference to T" (8.3.2,
2759e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor///   8.5.3), the type is adjusted to "T" prior to any further
2760e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor///   analysis, the expression designates the object or function
2761e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor///   denoted by the reference, and the expression is an lvalue.
2762e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregorinline QualType QualType::getNonReferenceType() const {
27636217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>())
2764e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor    return RefType->getPointeeType();
2765e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor  else
2766e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor    return *this;
2767e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor}
2768e0a5d5fe8eab573f7764bf6d2ddb02bee8dceaf9Douglas Gregor
27692b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattnerinline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
27706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType *PT = getAs<PointerType>())
2771183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    return PT->getPointeeType()->getAs<ObjCInterfaceType>();
27722b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  return 0;
27732b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner}
27741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2775c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner// NOTE: All of these methods use "getUnqualifiedType" to strip off address
2776c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner// space qualifiers if present.
2777611c1fff195d32df97706e0920c92468b2509900Chris Lattnerinline bool Type::isFunctionType() const {
2778ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  return isa<FunctionType>(CanonicalType.getUnqualifiedType());
2779611c1fff195d32df97706e0920c92468b2509900Chris Lattner}
2780611c1fff195d32df97706e0920c92468b2509900Chris Lattnerinline bool Type::isPointerType() const {
27811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return isa<PointerType>(CanonicalType.getUnqualifiedType());
2782611c1fff195d32df97706e0920c92468b2509900Chris Lattner}
278358f9f2c884af6b72d036b746a016d8031d31cb7aSteve Naroffinline bool Type::isAnyPointerType() const {
278458f9f2c884af6b72d036b746a016d8031d31cb7aSteve Naroff  return isPointerType() || isObjCObjectPointerType();
278558f9f2c884af6b72d036b746a016d8031d31cb7aSteve Naroff}
27865618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroffinline bool Type::isBlockPointerType() const {
27871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return isa<BlockPointerType>(CanonicalType.getUnqualifiedType());
27885618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff}
2789bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattnerinline bool Type::isReferenceType() const {
2790bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
2791bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner}
27927c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlinline bool Type::isLValueReferenceType() const {
27937c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  return isa<LValueReferenceType>(CanonicalType.getUnqualifiedType());
27947c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl}
27957c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlinline bool Type::isRValueReferenceType() const {
27967c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  return isa<RValueReferenceType>(CanonicalType.getUnqualifiedType());
27977c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl}
2798498b0d1aba38f5ec64d566d1dd9e6be237ecc50fTed Kremenekinline bool Type::isFunctionPointerType() const {
27996217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType* T = getAs<PointerType>())
2800498b0d1aba38f5ec64d566d1dd9e6be237ecc50fTed Kremenek    return T->getPointeeType()->isFunctionType();
2801498b0d1aba38f5ec64d566d1dd9e6be237ecc50fTed Kremenek  else
2802498b0d1aba38f5ec64d566d1dd9e6be237ecc50fTed Kremenek    return false;
2803498b0d1aba38f5ec64d566d1dd9e6be237ecc50fTed Kremenek}
2804f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlinline bool Type::isMemberPointerType() const {
2805f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  return isa<MemberPointerType>(CanonicalType.getUnqualifiedType());
2806f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl}
2807f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlinline bool Type::isMemberFunctionPointerType() const {
28086217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const MemberPointerType* T = getAs<MemberPointerType>())
2809f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    return T->getPointeeType()->isFunctionType();
2810f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  else
2811f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    return false;
2812f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl}
2813611c1fff195d32df97706e0920c92468b2509900Chris Lattnerinline bool Type::isArrayType() const {
2814ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  return isa<ArrayType>(CanonicalType.getUnqualifiedType());
2815611c1fff195d32df97706e0920c92468b2509900Chris Lattner}
2816c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattnerinline bool Type::isConstantArrayType() const {
2817c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
2818c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
2819c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattnerinline bool Type::isIncompleteArrayType() const {
2820c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
2821c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
2822c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattnerinline bool Type::isVariableArrayType() const {
2823c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
2824c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
2825898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorinline bool Type::isDependentSizedArrayType() const {
2826898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  return isa<DependentSizedArrayType>(CanonicalType.getUnqualifiedType());
2827898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
2828611c1fff195d32df97706e0920c92468b2509900Chris Lattnerinline bool Type::isRecordType() const {
2829ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  return isa<RecordType>(CanonicalType.getUnqualifiedType());
2830611c1fff195d32df97706e0920c92468b2509900Chris Lattner}
2831f23d364084d1aabea688222780d6fc1dd8c7f78cChris Lattnerinline bool Type::isAnyComplexType() const {
2832c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  return isa<ComplexType>(CanonicalType.getUnqualifiedType());
2833f23d364084d1aabea688222780d6fc1dd8c7f78cChris Lattner}
2834611c1fff195d32df97706e0920c92468b2509900Chris Lattnerinline bool Type::isVectorType() const {
2835ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  return isa<VectorType>(CanonicalType.getUnqualifiedType());
2836611c1fff195d32df97706e0920c92468b2509900Chris Lattner}
2837213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begemaninline bool Type::isExtVectorType() const {
2838213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
2839611c1fff195d32df97706e0920c92468b2509900Chris Lattner}
2840d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffinline bool Type::isObjCObjectPointerType() const {
2841d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
2842d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff}
2843a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekinline bool Type::isObjCInterfaceType() const {
2844c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
2845368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner}
2846a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekinline bool Type::isObjCQualifiedIdType() const {
2847183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
2848d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    return OPT->isObjCQualifiedIdType();
2849d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  return false;
2850d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian}
2851470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroffinline bool Type::isObjCQualifiedClassType() const {
2852183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
2853470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff    return OPT->isObjCQualifiedClassType();
2854470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff  return false;
2855470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff}
285614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroffinline bool Type::isObjCIdType() const {
2857183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
285814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return OPT->isObjCIdType();
285914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  return false;
286014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff}
286114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroffinline bool Type::isObjCClassType() const {
2862183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
286314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return OPT->isObjCClassType();
286414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  return false;
286514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff}
2866de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroffinline bool Type::isObjCBuiltinType() const {
2867de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  return isObjCIdType() || isObjCClassType();
2868de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff}
286972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregorinline bool Type::isTemplateTypeParmType() const {
287072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
287172c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor}
287272c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
2873e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbarinline bool Type::isSpecificBuiltinType(unsigned K) const {
2874183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (const BuiltinType *BT = getAs<BuiltinType>())
2875e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar    if (BT->getKind() == (BuiltinType::Kind) K)
2876e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar      return true;
2877e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar  return false;
2878e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar}
2879e00d5c00f35163308a18ec1d3d2b9dfa1ecaf234Daniel Dunbar
2880063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor/// \brief Determines whether this is a type for which one can define
2881063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor/// an overloaded operator.
2882063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregorinline bool Type::isOverloadableType() const {
2883063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  return isDependentType() || isRecordType() || isEnumeralType();
2884904eed3f6148758d39a2d3c88f3133274460d645Douglas Gregor}
2885904eed3f6148758d39a2d3c88f3133274460d645Douglas Gregor
28868958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbarinline bool Type::hasPointerRepresentation() const {
28878958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar  return (isPointerType() || isReferenceType() || isBlockPointerType() ||
28881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          isObjCInterfaceType() || isObjCObjectPointerType() ||
28896e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl          isObjCQualifiedInterfaceType() || isNullPtrType());
28908958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar}
28918958891f5fa1e593c4519a36b3df427ee019d70bDaniel Dunbar
2892820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanianinline bool Type::hasObjCPointerRepresentation() const {
28931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return (isObjCInterfaceType() || isObjCObjectPointerType() ||
2894820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian          isObjCQualifiedInterfaceType());
2895820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian}
2896820e0203079afd64b0de422832f9e0b31a27c0c8Fariborz Jahanian
289722caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner/// Insertion operator for diagnostics.  This allows sending QualType's into a
289822caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner/// diagnostic with <<.
289922caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattnerinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
290022caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner                                           QualType T) {
290122caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner  DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
290222caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner                  Diagnostic::ak_qualtype);
290322caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner  return DB;
290422caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner}
29051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29061a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek/// Member-template getAs<specific type>'.
29071a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenektemplate <typename T> const T *Type::getAs() const {
29081a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  // If this is directly a T type, return it.
29091a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  if (const T *Ty = dyn_cast<T>(this))
29101a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek    return Ty;
29111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29121a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  // If the canonical form of this type isn't the right kind, reject it.
29130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  if (!isa<T>(CanonicalType))
29141a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek    return 0;
29151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  // If this is a typedef for the type, strip the typedef off without
29171a1a6e2bd4c5aefd7fd643cf25915f9623a02e59Ted Kremenek  // losing all typedef information.
2918bf1cc05907ceb2081e8158b26f3d3f48b31caad3John McCall  return cast<T>(getUnqualifiedDesugaredType());
29191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
292022caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner
29215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
29225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
29235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
2924