ASTContext.cpp revision 7176331b0f5cfaaa2b5aa487a6660e859e371119
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file implements the ASTContext interface.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/ASTContext.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/Decl.h"
16980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#include "clang/AST/DeclObjC.h"
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TargetInfo.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallVector.h"
1985f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson#include "llvm/ADT/StringExtras.h"
207192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek#include "llvm/Bitcode/Serialize.h"
217192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek#include "llvm/Bitcode/Deserialize.h"
2285f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerenum FloatingRank {
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FloatRank, DoubleRank, LongDoubleRank
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerASTContext::~ASTContext() {
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Deallocate all the types.
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (!Types.empty()) {
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(Types.back())) {
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // Destroy the object, but don't call delete.  These are malloc'd.
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      FT->~FunctionTypeProto();
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      free(FT);
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      delete Types.back();
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Types.pop_back();
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ASTContext::PrintStats() const {
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "*** AST Context Stats:\n");
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "  %d types total.\n", (int)Types.size());
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
476d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner  unsigned NumVector = 0, NumComplex = 0;
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
51a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0;
52a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  unsigned NumObjCQualifiedIds = 0;
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = Types.size(); i != e; ++i) {
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Type *T = Types[i];
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (isa<BuiltinType>(T))
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumBuiltin;
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isa<PointerType>(T))
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumPointer;
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isa<ReferenceType>(T))
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumReference;
626d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner    else if (isa<ComplexType>(T))
636d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner      ++NumComplex;
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isa<ArrayType>(T))
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumArray;
666d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner    else if (isa<VectorType>(T))
676d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner      ++NumVector;
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isa<FunctionTypeNoProto>(T))
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumFunctionNP;
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isa<FunctionTypeProto>(T))
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumFunctionP;
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isa<TypedefType>(T))
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumTypeName;
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (TagType *TT = dyn_cast<TagType>(T)) {
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++NumTagged;
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      switch (TT->getDecl()->getKind()) {
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      default: assert(0 && "Unknown tagged type!");
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      case Decl::Struct: ++NumTagStruct; break;
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      case Decl::Union:  ++NumTagUnion; break;
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      case Decl::Class:  ++NumTagClass; break;
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      case Decl::Enum:   ++NumTagEnum; break;
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
83a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    } else if (isa<ObjCInterfaceType>(T))
84a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ++NumObjCInterfaces;
85a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    else if (isa<ObjCQualifiedInterfaceType>(T))
86a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ++NumObjCQualifiedInterfaces;
87a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    else if (isa<ObjCQualifiedIdType>(T))
88a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ++NumObjCQualifiedIds;
893f128ad2691d299b96663da85a9e069c4081ea7cSteve Naroff    else {
90beb663677aa20db59da4e5ab7d535804ec6f963cChris Lattner      QualType(T, 0).dump();
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      assert(0 && "Unknown type!");
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d builtin types\n", NumBuiltin);
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d pointer types\n", NumPointer);
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d reference types\n", NumReference);
986d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner  fprintf(stderr, "    %d complex types\n", NumComplex);
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d array types\n", NumArray);
1006d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner  fprintf(stderr, "    %d vector types\n", NumVector);
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d function types with proto\n", NumFunctionP);
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d function types with no proto\n", NumFunctionNP);
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d typename (typedef) types\n", NumTypeName);
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "    %d tagged types\n", NumTagged);
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "      %d struct types\n", NumTagStruct);
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "      %d union types\n", NumTagUnion);
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "      %d class types\n", NumTagClass);
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "      %d enum types\n", NumTagEnum);
109a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  fprintf(stderr, "    %d interface types\n", NumObjCInterfaces);
110beb663677aa20db59da4e5ab7d535804ec6f963cChris Lattner  fprintf(stderr, "    %d protocol qualified interface types\n",
111a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek          NumObjCQualifiedInterfaces);
112c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  fprintf(stderr, "    %d protocol qualified id types\n",
113a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek          NumObjCQualifiedIds);
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
1166d87fc66ca0e156c4144b692c9e71700b8c18d17Chris Lattner    NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NumFunctionP*sizeof(FunctionTypeProto)+
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NumFunctionNP*sizeof(FunctionTypeNoProto)+
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)));
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ASTContext::InitBuiltinType(QualType &R, BuiltinType::Kind K) {
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back((R = QualType(new BuiltinType(K),0)).getTypePtr());
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ASTContext::InitBuiltinTypes() {
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(VoidTy.isNull() && "Context reinitialized?");
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p19.
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(VoidTy,              BuiltinType::Void);
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p2.
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(BoolTy,              BuiltinType::Bool);
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p3.
13698be4943e8dc4f3905629a7102668960873cf863Chris Lattner  if (Target.isCharSigned())
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InitBuiltinType(CharTy,            BuiltinType::Char_S);
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InitBuiltinType(CharTy,            BuiltinType::Char_U);
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p4.
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(SignedCharTy,        BuiltinType::SChar);
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(ShortTy,             BuiltinType::Short);
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(IntTy,               BuiltinType::Int);
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(LongTy,              BuiltinType::Long);
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(LongLongTy,          BuiltinType::LongLong);
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p6.
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(UnsignedCharTy,      BuiltinType::UChar);
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(UnsignedShortTy,     BuiltinType::UShort);
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(UnsignedIntTy,       BuiltinType::UInt);
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(UnsignedLongTy,      BuiltinType::ULong);
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(UnsignedLongLongTy,  BuiltinType::ULongLong);
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p10.
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(FloatTy,             BuiltinType::Float);
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(DoubleTy,            BuiltinType::Double);
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InitBuiltinType(LongDoubleTy,        BuiltinType::LongDouble);
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.2.5p11.
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FloatComplexTy      = getComplexType(FloatTy);
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DoubleComplexTy     = getComplexType(DoubleTy);
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  LongDoubleComplexTy = getComplexType(LongDoubleTy);
1637e219e47de26346885d667131977bd9ca2d7662aSteve Naroff
1647e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  BuiltinVaListType = QualType();
165a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIdType = QualType();
1667e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  IdStructType = 0;
167a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCClassType = QualType();
1688baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  ClassStructType = 0;
1698baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson
170a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCConstantStringType = QualType();
17133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
17233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // void * type
17333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  VoidPtrTy = getPointerType(VoidTy);
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
176464175bba1318bef7905122e9fda20cff926df78Chris Lattner//===----------------------------------------------------------------------===//
177464175bba1318bef7905122e9fda20cff926df78Chris Lattner//                         Type Sizing and Analysis
178464175bba1318bef7905122e9fda20cff926df78Chris Lattner//===----------------------------------------------------------------------===//
179a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner
180a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner/// getTypeSize - Return the size of the specified type, in bits.  This method
181a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner/// does not work on incomplete types.
182d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattnerstd::pair<uint64_t, unsigned>
18398be4943e8dc4f3905629a7102668960873cf863Chris LattnerASTContext::getTypeInfo(QualType T) {
184a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner  T = T.getCanonicalType();
1859e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner  uint64_t Width;
186d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner  unsigned Align;
187a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner  switch (T->getTypeClass()) {
188030d8846c7e520330007087e949f621989876e3aChris Lattner  case Type::TypeName: assert(0 && "Not a canonical type!");
1895d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  case Type::FunctionNoProto:
1905d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  case Type::FunctionProto:
191692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner  default:
192b1c2df99ba67ec6c29ac7dceaa4eb2c8cda4a017Chris Lattner    assert(0 && "Incomplete types have no size!");
193fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  case Type::VariableArray:
194fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    assert(0 && "VLAs not implemented yet!");
195fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  case Type::ConstantArray: {
196fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    ConstantArrayType *CAT = cast<ConstantArrayType>(T);
197030d8846c7e520330007087e949f621989876e3aChris Lattner
19898be4943e8dc4f3905629a7102668960873cf863Chris Lattner    std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
1999e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner    Width = EltInfo.first*CAT->getSize().getZExtValue();
200030d8846c7e520330007087e949f621989876e3aChris Lattner    Align = EltInfo.second;
201030d8846c7e520330007087e949f621989876e3aChris Lattner    break;
2025c09a02a5db85e08a432b6eeced9aa656349710dChristopher Lamb  }
2035c09a02a5db85e08a432b6eeced9aa656349710dChristopher Lamb  case Type::OCUVector:
204030d8846c7e520330007087e949f621989876e3aChris Lattner  case Type::Vector: {
205030d8846c7e520330007087e949f621989876e3aChris Lattner    std::pair<uint64_t, unsigned> EltInfo =
20698be4943e8dc4f3905629a7102668960873cf863Chris Lattner      getTypeInfo(cast<VectorType>(T)->getElementType());
2079e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner    Width = EltInfo.first*cast<VectorType>(T)->getNumElements();
208030d8846c7e520330007087e949f621989876e3aChris Lattner    // FIXME: Vector alignment is not the alignment of its elements.
209030d8846c7e520330007087e949f621989876e3aChris Lattner    Align = EltInfo.second;
210030d8846c7e520330007087e949f621989876e3aChris Lattner    break;
211030d8846c7e520330007087e949f621989876e3aChris Lattner  }
2125d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner
2139e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner  case Type::Builtin:
214a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner    // FIXME: need to use TargetInfo to derive the target specific sizes. This
215a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner    // implementation will suffice for play with vector support.
216a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner    switch (cast<BuiltinType>(T)->getKind()) {
217692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    default: assert(0 && "Unknown builtin type!");
218d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner    case BuiltinType::Void:
219d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner      assert(0 && "Incomplete types have no size!");
2206f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::Bool:
2219e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getBoolWidth();
2229e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getBoolAlign();
2236f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
224692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::Char_S:
225692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::Char_U:
226692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::UChar:
2276f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::SChar:
2289e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getCharWidth();
2299e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getCharAlign();
2306f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
231692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::UShort:
2326f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::Short:
2339e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getShortWidth();
2349e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getShortAlign();
2356f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
236692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::UInt:
2376f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::Int:
2389e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getIntWidth();
2399e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getIntAlign();
2406f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
241692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::ULong:
2426f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::Long:
2439e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getLongWidth();
2449e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getLongAlign();
2456f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
246692233e90a99c3a81dd04879d36eb9688f137c44Chris Lattner    case BuiltinType::ULongLong:
2476f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::LongLong:
2489e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getLongLongWidth();
2499e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getLongLongAlign();
2506f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
2516f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::Float:
2529e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getFloatWidth();
2539e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getFloatAlign();
2546f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
2556f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::Double:
2569e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner        Width = Target.getDoubleWidth();
2579e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner        Align = Target.getDoubleAlign();
2586f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
2596f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    case BuiltinType::LongDouble:
2609e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Width = Target.getLongDoubleWidth();
2619e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner      Align = Target.getLongDoubleAlign();
2626f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner      break;
263a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner    }
264bfef6d7c67831a135d6ab79931f010f750a730adChris Lattner    break;
265ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  case Type::ASQual:
26698be4943e8dc4f3905629a7102668960873cf863Chris Lattner    // FIXME: Pointers into different addr spaces could have different sizes and
26798be4943e8dc4f3905629a7102668960873cf863Chris Lattner    // alignment requirements: getPointerInfo should take an AddrSpace.
26898be4943e8dc4f3905629a7102668960873cf863Chris Lattner    return getTypeInfo(QualType(cast<ASQualType>(T)->getBaseType(), 0));
269a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  case Type::ObjCQualifiedId:
2709e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner    Width  = Target.getPointerWidth(0);
271f72a44330b9d9a4b2d93e9b91cfb8ab7bd4a0643Chris Lattner    Align = Target.getPointerAlign(0);
2726f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    break;
273f72a44330b9d9a4b2d93e9b91cfb8ab7bd4a0643Chris Lattner  case Type::Pointer: {
274f72a44330b9d9a4b2d93e9b91cfb8ab7bd4a0643Chris Lattner    unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
2759e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner    Width  = Target.getPointerWidth(AS);
276f72a44330b9d9a4b2d93e9b91cfb8ab7bd4a0643Chris Lattner    Align = Target.getPointerAlign(AS);
277f72a44330b9d9a4b2d93e9b91cfb8ab7bd4a0643Chris Lattner    break;
278f72a44330b9d9a4b2d93e9b91cfb8ab7bd4a0643Chris Lattner  }
279a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner  case Type::Reference:
2807ab2ed8e881ffdc84e890f5265c41b930df17ceeChris Lattner    // "When applied to a reference or a reference type, the result is the size
2815d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    // of the referenced type." C++98 5.3.3p2: expr.sizeof.
2826f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    // FIXME: This is wrong for struct layout: a reference in a struct has
2836f62c2abd8077bf70d2166d37e8caa426b34d8e4Chris Lattner    // pointer size.
284bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner    return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
2855d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner
2865d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  case Type::Complex: {
2875d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    // Complex types have the same alignment as their elements, but twice the
2885d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    // size.
2895d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    std::pair<uint64_t, unsigned> EltInfo =
29098be4943e8dc4f3905629a7102668960873cf863Chris Lattner      getTypeInfo(cast<ComplexType>(T)->getElementType());
2919e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner    Width = EltInfo.first*2;
2925d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    Align = EltInfo.second;
2935d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner    break;
2945d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  }
2957176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner  case Type::Tagged: {
2967176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    if (EnumType *ET = dyn_cast<EnumType>(cast<TagType>(T)))
2977176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner      return getTypeInfo(ET->getDecl()->getIntegerType());
2987176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner
2997176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    RecordType *RT = cast<RecordType>(T);
3007176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl());
3017176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    Width = Layout.getSize();
3027176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    Align = Layout.getAlignment();
303dc0d73e6495404418acf8548875aeaff07791a74Chris Lattner    break;
304a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner  }
3057176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner  }
306d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner
307464175bba1318bef7905122e9fda20cff926df78Chris Lattner  assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
3089e9b6dc3fd413f5341fab54b681420eeb21cd169Chris Lattner  return std::make_pair(Width, Align);
309a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner}
310a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner
31188a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel/// getASTRecordLayout - Get or compute information about the layout of the
312464175bba1318bef7905122e9fda20cff926df78Chris Lattner/// specified record (struct/union/class), which indicates its size and field
313464175bba1318bef7905122e9fda20cff926df78Chris Lattner/// position information.
31498be4943e8dc4f3905629a7102668960873cf863Chris Lattnerconst ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
315464175bba1318bef7905122e9fda20cff926df78Chris Lattner  assert(D->isDefinition() && "Cannot get layout of forward declarations!");
316464175bba1318bef7905122e9fda20cff926df78Chris Lattner
317464175bba1318bef7905122e9fda20cff926df78Chris Lattner  // Look up this layout, if already laid out, return what we have.
31888a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel  const ASTRecordLayout *&Entry = ASTRecordLayouts[D];
319464175bba1318bef7905122e9fda20cff926df78Chris Lattner  if (Entry) return *Entry;
320464175bba1318bef7905122e9fda20cff926df78Chris Lattner
32188a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel  // Allocate and assign into ASTRecordLayouts here.  The "Entry" reference can
32288a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel  // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
32388a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel  ASTRecordLayout *NewEntry = new ASTRecordLayout();
324464175bba1318bef7905122e9fda20cff926df78Chris Lattner  Entry = NewEntry;
325464175bba1318bef7905122e9fda20cff926df78Chris Lattner
326464175bba1318bef7905122e9fda20cff926df78Chris Lattner  uint64_t *FieldOffsets = new uint64_t[D->getNumMembers()];
327464175bba1318bef7905122e9fda20cff926df78Chris Lattner  uint64_t RecordSize = 0;
328464175bba1318bef7905122e9fda20cff926df78Chris Lattner  unsigned RecordAlign = 8;  // Default alignment = 1 byte = 8 bits.
329464175bba1318bef7905122e9fda20cff926df78Chris Lattner
330464175bba1318bef7905122e9fda20cff926df78Chris Lattner  if (D->getKind() != Decl::Union) {
331042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson    if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
332042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson      RecordAlign = std::max(RecordAlign, AA->getAlignment());
333042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson
3346a24acbb3dbb3bea9426716bee6ad6023ad15f3fAnders Carlsson    bool StructIsPacked = D->getAttr<PackedAttr>();
3356a24acbb3dbb3bea9426716bee6ad6023ad15f3fAnders Carlsson
336464175bba1318bef7905122e9fda20cff926df78Chris Lattner    // Layout each field, for now, just sequentially, respecting alignment.  In
337464175bba1318bef7905122e9fda20cff926df78Chris Lattner    // the future, this will need to be tweakable by targets.
338464175bba1318bef7905122e9fda20cff926df78Chris Lattner    for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
339464175bba1318bef7905122e9fda20cff926df78Chris Lattner      const FieldDecl *FD = D->getMember(i);
3406a24acbb3dbb3bea9426716bee6ad6023ad15f3fAnders Carlsson      bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
34175afb585496b8c521672a6a91b8dd1838d36185aEli Friedman      uint64_t FieldSize;
34275afb585496b8c521672a6a91b8dd1838d36185aEli Friedman      unsigned FieldAlign;
3438af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson
3448af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson      if (const Expr *BitWidthExpr = FD->getBitWidth()) {
3458af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        llvm::APSInt I(32);
3468af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        bool BitWidthIsICE =
3478af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          BitWidthExpr->isIntegerConstantExpr(I, *this);
3488af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        assert (BitWidthIsICE  && "Invalid BitField size expression");
3498af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        FieldSize = I.getZExtValue();
3508af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson
35198be4943e8dc4f3905629a7102668960873cf863Chris Lattner        std::pair<uint64_t, unsigned> TypeInfo = getTypeInfo(FD->getType());
3528af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        uint64_t TypeSize = TypeInfo.first;
353042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson
354042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson        if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
355042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson          FieldAlign = AA->getAlignment();
356042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson        else if (FieldIsPacked)
357042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson          FieldAlign = 8;
358042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson        else {
3598af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          // FIXME: This is X86 specific, use 32-bit alignment for long long.
3608af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          if (FD->getType()->isIntegerType() && TypeInfo.second > 32)
3618af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = 32;
3628af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          else
3638af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = TypeInfo.second;
364042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson        }
3658af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson
3668af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        // Check if we need to add padding to give the field the correct
3678af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        // alignment.
3688af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        if (RecordSize % FieldAlign + FieldSize > TypeSize)
3698af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
3708af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson
37175afb585496b8c521672a6a91b8dd1838d36185aEli Friedman      } else {
3728af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        if (FD->getType()->isIncompleteType()) {
3738af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          // This must be a flexible array member; we can't directly
3748af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          // query getTypeInfo about these, so we figure it out here.
3758af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          // Flexible array members don't have any size, but they
3768af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          // have to be aligned appropriately for their element type.
377042c4e7e9f0b54104f4f2e098c028aa8247b6bedAnders Carlsson
3788af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
3798af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = AA->getAlignment();
3808af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          else if (FieldIsPacked)
3818af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = 8;
3828af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          else {
3838af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            const ArrayType* ATy = FD->getType()->getAsArrayType();
38498be4943e8dc4f3905629a7102668960873cf863Chris Lattner            FieldAlign = getTypeAlign(ATy->getElementType());
3858af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          }
3868af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          FieldSize = 0;
3878af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        } else {
38898be4943e8dc4f3905629a7102668960873cf863Chris Lattner          std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
3898af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          FieldSize = FieldInfo.first;
3908af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson
3918af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
3928af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = AA->getAlignment();
3938af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          else if (FieldIsPacked)
3948af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = 8;
3958af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson          else
3968af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson            FieldAlign = FieldInfo.second;
3978af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        }
39875afb585496b8c521672a6a91b8dd1838d36185aEli Friedman
3998af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        // Round up the current record size to the field's alignment boundary.
4008af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
4018af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson      }
402464175bba1318bef7905122e9fda20cff926df78Chris Lattner
403464175bba1318bef7905122e9fda20cff926df78Chris Lattner      // Place this field at the current location.
404464175bba1318bef7905122e9fda20cff926df78Chris Lattner      FieldOffsets[i] = RecordSize;
405464175bba1318bef7905122e9fda20cff926df78Chris Lattner
406464175bba1318bef7905122e9fda20cff926df78Chris Lattner      // Reserve space for this field.
407464175bba1318bef7905122e9fda20cff926df78Chris Lattner      RecordSize += FieldSize;
408464175bba1318bef7905122e9fda20cff926df78Chris Lattner
409464175bba1318bef7905122e9fda20cff926df78Chris Lattner      // Remember max struct/class alignment.
410464175bba1318bef7905122e9fda20cff926df78Chris Lattner      RecordAlign = std::max(RecordAlign, FieldAlign);
411464175bba1318bef7905122e9fda20cff926df78Chris Lattner    }
412464175bba1318bef7905122e9fda20cff926df78Chris Lattner
413464175bba1318bef7905122e9fda20cff926df78Chris Lattner    // Finally, round the size of the total struct up to the alignment of the
414464175bba1318bef7905122e9fda20cff926df78Chris Lattner    // struct itself.
415464175bba1318bef7905122e9fda20cff926df78Chris Lattner    RecordSize = (RecordSize+RecordAlign-1) & ~(RecordAlign-1);
416464175bba1318bef7905122e9fda20cff926df78Chris Lattner  } else {
417464175bba1318bef7905122e9fda20cff926df78Chris Lattner    // Union layout just puts each member at the start of the record.
418464175bba1318bef7905122e9fda20cff926df78Chris Lattner    for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
419464175bba1318bef7905122e9fda20cff926df78Chris Lattner      const FieldDecl *FD = D->getMember(i);
42098be4943e8dc4f3905629a7102668960873cf863Chris Lattner      std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
421464175bba1318bef7905122e9fda20cff926df78Chris Lattner      uint64_t FieldSize = FieldInfo.first;
422464175bba1318bef7905122e9fda20cff926df78Chris Lattner      unsigned FieldAlign = FieldInfo.second;
423464175bba1318bef7905122e9fda20cff926df78Chris Lattner
4248af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson      // FIXME: This is X86 specific, use 32-bit alignment for long long.
4258af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson      if (FD->getType()->isIntegerType() && FieldAlign > 32)
4268af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson        FieldAlign = 32;
4278af226a62dd9bb4a33bb86a8265532bbd75d76fcAnders Carlsson
428464175bba1318bef7905122e9fda20cff926df78Chris Lattner      // Round up the current record size to the field's alignment boundary.
429464175bba1318bef7905122e9fda20cff926df78Chris Lattner      RecordSize = std::max(RecordSize, FieldSize);
430464175bba1318bef7905122e9fda20cff926df78Chris Lattner
431464175bba1318bef7905122e9fda20cff926df78Chris Lattner      // Place this field at the start of the record.
432464175bba1318bef7905122e9fda20cff926df78Chris Lattner      FieldOffsets[i] = 0;
433464175bba1318bef7905122e9fda20cff926df78Chris Lattner
434464175bba1318bef7905122e9fda20cff926df78Chris Lattner      // Remember max struct/class alignment.
435464175bba1318bef7905122e9fda20cff926df78Chris Lattner      RecordAlign = std::max(RecordAlign, FieldAlign);
436464175bba1318bef7905122e9fda20cff926df78Chris Lattner    }
437464175bba1318bef7905122e9fda20cff926df78Chris Lattner  }
4385d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner
4395d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets);
4405d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  return *NewEntry;
441464175bba1318bef7905122e9fda20cff926df78Chris Lattner}
442464175bba1318bef7905122e9fda20cff926df78Chris Lattner
443a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner//===----------------------------------------------------------------------===//
444a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner//                   Type creation/memoization methods
445a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner//===----------------------------------------------------------------------===//
446a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner
447ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher LambQualType ASTContext::getASQualType(QualType T, unsigned AddressSpace) {
448f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  if (T.getCanonicalType().getAddressSpace() == AddressSpace)
449f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    return T;
450f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner
451f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  // Type's cannot have multiple ASQuals, therefore we know we only have to deal
452f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  // with CVR qualifiers from here on out.
453f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  assert(T.getCanonicalType().getAddressSpace() == 0 &&
454f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner         "Type is already address space qualified");
455f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner
456f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  // Check if we've already instantiated an address space qual'd type of this
457f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  // type.
458ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  llvm::FoldingSetNodeID ID;
459f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  ASQualType::Profile(ID, T.getTypePtr(), AddressSpace);
460ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  void *InsertPos = 0;
461ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (ASQualType *ASQy = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos))
462ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    return QualType(ASQy, 0);
463ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
464ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // If the base type isn't canonical, this won't be a canonical type either,
465ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // so fill in the canonical type field.
466ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  QualType Canonical;
467ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!T->isCanonical()) {
468ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    Canonical = getASQualType(T.getCanonicalType(), AddressSpace);
469ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
470ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Get the new insert position for the node we care about.
471ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    ASQualType *NewIP = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos);
472ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    assert(NewIP == 0 && "Shouldn't be in the map!");
473ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
474f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  ASQualType *New = new ASQualType(T.getTypePtr(), Canonical, AddressSpace);
475ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  ASQualTypes.InsertNode(New, InsertPos);
476ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  Types.push_back(New);
477f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  return QualType(New, T.getCVRQualifiers());
478ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb}
479ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
480a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner
4815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getComplexType - Return the uniqued reference to the type for a complex
4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// number with the specified element type.
4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getComplexType(QualType T) {
4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unique pointers, to guarantee there is only one pointer of a particular
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // structure.
4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ComplexType::Profile(ID, T);
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
4905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
4915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(CT, 0);
4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the pointee type isn't canonical, this won't be a canonical type either,
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // so fill in the canonical type field.
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
4965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!T->isCanonical()) {
4975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Canonical = getComplexType(T.getCanonicalType());
4985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
5005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
5015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ComplexType *New = new ComplexType(T, Canonical);
5045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(New);
5055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ComplexTypes.InsertNode(New, InsertPos);
5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(New, 0);
5075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getPointerType - Return the uniqued reference to the type for a pointer to
5115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the specified type.
5125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getPointerType(QualType T) {
5135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unique pointers, to guarantee there is only one pointer of a particular
5145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // structure.
5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PointerType::Profile(ID, T);
5175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
5195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(PT, 0);
5215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the pointee type isn't canonical, this won't be a canonical type either,
5235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // so fill in the canonical type field.
5245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
5255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!T->isCanonical()) {
5265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Canonical = getPointerType(T.getCanonicalType());
5275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
5295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
5305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
5315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PointerType *New = new PointerType(T, Canonical);
5335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(New);
5345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PointerTypes.InsertNode(New, InsertPos);
5355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(New, 0);
5365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getReferenceType - Return the uniqued reference to the type for a reference
5395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// to the specified type.
5405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getReferenceType(QualType T) {
5415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unique pointers, to guarantee there is only one pointer of a particular
5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // structure.
5435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ReferenceType::Profile(ID, T);
5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
5475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (ReferenceType *RT = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
5485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(RT, 0);
5495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the referencee type isn't canonical, this won't be a canonical type
5515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // either, so fill in the canonical type field.
5525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
5535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!T->isCanonical()) {
5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Canonical = getReferenceType(T.getCanonicalType());
5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
5575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ReferenceType *NewIP = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
5585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
5595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ReferenceType *New = new ReferenceType(T, Canonical);
5625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(New);
5635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ReferenceTypes.InsertNode(New, InsertPos);
5645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(New, 0);
5655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
567fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff/// getConstantArrayType - Return the unique reference to the type for an
568fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff/// array of the specified element type.
569fb22d96692c5240fb8d611290dbf7eeed3759c73Steve NaroffQualType ASTContext::getConstantArrayType(QualType EltTy,
570c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                          const llvm::APInt &ArySize,
571c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                          ArrayType::ArraySizeModifier ASM,
572c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                          unsigned EltTypeQuals) {
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
574fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  ConstantArrayType::Profile(ID, EltTy, ArySize);
5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
5777192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek  if (ConstantArrayType *ATP =
5787192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek      ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
5795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(ATP, 0);
5805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the element type isn't canonical, this won't be a canonical type either,
5825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // so fill in the canonical type field.
5835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!EltTy->isCanonical()) {
585c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff    Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize,
586c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                     ASM, EltTypeQuals);
5875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
5887192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek    ConstantArrayType *NewIP =
5897192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek      ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
5907192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek
5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
594c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize,
595c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                                 ASM, EltTypeQuals);
5967192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek  ConstantArrayTypes.InsertNode(New, InsertPos);
5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(New);
5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(New, 0);
5995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
601bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff/// getVariableArrayType - Returns a non-unique reference to the type for a
602bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff/// variable array of the specified element type.
603c9406125e2cac9208098655ac8058c095c2c3a65Steve NaroffQualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
604c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                          ArrayType::ArraySizeModifier ASM,
605c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff                                          unsigned EltTypeQuals) {
606c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  // Since we don't unique expressions, it isn't possible to unique VLA's
607c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  // that have an expression provided for their size.
608c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
609c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
610c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman                                                 ASM, EltTypeQuals);
611c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
612c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  VariableArrayTypes.push_back(New);
613c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  Types.push_back(New);
614c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  return QualType(New, 0);
615c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman}
616c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
617c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli FriedmanQualType ASTContext::getIncompleteArrayType(QualType EltTy,
618c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman                                            ArrayType::ArraySizeModifier ASM,
619c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman                                            unsigned EltTypeQuals) {
620c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  llvm::FoldingSetNodeID ID;
621c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  IncompleteArrayType::Profile(ID, EltTy);
622c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
623c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  void *InsertPos = 0;
624c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  if (IncompleteArrayType *ATP =
625c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman       IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
626c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    return QualType(ATP, 0);
627c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
628c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  // If the element type isn't canonical, this won't be a canonical type
629c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  // either, so fill in the canonical type field.
630c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  QualType Canonical;
631c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
632c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  if (!EltTy->isCanonical()) {
633c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    Canonical = getIncompleteArrayType(EltTy.getCanonicalType(),
6342bd24ba6d10f8c811c8e2a57c8397e07082ba497Ted Kremenek                                       ASM, EltTypeQuals);
635c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
636c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    // Get the new insert position for the node we care about.
637c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    IncompleteArrayType *NewIP =
638c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman      IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
639c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
640c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    assert(NewIP == 0 && "Shouldn't be in the map!");
6412bd24ba6d10f8c811c8e2a57c8397e07082ba497Ted Kremenek  }
642c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
643c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  IncompleteArrayType *New = new IncompleteArrayType(EltTy, Canonical,
644c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman                                                     ASM, EltTypeQuals);
645c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
646c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  IncompleteArrayTypes.InsertNode(New, InsertPos);
647c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  Types.push_back(New);
648c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  return QualType(New, 0);
649fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff}
650fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
65173322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// getVectorType - Return the unique reference to a vector type of
65273322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// the specified element type and size. VectorType must be a built-in type.
65373322924127c873c13101b705dd823f5539ffa5fSteve NaroffQualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  BuiltinType *baseType;
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
65773322924127c873c13101b705dd823f5539ffa5fSteve Naroff  assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Check if we've already instantiated a vector of this type.
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
66173322924127c873c13101b705dd823f5539ffa5fSteve Naroff  VectorType::Profile(ID, vecType, NumElts, Type::Vector);
6625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
6635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
6645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(VTP, 0);
6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the element type isn't canonical, this won't be a canonical type either,
6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // so fill in the canonical type field.
6685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!vecType->isCanonical()) {
67073322924127c873c13101b705dd823f5539ffa5fSteve Naroff    Canonical = getVectorType(vecType.getCanonicalType(), NumElts);
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  VectorType *New = new VectorType(vecType, NumElts, Canonical);
6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  VectorTypes.InsertNode(New, InsertPos);
6785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(New);
6795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(New, 0);
6805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
68273322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// getOCUVectorType - Return the unique reference to an OCU vector type of
68373322924127c873c13101b705dd823f5539ffa5fSteve Naroff/// the specified element type and size. VectorType must be a built-in type.
68473322924127c873c13101b705dd823f5539ffa5fSteve NaroffQualType ASTContext::getOCUVectorType(QualType vecType, unsigned NumElts) {
68573322924127c873c13101b705dd823f5539ffa5fSteve Naroff  BuiltinType *baseType;
68673322924127c873c13101b705dd823f5539ffa5fSteve Naroff
68773322924127c873c13101b705dd823f5539ffa5fSteve Naroff  baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
68873322924127c873c13101b705dd823f5539ffa5fSteve Naroff  assert(baseType != 0 && "getOCUVectorType(): Expecting a built-in type");
68973322924127c873c13101b705dd823f5539ffa5fSteve Naroff
69073322924127c873c13101b705dd823f5539ffa5fSteve Naroff  // Check if we've already instantiated a vector of this type.
69173322924127c873c13101b705dd823f5539ffa5fSteve Naroff  llvm::FoldingSetNodeID ID;
69273322924127c873c13101b705dd823f5539ffa5fSteve Naroff  VectorType::Profile(ID, vecType, NumElts, Type::OCUVector);
69373322924127c873c13101b705dd823f5539ffa5fSteve Naroff  void *InsertPos = 0;
69473322924127c873c13101b705dd823f5539ffa5fSteve Naroff  if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
69573322924127c873c13101b705dd823f5539ffa5fSteve Naroff    return QualType(VTP, 0);
69673322924127c873c13101b705dd823f5539ffa5fSteve Naroff
69773322924127c873c13101b705dd823f5539ffa5fSteve Naroff  // If the element type isn't canonical, this won't be a canonical type either,
69873322924127c873c13101b705dd823f5539ffa5fSteve Naroff  // so fill in the canonical type field.
69973322924127c873c13101b705dd823f5539ffa5fSteve Naroff  QualType Canonical;
70073322924127c873c13101b705dd823f5539ffa5fSteve Naroff  if (!vecType->isCanonical()) {
70173322924127c873c13101b705dd823f5539ffa5fSteve Naroff    Canonical = getOCUVectorType(vecType.getCanonicalType(), NumElts);
70273322924127c873c13101b705dd823f5539ffa5fSteve Naroff
70373322924127c873c13101b705dd823f5539ffa5fSteve Naroff    // Get the new insert position for the node we care about.
70473322924127c873c13101b705dd823f5539ffa5fSteve Naroff    VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
70573322924127c873c13101b705dd823f5539ffa5fSteve Naroff    assert(NewIP == 0 && "Shouldn't be in the map!");
70673322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
70773322924127c873c13101b705dd823f5539ffa5fSteve Naroff  OCUVectorType *New = new OCUVectorType(vecType, NumElts, Canonical);
70873322924127c873c13101b705dd823f5539ffa5fSteve Naroff  VectorTypes.InsertNode(New, InsertPos);
70973322924127c873c13101b705dd823f5539ffa5fSteve Naroff  Types.push_back(New);
71073322924127c873c13101b705dd823f5539ffa5fSteve Naroff  return QualType(New, 0);
71173322924127c873c13101b705dd823f5539ffa5fSteve Naroff}
71273322924127c873c13101b705dd823f5539ffa5fSteve Naroff
7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
7155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {
7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unique functions, to guarantee there is only one function of a particular
7175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // structure.
7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
7195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeNoProto::Profile(ID, ResultTy);
7205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (FunctionTypeNoProto *FT =
7235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos))
7245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(FT, 0);
7255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!ResultTy->isCanonical()) {
7285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Canonical = getFunctionTypeNoProto(ResultTy.getCanonicalType());
7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FunctionTypeNoProto *NewIP =
7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos);
7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeNoProto *New = new FunctionTypeNoProto(ResultTy, Canonical);
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(New);
73856cd7e3848c2d59ca2ec3b72d0834192edf0bcdfEli Friedman  FunctionTypeNoProtos.InsertNode(New, InsertPos);
7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(New, 0);
7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getFunctionType - Return a normal function type with a typed argument
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// list.  isVariadic indicates whether the argument list includes '...'.
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getFunctionType(QualType ResultTy, QualType *ArgArray,
7455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                     unsigned NumArgs, bool isVariadic) {
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Unique functions, to guarantee there is only one function of a particular
7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // structure.
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::FoldingSetNodeID ID;
7495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void *InsertPos = 0;
7525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (FunctionTypeProto *FTP =
7535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
7545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return QualType(FTP, 0);
7555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Determine whether the type being created is already canonical or not.
7575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCanonical = ResultTy->isCanonical();
7585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
7595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (!ArgArray[i]->isCanonical())
7605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      isCanonical = false;
7615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this type isn't canonical, get the canonical version of it.
7635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical;
7645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!isCanonical) {
7655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    llvm::SmallVector<QualType, 16> CanonicalArgs;
7665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CanonicalArgs.reserve(NumArgs);
7675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    for (unsigned i = 0; i != NumArgs; ++i)
7685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      CanonicalArgs.push_back(ArgArray[i].getCanonicalType());
7695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Canonical = getFunctionType(ResultTy.getCanonicalType(),
7715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                &CanonicalArgs[0], NumArgs,
7725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                isVariadic);
7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Get the new insert position for the node we care about.
7755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FunctionTypeProto *NewIP =
7765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
7775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(NewIP == 0 && "Shouldn't be in the map!");
7785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FunctionTypeProto objects are not allocated with new because they have a
7815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // variable size array (for parameter types) at the end of them.
7825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeProto *FTP =
7835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
784942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner                               NumArgs*sizeof(QualType));
7855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
7865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              Canonical);
7875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(FTP);
7885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FunctionTypeProtos.InsertNode(FTP, InsertPos);
7895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(FTP, 0);
7905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getTypedefType - Return the unique reference to the type for the
7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// specified typename decl.
7945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getTypedefType(TypedefDecl *Decl) {
7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
7965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
798c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  Decl->TypeForDecl = new TypedefType(Type::TypeName, Decl, Canonical);
7995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Types.push_back(Decl->TypeForDecl);
8005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return QualType(Decl->TypeForDecl, 0);
8015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
803a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// getObjCInterfaceType - Return the unique reference to the type for the
8043536b443bc50d58a79f14fca9b6842541a434854Steve Naroff/// specified ObjC interface decl.
805a526c5c67e5a0473c340903ee542ce570119665fTed KremenekQualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
8063536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
8073536b443bc50d58a79f14fca9b6842541a434854Steve Naroff
808a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  Decl->TypeForDecl = new ObjCInterfaceType(Type::ObjCInterface, Decl);
8093536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  Types.push_back(Decl->TypeForDecl);
8103536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  return QualType(Decl->TypeForDecl, 0);
8113536b443bc50d58a79f14fca9b6842541a434854Steve Naroff}
8123536b443bc50d58a79f14fca9b6842541a434854Steve Naroff
813a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// getObjCQualifiedInterfaceType - Return a
814a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCQualifiedInterfaceType type for the given interface decl and
8154b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian/// the conforming protocol list.
816a526c5c67e5a0473c340903ee542ce570119665fTed KremenekQualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
817a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                       ObjCProtocolDecl **Protocols, unsigned NumProtocols) {
8184b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  llvm::FoldingSetNodeID ID;
819a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceType::Profile(ID, Protocols, NumProtocols);
8204b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
8214b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  void *InsertPos = 0;
822a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (ObjCQualifiedInterfaceType *QT =
823a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCQualifiedInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
8244b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian    return QualType(QT, 0);
8254b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
8264b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  // No Match;
827a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceType *QType =
828a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    new ObjCQualifiedInterfaceType(Decl, Protocols, NumProtocols);
8294b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  Types.push_back(QType);
830a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceTypes.InsertNode(QType, InsertPos);
8314b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  return QualType(QType, 0);
8324b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian}
8334b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
834a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// getObjCQualifiedIdType - Return a
835a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// getObjCQualifiedIdType type for the 'id' decl and
836c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian/// the conforming protocol list.
837a526c5c67e5a0473c340903ee542ce570119665fTed KremenekQualType ASTContext::getObjCQualifiedIdType(QualType idType,
838a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                                            ObjCProtocolDecl **Protocols,
839c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian                                            unsigned NumProtocols) {
840c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  llvm::FoldingSetNodeID ID;
841a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols);
842c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
843c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  void *InsertPos = 0;
844a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (ObjCQualifiedIdType *QT =
845a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
846c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian    return QualType(QT, 0);
847c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
848c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  // No Match;
849d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian  QualType Canonical;
850d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian  if (!idType->isCanonical()) {
851a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    Canonical = getObjCQualifiedIdType(idType.getCanonicalType(),
852d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian                                       Protocols, NumProtocols);
853a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCQualifiedIdType *NewQT =
854a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos);
855d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian    assert(NewQT == 0 && "Shouldn't be in the map!");
856d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian  }
857d58fabf7ed279be18a5e82617f809c9deff9be67Fariborz Jahanian
858a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedIdType *QType =
859a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    new ObjCQualifiedIdType(Canonical, Protocols, NumProtocols);
860c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  Types.push_back(QType);
861a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedIdTypes.InsertNode(QType, InsertPos);
862c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  return QualType(QType, 0);
863c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian}
864c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
8659752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
8669752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// TypeOfExpr AST's (since expression's are never shared). For example,
8679752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// multiple declarations that refer to "typeof(x)" all contain different
8689752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// DeclRefExpr's. This doesn't effect the type checker, since it operates
8699752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// on canonical type's (which are always unique).
8708d1a3b8ca1e5fcc4567b5a6f51d82be2e460de1cSteve NaroffQualType ASTContext::getTypeOfExpr(Expr *tofExpr) {
871d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  QualType Canonical = tofExpr->getType().getCanonicalType();
8729752f25748d954df99087d741ea35db37ff16beaSteve Naroff  TypeOfExpr *toe = new TypeOfExpr(tofExpr, Canonical);
8739752f25748d954df99087d741ea35db37ff16beaSteve Naroff  Types.push_back(toe);
8749752f25748d954df99087d741ea35db37ff16beaSteve Naroff  return QualType(toe, 0);
875d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff}
876d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
8779752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// getTypeOfType -  Unlike many "get<Type>" functions, we don't unique
8789752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// TypeOfType AST's. The only motivation to unique these nodes would be
8799752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
8809752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// an issue. This doesn't effect the type checker, since it operates
8819752f25748d954df99087d741ea35db37ff16beaSteve Naroff/// on canonical type's (which are always unique).
882d1861fd633d5096a00777c918eb8575ea7162fe7Steve NaroffQualType ASTContext::getTypeOfType(QualType tofType) {
883d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  QualType Canonical = tofType.getCanonicalType();
8849752f25748d954df99087d741ea35db37ff16beaSteve Naroff  TypeOfType *tot = new TypeOfType(tofType, Canonical);
8859752f25748d954df99087d741ea35db37ff16beaSteve Naroff  Types.push_back(tot);
8869752f25748d954df99087d741ea35db37ff16beaSteve Naroff  return QualType(tot, 0);
887d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff}
888d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
8895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getTagDeclType - Return the unique reference to the type for the
8905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// specified TagDecl (struct/union/class/enum) decl.
8915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getTagDeclType(TagDecl *Decl) {
892d778f88d32b96a74c9edb7342c81357606a7cdc0Ted Kremenek  assert (Decl);
893d778f88d32b96a74c9edb7342c81357606a7cdc0Ted Kremenek
8945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // The decl stores the type cache.
895d778f88d32b96a74c9edb7342c81357606a7cdc0Ted Kremenek  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
8965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
897ea0c6fb7c52df99349066ff1aed58e4dfc4c7289Ted Kremenek  TagType* T = new TagType(Decl, QualType());
898d778f88d32b96a74c9edb7342c81357606a7cdc0Ted Kremenek  Types.push_back(T);
899d778f88d32b96a74c9edb7342c81357606a7cdc0Ted Kremenek  Decl->TypeForDecl = T;
900ea0c6fb7c52df99349066ff1aed58e4dfc4c7289Ted Kremenek
901ea0c6fb7c52df99349066ff1aed58e4dfc4c7289Ted Kremenek  return QualType(T, 0);
9025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
9055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
9065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// needs to agree with the definition in <stddef.h>.
9075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::getSizeType() const {
9085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // On Darwin, size_t is defined as a "long unsigned int".
9095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: should derive from "Target".
9105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return UnsignedLongTy;
9115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
913fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman/// getWcharType - Return the unique type for "wchar_t" (C99 7.17), the
914fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman/// width of characters in wide strings, The value is target dependent and
915fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman/// needs to agree with the definition in <stddef.h>.
916fd888a581d6d329f5b447c8ff4d37cf396315993Eli FriedmanQualType ASTContext::getWcharType() const {
917fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman  // On Darwin, wchar_t is defined as a "int".
918fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman  // FIXME: should derive from "Target".
919fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman  return IntTy;
920fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman}
921fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman
9228b9023ba35a86838789e2c9034a6128728c547aaChris Lattner/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
9238b9023ba35a86838789e2c9034a6128728c547aaChris Lattner/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
9248b9023ba35a86838789e2c9034a6128728c547aaChris LattnerQualType ASTContext::getPointerDiffType() const {
9258b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  // On Darwin, ptrdiff_t is defined as a "int". This seems like a bug...
9268b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  // FIXME: should derive from "Target".
9278b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  return IntTy;
9288b9023ba35a86838789e2c9034a6128728c547aaChris Lattner}
9298b9023ba35a86838789e2c9034a6128728c547aaChris Lattner
930e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner//===----------------------------------------------------------------------===//
931e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner//                              Type Operators
932e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner//===----------------------------------------------------------------------===//
933e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
934e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner/// getArrayDecayedType - Return the properly qualified result of decaying the
935e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner/// specified array type to a pointer.  This operation is non-trivial when
936e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner/// handling typedefs etc.  The canonical type of "T" must be an array type,
937e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner/// this returns a pointer to a properly qualified element of the array.
938e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner///
939e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
940e6327747b72bb687c948270f702ff53c30f411a6Chris LattnerQualType ASTContext::getArrayDecayedType(QualType Ty) {
941e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  // Handle the common case where typedefs are not involved directly.
942e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  QualType EltTy;
943e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  unsigned ArrayQuals = 0;
944e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  unsigned PointerQuals = 0;
945e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
946e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // Since T "isa" an array type, it could not have had an address space
947e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // qualifier, just CVR qualifiers.  The properly qualified element pointer
948e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // gets the union of the CVR qualifiers from the element and the array, and
949e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // keeps any address space qualifier on the element type if present.
950e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    EltTy = AT->getElementType();
951e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    ArrayQuals = Ty.getCVRQualifiers();
952e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    PointerQuals = AT->getIndexTypeQualifier();
953e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  } else {
954e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // Otherwise, we have an ASQualType or a typedef, etc.  Make sure we don't
955e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // lose qualifiers when dealing with typedefs. Example:
956e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    //   typedef int arr[10];
957e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    //   void test2() {
958e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    //     const arr b;
959e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    //     b[4] = 1;
960e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    //   }
961e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    //
962e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // The decayed type of b is "const int*" even though the element type of the
963e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // array is "int".
964e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    QualType CanTy = Ty.getCanonicalType();
965e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    const ArrayType *PrettyArrayType = Ty->getAsArrayType();
966e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    assert(PrettyArrayType && "Not an array type!");
967e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
968e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // Get the element type with 'getAsArrayType' so that we don't lose any
969e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // typedefs in the element type of the array.
970e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    EltTy = PrettyArrayType->getElementType();
971e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
972e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // If the array was address-space qualifier, make sure to ASQual the element
973e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // type.  We can just grab the address space from the canonical type.
974e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    if (unsigned AS = CanTy.getAddressSpace())
975e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner      EltTy = getASQualType(EltTy, AS);
976e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
977e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // To properly handle [multiple levels of] typedefs, typeof's etc, we take
978e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // the CVR qualifiers directly from the canonical type, which is guaranteed
979e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    // to have the full set unioned together.
980e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    ArrayQuals = CanTy.getCVRQualifiers();
981e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner    PointerQuals = PrettyArrayType->getIndexTypeQualifier();
982e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  }
983e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
984d9654557562e77564309f6b83b493a9a424e008aChris Lattner  // Apply any CVR qualifiers from the array type to the element type.  This
985d9654557562e77564309f6b83b493a9a424e008aChris Lattner  // implements C99 6.7.3p8: "If the specification of an array type includes
986d9654557562e77564309f6b83b493a9a424e008aChris Lattner  // any type qualifiers, the element type is so qualified, not the array type."
987e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  EltTy = EltTy.getQualifiedType(ArrayQuals | EltTy.getCVRQualifiers());
988e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
989e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  QualType PtrTy = getPointerType(EltTy);
990e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
991e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  // int x[restrict 4] ->  int *restrict
992e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  PtrTy = PtrTy.getQualifiedType(PointerQuals);
993e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
994e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner  return PtrTy;
995e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner}
996e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner
9975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
9985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// routine will assert if passed a built-in type that isn't an integer or enum.
9995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic int getIntegerRank(QualType t) {
10007176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner  if (isa<EnumType>(t.getCanonicalType()))
10015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 4;
10025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1003ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  const BuiltinType *BT = t.getCanonicalType()->getAsBuiltinType();
10045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (BT->getKind()) {
10055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default:
10065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(0 && "getIntegerRank(): not a built-in integer");
10075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Bool:
10085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 1;
10095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Char_S:
10105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Char_U:
10115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::SChar:
10125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::UChar:
10135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 2;
10145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Short:
10155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::UShort:
10165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 3;
10175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Int:
10185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::UInt:
10195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 4;
10205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Long:
10215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::ULong:
10225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 5;
10235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::LongLong:
10245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::ULongLong:
10255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 6;
10265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getFloatingRank - Return a relative rank for floating point types.
10305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// This routine will assert if passed a built-in type that isn't a float.
10315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic int getFloatingRank(QualType T) {
10325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  T = T.getCanonicalType();
1033ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (const ComplexType *CT = T->getAsComplexType())
10345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return getFloatingRank(CT->getElementType());
10355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1036ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  switch (T->getAsBuiltinType()->getKind()) {
1037770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner  default:  assert(0 && "getFloatingRank(): not a floating type");
10385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Float:      return FloatRank;
10395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::Double:     return DoubleRank;
10405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case BuiltinType::LongDouble: return LongDoubleRank;
10415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
10425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1044716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff/// getFloatingTypeOfSizeWithinDomain - Returns a real floating
1045716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff/// point or a complex type (based on typeDomain/typeSize).
1046716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff/// 'typeDomain' is a real floating point or complex type.
1047716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff/// 'typeSize' is a real floating point or complex type.
1048f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve NaroffQualType ASTContext::getFloatingTypeOfSizeWithinDomain(
1049f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff  QualType typeSize, QualType typeDomain) const {
1050f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff  if (typeDomain->isComplexType()) {
1051f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    switch (getFloatingRank(typeSize)) {
1052716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff    default: assert(0 && "getFloatingRank(): illegal value for rank");
1053f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    case FloatRank:      return FloatComplexTy;
1054f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    case DoubleRank:     return DoubleComplexTy;
1055f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    case LongDoubleRank: return LongDoubleComplexTy;
1056f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    }
1057f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff  }
1058f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff  if (typeDomain->isRealFloatingType()) {
1059f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    switch (getFloatingRank(typeSize)) {
1060716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff    default: assert(0 && "getFloatingRank(): illegal value for rank");
1061f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    case FloatRank:      return FloatTy;
1062f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    case DoubleRank:     return DoubleTy;
1063f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    case LongDoubleRank: return LongDoubleTy;
1064f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff    }
10655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1066f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff  assert(0 && "getFloatingTypeOfSizeWithinDomain(): illegal domain");
1067b1776cb8d35dfa80bfd8606e58b8ade30dcd2438Chris Lattner  //an invalid return value, but the assert
1068b1776cb8d35dfa80bfd8606e58b8ade30dcd2438Chris Lattner  //will ensure that this code is never reached.
1069b1776cb8d35dfa80bfd8606e58b8ade30dcd2438Chris Lattner  return VoidTy;
10705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1072fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff/// compareFloatingType - Handles 3 different combos:
1073fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff/// float/float, float/complex, complex/complex.
1074fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff/// If lt > rt, return 1. If lt == rt, return 0. If lt < rt, return -1.
1075fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroffint ASTContext::compareFloatingType(QualType lt, QualType rt) {
1076fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff  if (getFloatingRank(lt) == getFloatingRank(rt))
1077fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff    return 0;
1078fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff  if (getFloatingRank(lt) > getFloatingRank(rt))
1079fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff    return 1;
1080fb0d49669aa370b4c0993c5cee60275ef9fd6518Steve Naroff  return -1;
10815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// maxIntegerType - Returns the highest ranked integer type. Handles 3 case:
10845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// unsigned/unsigned, signed/signed, signed/unsigned. C99 6.3.1.8p1.
10855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerQualType ASTContext::maxIntegerType(QualType lhs, QualType rhs) {
10865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (lhs == rhs) return lhs;
10875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool t1Unsigned = lhs->isUnsignedIntegerType();
10895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool t2Unsigned = rhs->isUnsignedIntegerType();
10905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if ((t1Unsigned && t2Unsigned) || (!t1Unsigned && !t2Unsigned))
10925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return getIntegerRank(lhs) >= getIntegerRank(rhs) ? lhs : rhs;
10935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // We have two integer types with differing signs
10955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType unsignedType = t1Unsigned ? lhs : rhs;
10965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  QualType signedType = t1Unsigned ? rhs : lhs;
10975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (getIntegerRank(unsignedType) >= getIntegerRank(signedType))
10995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return unsignedType;
11005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else {
11015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FIXME: Need to check if the signed type can represent all values of the
11025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // unsigned type. If it can, then the result is the signed type.
11035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If it can't, then the result is the unsigned version of the signed type.
11045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Should probably add a helper that returns a signed integer type from
11055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // an unsigned (and vice versa). C99 6.3.1.8.
11065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return signedType;
11075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
110971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson
111071993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson// getCFConstantStringType - Return the type used for constant CFStrings.
111171993dd85eed9cc42c6b2fa61ee5c53026b74817Anders CarlssonQualType ASTContext::getCFConstantStringType() {
111271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson  if (!CFConstantStringTypeDecl) {
11136c2b6eb8d836da19007f7540709e16d5e39a1cbaChris Lattner    CFConstantStringTypeDecl =
11140ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner      RecordDecl::Create(*this, Decl::Struct, NULL, SourceLocation(),
1115c63e660882ff93841fa234d70ef6757038302b92Chris Lattner                         &Idents.get("NSConstantString"), 0);
1116f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    QualType FieldTypes[4];
111771993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson
111871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    // const int *isa;
111971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));
1120f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    // int flags;
1121f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    FieldTypes[1] = IntTy;
112271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    // const char *str;
1123f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));
112471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    // long length;
1125f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    FieldTypes[3] = LongTy;
112671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    // Create fields
1127f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    FieldDecl *FieldDecls[4];
112871993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson
1129f06273f8bbacb086a46bde456429c8d08f6d07eeAnders Carlsson    for (unsigned i = 0; i < 4; ++i)
1130b048c9835969c4f7fe06264748be18ed4b442116Chris Lattner      FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0,
11318e25d8681822d8094bfeb97b2239363552548171Chris Lattner                                        FieldTypes[i]);
113271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson
113371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
113471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson  }
113571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson
113671993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson  return getTagDeclType(CFConstantStringTypeDecl);
11378467583c2704e7a9691ea56939a029015f0ade0aGabor Greif}
1138b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson
1139e8c49533521c40643653f943d47229e62d277f88Anders Carlsson// This returns true if a type has been typedefed to BOOL:
1140e8c49533521c40643653f943d47229e62d277f88Anders Carlsson// typedef <type> BOOL;
11412d99833e8c956775f2183601cd120b65b569c867Chris Lattnerstatic bool isTypeTypedefedAsBOOL(QualType T) {
1142e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  if (const TypedefType *TT = dyn_cast<TypedefType>(T))
11432d99833e8c956775f2183601cd120b65b569c867Chris Lattner    return !strcmp(TT->getDecl()->getName(), "BOOL");
114485f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
114585f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson  return false;
114685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson}
114785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
1148a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// getObjCEncodingTypeSize returns size of type for objective-c encoding
114933e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian/// purpose.
1150a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekint ASTContext::getObjCEncodingTypeSize(QualType type) {
115198be4943e8dc4f3905629a7102668960873cf863Chris Lattner  uint64_t sz = getTypeSize(type);
115233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
115333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // Make all integer and enum types at least as large as an int
115433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  if (sz > 0 && type->isIntegralType())
115598be4943e8dc4f3905629a7102668960873cf863Chris Lattner    sz = std::max(sz, getTypeSize(IntTy));
115633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // Treat arrays as pointers, since that's how they're passed in.
115733e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  else if (type->isArrayType())
115898be4943e8dc4f3905629a7102668960873cf863Chris Lattner    sz = getTypeSize(VoidPtrTy);
115998be4943e8dc4f3905629a7102668960873cf863Chris Lattner  return sz / getTypeSize(CharTy);
116033e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian}
116133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
1162a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// getObjCEncodingForMethodDecl - Return the encoded type for this method
116333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian/// declaration.
1164a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::getObjCEncodingForMethodDecl(ObjCMethodDecl *Decl,
116533e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian                                              std::string& S)
116633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian{
1167ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  // Encode type qualifer, 'in', 'inout', etc. for the return type.
1168a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S);
116933e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // Encode result type.
11707d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian  getObjCEncodingForType(Decl->getResultType(), S, EncodingRecordTypes);
117133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // Compute size of all parameters.
117233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // Start with computing size of a pointer in number of bytes.
117333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // FIXME: There might(should) be a better way of doing this computation!
117433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  SourceLocation Loc;
117598be4943e8dc4f3905629a7102668960873cf863Chris Lattner  int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy);
117633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // The first two arguments (self and _cmd) are pointers; account for
117733e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // their size.
117833e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  int ParmOffset = 2 * PtrSize;
117933e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  int NumOfParams = Decl->getNumParams();
118033e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  for (int i = 0; i < NumOfParams; i++) {
118133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    QualType PType = Decl->getParamDecl(i)->getType();
1182a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    int sz = getObjCEncodingTypeSize (PType);
1183a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    assert (sz > 0 && "getObjCEncodingForMethodDecl - Incomplete param type");
118433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    ParmOffset += sz;
118533e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  }
118633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  S += llvm::utostr(ParmOffset);
118733e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  S += "@0:";
118833e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  S += llvm::utostr(PtrSize);
118933e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
119033e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  // Argument types.
119133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  ParmOffset = 2 * PtrSize;
119233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  for (int i = 0; i < NumOfParams; i++) {
119333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    QualType PType = Decl->getParamDecl(i)->getType();
1194ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    // Process argument qualifiers for user supplied arguments; such as,
119533e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    // 'in', 'inout', etc.
1196a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    getObjCEncodingForTypeQualifier(
1197a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      Decl->getParamDecl(i)->getObjCDeclQualifier(), S);
11987d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    getObjCEncodingForType(PType, S, EncodingRecordTypes);
119933e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    S += llvm::utostr(ParmOffset);
1200a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ParmOffset += getObjCEncodingTypeSize(PType);
120133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  }
120233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian}
120333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
12047d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanianvoid ASTContext::getObjCEncodingForType(QualType T, std::string& S,
12057d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian       llvm::SmallVector<const RecordType *, 8> &ERType) const
120685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson{
1207e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // FIXME: This currently doesn't encode:
1208e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // @ An object (whether statically typed or typed id)
1209e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // # A class object (Class)
1210e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // : A method selector (SEL)
1211e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // {name=type...} A structure
1212e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // (name=type...) A union
1213e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  // bnum A bit field of num bits
1214e8c49533521c40643653f943d47229e62d277f88Anders Carlsson
1215e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  if (const BuiltinType *BT = T->getAsBuiltinType()) {
121685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    char encoding;
121785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    switch (BT->getKind()) {
12187176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    default: assert(0 && "Unhandled builtin type kind");
12197176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Void:       encoding = 'v'; break;
12207176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Bool:       encoding = 'B'; break;
122185f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    case BuiltinType::Char_U:
12227176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::UChar:      encoding = 'C'; break;
12237176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::UShort:     encoding = 'S'; break;
12247176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::UInt:       encoding = 'I'; break;
12257176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::ULong:      encoding = 'L'; break;
12267176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::ULongLong:  encoding = 'Q'; break;
122785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    case BuiltinType::Char_S:
12287176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::SChar:      encoding = 'c'; break;
12297176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Short:      encoding = 's'; break;
12307176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Int:        encoding = 'i'; break;
12317176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Long:       encoding = 'l'; break;
12327176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::LongLong:   encoding = 'q'; break;
12337176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Float:      encoding = 'f'; break;
12347176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::Double:     encoding = 'd'; break;
12357176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner    case BuiltinType::LongDouble: encoding = 'd'; break;
123685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    }
123785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
123885f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    S += encoding;
1239c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  }
1240a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  else if (T->isObjCQualifiedIdType()) {
1241c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian    // Treat id<P...> same as 'id' for encoding purposes.
12427d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    return getObjCEncodingForType(getObjCIdType(), S, ERType);
1243c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
1244c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  }
1245c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  else if (const PointerType *PT = T->getAsPointerType()) {
124685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    QualType PointeeTy = PT->getPointeeType();
1247a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    if (isObjCIdType(PointeeTy) || PointeeTy->isObjCInterfaceType()) {
1248c2939bc82ce177c0413feb0cd9ce70aefd6235fbFariborz Jahanian      S += '@';
1249c2939bc82ce177c0413feb0cd9ce70aefd6235fbFariborz Jahanian      return;
1250a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    } else if (isObjCClassType(PointeeTy)) {
12518baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson      S += '#';
12528baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson      return;
1253a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    } else if (isObjCSelType(PointeeTy)) {
12548baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson      S += ':';
12558baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson      return;
1256c2939bc82ce177c0413feb0cd9ce70aefd6235fbFariborz Jahanian    }
125785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
125885f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    if (PointeeTy->isCharType()) {
125985f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson      // char pointer types should be encoded as '*' unless it is a
126085f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson      // type that has been typedef'd to 'BOOL'.
1261e8c49533521c40643653f943d47229e62d277f88Anders Carlsson      if (!isTypeTypedefedAsBOOL(PointeeTy)) {
126285f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson        S += '*';
126385f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson        return;
126485f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson      }
126585f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    }
126685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
126785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    S += '^';
12687d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    getObjCEncodingForType(PT->getPointeeType(), S, ERType);
1269e8c49533521c40643653f943d47229e62d277f88Anders Carlsson  } else if (const ArrayType *AT = T->getAsArrayType()) {
127085f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    S += '[';
127185f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
127285f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
127385f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson      S += llvm::utostr(CAT->getSize().getZExtValue());
127485f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    else
127585f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson      assert(0 && "Unhandled array type!");
127685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
12777d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    getObjCEncodingForType(AT->getElementType(), S, ERType);
127885f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson    S += ']';
1279c0a87b7db06643178ad2cbce0767548c139ea387Anders Carlsson  } else if (T->getAsFunctionType()) {
1280c0a87b7db06643178ad2cbce0767548c139ea387Anders Carlsson    S += '?';
12816de88a873a4cbe06d72602eef57d68006730a80bFariborz Jahanian  } else if (const RecordType *RTy = T->getAsRecordType()) {
12826de88a873a4cbe06d72602eef57d68006730a80bFariborz Jahanian    RecordDecl *RDecl= RTy->getDecl();
12836de88a873a4cbe06d72602eef57d68006730a80bFariborz Jahanian    S += '{';
12846de88a873a4cbe06d72602eef57d68006730a80bFariborz Jahanian    S += RDecl->getName();
12857d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    bool found = false;
12867d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    for (unsigned i = 0, e = ERType.size(); i != e; ++i)
12877d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      if (ERType[i] == RTy) {
12887d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian        found = true;
12897d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian        break;
12907d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      }
12917d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    if (!found) {
12927d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      ERType.push_back(RTy);
12937d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      S += '=';
12947d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      for (int i = 0; i < RDecl->getNumMembers(); i++) {
12957d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian        FieldDecl *field = RDecl->getMember(i);
12967d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian        getObjCEncodingForType(field->getType(), S, ERType);
12977d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      }
12987d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      assert(ERType.back() == RTy && "Record Type stack mismatch.");
12997d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian      ERType.pop_back();
13006de88a873a4cbe06d72602eef57d68006730a80bFariborz Jahanian    }
13016de88a873a4cbe06d72602eef57d68006730a80bFariborz Jahanian    S += '}';
13025e71124dabe8017f17ce8996e4161a202694e3e6Steve Naroff  } else if (T->isEnumeralType()) {
13035e71124dabe8017f17ce8996e4161a202694e3e6Steve Naroff    S += 'i';
130485f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson  } else
1305f69cc5d6606fc65a76e3acd6eb6e13efd0098295Steve Naroff    assert(0 && "@encode for type not implemented!");
130685f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson}
130785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
1308a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
1309ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian                                                 std::string& S) const {
1310ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  if (QT & Decl::OBJC_TQ_In)
1311ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    S += 'n';
1312ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  if (QT & Decl::OBJC_TQ_Inout)
1313ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    S += 'N';
1314ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  if (QT & Decl::OBJC_TQ_Out)
1315ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    S += 'o';
1316ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  if (QT & Decl::OBJC_TQ_Bycopy)
1317ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    S += 'O';
1318ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  if (QT & Decl::OBJC_TQ_Byref)
1319ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    S += 'R';
1320ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  if (QT & Decl::OBJC_TQ_Oneway)
1321ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian    S += 'V';
1322ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian}
1323ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian
1324b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlssonvoid ASTContext::setBuiltinVaListType(QualType T)
1325b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson{
1326b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson  assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");
1327b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson
1328b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson  BuiltinVaListType = T;
1329b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson}
1330b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson
1331a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::setObjCIdType(TypedefDecl *TD)
13327e219e47de26346885d667131977bd9ca2d7662aSteve Naroff{
1333a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  assert(ObjCIdType.isNull() && "'id' type already set!");
13347e219e47de26346885d667131977bd9ca2d7662aSteve Naroff
1335a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIdType = getTypedefType(TD);
13367e219e47de26346885d667131977bd9ca2d7662aSteve Naroff
13377e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  // typedef struct objc_object *id;
13387e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
13397e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  assert(ptr && "'id' incorrectly typed");
13407e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
13417e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  assert(rec && "'id' incorrectly typed");
13427e219e47de26346885d667131977bd9ca2d7662aSteve Naroff  IdStructType = rec;
13437e219e47de26346885d667131977bd9ca2d7662aSteve Naroff}
13447e219e47de26346885d667131977bd9ca2d7662aSteve Naroff
1345a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::setObjCSelType(TypedefDecl *TD)
1346b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian{
1347a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  assert(ObjCSelType.isNull() && "'SEL' type already set!");
1348b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian
1349a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCSelType = getTypedefType(TD);
1350b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian
1351b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  // typedef struct objc_selector *SEL;
1352b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1353b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  assert(ptr && "'SEL' incorrectly typed");
1354b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1355b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  assert(rec && "'SEL' incorrectly typed");
1356b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  SelStructType = rec;
1357b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian}
1358b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian
1359a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::setObjCProtoType(QualType QT)
1360390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian{
1361a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  assert(ObjCProtoType.isNull() && "'Protocol' type already set!");
1362a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtoType = QT;
1363390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian}
1364390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian
1365a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::setObjCClassType(TypedefDecl *TD)
13668baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson{
1367a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  assert(ObjCClassType.isNull() && "'Class' type already set!");
13688baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson
1369a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCClassType = getTypedefType(TD);
13708baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson
13718baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  // typedef struct objc_class *Class;
13728baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
13738baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  assert(ptr && "'Class' incorrectly typed");
13748baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
13758baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  assert(rec && "'Class' incorrectly typed");
13768baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson  ClassStructType = rec;
13778baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson}
13788baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson
1379a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
1380a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  assert(ObjCConstantStringType.isNull() &&
13812198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff         "'NSConstantString' type already set!");
13822198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff
1383a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCConstantStringType = getObjCInterfaceType(Decl);
13842198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff}
13852198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff
1386ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
1387ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const BuiltinType *lBuiltin = lhs->getAsBuiltinType();
1388ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const BuiltinType *rBuiltin = rhs->getAsBuiltinType();
1389ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1390ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return lBuiltin->getKind() == rBuiltin->getKind();
1391ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1392ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1393b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian/// objcTypesAreCompatible - This routine is called when two types
1394b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian/// are of different class; one is interface type or is
1395b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian/// a qualified interface type and the other type is of a different class.
1396b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian/// Example, II or II<P>.
1397ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::objcTypesAreCompatible(QualType lhs, QualType rhs) {
1398a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (lhs->isObjCInterfaceType() && isObjCIdType(rhs))
1399ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return true;
1400a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  else if (isObjCIdType(lhs) && rhs->isObjCInterfaceType())
1401ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return true;
1402a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (ObjCInterfaceType *lhsIT =
1403a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      dyn_cast<ObjCInterfaceType>(lhs.getCanonicalType().getTypePtr())) {
1404a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCQualifiedInterfaceType *rhsQI =
1405a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      dyn_cast<ObjCQualifiedInterfaceType>(rhs.getCanonicalType().getTypePtr());
1406b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian    return rhsQI && (lhsIT->getDecl() == rhsQI->getDecl());
1407b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian  }
1408a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  else if (ObjCInterfaceType *rhsIT =
1409a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek           dyn_cast<ObjCInterfaceType>(rhs.getCanonicalType().getTypePtr())) {
1410a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCQualifiedInterfaceType *lhsQI =
1411a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    dyn_cast<ObjCQualifiedInterfaceType>(lhs.getCanonicalType().getTypePtr());
1412b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian    return lhsQI && (rhsIT->getDecl() == lhsQI->getDecl());
1413b145e7dedebe2ac3c6e8233bece6ffc3f67b3a66Fariborz Jahanian  }
1414ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return false;
1415ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1416ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1417c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian/// Check that 'lhs' and 'rhs' are compatible interface types. Both types
1418c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian/// must be canonical types.
1419ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
1420c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian  assert (lhs->isCanonical() &&
1421c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian          "interfaceTypesAreCompatible strip typedefs of lhs");
1422c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian  assert (rhs->isCanonical() &&
1423c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian          "interfaceTypesAreCompatible strip typedefs of rhs");
14240f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian  if (lhs == rhs)
14250f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian    return true;
1426a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceType *lhsIT = cast<ObjCInterfaceType>(lhs.getTypePtr());
1427a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceType *rhsIT = cast<ObjCInterfaceType>(rhs.getTypePtr());
1428a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *rhsIDecl = rhsIT->getDecl();
1429a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *lhsIDecl = lhsIT->getDecl();
14300f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian  // rhs is derived from lhs it is OK; else it is not OK.
14310f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian  while (rhsIDecl != NULL) {
14320f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian    if (rhsIDecl == lhsIDecl)
14330f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian      return true;
14340f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian    rhsIDecl = rhsIDecl->getSuperClass();
14350f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian  }
14360f01debd47b43c287f8f1135cd3f9679a5a3ab2eFariborz Jahanian  return false;
1437ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1438ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
14394ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanianbool ASTContext::QualifiedInterfaceTypesAreCompatible(QualType lhs,
14404ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian                                                      QualType rhs) {
1441a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceType *lhsQI =
1442a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    dyn_cast<ObjCQualifiedInterfaceType>(lhs.getCanonicalType().getTypePtr());
14434ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian  assert(lhsQI && "QualifiedInterfaceTypesAreCompatible - bad lhs type");
1444a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceType *rhsQI =
1445a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    dyn_cast<ObjCQualifiedInterfaceType>(rhs.getCanonicalType().getTypePtr());
14464ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian  assert(rhsQI && "QualifiedInterfaceTypesAreCompatible - bad rhs type");
1447c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian  if (!interfaceTypesAreCompatible(
1448c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian         getObjCInterfaceType(lhsQI->getDecl()).getCanonicalType(),
1449c5ae5cf88ff108f7a325c7b686f78c02517a44e5Fariborz Jahanian         getObjCInterfaceType(rhsQI->getDecl()).getCanonicalType()))
14504ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian    return false;
14514ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian  /* All protocols in lhs must have a presense in rhs. */
14524ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian  for (unsigned i =0; i < lhsQI->getNumProtocols(); i++) {
14534ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian    bool match = false;
1454a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCProtocolDecl *lhsProto = lhsQI->getProtocols(i);
14554ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian    for (unsigned j = 0; j < rhsQI->getNumProtocols(); j++) {
1456a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCProtocolDecl *rhsProto = rhsQI->getProtocols(j);
14574ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian      if (lhsProto == rhsProto) {
14584ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian        match = true;
14594ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian        break;
14604ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian      }
14614ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian    }
14624ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian    if (!match)
14634ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian      return false;
14644ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian  }
14654ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian  return true;
14664ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian}
14674ffc54111fdc0baa45bb287f59774e06dea8caa4Fariborz Jahanian
1468d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
1469d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian/// inheritance hierarchy of 'rProto'.
1470a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekstatic bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
1471a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                                           ObjCProtocolDecl *rProto) {
1472d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian  if (lProto == rProto)
1473d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian    return true;
1474a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl** RefPDecl = rProto->getReferencedProtocols();
1475d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian  for (unsigned i = 0; i < rProto->getNumReferencedProtocols(); i++)
1476d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian    if (ProtocolCompatibleWithProtocol(lProto, RefPDecl[i]))
1477d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian      return true;
1478d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian  return false;
1479d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian}
1480d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian
14814c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian/// ClassImplementsProtocol - Checks that 'lProto' protocol
14824c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian/// has been implemented in IDecl class, its super class or categories (if
14834c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian/// lookupCategory is true).
1484a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekstatic bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1485a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                                    ObjCInterfaceDecl *IDecl,
14864c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian                                    bool lookupCategory) {
14874c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
14884c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  // 1st, look up the class.
1489a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **protoList = IDecl->getReferencedProtocols();
14904c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  for (unsigned i = 0; i < IDecl->getNumIntfRefProtocols(); i++) {
14914c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    if (ProtocolCompatibleWithProtocol(lProto, protoList[i]))
14924c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      return true;
14934c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  }
14944c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
14954c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  // 2nd, look up the category.
14964c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  if (lookupCategory)
1497a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
14984c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian         CDecl = CDecl->getNextClassCategory()) {
14994c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      protoList = CDecl->getReferencedProtocols();
15004c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      for (unsigned i = 0; i < CDecl->getNumReferencedProtocols(); i++) {
15014c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian        if (ProtocolCompatibleWithProtocol(lProto, protoList[i]))
15024c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian          return true;
15034c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      }
15044c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    }
15054c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
15064c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  // 3rd, look up the super class(s)
15074c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  if (IDecl->getSuperClass())
15084c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    return
15094c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory);
15104c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
15114c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian  return false;
15124c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian}
15134c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
1514a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCQualifiedIdTypesAreCompatible - Compares two types, at least
1515d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian/// one of which is a protocol qualified 'id' type. When 'compare'
1516d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian/// is true it is for comparison; when false, for assignment/initialization.
1517a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekbool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs,
1518d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian                                                   QualType rhs,
1519d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian                                                   bool compare) {
1520411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  // match id<P..> with an 'id' type in all cases.
1521411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  if (const PointerType *PT = lhs->getAsPointerType()) {
1522411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    QualType PointeeTy = PT->getPointeeType();
1523a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    if (isObjCIdType(PointeeTy) || PointeeTy->isVoidType())
1524411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      return true;
1525411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian
1526411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  }
1527411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  else if (const PointerType *PT = rhs->getAsPointerType()) {
1528411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    QualType PointeeTy = PT->getPointeeType();
1529a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    if (isObjCIdType(PointeeTy) || PointeeTy->isVoidType())
1530411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      return true;
1531411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian
1532411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  }
1533411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian
1534a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceType *lhsQI = 0;
1535a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedInterfaceType *rhsQI = 0;
1536a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *lhsID = 0;
1537a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *rhsID = 0;
1538a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedIdType *lhsQID = dyn_cast<ObjCQualifiedIdType>(lhs);
1539a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQualifiedIdType *rhsQID = dyn_cast<ObjCQualifiedIdType>(rhs);
1540411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian
1541411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  if (lhsQID) {
1542411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    if (!rhsQID && rhs->getTypeClass() == Type::Pointer) {
1543411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      QualType rtype =
1544411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian        cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
1545411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      rhsQI =
1546a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek        dyn_cast<ObjCQualifiedInterfaceType>(
1547411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian          rtype.getCanonicalType().getTypePtr());
1548c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      if (!rhsQI) {
1549a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek        ObjCInterfaceType *IT = dyn_cast<ObjCInterfaceType>(
1550c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian                                  rtype.getCanonicalType().getTypePtr());
1551c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian        if (IT)
1552c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian          rhsID = IT->getDecl();
1553c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      }
1554411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    }
1555c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian    if (!rhsQI && !rhsQID && !rhsID)
1556411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      return false;
1557411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian
1558bca14a2c664dfb2e221a4b9d481f8d4116bfcf37Fariborz Jahanian    unsigned numRhsProtocols = 0;
1559a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCProtocolDecl **rhsProtoList = 0;
15604c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    if (rhsQI) {
15614c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      numRhsProtocols = rhsQI->getNumProtocols();
15624c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      rhsProtoList = rhsQI->getReferencedProtocols();
15634c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    }
15644c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    else if (rhsQID) {
15654c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      numRhsProtocols = rhsQID->getNumProtocols();
15664c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      rhsProtoList = rhsQID->getReferencedProtocols();
15674c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    }
15684c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
1569411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) {
1570a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCProtocolDecl *lhsProto = lhsQID->getProtocols(i);
15714c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      bool match = false;
15724c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian
15734c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      // when comparing an id<P> on lhs with a static type on rhs,
15744c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      // see if static class implements all of id's protocols, directly or
15754c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      // through its super class and categories.
15764c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      if (rhsID) {
15774c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian        if (ClassImplementsProtocol(lhsProto, rhsID, true))
15784c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian          match = true;
1579c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      }
15804c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      else for (unsigned j = 0; j < numRhsProtocols; j++) {
1581a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek        ObjCProtocolDecl *rhsProto = rhsProtoList[j];
1582d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
1583d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian            compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) {
1584411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian          match = true;
1585411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian          break;
1586411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian        }
1587411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      }
1588411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      if (!match)
1589411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian        return false;
1590411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    }
1591411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  }
1592411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  else if (rhsQID) {
1593411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    if (!lhsQID && lhs->getTypeClass() == Type::Pointer) {
1594411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      QualType ltype =
1595411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
1596411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      lhsQI =
1597a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      dyn_cast<ObjCQualifiedInterfaceType>(
1598411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian        ltype.getCanonicalType().getTypePtr());
1599c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      if (!lhsQI) {
1600a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek        ObjCInterfaceType *IT = dyn_cast<ObjCInterfaceType>(
1601c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian                                  ltype.getCanonicalType().getTypePtr());
1602c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian        if (IT)
1603c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian          lhsID = IT->getDecl();
1604c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      }
1605411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    }
1606c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian    if (!lhsQI && !lhsQID && !lhsID)
1607411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      return false;
1608c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian
1609bca14a2c664dfb2e221a4b9d481f8d4116bfcf37Fariborz Jahanian    unsigned numLhsProtocols = 0;
1610a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCProtocolDecl **lhsProtoList = 0;
1611411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    if (lhsQI) {
1612411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      numLhsProtocols = lhsQI->getNumProtocols();
1613411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      lhsProtoList = lhsQI->getReferencedProtocols();
1614411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian    }
1615c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian    else if (lhsQID) {
1616411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      numLhsProtocols = lhsQID->getNumProtocols();
1617411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      lhsProtoList = lhsQID->getReferencedProtocols();
16184c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    }
16194c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    bool match = false;
16204c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    // for static type vs. qualified 'id' type, check that class implements
16214c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    // one of 'id's protocols.
16224c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    if (lhsID) {
16234c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
1624a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek        ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
16254c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian        if (ClassImplementsProtocol(rhsProto, lhsID, compare)) {
16264c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian          match = true;
16274c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian          break;
16284c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian        }
16294c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      }
16304c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    }
16314c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    else for (unsigned i =0; i < numLhsProtocols; i++) {
16324c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      match = false;
1633a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCProtocolDecl *lhsProto = lhsProtoList[i];
1634411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
1635a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek        ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
1636d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
1637d0c89c4609494e4aae0afb7704c35c0e9523f532Fariborz Jahanian          compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) {
1638411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian          match = true;
1639411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian          break;
1640411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian        }
1641411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian      }
16424c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    }
16434c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian    if (!match)
16444c71f1a58e8892fc9f1fe6bdf10bfbe16f592b2dFariborz Jahanian      return false;
1645411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  }
1646411f373abf5692a1bd90d35a139d955fa67ae82dFariborz Jahanian  return true;
1647c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian}
1648c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
1649770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattnerbool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
1650770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner  const VectorType *lVector = lhs->getAsVectorType();
1651770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner  const VectorType *rVector = rhs->getAsVectorType();
1652770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner
1653770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner  if ((lVector->getElementType().getCanonicalType() ==
1654770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner      rVector->getElementType().getCanonicalType()) &&
1655770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner      (lVector->getNumElements() == rVector->getNumElements()))
1656770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner    return true;
1657770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner  return false;
1658770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner}
1659770951b5bb6028a8d326ddb4a13cef7d4a128162Chris Lattner
1660ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff// C99 6.2.7p1: If both are complete types, then the following additional
1661ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff// requirements apply...FIXME (handle compatibility across source files).
1662ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) {
1663ab373097926c4f24dd653e8b9aebcbf2eff17881Steve Naroff  // "Class" and "id" are compatible built-in structure types.
1664a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (isObjCIdType(lhs) && isObjCClassType(rhs) ||
1665a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      isObjCClassType(lhs) && isObjCIdType(rhs))
1666ab373097926c4f24dd653e8b9aebcbf2eff17881Steve Naroff    return true;
1667d57405250498a1b5f23c97c6e089318f6f3eefd7Eli Friedman
1668d57405250498a1b5f23c97c6e089318f6f3eefd7Eli Friedman  // Within a translation unit a tag type is
1669d57405250498a1b5f23c97c6e089318f6f3eefd7Eli Friedman  // only compatible with itself.
1670d57405250498a1b5f23c97c6e089318f6f3eefd7Eli Friedman  return lhs.getCanonicalType() == rhs.getCanonicalType();
1671ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1672ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1673ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
1674ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
1675ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // identically qualified and both shall be pointers to compatible types.
1676f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner  if (lhs.getCVRQualifiers() != rhs.getCVRQualifiers() ||
1677f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner      lhs.getAddressSpace() != rhs.getAddressSpace())
1678ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return false;
1679ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1680ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
1681ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
1682ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1683ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return typesAreCompatible(ltype, rtype);
1684ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1685ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
168643d69750e7f7b26076e7474dec8839bb777b260fBill Wendling// C++ 5.17p6: When the left operand of an assignment operator denotes a
1687ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff// reference to T, the operation assigns to the object of type T denoted by the
1688ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff// reference.
1689ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
1690ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  QualType ltype = lhs;
1691ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1692ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (lhs->isReferenceType())
1693bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner    ltype = cast<ReferenceType>(lhs.getCanonicalType())->getPointeeType();
1694ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1695ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  QualType rtype = rhs;
1696ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1697ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (rhs->isReferenceType())
1698bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner    rtype = cast<ReferenceType>(rhs.getCanonicalType())->getPointeeType();
1699ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1700ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return typesAreCompatible(ltype, rtype);
1701ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1702ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1703ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::functionTypesAreCompatible(QualType lhs, QualType rhs) {
1704ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
1705ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
1706ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
1707ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
1708ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1709ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // first check the return types (common between C99 and K&R).
1710ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
1711ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return false;
1712ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1713ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (lproto && rproto) { // two C99 style function prototypes
1714ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    unsigned lproto_nargs = lproto->getNumArgs();
1715ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    unsigned rproto_nargs = rproto->getNumArgs();
1716ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1717ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    if (lproto_nargs != rproto_nargs)
1718ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff      return false;
1719ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1720ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    // both prototypes have the same number of arguments.
1721ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    if ((lproto->isVariadic() && !rproto->isVariadic()) ||
1722ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff        (rproto->isVariadic() && !lproto->isVariadic()))
1723ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff      return false;
1724ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1725ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    // The use of ellipsis agree...now check the argument types.
1726ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    for (unsigned i = 0; i < lproto_nargs; i++)
1727f69cc5d6606fc65a76e3acd6eb6e13efd0098295Steve Naroff      // C99 6.7.5.3p15: ...and each parameter declared with qualified type
1728f69cc5d6606fc65a76e3acd6eb6e13efd0098295Steve Naroff      // is taken as having the unqualified version of it's declared type.
1729ba03eda1599dd89da935a2b46da10659afe46addSteve Naroff      if (!typesAreCompatible(lproto->getArgType(i).getUnqualifiedType(),
1730f69cc5d6606fc65a76e3acd6eb6e13efd0098295Steve Naroff                              rproto->getArgType(i).getUnqualifiedType()))
1731ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff        return false;
1732ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return true;
1733ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  }
1734ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (!lproto && !rproto) // two K&R style function decls, nothing to do.
1735ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return true;
1736ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1737ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // we have a mixture of K&R style with C99 prototypes
1738ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  const FunctionTypeProto *proto = lproto ? lproto : rproto;
1739ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1740ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (proto->isVariadic())
1741ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return false;
1742ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1743ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // FIXME: Each parameter type T in the prototype must be compatible with the
1744ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // type resulting from applying the usual argument conversions to T.
1745ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return true;
1746ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1747ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1748ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
17494e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman  // Compatible arrays must have compatible element types
17504e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman  QualType ltype = lhs->getAsArrayType()->getElementType();
17514e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman  QualType rtype = rhs->getAsArrayType()->getElementType();
17524e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman
1753ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (!typesAreCompatible(ltype, rtype))
1754ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return false;
17554e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman
17564e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman  // Compatible arrays must be the same size
17574e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman  if (const ConstantArrayType* LCAT = lhs->getAsConstantArrayType())
17584e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman    if (const ConstantArrayType* RCAT = rhs->getAsConstantArrayType())
17594e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman      return RCAT->getSize() == LCAT->getSize();
17604e92acf3b747b994e50fbf7bfe8ef71cdda20c50Eli Friedman
1761ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return true;
1762ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
1763ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
1764ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
1765ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff/// both shall have the identically qualified version of a compatible type.
1766ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff/// C99 6.2.7p1: Two types have compatible types if their types are the
1767ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff/// same. See 6.7.[2,3,5] for additional rules.
1768ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroffbool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
1769ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  QualType lcanon = lhs.getCanonicalType();
1770ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  QualType rcanon = rhs.getCanonicalType();
1771988ee6ef540d1203cf4aa52971f3c135c796bdf7Chris Lattner
1772ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  // If two types are identical, they are are compatible
1773ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  if (lcanon == rcanon)
1774ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return true;
1775988ee6ef540d1203cf4aa52971f3c135c796bdf7Chris Lattner
1776988ee6ef540d1203cf4aa52971f3c135c796bdf7Chris Lattner  if (lcanon.getCVRQualifiers() != rcanon.getCVRQualifiers() ||
1777988ee6ef540d1203cf4aa52971f3c135c796bdf7Chris Lattner      lcanon.getAddressSpace() != rcanon.getAddressSpace())
1778988ee6ef540d1203cf4aa52971f3c135c796bdf7Chris Lattner    return false;
177943d69750e7f7b26076e7474dec8839bb777b260fBill Wendling
178043d69750e7f7b26076e7474dec8839bb777b260fBill Wendling  // C++ [expr]: If an expression initially has the type "reference to T", the
178143d69750e7f7b26076e7474dec8839bb777b260fBill Wendling  // type is adjusted to "T" prior to any further analysis, the expression
178243d69750e7f7b26076e7474dec8839bb777b260fBill Wendling  // designates the object or function denoted by the reference, and the
178343d69750e7f7b26076e7474dec8839bb777b260fBill Wendling  // expression is an lvalue.
17841adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  if (ReferenceType *RT = dyn_cast<ReferenceType>(lcanon))
1785bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner    lcanon = RT->getPointeeType();
17861adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  if (ReferenceType *RT = dyn_cast<ReferenceType>(rcanon))
1787bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner    rcanon = RT->getPointeeType();
17881adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner
17891adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  Type::TypeClass LHSClass = lcanon->getTypeClass();
17901adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  Type::TypeClass RHSClass = rcanon->getTypeClass();
17911adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner
17921adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  // We want to consider the two function types to be the same for these
17931adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  // comparisons, just force one to the other.
17941adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto;
17951adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto;
17964c721d381fb279899337d120edd4a24d405e56b2Eli Friedman
17974c721d381fb279899337d120edd4a24d405e56b2Eli Friedman  // Same as above for arrays
17984c721d381fb279899337d120edd4a24d405e56b2Eli Friedman  if (LHSClass == Type::VariableArray) LHSClass = Type::ConstantArray;
17994c721d381fb279899337d120edd4a24d405e56b2Eli Friedman  if (RHSClass == Type::VariableArray) RHSClass = Type::ConstantArray;
1800c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  if (LHSClass == Type::IncompleteArray) LHSClass = Type::ConstantArray;
1801c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  if (RHSClass == Type::IncompleteArray) RHSClass = Type::ConstantArray;
1802ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff
18034a74678ed6c3dedac05d02b1ee341f1db869f049Steve Naroff  // If the canonical type classes don't match...
18041adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  if (LHSClass != RHSClass) {
1805ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    // For Objective-C, it is possible for two types to be compatible
1806ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    // when their classes don't match (when dealing with "id"). If either type
1807ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    // is an interface, we defer to objcTypesAreCompatible().
1808a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    if (lcanon->isObjCInterfaceType() || rcanon->isObjCInterfaceType())
1809ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff      return objcTypesAreCompatible(lcanon, rcanon);
1810f69cc5d6606fc65a76e3acd6eb6e13efd0098295Steve Naroff
18111adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    // C99 6.7.2.2p4: Each enumerated type shall be compatible with char,
18121adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    // a signed integer type, or an unsigned integer type.
1813bab96968886f4b77083f4e26a28986ddb1e42d67Eli Friedman    if (lcanon->isEnumeralType() && rcanon->isIntegralType()) {
18147176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner      EnumDecl* EDecl = cast<EnumType>(lcanon)->getDecl();
1815bab96968886f4b77083f4e26a28986ddb1e42d67Eli Friedman      return EDecl->getIntegerType() == rcanon;
1816bab96968886f4b77083f4e26a28986ddb1e42d67Eli Friedman    }
1817bab96968886f4b77083f4e26a28986ddb1e42d67Eli Friedman    if (rcanon->isEnumeralType() && lcanon->isIntegralType()) {
18187176331b0f5cfaaa2b5aa487a6660e859e371119Chris Lattner      EnumDecl* EDecl = cast<EnumType>(rcanon)->getDecl();
1819bab96968886f4b77083f4e26a28986ddb1e42d67Eli Friedman      return EDecl->getIntegerType() == lcanon;
1820bab96968886f4b77083f4e26a28986ddb1e42d67Eli Friedman    }
18211adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner
1822ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff    return false;
1823ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  }
18244a74678ed6c3dedac05d02b1ee341f1db869f049Steve Naroff  // The canonical type classes match.
18251adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  switch (LHSClass) {
18261adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::FunctionProto: assert(0 && "Canonicalized away above");
18271adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::Pointer:
18281adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return pointerTypesAreCompatible(lcanon, rcanon);
18291adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::ConstantArray:
18301adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::VariableArray:
1831c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  case Type::IncompleteArray:
18321adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return arrayTypesAreCompatible(lcanon, rcanon);
18331adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::FunctionNoProto:
18341adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return functionTypesAreCompatible(lcanon, rcanon);
18351adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::Tagged: // handle structures, unions
18361adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return tagTypesAreCompatible(lcanon, rcanon);
18371adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::Builtin:
18381adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return builtinTypesAreCompatible(lcanon, rcanon);
18391adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::ObjCInterface:
18401adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return interfaceTypesAreCompatible(lcanon, rcanon);
18411adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::Vector:
18421adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::OCUVector:
18431adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return vectorTypesAreCompatible(lcanon, rcanon);
18441adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  case Type::ObjCQualifiedInterface:
18451adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    return QualifiedInterfaceTypesAreCompatible(lcanon, rcanon);
18461adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner  default:
18471adb88370beab45af2f065afe86b51ccd59ec50dChris Lattner    assert(0 && "unexpected type");
1848ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  }
1849ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff  return true; // should never get here...
1850ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff}
18517192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek
18527192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek/// Emit - Serialize an ASTContext object to Bitcode.
18537192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenekvoid ASTContext::Emit(llvm::Serializer& S) const {
18545451350ea6881c55c9e05f3a15486471b97f0757Ted Kremenek  S.EmitRef(SourceMgr);
18555451350ea6881c55c9e05f3a15486471b97f0757Ted Kremenek  S.EmitRef(Target);
18565451350ea6881c55c9e05f3a15486471b97f0757Ted Kremenek  S.EmitRef(Idents);
18575451350ea6881c55c9e05f3a15486471b97f0757Ted Kremenek  S.EmitRef(Selectors);
18587192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek
1859fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  // Emit the size of the type vector so that we can reserve that size
1860fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  // when we reconstitute the ASTContext object.
1861a4559c3f69f3a5b01cced8df4f69c03c45821c74Ted Kremenek  S.EmitInt(Types.size());
1862a4559c3f69f3a5b01cced8df4f69c03c45821c74Ted Kremenek
186303ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek  for (std::vector<Type*>::const_iterator I=Types.begin(), E=Types.end();
186403ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek                                          I!=E;++I)
186503ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek    (*I)->Emit(S);
1866a4559c3f69f3a5b01cced8df4f69c03c45821c74Ted Kremenek
1867a9a4a24592a2164114a8a36717650e6341eb67a4Ted Kremenek  // FIXME: S.EmitOwnedPtr(CFConstantStringTypeDecl);
18687192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek}
18697192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek
18700f84c0059cec39fd1c73ac05bc2864dca664e7f4Ted KremenekASTContext* ASTContext::Create(llvm::Deserializer& D) {
1871fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  SourceManager &SM = D.ReadRef<SourceManager>();
1872fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  TargetInfo &t = D.ReadRef<TargetInfo>();
1873fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  IdentifierTable &idents = D.ReadRef<IdentifierTable>();
1874fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  SelectorTable &sels = D.ReadRef<SelectorTable>();
18750ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner
1876fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  unsigned size_reserve = D.ReadInt();
1877fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek
1878fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve);
1879fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek
188003ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek  for (unsigned i = 0; i < size_reserve; ++i)
188103ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek    Type::Create(*A,i,D);
18820ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner
1883a9a4a24592a2164114a8a36717650e6341eb67a4Ted Kremenek  // FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
1884fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek
1885fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek  return A;
1886fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek}
1887