//===-- 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;
}
namespace lldb_private {
class Breakpoint;
}
namespace lldb_private {
class CompileUnit;
}
namespace lldb_private {
class Status;
}
namespace lldb_private {
class Function;
}
namespace lldb_private {
class ModuleList;
}
namespace lldb_private {
class SearchFilter;
}
namespace lldb_private {
class Stream;
}
namespace lldb_private {
class SymbolContext;
}
namespace lldb_private {
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:
  typedef enum {
    eCallbackReturnStop = 0, // Stop the iteration
    eCallbackReturnContinue, // Continue the iteration
    eCallbackReturnPop       // Pop one level up and continue iterating
  } CallbackReturn;

  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 SearchFilter &rhs);

  SearchFilter(const lldb::TargetSP &target_sp, unsigned char filterType);

  virtual ~SearchFilter();

  SearchFilter &operator=(const SearchFilter &rhs);

  //------------------------------------------------------------------
  /// 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(const SearchFilterByModule &rhs);

  ~SearchFilterByModule() override;

  SearchFilterByModule &operator=(const SearchFilterByModule &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;

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_
