/* Definitions for expressions stored in reversed prefix form, for GDB.

   Copyright (C) 1986-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDB_EXPRESSION_H
#define GDB_EXPRESSION_H

#include "gdbtypes.h"
#include "symtab.h"

/* While parsing expressions we need to track the innermost lexical block
   that we encounter.  In some situations we need to track the innermost
   block just for symbols, and in other situations we want to track the
   innermost block for symbols and registers.  These flags are used by the
   innermost block tracker to control which blocks we consider for the
   innermost block.  These flags can be combined together as needed.  */

enum innermost_block_tracker_type
{
  /* Track the innermost block for symbols within an expression.  */
  INNERMOST_BLOCK_FOR_SYMBOLS = (1 << 0),

  /* Track the innermost block for registers within an expression.  */
  INNERMOST_BLOCK_FOR_REGISTERS = (1 << 1)
};
DEF_ENUM_FLAGS_TYPE (enum innermost_block_tracker_type,
		     innermost_block_tracker_types);

enum exp_opcode : uint8_t
  {
#define OP(name) name ,

#include "std-operator.def"

#undef OP
  };

/* Values of NOSIDE argument to eval_subexp.  */

enum noside
  {
    EVAL_NORMAL,
    EVAL_AVOID_SIDE_EFFECTS	/* Don't modify any variables or
				   call any functions.  The value
				   returned will have the correct
				   type, and will have an
				   approximately correct lvalue
				   type (inaccuracy: anything that is
				   listed as being in a register in
				   the function in which it was
				   declared will be lval_register).
				   Ideally this would not even read
				   target memory, but currently it
				   does in many situations.  */
  };

struct expression;
struct agent_expr;
struct axs_value;
struct type;
struct ui_file;

namespace expr
{

class operation;
typedef std::unique_ptr<operation> operation_up;

/* Base class for an operation.  An operation is a single component of
   an expression.  */

class operation
{
protected:

  operation () = default;
  DISABLE_COPY_AND_ASSIGN (operation);

public:

  virtual ~operation () = default;

  /* Evaluate this operation.  */
  virtual value *evaluate (struct type *expect_type,
			   struct expression *exp,
			   enum noside noside) = 0;

  /* Evaluate this operation in a context where C-like coercion is
     needed.  */
  virtual value *evaluate_with_coercion (struct expression *exp,
					 enum noside noside)
  {
    return evaluate (nullptr, exp, noside);
  }

  /* Evaluate this expression in the context of a cast to
     EXPECT_TYPE.  */
  virtual value *evaluate_for_cast (struct type *expect_type,
				    struct expression *exp,
				    enum noside noside);

  /* Evaluate this expression in the context of a sizeof
     operation.  */
  virtual value *evaluate_for_sizeof (struct expression *exp,
				      enum noside noside);

  /* Evaluate this expression in the context of an address-of
     operation.  Must return the address.  */
  virtual value *evaluate_for_address (struct expression *exp,
				       enum noside noside);

  /* Evaluate a function call, with this object as the callee.
     EXPECT_TYPE, EXP, and NOSIDE have the same meaning as in
     'evaluate'.  ARGS holds the operations that should be evaluated
     to get the arguments to the call.  */
  virtual value *evaluate_funcall (struct type *expect_type,
				   struct expression *exp,
				   enum noside noside,
				   const std::vector<operation_up> &args)
  {
    /* Defer to the helper overload.  */
    return evaluate_funcall (expect_type, exp, noside, nullptr, args);
  }

  /* True if this is a constant expression.  */
  virtual bool constant_p () const
  { return false; }

  /* Return true if this operation uses OBJFILE (and will become
     dangling when OBJFILE is unloaded), otherwise return false.
     OBJFILE must not be a separate debug info file.  */
  virtual bool uses_objfile (struct objfile *objfile) const
  { return false; }

  /* Some expression nodes represent a type, not a value.  This method
     should be overridden to return 'true' in these situations.  */
  virtual bool type_p () const
  { return false; }

  /* Generate agent expression bytecodes for this operation.  */
  void generate_ax (struct expression *exp, struct agent_expr *ax,
		    struct axs_value *value,
		    struct type *cast_type = nullptr);

  /* Return the opcode that is implemented by this operation.  */
  virtual enum exp_opcode opcode () const = 0;

  /* Print this operation to STREAM.  */
  virtual void dump (struct ui_file *stream, int depth) const = 0;

  /* Call to indicate that this is the outermost operation in the
     expression.  This should almost never be overridden.  */
  virtual void set_outermost () { }

protected:

  /* A helper overload that wraps evaluate_subexp_do_call.  */
  value *evaluate_funcall (struct type *expect_type,
			   struct expression *exp,
			   enum noside noside,
			   const char *function_name,
			   const std::vector<operation_up> &args);

  /* Called by generate_ax to do the work for this particular
     operation.  */
  virtual void do_generate_ax (struct expression *exp,
			       struct agent_expr *ax,
			       struct axs_value *value,
			       struct type *cast_type)
  {
    error (_("Cannot translate to agent expression"));
  }
};

/* A helper function for creating an operation_up, given a type.  */
template<typename T, typename... Arg>
operation_up
make_operation (Arg... args)
{
  return operation_up (new T (std::forward<Arg> (args)...));
}

}

struct expression
{
  expression (const struct language_defn *lang, struct gdbarch *arch)
    : language_defn (lang),
      gdbarch (arch)
  {
  }

  DISABLE_COPY_AND_ASSIGN (expression);

  /* Return the opcode for the outermost sub-expression of this
     expression.  */
  enum exp_opcode first_opcode () const
  {
    return op->opcode ();
  }

  /* Dump the expression to STREAM.  */
  void dump (struct ui_file *stream)
  {
    op->dump (stream, 0);
  }

  /* Call the type_p method on the outermost sub-expression of this
     expression, and return the result.  */
  bool type_p () const
  { return op->type_p (); }

  /* Return true if this expression uses OBJFILE (and will become
     dangling when OBJFILE is unloaded), otherwise return false.
     OBJFILE must not be a separate debug info file.  */
  bool uses_objfile (struct objfile *objfile) const;

  /* Evaluate the expression.  EXPECT_TYPE is the context type of the
     expression; normally this should be nullptr.  NOSIDE controls how
     evaluation is performed.  */
  struct value *evaluate (struct type *expect_type = nullptr,
			  enum noside noside = EVAL_NORMAL);

  /* Evaluate an expression, avoiding all memory references
     and getting a value whose type alone is correct.  */
  struct value *evaluate_type ()
  { return evaluate (nullptr, EVAL_AVOID_SIDE_EFFECTS); }

  /* Language it was entered in.  */
  const struct language_defn *language_defn;
  /* Architecture it was parsed in.  */
  struct gdbarch *gdbarch;
  expr::operation_up op;
};

typedef std::unique_ptr<expression> expression_up;

/* When parsing expressions we track the innermost block that was
   referenced.  */

class innermost_block_tracker
{
public:
  innermost_block_tracker (innermost_block_tracker_types types
			   = INNERMOST_BLOCK_FOR_SYMBOLS)
    : m_types (types),
      m_innermost_block (NULL)
  { /* Nothing.  */ }

  /* Update the stored innermost block if the new block B is more inner
     than the currently stored block, or if no block is stored yet.  The
     type T tells us whether the block B was for a symbol or for a
     register.  The stored innermost block is only updated if the type T is
     a type we are interested in, the types we are interested in are held
     in M_TYPES and set during RESET.  */
  void update (const struct block *b, innermost_block_tracker_types t);

