[Lldb-commits] [lldb] [LLDB] Respect the DW_AT_alignment attribute. (PR #73307)

Nikita Popov via lldb-commits lldb-commits at lists.llvm.org
Tue Nov 28 00:58:46 PST 2023


https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/73307

>From 5fb8fd532fe767feb2d361f9552ff31ea7770663 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Fri, 24 Nov 2023 10:46:03 +0100
Subject: [PATCH 1/3] [LLDB] Respect the DW_AT_alignment attribute.

Part of fixes for #72913.

clang emits the DW_AT_alignment attribute, however LLDB didn't respect it,
resulting an incorrect the RecordDecl built by lldb.

This only fixes non-inheritance cases. The inheritance case
will be handled in a follow-up patch.
---
 .../Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 12 ++++++++++--
 .../Plugins/SymbolFile/DWARF/DWARFASTParserClang.h   |  1 +
 .../cpp/alignas_base_class/TestAlignAsBaseClass.py   |  4 ++++
 lldb/test/API/lang/cpp/alignas_base_class/main.cpp   |  2 ++
 4 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index abe3c673e2cce69..a55ca0bf0f0fc1a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -355,6 +355,10 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
       byte_size = form_value.Unsigned();
       break;
 
+    case DW_AT_alignment:
+      alignment = form_value.Unsigned();
+      break;
+
     case DW_AT_byte_stride:
       byte_stride = form_value.Unsigned();
       break;
@@ -1926,12 +1930,13 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
       // TypeSystemClang is always in C++ mode, but some compilers such as
       // GCC and Clang give empty structs a size of 0 in C mode (in contrast to
       // the size of 1 for empty structs that would be computed in C++ mode).
-      if (attrs.byte_size) {
+      if (attrs.byte_size || attrs.alignment) {
         clang::RecordDecl *record_decl =
             TypeSystemClang::GetAsRecordDecl(clang_type);
         if (record_decl) {
           ClangASTImporter::LayoutInfo layout;
-          layout.bit_size = *attrs.byte_size * 8;
+          layout.bit_size = attrs.byte_size.value_or(0) * 8;
+          layout.alignment = attrs.alignment.value_or(0) * 8;
           GetClangASTImporter().SetRecordLayout(record_decl, layout);
         }
       }
@@ -2270,6 +2275,9 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
     if (layout_info.bit_size == 0)
       layout_info.bit_size =
           die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+    if (layout_info.alignment == 0)
+      layout_info.alignment =
+          die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;
 
     clang::CXXRecordDecl *record_decl =
         m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 0247783217008e8..81b705a036189eb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -456,6 +456,7 @@ struct ParsedDWARFTypeAttributes {
   lldb_private::plugin::dwarf::DWARFFormValue type;
   lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
   std::optional<uint64_t> byte_size;
+  std::optional<uint64_t> alignment;
   size_t calling_convention = llvm::dwarf::DW_CC_normal;
   uint32_t bit_stride = 0;
   uint32_t byte_stride = 0;
diff --git a/lldb/test/API/lang/cpp/alignas_base_class/TestAlignAsBaseClass.py b/lldb/test/API/lang/cpp/alignas_base_class/TestAlignAsBaseClass.py
index c7a88987733e176..7d97b0c42b7e166 100644
--- a/lldb/test/API/lang/cpp/alignas_base_class/TestAlignAsBaseClass.py
+++ b/lldb/test/API/lang/cpp/alignas_base_class/TestAlignAsBaseClass.py
@@ -12,3 +12,7 @@ def test(self):
 
         # The offset of f2 should be 8 because of `alignas(8)`.
         self.expect_expr("(intptr_t)&d3g.f2 - (intptr_t)&d3g", result_value="8")
+
+        # Verify specified class alignments.
+        self.expect_expr("alignof(B2)", result_value="8")
+        self.expect_expr("alignof(EmptyClassAlign8)", result_value="8")
diff --git a/lldb/test/API/lang/cpp/alignas_base_class/main.cpp b/lldb/test/API/lang/cpp/alignas_base_class/main.cpp
index 8dfced6c784e102..cf727e808017bcc 100644
--- a/lldb/test/API/lang/cpp/alignas_base_class/main.cpp
+++ b/lldb/test/API/lang/cpp/alignas_base_class/main.cpp
@@ -10,4 +10,6 @@ struct D : B1, B2 {};
 
 D d3g;
 
+struct alignas(8) EmptyClassAlign8 {} t;
+
 int main() {}

>From fc488ecda9a0ab1a81d738b52b12ca88224346ea Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 28 Nov 2023 09:23:29 +0100
Subject: [PATCH 2/3] Update a stale comment.

---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp        | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a55ca0bf0f0fc1a..4d7d27b64e4c7f2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1925,11 +1925,14 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
             die.GetOffset(), attrs.name.GetCString());
       }
 
-      // If the byte size of the record is specified then overwrite the size
-      // that would be computed by Clang. This is only needed as LLDB's
-      // TypeSystemClang is always in C++ mode, but some compilers such as
-      // GCC and Clang give empty structs a size of 0 in C mode (in contrast to
-      // the size of 1 for empty structs that would be computed in C++ mode).
+      // Setting authority byte size and alignment for empty structures.
+      //
+      // If the byte size or alignmenet of the record is specified then
+      // overwrite the ones that would be computed by Clang.
+      // This is only needed as LLDB's TypeSystemClang is always in C++ mode,
+      // but some compilers such as GCC and Clang give empty structs a size of 0
+      // in C mode (in contrast to the size of 1 for empty structs that would be
+      // computed in C++ mode).
       if (attrs.byte_size || attrs.alignment) {
         clang::RecordDecl *record_decl =
             TypeSystemClang::GetAsRecordDecl(clang_type);

>From 9a8afb57b24becd7927e2184d47027b21fb18b08 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 28 Nov 2023 09:58:18 +0100
Subject: [PATCH 3/3] Make clang-format happy

---
 lldb/test/API/lang/cpp/alignas_base_class/main.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/test/API/lang/cpp/alignas_base_class/main.cpp b/lldb/test/API/lang/cpp/alignas_base_class/main.cpp
index cf727e808017bcc..9d37554957ba3fb 100644
--- a/lldb/test/API/lang/cpp/alignas_base_class/main.cpp
+++ b/lldb/test/API/lang/cpp/alignas_base_class/main.cpp
@@ -10,6 +10,7 @@ struct D : B1, B2 {};
 
 D d3g;
 
-struct alignas(8) EmptyClassAlign8 {} t;
+struct alignas(8) EmptyClassAlign8 {
+} t;
 
 int main() {}



More information about the lldb-commits mailing list