[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:🅱️:foo we would first search for all instances of foo and then filter
out the results to just names that have a:🅱️: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
This commit is contained in:
Alex Langford 2022-07-12 08:51:30 -07:00
parent 1486a2eaf0
commit befa77e59a
31 changed files with 237 additions and 149 deletions

View File

@ -85,6 +85,7 @@ struct ModuleFunctionSearchOptions {
class Module : public std::enable_shared_from_this<Module>,
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:

View File

@ -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 &regex,
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 &regex,
bool include_inlines, SymbolContextList &sc_list);

View File

@ -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;

View File

@ -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();

View File

@ -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(const Module::LookupInfo &lookup_info,
const CompilerDeclContext &parent_decl_ctx,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
// Find all the functions (not symbols, but debug information functions...
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();
// Find all the functions (not symbols, but debug information functions...
SymbolFile *symbols = GetSymbolFile();
LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
FindFunctions(lookup_info, parent_decl_ctx, options, sc_list);
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);
}
}
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);
}
}
}
}

View File

@ -425,9 +425,8 @@ void ModuleList::FindFunctions(ConstString name,
std::lock_guard<std::recursive_mutex> 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();

View File

@ -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<std::recursive_mutex> 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);

View File

@ -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 &regex, bool include_inlines,

View File

@ -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<bool(DWARFDIE die)> 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);
});
}

View File

@ -52,9 +52,9 @@ public:
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetNamespaces(ConstString name,
llvm::function_ref<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> callback) override;
void GetFunctions(const RegularExpression &regex,
llvm::function_ref<bool(DWARFDIE die)> callback) override;

View File

@ -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,

View File

@ -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<CompilerType> param_types;
std::vector<clang::ParmVarDecl *> 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<CompilerType> param_types;
std::vector<clang::ParmVarDecl *> 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);

View File

@ -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,

View File

@ -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"

View File

@ -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<bool(DWARFDIE die)> 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 =

View File

@ -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<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> callback) = 0;
virtual void
GetFunctions(const RegularExpression &regex,
@ -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<bool(DWARFDIE die)> callback);
class DIERefCallbackImpl {

View File

@ -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<bool(DWARFDIE die)> callback) {
ConstString name = lookup_info.GetLookupName();
std::set<DWARFDebugInfoEntry *> 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<DIERef> 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(

View File

@ -46,9 +46,9 @@ public:
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetNamespaces(ConstString name,
llvm::function_ref<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> callback) override;
void GetFunctions(const RegularExpression &regex,
llvm::function_ref<bool(DWARFDIE die)> callback) override;

View File

@ -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<bool(DWARFDIE die)> 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(

View File

@ -46,9 +46,9 @@ public:
llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetNamespaces(ConstString name,
llvm::function_ref<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> callback) override;
void GetFunctions(const RegularExpression &regex,
llvm::function_ref<bool(DWARFDIE die)> callback) override;

View File

@ -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<std::recursive_mutex> 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<const DWARFDebugInfoEntry *> 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;

View File

@ -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<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;

View File

@ -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<std::recursive_mutex> 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);

View File

@ -109,9 +109,8 @@ public:
void FindGlobalVariables(const lldb_private::RegularExpression &regex,
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 &regex,

View File

@ -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<std::recursive_mutex> 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))

View File

@ -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 &regex, bool include_inlines,

View File

@ -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<std::recursive_mutex> 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)

View File

@ -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;

View File

@ -120,9 +120,8 @@ void SymbolFile::FindGlobalVariables(const RegularExpression &regex,
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) {}

View File

@ -375,9 +375,11 @@ void SymbolFileOnDemand::FindFunctions(const RegularExpression &regex,
}
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);
}

View File

@ -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;