//===-- LLVMUserExpression.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_LLVMUserExpression_h
#define liblldb_LLVMUserExpression_h

#include <map>
#include <string>
#include <vector>

#include "llvm/IR/LegacyPassManager.h"

#include "lldb/Expression/UserExpression.h"

namespace lldb_private {

/// \class LLVMUserExpression LLVMUserExpression.h
/// "lldb/Expression/LLVMUserExpression.h" Encapsulates a one-time expression
/// for use in lldb.
///
/// LLDB uses expressions for various purposes, notably to call functions
/// and as a backend for the expr command.  LLVMUserExpression is a virtual
/// base class that encapsulates the objects needed to parse and JIT an
/// expression. The actual parsing part will be provided by the specific
/// implementations of LLVMUserExpression - which will be vended through the
/// appropriate TypeSystem.
class LLVMUserExpression : public UserExpression {
public:
  /// LLVM-style RTTI support.
  static bool classof(const Expression *E) {
    return E->getKind() == eKindLLVMUserExpression;
  }

  // The IRPasses struct is filled in by a runtime after an expression is
  // compiled and can be used to to run fixups/analysis passes as required.
  // EarlyPasses are run on the generated module before lldb runs its own IR
  // fixups and inserts instrumentation code/pointer checks. LatePasses are run
  // after the module has been processed by llvm, before the module is
  // assembled and run in the ThreadPlan.
  struct IRPasses {
    IRPasses() : EarlyPasses(nullptr), LatePasses(nullptr){};
    std::shared_ptr<llvm::legacy::PassManager> EarlyPasses;
    std::shared_ptr<llvm::legacy::PassManager> LatePasses;
  };

  LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
                     llvm::StringRef prefix, lldb::LanguageType language,
                     ResultType desired_type,
                     const EvaluateExpressionOptions &options,
                     ExpressionKind kind);
  ~LLVMUserExpression() override;

  bool FinalizeJITExecution(
      DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
      lldb::ExpressionVariableSP &result,
      lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
      lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override;

  bool CanInterpret() override { return m_can_interpret; }

  /// Return the string that the parser should parse.  Must be a full
  /// translation unit.
  const char *Text() override { return m_transformed_text.c_str(); }

  lldb::ModuleSP GetJITModule() override;

protected:
  lldb::ExpressionResults
  DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
            const EvaluateExpressionOptions &options,
            lldb::UserExpressionSP &shared_ptr_to_me,
            lldb::ExpressionVariableSP &result) override;

  virtual void ScanContext(ExecutionContext &exe_ctx,
                           lldb_private::Status &err) = 0;

  bool PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager,
                                     ExecutionContext &exe_ctx,
                                     lldb::addr_t &struct_address);

  virtual bool AddArguments(ExecutionContext &exe_ctx,
                            std::vector<lldb::addr_t> &args,
                            lldb::addr_t struct_address,
                            DiagnosticManager &diagnostic_manager) = 0;

  lldb::addr_t
      m_stack_frame_bottom;       ///< The bottom of the allocated stack frame.
  lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame.

  bool m_allow_cxx;  ///< True if the language allows C++.
  bool m_allow_objc; ///< True if the language allows Objective-C.
  std::string
      m_transformed_text; ///< The text of the expression, as send to the parser

  std::shared_ptr<IRExecutionUnit>
      m_execution_unit_sp; ///< The execution unit the expression is stored in.
  std::unique_ptr<Materializer> m_materializer_up; ///< The materializer to use
                                                   /// when running the
                                                   /// expression.
  lldb::ModuleWP m_jit_module_wp;
  bool m_enforce_valid_object; ///< True if the expression parser should enforce
                               ///the presence of a valid class pointer
  /// in order to generate the expression as a method.
  bool m_in_cplusplus_method;  ///< True if the expression is compiled as a C++
                               ///member function (true if it was parsed
                               /// when exe_ctx was in a C++ method).
  bool m_in_objectivec_method; ///< True if the expression is compiled as an
                               ///Objective-C method (true if it was parsed
                               /// when exe_ctx was in an Objective-C method).
  bool m_in_static_method; ///< True if the expression is compiled as a static
                           ///(or class) method (currently true if it
  /// was parsed when exe_ctx was in an Objective-C class method).
  bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and
                           ///passed in.  False if the expression
                           /// doesn't really use them and they can be NULL.
  bool m_const_object;     ///< True if "this" is const.
  Target *m_target; ///< The target for storing persistent data like types and
                    ///variables.

  bool m_can_interpret; ///< True if the expression could be evaluated
                        ///statically; false otherwise.
  lldb::addr_t m_materialized_address; ///< The address at which the arguments
                                       ///to the expression have been
                                       ///materialized.
  Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer.
};

} // namespace lldb_private
#endif
