Type.h revision b7d2553edd2532d29b98b9e76bcf6a62bc48b417
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//                     The LLVM Compiler Infrastructure
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// This file is distributed under the University of Illinois Open Source
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// License. See LICENSE.TXT for details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt//===----------------------------------------------------------------------===//
904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt//
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//  This file defines the Type interface and subclasses.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===//
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef LLVM_CLANG_AST_TYPE_H
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define LLVM_CLANG_AST_TYPE_H
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "clang/Basic/Diagnostic.h"
1861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/Support/Casting.h"
1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/ADT/APSInt.h"
2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/ADT/FoldingSet.h"
2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/ADT/PointerIntPair.h"
2261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/Bitcode/SerializationFwd.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing llvm::isa;
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing llvm::cast;
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing llvm::cast_or_null;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing llvm::dyn_cast;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing llvm::dyn_cast_or_null;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace clang {
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ASTContext;
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class Type;
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TypedefDecl;
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TemplateDecl;
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TemplateTypeParmDecl;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class NonTypeTemplateParmDecl;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TemplateTemplateParamDecl;
371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  class TagDecl;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class RecordDecl;
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class CXXRecordDecl;
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class EnumDecl;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class FieldDecl;
4204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  class ObjCInterfaceDecl;
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ObjCProtocolDecl;
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ObjCMethodDecl;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class Expr;
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class Stmt;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class SourceLocation;
481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  class PointerLikeType;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class PointerType;
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class BlockPointerType;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ReferenceType;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class MemberPointerType;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class VectorType;
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ArrayType;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ConstantArrayType;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class VariableArrayType;
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class IncompleteArrayType;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class DependentSizedArrayType;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class RecordType;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class EnumType;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ComplexType;
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TagType;
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TypedefType;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class TemplateTypeParmType;
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class FunctionType;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class FunctionTypeProto;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ExtVectorType;
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class BuiltinType;
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ObjCInterfaceType;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ObjCQualifiedIdType;
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ObjCQualifiedInterfaceType;
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class StmtIteratorBase;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  class ClassTemplateSpecializationType;
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
7604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// their own: instead each reference to a type stores the qualifiers.  This
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// greatly reduces the number of nodes we need to allocate for types (for
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// example we only need one for 'int', 'const int', 'volatile int',
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 'const volatile int', etc).
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// As an added efficiency bonus, instead of making this a pair, we just store
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// the three bits we care about in the low bits of the pointer.  To handle the
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// packing/unpacking, we make QualType be a simple wrapper class that acts like
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// a smart pointer.
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass QualType {
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  llvm::PointerIntPair<Type*, 3> Value;
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  enum TQ {   // NOTE: These flags must be kept in sync with DeclSpec::TQ.
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Const    = 0x1,
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Restrict = 0x2,
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Volatile = 0x4,
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CVRFlags = Const|Restrict|Volatile
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  };
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  enum GCAttrTypes {
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    GCNone = 0,
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Weak,
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Strong
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  };
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType() {}
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType(const Type *Ptr, unsigned Quals)
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Value(const_cast<Type*>(Ptr), Quals) {}
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getCVRQualifiers() const { return Value.getInt(); }
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void setCVRQualifiers(unsigned Quals) { Value.setInt(Quals); }
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type *getTypePtr() const { return Value.getPointer(); }
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static QualType getFromOpaquePtr(void *Ptr) {
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    QualType T;
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    T.Value.setFromOpaqueValue(Ptr);
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T;
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type &operator*() const {
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return *getTypePtr();
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type *operator->() const {
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return getTypePtr();
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isNull - Return true if this QualType doesn't point to a type yet.
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isNull() const {
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return getTypePtr() == 0;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isConstQualified() const {
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return (getCVRQualifiers() & Const) ? true : false;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isVolatileQualified() const {
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return (getCVRQualifiers() & Volatile) ? true : false;
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isRestrictQualified() const {
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return (getCVRQualifiers() & Restrict) ? true : false;
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isConstant(ASTContext& Ctx) const;
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// addConst/addVolatile/addRestrict - add the specified type qual to this
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// QualType.
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void addConst()    { Value.setInt(Value.getInt() | Const); }
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void addVolatile() { Value.setInt(Value.getInt() | Volatile); }
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void addRestrict() { Value.setInt(Value.getInt() | Restrict); }
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void removeConst()    { Value.setInt(Value.getInt() & ~Const); }
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void removeVolatile() { Value.setInt(Value.getInt() & ~Volatile); }
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void removeRestrict() { Value.setInt(Value.getInt() & ~Restrict); }
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getQualifiedType(unsigned TQs) const {
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return QualType(getTypePtr(), TQs);
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getWithAdditionalQualifiers(unsigned TQs) const {
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return QualType(getTypePtr(), TQs|getCVRQualifiers());
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType withConst() const { return getWithAdditionalQualifiers(Const); }
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType withVolatile() const { return getWithAdditionalQualifiers(Volatile);}
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType withRestrict() const { return getWithAdditionalQualifiers(Restrict);}
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getUnqualifiedType() const;
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isMoreQualifiedThan(QualType Other) const;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isAtLeastAsQualifiedAs(QualType Other) const;
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getNonReferenceType() const;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// operator==/!= - Indicate whether the specified types and qualifiers are
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// identical.
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool operator==(const QualType &RHS) const {
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Value == RHS.Value;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool operator!=(const QualType &RHS) const {
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Value != RHS.Value;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  std::string getAsString() const {
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    std::string S;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    getAsStringInternal(S);
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return S;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void getAsStringInternal(std::string &Str) const;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void dump(const char *s) const;
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void dump() const;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) const {
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(getAsOpaquePtr());
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// getAddressSpace - Return the address space of this type.
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inline unsigned getAddressSpace() const;
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// GCAttrTypesAttr - Returns gc attribute of this type.
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inline QualType::GCAttrTypes getObjCGCAttr() const;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Emit - Serialize a QualType to Bitcode.
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Emit(llvm::Serializer& S) const;
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Read - Deserialize a QualType from Bitcode.
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static QualType ReadVal(llvm::Deserializer& D);
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void ReadBackpatch(llvm::Deserializer& D);
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} // end clang.
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace llvm {
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// to a specific Type class.
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate<> struct simplify_type<const ::clang::QualType> {
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  typedef ::clang::Type* SimpleType;
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Val.getTypePtr();
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate<> struct simplify_type< ::clang::QualType>
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  : public simplify_type<const ::clang::QualType> {};
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} // end namespace llvm
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace clang {
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Type - This is the base class of the type hierarchy.  A central concept
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// with types is that each type always has a canonical type.  A canonical type
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// is the type with any typedef names stripped out of it or the types it
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// references.  For example, consider:
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///  typedef int  foo;
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///  typedef foo* bar;
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///    'int *'    'foo *'    'bar'
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// There will be a Type object created for 'int'.  Since int is canonical, its
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// canonicaltype pointer points to itself.  There is also a Type for 'foo' (a
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// TypeNameType).  Its CanonicalType pointer points to the 'int' Type.  Next
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// there is a PointerType that represents 'int*', which, like 'int', is
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// canonical.  Finally, there is a PointerType type for 'foo*' whose canonical
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// type is 'int*', and there is a TypeNameType for 'bar', whose canonical type
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// is also 'int*'.
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Non-canonical types are useful for emitting diagnostics, without losing
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// information about typedefs being used.  Canonical types are useful for type
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// comparisons (they allow by-pointer equality tests) and useful for reasoning
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// about whether something has a particular form (e.g. is a function type),
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// because they implicitly, recursively, strip all typedefs out of a type.
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Types, once created, are immutable.
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass Type {
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  enum TypeClass {
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Builtin, Complex, Pointer, Reference, MemberPointer,
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ConstantArray, VariableArray, IncompleteArray, DependentSizedArray,
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Vector, ExtVector,
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    FunctionNoProto, FunctionProto,
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    TypeName, Tagged, ExtQual,
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    TemplateTypeParm, ClassTemplateSpecialization,
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ObjCInterface, ObjCQualifiedInterface,
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ObjCQualifiedId,
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    TypeOfExp, TypeOfTyp, // GNU typeof extension.
26309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt    BlockPointer,          // C extension
26409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt    FixedWidthInt
26509f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  };
26609f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
26709f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidtprivate:
26809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  QualType CanonicalType;
26909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
27009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
27109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  bool Dependent : 1;
27209f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
27309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Note that this should stay at the end of the ivars for Type so that
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// subclasses can pack their bitfields into the same word.
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned TC : 5;
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // silence VC++ warning C4355: 'this' : used in base member initializer list
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type *this_() { return this; }
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type(TypeClass tc, QualType Canonical, bool dependent)
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Dependent(dependent), TC(tc) {}
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual ~Type() {}
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void Destroy(ASTContext& C);
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void EmitTypeInternal(llvm::Serializer& S) const;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void ReadTypeInternal(llvm::Deserializer& D);
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isCanonical() const { return CanonicalType.getTypePtr() == this; }
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// object types, function types, and incomplete types.
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isObjectType - types that fully describe objects. An object is a region
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// of memory that can be examined and stored into (H&S).
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isObjectType() const;
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isIncompleteType - Return true if this is an incomplete type.
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// A type that can describe objects, but which lacks information needed to
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// routine will need to determine if the size is actually required.
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isIncompleteType() const;
30809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
30909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  /// isIncompleteOrObjectType - Return true if this is an incomplete or object
31009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  /// type, in other words, not a function type.
31109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  bool isIncompleteOrObjectType() const {
31209f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt    return !isFunctionType();
31309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  }
31409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
31509f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isPODType() const;
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// types that have a non-constant expression. This does not include "[]".
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isVariablyModifiedType() const;
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Helper methods to distinguish type categories. All type predicates
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// operate on the canonical type, ignoring typedefs and qualifiers.
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isSpecificBuiltinType - Test for a particular builtin type.
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isSpecificBuiltinType(unsigned K) const;
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isIntegerType() does *not* include complex integers (a GCC extension).
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isComplexIntegerType() can be used to test for complex integers.
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isEnumeralType() const;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isBooleanType() const;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isCharType() const;
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isWideCharType() const;
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isIntegralType() const;
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Floating point categories.
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isComplexType() does *not* include complex integers (a GCC extension).
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isComplexIntegerType() can be used to test for complex integers.
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isComplexType() const;      // C99 6.2.5p11 (complex)
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isAnyComplexType() const;   // C99 6.2.5p11 (complex) + Complex Int.
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isFloatingType() const;     // C99 6.2.5p11 (real floating + complex)
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isRealType() const;         // C99 6.2.5p17 (real floating + integer)
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isArithmeticType() const;   // C99 6.2.5p18 (integer + floating)
3464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt  bool isVoidType() const;         // C99 6.2.5p19
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isDerivedType() const;      // C99 6.2.5p20
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isAggregateType() const;
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Type Predicates: Check to see if this type is structurally the specified
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // type, ignoring typedefs and qualifiers.
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isFunctionType() const;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isPointerLikeType() const; // Pointer or Reference.
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isPointerType() const;
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isBlockPointerType() const;
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isReferenceType() const;
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isFunctionPointerType() const;
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isMemberPointerType() const;
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isMemberFunctionPointerType() const;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isArrayType() const;
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isConstantArrayType() const;
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isIncompleteArrayType() const;
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isVariableArrayType() const;
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isDependentSizedArrayType() const;
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isRecordType() const;
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isClassType() const;
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isStructureType() const;
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isUnionType() const;
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isComplexIntegerType() const;            // GCC _Complex integer type.
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isVectorType() const;                    // GCC vector type.
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isExtVectorType() const;                 // Extended vector type.
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isObjCInterfaceType() const;             // NSString or NSString<foo>
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isObjCQualifiedIdType() const;           // id<foo>
3765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt  bool isTemplateTypeParmType() const;          // C++ template type parameter
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isDependentType - Whether this type is a dependent type, meaning
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// that its definition somehow depends on a template parameter
3805460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt  /// (C++ [temp.dep.type]).
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isDependentType() const { return Dependent; }
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isOverloadType() const;                  // C++ overloaded function
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Type Checking Functions: Check to see if this type is structurally the
3855460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt  // specified type, ignoring typedefs and qualifiers, and return a pointer to
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // the best type we can.
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const BuiltinType *getAsBuiltinType() const;
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const FunctionType *getAsFunctionType() const;
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const FunctionTypeProto *getAsFunctionTypeProto() const;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const PointerLikeType *getAsPointerLikeType() const; // Pointer or Reference.
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const PointerType *getAsPointerType() const;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const BlockPointerType *getAsBlockPointerType() const;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ReferenceType *getAsReferenceType() const;
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const MemberPointerType *getAsMemberPointerType() const;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const RecordType *getAsRecordType() const;
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const RecordType *getAsStructureType() const;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// NOTE: getAs*ArrayType are methods on ASTContext.
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const TypedefType *getAsTypedefType() const;
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const RecordType *getAsUnionType() const;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const EnumType *getAsEnumType() const;
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const VectorType *getAsVectorType() const; // GCC vector type.
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ComplexType *getAsComplexType() const;
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ExtVectorType *getAsExtVectorType() const; // Extended vector type.
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ObjCInterfaceType *getAsObjCInterfaceType() const;
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const;
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const TemplateTypeParmType *getAsTemplateTypeParmType() const;
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ClassTemplateSpecializationType *
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    getClassTemplateSpecializationType() const;
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// interface, return the interface type, otherwise return null.
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// getArrayElementTypeNoTypeQual - If this is an array type, return the
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// element type of the array, potentially with type qualifiers missing.
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// This method should never be used when type qualifiers are meaningful.
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Type *getArrayElementTypeNoTypeQual() const;
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// getDesugaredType - Return the specified type with any "sugar" removed from
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// the type is already concrete, it returns it unmodified.  This is similar
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// to getting the canonical type, but it doesn't remove *all* typedefs.  For
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// concrete.
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getDesugaredType() const;
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// More type predicates useful for type checking/promotion
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isSignedIntegerType - Return true if this is an integer type that is
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// an enum decl which has a signed representation, or a vector of signed
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// integer element type.
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isSignedIntegerType() const;
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isUnsignedIntegerType - Return true if this is an integer type that is
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// decl which has an unsigned representation, or a vector of unsigned integer
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// element type.
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isUnsignedIntegerType() const;
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// isConstantSizeType - Return true if this is not a variable sized type,
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// according to the rules of C99 6.7.5p3.  It is not legal to call this on
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// incomplete types.
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isConstantSizeType() const;
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getCanonicalTypeInternal() const { return CanonicalType; }
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void dump() const;
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const = 0;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *) { return true; }
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Emit - Emit a Type to bitcode.  Used by ASTContext.
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Emit(llvm::Serializer& S) const;
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Create - Construct a Type from bitcode.  Used by ASTContext.
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Create(ASTContext& Context, unsigned i, llvm::Deserializer& S);
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// EmitImpl - Subclasses must implement this method in order to
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ///  be serialized.
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: Make this abstract once implemented.
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const {
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    assert(false && "Serializization for type not supported.");
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ExtQualType - TR18037 (C embedded extensions) 6.2.5p26
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// This supports all kinds of type attributes; including,
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// address space qualified types, objective-c's __weak and
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// __strong attributes.
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass ExtQualType : public Type, public llvm::FoldingSetNode {
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// BaseType - This is the underlying type that this qualifies.  All CVR
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// qualifiers are stored on the QualType that references this type, so we
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// can't have any here.
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type *BaseType;
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Address Space ID - The address space ID this type is qualified with.
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned AddressSpace;
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// GC __weak/__strong attributes
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType::GCAttrTypes GCAttrType;
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ExtQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace,
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt              QualType::GCAttrTypes gcAttr) :
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Type(ExtQual, CanonicalPtr, Base->isDependentType()), BaseType(Base),
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      AddressSpace(AddrSpace), GCAttrType(gcAttr) {
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    assert(!isa<ExtQualType>(BaseType) &&
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt           "Cannot have ExtQualType of ExtQualType");
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
49309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
49409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidtpublic:
49509f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  Type *getBaseType() const { return BaseType; }
49609f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  QualType::GCAttrTypes getObjCGCAttr() const { return GCAttrType; }
49709f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  unsigned getAddressSpace() const { return AddressSpace; }
49809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
49909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
50009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
50109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
50209f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt    Profile(ID, getBaseType(), AddressSpace, GCAttrType);
50309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  }
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, Type *Base,
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      unsigned AddrSpace, QualType::GCAttrTypes gcAttr) {
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Base);
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddInteger(AddrSpace);
50809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt    ID.AddInteger(gcAttr);
50909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  }
51009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
51109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == ExtQual; }
51209f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  static bool classof(const ExtQualType *) { return true; }
51309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt
51409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidtprotected:
51509f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
51609f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
51709f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt  friend class Type;
51809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt};
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// BuiltinType - This class is used for builtin types like 'int'.  Builtin
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// types are always canonical and have a literal name field.
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass BuiltinType : public Type {
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  enum Kind {
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Void,
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Bool,     // This is bool and/or _Bool.
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Char_U,   // This is 'char' for targets where char is unsigned.
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    UChar,    // This is explicitly qualified unsigned char.
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    UShort,
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    UInt,
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ULong,
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ULongLong,
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Char_S,   // This is 'char' for targets where char is signed.
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    SChar,    // This is explicitly qualified signed char.
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    WChar,    // This is 'wchar_t' for C++.
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Short,
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Int,
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Long,
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    LongLong,
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Float, Double, LongDouble,
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Overload,  // This represents the type of an overloaded function declaration.
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Dependent  // This represents the type of a type-dependent expression.
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  };
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprivate:
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Kind TypeKind;
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  BuiltinType(Kind K)
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      TypeKind(K) {}
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Kind getKind() const { return TypeKind; }
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const char *getName() const;
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const BuiltinType *) { return true; }
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// FixedWidthIntType - Used for arbitrary width types that we either don't
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// want to or can't map to named integer types.  These always have a lower
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// integer rank than builtin types of the same width.
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass FixedWidthIntType : public Type {
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprivate:
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned Width;
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool Signed;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  FixedWidthIntType(unsigned W, bool S) : Type(FixedWidthInt, QualType(), false),
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                          Width(W), Signed(S) {}
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getWidth() const { return Width; }
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isSigned() const { return Signed; }
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const char *getName() const;
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == FixedWidthInt; }
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const FixedWidthIntType *) { return true; }
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ComplexType - C99 6.2.5p11 - Complex values.  This supports the C99 complex
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// types (_Complex float etc) as well as the GCC integer complex extensions.
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass ComplexType : public Type, public llvm::FoldingSetNode {
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType ElementType;
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ComplexType(QualType Element, QualType CanonicalPtr) :
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Type(Complex, CanonicalPtr, Element->isDependentType()),
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ElementType(Element) {
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getElementType() const { return ElementType; }
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Profile(ID, getElementType());
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Element.getAsOpaquePtr());
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ComplexType *) { return true; }
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// PointerLikeType - Common base class for pointers and references.
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// FIXME: Add more documentation on this classes design point. For example,
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// should BlockPointerType inherit from it? Is the concept of a PointerLikeType
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// in the C++ standard?
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass PointerLikeType : public Type {
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType PointeeType;
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  PointerLikeType(TypeClass K, QualType Pointee, QualType CanonicalPtr) :
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Type(K, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) {
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getPointeeType() const { return PointeeType; }
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == Pointer || T->getTypeClass() == Reference;
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const PointerLikeType *) { return true; }
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// PointerType - C99 6.7.5.1 - Pointer Declarators.
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass PointerType : public PointerLikeType, public llvm::FoldingSetNode {
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  PointerType(QualType Pointee, QualType CanonicalPtr) :
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    PointerLikeType(Pointer, Pointee, CanonicalPtr) {
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Profile(ID, getPointeeType());
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Pointee.getAsOpaquePtr());
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const PointerType *) { return true; }
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// BlockPointerType - pointer to a block type.
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// This type is to represent types syntactically represented as
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// "void (^)(int)", etc. Pointee is required to always be a function type.
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// FIXME: Should BlockPointerType inherit from PointerLikeType? It could
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// simplfy some type checking code, however PointerLikeType doesn't appear
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// to be used by the type checker.
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass BlockPointerType : public Type, public llvm::FoldingSetNode {
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType PointeeType;  // Block is some kind of pointer type
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  BlockPointerType(QualType Pointee, QualType CanonicalCls) :
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Type(BlockPointer, CanonicalCls, Pointee->isDependentType()),
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    PointeeType(Pointee) {
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Get the pointee type. Pointee is required to always be a function type.
6821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  QualType getPointeeType() const { return PointeeType; }
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Profile(ID, getPointeeType());
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ID.AddPointer(Pointee.getAsOpaquePtr());
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == BlockPointer;
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const BlockPointerType *) { return true; }
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  protected:
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    virtual void EmitImpl(llvm::Serializer& S) const;
7001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
7011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    friend class Type;
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ReferenceType - C++ 8.3.2 - Reference Declarators.
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass ReferenceType : public PointerLikeType, public llvm::FoldingSetNode {
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ReferenceType(QualType Referencee, QualType CanonicalRef) :
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    PointerLikeType(Reference, Referencee, CanonicalRef) {
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Profile(ID, getPointeeType());
7161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  }
7171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Referencee.getAsOpaquePtr());
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == Reference; }
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ReferenceType *) { return true; }
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// MemberPointerType - C++ 8.3.3 - Pointers to members
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass MemberPointerType : public Type, public llvm::FoldingSetNode {
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType PointeeType;
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// The class of which the pointee is a member. Must ultimately be a
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// RecordType, but could be a typedef or a template parameter too.
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Type *Class;
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Type(MemberPointer, CanonicalPtr,
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         Cls->isDependentType() || Pointee->isDependentType()),
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    PointeeType(Pointee), Class(Cls) {
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext; // ASTContext creates these.
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getPointeeType() const { return PointeeType; }
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Type *getClass() const { return Class; }
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Profile(ID, getPointeeType(), getClass());
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      const Type *Class) {
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Pointee.getAsOpaquePtr());
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Class);
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == MemberPointer;
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const MemberPointerType *) { return true; }
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ArrayType - C99 6.7.5.2 - Array Declarators.
77304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt///
77404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtclass ArrayType : public Type, public llvm::FoldingSetNode {
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// an array with a static size (e.g. int X[static 4]), or an array
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// with a star size (e.g. int X[*]).
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// 'static' is only allowed on function parameters.
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  enum ArraySizeModifier {
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Normal, Static, Star
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  };
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprivate:
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// ElementType - The element type of the array.
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType ElementType;
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// NOTE: These fields are packed into the bitfields space in the Type class.
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned SizeModifier : 2;
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// IndexTypeQuals - Capture qualifiers in declarations like:
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// 'int X[static restrict 4]'. For function parameters only.
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned IndexTypeQuals : 3;
7941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtprotected:
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // C++ [temp.dep.type]p1:
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  //   A type is dependent if it is...
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  //     - an array type constructed from any dependent type or whose
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  //       size is specified by a constant expression that is
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  //       value-dependent,
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ArrayType(TypeClass tc, QualType et, QualType can,
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            ArraySizeModifier sm, unsigned tq)
80304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    : Type(tc, can, et->isDependentType() || tc == DependentSizedArray),
80404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
80504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
80604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
80704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
80804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  QualType getElementType() const { return ElementType; }
80904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  ArraySizeModifier getSizeModifier() const {
81004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return ArraySizeModifier(SizeModifier);
81104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
81204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
81304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
81404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const Type *T) {
81504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return T->getTypeClass() == ConstantArray ||
81604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt           T->getTypeClass() == VariableArray ||
81704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt           T->getTypeClass() == IncompleteArray ||
81804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt           T->getTypeClass() == DependentSizedArray;
81904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
82004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const ArrayType *) { return true; }
82104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
82204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
82304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// ConstantArrayType - This class represents C arrays with a specified constant
82404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// size.  For example 'int A[100]' has ConstantArrayType where the element type
82504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// is 'int' and the size is 100.
82604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtclass ConstantArrayType : public ArrayType {
82704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  llvm::APInt Size; // Allows us to unique the type.
82804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
82904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  ConstantArrayType(QualType et, QualType can, llvm::APInt sz,
83004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                    ArraySizeModifier sm, unsigned tq)
83104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    : ArrayType(ConstantArray, et, can, sm, tq), Size(sz) {}
83204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
83304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
83404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  const llvm::APInt &getSize() const { return Size; }
83504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
83604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
83704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
83804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    Profile(ID, getElementType(), getSize());
83904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
84004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
84104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                      llvm::APInt ArraySize) {
84204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    ID.AddPointer(ET.getAsOpaquePtr());
84304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    ID.AddInteger(ArraySize.getZExtValue());
84404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
84504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const Type *T) {
84604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return T->getTypeClass() == ConstantArray;
84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const ConstantArrayType *) { return true; }
84904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
85004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtprotected:
851fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
852fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
853fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt  friend class Type;
85404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
85504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
85604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// IncompleteArrayType - This class represents C arrays with an unspecified
85704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// size.  For example 'int A[]' has an IncompleteArrayType where the element
85804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// type is 'int' and the size is unspecified.
85904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtclass IncompleteArrayType : public ArrayType {
86004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  IncompleteArrayType(QualType et, QualType can,
86104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                    ArraySizeModifier sm, unsigned tq)
86204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    : ArrayType(IncompleteArray, et, can, sm, tq) {}
86304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
86404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
86504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
86604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
86704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
86804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const Type *T) {
86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return T->getTypeClass() == IncompleteArray;
87004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
87104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const IncompleteArrayType *) { return true; }
87204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
87304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class StmtIteratorBase;
87404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
87504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
87604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    Profile(ID, getElementType());
87761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
87861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
87961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET) {
88061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    ID.AddPointer(ET.getAsOpaquePtr());
88161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
88261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
88361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtprotected:
88461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
88561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
88661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  friend class Type;
88761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt};
88861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
88961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// VariableArrayType - This class represents C arrays with a specified size
89061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// which is not an integer-constant-expression.  For example, 'int s[x+foo()]'.
89161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// Since the size expression is an arbitrary expression, we store it as such.
89261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///
89361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
89461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// should not be: two lexically equivalent variable array types could mean
89561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// different things, for example, these variables do not have the same type
89661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// dynamically:
89761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///
89861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// void foo(int x) {
89961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///   int Y[x];
90061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///   ++x;
90161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///   int Z[x];
90261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// }
90361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///
90461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtclass VariableArrayType : public ArrayType {
90561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// SizeExpr - An assignment expression. VLA's are only permitted within
90661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// a function block.
907051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  Stmt *SizeExpr;
90861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
90961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  VariableArrayType(QualType et, QualType can, Expr *e,
910051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt                    ArraySizeModifier sm, unsigned tq)
911051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    : ArrayType(VariableArray, et, can, sm, tq), SizeExpr((Stmt*) e) {}
912051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
913051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  virtual void Destroy(ASTContext& C);
914051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
915051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtpublic:
916051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  Expr *getSizeExpr() const {
917051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    // We use C-style casts instead of cast<> here because we do not wish
918051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    // to have a dependency of Type.h on Stmt.h/Expr.h.
919051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    return (Expr*) SizeExpr;
920051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  }
921051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
922051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
923051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
924051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  static bool classof(const Type *T) {
925051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    return T->getTypeClass() == VariableArray;
926051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  }
927051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  static bool classof(const VariableArrayType *) { return true; }
928051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
92968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt  friend class StmtIteratorBase;
930051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
931051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
932051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    assert(0 && "Cannnot unique VariableArrayTypes.");
933051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  }
934051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
935051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtprotected:
936051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
937051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
938051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  friend class Type;
939051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt};
940051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
941051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// DependentSizedArrayType - This type represents an array type in
942051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// C++ whose size is a value-dependent expression. For example:
943051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// @code
944051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// template<typename T, int Size>
945051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// class array {
946051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt///   T data[Size];
947051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// };
948051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// @endcode
949051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// For these types, we won't actually know what the array bound is
950051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// until template instantiation occurs, at which point this will
951051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/// become either a ConstantArrayType or a VariableArrayType.
952051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtclass DependentSizedArrayType : public ArrayType {
953051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  /// SizeExpr - An assignment expression that will instantiate to the
954051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  /// size of the array.
955051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  Stmt *SizeExpr;
956051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
957051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt  DependentSizedArrayType(QualType et, QualType can, Expr *e,
958051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  ArraySizeModifier sm, unsigned tq)
959051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt    : ArrayType(DependentSizedArray, et, can, sm, tq), SizeExpr((Stmt*) e) {}
960a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
96161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void Destroy(ASTContext& C);
96261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
96361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtpublic:
96461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  Expr *getSizeExpr() const {
96561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    // We use C-style casts instead of cast<> here because we do not wish
96661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    // to have a dependency of Type.h on Stmt.h/Expr.h.
96761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    return (Expr*) SizeExpr;
96861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
96961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
97061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
97161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
97261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const Type *T) {
97361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    return T->getTypeClass() == DependentSizedArray;
97461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
97561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const DependentSizedArrayType *) { return true; }
97661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
97761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  friend class StmtIteratorBase;
97861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
97961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
98061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    assert(0 && "Cannnot unique DependentSizedArrayTypes.");
98161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
98261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
98361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtprotected:
98461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
98561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
98661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  friend class Type;
98761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt};
98861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
98961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// VectorType - GCC generic vector type. This type is created using
99061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// __attribute__((vector_size(n)), where "n" specifies the vector size in
99161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// bytes. Since the constructor takes the number of vector elements, the
99261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// client is responsible for converting the size into the number of elements.
993fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtclass VectorType : public Type, public llvm::FoldingSetNode {
994fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtprotected:
995fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt  /// ElementType - The element type of the vector.
99661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  QualType ElementType;
99761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
99861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// NumElements - The number of elements in the vector.
99961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  unsigned NumElements;
100061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1001a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  VectorType(QualType vecType, unsigned nElements, QualType canonType) :
100261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    Type(Vector, canonType, vecType->isDependentType()),
1003a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt    ElementType(vecType), NumElements(nElements) {}
100404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  VectorType(TypeClass tc, QualType vecType, unsigned nElements,
100504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt             QualType canonType)
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      NumElements(nElements) {}
100804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
100904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
101104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  QualType getElementType() const { return ElementType; }
101204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  unsigned getNumElements() const { return NumElements; }
1013a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
101461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
1015a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
101661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
101761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    Profile(ID, getElementType(), getNumElements(), getTypeClass());
101861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
101904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
102004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                      unsigned NumElements, TypeClass TypeClass) {
102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    ID.AddPointer(ElementType.getAsOpaquePtr());
102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    ID.AddInteger(NumElements);
102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    ID.AddInteger(TypeClass);
102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const VectorType *) { return true; }
102904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
103004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
103104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// ExtVectorType - Extended vector type. This type is created using
103204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
103304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
103461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// class enables syntactic extensions, like Vector Components for accessing
103561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// points, colors, and textures (modeled after OpenGL Shading Language).
103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtclass ExtVectorType : public VectorType {
1037a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
103861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    VectorType(ExtVector, vecType, nElements, canonType) {}
1039a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
104061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtpublic:
104161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static int getPointAccessorIdx(char c) {
104261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    switch (c) {
104304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    default: return -1;
104404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    case 'x': return 0;
104504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    case 'y': return 1;
104604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    case 'z': return 2;
104704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    case 'w': return 3;
104804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    }
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
105004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static int getNumericAccessorIdx(char c) {
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    switch (c) {
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      default: return -1;
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case '0': return 0;
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case '1': return 1;
105504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case '2': return 2;
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case '3': return 3;
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case '4': return 4;
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case '5': return 5;
105904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case '6': return 6;
106004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case '7': return 7;
106104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case '8': return 8;
106204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case '9': return 9;
106304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case 'a': return 10;
106404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case 'b': return 11;
106504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case 'c': return 12;
106604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      case 'd': return 13;
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case 'e': return 14;
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      case 'f': return 15;
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static int getAccessorIdx(char c) {
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (int idx = getPointAccessorIdx(c)+1) return idx-1;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return getNumericAccessorIdx(c);
10751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  }
10761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
10771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  bool isAccessorWithinNumElements(char c) const {
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (int idx = getAccessorIdx(c)+1)
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return unsigned(idx-1) < NumElements;
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == ExtVector;
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ExtVectorType *) { return true; }
10881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt};
10891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// class of FunctionTypeNoProto and FunctionTypeProto.
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass FunctionType : public Type {
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// SubClassData - This field is owned by the subclass, put here to pack
10951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  /// tightly with the ivars in Type.
10961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  bool SubClassData : 1;
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// TypeQuals - Used only by FunctionTypeProto, put here to pack with the
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// other bitfields.
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// The qualifiers are part of FunctionTypeProto because...
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ///
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// C++ 8.3.5p4: The return type, the parameter type list and the
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// cv-qualifier-seq, [...], are part of the function type.
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ///
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned TypeQuals : 3;
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // The type returned by the function.
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType ResultType;
11091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtprotected:
11101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
11111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt               unsigned typeQuals, QualType Canonical, bool Dependent)
11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    : Type(tc, Canonical, Dependent),
11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      SubClassData(SubclassInfo), TypeQuals(typeQuals), ResultType(res) {}
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool getSubClassData() const { return SubClassData; }
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getTypeQuals() const { return TypeQuals; }
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getResultType() const { return ResultType; }
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == FunctionNoProto ||
11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt           T->getTypeClass() == FunctionProto;
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const FunctionType *) { return true; }
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// FunctionTypeNoProto - Represents a K&R-style 'int foo()' function, which has
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// no information available about its arguments.
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode {
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  FunctionTypeNoProto(QualType Result, QualType Canonical)
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : FunctionType(FunctionNoProto, Result, false, 0, Canonical,
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                   /*Dependent=*/false) {}
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
113504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
113604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  // No additional state past what FunctionType provides.
113704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
113804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
113904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
114004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
114104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    Profile(ID, getResultType());
114204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
114304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType) {
114404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    ID.AddPointer(ResultType.getAsOpaquePtr());
114504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
114604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
114704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const Type *T) {
114804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return T->getTypeClass() == FunctionNoProto;
114904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
115004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const FunctionTypeNoProto *) { return true; }
115104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
115204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtprotected:
115304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
115404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
115504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class Type;
115604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
115704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
115804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// FunctionTypeProto - Represents a prototype with argument type info, e.g.
115904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
116004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// arguments, not as having a single void argument.
116104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtclass FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
116204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  /// hasAnyDependentType - Determine whether there are any dependent
116304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  /// types within the arguments passed in.
116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) {
116504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    for (unsigned Idx = 0; Idx < numArgs; ++Idx)
116604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      if (ArgArray[Idx]->isDependentType())
116704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return true;
116804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
116904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return false;
117004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
117104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
117204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  FunctionTypeProto(QualType Result, const QualType *ArgArray, unsigned numArgs,
117304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                    bool isVariadic, unsigned typeQuals, QualType Canonical)
117404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
117504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                   (Result->isDependentType() ||
117604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                    hasAnyDependentType(ArgArray, numArgs))),
117704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      NumArgs(numArgs) {
117804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    // Fill in the trailing argument array.
117904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    QualType *ArgInfo = reinterpret_cast<QualType *>(this+1);;
118004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    for (unsigned i = 0; i != numArgs; ++i)
118104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      ArgInfo[i] = ArgArray[i];
118204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
118304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
118404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  /// NumArgs - The number of arguments this function has, not counting '...'.
118504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  unsigned NumArgs;
118604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
118704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  /// ArgInfo - There is an variable size array after the class in memory that
118804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  /// holds the argument types.
118904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
119004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
119104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
119204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
119304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  unsigned getNumArgs() const { return NumArgs; }
119404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  QualType getArgType(unsigned i) const {
119504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    assert(i < NumArgs && "Invalid argument number!");
119604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return arg_type_begin()[i];
119704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
119804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
119904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  bool isVariadic() const { return getSubClassData(); }
120004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
120104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
120204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  typedef const QualType *arg_type_iterator;
120304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  arg_type_iterator arg_type_begin() const {
120404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return reinterpret_cast<const QualType *>(this+1);
120504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
120604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
120704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
120804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
120904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
121004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const Type *T) {
121104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return T->getTypeClass() == FunctionProto;
121204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const FunctionTypeProto *) { return true; }
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID);
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      arg_type_iterator ArgTys, unsigned NumArgs,
12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      bool isVariadic, unsigned TypeQuals);
12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass TypedefType : public Type {
12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TypedefDecl *Decl;
12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TypedefType(TypeClass tc, TypedefDecl *D, QualType can)
12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Type(tc, can, can->isDependentType()), Decl(D) {
12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    assert(!isa<TypedefType>(can) && "Invalid canonical type");
12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TypedefDecl *getDecl() const { return Decl; }
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// potentially looking through *all* consecutive typedefs.  This returns the
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// sum of the type qualifiers, so if you have:
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ///   typedef const int A;
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ///   typedef volatile A B;
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// looking through the typedefs for B will give you "const volatile A".
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType LookThroughTypedefs() const;
12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == TypeName; }
12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const TypedefType *) { return true; }
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// TypeOfExpr (GCC extension).
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass TypeOfExpr : public Type {
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Expr *TOExpr;
12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TypeOfExpr(Expr *E, QualType can);
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Expr *getUnderlyingExpr() const { return TOExpr; }
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExp; }
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const TypeOfExpr *) { return true; }
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// TypeOfType (GCC extension).
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass TypeOfType : public Type {
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType TOType;
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TypeOfType(QualType T, QualType can)
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Type(TypeOfTyp, can, T->isDependentType()), TOType(T) {
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    assert(!isa<TypedefType>(can) && "Invalid canonical type");
12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getUnderlyingType() const { return TOType; }
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == TypeOfTyp; }
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const TypeOfType *) { return true; }
12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass TagType : public Type {
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// Stores the TagDecl associated with this type. The decl will
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// point to the TagDecl that actually defines the entity (or is a
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// definition in progress), if there is such a definition. The
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// single-bit value will be non-zero when this tag is in the
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// process of being defined.
13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  llvm::PointerIntPair<TagDecl *, 1> decl;
13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;
13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class TagDecl;
13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: We'll need the user to pass in information about whether
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // this type is dependent or not, because we don't have enough
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // information to compute it here.
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TagType(TagDecl *D, QualType can)
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Type(Tagged, can, /*Dependent=*/false), decl(D, 0) {}
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TagDecl *getDecl() const { return decl.getPointer(); }
13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// @brief Determines whether this type is in the process of being
13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// defined.
13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isBeingDefined() const { return decl.getInt(); }
13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void setBeingDefined(bool Def) { decl.setInt(Def? 1 : 0); }
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) { return T->getTypeClass() == Tagged; }
13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const TagType *) { return true; }
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// to detect TagType objects of structs/unions/classes.
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass RecordType : public TagType {
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  explicit RecordType(RecordDecl *D)
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : TagType(reinterpret_cast<TagDecl*>(D), QualType()) { }
134104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;   // ASTContext creates these.
134261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtpublic:
134361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  RecordDecl *getDecl() const {
13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: This predicate is a helper to QualType/Type. It needs to
13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // recursively check all fields for const-ness. If any field is declared
13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // const, it needs to return false.
13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool hasConstFields() const { return false; }
135261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: RecordType needs to check when it is created that all fields are in
13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // the same address space, and return that.
13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getAddressSpace() const { return 0; }
13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const TagType *T);
135861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const Type *T) {
135904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return isa<TagType>(T) && classof(cast<TagType>(T));
136004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
136104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const RecordType *) { return true; }
136204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
136361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
136404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// CXXRecordType - This is a helper class that allows the use of
136504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// isa/cast/dyncast to detect TagType objects of C++ structs/unions/classes.
136604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtclass CXXRecordType : public RecordType {
136704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  explicit CXXRecordType(CXXRecordDecl *D)
136804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    : RecordType(reinterpret_cast<RecordDecl*>(D)) { }
136961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  friend class ASTContext;   // ASTContext creates these.
137004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
137104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
137204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  CXXRecordDecl *getDecl() const {
137304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return reinterpret_cast<CXXRecordDecl*>(RecordType::getDecl());
137461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
137504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
137604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const TagType *T);
137704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  static bool classof(const Type *T) {
137804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return isa<TagType>(T) && classof(cast<TagType>(T));
137904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
138061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const CXXRecordType *) { return true; }
138104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
138204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
138304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
138404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/// to detect TagType objects of enums.
138561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtclass EnumType : public TagType {
138604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  explicit EnumType(EnumDecl *D)
138704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    : TagType(reinterpret_cast<TagDecl*>(D), QualType()) { }
138804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  friend class ASTContext;   // ASTContext creates these.
138904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtpublic:
139004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
139161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  EnumDecl *getDecl() const {
139204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    return reinterpret_cast<EnumDecl*>(TagType::getDecl());
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const TagType *T);
139661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const Type *T) {
139761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    return isa<TagType>(T) && classof(cast<TagType>(T));
139861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
139961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const EnumType *) { return true; }
140061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt};
140161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
140261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtclass TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
140361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  unsigned Depth : 16;
140461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  unsigned Index : 16;
140561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  IdentifierInfo *Name;
140661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
140761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  TemplateTypeParmType(unsigned D, unsigned I, IdentifierInfo *N,
140861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                       QualType Canon)
140961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    : Type(TemplateTypeParm, Canon, /*Dependent=*/true),
141061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      Depth(D), Index(I), Name(N) { }
141161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
141261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  TemplateTypeParmType(unsigned D, unsigned I)
141361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true),
141468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt      Depth(D), Index(I), Name(0) { }
141561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
141661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these
141761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
141861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtpublic:
141961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  unsigned getDepth() const { return Depth; }
142061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  unsigned getIndex() const { return Index; }
142161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  IdentifierInfo *getName() const { return Name; }
142261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
142361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
142461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
142561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
142661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    Profile(ID, Depth, Index, Name);
142761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
142861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
142961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
143061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                      unsigned Index, IdentifierInfo *Name) {
143161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    ID.AddInteger(Depth);
143261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    ID.AddInteger(Index);
143361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    ID.AddPointer(Name);
143461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
143561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
143661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const Type *T) {
143761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    return T->getTypeClass() == TemplateTypeParm;
143861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
143961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static bool classof(const TemplateTypeParmType *T) { return true; }
144061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
144161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtprotected:
144261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
144361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
144461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  friend class Type;
144561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt};
144661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
144761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// \brief Represents the type of a class template specialization as
144861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// written in the source code.
144961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt///
145061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// Class template specialization types represent the syntactic form
145161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// of a template-id that refers to a type, e.g., @c vector<int>. All
145261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// class template specialization types are syntactic sugar, whose
145361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// canonical type will point to some other type node that represents
145461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// the instantiation or class template specialization. For example, a
145561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// class template specialization type of @c vector<int> will refer to
145661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// a tag type for the instantiation
145761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/// @c std::vector<int, std::allocator<int>>.
145861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtclass ClassTemplateSpecializationType
145961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  : public Type, public llvm::FoldingSetNode {
146061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
146161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // FIXME: Do we want templates to have a representation in the type
146261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // system? It will probably help with dependent templates and
146361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // possibly with template-names preceded by a nested-name-specifier.
146461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  TemplateDecl *Template;
146561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
146661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  unsigned NumArgs;
146761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
146861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  ClassTemplateSpecializationType(TemplateDecl *T, unsigned NumArgs,
146961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                                  uintptr_t *Args, bool *ArgIsType,
147061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                                  QualType Canon);
147161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
147261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// \brief Retrieve the number of packed words that precede the
147361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// actual arguments.
147461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  ///
147561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// The flags that specify whether each argument is a type or an
147661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// expression are packed into the
147761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// ClassTemplateSpecializationType. This routine computes the
147861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// number of pointer-sized words we need to store this information,
147961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  /// based on the number of template arguments
148061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static unsigned getNumPackedWords(unsigned NumArgs) {
148161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    const unsigned BitsPerWord = sizeof(uintptr_t) * 8;
14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return NumArgs / BitsPerWord + (NumArgs % BitsPerWord > 0);
14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \brief Pack the given boolean values into words.
14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void
14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  packBooleanValues(unsigned NumArgs, bool *Values, uintptr_t *Words);
14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void Destroy(ASTContext& C);
14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these
14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \brief Retrieve the template that we are specializing.
14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  TemplateDecl *getTemplate() const { return Template; }
14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \briefe Retrieve the number of template arguments.
14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getNumArgs() const { return NumArgs; }
14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \brief Retrieve a specific template argument as a type.
15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \precondition @c isArgType(Arg)
15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType getArgAsType(unsigned Arg) const {
15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    assert(isArgType(Arg) && "Argument is not a type");
15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return QualType::getFromOpaquePtr(
15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                          reinterpret_cast<void *>(getArgAsOpaqueValue(Arg)));
15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \brief Retrieve a specific template argument as an expression.
15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \precondition @c !isArgType(Arg)
15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Expr *getArgAsExpr(unsigned Arg) const {
15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    assert(!isArgType(Arg) && "Argument is not an expression");
15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return reinterpret_cast<Expr *>(getArgAsOpaqueValue(Arg));
15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \brief Retrieve the specified template argument as an opaque value.
15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  uintptr_t getArgAsOpaqueValue(unsigned Arg) const;
15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// \brief Determine whether the given template argument is a type.
15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isArgType(unsigned Arg) const;
15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID) {
15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Add the template
15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ID.AddPointer(Template);
15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Add the packed words describing what kind of template arguments
15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // we have.
15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // FIXME: Would like to be smarter about the profile of expressions,
15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // so that we can combine expression nodes more effectively.
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    uintptr_t *Data = reinterpret_cast<uintptr_t *>(this + 1);
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    for (unsigned Packed = 0, NumPacked = getNumPackedWords(NumArgs);
15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         Packed != NumPacked; ++Packed)
15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ID.AddInteger(Data[Packed]);
15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Add the template arguments themselves.
153761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
153861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      ID.AddInteger(getArgAsOpaqueValue(Arg));
153961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  }
154061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
154161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID, TemplateDecl *T,
154261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                      unsigned NumArgs, uintptr_t *Args, bool *ArgIsType) {
154361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    // Add the template
154461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    ID.AddPointer(T);
154561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Add the packed words describing what kind of template arguments
15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // we have.
15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    unsigned NumPackedWords = getNumPackedWords(NumArgs);
15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    unsigned NumPackedBytes = NumPackedWords * sizeof(uintptr_t);
15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    uintptr_t *PackedWords
15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      = reinterpret_cast<uintptr_t *>(alloca(NumPackedBytes));
15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    packBooleanValues(NumArgs, ArgIsType, PackedWords);
15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    for (unsigned Packed = 0; Packed != NumPackedWords; ++Packed)
15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ID.AddInteger(PackedWords[Packed]);
15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Add the template arguments themselves.
15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ID.AddInteger(Args[Arg]);
15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == ClassTemplateSpecialization;
15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ClassTemplateSpecializationType *T) { return true; }
15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void EmitImpl(llvm::Serializer& S) const;
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class Type;
15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// object oriented design.  They basically correspond to C++ classes.  There
15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// are two kinds of interface types, normal interfaces like "NSString" and
15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// qualified interfaces, which are qualified with a protocol list like
15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// "NSString<NSCopyable, NSAmazing>".  Qualified interface types are instances
15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// of ObjCQualifiedInterfaceType, which is a subclass of ObjCInterfaceType.
15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass ObjCInterfaceType : public Type {
15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCInterfaceDecl *Decl;
15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprotected:
15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCInterfaceType(TypeClass tc, ObjCInterfaceDecl *D) :
15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Type(tc, QualType(), /*Dependent=*/false), Decl(D) { }
15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCInterfaceDecl *getDecl() const { return Decl; }
15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// qual_iterator and friends: this provides access to the (potentially empty)
15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// list of protocols qualifying this interface.  If this is an instance of
15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// ObjCQualifiedInterfaceType it returns the list, otherwise it returns an
15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// empty list if there are no qualifying protocols.
15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inline qual_iterator qual_begin() const;
15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inline qual_iterator qual_end() const;
15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool qual_empty() const { return getTypeClass() != ObjCQualifiedInterface; }
15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// getNumProtocols - Return the number of qualifying protocols in this
15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// interface type, or 0 if there are none.
15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inline unsigned getNumProtocols() const;
16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  /// getProtocol - Return the specified qualifying protocol.
16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inline ObjCProtocolDecl *getProtocol(unsigned i) const;
16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == ObjCInterface ||
16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt           T->getTypeClass() == ObjCQualifiedInterface;
16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ObjCInterfaceType *) { return true; }
16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ObjCQualifiedInterfaceType - This class represents interface types
16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// conforming to a list of protocols, such as INTF<Proto1, Proto2, Proto1>.
16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Duplicate protocols are removed and protocol list is canonicalized to be in
16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// alphabetical order.
16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass ObjCQualifiedInterfaceType : public ObjCInterfaceType,
16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                   public llvm::FoldingSetNode {
16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // List of protocols for this protocol conforming object type
162275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  // List is sorted on protocol name. No protocol is enterred more than once.
16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCQualifiedInterfaceType(ObjCInterfaceDecl *D,
16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                             ObjCProtocolDecl **Protos, unsigned NumP) :
16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ObjCInterfaceType(ObjCQualifiedInterface, D),
16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Protocols(Protos, Protos+NumP) { }
16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCProtocolDecl *getProtocol(unsigned i) const {
16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Protocols[i];
16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getNumProtocols() const {
16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Protocols.size();
16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  qual_iterator qual_begin() const { return Protocols.begin(); }
16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  qual_iterator qual_end() const   { return Protocols.end(); }
16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID);
16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID,
16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      const ObjCInterfaceDecl *Decl,
16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      ObjCProtocolDecl **protocols, unsigned NumProtocols);
16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == ObjCQualifiedInterface;
16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ObjCQualifiedInterfaceType *) { return true; }
16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline ObjCInterfaceType::qual_iterator ObjCInterfaceType::qual_begin() const {
16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ObjCQualifiedInterfaceType *QIT =
16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         dyn_cast<ObjCQualifiedInterfaceType>(this))
16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return QIT->qual_begin();
16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return 0;
16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline ObjCInterfaceType::qual_iterator ObjCInterfaceType::qual_end() const {
16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ObjCQualifiedInterfaceType *QIT =
16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt         dyn_cast<ObjCQualifiedInterfaceType>(this))
16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return QIT->qual_end();
16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return 0;
16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// getNumProtocols - Return the number of qualifying protocols in this
16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// interface type, or 0 if there are none.
16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline unsigned ObjCInterfaceType::getNumProtocols() const {
16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ObjCQualifiedInterfaceType *QIT =
16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        dyn_cast<ObjCQualifiedInterfaceType>(this))
16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return QIT->getNumProtocols();
16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return 0;
16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// getProtocol - Return the specified qualifying protocol.
16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline ObjCProtocolDecl *ObjCInterfaceType::getProtocol(unsigned i) const {
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return cast<ObjCQualifiedInterfaceType>(this)->getProtocol(i);
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// ObjCQualifiedIdType - to represent id<protocol-list>.
16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Duplicate protocols are removed and protocol list is canonicalized to be in
16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// alphabetical order.
16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass ObjCQualifiedIdType : public Type,
16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                            public llvm::FoldingSetNode {
16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // List of protocols for this protocol conforming 'id' type
16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // List is sorted on protocol name. No protocol is enterred more than once.
16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCQualifiedIdType(ObjCProtocolDecl **Protos, unsigned NumP)
16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    : Type(ObjCQualifiedId, QualType()/*these are always canonical*/,
16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt           /*Dependent=*/false),
16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Protocols(Protos, Protos+NumP) { }
16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  friend class ASTContext;  // ASTContext creates these.
16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic:
17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCProtocolDecl *getProtocols(unsigned i) const {
17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Protocols[i];
17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned getNumProtocols() const {
17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return Protocols.size();
17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ObjCProtocolDecl **getReferencedProtocols() {
17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return &Protocols[0];
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  qual_iterator qual_begin() const { return Protocols.begin(); }
17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  qual_iterator qual_end() const   { return Protocols.end(); }
17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  virtual void getAsStringInternal(std::string &InnerString) const;
17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  void Profile(llvm::FoldingSetNodeID &ID);
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void Profile(llvm::FoldingSetNodeID &ID,
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                      ObjCProtocolDecl **protocols, unsigned NumProtocols);
17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const Type *T) {
17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getTypeClass() == ObjCQualifiedId;
17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static bool classof(const ObjCQualifiedIdType *) { return true; }
17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// Inline function definitions.
17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// getUnqualifiedType - Return the type without any qualifiers.
17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline QualType QualType::getUnqualifiedType() const {
17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Type *TP = getTypePtr();
1734d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(TP))
17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    TP = EXTQT->getBaseType();
17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return QualType(TP, 0);
17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// getAddressSpace - Return the address space of this type.
17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline unsigned QualType::getAddressSpace() const {
17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType CT = getTypePtr()->getCanonicalTypeInternal();
17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return AT->getElementType().getAddressSpace();
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const RecordType *RT = dyn_cast<RecordType>(CT))
17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return RT->getAddressSpace();
17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CT))
17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EXTQT->getAddressSpace();
17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return 0;
17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// getObjCGCAttr - Return the gc attribute of this type.
17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline QualType::GCAttrTypes QualType::getObjCGCAttr() const {
17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType CT = getTypePtr()->getCanonicalTypeInternal();
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return AT->getElementType().getObjCGCAttr();
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CT))
17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EXTQT->getObjCGCAttr();
17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return GCNone;
17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// isMoreQualifiedThan - Determine whether this type is more
17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// qualified than the Other type. For example, "const volatile int"
17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// is more qualified than "const int", "volatile int", and
17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// "int". However, it is not more qualified than "const volatile
17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// int".
17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool QualType::isMoreQualifiedThan(QualType Other) const {
17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: Handle address spaces
1768a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  unsigned MyQuals = this->getCVRQualifiers();
1769a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  unsigned OtherQuals = Other.getCVRQualifiers();
17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(this->getAddressSpace() == 0 && "Address space not checked");
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(Other.getAddressSpace() == 0 && "Address space not checked");
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals;
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// isAtLeastAsQualifiedAs - Determine whether this type is at last
1776a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/// as qualified as the Other type. For example, "const volatile
1777a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/// int" is at least as qualified as "const int", "volatile int",
1778a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/// "int", and "const volatile int".
17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool QualType::isAtLeastAsQualifiedAs(QualType Other) const {
17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: Handle address spaces
17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned MyQuals = this->getCVRQualifiers();
17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned OtherQuals = Other.getCVRQualifiers();
17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(this->getAddressSpace() == 0 && "Address space not checked");
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(Other.getAddressSpace() == 0 && "Address space not checked");
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return (MyQuals | OtherQuals) == MyQuals;
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// getNonReferenceType - If Type is a reference type (e.g., const
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// int&), returns the type that the reference refers to ("const
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// int"). Otherwise, returns the type itself. This routine is used
17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// throughout Sema to implement C++ 5p6:
17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///   If an expression initially has the type "reference to T" (8.3.2,
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///   8.5.3), the type is adjusted to "T" prior to any further
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt///   analysis, the expression designates the object or function
179604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt///   denoted by the reference, and the expression is an lvalue.
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline QualType QualType::getNonReferenceType() const {
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ReferenceType *RefType = (*this)->getAsReferenceType())
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return RefType->getPointeeType();
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  else
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return *this;
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline const TypedefType* Type::getAsTypedefType() const {
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return dyn_cast<TypedefType>(this);
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const PointerType *PT = getAsPointerType())
18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return PT->getPointeeType()->getAsObjCInterfaceType();
18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return 0;
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// NOTE: All of these methods use "getUnqualifiedType" to strip off address
18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// space qualifiers if present.
18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isFunctionType() const {
18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<FunctionType>(CanonicalType.getUnqualifiedType());
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isPointerType() const {
18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<PointerType>(CanonicalType.getUnqualifiedType());
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isBlockPointerType() const {
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return isa<BlockPointerType>(CanonicalType);
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isReferenceType() const {
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isPointerLikeType() const {
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<PointerLikeType>(CanonicalType.getUnqualifiedType());
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isFunctionPointerType() const {
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const PointerType* T = getAsPointerType())
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getPointeeType()->isFunctionType();
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  else
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isMemberPointerType() const {
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<MemberPointerType>(CanonicalType.getUnqualifiedType());
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isMemberFunctionPointerType() const {
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const MemberPointerType* T = getAsMemberPointerType())
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return T->getPointeeType()->isFunctionType();
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  else
18431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    return false;
18441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isArrayType() const {
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<ArrayType>(CanonicalType.getUnqualifiedType());
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isConstantArrayType() const {
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isIncompleteArrayType() const {
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isVariableArrayType() const {
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isDependentSizedArrayType() const {
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<DependentSizedArrayType>(CanonicalType.getUnqualifiedType());
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isRecordType() const {
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<RecordType>(CanonicalType.getUnqualifiedType());
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isAnyComplexType() const {
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<ComplexType>(CanonicalType.getUnqualifiedType());
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isVectorType() const {
18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return isa<VectorType>(CanonicalType.getUnqualifiedType());
18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtinline bool Type::isExtVectorType() const {
187075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
187175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
187275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninline bool Type::isObjCInterfaceType() const {
187375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
187475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
187575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninline bool Type::isObjCQualifiedInterfaceType() const {
187675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  return isa<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
187775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
187875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninline bool Type::isObjCQualifiedIdType() const {
187975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  return isa<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
188075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
188175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninline bool Type::isTemplateTypeParmType() const {
188275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
188375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
188475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
188575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninline bool Type::isSpecificBuiltinType(unsigned K) const {
188675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen  if (const BuiltinType *BT = getAsBuiltinType())
18871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    if (BT->getKind() == (BuiltinType::Kind) K)
18881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      return true;
18891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  return false;
18901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
18911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
18921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtinline bool Type::isOverloadType() const {
18931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  return isSpecificBuiltinType(BuiltinType::Overload);
18941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
18951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
18961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/// Insertion operator for diagnostics.  This allows sending QualType's into a
18971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/// diagnostic with <<.
18981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
18991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                                           QualType T) {
19001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
19011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                  Diagnostic::ak_qualtype);
19021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  return DB;
19031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
19041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
19051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}  // end namespace clang
19061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
19071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif
19081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt