From: Fariborz Jahanian Date: Sat, 7 Mar 2009 19:43:20 +0000 (+0000) Subject: correct bitfield ivar offset in ivar meta-data. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11894a4ad600a4919008b2693143cde395b9e9de;p=clang correct bitfield ivar offset in ivar meta-data. (objc abi specific). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66345 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index e48b6c0914..ece675f0c8 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1706,8 +1706,13 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, const RecordDecl *RD = GetFirstIvarInRecord(OID, ifield, pfield); for (RecordDecl::field_iterator e = RD->field_end(); ifield != e; ++ifield) { FieldDecl *Field = *ifield; - unsigned Offset = Layout->getElementOffset(CGM.getTypes(). - getLLVMFieldNo(Field)); + unsigned Offset; + if (Field->isBitField()) + // Bit field staring offset is cached in FieldInfo[Field]. + Offset = CGM.getTypes().getLLVMFieldNo(Field); + else + Offset = Layout->getElementOffset(CGM.getTypes(). + getLLVMFieldNo(Field)); if (Field->getIdentifier()) Ivar[0] = GetMethodVarName(Field->getIdentifier()); else @@ -2267,8 +2272,9 @@ llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const llvm::StructLayout *Layout = CGM.getTargetData().getStructLayout(cast(InterfaceLTy)); FieldDecl *Field = Interface->lookupFieldDeclForIvar(CGM.getContext(), Ivar); - uint64_t Offset = - Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); + uint64_t Offset = + Field->isBitField() ? CGM.getTypes().getLLVMFieldNo(Field) : + Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); return llvm::ConstantInt::get( CGM.getTypes().ConvertType(CGM.getContext().LongTy), @@ -3841,14 +3847,18 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { const llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(Field->getType()); unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy); - InstanceSize = Layout->getElementOffset( - CGM.getTypes().getLLVMFieldNo(Field)) + - Size; + uint64_t Offset = + Field->isBitField() ? CGM.getTypes().getLLVMFieldNo(Field) : + Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); + InstanceSize = Offset + Size; if (firstField == RD->field_end()) InstanceStart = InstanceSize; - else - InstanceStart = Layout->getElementOffset(CGM.getTypes(). - getLLVMFieldNo(*firstField)); + else { + Field = *firstField; + InstanceStart = + Field->isBitField() ? CGM.getTypes().getLLVMFieldNo(Field) : + Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); + } } } CLASS_RO_GV = BuildClassRoTInitializer(flags, @@ -4150,8 +4160,13 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { FieldDecl *Field = *i; - unsigned long offset = Layout->getElementOffset(CGM.getTypes(). - getLLVMFieldNo(Field)); + unsigned long offset; + if (Field->isBitField()) + // Bit field starting offset is cached in FieldInfo[Field]. + offset = CGM.getTypes().getLLVMFieldNo(Field); + else + offset = Layout->getElementOffset(CGM.getTypes(). + getLLVMFieldNo(Field)); const ObjCIvarDecl *ivarDecl = *I++; Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), ivarDecl, offset); if (Field->getIdentifier()) diff --git a/test/CodeGenObjC/bitfield-ivar-metadata.m b/test/CodeGenObjC/bitfield-ivar-metadata.m new file mode 100644 index 0000000000..c73fa6717f --- /dev/null +++ b/test/CodeGenObjC/bitfield-ivar-metadata.m @@ -0,0 +1,15 @@ +// RUN: clang -fnext-runtime -emit-llvm -o %t %s + +@interface INTF +{ + unsigned ivar1; + unsigned ivar2; + unsigned char BDIVAR3:1; + unsigned char BDIVAR4:1; +} +@end + +@implementation INTF +@end + +