shafik created this revision. shafik added reviewers: teemperor, jingham, aprantl.
Currently expressions dealing with bit-fields in Objective-C objects is pretty broken. When generating debug-info for Objective-C bit-fields we don't generate offsets because the Objective-C runtime is supposed to handle generating the offsets for us. When we parse the DWARF we expect to always have valid bit offsets and if we don't we treat that as an error and stop adding bit-fields to the AST. Later on when we do a name lookup we don't find the `ObjCIvarDecl` in the `ObjCInterfaceDecl` in some cases since we never added it and then we don't go to the runtime to obtain the offset. This will fix how we handle bit-fields for the Objective-C case and add tests to verify this fix but also to documents areas that still don't work and will be addressed in follow-up PRs. https://reviews.llvm.org/D83433 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/test/API/lang/objc/bitfield_ivars/Makefile lldb/test/API/lang/objc/bitfield_ivars/TestBitfieldIvars.py lldb/test/API/lang/objc/bitfield_ivars/main.m
Index: lldb/test/API/lang/objc/bitfield_ivars/main.m =================================================================== --- lldb/test/API/lang/objc/bitfield_ivars/main.m +++ lldb/test/API/lang/objc/bitfield_ivars/main.m @@ -34,10 +34,31 @@ @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 } Index: lldb/test/API/lang/objc/bitfield_ivars/TestBitfieldIvars.py =================================================================== --- lldb/test/API/lang/objc/bitfield_ivars/TestBitfieldIvars.py +++ lldb/test/API/lang/objc/bitfield_ivars/TestBitfieldIvars.py @@ -1,12 +1,32 @@ -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__) + + 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") + + @expectedFailureAll() + def ExpressionOnObject(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']) Index: lldb/test/API/lang/objc/bitfield_ivars/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/objc/bitfield_ivars/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS = -framework Foundation + +include Makefile.rules Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2609,10 +2609,11 @@ } } - if ((this_field_info.bit_offset >= parent_bit_size) || - (last_field_info.IsBitfield() && - !last_field_info.NextBitfieldOffsetIsValid( - this_field_info.bit_offset))) { + if (class_language != eLanguageTypeObjC && + ((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 "
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits