[Lldb-commits] [lldb] 1361c19 - [lldb] Index static const members of classes, structs and unions as global variables in DWARF 4 and earlier (#111859)

via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 7 03:06:07 PST 2024


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();


        


More information about the lldb-commits mailing list