Index: include/lldb/Symbol/ClangASTContext.h =================================================================== --- include/lldb/Symbol/ClangASTContext.h +++ include/lldb/Symbol/ClangASTContext.h @@ -420,7 +420,8 @@ clang::NamespaceDecl * GetUniqueNamespaceDeclaration (const char *name, - clang::DeclContext *decl_ctx); + clang::DeclContext *decl_ctx, + clang::ASTContext *ast=nullptr); //------------------------------------------------------------------ // Function Types Index: source/Expression/ExpressionSourceCode.cpp =================================================================== --- source/Expression/ExpressionSourceCode.cpp +++ source/Expression/ExpressionSourceCode.cpp @@ -16,7 +16,9 @@ #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Platform.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" @@ -175,6 +177,51 @@ } } +static bool +IsCppMethod(StackFrame *frame, ConstString &object_name) +{ + if (frame == nullptr) + return false; + + Block *frame_block = frame->GetFrameBlock(); + if (frame_block == nullptr) + return false; + + Function *function = frame_block->CalculateSymbolContextFunction(); + if (function == nullptr) + return false; + + CompilerDeclContext decl_context = function->GetDeclContext(); + if (!decl_context.IsValid()) + return false; + + lldb::LanguageType lang_type; + if (!decl_context.IsClassMethod(&lang_type, nullptr, &object_name)) + return false; + + if (Language::LanguageIsCPlusPlus(lang_type)) + return true; + + return false; +} + +static void +AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, const ConstString &object_name, StreamString &stream) +{ + for (size_t i = 0; i < var_list_sp->GetSize(); i++) + { + lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i); + + ConstString var_name = var_sp->GetName(); + if (var_name == object_name) + continue; + + const char *var_name_cstr = var_name.AsCString(); + + stream.Printf("using $__lldb_local_vars::%s;\n", var_name_cstr); + } +} + bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method, ExecutionContext &exe_ctx) const { const char *target_specific_defines = "typedef signed char BOOL;\n"; @@ -239,6 +286,7 @@ } StreamString debug_macros_stream; + StreamString lldb_local_var_decls; if (StackFrame *frame = exe_ctx.GetFramePtr()) { const SymbolContext &sc = frame->GetSymbolContext( @@ -253,8 +301,15 @@ AddMacros(dm, sc.comp_unit, state, debug_macros_stream); } } + + ConstString object_name; + if (IsCppMethod(frame, object_name)) + { + lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false); + AddLocalVariableDecls(var_list_sp, object_name, lldb_local_var_decls); + } } - + if (m_wrap) { switch (wrapping_language) @@ -293,10 +348,12 @@ wrap_stream.Printf("void \n" "$__lldb_class::%s(void *$__lldb_arg) %s\n" "{ \n" + " %s \n" " %s; \n" "} \n", m_name.c_str(), (const_object ? "const" : ""), + lldb_local_var_decls.GetData(), m_body.c_str()); break; case lldb::eLanguageTypeObjC: @@ -339,6 +396,6 @@ { text.append(m_body); } - + return true; } Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -707,6 +707,9 @@ AddThisType(NameSearchContext &context, TypeFromUser &type, unsigned int current_id); + + ClangASTContext * + GetClangASTContext(); }; } // namespace lldb_private Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -57,6 +57,11 @@ using namespace lldb_private; using namespace clang; +namespace +{ + const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; +} // anonymous namespace + ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, ExecutionContext &exe_ctx) : @@ -1004,6 +1009,24 @@ return VariableSP(); } +ClangASTContext * +ClangExpressionDeclMap::GetClangASTContext () +{ + StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); + if (frame == nullptr) + return nullptr; + + SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock); + if (sym_ctx.block == nullptr) + return nullptr; + + CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext(); + if (!frame_decl_context) + return nullptr; + + return llvm::dyn_cast_or_null(frame_decl_context.GetTypeSystem()); +} + // Interface for ClangASTSource void @@ -1039,6 +1062,13 @@ if (const NamespaceDecl *namespace_context = dyn_cast(context.m_decl_context)) { + if (namespace_context->getName().str() == std::string(g_lldb_local_vars_namespace_cstr)) + { + CompilerDeclContext compiler_decl_ctx(GetClangASTContext(), (void*)context.m_decl_context); + FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx, current_id); + return; + } + ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context); if (log && log->GetVerbose()) @@ -1335,6 +1365,32 @@ return; } + if (name == ConstString(g_lldb_local_vars_namespace_cstr)) + { + CompilerDeclContext frame_decl_context = sym_ctx.block != nullptr ? + sym_ctx.block->GetDeclContext() : + CompilerDeclContext(); + + if (frame_decl_context) + { + ClangASTContext *ast = llvm::dyn_cast_or_null(frame_decl_context.GetTypeSystem()); + + if (ast) + { + clang::NamespaceDecl *namespace_decl = ast->GetUniqueNamespaceDeclaration( + name_unique_cstr, nullptr, m_ast_context); + if (namespace_decl) + { + context.AddNamedDecl(namespace_decl); + clang::DeclContext *clang_decl_ctx = clang::Decl::castToDeclContext(namespace_decl); + clang_decl_ctx->setHasExternalVisibleStorage(true); + } + } + } + + return; + } + // any other $__lldb names should be weeded out now if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1)) return; @@ -1403,7 +1459,9 @@ ValueObjectSP valobj; VariableSP var; - if (frame && !namespace_decl) + bool local_var_lookup = !namespace_decl || + (namespace_decl.GetName() == ConstString(g_lldb_local_vars_namespace_cstr)); + if (frame && local_var_lookup) { CompilerDeclContext compiler_decl_context = sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext() : CompilerDeclContext(); Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -1804,10 +1804,11 @@ #pragma mark Namespace Declarations NamespaceDecl * -ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx) +ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx, ASTContext *ast) { NamespaceDecl *namespace_decl = nullptr; - ASTContext *ast = getASTContext(); + if (ast == nullptr) + ast = getASTContext(); TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl (); if (decl_ctx == nullptr) decl_ctx = translation_unit_decl; Index: source/Target/StackFrame.cpp =================================================================== --- source/Target/StackFrame.cpp +++ source/Target/StackFrame.cpp @@ -597,7 +597,7 @@ var_list_sp.get()); } - if (m_sc.comp_unit) + if (m_sc.comp_unit && get_file_globals) { VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); if (global_variable_list_sp)