Get the bit-field offset & size for ObjC ivars that are bitfields.

<rdar://problem/10535460> lldb expression evaluation doesn't handle bit fields in ObjC classes properly

llvm-svn: 146134
This commit is contained in:
Jim Ingham 2011-12-08 02:53:10 +00:00
parent 56d6fdf695
commit f80bc3f447
4 changed files with 41 additions and 5 deletions

View File

@ -3458,7 +3458,7 @@ ClangASTContext::GetChildClangTypeAtIndex
{
if (child_idx == idx)
{
const ObjCIvarDecl* ivar_decl = *ivar_pos;
ObjCIvarDecl* ivar_decl = *ivar_pos;
QualType ivar_qual_type(ivar_decl->getType());
@ -3487,12 +3487,26 @@ ClangASTContext::GetChildClangTypeAtIndex
}
}
// Setting this to UINT32_MAX to make sure we don't compute it twice...
bit_offset = UINT32_MAX;
if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
{
bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
child_byte_offset = bit_offset / 8;
}
// Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
// of a bitfield within its containing object. So regardless of where we get the byte
// offset from, we still need to get the bit offset for bitfields from the layout.
if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
{
if (bit_offset == UINT32_MAX)
bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
child_bitfield_bit_offset = bit_offset % 8;
}
return ivar_qual_type.getAsOpaquePtr();
}
++child_idx;

View File

@ -56,18 +56,34 @@ class TestObjCIvarOffsets(TestBase):
# Test the value object value for BaseClass->_backed_int
error = lldb.SBError()
mine_backed_int = mine.GetChildMemberWithName ("_backed_int")
self.assertTrue(mine_backed_int, "Found mine->backed_int local variable.")
backed_value = int (mine_backed_int.GetValue (), 0)
backed_value = mine_backed_int.GetValueAsSigned (error)
self.assertTrue (error.Success())
self.assertTrue (backed_value == 1111)
# Test the value object value for DerivedClass->_derived_backed_int
mine_derived_backed_int = mine.GetChildMemberWithName ("_derived_backed_int")
self.assertTrue(mine_derived_backed_int, "Found mine->derived_backed_int local variable.")
derived_backed_value = int (mine_derived_backed_int.GetValue (), 0)
derived_backed_value = mine_derived_backed_int.GetValueAsSigned (error)
self.assertTrue (error.Success())
self.assertTrue (derived_backed_value == 3333)
# Make sure we also get bit-field offsets correct:
mine_flag2 = mine.GetChildMemberWithName ("flag2")
self.assertTrue(mine_flag2, "Found mine->flag2 local variable.")
flag2_value = int (mine_flag2.GetValue (), 0)
self.assertTrue (flag2_value == 7)
# GetValueAsUnsigned fails for bit-fields:
# flag2_value = mine_flag2.GetValueAsUnsigned (error)
# self.assertTrue (error.Success())
# self.assertTrue (flag2_value == 7)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()

View File

@ -8,6 +8,8 @@ main ()
mine.unbacked_int = 2222;
mine.derived_backed_int = 3333;
mine.derived_unbacked_int = 4444;
mine->flag1 = 1;
mine->flag2 = 7;
return 0; // Set breakpoint here.
}

View File

@ -17,7 +17,11 @@
#if !__OBJC2__
int _derived_unbacked_int;
#endif
@public
uint32_t flag1 : 1;
uint32_t flag2 : 3;
}
@property int derived_backed_int;
@property int derived_unbacked_int;
@end