kpdev42 updated this revision to Diff 511683.
kpdev42 edited the summary of this revision.
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/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/test/API/lang/cpp/no_unique_address/Makefile
lldb/test/API/lang/cpp/no_unique_address/TestNoUniqueAddress.py
lldb/test/API/lang/cpp/no_unique_address/main.cpp
Index: lldb/test/API/lang/cpp/no_unique_address/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/lang/cpp/no_unique_address/main.cpp
@@ -0,0 +1,67 @@
+struct C
+{
+ long c,d;
+};
+
+struct Q
+{
+ long h;
+};
+
+struct D
+{
+};
+
+struct B
+{
+ [[no_unique_address]] D x;
+};
+
+struct E
+{
+ [[no_unique_address]] D x;
+};
+
+struct Foo1 : B,E,C
+{
+ long a = 42,b = 52;
+} _f1;
+
+struct Foo2 : B,E
+{
+ long v = 42;
+} _f2;
+
+struct Foo3 : C,B,E
+{
+ long v = 42;
+} _f3;
+
+struct Foo4 : B,C,E,Q
+{
+ long v = 42;
+} _f4;
+
+struct Foo5 : B,C,E
+{
+ [[no_unique_address]] D x1;
+ [[no_unique_address]] D x2;
+ long v1 = 42;
+ [[no_unique_address]] D y1;
+ [[no_unique_address]] D y2;
+ long v2 = 52;
+ [[no_unique_address]] D z1;
+ [[no_unique_address]] D z2;
+} _f5;
+
+struct Foo6 : B,E
+{
+ long v1 = 42;
+ [[no_unique_address]] D y1;
+ [[no_unique_address]] D y2;
+ long v2 = 52;
+} _f6;
+
+int main() {
+ return 0; // Set breakpoint here.
+}
Index: lldb/test/API/lang/cpp/no_unique_address/TestNoUniqueAddress.py
===================================================================
--- /dev/null
+++ lldb/test/API/lang/cpp/no_unique_address/TestNoUniqueAddress.py
@@ -0,0 +1,28 @@
+"""
+Test that we correctly handle [[no_unique_address]] attribute.
+"""
+
+import lldb
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestInlineNamespace(TestBase):
+
+ def test(self):
+ self.build()
+
+ lldbutil.run_to_source_breakpoint(self,
+ "// Set breakpoint here.", lldb.SBFileSpec("main.cpp"))
+
+ self.expect_expr("_f1.a", result_type="long", result_value="42")
+ self.expect_expr("_f1.b", result_type="long", result_value="52")
+ self.expect_expr("_f2.v", result_type="long", result_value="42")
+ self.expect_expr("_f3.v", result_type="long", result_value="42")
+ self.expect_expr("_f4.v", result_type="long", result_value="42")
+ self.expect_expr("_f5.v1", result_type="long", result_value="42")
+ self.expect_expr("_f5.v2", result_type="long", result_value="52")
+ self.expect_expr("_f6.v1", result_type="long", result_value="42")
+ self.expect_expr("_f6.v2", result_type="long", result_value="52")
Index: lldb/test/API/lang/cpp/no_unique_address/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/lang/cpp/no_unique_address/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -223,6 +223,7 @@
uint64_t bit_size = 0;
uint64_t bit_offset = 0;
bool is_bitfield = false;
+ clang::FieldDecl *field_decl = nullptr;
FieldInfo() = default;
@@ -275,6 +276,10 @@
const ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
+ void FixupBaseClasses(
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
+ const lldb_private::ClangASTImporter::LayoutInfo &layout_info,
+ long byte_offset);
/// Parses a DW_TAG_inheritance DIE into a base/super class.
///
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1366,6 +1366,28 @@
return nullptr;
}
+void DWARFASTParserClang::FixupBaseClasses(
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
+ const ClangASTImporter::LayoutInfo &layout_info, long byte_offset) {
+ 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);
+ if (it_layout == layout_info.base_offsets.end())
+ continue;
+ // We found a normal base class, exit.
+ if (it_layout->second.getQuantity() < byte_offset)
+ break;
+ prev_base_decl->markEmpty();
+ for (auto *field : prev_base_decl->fields())
+ field->addAttr(clang::NoUniqueAddressAttr::Create(m_ast.getASTContext(),
+ clang::SourceRange()));
+ }
+}
+
void DWARFASTParserClang::ParseInheritance(
const DWARFDIE &die, const DWARFDIE &parent_die,
const CompilerType class_clang_type, const AccessType default_accessibility,
@@ -1460,8 +1482,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 +1496,18 @@
// 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.
+ FixupBaseClasses(base_classes, layout_info, member_byte_offset);
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(
@@ -2991,7 +3019,7 @@
attrs.bit_size);
m_ast.SetMetadataAsUserID(field_decl, die.GetID());
-
+ last_field_info.field_decl = field_decl;
layout_info.field_offsets.insert(
std::make_pair(field_decl, field_bit_offset));
}
@@ -3007,6 +3035,7 @@
return false;
FieldInfo last_field_info;
+ std::vector<FieldInfo> seen_fields;
ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
auto ts = class_clang_type.GetTypeSystem();
@@ -3025,6 +3054,21 @@
case DW_TAG_member:
ParseSingleMember(die, parent_die, class_clang_type,
default_accessibility, layout_info, last_field_info);
+ if (!last_field_info.field_decl)
+ break;
+ for (auto it = seen_fields.rbegin(); it != seen_fields.rend(); ++it) {
+ FieldInfo &fi = *it;
+ if (fi.field_decl->hasAttr<clang::NoUniqueAddressAttr>())
+ break;
+ if (fi.bit_offset >= last_field_info.bit_offset)
+ fi.field_decl->addAttr(clang::NoUniqueAddressAttr::Create(
+ ast->getASTContext(), clang::SourceRange()));
+ else
+ break;
+ }
+ FixupBaseClasses(base_classes, layout_info,
+ last_field_info.bit_offset / 8);
+ seen_fields.push_back(last_field_info);
break;
case DW_TAG_subprogram:
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits