}
}
- if ((this_field_info.bit_offset >= parent_bit_size) ||
- (last_field_info.IsBitfield() &&
- !last_field_info.NextBitfieldOffsetIsValid(
- this_field_info.bit_offset))) {
+ // The ObjC runtime knows the byte offset but we still need to provide
+ // the bit-offset in the layout. It just means something different then
+ // what it does in C and C++. So we skip this check for ObjC types.
+ if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) &&
+ ((this_field_info.bit_offset >= parent_bit_size) ||
+ (last_field_info.IsBitfield() &&
+ !last_field_info.NextBitfieldOffsetIsValid(
+ this_field_info.bit_offset)))) {
ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
objfile->GetModule()->ReportWarning(
"0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
-from lldbsuite.test import lldbinline
-from lldbsuite.test import decorators
-
-lldbinline.MakeInlineTest(
- __file__,
- globals(),
- [
- # This is a Darwin-only failure related to incorrect expression-
- # evaluation for single-bit ObjC bitfields.
- decorators.skipUnlessDarwin,
- decorators.expectedFailureAll(
- bugnumber="rdar://problem/17990991")])
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBitfieldIvars(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+
+ @skipUnlessDarwin
+ def test(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.m"))
+
+ self.expect_expr("chb->hb->field1", result_type="unsigned int", result_value="0")
+
+ ## FIXME field2 should have a value of 1
+ self.expect("expr chb->hb->field2", matching=False, substrs = ["= 1"]) # this must happen second
+
+ self.expect_expr("hb2->field1", result_type="unsigned int", result_value="10")
+ self.expect_expr("hb2->field2", result_type="unsigned int", result_value="3")
+ self.expect_expr("hb2->field3", result_type="unsigned int", result_value="4")
+
+ self.expect("frame var *hb2", substrs = [ 'x =', '100',
+ 'field1 =', '10',
+ 'field2 =', '3',
+ 'field3 =', '4'])
+
+ @expectedFailureAll()
+ def testExprWholeObject(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.m"))
+
+ ## FIXME expression with individual bit-fields obtains correct values but not with the whole object
+ self.expect("expr *hb2", substrs = [ 'x =', '100',
+ 'field1 =', '10',
+ 'field2 =', '3',
+ 'field3 =', '4'])
@end
+@interface HasBitfield2 : NSObject {
+@public
+ unsigned int x;
+
+ unsigned field1 : 15;
+ unsigned field2 : 4;
+ unsigned field3 : 4;
+}
+@end
+
+@implementation HasBitfield2
+- (id)init {
+ return (self = [super init]);
+}
+@end
+
int main(int argc, const char * argv[]) {
ContainsAHasBitfield *chb = [[ContainsAHasBitfield alloc] init];
- printf("%d\n", chb->hb->field2); //% self.expect("expression -- chb->hb->field1", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["= 0"])
- //% self.expect("expression -- chb->hb->field2", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["= 1"]) # this must happen second
- return 0;
+ HasBitfield2 *hb2 = [[HasBitfield2 alloc] init];
+
+ hb2->x = 100;
+ hb2->field1 = 10;
+ hb2->field2 = 3;
+ hb2->field3 = 4;
+
+ return 0; // break here
}