/* Thread command's finish-state machine, for GDB, the GNU debugger.
   Copyright (C) 2015-2024 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_THREAD_FSM_H
#define GDB_THREAD_FSM_H

#include "mi/mi-common.h"

struct return_value_info;
struct thread_fsm_ops;
struct type;
struct value;

/* The captured function return value/type and its position in the
   value history.  */

struct return_value_info
{
  /* The captured return value.  May be NULL if we weren't able to
     retrieve it.  See get_return_value.  */
  struct value *value;

  /* The return type.  In some cases, we'll not be able extract the
     return value, but we always know the type.  */
  struct type *type;

  /* If we captured a value, this is the value history index.  */
  int value_history_index;
};

/* A thread finite-state machine structure contains the necessary info
   and callbacks to manage the state machine protocol of a thread's
   execution command.  */

struct thread_fsm
{
  explicit thread_fsm (struct interp *cmd_interp)
    : command_interp (cmd_interp)
  {
  }

  /* The destructor.  This should simply free heap allocated data
     structures.  Cleaning up target resources (like, e.g.,
     breakpoints) should be done in the clean_up method.  */
  virtual ~thread_fsm () = default;

  DISABLE_COPY_AND_ASSIGN (thread_fsm);

  /* Called to clean up target resources after the FSM.  E.g., if the
     FSM created internal breakpoints, this is where they should be
     deleted.  */
  virtual void clean_up (struct thread_info *thread)
  {
  }

  /* Called after handle_inferior_event decides the target is done
     (that is, after stop_waiting).  The FSM is given a chance to
     decide whether the command is done and thus the target should
     stop, or whether there's still more to do and thus the thread
     should be re-resumed.  This is a good place to cache target data
     too.  For example, the "finish" command saves the just-finished
     function's return value here.  */
  virtual bool should_stop (struct thread_info *thread) = 0;

  /* If this FSM saved a function's return value, you can use this
     method to retrieve it.  Otherwise, this returns NULL.  */
  virtual struct return_value_info *return_value ()
  {
    return nullptr;
  }

  enum async_reply_reason async_reply_reason ()
  {
    /* If we didn't finish, then the stop reason must come from
       elsewhere.  E.g., a breakpoint hit or a signal intercepted.  */
    gdb_assert (finished_p ());
    return do_async_reply_reason ();
  }

  /* Whether the stop should be notified to the user/frontend.  */
  virtual bool should_notify_stop ()
  {
    return true;
  }

  void set_finished ()
  {
    finished = true;
  }

  bool finished_p () const
  {
    return finished;
  }

  /* The interpreter that issued the execution command that caused
     this thread to resume.  If the top level interpreter is MI/async,
     and the execution command was a CLI command (next/step/etc.),
     we'll want to print stop event output to the MI console channel
     (the stepped-to line, etc.), as if the user entered the execution
     command on a real GDB console.  */
  struct interp *command_interp = nullptr;

protected:

  /* Whether the FSM is done successfully.  */
  bool finished = false;

  /* The async_reply_reason that is broadcast to MI clients if this
     FSM finishes successfully.  */
  virtual enum async_reply_reason do_async_reply_reason ()
  {
    gdb_assert_not_reached ("should not call async_reply_reason here");
  }
};

#endif /* GDB_THREAD_FSM_H */
