forked from OSchip/llvm-project
[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:
parent
1486a2eaf0
commit
befa77e59a
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ®ex,
|
||||
llvm::function_ref<bool(DWARFDIE die)> callback) override;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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 ®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<bool(DWARFDIE die)> callback);
|
||||
|
||||
class DIERefCallbackImpl {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 ®ex,
|
||||
llvm::function_ref<bool(DWARFDIE die)> callback) override;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 ®ex,
|
||||
llvm::function_ref<bool(DWARFDIE die)> callback) override;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue