//===-- 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 LLDB_CORE_SEARCHFILTER_H
#define LLDB_CORE_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) = 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_sp
  ///    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.
  ///
  /// \note the default implementation always returns \c true.
  virtual bool ModulePasses(const FileSpec &spec);

  /// Call this method with a Module to see if that module passes the filter.
  ///
  /// \param[in] module_sp
  ///    The Module to check against the filter.
  ///
  /// \return
  ///    \b true if \a module passes, and \b false otherwise.
  ///
  /// \note the default implementation always returns \c true.
  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.
  ///
  /// \note the default implementation always returns \c true.
  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.
  ///
  /// \note the default implementation always returns \c true.
  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.
  ///
  /// \note the default implementation always returns \c true.
  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 CreateCopy(lldb::TargetSP& target_sp);

  static lldb::SearchFilterSP
  CreateFromStructuredData(const lldb::TargetSP& target_sp,
                           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 DoCreateCopy() = 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(const lldb::TargetSP& target_sp,
                           const StructuredData::Dictionary &data_dict,
                           Status &error);

  StructuredData::ObjectSP SerializeToStructuredData() override;

protected:
  lldb::SearchFilterSP DoCreateCopy() 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] targetSP
  ///    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;

  void GetDescription(Stream *s) override;

  uint32_t GetFilterRequiredItems() override;

  void Dump(Stream *s) const override;

  void Search(Searcher &searcher) override;

  static lldb::SearchFilterSP
  CreateFromStructuredData(const lldb::TargetSP& target_sp,
                           const StructuredData::Dictionary &data_dict,
                           Status &error);

  StructuredData::ObjectSP SerializeToStructuredData() override;

protected:
  lldb::SearchFilterSP DoCreateCopy() 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] targetSP
  ///    The Target that provides the module list to search.
  ///
  /// \param[in] module_list
  ///    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() override;

  bool ModulePasses(const lldb::ModuleSP &module_sp) override;

  bool ModulePasses(const FileSpec &spec) override;

  bool AddressPasses(Address &address) 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(const lldb::TargetSP& target_sp,
                           const StructuredData::Dictionary &data_dict,
                           Status &error);

  StructuredData::ObjectSP SerializeToStructuredData() override;

  void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp);

protected:
  lldb::SearchFilterSP DoCreateCopy() override;

  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.
  SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP,
                                const FileSpecList &module_list,
                                const FileSpecList &cu_list);

  ~SearchFilterByModuleListAndCU() 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(const lldb::TargetSP& target_sp,
                           const StructuredData::Dictionary &data_dict,
                           Status &error);

  StructuredData::ObjectSP SerializeToStructuredData() override;

protected:
  lldb::SearchFilterSP DoCreateCopy() override;

private:
  FileSpecList m_cu_spec_list;
};

} // namespace lldb_private

#endif // LLDB_CORE_SEARCHFILTER_H
