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 | 705c6d9cdd035745a603bc49ae81b0e208122259 (patch) | |
| tree | 832b8cbcce57faea99f0e40c011a33032824b05a | |
| parent | 2269f405b0719191fdf8affbe0430082a30a26fd (diff) | |
| download | bcm5719-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.cpp | 42 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/unname-bf-metadata.m | 14 | 
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  | 

