diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-01-17 19:36:33 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-01-17 19:36:33 +0000 |
commit | f54b19497cb832da78700a6c86473231f35fba65 (patch) | |
tree | 551a737cac38ac6f394d0d106600a7fe2f433ac0 | |
parent | 3b4d5e955e819dd3a4bed37ea2e47d6e4cb05274 (diff) |
Patch to re-implement ivar-list meta-data generation to fix
cases of unnamed ivar bitfields.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62429 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 42 | ||||
-rw-r--r-- | test/CodeGenObjC/unname-bf-metadata.m | 14 |
2 files changed, 45 insertions, 11 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 0a8aa45b2d..447b3d0a46 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/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/test/CodeGenObjC/unname-bf-metadata.m b/test/CodeGenObjC/unname-bf-metadata.m new file mode 100644 index 0000000000..bac530eaf9 --- /dev/null +++ b/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 |