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(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to