kpdev42 updated this revision to Diff 511362.
kpdev42 added a comment.
Address review comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D143347/new/
https://reviews.llvm.org/D143347
Files:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/test/API/types/TestEmptyBase.py
lldb/test/API/types/empty_base_type.cpp
Index: lldb/test/API/types/empty_base_type.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/types/empty_base_type.cpp
@@ -0,0 +1,29 @@
+struct C
+{
+ long c,d;
+};
+
+struct D
+{
+};
+
+struct B
+{
+ [[no_unique_address]] D x;
+};
+
+struct E
+{
+ [[no_unique_address]] D x;
+};
+
+
+struct A : B,E,C
+{
+ long a,b;
+} _a;
+
+
+int main() {
+ return _a.a; // Set breakpoint here.
+}
Index: lldb/test/API/types/TestEmptyBase.py
===================================================================
--- /dev/null
+++ lldb/test/API/types/TestEmptyBase.py
@@ -0,0 +1,42 @@
+"""
+Test that recursive types are handled correctly.
+"""
+
+
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class EmptyBaseTestCase(TestBase):
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ # Find the line number to break for main.c.
+ self.line = line_number('empty_base_type.cpp',
+ '// Set breakpoint here.')
+
+ self.sources = {
+ 'CXX_SOURCES': 'empty_base_type.cpp'}
+
+ def test(self):
+ """Test that recursive structs are displayed correctly."""
+ self.build(dictionary=self.sources)
+ self.setTearDownCleanup(dictionary=self.sources)
+ self.run_expr()
+
+ def run_expr(self):
+ self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line(
+ self,
+ "empty_base_type.cpp",
+ self.line,
+ num_expected_locations=-1,
+ loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.runCmd("expression _a")
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1460,8 +1460,6 @@
if (!result)
return;
- base_classes.push_back(std::move(result));
-
if (is_virtual) {
// Do not specify any offset for virtual inheritance. The DWARF
// produced by clang doesn't give us a constant offset, but gives
@@ -1476,10 +1474,33 @@
// be removed from LayoutRecordType() in the external
// AST source in clang.
} else {
+ // DWARF doesn't have any representation for [[no_unique_address]]
+ // attribute. Empty base classes with [[no_unique_address]] fields
+ // confuse lldb and prevent construction of object memory layout.
+ // To fix this we scan base classes in reverse order to determine
+ // overlapping offsets. Wnen found we consider such class as empty
+ // base with all fields having [[no_unique_address]] attribute.
+ for (auto it = base_classes.rbegin(); it != base_classes.rend(); ++it) {
+ clang::CXXRecordDecl *prev_base_decl =
+ (*it)->getType()->getAsCXXRecordDecl();
+ // We've already marked this class, exit.
+ if (prev_base_decl->isEmpty())
+ break;
+ auto it_layout = layout_info.base_offsets.find(prev_base_decl);
+ assert(it_layout != layout_info.base_offsets.end());
+ // We found a normal base class, exit.
+ if (it_layout->second.getQuantity() < member_byte_offset)
+ break;
+ prev_base_decl->markEmpty();
+ for (auto *field : prev_base_decl->fields())
+ field->addAttr(clang::NoUniqueAddressAttr::Create(
+ ast->getASTContext(), clang::SourceRange()));
+ }
layout_info.base_offsets.insert(std::make_pair(
ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),
clang::CharUnits::fromQuantity(member_byte_offset)));
}
+ base_classes.push_back(std::move(result));
}
TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits