Index: include/lldb/Symbol/ClangASTContext.h =================================================================== --- include/lldb/Symbol/ClangASTContext.h +++ include/lldb/Symbol/ClangASTContext.h @@ -30,6 +30,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/Symbol/Variable.h" namespace lldb_private { @@ -1069,6 +1070,40 @@ int tag_decl_kind, const ClangASTContext::TemplateParameterInfos &template_param_infos); + + clang::VarDecl * + CreateVariableDeclaration (CompilerDeclContext var_decl_context, lldb::VariableSP var_sp) + { + if (var_decl_context.IsValid() && var_decl_context.IsClang()) + { + clang::DeclContext *var_clang_decl_context = DeclContextGetAsDeclContext(var_decl_context); + const char *name = var_sp->GetUnqualifiedName().AsCString(nullptr); + clang::VarDecl *var_decl = clang::VarDecl::Create(*getASTContext(), + var_clang_decl_context, + clang::SourceLocation(), + clang::SourceLocation(), + name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, + GetQualType(var_sp->GetType()), + nullptr, + clang::SC_None); + var_clang_decl_context->addDecl(var_decl); + var_clang_decl_context->makeDeclVisibleInContext(var_decl); + m_decl_to_var.insert(std::make_pair(var_decl, var_sp)); + var_sp->SetVarDecl(var_decl); + return var_decl; + } + return nullptr; + } + + lldb::VariableSP + GetVariableFromDecl (clang::VarDecl *var_decl) + { + auto decl_to_var_it = m_decl_to_var.find(var_decl); + if (decl_to_var_it != m_decl_to_var.end()) + return decl_to_var_it->second; + return lldb::VariableSP(); + } + protected: static clang::QualType GetQualType (void *type) @@ -1108,6 +1143,7 @@ void * m_callback_baton; uint32_t m_pointer_byte_size; bool m_ast_owned; + std::map m_decl_to_var; private: //------------------------------------------------------------------ Index: include/lldb/Symbol/Variable.h =================================================================== --- include/lldb/Symbol/Variable.h +++ include/lldb/Symbol/Variable.h @@ -59,6 +59,9 @@ ConstString GetName() const; + ConstString + GetUnqualifiedName() const; + SymbolContextScope * GetSymbolContextScope() const { @@ -167,6 +170,21 @@ StringList &matches, bool &word_complete); + CompilerDeclContext + GetParentDeclContext (); + + clang::VarDecl * + GetVarDecl () + { + return m_var_decl; + } + + void + SetVarDecl (clang::VarDecl *var_decl) + { + m_var_decl = var_decl; + } + protected: ConstString m_name; // The basename of the variable (no namespaces) Mangled m_mangled; // The mangled name of the variable @@ -179,6 +197,7 @@ m_artificial:1, // Non-zero if the variable is not explicitly declared in source m_loc_is_const_data:1, // The m_location expression contains the constant variable value data, not a DWARF location m_static_member:1; // Non-zero if variable is static member of a class or struct. + clang::VarDecl *m_var_decl; private: Variable(const Variable& rhs); Variable& operator=(const Variable& rhs); Index: source/Expression/ClangExpressionDeclMap.cpp =================================================================== --- source/Expression/ClangExpressionDeclMap.cpp +++ source/Expression/ClangExpressionDeclMap.cpp @@ -1029,6 +1029,9 @@ // doesn't start with our phony prefix of '$' Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); + SymbolContext sym_ctx; + if (frame != nullptr) + sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock); if (name_unique_cstr[0] == '$' && !namespace_decl) { static ConstString g_lldb_class_name ("$__lldb_class"); @@ -1040,7 +1043,6 @@ if (frame == NULL) return; - SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock); // Find the block that defines the function represented by "sym_ctx" Block *function_block = sym_ctx.GetFunctionBlock(); @@ -1343,7 +1345,34 @@ ValueObjectSP valobj; VariableSP var; Error err; + + if (sym_ctx.block != nullptr) + { + CompilerDeclContext compiler_decl_ctx = sym_ctx.GetFunctionBlock()->GetDeclContext(); + ClangASTContext *ast_context = (ClangASTContext *)compiler_decl_ctx.GetTypeSystem(); + if (ast_context != nullptr) + { + std::vector found_vars; + clang::DeclContext *current_decl_context = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx); + + for (clang::DeclContext *decl_context = current_decl_context; decl_context != nullptr && found_vars.empty(); decl_context = decl_context->getParent()) + for (clang::Decl *child : decl_context->decls()) + if (clang::VarDecl *vd = llvm::dyn_cast(child)) + if (vd->getName().equals(name_unique_cstr)) + found_vars.push_back(vd); + for (clang::VarDecl *var_decl : found_vars) + { + //printf("paul herman\n"); + var = ast_context->GetVariableFromDecl(var_decl); + valobj = ValueObjectVariable::Create(frame, var); + AddOneVariable(context, var, valobj, current_id); + context.m_found.variable = true; + return; + } + } + } + if (frame && !namespace_decl) { valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr, Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -4096,6 +4096,17 @@ // (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; + + + CompilerDeclContext var_decl_context; + if (sc.block != nullptr) + var_decl_context = sc.block->GetDeclContext(); + else if (sc.function != nullptr) + var_decl_context = sc.function->GetDeclContext(); + else + var_decl_context = var_sp->GetParentDeclContext(); + + this->GetClangASTContext().CreateVariableDeclaration(var_decl_context, var_sp); } return var_sp; } Index: source/Symbol/Variable.cpp =================================================================== --- source/Symbol/Variable.cpp +++ source/Symbol/Variable.cpp @@ -18,6 +18,7 @@ #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ABI.h" @@ -89,6 +90,13 @@ return m_name; } +ConstString +Variable::GetUnqualifiedName() const +{ + return m_name; +} + + bool Variable::NameMatches (const ConstString &name) const { @@ -230,6 +238,12 @@ return sizeof(Variable); } +CompilerDeclContext +Variable::GetParentDeclContext () +{ + Type *type = GetType(); + return type->GetSymbolFile()->GetDeclContextContainingUID(GetID()); +} void Variable::CalculateSymbolContext (SymbolContext *sc)