Skip to content

Commit 00c8120

Browse files
committed
[LLDB] Fix handling of bit-fields when there is a base class when parsing DWARF
When parsing DWARF and laying out bit-fields we currently don't take into account whether we have a base class or not. Currently if the first field is a bit-field but the bit offset is due a field we inherit from a base class we currently treat it as an unnamed bit-field and therefore add an extra field. This fix will not check if we have a base class and assume that this offset is due to members we are inheriting from the base. We are currently seeing asserts during codegen when debugging clang::DiagnosticOptions. This assumption will fail in the case where the first field in the derived class in an unnamed bit-field. Fixing the first field being an unnamed bit-field looks like it will require a larger change since we will need a way to track or discover the last field offset of the bases(s). Differential Revision: https://reviews.llvm.org/D76808
1 parent 853a1e6 commit 00c8120

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,9 +2668,19 @@ void DWARFASTParserClang::ParseSingleMember(
26682668
}
26692669

26702670
// If we have a gap between the last_field_end and the current
2671-
// field we have an unnamed bit-field
2671+
// field we have an unnamed bit-field.
2672+
// If we have a base class, we assume there is no unnamed
2673+
// bit-field if this is the first field since the gap can be
2674+
// attributed to the members from the base class. This assumption
2675+
// is not correct if the first field of the derived class is
2676+
// indeed an unnamed bit-field. We currently do not have the
2677+
// machinary to track the offset of the last field of classes we
2678+
// have seen before, so we are not handling this case.
26722679
if (this_field_info.bit_offset != last_field_end &&
2673-
!(this_field_info.bit_offset < last_field_end)) {
2680+
this_field_info.bit_offset > last_field_end &&
2681+
!(last_field_info.bit_offset == 0 &&
2682+
last_field_info.bit_size == 0 &&
2683+
layout_info.base_offsets.size() != 0)) {
26742684
unnamed_field_info = FieldInfo{};
26752685
unnamed_field_info->bit_size =
26762686
this_field_info.bit_offset - last_field_end;

lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,10 @@ def test_and_run_command(self):
103103
'(uint64_t:1) k = 1',
104104
])
105105

106+
self.expect(
107+
"frame variable --show-types derived",
108+
VARIABLES_DISPLAYED_CORRECTLY,
109+
substrs=[
110+
'(uint32_t) b_a = 2',
111+
'(uint32_t:1) d_a = 1',
112+
])

lldb/test/API/lang/cpp/bitfields/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ int main(int argc, char const *argv[]) {
6060
}
6161
} clang_example;
6262

63+
class B {
64+
public:
65+
uint32_t b_a;
66+
};
67+
68+
class D : public B {
69+
public:
70+
uint32_t d_a : 1;
71+
} derived;
72+
6373
lba.a = 2;
6474

6575
lbb.a = 1;
@@ -76,6 +86,8 @@ int main(int argc, char const *argv[]) {
7686
lbd.arr[2] = '\0';
7787
lbd.a = 5;
7888

89+
derived.b_a = 2;
90+
derived.d_a = 1;
7991

8092
return 0; // Set break point at this line.
8193
}

0 commit comments

Comments
 (0)