Author: Ilia Kuklin Date: 2024-11-07T16:06:03+05:00 New Revision: 1361c19c04d0b3d9156fe0c5393d158cf69c14e7
URL: https://github.com/llvm/llvm-project/commit/1361c19c04d0b3d9156fe0c5393d158cf69c14e7 DIFF: https://github.com/llvm/llvm-project/commit/1361c19c04d0b3d9156fe0c5393d158cf69c14e7.diff LOG: [lldb] Index static const members of classes, structs and unions as global variables in DWARF 4 and earlier (#111859) In DWARF 4 and earlier `static const` members of structs, classes and unions have an entry tag `DW_TAG_member`, and are also tagged as `DW_AT_declaration`, but otherwise follow the same rules as `DW_TAG_variable`. Added: Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py lldb/test/API/lang/cpp/const_static_integral_member/main.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 66d0bc4b90cb52..c0a2066f8239e5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -614,7 +614,7 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { } bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const { - if (Tag() != DW_TAG_variable) + if (Tag() != DW_TAG_variable && Tag() != DW_TAG_member) return false; const DWARFDebugInfoEntry *parent_die = GetParent(); while (parent_die != nullptr) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 887983de2e8516..1220e6115a2a95 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -222,6 +222,13 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, case DW_TAG_variable: break; + case DW_TAG_member: + // Only in DWARF 4 and earlier `static const` members of a struct, a class + // or a union have an entry tag `DW_TAG_member` + if (unit.GetVersion() >= 5) + continue; + break; + default: continue; } @@ -362,6 +369,18 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, set.namespaces.Insert(ConstString(name), ref); break; + case DW_TAG_member: { + // In DWARF 4 and earlier `static const` members of a struct, a class or a + // union have an entry tag `DW_TAG_member`, and are also tagged as + // `DW_AT_declaration`, but otherwise follow the same rules as + // `DW_TAG_variable`. + bool parent_is_class_type = false; + if (auto parent = die.GetParent()) + parent_is_class_type = DWARFDIE(&unit, parent).IsStructUnionOrClass(); + if (!parent_is_class_type || !is_declaration) + break; + [[fallthrough]]; + } case DW_TAG_variable: if (name && has_location_or_const_value && is_global_or_static_variable) { set.globals.Insert(ConstString(name), ref); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index f39189b6cead42..e19c490bf44d3f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2403,7 +2403,7 @@ void SymbolFileDWARF::FindGlobalVariables( sc.module_sp = m_objfile_sp->GetModule(); assert(sc.module_sp); - if (die.Tag() != DW_TAG_variable) + if (die.Tag() != DW_TAG_variable && die.Tag() != DW_TAG_member) return true; auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); @@ -3505,7 +3505,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, ModuleSP module = GetObjectFile()->GetModule(); if (tag != DW_TAG_variable && tag != DW_TAG_constant && - (tag != DW_TAG_formal_parameter || !sc.function)) + tag != DW_TAG_member && (tag != DW_TAG_formal_parameter || !sc.function)) return nullptr; DWARFAttributes attributes = die.GetAttributes(); @@ -3811,7 +3811,7 @@ void SymbolFileDWARF::ParseAndAppendGlobalVariable( return; dw_tag_t tag = die.Tag(); - if (tag != DW_TAG_variable && tag != DW_TAG_constant) + if (tag != DW_TAG_variable && tag != DW_TAG_constant && tag != DW_TAG_member) return; // Check to see if we have already parsed this variable or constant? 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 cdade2d335df0b..e3d004b38a1571 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 @@ -120,17 +120,15 @@ def check_global_var(self, name: str, expect_type, expect_val): self.assertEqual(varobj.type.name, expect_type) self.assertEqual(varobj.value, expect_val) - @expectedFailureAll(dwarf_version=["<", "5"]) - # On linux this passes due to the manual index - @expectedFailureDarwin(debug_info=no_match(["dsym"])) - def test_inline_static_members(self): - self.build() + def check_inline_static_members(self, flags): + self.build(dictionary={"CXXFLAGS_EXTRAS": flags}) lldbutil.run_to_source_breakpoint( self, "// break here", lldb.SBFileSpec("main.cpp") ) self.check_global_var("A::int_val", "const int", "1") self.check_global_var("A::int_val_with_address", "const int", "2") + self.check_global_var("A::inline_int_val", "const int", "3") self.check_global_var("A::bool_val", "const bool", "true") self.check_global_var("A::enum_val", "Enum", "enum_case2") self.check_global_var("A::enum_bool_val", "EnumBool", "enum_bool_case1") @@ -144,6 +142,16 @@ def test_inline_static_members(self): "ClassWithConstexprs::scoped_enum_val", "ScopedEnum", "scoped_enum_case2" ) + # On linux this passes due to the manual index + @expectedFailureDarwin(debug_info=no_match(["dsym"])) + def test_inline_static_members_dwarf5(self): + self.check_inline_static_members("-gdwarf-5") + + # On linux this passes due to the manual index + @expectedFailureDarwin(debug_info=no_match(["dsym"])) + def test_inline_static_members_dwarf4(self): + self.check_inline_static_members("-gdwarf-4") + # With older versions of Clang, LLDB fails to evaluate classes with only # constexpr members when dsymutil is enabled @expectedFailureAll( @@ -170,15 +178,12 @@ def test_class_with_only_constexpr_static(self): "ClassWithEnumAlias::enum_alias_alias", result_value="scoped_enum_case1" ) - @expectedFailureAll(dwarf_version=["<", "5"]) - # On linux this passes due to the manual index - @expectedFailureDarwin(debug_info=no_match(["dsym"])) - def test_shadowed_static_inline_members(self): + def check_shadowed_static_inline_members(self, flags): """Tests that the expression evaluator and SBAPI can both correctly determine the requested inline static variable in the presence of multiple variables of the same name.""" - self.build() + self.build(dictionary={"CXXFLAGS_EXTRAS": flags}) lldbutil.run_to_name_breakpoint(self, "bar") self.check_global_var("ns::Foo::mem", "const int", "10") @@ -188,6 +193,16 @@ def test_shadowed_static_inline_members(self): self.expect_expr("ns::Foo::mem", result_value="10") self.expect_expr("::Foo::mem", result_value="-29") + # On linux this passes due to the manual index + @expectedFailureDarwin(debug_info=no_match(["dsym"])) + def test_shadowed_static_inline_members_dwarf5(self): + self.check_shadowed_static_inline_members("-gdwarf-5") + + # On linux this passes due to the manual index + @expectedFailureDarwin(debug_info=no_match(["dsym"])) + def test_shadowed_static_inline_members_dwarf4(self): + self.check_shadowed_static_inline_members("-gdwarf-4") + @expectedFailureAll(bugnumber="target var doesn't honour global namespace") def test_shadowed_static_inline_members_xfail(self): self.build() diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp index fb0b49e2d7aad7..564a3643dd8fcd 100644 --- a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp +++ b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp @@ -29,6 +29,7 @@ enum class ScopedLongLongEnum : long long { struct A { const static int int_val = 1; const static int int_val_with_address = 2; + inline const static int inline_int_val = 3; const static bool bool_val = true; const static auto char_max = std::numeric_limits<char>::max(); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits