]> granicus.if.org Git - clang/commitdiff
correct bitfield ivar offset in ivar meta-data.
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 7 Mar 2009 19:43:20 +0000 (19:43 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 7 Mar 2009 19:43:20 +0000 (19:43 +0000)
(objc abi specific).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66345 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjCMac.cpp
test/CodeGenObjC/bitfield-ivar-metadata.m [new file with mode: 0644]

index e48b6c09142cbfd290169922f700e92d8cf95ae2..ece675f0c8ae73844d0ddf6bdb097779710ad10e 100644 (file)
@@ -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<llvm::StructType>(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 (file)
index 0000000..c73fa67
--- /dev/null
@@ -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
+
+