From 10bc1a4e833c31d88c4724178f269e21ff1eab12 Mon Sep 17 00:00:00 2001 From: Paul Herman Date: Tue, 18 Aug 2015 22:46:57 +0000 Subject: [PATCH] Fix resolution conflict between global and class static variables in C++ llvm-svn: 245381 --- lldb/include/lldb/Symbol/Variable.h | 11 ++- lldb/include/lldb/Symbol/VariableList.h | 4 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 7 +- lldb/source/Symbol/Variable.cpp | 6 +- lldb/source/Symbol/VariableList.cpp | 18 ++-- lldb/source/Target/StackFrame.cpp | 2 +- lldb/test/lang/cpp/scope/Makefile | 5 ++ lldb/test/lang/cpp/scope/TestCppScope.py | 83 +++++++++++++++++++ lldb/test/lang/cpp/scope/main.cpp | 25 ++++++ 9 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 lldb/test/lang/cpp/scope/Makefile create mode 100644 lldb/test/lang/cpp/scope/TestCppScope.py create mode 100644 lldb/test/lang/cpp/scope/main.cpp diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 8d413cac3d7d..59b513c68c64 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -36,7 +36,8 @@ public: Declaration* decl, const DWARFExpression& location, bool external, - bool artificial); + bool artificial, + bool static_member = false); virtual ~Variable(); @@ -99,6 +100,11 @@ public: return m_artificial; } + bool IsStaticMember() const + { + return m_static_member; + } + DWARFExpression & LocationExpression() { @@ -171,7 +177,8 @@ protected: DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() uint8_t m_external:1, // Visible outside the containing compile unit? m_artificial:1, // Non-zero if the variable is not explicitly declared in source - m_loc_is_const_data:1; // The m_location expression contains the constant variable value data, not a DWARF location + m_loc_is_const_data:1, // The m_location expression contains the constant variable value data, not a DWARF location + m_static_member:1; // Non-zero if variable is static member of a class or struct. private: Variable(const Variable& rhs); Variable& operator=(const Variable& rhs); diff --git a/lldb/include/lldb/Symbol/VariableList.h b/lldb/include/lldb/Symbol/VariableList.h index 5f8f2a225650..1c1d5dfefb9e 100644 --- a/lldb/include/lldb/Symbol/VariableList.h +++ b/lldb/include/lldb/Symbol/VariableList.h @@ -48,10 +48,10 @@ public: RemoveVariableAtIndex (size_t idx); lldb::VariableSP - FindVariable (const ConstString& name); + FindVariable (const ConstString& name, bool include_static_members = true); lldb::VariableSP - FindVariable (const ConstString& name, lldb::ValueType value_type); + FindVariable (const ConstString& name, lldb::ValueType value_type, bool include_static_members = true); uint32_t FindVariableIndex (const lldb::VariableSP &var_sp); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 3e5a88550246..35095fcfccdb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3968,7 +3968,6 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) return 0; } - VariableSP SymbolFileDWARF::ParseVariableDIE ( @@ -4124,6 +4123,9 @@ SymbolFileDWARF::ParseVariableDIE } } + const DWARFDebugInfoEntry *parent_context_die = GetDeclContextDIEContainingDIE(dwarf_cu, die); + bool is_static_member = die->GetParent()->Tag() == DW_TAG_compile_unit && (parent_context_die->Tag() == DW_TAG_class_type || parent_context_die->Tag() == DW_TAG_structure_type); + ValueType scope = eValueTypeInvalid; const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); @@ -4301,7 +4303,8 @@ SymbolFileDWARF::ParseVariableDIE &decl, location, is_external, - is_artificial)); + is_artificial, + is_static_member)); var_sp->SetLocationIsConstantValueData (location_is_const_value_data); } diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index c2772cd3a217..88a6cd54b1b2 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -44,7 +44,8 @@ Variable::Variable Declaration* decl_ptr, const DWARFExpression& location, bool external, - bool artificial + bool artificial, + bool static_member ) : UserID(uid), m_name(name), @@ -55,7 +56,8 @@ Variable::Variable m_declaration(decl_ptr), m_location(location), m_external(external), - m_artificial(artificial) + m_artificial(artificial), + m_static_member(static_member) { } diff --git a/lldb/source/Symbol/VariableList.cpp b/lldb/source/Symbol/VariableList.cpp index 75eb8700c9ff..487c57194346 100644 --- a/lldb/source/Symbol/VariableList.cpp +++ b/lldb/source/Symbol/VariableList.cpp @@ -100,7 +100,7 @@ VariableList::FindVariableIndex (const VariableSP &var_sp) } VariableSP -VariableList::FindVariable(const ConstString& name) +VariableList::FindVariable(const ConstString& name, bool include_static_members) { VariableSP var_sp; iterator pos, end = m_variables.end(); @@ -108,15 +108,18 @@ VariableList::FindVariable(const ConstString& name) { if ((*pos)->NameMatches(name)) { - var_sp = (*pos); - break; + if (include_static_members || !(*pos)->IsStaticMember()) + { + var_sp = (*pos); + break; + } } } return var_sp; } VariableSP -VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type) +VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type, bool include_static_members) { VariableSP var_sp; iterator pos, end = m_variables.end(); @@ -124,8 +127,11 @@ VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type) { if ((*pos)->NameMatches(name) && (*pos)->GetScope() == value_type) { - var_sp = (*pos); - break; + if (include_static_members || !(*pos)->IsStaticMember()) + { + var_sp = (*pos); + break; + } } } return var_sp; diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 7c5b022dac7c..3e6703531e7b 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -659,7 +659,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, else name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); - var_sp = variable_list->FindVariable(name_const_string); + var_sp = variable_list->FindVariable(name_const_string, false); bool synthetically_added_instance_object = false; diff --git a/lldb/test/lang/cpp/scope/Makefile b/lldb/test/lang/cpp/scope/Makefile new file mode 100644 index 000000000000..314f1cb2f077 --- /dev/null +++ b/lldb/test/lang/cpp/scope/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/lang/cpp/scope/TestCppScope.py b/lldb/test/lang/cpp/scope/TestCppScope.py new file mode 100644 index 000000000000..13906f370e9d --- /dev/null +++ b/lldb/test/lang/cpp/scope/TestCppScope.py @@ -0,0 +1,83 @@ +""" +Test scopes in C++. +""" +import lldb +from lldbtest import * +import lldbutil + +class TestCppScopes(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @dsym_test + def test_with_dsym_and_run_command(self): + self.buildDsym() + self.check() + + @dwarf_test + def test_with_dwarf_and_run_command(self): + self.buildDwarf() + self.check() + + def setUp(self): + TestBase.setUp(self) + + def check(self): + # Get main source file + src_file = "main.cpp" + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + cwd = os.getcwd() + exe_file = "a.out" + exe_path = os.path.join(cwd, exe_file) + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + main_breakpoint = target.BreakpointCreateBySourceRegex("// break here", src_file_spec) + self.assertTrue(main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) + + # Launch the process + args = None + env = None + process = target.LaunchSimple(args, env, cwd) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + + # Get current fream of the thread at the breakpoint + frame = thread.GetSelectedFrame() + + # Test result for scopes of variables + + global_variables = frame.GetVariables(True, True, True, False) + global_variables_assert = { + 'A::a': 1111, + 'B::a': 2222, + 'C::a': 3333, + '::a': 4444, + 'a': 4444 + } + + self.assertTrue(global_variables.GetSize() == 4, "target variable returns all variables") + for variable in global_variables: + name = variable.GetName() + self.assertTrue(name in global_variables_assert, "target variable returns wrong variable " + name) + + for name in global_variables_assert: + value = frame.EvaluateExpression(name) + assert_value = global_variables_assert[name] + self.assertTrue(value.IsValid() and value.GetValueAsSigned() == assert_value, name + " = " + str(assert_value)) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/lang/cpp/scope/main.cpp b/lldb/test/lang/cpp/scope/main.cpp new file mode 100644 index 000000000000..da5d7ed529d1 --- /dev/null +++ b/lldb/test/lang/cpp/scope/main.cpp @@ -0,0 +1,25 @@ +class A { +public: + static int a; + int b; +}; + +class B { +public: + static int a; + int b; +}; + +struct C { + static int a; +}; + +int A::a = 1111; +int B::a = 2222; +int C::a = 3333; +int a = 4444; + +int main() // break here +{ + return 0; +}