Patch to re-implement ivar-list meta-data generation to fix

cases of unnamed ivar bitfields.

llvm-svn: 62429
This commit is contained in:
Fariborz Jahanian 2009-01-17 19:36:33 +00:00
parent 2269f405b0
commit 705c6d9cdd
2 changed files with 45 additions and 11 deletions

View 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));

View File

@ -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