blob: 01dcadd12124b61b00cabe4ef5905aea924fad81 [file] [log] [blame]
//===-- SearchFilter.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_SearchFilter_h_
#define liblldb_SearchFilter_h_
#include "lldb/Core/FileSpecList.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-forward.h"
#include <stdint.h>
namespace lldb_private {
class Address;
class Breakpoint;
class CompileUnit;
class Status;
class Function;
class ModuleList;
class SearchFilter;
class Stream;
class SymbolContext;
class Target;
}
namespace lldb_private {
/// \class Searcher SearchFilter.h "lldb/Core/SearchFilter.h" Class that is
/// driven by the SearchFilter to search the SymbolContext space of the target
/// program.
/// General Outline:
/// Provides the callback and search depth for the SearchFilter search.
class Searcher {
public:
enum CallbackReturn {
eCallbackReturnStop = 0, // Stop the iteration
eCallbackReturnContinue, // Continue the iteration
eCallbackReturnPop // Pop one level up and continue iterating
};
Searcher();
virtual ~Searcher();
virtual CallbackReturn SearchCallback(SearchFilter &filter,
SymbolContext &context, Address *addr,
bool complete) = 0;
virtual lldb::SearchDepth GetDepth() = 0;
/// Prints a canonical description for the searcher to the stream \a s.
///
/// \param[in] s
/// Stream to which the output is copied.
virtual void GetDescription(Stream *s);
};
/// \class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h" Class
/// descends through the SymbolContext space of the target, applying a filter
/// at each stage till it reaches the depth specified by the GetDepth method
/// of the searcher, and calls its callback at that point.
/// General Outline:
/// Provides the callback and search depth for the SearchFilter search.
///
/// The search is done by cooperation between the search filter and the
/// searcher. The search filter does the heavy work of recursing through the
/// SymbolContext space of the target program's symbol space. The Searcher
/// specifies the depth at which it wants its callback to be invoked. Note
/// that since the resolution of the Searcher may be greater than that of the
/// SearchFilter, before the Searcher qualifies an address it should pass it
/// to "AddressPasses." The default implementation is "Everything Passes."
class SearchFilter {
public:
/// The basic constructor takes a Target, which gives the space to search.
///
/// \param[in] target
/// The Target that provides the module list to search.
SearchFilter(const lldb::TargetSP &target_sp);
SearchFilter(const lldb::TargetSP &target_sp, unsigned char filterType);
virtual ~SearchFilter();
/// Call this method with a file spec to see if that spec passes the filter.
///
/// \param[in] spec
/// The file spec to check against the filter.
/// \return
/// \b true if \a spec passes, and \b false otherwise.
virtual bool ModulePasses(const FileSpec &spec);
/// Call this method with a Module to see if that module passes the filter.
///
/// \param[in] module
/// The Module to check against the filter.
///
/// \return
/// \b true if \a module passes, and \b false otherwise.
virtual bool ModulePasses(const lldb::ModuleSP &module_sp);
/// Call this method with a Address to see if \a address passes the filter.
///
/// \param[in] addr
/// The address to check against the filter.
///
/// \return
/// \b true if \a address passes, and \b false otherwise.
virtual bool AddressPasses(Address &addr);
/// Call this method with a FileSpec to see if \a file spec passes the
/// filter as the name of a compilation unit.
///
/// \param[in] fileSpec
/// The file spec to check against the filter.
///
/// \return
/// \b true if \a file spec passes, and \b false otherwise.
virtual bool CompUnitPasses(FileSpec &fileSpec);
/// Call this method with a CompileUnit to see if \a comp unit passes the
/// filter.
///
/// \param[in] compUnit
/// The CompileUnit to check against the filter.
///
/// \return
/// \b true if \a Comp Unit passes, and \b false otherwise.
virtual bool CompUnitPasses(CompileUnit &compUnit);
/// Call this method with a Function to see if \a function passes the
/// filter.
///
/// \param[in] function
/// The Functions to check against the filter.
///
/// \return
/// \b true if \a function passes, and \b false otherwise.
virtual bool FunctionPasses(Function &function);
/// Call this method to do the search using the Searcher.
///
/// \param[in] searcher
/// The searcher to drive with this search.
///
virtual void Search(Searcher &searcher);
/// Call this method to do the search using the Searcher in the module list
/// \a modules.
///
/// \param[in] searcher
/// The searcher to drive with this search.
///
/// \param[in] modules
/// The module list within which to restrict the search.
///
virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules);
/// This determines which items are REQUIRED for the filter to pass. For
/// instance, if you are filtering by Compilation Unit, obviously symbols
/// that have no compilation unit can't pass So return eSymbolContextCU and
/// search callbacks can then short cut the search to avoid looking at
/// things that obviously won't pass.
///
/// \return
/// The required elements for the search, which is an or'ed together
/// set of lldb:SearchContextItem enum's.
///
virtual uint32_t GetFilterRequiredItems();
/// Prints a canonical description for the search filter to the stream \a s.
///
/// \param[in] s
/// Stream to which the output is copied.
virtual void GetDescription(Stream *s);
/// Standard "Dump" method. At present it does nothing.
virtual void Dump(Stream *s) const;
lldb::SearchFilterSP CopyForBreakpoint(Breakpoint &breakpoint);
static lldb::SearchFilterSP
CreateFromStructuredData(Target &target,
const StructuredData::Dictionary &data_dict,
Status &error);
virtual StructuredData::ObjectSP SerializeToStructuredData() {
return StructuredData::ObjectSP();
}
static const char *GetSerializationKey() { return "SearchFilter"; }
static const char *GetSerializationSubclassKey() { return "Type"; }
static const char *GetSerializationSubclassOptionsKey() { return "Options"; }
enum FilterTy {
Unconstrained = 0,
Exception,
ByModule,
ByModules,
ByModulesAndCU,
LastKnownFilterType = ByModulesAndCU,
UnknownFilter
};
static const char *g_ty_to_name[LastKnownFilterType + 2];
enum FilterTy GetFilterTy() {
if (SubclassID > FilterTy::LastKnownFilterType)
return FilterTy::UnknownFilter;
else
return (enum FilterTy)SubclassID;
}
const char *GetFilterName() { return FilterTyToName(GetFilterTy()); }
static const char *FilterTyToName(enum FilterTy);
static FilterTy NameToFilterTy(llvm::StringRef name);
protected:
// Serialization of SearchFilter options:
enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName };
static const char *g_option_names[LastOptionName];
static const char *GetKey(enum OptionNames enum_value) {
return g_option_names[enum_value];
}
StructuredData::DictionarySP
WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);
void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp,
OptionNames name, FileSpecList &file_list);
// These are utility functions to assist with the search iteration. They are
// used by the default Search method.
Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context,
Searcher &searcher);
Searcher::CallbackReturn DoModuleIteration(const lldb::ModuleSP &module_sp,
Searcher &searcher);
Searcher::CallbackReturn DoCUIteration(const lldb::ModuleSP &module_sp,
const SymbolContext &context,
Searcher &searcher);
Searcher::CallbackReturn DoFunctionIteration(Function *function,
const SymbolContext &context,
Searcher &searcher);
virtual lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) = 0;
void SetTarget(lldb::TargetSP &target_sp) { m_target_sp = target_sp; }
lldb::TargetSP
m_target_sp; // Every filter has to be associated with a target for
// now since you need a starting place for the search.
private:
unsigned char SubclassID;
};
/// \class SearchFilterForUnconstrainedSearches SearchFilter.h
/// "lldb/Core/SearchFilter.h" This is a SearchFilter that searches through
/// all modules. It also consults the
/// Target::ModuleIsExcludedForUnconstrainedSearches.
class SearchFilterForUnconstrainedSearches : public SearchFilter {
public:
SearchFilterForUnconstrainedSearches(const lldb::TargetSP &target_sp)
: SearchFilter(target_sp, FilterTy::Unconstrained) {}
~SearchFilterForUnconstrainedSearches() override = default;
bool ModulePasses(const FileSpec &module_spec) override;
bool ModulePasses(const lldb::ModuleSP &module_sp) override;
static lldb::SearchFilterSP
CreateFromStructuredData(Target &target,
const StructuredData::Dictionary &data_dict,
Status &error);
StructuredData::ObjectSP SerializeToStructuredData() override;
protected:
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
};
/// \class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This
/// is a SearchFilter that restricts the search to a given module.
class SearchFilterByModule : public SearchFilter {
public:
/// The basic constructor takes a Target, which gives the space to search,
/// and the module to restrict the search to.
///
/// \param[in] target
/// The Target that provides the module list to search.
///
/// \param[in] module
/// The Module that limits the search.
SearchFilterByModule(const lldb::TargetSP &targetSP, const FileSpec &module);
~SearchFilterByModule() override;
bool ModulePasses(const lldb::ModuleSP &module_sp) override;
bool ModulePasses(const FileSpec &spec) override;
bool AddressPasses(Address &address) override;
bool CompUnitPasses(FileSpec &fileSpec) override;
bool CompUnitPasses(CompileUnit &compUnit) override;
void GetDescription(Stream *s) override;
uint32_t GetFilterRequiredItems() override;
void Dump(Stream *s) const override;
void Search(Searcher &searcher) override;
static lldb::SearchFilterSP
CreateFromStructuredData(Target &target,
const StructuredData::Dictionary &data_dict,
Status &error);
StructuredData::ObjectSP SerializeToStructuredData() override;
protected:
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
private:
FileSpec m_module_spec;
};
class SearchFilterByModuleList : public SearchFilter {
public:
/// The basic constructor takes a Target, which gives the space to search,
/// and the module list to restrict the search to.
///
/// \param[in] target
/// The Target that provides the module list to search.
///
/// \param[in] module
/// The Module that limits the search.
SearchFilterByModuleList(const lldb::TargetSP &targetSP,
const FileSpecList &module_list);
SearchFilterByModuleList(const lldb::TargetSP &targetSP,
const FileSpecList &module_list,
enum FilterTy filter_ty);
SearchFilterByModuleList(const SearchFilterByModuleList &rhs);
~SearchFilterByModuleList() override;
SearchFilterByModuleList &operator=(const SearchFilterByModuleList &rhs);
bool ModulePasses(const lldb::ModuleSP &module_sp) override;
bool ModulePasses(const FileSpec &spec) override;
bool AddressPasses(Address &address) override;
bool CompUnitPasses(FileSpec &fileSpec) override;
bool CompUnitPasses(CompileUnit &compUnit) override;
void GetDescription(Stream *s) override;
uint32_t GetFilterRequiredItems() override;
void Dump(Stream *s) const override;
void Search(Searcher &searcher) override;
static lldb::SearchFilterSP
CreateFromStructuredData(Target &target,
const StructuredData::Dictionary &data_dict,
Status &error);
StructuredData::ObjectSP SerializeToStructuredData() override;
void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp);
protected:
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
protected:
FileSpecList m_module_spec_list;
};
class SearchFilterByModuleListAndCU : public SearchFilterByModuleList {
public:
/// The basic constructor takes a Target, which gives the space to search,
/// and the module list to restrict the search to.
///
/// \param[in] target
/// The Target that provides the module list to search.
///
/// \param[in] module
/// The Module that limits the search.
SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP,
const FileSpecList &module_list,
const FileSpecList &cu_list);
SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU &rhs);
~SearchFilterByModuleListAndCU() override;
SearchFilterByModuleListAndCU &
operator=(const SearchFilterByModuleListAndCU &rhs);
bool AddressPasses(Address &address) override;
bool CompUnitPasses(FileSpec &fileSpec) override;
bool CompUnitPasses(CompileUnit &compUnit) override;
void GetDescription(Stream *s) override;
uint32_t GetFilterRequiredItems() override;
void Dump(Stream *s) const override;
void Search(Searcher &searcher) override;
static lldb::SearchFilterSP
CreateFromStructuredData(Target &target,
const StructuredData::Dictionary &data_dict,
Status &error);
StructuredData::ObjectSP SerializeToStructuredData() override;
protected:
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
private:
FileSpecList m_cu_spec_list;
};
} // namespace lldb_private
#endif // liblldb_SearchFilter_h_