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