Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,22 @@ class Module : public std::enable_shared_from_this<Module>,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list);

/// Find functions by a vector of lookup infos.
///
/// 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_infos
/// The vector of lookup infos of the function we are looking for.
///
/// \param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
Comment on lines +323 to +329
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Doxygen comment is missing arguments. I personally think it adds little value compared to the cost of keeping it in sync as the function will eventually change, so I would just omit it.

void FindFunctions(const std::vector<LookupInfo> &lookup_infos,
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,
Expand Down Expand Up @@ -917,8 +933,29 @@ class Module : public std::enable_shared_from_this<Module>,
public:
LookupInfo() = default;

LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask,
lldb::LanguageType language);
/// Creates a vector of lookup infos for function name resolution.
///
/// \param[in] name
/// The function name to search for. This can be a simple name like
/// "foo" or a qualified name like "Class::method".
///
/// \param[in] name_type_mask
/// A bitmask specifying what types of names to search for
/// (e.g., eFunctionNameTypeFull, eFunctionNameTypeBase,
/// eFunctionNameTypeMethod, eFunctionNameTypeAuto). Multiple types
/// can be combined with bitwise OR.
///
/// \param[in] requested_lang_type
/// The language to create lookups for. If eLanguageTypeUnknown is
/// passed, creates one LookupInfo for each language plugin currently
/// available in LLDB. If a specific language is provided, creates only
// a single LookupInfo for that language.
///
/// \return
/// A vector of LookupInfo objects, one per relevant language.
static std::vector<LookupInfo>
MakeLookupInfos(ConstString name, lldb::FunctionNameType name_type_mask,
lldb::LanguageType requested_lang_type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just lang_type?

Suggested change
lldb::LanguageType requested_lang_type);
lldb::LanguageType lang_type);


ConstString GetName() const { return m_name; }

Expand Down Expand Up @@ -959,6 +996,10 @@ class Module : public std::enable_shared_from_this<Module>,
/// If \b true, then demangled names that match will need to contain
/// "m_name" in order to be considered a match
bool m_match_name_after_lookup = false;

private:
LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask,
lldb::LanguageType lang_type);
};

