diff options
Diffstat (limited to 'source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp')
-rw-r--r-- | source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp | 496 |
1 files changed, 201 insertions, 295 deletions
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index f4d6b195c7f0..7aeff6e964fe 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -57,6 +57,11 @@ using namespace lldb; 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) : @@ -510,248 +515,6 @@ ClangExpressionDeclMap::GetFunctionInfo return true; } -static void -FindCodeSymbolInContext -( - const ConstString &name, - SymbolContext &sym_ctx, - uint32_t name_type_mask, - SymbolContextList &sc_list -) -{ - sc_list.Clear(); - SymbolContextList temp_sc_list; - if (sym_ctx.module_sp) - sym_ctx.module_sp->FindFunctions(name, - NULL, - name_type_mask, - true, // include_symbols - false, // include_inlines - true, // append - temp_sc_list); - if (temp_sc_list.GetSize() == 0) - { - if (sym_ctx.target_sp) - sym_ctx.target_sp->GetImages().FindFunctions(name, - name_type_mask, - true, // include_symbols - false, // include_inlines - true, // append - temp_sc_list); - } - - SymbolContextList internal_symbol_sc_list; - unsigned temp_sc_list_size = temp_sc_list.GetSize(); - for (unsigned i = 0; i < temp_sc_list_size; i++) - { - SymbolContext sc; - temp_sc_list.GetContextAtIndex(i, sc); - if (sc.function) - { - sc_list.Append(sc); - } - else if (sc.symbol) - { - if (sc.symbol->IsExternal()) - { - sc_list.Append(sc); - } - else - { - internal_symbol_sc_list.Append(sc); - } - } - } - - // If we had internal symbols and we didn't find any external symbols or - // functions in debug info, then fallback to the internal symbols - if (sc_list.GetSize() == 0 && internal_symbol_sc_list.GetSize()) - { - sc_list = internal_symbol_sc_list; - } -} - -ConstString -FindBestAlternateMangledName -( - const ConstString &demangled, - const LanguageType &lang_type, - SymbolContext &sym_ctx -) -{ - CPlusPlusLanguage::MethodName cpp_name(demangled); - std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); - - if (!scope_qualified_name.size()) - return ConstString(); - - if (!sym_ctx.module_sp) - return ConstString(); - - SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor(); - if (!sym_vendor) - return ConstString(); - - lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile(); - if (!sym_file) - return ConstString(); - - std::vector<ConstString> alternates; - sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates); - - std::vector<ConstString> param_and_qual_matches; - std::vector<ConstString> param_matches; - for (size_t i = 0; i < alternates.size(); i++) - { - ConstString alternate_mangled_name = alternates[i]; - Mangled mangled(alternate_mangled_name, true); - ConstString demangled = mangled.GetDemangledName(lang_type); - - CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); - if (!cpp_name.IsValid()) - continue; - - if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) - { - if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers()) - param_and_qual_matches.push_back(alternate_mangled_name); - else - param_matches.push_back(alternate_mangled_name); - } - } - - if (param_and_qual_matches.size()) - return param_and_qual_matches[0]; // It is assumed that there will be only one! - else if (param_matches.size()) - return param_matches[0]; // Return one of them as a best match - else - return ConstString(); -} - -bool -ClangExpressionDeclMap::GetFunctionAddress -( - const ConstString &name, - uint64_t &func_addr -) -{ - assert (m_parser_vars.get()); - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; - Target *target = exe_ctx.GetTargetPtr(); - // Back out in all cases where we're not fully initialized - if (target == NULL) - return false; - if (!m_parser_vars->m_sym_ctx.target_sp) - return false; - - SymbolContextList sc_list; - - FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list); - - uint32_t sc_list_size = sc_list.GetSize(); - - if (sc_list_size == 0) - { - SymbolContext &sc = m_parser_vars->m_sym_ctx; - if (sc.comp_unit) - { - LanguageType lang_type = sc.comp_unit->GetLanguage(); - if (Language::LanguageIsCPlusPlus(lang_type) && - CPlusPlusLanguage::IsCPPMangledName(name.AsCString())) - { - Mangled mangled(name, true); - ConstString demangled = mangled.GetDemangledName(lang_type); - - if (demangled) - { - ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lang_type, sc); - if (best_alternate_mangled_name) - { - FindCodeSymbolInContext( - best_alternate_mangled_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list); - sc_list_size = sc_list.GetSize(); - } - - if (sc_list_size == 0) - { - FindCodeSymbolInContext( - demangled, m_parser_vars->m_sym_ctx, eFunctionNameTypeFull, sc_list); - sc_list_size = sc_list.GetSize(); - } - } - } - } - } - - if (sc_list_size == 0) - { - // We occasionally get debug information in which a const function is reported - // as non-const, so the mangled name is wrong. This is a hack to compensate. - - if (!strncmp(name.GetCString(), "_ZN", 3) && - strncmp(name.GetCString(), "_ZNK", 4)) - { - std::string fixed_scratch("_ZNK"); - fixed_scratch.append(name.GetCString() + 3); - ConstString fixed_name(fixed_scratch.c_str()); - - if (log) - log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString()); - - FindCodeSymbolInContext( - fixed_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list); - sc_list_size = sc_list.GetSize(); - } - } - - lldb::addr_t intern_callable_load_addr = LLDB_INVALID_ADDRESS; - - for (uint32_t i=0; i<sc_list_size; ++i) - { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(i, sym_ctx); - - - lldb::addr_t callable_load_addr = LLDB_INVALID_ADDRESS; - - if (sym_ctx.function) - { - const Address func_so_addr = sym_ctx.function->GetAddressRange().GetBaseAddress(); - if (func_so_addr.IsValid()) - { - callable_load_addr = func_so_addr.GetCallableLoadAddress(target, false); - } - } - else if (sym_ctx.symbol) - { - if (sym_ctx.symbol->IsExternal()) - callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target); - else - { - if (intern_callable_load_addr == LLDB_INVALID_ADDRESS) - intern_callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target); - } - } - - if (callable_load_addr != LLDB_INVALID_ADDRESS) - { - func_addr = callable_load_addr; - return true; - } - } - - // See if we found an internal symbol - if (intern_callable_load_addr != LLDB_INVALID_ADDRESS) - { - func_addr = intern_callable_load_addr; - return true; - } - - return false; -} - addr_t ClangExpressionDeclMap::GetSymbolAddress (Target &target, Process *process, @@ -1004,6 +767,24 @@ ClangExpressionDeclMap::FindGlobalVariable 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<ClangASTContext>(frame_decl_context.GetTypeSystem()); +} + // Interface for ClangASTSource void @@ -1039,6 +820,13 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context) if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context)) { + if (namespace_context->getName().str() == std::string(g_lldb_local_vars_namespace_cstr)) + { + CompilerDeclContext compiler_decl_ctx(GetClangASTContext(), const_cast<void *>(static_cast<const 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()) @@ -1078,7 +866,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context) current_id); } - if (!context.m_found.variable) + if (!context.m_found.variable && !context.m_found.local_vars_nsp) ClangASTSource::FindExternalVisibleDecls(context); } @@ -1089,6 +877,17 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, unsigned int current_id) { assert (m_ast_context); + + std::function<void (clang::FunctionDecl *)> MaybeRegisterFunctionBody = + [this](clang::FunctionDecl *copied_function_decl) + { + if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) + { + DeclGroupRef decl_group_ref(copied_function_decl); + m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref); + } + }; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1114,6 +913,52 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, SymbolContext sym_ctx; if (frame != nullptr) sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock); + + // Try the persistent decls, which take precedence over all else. + if (!namespace_decl) + { + do + { + if (!target) + break; + + ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext(); + + if (!scratch_clang_ast_context) + break; + + ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext(); + + if (!scratch_ast_context) + break; + + NamedDecl *persistent_decl = m_parser_vars->m_persistent_vars->GetPersistentDecl(name); + + if (!persistent_decl) + break; + + Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, persistent_decl); + + if (!parser_persistent_decl) + break; + + NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl); + + if (!parser_named_decl) + break; + + if (clang::FunctionDecl *parser_function_decl = llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) + { + MaybeRegisterFunctionBody(parser_function_decl); + } + + if (log) + log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id, name.GetCString()); + + context.AddNamedDecl(parser_named_decl); + } while (0); + } + if (name_unique_cstr[0] == '$' && !namespace_decl) { static ConstString g_lldb_class_name ("$__lldb_class"); @@ -1335,45 +1180,36 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, return; } - // any other $__lldb names should be weeded out now - if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1)) - return; - - do + if (name == ConstString(g_lldb_local_vars_namespace_cstr)) { - if (!target) - break; - - ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext(); - - if (!scratch_clang_ast_context) - break; - - ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext(); - - if (!scratch_ast_context) - break; - - TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name); - - if (!ptype_type_decl) - break; - - Decl *parser_ptype_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl); + CompilerDeclContext frame_decl_context = sym_ctx.block != nullptr ? + sym_ctx.block->GetDeclContext() : + CompilerDeclContext(); - if (!parser_ptype_decl) - break; - - TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl); + if (frame_decl_context) + { + ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem()); - if (!parser_ptype_type_decl) - break; + if (ast) + { + clang::NamespaceDecl *namespace_decl = ClangASTContext::GetUniqueNamespaceDeclaration( + m_ast_context, name_unique_cstr, nullptr); + if (namespace_decl) + { + context.AddNamedDecl(namespace_decl); + clang::DeclContext *clang_decl_ctx = clang::Decl::castToDeclContext(namespace_decl); + clang_decl_ctx->setHasExternalVisibleStorage(true); + context.m_found.local_vars_nsp = true; + } + } + } - if (log) - log->Printf(" CEDM::FEVD[%u] Found persistent type %s", current_id, name.GetCString()); + return; + } - context.AddNamedDecl(parser_ptype_type_decl); - } while (0); + // any other $__lldb names should be weeded out now + if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1)) + return; ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name)); @@ -1403,24 +1239,37 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, 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(); if (compiler_decl_context) { - // Make sure that the variables are parsed so that we have the declarations + // Make sure that the variables are parsed so that we have the declarations. VariableListSP vars = frame->GetInScopeVariableList(true); for (size_t i = 0; i < vars->GetSize(); i++) vars->GetVariableAtIndex(i)->GetDecl(); - // Search for declarations matching the name - std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name); + // Search for declarations matching the name. Do not include imported decls + // in the search if we are looking for decls in the artificial namespace + // $__lldb_local_vars. + std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name, namespace_decl.IsValid()); bool variable_found = false; for (CompilerDecl decl : found_decls) { - var = decl.GetAsVariable(); + for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) + { + VariableSP candidate_var = vars->GetVariableAtIndex(vi); + if (candidate_var->GetDecl() == decl) + { + var = candidate_var; + break; + } + } + if (var) { variable_found = true; @@ -1663,9 +1512,12 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, { if (llvm::isa<clang::FunctionDecl>(decl)) { - clang::NamedDecl *copied_decl = llvm::cast<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl)); - context.AddNamedDecl(copied_decl); - context.m_found.function_with_type_info = true; + clang::NamedDecl *copied_decl = llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl)); + if (copied_decl) + { + context.AddNamedDecl(copied_decl); + context.m_found.function_with_type_info = true; + } } } } @@ -1726,11 +1578,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, break; } - if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) - { - DeclGroupRef decl_group_ref(copied_function_decl); - m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref); - } + MaybeRegisterFunctionBody(copied_function_decl); context.AddNamedDecl(copied_function_decl); @@ -2208,6 +2056,54 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, if (function) { Type *function_type = function->GetType(); + + const lldb::LanguageType comp_unit_language = function->GetCompileUnit()->GetLanguage(); + const bool extern_c = Language::LanguageIsC(comp_unit_language) || + (Language::LanguageIsObjC(comp_unit_language) && + !Language::LanguageIsCPlusPlus(comp_unit_language)); + + if (!extern_c) + { + TypeSystem *type_system = function->GetDeclContext().GetTypeSystem(); + if (ClangASTContext *src_ast = llvm::dyn_cast<ClangASTContext>(type_system)) + { + clang::DeclContext *src_decl_context = (clang::DeclContext*)function->GetDeclContext().GetOpaqueDeclContext(); + clang::FunctionDecl *src_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context); + + if (src_function_decl) + { + if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, src_ast->getASTContext(), src_function_decl))) + { + if (log) + { + ASTDumper ast_dumper((clang::Decl*)copied_function_decl); + + StreamString ss; + + function->DumpSymbolContext(&ss); + + log->Printf(" CEDM::FEVD[%u] Imported decl for function %s (description %s), returned %s", + current_id, + copied_function_decl->getName().str().c_str(), + ss.GetData(), + ast_dumper.GetCString()); + + } + + context.AddNamedDecl(copied_function_decl); + return; + } + else + { + if (log) + { + log->Printf (" Failed to import the function decl for '%s'", + src_function_decl->getName().str().c_str()); + } + } + } + } + } if (!function_type) { @@ -2230,7 +2126,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, CompilerType copied_function_type = GuardedCopyType(function_clang_type); if (copied_function_type) { - function_decl = context.AddFunDecl(copied_function_type); + function_decl = context.AddFunDecl(copied_function_type, extern_c); if (!function_decl) { @@ -2329,10 +2225,10 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context, { CompilerType copied_clang_type = GuardedCopyType(ut); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (!copied_clang_type) { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - if (log) log->Printf("ClangExpressionDeclMap::AddThisType - Couldn't import the type"); @@ -2349,7 +2245,7 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context, &void_ptr_clang_type, 1, false, - copied_clang_type.GetTypeQualifiers()); + 0); const bool is_virtual = false; const bool is_static = false; @@ -2358,7 +2254,7 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context, const bool is_attr_used = true; const bool is_artificial = false; - ClangASTContext::GetASTContext(m_ast_context)-> + CXXMethodDecl *method_decl = ClangASTContext::GetASTContext(m_ast_context)-> AddMethodToCXXRecordType (copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", method_type, @@ -2369,6 +2265,16 @@ ClangExpressionDeclMap::AddThisType(NameSearchContext &context, is_explicit, is_attr_used, is_artificial); + + if (log) + { + ASTDumper method_ast_dumper((clang::Decl*)method_decl); + ASTDumper type_ast_dumper(copied_clang_type); + + log->Printf(" CEDM::AddThisType Added function $__lldb_expr (description %s) for this type %s", + method_ast_dumper.GetCString(), + type_ast_dumper.GetCString()); + } } if (!copied_clang_type.IsValid()) |