Skip to content

Commit

Permalink
[LLDB] Fix handling of bit-fields when there is a base class when par…
Browse files Browse the repository at this point in the history
…sing 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

(cherry picked from commit 00c8120)
  • Loading branch information
shafik committed Mar 30, 2020
1 parent 2fe2276 commit 4554055
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
14 changes: 12 additions & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Expand Up @@ -2720,9 +2720,19 @@ void DWARFASTParserClang::ParseSingleMember(
}

// If we have a gap between the last_field_end and the current
// field we have an unnamed bit-field
// field we have an unnamed bit-field.
// If we have a base class, we assume there is no unnamed
// bit-field if this is the first field since the gap can be
// attributed to the members from the base class. This assumption
// is not correct if the first field of the derived class is
// indeed an unnamed bit-field. We currently do not have the
// machinary to track the offset of the last field of classes we
// have seen before, so we are not handling this case.
if (this_field_info.bit_offset != last_field_end &&
!(this_field_info.bit_offset < last_field_end)) {
this_field_info.bit_offset > last_field_end &&
!(last_field_info.bit_offset == 0 &&
last_field_info.bit_size == 0 &&
layout_info.base_offsets.size() != 0)) {
unnamed_field_info = FieldInfo{};
unnamed_field_info->bit_size =
this_field_info.bit_offset - last_field_end;
Expand Down
7 changes: 7 additions & 0 deletions lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py
Expand Up @@ -103,3 +103,10 @@ def test_and_run_command(self):
'(uint64_t:1) k = 1',
])

self.expect(
"frame variable --show-types derived",
VARIABLES_DISPLAYED_CORRECTLY,
substrs=[
'(uint32_t) b_a = 2',
'(uint32_t:1) d_a = 1',
])
12 changes: 12 additions & 0 deletions lldb/test/API/lang/cpp/bitfields/main.cpp
Expand Up @@ -60,6 +60,16 @@ int main(int argc, char const *argv[]) {
}
} clang_example;

class B {
public:
uint32_t b_a;
};

class D : public B {
public:
uint32_t d_a : 1;
} derived;

lba.a = 2;

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

derived.b_a = 2;
derived.d_a = 1;

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

0 comments on commit 4554055

Please sign in to comment.