paulherman created this revision.
paulherman added reviewers: clayborg, sivachandra, spyffe.
paulherman added a subscriber: lldb-commits.

Consider having a global variable 'a' and a static variable with the same name 
inside a class. This resolves the arbitrary choice when resolving the name 'a'.

http://reviews.llvm.org/D12044

Files:
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  test/lang/cpp/scope/Makefile
  test/lang/cpp/scope/TestCppScope.py
  test/lang/cpp/scope/main.cpp

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;
+}
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/Makefile
===================================================================
--- /dev/null
+++ test/lang/cpp/scope/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
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
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to