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; 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 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/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/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/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/VariableTree.h =================================================================== --- /dev/null +++ include/lldb/Symbol/VariableTree.h @@ -0,0 +1,59 @@ +//===-- 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 + +namespace lldb_private { + +class VariableTree : public std::enable_shared_from_this +{ +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 &imported_variables); + + lldb::VariableSP FindRecVariable(const ConstString &name, lldb::ValueType type, std::unordered_map &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/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 ValueListSP; typedef std::shared_ptr VariableSP; typedef std::shared_ptr VariableListSP; + typedef std::shared_ptr VariableTreeSP; typedef std::shared_ptr ValueObjectListSP; typedef std::shared_ptr WatchpointSP; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -268,6 +268,11 @@ DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, const lldb::addr_t func_low_pc); + void ParseImportedNamespace ( + 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, 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" @@ -3880,14 +3881,30 @@ return 0; const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); - + dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (func_lo_pc != LLDB_INVALID_ADDRESS) { const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); - + // Let all blocks know they have parse all their variables sc.function->GetBlock (false).SetDidParseVariables (true, true); + + const DWARFDebugInfoEntry *context_parent_die = GetDeclContextDIEContainingDIE(dwarf_cu, function_die); + if (context_parent_die != nullptr && context_parent_die->Tag() == DW_TAG_namespace) + sc.comp_unit->GetVariableList(true); + while (context_parent_die != nullptr && context_parent_die->Tag() == DW_TAG_namespace) + { + DWARFCompileUnitSP cu_sp; + VariableListSP imported_variables(new VariableList()); + ParseVariables(sc, dwarf_cu, func_lo_pc, context_parent_die->GetFirstChild(), true, false, imported_variables.get()); + if (sc.function != nullptr) + sc.function->GetVariables()->AddImportedVariableList(imported_variables); + else if (sc.comp_unit != nullptr) + sc.comp_unit->GetVariables()->AddImportedVariableList(imported_variables); + + context_parent_die = GetDeclContextDIEContainingDIE(dwarf_cu, context_parent_die); + } return num_variables; } } @@ -3961,6 +3978,9 @@ } } + if (DWARFDebugInfoEntry *cu_die = dwarf_cu->GetDIEPtr(dwarf_cu->GetFirstDIEOffset())) + for (auto d = cu_die->GetFirstChild(); d != nullptr; d = d->GetSibling()) + ParseImportedNamespace(sc, dwarf_cu, d, LLDB_INVALID_ADDRESS); } return vars_added; } @@ -3968,6 +3988,56 @@ return 0; } +void +SymbolFileDWARF::ParseImportedNamespace +( + const SymbolContext &sc, + DWARFCompileUnit *dwarf_cu, + const DWARFDebugInfoEntry *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(this, dwarf_cu, DW_AT_import, DW_INVALID_OFFSET); + if (UserIDMatches(imported_uid)) + { + DWARFDebugInfo* debug_info = DebugInfo(); + if (debug_info) + { + DWARFCompileUnitSP cu_sp; + const DWARFDebugInfoEntry* imported_die = debug_info->GetDIEPtr(imported_uid, &cu_sp); + + if (imported_die) + { + sc.comp_unit->GetVariableList(true); + VariableListSP imported_variables(new VariableList()); + + if (imported_die->Tag() == DW_TAG_variable) + { + VariableSP var = ParseVariableDIE(sc, dwarf_cu, imported_die, func_low_pc); + if (var) + imported_variables->AddVariable(var); + } + else if (imported_die->Tag() == DW_TAG_namespace) + ParseVariables(sc, dwarf_cu, func_low_pc, imported_die->GetFirstChild(), 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 ( @@ -3990,6 +4060,7 @@ { DWARFDebugInfoEntry::Attributes attributes; const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); + const DWARFDebugInfoEntry* spec_die = nullptr; if (num_attributes > 0) { const char *name = NULL; @@ -4108,6 +4179,20 @@ 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) + { + DWARFCompileUnitSP cu_sp; + spec_die = debug_info->GetDIEPtr(spec_uid, &cu_sp); + } + } + break; + } case DW_AT_declaration: case DW_AT_description: case DW_AT_endianity: @@ -4117,14 +4202,13 @@ default: case DW_AT_abstract_origin: case DW_AT_sibling: - case DW_AT_specification: break; } } } 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); + 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 || (parent_context_die->Tag() == DW_TAG_namespace && parent_context_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, nullptr) != nullptr)); ValueType scope = eValueTypeInvalid; @@ -4321,6 +4405,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] = var_sp; + if (spec_die != nullptr) + m_die_to_variable_sp[spec_die] = var_sp; } return var_sp; } @@ -4412,6 +4498,7 @@ size_t vars_added = 0; const DWARFDebugInfoEntry *die = orig_die; + while (die != NULL) { dw_tag_t tag = die->Tag(); @@ -4510,7 +4597,9 @@ } } } - } + else if (tag == DW_TAG_imported_module || tag == DW_TAG_imported_declaration) + ParseImportedNamespace(sc, dwarf_cu, die, func_low_pc); + } bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 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/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/CompileUnit.cpp =================================================================== --- source/Symbol/CompileUnit.cpp +++ source/Symbol/CompileUnit.cpp @@ -13,6 +13,7 @@ #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Symbol/VariableTree.h" using namespace lldb; using namespace lldb_private; @@ -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/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/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 ""; } +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/VariableTree.cpp =================================================================== --- /dev/null +++ source/Symbol/VariableTree.cpp @@ -0,0 +1,167 @@ +//===-- 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 +#include + +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 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 imported_variables; + return FindRecVariable(name, type, imported_variables); +} + +VariableSP +VariableTree::FindRecVariable (const ConstString &name, std::unordered_map &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 (node_result) + result = node_result; + else if (imported_result) + result = imported_result; + // TODO: if (node_result && imported_result) report ambiguousity + + if (!result && GetParent()) + result = GetParent()->FindRecVariable(name, imported_variables); + + return result; +} + +VariableSP +VariableTree::FindRecVariable (const ConstString &name, ValueType type, std::unordered_map &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 (node_result) + result = node_result; + else if (imported_result) + result = imported_result; + // TODO: if (node_result && imported_result) report ambiguousity + + if (!result && GetParent()) + result = GetParent()->FindRecVariable(name, imported_variables); + + return result; +} + 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,19 @@ bool deref = false; bool address_of = false; ValueObjectSP valobj_sp; - const bool get_file_globals = true; + //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(); + //VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); + //VariableList *variable_list = var_list_sp.get(); + + VariableTreeSP vars; + if (m_sc.block) + vars = m_sc.block->GetVariables(); + else if (m_sc.comp_unit) + vars = m_sc.comp_unit->GetVariables(); - if (variable_list) + if (vars) { // If first character is a '*', then show pointer contents const char *var_expr = var_expr_cstr; @@ -659,7 +665,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 +685,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: test/lang/cpp/nsimport/main.cpp =================================================================== --- test/lang/cpp/nsimport/main.cpp +++ test/lang/cpp/nsimport/main.cpp @@ -16,11 +16,11 @@ } } -using namespace N; -using namespace Nested; int main() { + using namespace N; + using namespace Nested; n = 1; anon = 2; nested = 3;