diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2023-11-28 12:27:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-28 12:27:55 +0100 |
commit | 439b16e2b369a0e3d482597b2c6597ce187e65f9 (patch) | |
tree | 531309a2b4d339e565f447df87bee5b550311dc2 /lldb | |
parent | c66c15a76dc7b021c29479a54aa1785928e9d1bf (diff) | |
download | llvm-439b16e2b369a0e3d482597b2c6597ce187e65f9.zip llvm-439b16e2b369a0e3d482597b2c6597ce187e65f9.tar.gz llvm-439b16e2b369a0e3d482597b2c6597ce187e65f9.tar.bz2 |
[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.
Diffstat (limited to 'lldb')
4 files changed, 26 insertions, 7 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index abe3c67..4d7d27b 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 0247783..81b705a 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 c7a8898..7d97b0c 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 @@ class TestCase(TestBase): # 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 8dfced6..9d37554 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() {} |