paulherman updated this revision to Diff 33345.
paulherman added a comment.

Add scope tree for variable searching


http://reviews.llvm.org/D12304

Files:
  include/lldb/Symbol/Block.h
  include/lldb/Symbol/CompileUnit.h
  include/lldb/Symbol/Function.h
  include/lldb/Symbol/Symbol.h
  include/lldb/Symbol/SymbolContextScope.h
  include/lldb/Symbol/VariableTree.h
  include/lldb/lldb-forward.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Symbol/Block.cpp
  source/Symbol/CMakeLists.txt
  source/Symbol/CompileUnit.cpp
  source/Symbol/Function.cpp
  source/Symbol/Symbol.cpp
  source/Symbol/VariableTree.cpp
  source/Target/StackFrame.cpp
  test/lang/cpp/nsimport/TestCppNsImport.py
  test/lang/cpp/nsimport/main.cpp

Index: test/lang/cpp/nsimport/main.cpp
===================================================================
--- test/lang/cpp/nsimport/main.cpp
+++ test/lang/cpp/nsimport/main.cpp
@@ -16,13 +16,32 @@
     }
 }
 
-using namespace N;
-using namespace Nested;
+namespace Global
+{
+    int global;
+}
+
+namespace Fun
+{
+    int fun_var;
+    int fun()
+    {
+        fun_var = 5;
+        return 0; // break 1
+    }
+}
+
+using namespace Global;
+
+int fun_var = 9;
 
 int main()
 {
+    using namespace N;
+    using namespace Nested;
     n = 1;
     anon = 2;
     nested = 3;
-    return 0; // break 0
+    global = 4;
+    return Fun::fun(); // break 0
 }
Index: test/lang/cpp/nsimport/TestCppNsImport.py
===================================================================
--- test/lang/cpp/nsimport/TestCppNsImport.py
+++ test/lang/cpp/nsimport/TestCppNsImport.py
@@ -45,6 +45,8 @@
         # Break on main function
         break_0 = target.BreakpointCreateBySourceRegex("// break 0", src_file_spec)
         self.assertTrue(break_0.IsValid() and break_0.GetNumLocations() >= 1, VALID_BREAKPOINT)
+        break_1 = target.BreakpointCreateBySourceRegex("// break 1", src_file_spec)
+        self.assertTrue(break_1.IsValid() and break_1.GetNumLocations() >= 1, VALID_BREAKPOINT)
 
         # Launch the process
         args = None
@@ -72,6 +74,26 @@
         test_result = frame.EvaluateExpression("anon")
         self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 2, "anon = 2")
 
+        test_result = frame.EvaluateExpression("global")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 4, "global = 4")
+
+        test_result = frame.EvaluateExpression("fun_var")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 9, "fun_var = 9")
+
+        # Continue to second breakpoint
+        process.Continue()
+
+        # 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 function inside namespace
+        test_result = frame.EvaluateExpression("fun_var")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 5, "fun_var = 5")
+        
 
 if __name__ == '__main__':
     import atexit
Index: source/Target/StackFrame.cpp
===================================================================
--- source/Target/StackFrame.cpp
+++ source/Target/StackFrame.cpp
@@ -25,6 +25,7 @@
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Symbol/SymbolContextScope.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Symbol/VariableTree.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -606,7 +607,6 @@
     return var_list_sp;
 }
 
-
 ValueObjectSP
 StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
                                                DynamicValueType use_dynamic,
@@ -628,13 +628,18 @@
         bool deref = false;
         bool address_of = false;
         ValueObjectSP valobj_sp;
-        const bool get_file_globals = true;
         // When looking up a variable for an expression, we need only consider the
         // variables that are in scope.
-        VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
-        VariableList *variable_list = var_list_sp.get();
         
-        if (variable_list)
+        VariableTreeSP vars;
+        if (m_sc.block)
+            vars = m_sc.block->GetVariables();
+        else if (m_sc.function)
+            vars = m_sc.function->GetVariables();
+        else if (m_sc.comp_unit)
+            vars = m_sc.comp_unit->GetVariables();
+        
+        if (vars)
         {
             // If first character is a '*', then show pointer contents
             const char *var_expr = var_expr_cstr;
@@ -659,7 +664,7 @@
             else
                 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
 
-            var_sp = variable_list->FindVariable(name_const_string, false);
+            var_sp = vars->FindVariable(name_const_string);
             
             bool synthetically_added_instance_object = false;
 
@@ -679,7 +684,7 @@
                 {
                     if (is_instance_method && method_object_name)
                     {
-                        var_sp = variable_list->FindVariable(method_object_name);
+                        var_sp = vars->FindVariable(method_object_name);
                         if (var_sp)
                         {
                             separator_idx = 0;
Index: source/Symbol/VariableTree.cpp
===================================================================
--- /dev/null
+++ source/Symbol/VariableTree.cpp
@@ -0,0 +1,165 @@
+//===-- VariableTree.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/VariableTree.h"
+#include <sstream>
+#include <unordered_map>
+
+using namespace lldb;
+using namespace lldb_private;
+
+VariableTree::VariableTree(VariableListSP &variables, SymbolContextScope *scope) 
+    : m_variables(variables),
+    m_scope(scope),
+    m_parent_scope(scope != nullptr ? scope->GetParentSymbolContextScope() : nullptr),
+    m_imported_variables(new VariableList())
+{
+    if (!m_variables)
+        m_variables.reset(new VariableList());
+}
+
+VariableTree::VariableTree(VariableListSP &variables, SymbolContextScope *scope, VariableListSP &imported_variables)
+    : m_variables(variables),
+    m_scope(scope),
+    m_parent_scope(scope != nullptr ? scope->GetParentSymbolContextScope() : nullptr),
+    m_imported_variables(imported_variables)
+{
+    if (!m_variables)
+        m_variables.reset(new VariableList());
+    if (!m_imported_variables)
+        m_imported_variables.reset(new VariableList());
+}
+
+VariableTree::~VariableTree()
+{
+}
+
+bool
+VariableTree::AddVariable (const VariableSP &var)
+{
+    if (!m_variables->FindVariable(var->GetName()) && var->GetSymbolContextScope() == m_scope)
+    {
+        m_variables->AddVariable(var);
+        return true;
+    }
+    return false;
+}
+
+VariableTreeSP
+VariableTree::GetParent ()
+{
+    if (!m_parent && m_parent_scope != nullptr)
+        m_parent = m_parent_scope->GetVariables();
+    return m_parent;
+}
+
+size_t
+VariableTree::AddVariableList (const VariableListSP &vars)
+{
+    size_t added = 0;
+    for (size_t i = 0; i < vars->GetSize(); i++)
+        if (AddVariable(vars->GetVariableAtIndex(i)))
+            added++;
+    return added;
+}
+
+void
+VariableTree::Clear ()
+{
+    m_variables->Clear();
+}
+
+size_t
+VariableTree::GetSize ()
+{
+    return m_variables->GetSize();
+}
+
+VariableSP
+VariableTree::FindVariable (const ConstString &name)
+{
+    std::unordered_map<SymbolContextScope *, VariableListSP> imported_variables;
+    return FindRecVariable(name, imported_variables);
+}
+
+size_t
+VariableTree::AddImportedVariableList (const VariableListSP &imported_variables)
+{
+    if (!imported_variables)
+        return 0;
+
+    size_t added = 0;
+    for (size_t i = 0; i < imported_variables->GetSize(); i++)
+        if (m_imported_variables->AddVariableIfUnique(imported_variables->GetVariableAtIndex(i)))
+            added++;
+    return added;
+}
+
+VariableSP
+VariableTree::FindVariable (const ConstString &name, ValueType type)
+{
+    std::unordered_map<SymbolContextScope *, VariableListSP> imported_variables;
+    return FindRecVariable(name, type, imported_variables);
+}
+
+VariableSP
+VariableTree::FindRecVariable (const ConstString &name, std::unordered_map<SymbolContextScope *, VariableListSP> &imported_variables)
+{
+    for (size_t i = 0; i < m_imported_variables->GetSize(); i++)
+    {
+        VariableSP var = m_imported_variables->GetVariableAtIndex(i);
+        SymbolContextScope *scope = var->GetSymbolContextScope();
+
+        if (imported_variables.find(scope) == imported_variables.end())
+            imported_variables[scope] = VariableListSP(new VariableList());
+        imported_variables[scope]->AddVariable(var);
+    }
+
+    VariableSP node_result = m_variables->FindVariable(name, false);
+    VariableSP imported_result = imported_variables.find(m_scope) != imported_variables.end() ? imported_variables[m_scope]->FindVariable(name) : VariableSP();
+
+    VariableSP result;
+    if (imported_result)
+        result = imported_result;
+    else if (node_result)
+        result = node_result;
+
+    if (!result && GetParent())
+        result = GetParent()->FindRecVariable(name, imported_variables);
+
+    return result;
+}
+
+VariableSP
+VariableTree::FindRecVariable (const ConstString &name, ValueType type, std::unordered_map<SymbolContextScope *, VariableListSP> &imported_variables)
+{
+    for (size_t i = 0; i < m_imported_variables->GetSize(); i++)
+    {
+        VariableSP var = m_imported_variables->GetVariableAtIndex(i);
+        SymbolContextScope *scope = var->GetSymbolContextScope();
+
+        if (imported_variables.find(scope) == imported_variables.end())
+            imported_variables[scope] = VariableListSP(new VariableList());
+        imported_variables[scope]->AddVariable(var);
+    }
+    VariableSP node_result = m_variables->FindVariable(name, type, false);
+    VariableSP imported_result = imported_variables.find(m_scope) != imported_variables.end() ? imported_variables[m_scope]->FindVariable(name, type) : VariableSP();
+
+    VariableSP result;
+    if (imported_result)
+        result = imported_result;
+    else if (node_result)
+        result = node_result;
+
+    if (!result && GetParent())
+        result = GetParent()->FindRecVariable(name, imported_variables);
+    
+    return result;
+}
+
Index: source/Symbol/Symbol.cpp
===================================================================
--- source/Symbol/Symbol.cpp
+++ source/Symbol/Symbol.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/Symtab.h"
 #include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/VariableTree.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Symbol/SymbolVendor.h"
@@ -495,6 +496,25 @@
     return "<unknown SymbolType>";
 }
 
+SymbolContextScope *
+Symbol::GetParentSymbolContextScope ()
+{
+    SymbolContext sc;
+    CalculateSymbolContext(&sc);
+    return sc.module_sp.get();
+}
+
+VariableTreeSP
+Symbol::GetVariables ()
+{
+    if (!m_variable_tree_sp)
+    {
+        VariableListSP vars(new VariableList());
+        m_variable_tree_sp.reset(new VariableTree(vars, this));
+    }
+    return m_variable_tree_sp;
+}
+
 void
 Symbol::CalculateSymbolContext (SymbolContext *sc)
 {
Index: source/Symbol/Function.cpp
===================================================================
--- source/Symbol/Function.cpp
+++ source/Symbol/Function.cpp
@@ -17,6 +17,9 @@
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Symbol/VariableTree.h"
 #include "llvm/Support/Casting.h"
 
 using namespace lldb;
@@ -378,6 +381,22 @@
         m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX, show_context);
 }
 
+VariableTreeSP
+Function::GetVariables ()
+{
+    if (!m_variable_tree_sp)
+    {
+        VariableListSP vars(new VariableList());
+        m_variable_tree_sp.reset(new VariableTree(vars, this)); 
+    }
+    return m_variable_tree_sp;
+}
+
+SymbolContextScope *
+Function::GetParentSymbolContextScope ()
+{
+    return m_comp_unit;
+}
 
 void
 Function::CalculateSymbolContext(SymbolContext* sc)
Index: source/Symbol/CompileUnit.cpp
===================================================================
--- source/Symbol/CompileUnit.cpp
+++ source/Symbol/CompileUnit.cpp
@@ -12,6 +12,7 @@
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Symbol/VariableTree.h"
 #include "lldb/Target/LanguageRuntime.h"
 
 using namespace lldb;
@@ -57,6 +58,23 @@
 {
 }
 
+SymbolContextScope *
+CompileUnit::GetParentSymbolContextScope ()
+{
+    return GetModule().get();
+}
+
+VariableTreeSP
+CompileUnit::GetVariables ()
+{
+    if (!m_variable_tree_sp)
+    {
+        VariableListSP vars(GetVariableList(true));
+        m_variable_tree_sp.reset(new VariableTree(vars, this));
+    }
+    return m_variable_tree_sp;
+}
+
 void
 CompileUnit::CalculateSymbolContext(SymbolContext* sc)
 {
Index: source/Symbol/CMakeLists.txt
===================================================================
--- source/Symbol/CMakeLists.txt
+++ source/Symbol/CMakeLists.txt
@@ -29,5 +29,6 @@
   UnwindTable.cpp
   Variable.cpp
   VariableList.cpp
+  VariableTree.cpp
   VerifyDecl.cpp
   )
Index: source/Symbol/Block.cpp
===================================================================
--- source/Symbol/Block.cpp
+++ source/Symbol/Block.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Symbol/VariableTree.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -148,6 +149,34 @@
     return matching_block;
 }
 
+SymbolContextScope *
+Block::GetParentSymbolContextScope ()
+{
+    SymbolContext sc;
+    CalculateSymbolContext(&sc);
+    if (m_parent_scope != nullptr)
+        return m_parent_scope;
+    else if (sc.function != nullptr)
+        return sc.function;
+    else if (sc.comp_unit != nullptr)
+        return (SymbolContextScope *)sc.comp_unit;
+    else if (sc.module_sp)
+        return sc.module_sp.get();
+    else
+        return nullptr;
+}
+
+VariableTreeSP
+Block::GetVariables ()
+{
+    if (!m_variable_tree_sp)
+    {
+        VariableListSP vars(GetBlockVariableList(true));
+        m_variable_tree_sp.reset(new VariableTree(vars, this)); 
+    }
+    return m_variable_tree_sp;
+}
+
 void
 Block::CalculateSymbolContext (SymbolContext* sc)
 {
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -396,6 +396,12 @@
                     bool parse_siblings,
                     bool parse_children,
                     lldb_private::VariableList* cc_variable_list = NULL);
+    
+    void
+    ParseImportedNamespace (                                                                                             
+        const lldb_private::SymbolContext &sc,                                                                           
+        const DWARFDIE die,                                                                                  
+        const lldb::addr_t func_low_pc);
 
     bool
     ClassOrStructIsVirtual (const DWARFDIE &die);
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -53,6 +53,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Symbol/VariableTree.h"
 
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/CPPLanguageRuntime.h"
@@ -3651,6 +3652,18 @@
             
                 // Let all blocks know they have parse all their variables
                 sc.function->GetBlock (false).SetDidParseVariables (true, true);
+
+                DWARFDIE context_parent_die = GetDeclContextDIEContainingDIE(function_die);
+                if (context_parent_die && context_parent_die.Tag() == DW_TAG_namespace)
+                    sc.comp_unit->GetVariableList(true);
+                while (context_parent_die && context_parent_die.Tag() == DW_TAG_namespace)
+                {
+                    VariableListSP imported_variables(new VariableList());
+                    ParseVariables(sc, context_parent_die.GetFirstChild(), func_lo_pc, true, false, imported_variables.get());
+                    sc.function->GetVariables()->AddImportedVariableList(imported_variables);
+
+                    context_parent_die = GetDeclContextDIEContainingDIE(context_parent_die);
+                }
                 return num_variables;
             }
         }
@@ -3722,13 +3735,64 @@
 
                     }
                 }
+                if (DWARFDIE cu_die = dwarf_cu->GetDIE(dwarf_cu->GetFirstDIEOffset()))
+                    for (auto d = cu_die.GetFirstChild(); d; d = d.GetSibling())
+                        ParseImportedNamespace(sc, d, LLDB_INVALID_ADDRESS);
             }
             return vars_added;
         }
     }
     return 0;
 }
 
+void
+SymbolFileDWARF::ParseImportedNamespace
+(
+    const SymbolContext &sc,
+    const DWARFDIE die,
+    const lldb::addr_t func_low_pc
+)
+{
+    if (die.Tag() == DW_TAG_imported_declaration || die.Tag() == DW_TAG_imported_module)
+    {
+        dw_offset_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
+        if (UserIDMatches(imported_uid))
+        {
+            DWARFDebugInfo* debug_info = DebugInfo();
+            if (debug_info)
+            {
+                const DWARFDIE imported_die = debug_info->GetDIE(imported_uid);
+
+                if (imported_die)
+                {
+                    sc.comp_unit->GetVariableList(true);
+                    VariableListSP imported_variables(new VariableList());
+
+                    if (imported_die.Tag() == DW_TAG_variable)
+                    {
+                        VariableSP var = ParseVariableDIE(sc, imported_die, func_low_pc);
+                        if (var)
+                            imported_variables->AddVariable(var);
+                    }
+                    else if (imported_die.Tag() == DW_TAG_namespace)
+                        ParseVariables(sc, imported_die.GetFirstChild(), func_low_pc, true, false, imported_variables.get());
+
+                    SymbolContextScope *scope = nullptr;
+                    if (sc.block != nullptr)
+                        scope = sc.block;
+                    else if (sc.function != nullptr)
+                        scope = sc.function;
+                    else if (sc.comp_unit != nullptr)
+                        scope = sc.comp_unit;
+                    if (scope != nullptr)
+                        scope->GetVariables()->AddImportedVariableList(imported_variables);
+                }
+            }
+        }
+    }
+
+}
+
 VariableSP
 SymbolFileDWARF::ParseVariableDIE
 (
@@ -3754,6 +3818,7 @@
     {
         DWARFAttributes attributes;
         const size_t num_attributes = die.GetAttributes(attributes);
+        DWARFDIE spec_die;
         if (num_attributes > 0)
         {
             const char *name = NULL;
@@ -3878,6 +3943,17 @@
 
                     case DW_AT_artificial:      is_artificial = form_value.Boolean(); break;
                     case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+                    case DW_AT_specification:
+                    {
+                        dw_offset_t spec_uid = form_value.Reference();
+                        if (UserIDMatches(spec_uid))
+                        {
+                            DWARFDebugInfo* debug_info = DebugInfo();
+                            if (debug_info)
+                                spec_die = debug_info->GetDIE(spec_uid);
+                        }
+                        break;
+                    }
                     case DW_AT_declaration:
                     case DW_AT_description:
                     case DW_AT_endianity:
@@ -3887,15 +3963,14 @@
                     default:
                     case DW_AT_abstract_origin:
                     case DW_AT_sibling:
-                    case DW_AT_specification:
                         break;
                     }
                 }
             }
 
             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_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_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type || (parent_context_die.Tag() == DW_TAG_namespace && parent_context_die.GetAttributeValueAsString(DW_AT_name, nullptr) != nullptr));
 
             ValueType scope = eValueTypeInvalid;
 
@@ -4091,6 +4166,8 @@
         // (missing location due to optimization, etc)) so we don't re-parse
         // this DIE over and over later...
         m_die_to_variable_sp[die.GetDIE()] = var_sp;
+        if (spec_die)
+            m_die_to_variable_sp[spec_die.GetDIE()] = var_sp;
     }
     return var_sp;
 }
@@ -4254,7 +4331,9 @@
                     }
                 }
             }
-        }
+            else if (tag == DW_TAG_imported_module || tag == DW_TAG_imported_declaration)
+                ParseImportedNamespace(sc, die, func_low_pc);
+        } 
 
         bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
 
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -277,6 +277,7 @@
 class   ValueObjectPrinter;
 class   Variable;
 class   VariableList;
+class   VariableTree;
 class   Watchpoint;
 class   WatchpointList;
 class   WatchpointOptions;
@@ -435,6 +436,7 @@
     typedef std::shared_ptr<lldb_private::ValueList> ValueListSP;
     typedef std::shared_ptr<lldb_private::Variable> VariableSP;
     typedef std::shared_ptr<lldb_private::VariableList> VariableListSP;
+    typedef std::shared_ptr<lldb_private::VariableTree> VariableTreeSP;
     typedef std::shared_ptr<lldb_private::ValueObjectList> ValueObjectListSP;
     typedef std::shared_ptr<lldb_private::Watchpoint> WatchpointSP;
 
Index: include/lldb/Symbol/VariableTree.h
===================================================================
--- /dev/null
+++ include/lldb/Symbol/VariableTree.h
@@ -0,0 +1,69 @@
+//===-- VariableTree.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_VariableTree_h_
+#define liblldb_VariableTree_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Variable.h"
+#include "lldb/Symbol/VariableList.h"
+#include <unordered_map>
+
+namespace lldb_private {
+
+class VariableTree : public std::enable_shared_from_this<VariableTree>
+{
+public:
+    VariableTree (lldb::VariableListSP &variables, SymbolContextScope *scope);
+
+    VariableTree (lldb::VariableListSP &variables, SymbolContextScope *scope, lldb::VariableListSP &imported_variables);
+    
+    ~VariableTree ();
+
+    bool
+    AddVariable (const lldb::VariableSP &var);
+
+    size_t
+    AddVariableList (const lldb::VariableListSP &vars);
+
+    size_t
+    AddImportedVariableList (const lldb::VariableListSP &imported_variables);
+
+    void
+    Clear ();
+
+    lldb::VariableSP
+    FindVariable (const ConstString &name);
+
+    lldb::VariableSP
+    FindVariable (const ConstString &name, lldb::ValueType type);
+
+    lldb::VariableTreeSP
+    GetParent ();
+
+    size_t
+    GetSize ();
+
+private:
+    lldb::VariableSP
+    FindRecVariable (const ConstString &name, std::unordered_map<SymbolContextScope *, lldb::VariableListSP> &imported_variables);
+
+    lldb::VariableSP
+    FindRecVariable (const ConstString &name, lldb::ValueType type, std::unordered_map<SymbolContextScope *, lldb::VariableListSP> &imported_variables);
+
+    lldb::VariableTreeSP m_parent;
+    lldb::VariableListSP m_variables;
+    SymbolContextScope *m_scope, *m_parent_scope;
+    lldb::VariableListSP m_imported_variables;
+};
+
+}
+
+#endif // liblldb_VariableTree_h_
Index: include/lldb/Symbol/SymbolContextScope.h
===================================================================
--- include/lldb/Symbol/SymbolContextScope.h
+++ include/lldb/Symbol/SymbolContextScope.h
@@ -118,6 +118,18 @@
         return NULL;
     }
 
+    virtual lldb::VariableTreeSP
+    GetVariables ()
+    {
+        return NULL;
+    }
+
+    virtual SymbolContextScope *
+    GetParentSymbolContextScope ()
+    {
+        return NULL;
+    }
+
     //------------------------------------------------------------------
     /// Dump the object's symbol context to the stream \a s.
     ///
Index: include/lldb/Symbol/Symbol.h
===================================================================
--- include/lldb/Symbol/Symbol.h
+++ include/lldb/Symbol/Symbol.h
@@ -354,6 +354,12 @@
     ///
     /// @see SymbolContextScope
     //------------------------------------------------------------------
+    virtual lldb::VariableTreeSP
+    GetVariables ();
+
+    virtual SymbolContextScope *
+    GetParentSymbolContextScope ();
+
     virtual void
     CalculateSymbolContext (SymbolContext *sc);
 
@@ -407,6 +413,7 @@
     Mangled         m_mangled;              // uniqued symbol name/mangled name pair
     AddressRange    m_addr_range;           // Contains the value, or the section offset address when the value is an address in a section, and the size (if any)
     uint32_t        m_flags;                // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these
+    lldb::VariableTreeSP m_variable_tree_sp;
 };
 
 } // namespace lldb_private
Index: include/lldb/Symbol/Function.h
===================================================================
--- include/lldb/Symbol/Function.h
+++ include/lldb/Symbol/Function.h
@@ -422,6 +422,12 @@
     ///
     /// @see SymbolContextScope
     //------------------------------------------------------------------
+    virtual SymbolContextScope *
+    GetParentSymbolContextScope ();
+
+    virtual lldb::VariableTreeSP
+    GetVariables ();
+
     virtual void
     CalculateSymbolContext(SymbolContext* sc);
 
@@ -666,6 +672,7 @@
     DWARFExpression m_frame_base;   ///< The frame base expression for variables that are relative to the frame pointer.
     Flags m_flags;
     uint32_t m_prologue_byte_size;  ///< Compute the prologue size once and cache it
+    lldb::VariableTreeSP m_variable_tree_sp;
 private:
     DISALLOW_COPY_AND_ASSIGN(Function);
 };
Index: include/lldb/Symbol/CompileUnit.h
===================================================================
--- include/lldb/Symbol/CompileUnit.h
+++ include/lldb/Symbol/CompileUnit.h
@@ -131,6 +131,12 @@
     ///
     /// @see SymbolContextScope
     //------------------------------------------------------------------
+    virtual lldb::VariableTreeSP
+    GetVariables ();
+
+    virtual SymbolContextScope *
+    GetParentSymbolContextScope ();
+
     virtual void
     CalculateSymbolContext(SymbolContext* sc);
 
@@ -440,6 +446,7 @@
     std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand.
     lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand.
     bool       m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization.
+    lldb::VariableTreeSP m_variable_tree_sp;
 
 private:
     enum
Index: include/lldb/Symbol/Block.h
===================================================================
--- include/lldb/Symbol/Block.h
+++ include/lldb/Symbol/Block.h
@@ -110,6 +110,12 @@
     ///
     /// @see SymbolContextScope
     //------------------------------------------------------------------
+    virtual SymbolContextScope *
+    GetParentSymbolContextScope ();
+
+    virtual lldb::VariableTreeSP
+    GetVariables ();
+
     virtual void
     CalculateSymbolContext(SymbolContext* sc);
 
@@ -478,6 +484,7 @@
     RangeList m_ranges;
     lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
     lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and parameter variables scoped to this block.
+    lldb::VariableTreeSP m_variable_tree_sp;
     bool m_parsed_block_info:1,         ///< Set to true if this block and it's children have all been parsed
          m_parsed_block_variables:1,
          m_parsed_child_blocks:1;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to