forked from OSchip/llvm-project
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:
parent
56d6fdf695
commit
f80bc3f447
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue