summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-01-17 19:36:33 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-01-17 19:36:33 +0000
commit705c6d9cdd035745a603bc49ae81b0e208122259 (patch)
tree832b8cbcce57faea99f0e40c011a33032824b05a
parent2269f405b0719191fdf8affbe0430082a30a26fd (diff)
downloadbcm5719-llvm-705c6d9cdd035745a603bc49ae81b0e208122259.tar.gz
bcm5719-llvm-705c6d9cdd035745a603bc49ae81b0e208122259.zip
Patch to re-implement ivar-list meta-data generation to fix
cases of unnamed ivar bitfields. llvm-svn: 62429
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp42
-rw-r--r--clang/test/CodeGenObjC/unname-bf-metadata.m14
2 files changed, 45 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 0a8aa45b2d7..447b3d0a460 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -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/clang/test/CodeGenObjC/unname-bf-metadata.m b/clang/test/CodeGenObjC/unname-bf-metadata.m
new file mode 100644
index 00000000000..bac530eaf94
--- /dev/null
+++ b/clang/test/CodeGenObjC/unname-bf-metadata.m
@@ -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
OpenPOWER on IntegriCloud