[Lldb-commits] [lldb] 439b16e - [LLDB] Respect the DW_AT_alignment attribute. (#73307)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Nov 28 03:27:59 PST 2023
Author: Haojian Wu
Date: 2023-11-28T12:27:55+01:00
New Revision: 439b16e2b369a0e3d482597b2c6597ce187e65f9
URL: https://github.com/llvm/llvm-project/commit/439b16e2b369a0e3d482597b2c6597ce187e65f9
DIFF: https://github.com/llvm/llvm-project/commit/439b16e2b369a0e3d482597b2c6597ce187e65f9.diff
LOG: [LLDB] Respect the DW_AT_alignment attribute. (#73307)
Part of fixes for #72913.
clang emits `DW_AT_alignment` attribute, however LLDB didn't respect it,
resulting in incorrect RecordDecls built by lldb.
This only fixes non-inheritance cases. The inheritance case will be
handled in a follow-up patch.
Added:
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/test/API/lang/cpp/alignas_base_class/TestAlignAsBaseClass.py
lldb/test/API/lang/cpp/alignas_base_class/main.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index abe3c673e2cce69..4d7d27b64e4c7f2 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;
@@ -1921,17 +1925,21 @@ 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).
- if (attrs.byte_size) {
+ // 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);
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 +2278,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..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,4 +10,7 @@ struct D : B1, B2 {};
D d3g;
+struct alignas(8) EmptyClassAlign8 {
+} t;
+
int main() {}
More information about the lldb-commits
mailing list