  /* Overload of main UPDATE method which extracts the block from BS.  */
  void update (const struct block_symbol &bs)
  {
    update (bs.block, INNERMOST_BLOCK_FOR_SYMBOLS);
  }

  /* Return the stored innermost block.  Can be nullptr if no symbols or
     registers were found during an expression parse, and so no innermost
     block was defined.  */
  const struct block *block () const
  {
    return m_innermost_block;
  }

private:
  /* The type of innermost block being looked for.  */
  innermost_block_tracker_types m_types;

  /* The currently stored innermost block found while parsing an
     expression.  */
  const struct block *m_innermost_block;
};

/* Flags that can affect the parsers.  */

enum parser_flag
{
  /* This flag is set if the expression is being evaluated in a
     context where a 'void' result type is expected.  Parsers are free
     to ignore this, or to use it to help with overload resolution
     decisions.  */
  PARSER_VOID_CONTEXT = (1 << 0),

  /* This flag is set if a top-level comma terminates the
     expression.  */
  PARSER_COMMA_TERMINATES = (1 << 1),

  /* This flag is set if the parser should print debugging output as
     it parses.  For yacc-based parsers, this translates to setting
     yydebug.  */
  PARSER_DEBUG = (1 << 2),

  /* Normally the expression-parsing functions like parse_exp_1 will
     attempt to find a context block if one is not passed in.  If set,
     this flag suppresses this search and uses a null context for the
     parse.  */
  PARSER_LEAVE_BLOCK_ALONE = (1 << 3),
};
DEF_ENUM_FLAGS_TYPE (enum parser_flag, parser_flags);

/* From parse.c */

extern expression_up parse_expression (const char *,
				       innermost_block_tracker * = nullptr,
				       parser_flags flags = 0);

extern expression_up parse_expression_with_language (const char *string,
						     enum language lang);


class completion_tracker;

/* Base class for expression completion.  An instance of this
   represents a completion request from the parser.  */
struct expr_completion_base
{
  /* Perform this object's completion.  EXP is the expression in which
     the completion occurs.  TRACKER is the tracker to update with the
     results.  Return true if completion was possible (even if no
     completions were found), false to fall back to ordinary
     expression completion (i.e., symbol names).  */
  virtual bool complete (struct expression *exp,
			 completion_tracker &tracker) = 0;

  virtual ~expr_completion_base () = default;
};

extern expression_up parse_expression_for_completion
     (const char *, std::unique_ptr<expr_completion_base> *completer);

extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
				  const struct block *,
				  parser_flags flags,
				  innermost_block_tracker * = nullptr);

/* From eval.c */

/* Evaluate a function call.  The function to be called is in CALLEE and
   the arguments passed to the function are in ARGVEC.
   FUNCTION_NAME is the name of the function, if known.
   DEFAULT_RETURN_TYPE is used as the function's return type if the return
   type is unknown.  */

extern struct value *evaluate_subexp_do_call (expression *exp,
					      enum noside noside,
					      value *callee,
					      gdb::array_view<value *> argvec,
					      const char *function_name,
					      type *default_return_type);

/* In an OP_RANGE expression, either bound could be empty, indicating
   that its value is by default that of the corresponding bound of the
   array or string.  Also, the upper end of the range can be exclusive
   or inclusive.  So we have six sorts of subrange.  This enumeration
   type is to identify this.  */

enum range_flag : unsigned
{
  /* This is a standard range.  Both the lower and upper bounds are
     defined, and the bounds are inclusive.  */
  RANGE_STANDARD = 0,

  /* The low bound was not given.  */
  RANGE_LOW_BOUND_DEFAULT = 1 << 0,

  /* The high bound was not given.  */
  RANGE_HIGH_BOUND_DEFAULT = 1 << 1,

  /* The high bound of this range is exclusive.  */
  RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,

  /* The range has a stride.  */
  RANGE_HAS_STRIDE = 1 << 3,
};

DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);

#endif /* GDB_EXPRESSION_H */
