From befa77e59a7760d8c4fdd177b234e4a59500f61c Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Tue, 12 Jul 2022 08:51:30 -0700 Subject: [PATCH] [lldb] Filter DIEs based on qualified name where possible Context: When setting a breakpoint by name, we invoke Module::FindFunctions to find the function(s) in question. However, we use a Module::LookupInfo to first process the user-provided name and figure out exactly what we're looking for. When we actually perform the function lookup, we search for the basename. After performing the search, we then filter out the results using Module::LookupInfo::Prune. For example, given a::b::foo we would first search for all instances of foo and then filter out the results to just names that have a::b::foo in them. As one can imagine, this involves a lot of debug info processing that we do not necessarily need to be doing. Instead of doing one large post-processing step after finding each instance of `foo`, we can filter them as we go to save time. Some numbers: Debugging LLDB and placing a breakpoint on llvm::itanium_demangle::StringView::begin without this change takes approximately 70 seconds and resolves 31,920 DIEs. With this change, placing the breakpoint takes around 30 seconds and resolves 8 DIEs. Differential Revision: https://reviews.llvm.org/D129682 --- lldb/include/lldb/Core/Module.h | 24 +++++ lldb/include/lldb/Symbol/SymbolFile.h | 4 +- lldb/include/lldb/Symbol/SymbolFileOnDemand.h | 3 +- lldb/source/Breakpoint/BreakpointResolverName.cpp | 5 +- lldb/source/Core/Module.cpp | 107 +++++++++++---------- lldb/source/Core/ModuleList.cpp | 5 +- .../SymbolFile/Breakpad/SymbolFileBreakpad.cpp | 5 +- .../SymbolFile/Breakpad/SymbolFileBreakpad.h | 3 +- .../Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp | 9 +- .../Plugins/SymbolFile/DWARF/AppleDWARFIndex.h | 4 +- .../Plugins/SymbolFile/DWARF/DWARFASTParser.h | 3 + .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 63 ++++++------ .../Plugins/SymbolFile/DWARF/DWARFASTParserClang.h | 3 + .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 1 + .../source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp | 24 ++++- lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h | 7 +- .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 13 ++- .../SymbolFile/DWARF/DebugNamesDWARFIndex.h | 4 +- .../Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp | 6 +- .../Plugins/SymbolFile/DWARF/ManualDWARFIndex.h | 4 +- .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 37 +++++-- .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 5 +- .../SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 10 +- .../SymbolFile/DWARF/SymbolFileDWARFDebugMap.h | 3 +- .../SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 6 +- .../SymbolFile/NativePDB/SymbolFileNativePDB.h | 3 +- .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 6 +- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h | 3 +- lldb/source/Symbol/SymbolFile.cpp | 3 +- lldb/source/Symbol/SymbolFileOnDemand.cpp | 8 +- lldb/tools/lldb-test/lldb-test.cpp | 5 +- 31 files changed, 237 insertions(+), 149 deletions(-) diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h index 117b14c..e877a14 100644 --- a/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h @@ -85,6 +85,7 @@ struct ModuleFunctionSearchOptions { class Module : public std::enable_shared_from_this, public SymbolContextScope { public: + class LookupInfo; // Static functions that can track the lifetime of module objects. This is // handy because we might have Module objects that are in shared pointers // that aren't in the global module list (from ModuleList). If this is the @@ -294,6 +295,23 @@ public: /// matches. void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list); + /// Find functions by lookup info. + /// + /// If the function is an inlined function, it will have a block, + /// representing the inlined function, and the function will be the + /// containing function. If it is not inlined, then the block will be NULL. + /// + /// \param[in] lookup_info + /// The lookup info of the function we are looking for. + /// + /// \param[out] sc_list + /// A symbol context list that gets filled in with all of the + /// matches. + void FindFunctions(const LookupInfo &lookup_info, + const CompilerDeclContext &parent_decl_ctx, + const ModuleFunctionSearchOptions &options, + SymbolContextList &sc_list); + /// Find functions by name. /// /// If the function is an inlined function, it will have a block, @@ -931,6 +949,12 @@ public: m_name_type_mask = mask; } + lldb::LanguageType GetLanguageType() const { return m_language; } + + bool NameMatchesLookupInfo( + ConstString function_name, + lldb::LanguageType language_type = lldb::eLanguageTypeUnknown) const; + void Prune(SymbolContextList &sc_list, size_t start_idx) const; protected: diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index ed0de1b..6d34e4c 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -9,6 +9,7 @@ #ifndef LLDB_SYMBOL_SYMBOLFILE_H #define LLDB_SYMBOL_SYMBOLFILE_H +#include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SourceLocationSpec.h" @@ -234,9 +235,8 @@ public: virtual void FindGlobalVariables(const RegularExpression ®ex, uint32_t max_matches, VariableList &variables); - virtual void FindFunctions(ConstString name, + virtual void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list); virtual void FindFunctions(const RegularExpression ®ex, bool include_inlines, SymbolContextList &sc_list); diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index e47872c9..653a004 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -135,9 +135,8 @@ public: uint32_t max_matches, lldb_private::VariableList &variables) override; - void FindFunctions(lldb_private::ConstString name, + void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index 24e36f3..dbaeec9 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -274,9 +274,8 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, if (context.module_sp) { for (const auto &lookup : m_lookups) { const size_t start_func_idx = func_list.GetSize(); - context.module_sp->FindFunctions( - lookup.GetLookupName(), CompilerDeclContext(), - lookup.GetNameTypeMask(), function_options, func_list); + context.module_sp->FindFunctions(lookup, CompilerDeclContext(), + function_options, func_list); const size_t end_func_idx = func_list.GetSize(); diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 0d4466a..0704e0e 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -727,6 +727,41 @@ Module::LookupInfo::LookupInfo(ConstString name, } } +bool Module::LookupInfo::NameMatchesLookupInfo( + ConstString function_name, LanguageType language_type) const { + // We always keep unnamed symbols + if (!function_name) + return true; + + // If we match exactly, we can return early + if (m_name == function_name) + return true; + + // If function_name is mangled, we'll need to demangle it. + // In the pathologial case where the function name "looks" mangled but is + // actually demangled (e.g. a method named _Zonk), this operation should be + // relatively inexpensive since no demangling is actually occuring. See + // Mangled::SetValue for more context. + const bool function_name_may_be_mangled = + Mangled::GetManglingScheme(function_name.GetStringRef()) != + Mangled::eManglingSchemeNone; + ConstString demangled_function_name = function_name; + if (function_name_may_be_mangled) { + Mangled mangled_function_name(function_name); + demangled_function_name = mangled_function_name.GetDemangledName(); + } + + // If the symbol has a language, then let the language make the match. + // Otherwise just check that the demangled function name contains the + // demangled user-provided name. + if (Language *language = Language::FindPlugin(language_type)) + return language->DemangledNameContainsPath(m_name.GetStringRef(), + demangled_function_name); + + llvm::StringRef function_name_ref = demangled_function_name.GetStringRef(); + return function_name_ref.contains(m_name.GetStringRef()); +} + void Module::LookupInfo::Prune(SymbolContextList &sc_list, size_t start_idx) const { if (m_match_name_after_lookup && m_name) { @@ -736,20 +771,8 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, if (!sc_list.GetContextAtIndex(i, sc)) break; - llvm::StringRef user_name = m_name.GetStringRef(); - bool keep_it = true; - Language *language = Language::FindPlugin(sc.GetLanguage()); - // If the symbol has a language, then let the language make the match. - // Otherwise just check that the demangled name contains the user name. - if (language) - keep_it = language->DemangledNameContainsPath(m_name.GetStringRef(), - sc.GetFunctionName()); - else { - llvm::StringRef full_name = sc.GetFunctionName().GetStringRef(); - // We always keep unnamed symbols: - if (!full_name.empty()) - keep_it = full_name.contains(user_name); - } + bool keep_it = + NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage()); if (keep_it) ++i; else @@ -798,51 +821,37 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, } } -void Module::FindFunctions(ConstString name, +void Module::FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { - const size_t old_size = sc_list.GetSize(); - // Find all the functions (not symbols, but debug information functions... - SymbolFile *symbols = GetSymbolFile(); - - if (name_type_mask & eFunctionNameTypeAuto) { - LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); - - if (symbols) { - symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx, - lookup_info.GetNameTypeMask(), - options.include_inlines, sc_list); - - // Now check our symbol table for symbols that are code symbols if - // requested - if (options.include_symbols) { - Symtab *symtab = symbols->GetSymtab(); - if (symtab) - symtab->FindFunctionSymbols(lookup_info.GetLookupName(), - lookup_info.GetNameTypeMask(), sc_list); + if (SymbolFile *symbols = GetSymbolFile()) { + symbols->FindFunctions(lookup_info, parent_decl_ctx, + options.include_inlines, sc_list); + // Now check our symbol table for symbols that are code symbols if + // requested + if (options.include_symbols) { + if (Symtab *symtab = symbols->GetSymtab()) { + symtab->FindFunctionSymbols(lookup_info.GetLookupName(), + lookup_info.GetNameTypeMask(), sc_list); } } + } +} +void Module::FindFunctions(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + FunctionNameType name_type_mask, + const ModuleFunctionSearchOptions &options, + SymbolContextList &sc_list) { + const size_t old_size = sc_list.GetSize(); + LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); + FindFunctions(lookup_info, parent_decl_ctx, options, sc_list); + if (name_type_mask & eFunctionNameTypeAuto) { const size_t new_size = sc_list.GetSize(); - if (old_size < new_size) lookup_info.Prune(sc_list, old_size); - } else { - if (symbols) { - symbols->FindFunctions(name, parent_decl_ctx, name_type_mask, - options.include_inlines, sc_list); - - // Now check our symbol table for symbols that are code symbols if - // requested - if (options.include_symbols) { - Symtab *symtab = symbols->GetSymtab(); - if (symtab) - symtab->FindFunctionSymbols(name, name_type_mask, sc_list); - } - } } } diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 1692a37..baf44d2 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -425,9 +425,8 @@ void ModuleList::FindFunctions(ConstString name, std::lock_guard guard(m_modules_mutex); for (const ModuleSP &module_sp : m_modules) { - module_sp->FindFunctions(lookup_info.GetLookupName(), - CompilerDeclContext(), - lookup_info.GetNameTypeMask(), options, sc_list); + module_sp->FindFunctions(lookup_info, CompilerDeclContext(), options, + sc_list); } const size_t new_size = sc_list.GetSize(); diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index b5615c3..2782472 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -421,12 +421,13 @@ uint32_t SymbolFileBreakpad::ResolveSymbolContext( } void SymbolFileBreakpad::FindFunctions( - ConstString name, const CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, bool include_inlines, + const Module::LookupInfo &lookup_info, + const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); // TODO: Implement this with supported FunctionNameType. + ConstString name = lookup_info.GetLookupName(); for (uint32_t i = 0; i < GetNumCompileUnits(); ++i) { CompUnitSP cu_sp = GetCompileUnitAtIndex(i); FunctionSP func_sp = GetOrCreateFunction(*cu_sp); diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index 639d2e2..7c1f6fa 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -110,9 +110,8 @@ public: void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override {} - void FindFunctions(ConstString name, + void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override; void FindFunctions(const RegularExpression ®ex, bool include_inlines, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index 4877169..f6a49ba 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -180,12 +180,13 @@ void AppleDWARFIndex::GetNamespaces( } void AppleDWARFIndex::GetFunctions( - ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, llvm::function_ref callback) { + ConstString name = lookup_info.GetLookupName(); m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) { - return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, - parent_decl_ctx, name_type_mask, callback); + return ProcessFunctionDIE(lookup_info, die_ref, dwarf, parent_decl_ctx, + callback); }); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h index ef3cb5d..3a5b8ee 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -52,9 +52,9 @@ public: llvm::function_ref callback) override; void GetNamespaces(ConstString name, llvm::function_ref callback) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + void GetFunctions(const Module::LookupInfo &lookup_info, + SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, llvm::function_ref callback) override; void GetFunctions(const RegularExpression ®ex, llvm::function_ref callback) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 97b0ea1..a6dba10 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -31,6 +31,9 @@ public: const DWARFDIE &die, bool *type_is_new_ptr) = 0; + virtual lldb_private::ConstString + ConstructDemangledNameFromDWARF(const DWARFDIE &die) = 0; + virtual lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index b6407af..9e37bef 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2280,6 +2280,39 @@ size_t DWARFASTParserClang::ParseChildEnumerators( return enumerators_added; } +ConstString +DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) { + bool is_static = false; + bool is_variadic = false; + bool has_template_params = false; + unsigned type_quals = 0; + std::vector param_types; + std::vector param_decls; + StreamString sstr; + + DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); + sstr << decl_ctx.GetQualifiedName(); + + clang::DeclContext *containing_decl_ctx = + GetClangDeclContextContainingDIE(die, nullptr); + ParseChildParameters(containing_decl_ctx, die, true, is_static, is_variadic, + has_template_params, param_types, param_decls, + type_quals); + sstr << "("; + for (size_t i = 0; i < param_types.size(); i++) { + if (i > 0) + sstr << ", "; + sstr << param_types[i].GetTypeName(); + } + if (is_variadic) + sstr << ", ..."; + sstr << ")"; + if (type_quals & clang::Qualifiers::Const) + sstr << " const"; + + return ConstString(sstr.GetString()); +} + Function * DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, const DWARFDIE &die, @@ -2317,35 +2350,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, // If the mangled name is not present in the DWARF, generate the // demangled name using the decl context. We skip if the function is // "main" as its name is never mangled. - bool is_static = false; - bool is_variadic = false; - bool has_template_params = false; - unsigned type_quals = 0; - std::vector param_types; - std::vector param_decls; - StreamString sstr; - - DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); - sstr << decl_ctx.GetQualifiedName(); - - clang::DeclContext *containing_decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(containing_decl_ctx, die, true, is_static, - is_variadic, has_template_params, param_types, - param_decls, type_quals); - sstr << "("; - for (size_t i = 0; i < param_types.size(); i++) { - if (i > 0) - sstr << ", "; - sstr << param_types[i].GetTypeName(); - } - if (is_variadic) - sstr << ", ..."; - sstr << ")"; - if (type_quals & clang::Qualifiers::Const) - sstr << " const"; - - func_name.SetValue(ConstString(sstr.GetString()), false); + func_name.SetValue(ConstructDemangledNameFromDWARF(die), false); } else func_name.SetValue(ConstString(name), false); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 2bc166c..7356653 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -45,6 +45,9 @@ public: const DWARFDIE &die, bool *type_is_new_ptr) override; + lldb_private::ConstString + ConstructDemangledNameFromDWARF(const DWARFDIE &die) override; + lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index c989536..600a2ea 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -18,6 +18,7 @@ #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" #include "DWARFCompileUnit.h" #include "DWARFDebugAbbrev.h" diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index 5131584..71df9e0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -11,7 +11,9 @@ #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" +#include "lldb/Target/Language.h" using namespace lldb_private; using namespace lldb; @@ -19,15 +21,33 @@ using namespace lldb; DWARFIndex::~DWARFIndex() = default; bool DWARFIndex::ProcessFunctionDIE( - llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + const Module::LookupInfo &lookup_info, DIERef ref, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, llvm::function_ref callback) { + llvm::StringRef name = lookup_info.GetLookupName().GetStringRef(); + FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); DWARFDIE die = dwarf.GetDIE(ref); if (!die) { ReportInvalidDIERef(ref, name); return true; } + if (!(name_type_mask & eFunctionNameTypeFull)) { + ConstString name_to_match_against; + if (const char *mangled_die_name = die.GetMangledName()) { + name_to_match_against = ConstString(mangled_die_name); + } else { + SymbolFileDWARF *symbols = die.GetDWARF(); + if (ConstString demangled_die_name = + symbols->ConstructFunctionDemangledName(die)) + name_to_match_against = demangled_die_name; + } + + if (!lookup_info.NameMatchesLookupInfo(name_to_match_against, + lookup_info.GetLanguageType())) + return true; + } + // Exit early if we're searching exclusively for methods or selectors and // we have a context specified (no methods in namespaces). uint32_t looking_for_nonmethods = diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index c4995e7..c820793 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -13,6 +13,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/DWARFFormValue.h" +#include "lldb/Core/Module.h" #include "lldb/Target/Statistics.h" class DWARFDeclContext; @@ -54,9 +55,8 @@ public: GetNamespaces(ConstString name, llvm::function_ref callback) = 0; virtual void - GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, llvm::function_ref callback) = 0; virtual void GetFunctions(const RegularExpression ®ex, @@ -74,10 +74,9 @@ protected: /// the function given by "ref" matches search criteria given by /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies" /// vector. - bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref, + bool ProcessFunctionDIE(const Module::LookupInfo &lookup_info, DIERef ref, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, llvm::function_ref callback); class DIERefCallbackImpl { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index ad22078..a8e9b41 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -238,10 +238,10 @@ void DebugNamesDWARFIndex::GetNamespaces( } void DebugNamesDWARFIndex::GetFunctions( - ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, llvm::function_ref callback) { - + ConstString name = lookup_info.GetLookupName(); std::set seen; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { @@ -250,8 +250,8 @@ void DebugNamesDWARFIndex::GetFunctions( continue; if (llvm::Optional ref = ToDIERef(entry)) { - if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, - name_type_mask, [&](DWARFDIE die) { + if (!ProcessFunctionDIE(lookup_info, *ref, dwarf, parent_decl_ctx, + [&](DWARFDIE die) { if (!seen.insert(die.GetDIE()).second) return true; return callback(die); @@ -260,8 +260,7 @@ void DebugNamesDWARFIndex::GetFunctions( } } - m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, - callback); + m_fallback.GetFunctions(lookup_info, dwarf, parent_decl_ctx, callback); } void DebugNamesDWARFIndex::GetFunctions( diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index c451ccd..a0880c6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -46,9 +46,9 @@ public: llvm::function_ref callback) override; void GetNamespaces(ConstString name, llvm::function_ref callback) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + void GetFunctions(const Module::LookupInfo &lookup_info, + SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, llvm::function_ref callback) override; void GetFunctions(const RegularExpression ®ex, llvm::function_ref callback) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index b743c84..86e5653 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -411,10 +411,12 @@ void ManualDWARFIndex::GetNamespaces( } void ManualDWARFIndex::GetFunctions( - ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, llvm::function_ref callback) { Index(); + ConstString name = lookup_info.GetLookupName(); + FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); if (name_type_mask & eFunctionNameTypeFull) { if (!m_set.function_fullnames.Find( diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index 5c5e43d..d95cf50 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -46,9 +46,9 @@ public: llvm::function_ref callback) override; void GetNamespaces(ConstString name, llvm::function_ref callback) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + void GetFunctions(const Module::LookupInfo &lookup_info, + SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, llvm::function_ref callback) override; void GetFunctions(const RegularExpression ®ex, llvm::function_ref callback) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 9d68cb1..af74a7b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -862,6 +862,27 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, func_range); } +ConstString +SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) { + ASSERT_MODULE_LOCK(this); + if (!die.IsValid()) { + return ConstString(); + } + + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to construct demangled name for function"); + return ConstString(); + } + + DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(); + if (!dwarf_ast) + return ConstString(); + + return dwarf_ast->ConstructDemangledNameFromDWARF(die); +} + lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) { SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) @@ -2310,12 +2331,13 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, return false; } -void SymbolFileDWARF::FindFunctions(ConstString name, +void SymbolFileDWARF::FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); + ConstString name = lookup_info.GetLookupName(); + FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (name = '%s')", name.AsCString()); @@ -2347,12 +2369,11 @@ void SymbolFileDWARF::FindFunctions(ConstString name, llvm::DenseSet resolved_dies; - m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, - [&](DWARFDIE die) { - if (resolved_dies.insert(die.GetDIE()).second) - ResolveFunction(die, include_inlines, sc_list); - return true; - }); + m_index->GetFunctions(lookup_info, *this, parent_decl_ctx, [&](DWARFDIE die) { + if (resolved_dies.insert(die.GetDIE()).second) + ResolveFunction(die, include_inlines, sc_list); + return true; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index cfd18f0..235fa7c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -178,9 +178,8 @@ public: uint32_t max_matches, lldb_private::VariableList &variables) override; - void FindFunctions(lldb_private::ConstString name, + void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -329,6 +328,8 @@ public: return m_parse_time; } + lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die); + protected: typedef llvm::DenseMap DIEToTypePtr; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 7637726..7bc6aae 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1004,17 +1004,17 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, } void SymbolFileDWARFDebugMap::FindFunctions( - ConstString name, const CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, bool include_inlines, + const Module::LookupInfo &lookup_info, + const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (name = %s)", - name.GetCString()); + lookup_info.GetLookupName().GetCString()); ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { uint32_t sc_idx = sc_list.GetSize(); - oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, - include_inlines, sc_list); + oso_dwarf->FindFunctions(lookup_info, parent_decl_ctx, include_inlines, + sc_list); if (!sc_list.IsEmpty()) { RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list, sc_idx); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 52c4d77..10a188f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -109,9 +109,8 @@ public: void FindGlobalVariables(const lldb_private::RegularExpression ®ex, uint32_t max_matches, lldb_private::VariableList &variables) override; - void FindFunctions(lldb_private::ConstString name, + void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; void FindFunctions(const lldb_private::RegularExpression ®ex, diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index fbaea33..3325af6 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1563,10 +1563,12 @@ void SymbolFileNativePDB::FindGlobalVariables( } void SymbolFileNativePDB::FindFunctions( - ConstString name, const CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, bool include_inlines, + const Module::LookupInfo &lookup_info, + const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); + ConstString name = lookup_info.GetLookupName(); + FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); // For now we only support lookup by method name or full name. if (!(name_type_mask & eFunctionNameTypeFull || name_type_mask & eFunctionNameTypeMethod)) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 187791b..4bb37d9 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -130,9 +130,8 @@ public: void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override; - void FindFunctions(ConstString name, + void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override; void FindFunctions(const RegularExpression ®ex, bool include_inlines, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index baa4853..da97507 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1305,11 +1305,13 @@ void SymbolFilePDB::CacheFunctionNames() { } void SymbolFilePDB::FindFunctions( - lldb_private::ConstString name, + const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, bool include_inlines, + bool include_inlines, lldb_private::SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); + ConstString name = lookup_info.GetLookupName(); + FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0); if (name_type_mask == eFunctionNameTypeNone) diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 5d4b51b..1292bbe 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -119,9 +119,8 @@ public: uint32_t max_matches, lldb_private::VariableList &variables) override; - void FindFunctions(lldb_private::ConstString name, + void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp index e69150e..362f6ba 100644 --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -120,9 +120,8 @@ void SymbolFile::FindGlobalVariables(const RegularExpression ®ex, uint32_t max_matches, VariableList &variables) {} -void SymbolFile::FindFunctions(ConstString name, +void SymbolFile::FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) {} diff --git a/lldb/source/Symbol/SymbolFileOnDemand.cpp b/lldb/source/Symbol/SymbolFileOnDemand.cpp index b97bc54..b4c9ed0 100644 --- a/lldb/source/Symbol/SymbolFileOnDemand.cpp +++ b/lldb/source/Symbol/SymbolFileOnDemand.cpp @@ -375,9 +375,11 @@ void SymbolFileOnDemand::FindFunctions(const RegularExpression ®ex, } void SymbolFileOnDemand::FindFunctions( - ConstString name, const CompilerDeclContext &parent_decl_ctx, - FunctionNameType name_type_mask, bool include_inlines, + const Module::LookupInfo &lookup_info, + const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) { + ConstString name = lookup_info.GetLookupName(); + FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); if (!m_debug_info_enabled) { Log *log = GetLog(); @@ -402,7 +404,7 @@ void SymbolFileOnDemand::FindFunctions( // allow the FindFucntions to go through. SetLoadDebugInfoEnabled(); } - return m_sym_file_impl->FindFunctions(name, parent_decl_ctx, name_type_mask, + return m_sym_file_impl->FindFunctions(lookup_info, parent_decl_ctx, include_inlines, sc_list); } diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index c0dd95d..5c7b128 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -505,8 +505,9 @@ Error opts::symbols::findFunctions(lldb_private::Module &Module) { ContextOr->IsValid() ? *ContextOr : CompilerDeclContext(); List.Clear(); - Symfile.FindFunctions(ConstString(Name), ContextPtr, getFunctionNameFlags(), - true, List); + Module::LookupInfo lookup_info(ConstString(Name), getFunctionNameFlags(), + eLanguageTypeUnknown); + Symfile.FindFunctions(lookup_info, ContextPtr, true, List); } outs() << formatv("Found {0} functions:\n", List.GetSize()); StreamString Stream; -- 2.7.4