diff options
Diffstat (limited to 'lldb')
| -rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 42 | ||||
| -rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionVariable.h | 1 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 227 | ||||
| -rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 2 |
4 files changed, 223 insertions, 49 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 4aa96d69f9a..c53157a121b 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -316,6 +316,10 @@ public: /// [Used by IRForTarget] Get the address of a symbol given nothing /// but its name. /// + /// @param[in] target + /// The target to find the symbol in. If not provided, + /// then the current parsing context's Target. + /// /// @param[in] name /// The name of the symbol. /// @@ -326,6 +330,11 @@ public: /// True if the address could be retrieved; false otherwise. //------------------------------------------------------------------ bool + GetSymbolAddress (Target &target, + const ConstString &name, + uint64_t &ptr); + + bool GetSymbolAddress (const ConstString &name, uint64_t &ptr); @@ -648,6 +657,22 @@ private: TypeFromUser *type = NULL); //------------------------------------------------------------------ + /// Given a target, find a data symbol that has the given name. + /// + /// @param[in] target + /// The target to use as the basis for the search. + /// + /// @param[in] name + /// The name as a plain C string. + /// + /// @return + /// The LLDB Symbol found, or NULL if none was found. + //--------------------------------------------------------- + Symbol * + FindGlobalDataSymbol (Target &target, + const ConstString &name); + + //------------------------------------------------------------------ /// Get the value of a variable in a given execution context and return /// the associated Types if needed. /// @@ -699,7 +724,7 @@ private: //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given - /// persistent variable, and put it in the Tuple list. + /// persistent variable, and put it in the list of found entities. /// /// @param[in] context /// The NameSearchContext to use when constructing the Decl. @@ -712,6 +737,21 @@ private: lldb::ClangExpressionVariableSP &pvar_sp); //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given LLDB + /// symbol (treated as a variable), and put it in the list of found + /// entities. + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] var + /// The LLDB Variable that needs a Decl. + //------------------------------------------------------------------ + void + AddOneGenericVariable (NameSearchContext &context, + Symbol &symbol); + + //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given /// function. (Functions are not placed in the Tuple list.) Can /// handle both fully typed functions and generic functions. diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index 7f8203e830b..4c3263dbe9d 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -107,6 +107,7 @@ public: llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable lldb::VariableSP m_lldb_var; ///< The original variable for this variable + lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol private: DISALLOW_COPY_AND_ASSIGN (ParserVars); diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 9e0f67c9c1d..fa69e49e44d 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -533,19 +533,14 @@ ClangExpressionDeclMap::GetFunctionAddress bool ClangExpressionDeclMap::GetSymbolAddress ( + Target &target, const ConstString &name, uint64_t &ptr ) { - assert (m_parser_vars.get()); - - // Back out in all cases where we're not fully initialized - if (m_parser_vars->m_exe_ctx->target == NULL) - return false; - SymbolContextList sc_list; - m_parser_vars->m_exe_ctx->target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); + target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); if (!sc_list.GetSize()) return false; @@ -555,11 +550,29 @@ ClangExpressionDeclMap::GetSymbolAddress const Address *sym_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress(); - ptr = sym_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target); + ptr = sym_address->GetLoadAddress(&target); return true; } +bool +ClangExpressionDeclMap::GetSymbolAddress +( + const ConstString &name, + uint64_t &ptr +) +{ + assert (m_parser_vars.get()); + + if (!m_parser_vars->m_exe_ctx || + !m_parser_vars->m_exe_ctx->target) + return false; + + return GetSymbolAddress(*m_parser_vars->m_exe_ctx->target, + name, + ptr); +} + // Interface for CommandObjectExpression bool @@ -1225,8 +1238,32 @@ ClangExpressionDeclMap::DoMaterializeOneVariable TypeFromUser type(expr_var->GetTypeFromUser()); VariableSP var = FindVariableInScope (*exe_ctx.frame, name, &type); + Symbol *sym = FindGlobalDataSymbol(*exe_ctx.target, name); - if (!var) + std::auto_ptr<lldb_private::Value> location_value; + + if (var) + { + location_value.reset(GetVariableValue(exe_ctx, + var, + NULL)); + } + else if (sym) + { + location_value.reset(new Value); + + uint64_t location_load_addr; + + if (!GetSymbolAddress(*exe_ctx.target, name, location_load_addr)) + { + if (log) + err.SetErrorStringWithFormat("Couldn't find value for global symbol %s", name.GetCString()); + } + + location_value->SetValueType(Value::eValueTypeLoadAddress); + location_value->GetScalar() = location_load_addr; + } + else { err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString()); return false; @@ -1235,9 +1272,6 @@ ClangExpressionDeclMap::DoMaterializeOneVariable if (log) log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType()); - std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx, - var, - NULL)); if (!location_value.get()) { @@ -1627,6 +1661,30 @@ ClangExpressionDeclMap::FindVariableInScope return var_sp; } +Symbol * +ClangExpressionDeclMap::FindGlobalDataSymbol +( + Target &target, + const ConstString &name +) +{ + SymbolContextList sc_list; + + target.GetImages().FindSymbolsWithNameAndType(name, + eSymbolTypeData, + sc_list); + + if (sc_list.GetSize()) + { + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(0, sym_ctx); + + return sym_ctx.symbol; + } + + return NULL; +} + // Interface for ClangASTSource void ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name) @@ -1677,48 +1735,61 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString append, sc_list); - bool found_specific = false; - Symbol *generic_symbol = NULL; - Symbol *non_extern_symbol = NULL; - - for (uint32_t index = 0, num_indices = sc_list.GetSize(); - index < num_indices; - ++index) + if (sc_list.GetSize()) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); - - if (sym_ctx.function) + bool found_specific = false; + Symbol *generic_symbol = NULL; + Symbol *non_extern_symbol = NULL; + + for (uint32_t index = 0, num_indices = sc_list.GetSize(); + index < num_indices; + ++index) + { + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(index, sym_ctx); + + if (sym_ctx.function) + { + // TODO only do this if it's a C function; C++ functions may be + // overloaded + if (!found_specific) + AddOneFunction(context, sym_ctx.function, NULL); + found_specific = true; + } + else if (sym_ctx.symbol) + { + if (sym_ctx.symbol->IsExternal()) + generic_symbol = sym_ctx.symbol; + else + non_extern_symbol = sym_ctx.symbol; + } + } + + if (!found_specific) { - // TODO only do this if it's a C function; C++ functions may be - // overloaded - if (!found_specific) - AddOneFunction(context, sym_ctx.function, NULL); - found_specific = true; + if (generic_symbol) + AddOneFunction (context, NULL, generic_symbol); + else if (non_extern_symbol) + AddOneFunction (context, NULL, non_extern_symbol); } - else if (sym_ctx.symbol) + + ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name)); + if (namespace_decl) { - if (sym_ctx.symbol->IsExternal()) - generic_symbol = sym_ctx.symbol; - else - non_extern_symbol = sym_ctx.symbol; + clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); + if (clang_namespace_decl) + clang_namespace_decl->setHasExternalLexicalStorage(); } } - - if (!found_specific) - { - if (generic_symbol) - AddOneFunction (context, NULL, generic_symbol); - else if (non_extern_symbol) - AddOneFunction (context, NULL, non_extern_symbol); - } - - ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name)); - if (namespace_decl) + else { - clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); - if (clang_namespace_decl) - clang_namespace_decl->setHasExternalLexicalStorage(); + // We couldn't find a variable or function for this. Now we'll hunt for a generic + // data symbol, and -- if it is found -- treat it as a variable. + + Symbol *data_symbol = FindGlobalDataSymbol(*m_parser_vars->m_exe_ctx->target, name); + + if (data_symbol) + AddOneGenericVariable(context, *data_symbol); } } } @@ -2060,6 +2131,68 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, } void +ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, + Symbol &symbol) +{ + assert(m_parser_vars.get()); + + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + clang::ASTContext *scratch_ast_context = m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext(); + + TypeFromUser user_type (ClangASTContext::GetVoidPtrType(scratch_ast_context, false), + scratch_ast_context); + + TypeFromParser parser_type (ClangASTContext::GetVoidPtrType(context.GetASTContext(), false), + context.GetASTContext()); + + NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType())); + + std::string decl_name(context.m_decl_name.getAsString()); + ConstString entity_name(decl_name.c_str()); + ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope (), + entity_name, + user_type, + m_parser_vars->m_exe_ctx->process->GetByteOrder(), + m_parser_vars->m_exe_ctx->process->GetAddressByteSize())); + assert (entity.get()); + entity->EnableParserVars(); + + std::auto_ptr<Value> symbol_location(new Value); + + AddressRange &symbol_range = symbol.GetAddressRangeRef(); + Address &symbol_address = symbol_range.GetBaseAddress(); + lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(m_parser_vars->m_exe_ctx->target); + + symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); + symbol_location->GetScalar() = symbol_load_addr; + symbol_location->SetValueType(Value::eValueTypeLoadAddress); + + entity->m_parser_vars->m_parser_type = parser_type; + entity->m_parser_vars->m_named_decl = var_decl; + entity->m_parser_vars->m_llvm_value = NULL; + entity->m_parser_vars->m_lldb_value = symbol_location.release(); + entity->m_parser_vars->m_lldb_sym = &symbol; + + if (log) + { + std::string var_decl_print_string; + llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string); + var_decl->print(var_decl_print_stream); + var_decl_print_stream.flush(); + + log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str()); + + if (log->GetVerbose()) + { + StreamString var_decl_dump_string; + ASTDumper::DumpDecl(var_decl_dump_string, var_decl); + log->Printf("%s\n", var_decl_dump_string.GetData()); + } + } +} + +void ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, const RegisterInfo *reg_info) { diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index 8be2a429fb4..212af48cc6c 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -1295,7 +1295,7 @@ IRForTarget::MaybeHandleVariable (Module &llvm_module, Value *llvm_value_ptr) bool IRForTarget::HandleSymbol (Module &llvm_module, Value *symbol) -{ +{ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); lldb_private::ConstString name(symbol->getName().str().c_str()); |

