diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -217,9 +217,20 @@ void CollectCandidateCNames(std::vector &C_names, ConstString name); - void CollectCandidateCPlusPlusNames(std::vector &CPP_names, - const std::vector &C_names, - const SymbolContext &sc); + /// Generates a list of mangled function names from a list of + /// of similar mangled function names. + /// + /// \param[in] C_names List of mangled names to generate + /// alternatives for. + /// + /// \param[in] sc SymbolContext used to find approximately matching + /// mangled function names. + /// + /// \returns List of mangled function names that are similar to + /// the names in 'C_names'. + std::vector + CollectCandidateCPlusPlusNames(const std::vector &C_names, + const SymbolContext &sc); lldb::addr_t FindInSymbols(const std::vector &names, const lldb_private::SymbolContext &sc, diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -310,10 +310,20 @@ return std::vector(); } - virtual ConstString - FindBestAlternateFunctionMangledName(const Mangled mangled, - const SymbolContext &sym_ctx) const { - return ConstString(); + /// Generates a list of mangled function name alternatives + /// + /// \param[in] mangled_names List of mangled names to generate + /// alternatives for. + /// + /// \param[in] sc SymbolContext used to find approximately matching + /// mangled function names. + /// + /// \returns List of mangled function names that are similar to + /// the names in 'mangled_names'. + virtual std::vector + CollectAlternateFunctionNames(const std::vector &mangled_names, + const SymbolContext &sc) const { + return {}; } protected: diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -671,30 +671,13 @@ C_names.push_back(name); } -void IRExecutionUnit::CollectCandidateCPlusPlusNames( - std::vector &CPP_names, +std::vector IRExecutionUnit::CollectCandidateCPlusPlusNames( const std::vector &C_names, const SymbolContext &sc) { if (auto *cpp_lang = Language::FindPlugin(lldb::eLanguageTypeC_plus_plus)) { - for (const ConstString &name : C_names) { - Mangled mangled(name); - if (cpp_lang->SymbolNameFitsToLanguage(mangled)) { - if (ConstString best_alternate = - cpp_lang->FindBestAlternateFunctionMangledName(mangled, sc)) { - CPP_names.push_back(best_alternate); - } - } - - std::vector alternates = - cpp_lang->GenerateAlternateFunctionManglings(name); - CPP_names.insert(CPP_names.end(), alternates.begin(), alternates.end()); - - // As a last-ditch fallback, try the base name for C++ names. It's - // terrible, but the DWARF doesn't always encode "extern C" correctly. - ConstString basename = - cpp_lang->GetDemangledFunctionNameWithoutArguments(mangled); - CPP_names.push_back(basename); - } + return cpp_lang->CollectAlternateFunctionNames(C_names, sc); } + + return {}; } class LoadAddressResolver { @@ -869,7 +852,6 @@ lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name, bool &missing_weak) { std::vector candidate_C_names; - std::vector candidate_CPlusPlus_names; CollectCandidateCNames(candidate_C_names, name); @@ -888,9 +870,9 @@ if (ret != LLDB_INVALID_ADDRESS) return ret; - CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, - m_sym_ctx); - ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx, missing_weak); + ret = FindInSymbols( + CollectCandidateCPlusPlusNames(candidate_C_names, m_sym_ctx), m_sym_ctx, + missing_weak); return ret; } diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -135,8 +135,9 @@ std::vector GenerateAlternateFunctionManglings(const ConstString mangled) const override; - ConstString FindBestAlternateFunctionMangledName( - const Mangled mangled, const SymbolContext &sym_ctx) const override; + std::vector + CollectAlternateFunctionNames(const std::vector &mangled_names, + const SymbolContext &sc) const override; // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -510,8 +510,9 @@ return alternates; } -ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName( - const Mangled mangled, const SymbolContext &sym_ctx) const { +static ConstString +FindBestAlternateFunctionMangledName(const Mangled mangled, + const SymbolContext &sym_ctx) { ConstString demangled = mangled.GetDemangledName(); if (!demangled) return ConstString(); @@ -1405,3 +1406,29 @@ // that we could check for. return file_path.contains("/usr/include/c++/"); } + +std::vector CPlusPlusLanguage::CollectAlternateFunctionNames( + const std::vector &mangled_names, + const SymbolContext &sc) const { + std::vector results; + for (const ConstString &name : mangled_names) { + Mangled mangled(name); + if (SymbolNameFitsToLanguage(mangled)) { + if (ConstString best_alternate = + FindBestAlternateFunctionMangledName(mangled, sc)) { + results.push_back(best_alternate); + } + } + + std::vector alternates = + GenerateAlternateFunctionManglings(name); + results.insert(results.end(), alternates.begin(), alternates.end()); + + // As a last-ditch fallback, try the base name for C++ names. It's + // terrible, but the DWARF doesn't always encode "extern C" correctly. + ConstString basename = GetDemangledFunctionNameWithoutArguments(mangled); + results.push_back(basename); + } + + return results; +}