/// Get a unique hash for this module.
Expand Down
14 changes: 14 additions & 0 deletions lldb/include/lldb/Symbol/SymbolContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,20 @@ class SymbolContext {

lldb::LanguageType GetLanguage() const;

/// Compares the two symbol contexts, considering that the symbol may or may
/// not be present. If both symbols are present, compare them, if one of the
/// symbols is not present, consider the symbol contexts as equal as long as
/// the other fields are equal.
///
/// This function exists because SymbolContexts are often created without the
/// symbol, which is filled in later on, after its creation.
static bool CompareConsideringPossiblyNullSymbol(const SymbolContext &lhs,
const SymbolContext &rhs);

/// Compares the two symbol contexts, except for the symbol field.
static bool CompareWithoutSymbol(const SymbolContext &lhs,
const SymbolContext &rhs);

/// Find a block that defines the function represented by this symbol
/// context.
///
Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ class SymbolFile : public PluginInterface {
virtual void FindFunctions(const Module::LookupInfo &lookup_info,
const CompilerDeclContext &parent_decl_ctx,
bool include_inlines, SymbolContextList &sc_list);
virtual void
FindFunctions(const std::vector<Module::LookupInfo> &lookup_infos,
const CompilerDeclContext &parent_decl_ctx,
bool include_inlines, SymbolContextList &sc_list);
virtual void FindFunctions(const RegularExpression &regex,
bool include_inlines, SymbolContextList &sc_list);

Expand Down
33 changes: 22 additions & 11 deletions lldb/source/Breakpoint/BreakpointResolverName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,19 +218,22 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {

void BreakpointResolverName::AddNameLookup(ConstString name,
FunctionNameType name_type_mask) {

Module::LookupInfo lookup(name, name_type_mask, m_language);
m_lookups.emplace_back(lookup);
std::vector<Module::LookupInfo> infos =
Module::LookupInfo::MakeLookupInfos(name, name_type_mask, m_language);
llvm::append_range(m_lookups, infos);

auto add_variant_funcs = [&](Language *lang) {
for (Language::MethodNameVariant variant :
lang->GetMethodNameVariants(name)) {
// FIXME: Should we be adding variants that aren't of type Full?
if (variant.GetType() & lldb::eFunctionNameTypeFull) {
Module::LookupInfo variant_lookup(name, variant.GetType(),
lang->GetLanguageType());
variant_lookup.SetLookupName(variant.GetName());
m_lookups.emplace_back(variant_lookup);
std::vector<Module::LookupInfo> variant_lookups =
Module::LookupInfo::MakeLookupInfos(name, variant.GetType(),
lang->GetLanguageType());
llvm::for_each(variant_lookups, [&](auto &variant_lookup) {
variant_lookup.SetLookupName(variant.GetName());
});
llvm::append_range(m_lookups, variant_lookups);
}
}
return IterationAction::Continue;
Expand Down Expand Up @@ -401,14 +404,22 @@ void BreakpointResolverName::GetDescription(Stream *s) {
if (m_match_type == Breakpoint::Regexp)
s->Printf("regex = '%s'", m_regex.GetText().str().c_str());
else {
size_t num_names = m_lookups.size();
if (num_names == 1)
s->Printf("name = '%s'", m_lookups[0].GetName().GetCString());
// Since there may be many lookups objects for the same name breakpoint (one
// per language available), unique them by name, and operate on those unique
// names.
std::vector<ConstString> unique_lookups;
for (auto &lookup : m_lookups) {
if (!llvm::is_contained(unique_lookups, lookup.GetName()))
unique_lookups.push_back(lookup.GetName());
}
if (unique_lookups.size() == 1)
s->Printf("name = '%s'", unique_lookups[0].GetCString());
else {
size_t num_names = unique_lookups.size();
s->Printf("names = {");
for (size_t i = 0; i < num_names; i++) {
s->Printf("%s'%s'", (i == 0 ? "" : ", "),
m_lookups[i].GetName().GetCString());
unique_lookups[i].GetCString());
}
s->Printf("}");
}
Expand Down
90 changes: 58 additions & 32 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,26 +643,13 @@ void Module::FindCompileUnits(const FileSpec &path,

Module::LookupInfo::LookupInfo(ConstString name,
FunctionNameType name_type_mask,
LanguageType language)
: m_name(name), m_lookup_name(name), m_language(language) {
LanguageType lang_type)
: m_name(name), m_lookup_name(name), m_language(lang_type) {
std::optional<ConstString> basename;

std::vector<Language *> languages;
{
std::vector<LanguageType> lang_types;
if (language != eLanguageTypeUnknown)
lang_types.push_back(language);
else
lang_types = {eLanguageTypeObjC, eLanguageTypeC_plus_plus};

for (LanguageType lang_type : lang_types) {
if (Language *lang = Language::FindPlugin(lang_type))
languages.push_back(lang);
}
}
Language *lang = Language::FindPlugin(lang_type);

if (name_type_mask & eFunctionNameTypeAuto) {
for (Language *lang : languages) {
if (lang) {
auto info = lang->GetFunctionNameInfo(name);
if (info.first != eFunctionNameTypeNone) {
m_name_type_mask |= info.first;
Expand All @@ -679,7 +666,7 @@ Module::LookupInfo::LookupInfo(ConstString name,

} else {
m_name_type_mask = name_type_mask;
for (Language *lang : languages) {
if (lang) {
auto info = lang->GetFunctionNameInfo(name);
if (info.first & m_name_type_mask) {
// If the user asked for FunctionNameTypes that aren't possible,
Expand All @@ -688,14 +675,12 @@ Module::LookupInfo::LookupInfo(ConstString name,
// ObjC)
m_name_type_mask &= info.first;
basename = info.second;
break;
}
// Still try and get a basename in case someone specifies a name type mask
// of eFunctionNameTypeFull and a name like "A::func"
if (name_type_mask & eFunctionNameTypeFull &&
info.first != eFunctionNameTypeNone && !basename && info.second) {
} else if (name_type_mask & eFunctionNameTypeFull &&
info.first != eFunctionNameTypeNone && !basename &&
info.second) {
// Still try and get a basename in case someone specifies a name type
// mask of eFunctionNameTypeFull and a name like "A::func"
basename = info.second;
break;
}
}
}
Expand All @@ -711,6 +696,36 @@ Module::LookupInfo::LookupInfo(ConstString name,
}
}

std::vector<Module::LookupInfo>
Module::LookupInfo::MakeLookupInfos(ConstString name,
lldb::FunctionNameType name_type_mask,
lldb::LanguageType requested_lang_type) {
std::vector<LanguageType> lang_types;
if (requested_lang_type != eLanguageTypeUnknown) {
lang_types.push_back(requested_lang_type);
} else {
// If the language type was not specified, look up in every language
// available.
Language::ForEach([&](Language *lang) {
auto lang_type = lang->GetLanguageType();
if (!llvm::is_contained(lang_types, lang_type))
lang_types.push_back(lang_type);
return IterationAction::Continue;
});

if (lang_types.empty())
lang_types = {eLanguageTypeObjC, eLanguageTypeC_plus_plus};
}

std::vector<Module::LookupInfo> infos;
infos.reserve(lang_types.size());
for (LanguageType lang_type : lang_types) {
Module::LookupInfo info(name, name_type_mask, lang_type);
infos.push_back(info);
}
return infos;
}

bool Module::LookupInfo::NameMatchesLookupInfo(
ConstString function_name, LanguageType language_type) const {
// We always keep unnamed symbols
Expand Down Expand Up @@ -824,18 +839,29 @@ void Module::FindFunctions(const Module::LookupInfo &lookup_info,
}
}

void Module::FindFunctions(const std::vector<Module::LookupInfo> &lookup_infos,
const CompilerDeclContext &parent_decl_ctx,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
for (auto &lookup_info : lookup_infos)
FindFunctions(lookup_info, parent_decl_ctx, options, 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);
std::vector<LookupInfo> lookup_infos =
LookupInfo::MakeLookupInfos(name, name_type_mask, eLanguageTypeUnknown);
for (auto &lookup_info : lookup_infos) {
const size_t old_size = sc_list.GetSize();
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);
}
}
}

Expand Down
48 changes: 26 additions & 22 deletions lldb/source/Core/ModuleList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,21 +453,22 @@ void ModuleList::FindFunctions(ConstString name,
FunctionNameType name_type_mask,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) const {
const size_t old_size = sc_list.GetSize();

if (name_type_mask & eFunctionNameTypeAuto) {
Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);

std::vector<Module::LookupInfo> lookup_infos =
Module::LookupInfo::MakeLookupInfos(name, name_type_mask,
eLanguageTypeUnknown);
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (const ModuleSP &module_sp : m_modules) {
module_sp->FindFunctions(lookup_info, CompilerDeclContext(), options,
sc_list);
}

const size_t new_size = sc_list.GetSize();
for (const auto &lookup_info : lookup_infos) {
const size_t old_size = sc_list.GetSize();
for (const ModuleSP &module_sp : m_modules) {
module_sp->FindFunctions(lookup_info, CompilerDeclContext(), options,
sc_list);
}

if (old_size < new_size)
lookup_info.Prune(sc_list, old_size);
const size_t new_size = sc_list.GetSize();
if (old_size < new_size)
lookup_info.Prune(sc_list, old_size);
}
} else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (const ModuleSP &module_sp : m_modules) {
Expand All @@ -480,21 +481,24 @@ void ModuleList::FindFunctions(ConstString name,
void ModuleList::FindFunctionSymbols(ConstString name,
lldb::FunctionNameType name_type_mask,
SymbolContextList &sc_list) {
const size_t old_size = sc_list.GetSize();

if (name_type_mask & eFunctionNameTypeAuto) {
Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
std::vector<Module::LookupInfo> lookup_infos =
Module::LookupInfo::MakeLookupInfos(name, name_type_mask,
eLanguageTypeUnknown);

std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (const ModuleSP &module_sp : m_modules) {
module_sp->FindFunctionSymbols(lookup_info.GetLookupName(),
lookup_info.GetNameTypeMask(), sc_list);
}
for (const auto &lookup_info : lookup_infos) {
const size_t old_size = sc_list.GetSize();
for (const ModuleSP &module_sp : m_modules) {
module_sp->FindFunctionSymbols(lookup_info.GetLookupName(),
lookup_info.GetNameTypeMask(), sc_list);
}

const size_t new_size = sc_list.GetSize();
const size_t new_size = sc_list.GetSize();

if (old_size < new_size)
lookup_info.Prune(sc_list, old_size);
if (old_size < new_size)
lookup_info.Prune(sc_list, old_size);
}
} else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (const ModuleSP &module_sp : m_modules) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ void SymbolFileBreakpad::FindFunctions(
sc.comp_unit = cu_sp.get();
sc.function = func_sp.get();
sc.module_sp = func_sp->CalculateSymbolContextModule();
sc_list.Append(sc);
sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/true);
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,14 @@ void DWARFIndex::GetNamespacesWithParents(
});
}

void DWARFIndex::GetFunctions(
const std::vector<Module::LookupInfo> &lookup_infos, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
for (auto &lookup_info : lookup_infos)
GetFunctions(lookup_info, dwarf, parent_decl_ctx, callback);
}

IterationAction DWARFIndex::ProcessNamespaceDieMatchParents(
const CompilerDeclContext &parent_decl_ctx, DWARFDIE die,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ class DWARFIndex {
const CompilerDeclContext &parent_decl_ctx,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) = 0;
virtual void
GetFunctions(const std::vector<Module::LookupInfo> &lookup_infos,
SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
llvm::function_ref<IterationAction(DWARFDIE die)> callback);
virtual void
GetFunctions(const RegularExpression &regex,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) = 0;

Expand Down
Loading
Loading