//===-- DWARFExpressionList.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_EXPRESSION_DWARFEXPRESSIONLIST_H
#define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H

#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/Optional.h"

class DWARFUnit;

namespace lldb_private {

/// \class DWARFExpressionList DWARFExpressionList.h
/// "lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file
/// address range to a single DWARF location expression.
class DWARFExpressionList {
public:
  DWARFExpressionList() = default;

  DWARFExpressionList(lldb::ModuleSP module_sp, const DWARFUnit *dwarf_cu,
                      lldb::addr_t func_file_addr)
      : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu),
        m_func_file_addr(func_file_addr) {}

  DWARFExpressionList(lldb::ModuleSP module_sp, DWARFExpression expr,
                      const DWARFUnit *dwarf_cu)
      : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu) {
    AddExpression(0, LLDB_INVALID_ADDRESS, expr);
  }

  /// Return true if the location expression contains data
  bool IsValid() const { return !m_exprs.IsEmpty(); }

  void Clear() { m_exprs.Clear(); }

  // Return true if the location expression is always valid.
  bool IsAlwaysValidSingleExpr() const;

  bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr);

  /// Get the expression data at the file address.
  bool GetExpressionData(DataExtractor &data,
                         lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS,
                         lldb::addr_t file_addr = 0) const;

  /// Sort m_expressions.
  void Sort() { m_exprs.Sort(); }

  void SetFuncFileAddress(lldb::addr_t func_file_addr) {
    m_func_file_addr = func_file_addr;
  }

  lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }

  const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr,
                                                lldb::addr_t load_addr) const;

  const DWARFExpression *GetAlwaysValidExpr() const;

  DWARFExpression *GetMutableExpressionAtAddress(
      lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS,
      lldb::addr_t load_addr = 0);

  size_t GetSize() const { return m_exprs.GetSize(); }

  bool ContainsThreadLocalStorage() const;

  bool LinkThreadLocalStorage(
      lldb::ModuleSP new_module_sp,
      std::function<lldb::addr_t(lldb::addr_t file_addr)> const
          &link_address_callback);

  bool MatchesOperand(StackFrame &frame,
                      const Instruction::Operand &operand) const;

  /// Dump locations that contains file_addr if it's valid. Otherwise. dump all
  /// locations.
  bool DumpLocations(Stream *s, lldb::DescriptionLevel level,
                     lldb::addr_t func_load_addr, lldb::addr_t file_addr,
                     ABI *abi) const;

  /// Dump all locaitons with each seperated by new line.
  void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;

  /// Search for a load address in the dwarf location list
  ///
  /// \param[in] func_load_addr
  ///     The actual address of the function containing this location list.
  ///
  /// \param[in] addr
  ///     The address to resolve.
  ///
  /// \return
  ///     True if IsLocationList() is true and the address was found;
  ///     false otherwise.
  //    bool
  //    LocationListContainsLoadAddress (Process* process, const Address &addr)
  //    const;
  //
  bool ContainsAddress(lldb::addr_t func_load_addr, lldb::addr_t addr) const;

  void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }

  bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
                lldb::addr_t func_load_addr, const Value *initial_value_ptr,
                const Value *object_address_ptr, Value &result,
                Status *error_ptr) const;

private:
  // RangeDataVector requires a comparator for DWARFExpression, but it doesn't
  // make sense to do so.
  struct DWARFExpressionCompare {
  public:
    bool operator()(const DWARFExpression &lhs,
                    const DWARFExpression &rhs) const {
      return false;
    }
  };
  using ExprVec = RangeDataVector<lldb::addr_t, lldb::addr_t, DWARFExpression,
                                  0, DWARFExpressionCompare>;
  using Entry = ExprVec::Entry;

  // File address range mapping to single dwarf expression.
  ExprVec m_exprs;

  /// Module which defined this expression.
  lldb::ModuleWP m_module_wp;

  /// The DWARF compile unit this expression belongs to. It is used to evaluate
  /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
  /// DW_OP_GNU_const_index)
  const DWARFUnit *m_dwarf_cu = nullptr;

  // Function base file address.
  lldb::addr_t m_func_file_addr = LLDB_INVALID_ADDRESS;

  using const_iterator = ExprVec::Collection::const_iterator;
  const_iterator begin() const { return m_exprs.begin(); }
  const_iterator end() const { return m_exprs.end(); }
};
} // namespace lldb_private

#endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
