diff options
-rw-r--r-- | include/clang/AST/DeclObjC.h | 3 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 66 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 41 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 6 |
9 files changed, 66 insertions, 73 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 8f9bc2f01c..333dcd3401 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -384,7 +384,8 @@ public: void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars, SourceLocation RBracLoc); - FieldDecl *lookupFieldDeclForIvar(ASTContext &Context, ObjCIvarDecl *ivar); + FieldDecl *lookupFieldDeclForIvar(ASTContext &Context, + const ObjCIvarDecl *ivar); void addLayoutToClass(ASTContext &Context); void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 27e6a6df65..50f45e8579 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -367,7 +367,7 @@ void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars, /// storage which matches this 'ivar'. /// FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, - ObjCIvarDecl *ivar) { + const ObjCIvarDecl *ivar) { assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class"); DeclarationName Member = ivar->getDeclName(); DeclContext::lookup_result Lookup = RecordForDecl->lookup(Context, Member); @@ -392,7 +392,8 @@ void ObjCInterfaceDecl::addLayoutToClass(ASTContext &Context) for (unsigned int i = 0; i != RecFields.size(); i++) { FieldDecl *Field = FieldDecl::Create(Context, RD, SourceLocation(), RecFields[i]->getIdentifier(), - RecFields[i]->getType(), 0, false, 0); + RecFields[i]->getType(), + RecFields[i]->getBitWidth(), false, 0); RD->addDecl(Context, Field); } RD->completeDefinition(Context); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index a7a64e3860..31b63d1fbc 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -788,36 +788,41 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { return MemExpLV; } +LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, + FieldDecl* Field, + unsigned CVRQualifiers, + unsigned idx) { + // FIXME: CodeGenTypes should expose a method to get the appropriate + // type for FieldTy (the appropriate type is ABI-dependent). + const llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(Field->getType()); + const llvm::PointerType *BaseTy = + cast<llvm::PointerType>(BaseValue->getType()); + unsigned AS = BaseTy->getAddressSpace(); + BaseValue = Builder.CreateBitCast(BaseValue, + llvm::PointerType::get(FieldTy, AS), + "tmp"); + llvm::Value *V = Builder.CreateGEP(BaseValue, + llvm::ConstantInt::get(llvm::Type::Int32Ty, idx), + "tmp"); + + CodeGenTypes::BitFieldInfo bitFieldInfo = + CGM.getTypes().getBitFieldInfo(Field); + return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size, + Field->getType()->isSignedIntegerType(), + Field->getType().getCVRQualifiers()|CVRQualifiers); +} + LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, FieldDecl* Field, bool isUnion, unsigned CVRQualifiers) { - llvm::Value *V; unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); - if (Field->isBitField()) { - // FIXME: CodeGenTypes should expose a method to get the appropriate - // type for FieldTy (the appropriate type is ABI-dependent). - const llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(Field->getType()); - const llvm::PointerType *BaseTy = - cast<llvm::PointerType>(BaseValue->getType()); - unsigned AS = BaseTy->getAddressSpace(); - BaseValue = Builder.CreateBitCast(BaseValue, - llvm::PointerType::get(FieldTy, AS), - "tmp"); - V = Builder.CreateGEP(BaseValue, - llvm::ConstantInt::get(llvm::Type::Int32Ty, idx), - "tmp"); - - CodeGenTypes::BitFieldInfo bitFieldInfo = - CGM.getTypes().getBitFieldInfo(Field); - return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size, - Field->getType()->isSignedIntegerType(), - Field->getType().getCVRQualifiers()|CVRQualifiers); - } + if (Field->isBitField()) + return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers, idx); - V = Builder.CreateStructGEP(BaseValue, idx, "tmp"); + llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp"); // Match union field type. if (isUnion) { @@ -944,8 +949,9 @@ llvm::Value *CodeGenFunction::EmitIvarOffset(ObjCInterfaceDecl *Interface, CGM.getTypes().ConvertType(getContext().getObjCInterfaceType(Interface)); const llvm::StructLayout *Layout = CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceLTy)); + FieldDecl *Field = Interface->lookupFieldDeclForIvar(getContext(), Ivar); uint64_t Offset = - Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Ivar)); + Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); return llvm::ConstantInt::get(CGM.getTypes().ConvertType(getContext().LongTy), Offset); @@ -953,17 +959,18 @@ llvm::Value *CodeGenFunction::EmitIvarOffset(ObjCInterfaceDecl *Interface, LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, + const FieldDecl *Field, unsigned CVRQualifiers) { // See comment in EmitIvarOffset. if (CGM.getObjCRuntime().LateBoundIVars()) assert(0 && "late-bound ivars are unsupported"); - - if (Ivar->isBitField()) - assert(0 && "ivar bitfields are unsupported"); - // TODO: Add a special case for isa (index 0) - unsigned Index = CGM.getTypes().getLLVMFieldNo(Ivar); + unsigned Index = CGM.getTypes().getLLVMFieldNo(Field); + if (Ivar->isBitField()) { + return EmitLValueForBitfield(BaseValue, const_cast<FieldDecl *>(Field), + CVRQualifiers, Index); + } llvm::Value *V = Builder.CreateStructGEP(BaseValue, Index, "tmp"); LValue LV = LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers); SetVarDeclObjCAttribute(getContext(), Ivar, Ivar->getType(), LV); @@ -988,7 +995,8 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { CVRQualifiers = BaseExpr->getType().getCVRQualifiers(); } - return EmitLValueForIvar(BaseValue, E->getDecl(), CVRQualifiers); + return EmitLValueForIvar(BaseValue, E->getDecl(), E->getFieldDecl(), + CVRQualifiers); } LValue diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 0237b96b51..e419a7b959 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -190,7 +190,9 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, Types.ConvertType(PD->getType()))); EmitReturnOfRValue(RV, PD->getType()); } else { - LValue LV = EmitLValueForIvar(LoadObjCSelf(), Ivar, 0); + FieldDecl *Field = + IMP->getClassInterface()->lookupFieldDeclForIvar(getContext(), Ivar); + LValue LV = EmitLValueForIvar(LoadObjCSelf(), Ivar, Field, 0); if (hasAggregateLLVMType(Ivar->getType())) { EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType()); } diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index aa96bc53ea..08c9b938f1 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -720,8 +720,9 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { Context.getObjCEncodingForType((*iter)->getType(), TypeStr); IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr)); // Get the offset + FieldDecl *Field = ClassDecl->lookupFieldDeclForIvar(Context, (*iter)); int offset = - (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(*iter)); + (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); IvarOffsets.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, offset)); } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 201f53e34d..33dfff1030 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1328,9 +1328,12 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, for (ObjCInterfaceDecl::ivar_iterator i = ID->getClassInterface()->ivar_begin(), e = ID->getClassInterface()->ivar_end(); i != e; ++i) { - ObjCIvarDecl *V = *i; + const ObjCIvarDecl *V = *i; + ObjCInterfaceDecl *OID = + const_cast<ObjCInterfaceDecl *>(ID->getClassInterface()); + FieldDecl *Field = OID->lookupFieldDeclForIvar(CGM.getContext(), V); unsigned Offset = - Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V)); + Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); std::string TypeStr; Ivar[0] = GetMethodVarName(V->getIdentifier()); CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, true); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 2959c08a44..a92bac7f1e 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -497,8 +497,12 @@ public: LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field, bool isUnion, unsigned CVRQualifiers); LValue EmitLValueForIvar(llvm::Value* Base, const ObjCIvarDecl *Ivar, + const FieldDecl *Field, unsigned CVRQualifiers); + LValue EmitLValueForBitfield(llvm::Value* Base, FieldDecl* Field, + unsigned CVRQualifiers, unsigned idx); + LValue EmitCXXConditionDeclLValue(const CXXConditionDeclExpr *E); LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index ff89341ddc..3470cca4d1 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -155,21 +155,6 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) { cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT); } -/// Produces a vector containing the all of the instance variables in an -/// Objective-C object, in the order that they appear. Used to create LLVM -/// structures corresponding to Objective-C objects. -void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass, - std::vector<const llvm::Type*> &IvarTypes) { - ObjCInterfaceDecl *SuperClass = ObjCClass->getSuperClass(); - if (SuperClass) - CollectObjCIvarTypes(SuperClass, IvarTypes); - for (ObjCInterfaceDecl::ivar_iterator I = ObjCClass->ivar_begin(), - E = ObjCClass->ivar_end(); I != E; ++I) { - IvarTypes.push_back(ConvertType((*I)->getType())); - ObjCIvarInfo[*I] = IvarTypes.size() - 1; - } -} - static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) { if (&format == &llvm::APFloat::IEEEsingle) return llvm::Type::FloatTy; @@ -280,21 +265,22 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { ConvertTypeRecursive(QualType(cast<ASQualType>(Ty).getBaseType(), 0)); case Type::ObjCInterface: { - // FIXME: This comment is broken. Either the code should check for - // the flag it is referring to or it should do the right thing in - // the presence of it. - // Warning: Use of this is strongly discouraged. Late binding of instance // variables is supported on some runtimes and so using static binding can // break code when libraries are updated. Only use this if you have // previously checked that the ObjCRuntime subclass in use does not support // late-bound ivars. + // We are issuing warnings elsewhere! ObjCInterfaceType OIT = cast<ObjCInterfaceType>(Ty); - std::vector<const llvm::Type*> IvarTypes; - CollectObjCIvarTypes(OIT.getDecl(), IvarTypes); - llvm::Type *T = llvm::StructType::get(IvarTypes); - TheModule.addTypeName("struct." + OIT.getDecl()->getNameAsString(), T); - return T; + ObjCInterfaceDecl *ID = OIT.getDecl(); + RecordDecl *RD = ID->getRecordForDecl(); + if(!RD) { + // Sometimes, class type is being directly generated in code gen for + // built-in class types. + ID->addLayoutToClass(Context); + RD = ID->getRecordForDecl(); + } + return ConvertTagDeclType(cast<TagDecl>(RD)); } case Type::ObjCQualifiedInterface: { @@ -427,13 +413,6 @@ unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) { return I->second; } -unsigned CodeGenTypes::getLLVMFieldNo(const ObjCIvarDecl *OID) { - llvm::DenseMap<const ObjCIvarDecl*, unsigned>::iterator - I = ObjCIvarInfo.find(OID); - assert(I != ObjCIvarInfo.end() && "Unable to find field info"); - return I->second; -} - /// addFieldInfo - Assign field number to field FD. void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) { FieldInfo[FD] = No; diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index 1c6019303c..2fe7c89fad 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -99,7 +99,6 @@ class CodeGenTypes { /// FieldInfo - This maps struct field with corresponding llvm struct type /// field no. This info is populated by record organizer. llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo; - llvm::DenseMap<const ObjCIvarDecl *, unsigned> ObjCIvarInfo; public: class BitFieldInfo { @@ -158,9 +157,6 @@ public: ArgTypeIterator end, bool IsVariadic); - void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass, - std::vector<const llvm::Type*> &IvarTypes); - const CGRecordLayout *getCGRecordLayout(const TagDecl*) const; /// Returns a StructType representing an Objective-C object const llvm::Type *ConvertObjCInterfaceToStruct(const ObjCInterfaceDecl *OID); @@ -168,8 +164,6 @@ public: /// getLLVMFieldNo - Return llvm::StructType element number /// that corresponds to the field FD. unsigned getLLVMFieldNo(const FieldDecl *FD); - unsigned getLLVMFieldNo(const ObjCIvarDecl *OID); - /// UpdateCompletedType - When we find the full definition for a TagDecl, /// replace the 'opaque' type we previously made for it if applicable. |