]> granicus.if.org Git - clang/commitdiff
Patch to re-implement ivar-list meta-data generation to fix
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 17 Jan 2009 19:36:33 +0000 (19:36 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 17 Jan 2009 19:36:33 +0000 (19:36 +0000)
cases of unnamed ivar bitfields.

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

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

index 0a8aa45b2d71a30ec5fde213b190fe73d7bd5477..447b3d0a46012632ba07d8c45c8a54c5661314d4 100644 (file)
@@ -1295,6 +1295,21 @@ CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
   return GV;
 }
 
+/// countInheritedIvars - count number of ivars in class and its super class(s)
+///
+static int countInheritedIvars(const ObjCInterfaceDecl *OI) {
+  int count = 0;
+  if (!OI)
+    return 0;
+  const ObjCInterfaceDecl *SuperClass = OI->getSuperClass();
+  if (SuperClass)
+    count += countInheritedIvars(SuperClass);
+  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+       E = OI->ivar_end(); I != E; ++I)
+    ++count;
+  return count;
+}
+
 /*
   struct objc_ivar {
     char *ivar_name;
@@ -1322,18 +1337,23 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
 
   const llvm::StructLayout *Layout =
     CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
-  for (ObjCInterfaceDecl::ivar_iterator 
-         i = ID->getClassInterface()->ivar_begin(),
-         e = ID->getClassInterface()->ivar_end(); i != e; ++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(Field));
+  ObjCInterfaceDecl *OID = 
+    const_cast<ObjCInterfaceDecl *>(ID->getClassInterface());
+  int countSuperClassIvars = countInheritedIvars(OID->getSuperClass());
+  const RecordDecl *RD = CGM.getContext().addRecordToClass(OID);
+  RecordDecl::field_iterator ifield = RD->field_begin();
+  while (countSuperClassIvars-- > 0)
+    ++ifield;
+  for (RecordDecl::field_iterator e = RD->field_end(); ifield != e; ++ifield) {
+    FieldDecl *Field = *ifield;
+    unsigned Offset = Layout->getElementOffset(CGM.getTypes().
+                                               getLLVMFieldNo(Field));
+    if (Field->getIdentifier())
+      Ivar[0] = GetMethodVarName(Field->getIdentifier());
+    else
+      Ivar[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
     std::string TypeStr;
-    Ivar[0] = GetMethodVarName(V->getIdentifier());
-    CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, Field);
+    CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
     Ivar[1] = GetMethodVarType(TypeStr);
     Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
     Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
diff --git a/test/CodeGenObjC/unname-bf-metadata.m b/test/CodeGenObjC/unname-bf-metadata.m
new file mode 100644 (file)
index 0000000..bac530e
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: clang -fnext-runtime -emit-llvm -o %t %s
+// Test that meta-data for ivar lists with unnamed bitfield are generated.
+//
+@interface Foo {
+@private
+    int first;
+    int :1;
+    int third :1;
+    int :1;
+    int fifth :1;
+}
+@end
+@implementation Foo 
+@end