werat created this revision.
Herald added subscribers: lldb-commits, arphaman.
Herald added a project: LLDB.
werat requested review of this revision.
Herald added a subscriber: JDevlieghere.
Static const/constexpr members might have only DW_TAG_member entry with a
DW_AT_const_value attribute. Since there is no corresponding DW_TAG_variable
entry, these values are currently not indexed in the DWARF index and are not
available via SBTarget::FindGlobalVariables() API.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D92223
Files:
lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/test/API/python_api/target/globals/Makefile
lldb/test/API/python_api/target/globals/TestTargetGlobals.py
lldb/test/API/python_api/target/globals/main.cpp
Index: lldb/test/API/python_api/target/globals/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/target/globals/main.cpp
@@ -0,0 +1,15 @@
+struct Foo {
+ static constexpr int static_constexpr_int = 1;
+ static constexpr unsigned int static_constexpr_uint =
+ static_constexpr_int + 1;
+ static const int static_const_out_out_class;
+};
+
+const int Foo::static_const_out_out_class = 3;
+
+char global_var_of_char_type = 'X';
+
+int main() {
+ // Set a break at entry to main.
+ return 0;
+}
Index: lldb/test/API/python_api/target/globals/TestTargetGlobals.py
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/target/globals/TestTargetGlobals.py
@@ -0,0 +1,68 @@
+"""
+Test SBTarget::FindGlobalVariables API.
+"""
+
+from __future__ import print_function
+
+import unittest2
+import os
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TargetAPITestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to of function 'main'.
+ self.line = line_number("main.cpp", "// Set a break at entry to main.")
+
+ @add_test_categories(['pyapi'])
+ def test_find_global_variables(self):
+ """Exercise SBTarget.FindGlobalVariables() API."""
+ self.build()
+ self.setTearDownCleanup()
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(self.getBuildArtifact())
+ self.assertTrue(target, VALID_TARGET)
+
+ # Create the breakpoint inside function 'main'.
+ breakpoint = target.BreakpointCreateByLocation('main.cpp', self.line)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(
+ None, None, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+ # Make sure we hit our breakpoint:
+ thread = lldbutil.get_one_thread_stopped_at_breakpoint(
+ process, breakpoint)
+ self.assertTrue(thread, "Thread is valid")
+
+ def test_global_var(query, name, type_name, value):
+ value_list = target.FindGlobalVariables(query, 1)
+ self.assertEqual(value_list.GetSize(), 1)
+ var = value_list.GetValueAtIndex(0)
+ self.DebugSBValue(var)
+ self.assertTrue(var)
+ self.assertEqual(var.GetName(), name)
+ self.assertEqual(var.GetTypeName(), type_name)
+ self.assertEqual(var.GetValue(), value)
+
+ test_global_var(
+ "Foo::static_constexpr_int",
+ "Foo::static_constexpr_int", "const int", "1")
+ test_global_var(
+ "Foo::static_constexpr_uint",
+ "Foo::static_constexpr_uint", "const unsigned int", "2")
+ test_global_var(
+ "Foo::static_const_out_out_class",
+ "Foo::static_const_out_out_class", "const int", "3")
+ test_global_var(
+ "global_var_of_char_type",
+ "::global_var_of_char_type", "char", "'X'")
Index: lldb/test/API/python_api/target/globals/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/target/globals/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2120,7 +2120,8 @@
sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
- if (die.Tag() != DW_TAG_variable)
+ // Look only for variables and members with static const data.
+ if (die.Tag() != DW_TAG_variable && die.Tag() != DW_TAG_member)
return true;
auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
@@ -3103,7 +3104,7 @@
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;
@@ -3177,6 +3178,12 @@
}
}
+ if (tag == DW_TAG_member && !const_value_form.IsValid()) {
+ // Allows only members with DW_AT_const_value attribute, i.e. static const
+ // or static constexr.
+ return nullptr;
+ }
+
// Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
// for static constexpr member variables -- DW_AT_const_value will be
// present in the class declaration and DW_AT_location in the DIE defining
@@ -3236,10 +3243,11 @@
const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
const dw_tag_t parent_tag = die.GetParent().Tag();
- bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
- parent_tag == DW_TAG_partial_unit) &&
- (parent_context_die.Tag() == DW_TAG_class_type ||
- parent_context_die.Tag() == DW_TAG_structure_type);
+ bool is_static_member =
+ (parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit ||
+ tag == DW_TAG_member) &&
+ (parent_context_die.Tag() == DW_TAG_class_type ||
+ parent_context_die.Tag() == DW_TAG_structure_type);
ValueType scope = eValueTypeInvalid;
@@ -3259,7 +3267,7 @@
// able to generate a fully qualified name from the
// declaration context.
if ((parent_tag == DW_TAG_compile_unit ||
- parent_tag == DW_TAG_partial_unit) &&
+ parent_tag == DW_TAG_partial_unit || tag == DW_TAG_member) &&
Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
mangled =
GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
@@ -3367,7 +3375,8 @@
}
} else {
if (location_is_const_value_data &&
- die.GetDIE()->IsGlobalOrStaticScopeVariable())
+ (die.GetDIE()->IsGlobalOrStaticScopeVariable() ||
+ tag == DW_TAG_member))
scope = eValueTypeVariableStatic;
else {
scope = eValueTypeVariableLocal;
@@ -3506,6 +3515,7 @@
} else {
// We haven't already parsed it, lets do that now.
if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
+ (tag == DW_TAG_member) ||
(tag == DW_TAG_formal_parameter && sc.function)) {
if (variable_list_sp.get() == nullptr) {
DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -152,6 +152,7 @@
case DW_TAG_constant:
case DW_TAG_enumeration_type:
case DW_TAG_inlined_subroutine:
+ case DW_TAG_member:
case DW_TAG_namespace:
case DW_TAG_string_type:
case DW_TAG_structure_type:
@@ -303,8 +304,10 @@
set.namespaces.Insert(ConstString(name), ref);
break;
+ case DW_TAG_member:
case DW_TAG_variable:
- if (name && has_location_or_const_value && is_global_or_static_variable) {
+ if (name && has_location_or_const_value &&
+ (is_global_or_static_variable || tag == DW_TAG_member)) {
set.globals.Insert(ConstString(name), ref);
// Be sure to include variables by their mangled and demangled names if
// they have any since a variable can have a basename "i", a mangled
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits