diff options
author | Michael Buch <michaelbuch12@gmail.com> | 2023-12-06 22:13:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-06 22:13:54 +0000 |
commit | 4db54e659763401dbf2e5b1f90e9a3391e311e50 (patch) | |
tree | 2fdfbc804792d08aba50b1a2ba4d4059c7ce361e /lldb | |
parent | c5a1732cf31c81ee9f12264b40eee60d49fd05dd (diff) | |
download | llvm-4db54e659763401dbf2e5b1f90e9a3391e311e50.zip llvm-4db54e659763401dbf2e5b1f90e9a3391e311e50.tar.gz llvm-4db54e659763401dbf2e5b1f90e9a3391e311e50.tar.bz2 |
[clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (#74580)
This commit reverts the changes in
https://github.com/llvm/llvm-project/pull/71780 and all of its follow-up
patches.
We got reports of the `.debug_names/.debug_gnu_pubnames/gdb_index/etc.`
sections growing by a non-trivial amount for some large projects. While
GCC emits definitions for static data member constants into the Names
index, they do so *only* for explicitly `constexpr` members. We were
indexing *all* constant-initialized const-static members, which is
likely where the significant size difference comes from. However, only
emitting explicitly `constexpr` variables into the index doesn't seem
like a good way forward, since from clang's perspective `const`-static
integrals are `constexpr` too, and that shouldn't be any different in
the debug-info component. Also, as new code moves to `constexpr` instead
of `const` static for constants, such solution would just delay the
growth of the Names index.
To prevent the size regression we revert to not emitting definitions for
static data-members that have no location.
To support access to such constants from LLDB we'll most likely have to
have to make LLDB find the constants by looking at the containing class
first.
Diffstat (limited to 'lldb')
3 files changed, 9 insertions, 86 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index c3b22f8..e3c6464 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -142,54 +142,6 @@ static bool ShouldIgnoreArtificialField(llvm::StringRef FieldName) { || FieldName.starts_with("_vptr."); } -std::optional<DWARFFormValue> -DWARFASTParserClang::FindConstantOnVariableDefinition(DWARFDIE die) { - assert(die.Tag() == DW_TAG_member || die.Tag() == DW_TAG_variable); - - auto *dwarf = die.GetDWARF(); - if (!dwarf) - return {}; - - ConstString name{die.GetName()}; - if (!name) - return {}; - - auto *CU = die.GetCU(); - if (!CU) - return {}; - - DWARFASTParser *dwarf_ast = dwarf->GetDWARFParser(*CU); - auto parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); - - // Make sure we populate the GetDieToVariable cache. - VariableList variables; - dwarf->FindGlobalVariables(name, parent_decl_ctx, UINT_MAX, variables); - - // The cache contains the variable definition whose DW_AT_specification - // points to our declaration DIE. Look up that definition using our - // declaration. - auto const &die_to_var = dwarf->GetDIEToVariable(); - auto it = die_to_var.find(die.GetDIE()); - if (it == die_to_var.end()) - return {}; - - auto var_sp = it->getSecond(); - assert(var_sp != nullptr); - - if (!var_sp->GetLocationIsConstantValueData()) - return {}; - - auto def = dwarf->GetDIE(var_sp->GetID()); - auto def_attrs = def.GetAttributes(); - DWARFFormValue form_value; - if (!def_attrs.ExtractFormValueAtIndex( - def_attrs.FindAttributeIndex(llvm::dwarf::DW_AT_const_value), - form_value)) - return {}; - - return form_value; -} - TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, const DWARFDIE &die, Log *log) { @@ -2916,23 +2868,11 @@ void DWARFASTParserClang::CreateStaticMemberVariable( bool unused; // TODO: Support float/double static members as well. - if (!ct.IsIntegerOrEnumerationType(unused)) + if (!ct.IsIntegerOrEnumerationType(unused) || !attrs.const_value_form) return; - auto maybe_const_form_value = attrs.const_value_form; - - // Newer versions of Clang don't emit the DW_AT_const_value - // on the declaration of an inline static data member. Instead - // it's attached to the definition DIE. If that's the case, - // try and fetch it. - if (!maybe_const_form_value) { - maybe_const_form_value = FindConstantOnVariableDefinition(die); - if (!maybe_const_form_value) - return; - } - llvm::Expected<llvm::APInt> const_value_or_err = - ExtractIntFromFormValue(ct, *maybe_const_form_value); + ExtractIntFromFormValue(ct, *attrs.const_value_form); if (!const_value_or_err) { LLDB_LOG_ERROR(log, const_value_or_err.takeError(), "Failed to add const value to variable {1}: {0}", diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 7b49541..3e28e54d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -413,17 +413,6 @@ private: lldb_private::CompilerType &class_clang_type, const lldb::AccessType default_accesibility, lldb_private::ClangASTImporter::LayoutInfo &layout_info); - - /// Tries to find the definition DW_TAG_variable DIE of the the specified - /// DW_TAG_member 'die'. If such definition exists, returns the - /// DW_AT_const_value of that definition if available. Returns std::nullopt - /// otherwise. - /// - /// In newer versions of clang, DW_AT_const_value attributes are not attached - /// to the declaration of a inline static data-member anymore, but rather on - /// its definition. This function is used to locate said constant. - std::optional<lldb_private::plugin::dwarf::DWARFFormValue> - FindConstantOnVariableDefinition(lldb_private::plugin::dwarf::DWARFDIE die); }; /// Parsed form of all attributes that are relevant for type reconstruction. diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py index e63a26f..e6325eb 100644 --- a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py +++ b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py @@ -102,12 +102,9 @@ class TestCase(TestBase): # it does not crash. self.expect("image lookup -t A") - # For debug-info produced by older versions of clang, dsymutil strips the - # debug info for classes that only have const static data members without - # definitions. - @expectedFailureAll( - debug_info=["dsym"], compiler=["clang"], compiler_version=["<", "18.0"] - ) + # dsymutil strips the debug info for classes that only have const static + # data members without locations. + @expectedFailureAll(debug_info=["dsym"]) def test_class_with_only_const_static(self): self.build() lldbutil.run_to_source_breakpoint( @@ -123,10 +120,9 @@ class TestCase(TestBase): self.assertEqual(varobj.type.name, expect_type) self.assertEqual(varobj.value, expect_val) - # For debug-info produced by older versions of clang, inline static data members - # wouldn't get indexed into the Names accelerator table preventing LLDB from finding - # them. - @expectedFailureAll(compiler=["clang"], compiler_version=["<", "18.0"]) + # clang doesn't emit static data members without locations into the Names + # table, preventing LLDB from finding them. + @expectedFailureAll() def test_inline_static_members(self): self.build() lldbutil.run_to_source_breakpoint( @@ -174,9 +170,7 @@ class TestCase(TestBase): "ClassWithEnumAlias::enum_alias_alias", result_value="scoped_enum_case1" ) - # With older versions of Clang, LLDB fails to evaluate classes with only - # constexpr members when dsymutil is enabled - @expectedFailureAll(compiler=["clang"], compiler_version=["<", "18.0"]) + @expectedFailureAll() def test_shadowed_static_inline_members(self): """Tests that the expression evaluator and SBAPI can both correctly determine the requested inline static variable |