diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 8affb05d56a2..b6b99d2e9bcf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2675,11 +2675,6 @@ void DWARFASTParserClang::ParseSingleMember( // FIXME: Remove the workarounds below and make this const. MemberAttributes attrs(die, parent_die, module_sp); - // Skip artificial members such as vtable pointers. - // FIXME: This check should verify that this is indeed an artificial member - // we are supposed to ignore. - if (attrs.is_artificial) - return; const bool class_is_objc_object_or_interface = TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type); @@ -2845,6 +2840,17 @@ void DWARFASTParserClang::ParseSingleMember( last_field_info.SetIsBitfield(false); } + // Don't turn artificial members such as vtable pointers into real FieldDecls + // in our AST. Clang will re-create those articial members and they would + // otherwise just overlap in the layout with the FieldDecls we add here. + // This needs to be done after updating FieldInfo which keeps track of where + // field start/end so we don't later try to fill the the space of this + // artificial member with (unnamed bitfield) padding. + // FIXME: This check should verify that this is indeed an artificial member + // we are supposed to ignore. + if (attrs.is_artificial) + return; + if (!member_clang_type.IsCompleteType()) member_clang_type.GetCompleteType(); diff --git a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py index 4cdaf32ca065..956ae275b337 100644 --- a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py +++ b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py @@ -145,8 +145,6 @@ class CppBitfieldsTestCase(TestBase): self.expect_expr("base_with_vtable", result_children=base_with_vtable_children) self.expect_var_path("base_with_vtable", children=base_with_vtable_children) - # FIXME: These all crash due the vtable ptr. - @skipIf @no_debug_info_test def test_bitfield_behind_vtable_ptr(self): self.build() @@ -164,7 +162,7 @@ class CppBitfieldsTestCase(TestBase): # Test a class with a vtable ptr and unnamed bitfield directly after. with_vtable_and_unnamed_children = [ - ValueCheck(name="", type="unsigned int:4", value="0"), + ValueCheck(name="", type="int:4", value="0"), ValueCheck(name="b", type="unsigned int:4", value="0"), ValueCheck(name="c", type="unsigned int:4", value="5") ] diff --git a/lldb/test/API/lang/cpp/bitfields/main.cpp b/lldb/test/API/lang/cpp/bitfields/main.cpp index e40f1648ac83..eb9db7271aae 100644 --- a/lldb/test/API/lang/cpp/bitfields/main.cpp +++ b/lldb/test/API/lang/cpp/bitfields/main.cpp @@ -97,7 +97,7 @@ WithVTable with_vtable; struct WithVTableAndUnnamed { virtual ~WithVTableAndUnnamed() {} - unsigned a : 4; + unsigned : 4; unsigned b : 4; unsigned c : 4; }; @@ -146,7 +146,6 @@ int main(int argc, char const *argv[]) { with_vtable.b = 0; with_vtable.c = 5; - with_vtable_and_unnamed.a = 5; with_vtable_and_unnamed.b = 0; with_vtable_and_unnamed.c = 5;