Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -322,6 +322,12 @@ const DWARFDebugInfoEntry *die, const lldb::addr_t func_low_pc); + lldb::VariableSP ParseGlobalVariableDIE( + const lldb_private::SymbolContext& sc, + DWARFCompileUnit* dwarf_cu, + const DWARFDebugInfoEntry *die, + const lldb::addr_t func_low_pc); + size_t ParseVariables( const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -7386,7 +7386,7 @@ die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu); if (die) { - VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS)); + VariableSP var_sp (ParseGlobalVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS)); if (var_sp) { variables->AddVariableIfUnique (var_sp); @@ -7410,6 +7410,31 @@ return 0; } +VariableSP +SymbolFileDWARF::ParseGlobalVariableDIE +( + const SymbolContext& sc, + DWARFCompileUnit* dwarf_cu, + const DWARFDebugInfoEntry *die, + const lldb::addr_t func_low_pc +) +{ + assert(sc.function == NULL); + assert(sc.comp_unit != NULL); + + VariableSP var_sp(ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); + + if (var_sp) + { + const DWARFDebugInfoEntry *parent_die = GetDeclContextDIEContainingDIE(dwarf_cu, die); + if (parent_die->Tag() != DW_TAG_class_type && parent_die->Tag() != DW_TAG_structure_type) + return var_sp; + else + return VariableSP(); + } + + return var_sp; +} VariableSP SymbolFileDWARF::ParseVariableDIE Index: test/lang/cpp/scope/Makefile =================================================================== --- /dev/null +++ test/lang/cpp/scope/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Index: test/lang/cpp/scope/TestCppScope.py =================================================================== --- /dev/null +++ test/lang/cpp/scope/TestCppScope.py @@ -0,0 +1,76 @@ +""" +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 + test_result = frame.EvaluateExpression("A::a") + self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 1111, "A::a = 1111") + + test_result = frame.EvaluateExpression("B::a") + self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 2222, "B::a = 2222") + + test_result = frame.EvaluateExpression("C::a") + self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 3333, "C::a = 3333") + + test_result = frame.EvaluateExpression("a") + self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 4444, "a = 4444") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Index: test/lang/cpp/scope/main.cpp =================================================================== --- /dev/null +++ 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; +}