C++-ify struct thread_fsm
authorTom Tromey <tom@tromey.com>
Wed, 2 Jan 2019 21:35:57 +0000 (14:35 -0700)
committerTom Tromey <tom@tromey.com>
Thu, 7 Feb 2019 13:08:33 +0000 (06:08 -0700)
This C++-ifies struct thread_fsm, replacing the "ops" structure with
virtual methods, and changing all the implementations to derive from
thread_fsm.

gdb/ChangeLog
2019-02-07  Tom Tromey  <tom@tromey.com>

* thread.c (thread_cancel_execution_command): Update.
* thread-fsm.h (struct thread_fsm): Add constructor, destructor,
methods.
(struct thread_fsm_ops): Remove.
(thread_fsm_ctor, thread_fsm_delete, thread_fsm_clean_up)
(thread_fsm_should_stop, thread_fsm_return_value)
(thread_fsm_set_finished, thread_fsm_finished_p)
(thread_fsm_async_reply_reason, thread_fsm_should_notify_stop):
Don't declare.
* mi/mi-interp.c (mi_on_normal_stop_1): Update.
* infrun.c (clear_proceed_status_thread)
(clean_up_just_stopped_threads_fsms, fetch_inferior_event)
(print_stop_event): Update.
* infcmd.c (struct step_command_fsm): Inherit from thread_fsm.
Add constructor.
(step_command_fsm_ops): Remove.
(new_step_command_fsm): Remove.
(step_1): Update.
(step_command_fsm::should_stop): Rename from
step_command_fsm_should_stop.
(step_command_fsm::clean_up): Rename from
step_command_fsm_clean_up.
(step_command_fsm::do_async_reply_reason): Rename from
step_command_fsm_async_reply_reason.
(struct until_next_fsm): Inherit from thread_fsm.  Add
constructor.
(until_next_fsm_ops): Remove.
(new_until_next_fsm): Remove.
(until_next_fsm::should_stop): Rename from
until_next_fsm_should_stop.
(until_next_fsm::clean_up): Rename from until_next_fsm_clean_up.
(until_next_fsm::do_async_reply_reason): Rename from
until_next_fsm_async_reply_reason.
(struct finish_command_fsm): Inherit from thread_fsm.  Add
constructor.  Change type of breakpoint.
(finish_command_fsm_ops): Remove.
(new_finish_command_fsm): Remove.
(finish_command_fsm::should_stop): Rename from
finish_command_fsm_should_stop.
(finish_command_fsm::clean_up): Rename from
finish_command_fsm_clean_up.
(finish_command_fsm::return_value): Rename from
finish_command_fsm_return_value.
(finish_command_fsm::do_async_reply_reason): Rename from
finish_command_fsm_async_reply_reason.
(finish_command): Update.
* infcall.c (struct call_thread_fsm): Inherit from thread_fsm.
Add constructor.
(call_thread_fsm_ops): Remove.
(call_thread_fsm::call_thread_fsm): Rename from
new_call_thread_fsm.
(call_thread_fsm::should_stop): Rename from
call_thread_fsm_should_stop.
(call_thread_fsm::should_notify_stop): Rename from
call_thread_fsm_should_notify_stop.
(run_inferior_call, call_function_by_hand_dummy): Update.
* cli/cli-interp.c (should_print_stop_to_console): Update.
* breakpoint.c (struct until_break_fsm): Inherit from thread_fsm.
Add constructor.  Change type of location_breakpoint,
caller_breakpoint.
(until_break_fsm_ops): Remove.
(new_until_break_fsm): Remove.
(until_break_fsm::should_stop): Rename from
until_break_fsm_should_stop.
(until_break_fsm::clean_up): Rename from
until_break_fsm_clean_up.
(until_break_fsm::do_async_reply_reason): Rename from
until_break_fsm_async_reply_reason.
(until_break_command): Update.
* thread-fsm.c: Remove.
* Makefile.in (COMMON_SFILES): Remove thread-fsm.c.

gdb/ChangeLog
gdb/Makefile.in
gdb/breakpoint.c
gdb/cli/cli-interp.c
gdb/infcall.c
gdb/infcmd.c
gdb/infrun.c
gdb/mi/mi-interp.c
gdb/thread-fsm.c [deleted file]
gdb/thread-fsm.h
gdb/thread.c

index c17d05a..a714d50 100644 (file)
@@ -1,5 +1,79 @@
 2019-02-07  Tom Tromey  <tom@tromey.com>
 
+       * thread.c (thread_cancel_execution_command): Update.
+       * thread-fsm.h (struct thread_fsm): Add constructor, destructor,
+       methods.
+       (struct thread_fsm_ops): Remove.
+       (thread_fsm_ctor, thread_fsm_delete, thread_fsm_clean_up)
+       (thread_fsm_should_stop, thread_fsm_return_value)
+       (thread_fsm_set_finished, thread_fsm_finished_p)
+       (thread_fsm_async_reply_reason, thread_fsm_should_notify_stop):
+       Don't declare.
+       * mi/mi-interp.c (mi_on_normal_stop_1): Update.
+       * infrun.c (clear_proceed_status_thread)
+       (clean_up_just_stopped_threads_fsms, fetch_inferior_event)
+       (print_stop_event): Update.
+       * infcmd.c (struct step_command_fsm): Inherit from thread_fsm.
+       Add constructor.
+       (step_command_fsm_ops): Remove.
+       (new_step_command_fsm): Remove.
+       (step_1): Update.
+       (step_command_fsm::should_stop): Rename from
+       step_command_fsm_should_stop.
+       (step_command_fsm::clean_up): Rename from
+       step_command_fsm_clean_up.
+       (step_command_fsm::do_async_reply_reason): Rename from
+       step_command_fsm_async_reply_reason.
+       (struct until_next_fsm): Inherit from thread_fsm.  Add
+       constructor.
+       (until_next_fsm_ops): Remove.
+       (new_until_next_fsm): Remove.
+       (until_next_fsm::should_stop): Rename from
+       until_next_fsm_should_stop.
+       (until_next_fsm::clean_up): Rename from until_next_fsm_clean_up.
+       (until_next_fsm::do_async_reply_reason): Rename from
+       until_next_fsm_async_reply_reason.
+       (struct finish_command_fsm): Inherit from thread_fsm.  Add
+       constructor.  Change type of breakpoint.
+       (finish_command_fsm_ops): Remove.
+       (new_finish_command_fsm): Remove.
+       (finish_command_fsm::should_stop): Rename from
+       finish_command_fsm_should_stop.
+       (finish_command_fsm::clean_up): Rename from
+       finish_command_fsm_clean_up.
+       (finish_command_fsm::return_value): Rename from
+       finish_command_fsm_return_value.
+       (finish_command_fsm::do_async_reply_reason): Rename from
+       finish_command_fsm_async_reply_reason.
+       (finish_command): Update.
+       * infcall.c (struct call_thread_fsm): Inherit from thread_fsm.
+       Add constructor.
+       (call_thread_fsm_ops): Remove.
+       (call_thread_fsm::call_thread_fsm): Rename from
+       new_call_thread_fsm.
+       (call_thread_fsm::should_stop): Rename from
+       call_thread_fsm_should_stop.
+       (call_thread_fsm::should_notify_stop): Rename from
+       call_thread_fsm_should_notify_stop.
+       (run_inferior_call, call_function_by_hand_dummy): Update.
+       * cli/cli-interp.c (should_print_stop_to_console): Update.
+       * breakpoint.c (struct until_break_fsm): Inherit from thread_fsm.
+       Add constructor.  Change type of location_breakpoint,
+       caller_breakpoint.
+       (until_break_fsm_ops): Remove.
+       (new_until_break_fsm): Remove.
+       (until_break_fsm::should_stop): Rename from
+       until_break_fsm_should_stop.
+       (until_break_fsm::clean_up): Rename from
+       until_break_fsm_clean_up.
+       (until_break_fsm::do_async_reply_reason): Rename from
+       until_break_fsm_async_reply_reason.
+       (until_break_command): Update.
+       * thread-fsm.c: Remove.
+       * Makefile.in (COMMON_SFILES): Remove thread-fsm.c.
+
+2019-02-07  Tom Tromey  <tom@tromey.com>
+
        * yy-remap.h: Add include guard.
        * xtensa-tdep.h: Add include guard.
        * xcoffread.h: Rename include guard.
index 72ca855..cb5b740 100644 (file)
@@ -1122,7 +1122,6 @@ COMMON_SFILES = \
        test-target.c \
        thread.c \
        thread-iter.c \
-       thread-fsm.c \
        tid-parse.c \
        top.c \
        tracefile.c \
index b2096c5..bd05707 100644 (file)
@@ -10950,106 +10950,66 @@ awatch_command (const char *arg, int from_tty)
    in infcmd.c.  Here because it uses the mechanisms of
    breakpoints.  */
 
-struct until_break_fsm
+struct until_break_fsm : public thread_fsm
 {
-  /* The base class.  */
-  struct thread_fsm thread_fsm;
-
-  /* The thread that as current when the command was executed.  */
+  /* The thread that was current when the command was executed.  */
   int thread;
 
   /* The breakpoint set at the destination location.  */
-  struct breakpoint *location_breakpoint;
+  breakpoint_up location_breakpoint;
 
   /* Breakpoint set at the return address in the caller frame.  May be
      NULL.  */
-  struct breakpoint *caller_breakpoint;
-};
-
-static void until_break_fsm_clean_up (struct thread_fsm *self,
-                                     struct thread_info *thread);
-static int until_break_fsm_should_stop (struct thread_fsm *self,
-                                       struct thread_info *thread);
-static enum async_reply_reason
-  until_break_fsm_async_reply_reason (struct thread_fsm *self);
+  breakpoint_up caller_breakpoint;
 
-/* until_break_fsm's vtable.  */
+  until_break_fsm (struct interp *cmd_interp, int thread,
+                  breakpoint_up &&location_breakpoint,
+                  breakpoint_up &&caller_breakpoint)
+    : thread_fsm (cmd_interp),
+      thread (thread),
+      location_breakpoint (std::move (location_breakpoint)),
+      caller_breakpoint (std::move (caller_breakpoint))
+  {
+  }
 
-static struct thread_fsm_ops until_break_fsm_ops =
-{
-  NULL, /* dtor */
-  until_break_fsm_clean_up,
-  until_break_fsm_should_stop,
-  NULL, /* return_value */
-  until_break_fsm_async_reply_reason,
+  void clean_up (struct thread_info *thread) override;
+  bool should_stop (struct thread_info *thread) override;
+  enum async_reply_reason do_async_reply_reason () override;
 };
 
-/* Allocate a new until_break_command_fsm.  */
-
-static struct until_break_fsm *
-new_until_break_fsm (struct interp *cmd_interp, int thread,
-                    breakpoint_up &&location_breakpoint,
-                    breakpoint_up &&caller_breakpoint)
-{
-  struct until_break_fsm *sm;
-
-  sm = XCNEW (struct until_break_fsm);
-  thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops, cmd_interp);
-
-  sm->thread = thread;
-  sm->location_breakpoint = location_breakpoint.release ();
-  sm->caller_breakpoint = caller_breakpoint.release ();
-
-  return sm;
-}
-
 /* Implementation of the 'should_stop' FSM method for the
    until(location)/advance commands.  */
 
-static int
-until_break_fsm_should_stop (struct thread_fsm *self,
-                            struct thread_info *tp)
+bool
+until_break_fsm::should_stop (struct thread_info *tp)
 {
-  struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
   if (bpstat_find_breakpoint (tp->control.stop_bpstat,
-                             sm->location_breakpoint) != NULL
-      || (sm->caller_breakpoint != NULL
+                             location_breakpoint.get ()) != NULL
+      || (caller_breakpoint != NULL
          && bpstat_find_breakpoint (tp->control.stop_bpstat,
-                                    sm->caller_breakpoint) != NULL))
-    thread_fsm_set_finished (self);
+                                    caller_breakpoint.get ()) != NULL))
+    set_finished ();
 
-  return 1;
+  return true;
 }
 
 /* Implementation of the 'clean_up' FSM method for the
    until(location)/advance commands.  */
 
-static void
-until_break_fsm_clean_up (struct thread_fsm *self,
-                         struct thread_info *thread)
+void
+until_break_fsm::clean_up (struct thread_info *)
 {
-  struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
   /* Clean up our temporary breakpoints.  */
-  if (sm->location_breakpoint != NULL)
-    {
-      delete_breakpoint (sm->location_breakpoint);
-      sm->location_breakpoint = NULL;
-    }
-  if (sm->caller_breakpoint != NULL)
-    {
-      delete_breakpoint (sm->caller_breakpoint);
-      sm->caller_breakpoint = NULL;
-    }
-  delete_longjmp_breakpoint (sm->thread);
+  location_breakpoint.reset ();
+  caller_breakpoint.reset ();
+  delete_longjmp_breakpoint (thread);
 }
 
 /* Implementation of the 'async_reply_reason' FSM method for the
    until(location)/advance commands.  */
 
-static enum async_reply_reason
-until_break_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+until_break_fsm::do_async_reply_reason ()
 {
   return EXEC_ASYNC_LOCATION_REACHED;
 }
@@ -11063,7 +11023,6 @@ until_break_command (const char *arg, int from_tty, int anywhere)
   struct frame_id caller_frame_id;
   int thread;
   struct thread_info *tp;
-  struct until_break_fsm *sm;
 
   clear_proceed_status (0);
 
@@ -11142,10 +11101,9 @@ until_break_command (const char *arg, int from_tty, int anywhere)
     location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
                                                    stack_frame_id, bp_until);
 
-  sm = new_until_break_fsm (command_interp (), tp->global_num,
-                           std::move (location_breakpoint),
-                           std::move (caller_breakpoint));
-  tp->thread_fsm = &sm->thread_fsm;
+  tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num,
+                                       std::move (location_breakpoint),
+                                       std::move (caller_breakpoint));
 
   if (lj_deleter)
     lj_deleter->release ();
index 0299f3d..088f4f1 100644 (file)
@@ -113,7 +113,7 @@ should_print_stop_to_console (struct interp *console_interp,
        == BPSTAT_WHAT_STOP_NOISY)
       || tp->thread_fsm == NULL
       || tp->thread_fsm->command_interp == console_interp
-      || !thread_fsm_finished_p (tp->thread_fsm))
+      || !tp->thread_fsm->finished_p ())
     return 1;
   return 0;
 }
index 6ca479a..e58ba84 100644 (file)
@@ -470,106 +470,87 @@ get_call_return_value (struct call_return_meta_info *ri)
 /* Data for the FSM that manages an infcall.  It's main job is to
    record the called function's return value.  */
 
-struct call_thread_fsm
+struct call_thread_fsm : public thread_fsm
 {
-  /* The base class.  */
-  struct thread_fsm thread_fsm;
-
   /* All the info necessary to be able to extract the return
      value.  */
   struct call_return_meta_info return_meta_info;
 
   /* The called function's return value.  This is extracted from the
      target before the dummy frame is popped.  */
-  struct value *return_value;
+  struct value *return_value = nullptr;
 
   /* The top level that started the infcall (and is synchronously
      waiting for it to end).  */
   struct ui *waiting_ui;
-};
 
-static int call_thread_fsm_should_stop (struct thread_fsm *self,
-                                       struct thread_info *thread);
-static int call_thread_fsm_should_notify_stop (struct thread_fsm *self);
+  call_thread_fsm (struct ui *waiting_ui, struct interp *cmd_interp,
+                  struct gdbarch *gdbarch, struct value *function,
+                  struct type *value_type,
+                  int struct_return_p, CORE_ADDR struct_addr);
 
-/* call_thread_fsm's vtable.  */
+  bool should_stop (struct thread_info *thread) override;
 
-static struct thread_fsm_ops call_thread_fsm_ops =
-{
-  NULL, /*dtor */
-  NULL, /* clean_up */
-  call_thread_fsm_should_stop,
-  NULL, /* return_value */
-  NULL, /* async_reply_reason*/
-  call_thread_fsm_should_notify_stop,
+  bool should_notify_stop () override;
 };
 
 /* Allocate a new call_thread_fsm object.  */
 
-static struct call_thread_fsm *
-new_call_thread_fsm (struct ui *waiting_ui, struct interp *cmd_interp,
-                    struct gdbarch *gdbarch, struct value *function,
-                    struct type *value_type,
-                    int struct_return_p, CORE_ADDR struct_addr)
+call_thread_fsm::call_thread_fsm (struct ui *waiting_ui,
+                                 struct interp *cmd_interp,
+                                 struct gdbarch *gdbarch,
+                                 struct value *function,
+                                 struct type *value_type,
+                                 int struct_return_p, CORE_ADDR struct_addr)
+  : thread_fsm (cmd_interp),
+    waiting_ui (waiting_ui)
 {
-  struct call_thread_fsm *sm;
-
-  sm = XCNEW (struct call_thread_fsm);
-  thread_fsm_ctor (&sm->thread_fsm, &call_thread_fsm_ops, cmd_interp);
-
-  sm->return_meta_info.gdbarch = gdbarch;
-  sm->return_meta_info.function = function;
-  sm->return_meta_info.value_type = value_type;
-  sm->return_meta_info.struct_return_p = struct_return_p;
-  sm->return_meta_info.struct_addr = struct_addr;
-
-  sm->waiting_ui = waiting_ui;
-
-  return sm;
+  return_meta_info.gdbarch = gdbarch;
+  return_meta_info.function = function;
+  return_meta_info.value_type = value_type;
+  return_meta_info.struct_return_p = struct_return_p;
+  return_meta_info.struct_addr = struct_addr;
 }
 
 /* Implementation of should_stop method for infcalls.  */
 
-static int
-call_thread_fsm_should_stop (struct thread_fsm *self,
-                            struct thread_info *thread)
+bool
+call_thread_fsm::should_stop (struct thread_info *thread)
 {
-  struct call_thread_fsm *f = (struct call_thread_fsm *) self;
-
   if (stop_stack_dummy == STOP_STACK_DUMMY)
     {
       /* Done.  */
-      thread_fsm_set_finished (self);
+      set_finished ();
 
       /* Stash the return value before the dummy frame is popped and
         registers are restored to what they were before the
         call..  */
-      f->return_value = get_call_return_value (&f->return_meta_info);
+      return_value = get_call_return_value (&return_meta_info);
 
       /* Break out of wait_sync_command_done.  */
-      scoped_restore save_ui = make_scoped_restore (&current_ui, f->waiting_ui);
+      scoped_restore save_ui = make_scoped_restore (&current_ui, waiting_ui);
       target_terminal::ours ();
-      f->waiting_ui->prompt_state = PROMPT_NEEDED;
+      waiting_ui->prompt_state = PROMPT_NEEDED;
     }
 
-  return 1;
+  return true;
 }
 
 /* Implementation of should_notify_stop method for infcalls.  */
 
-static int
-call_thread_fsm_should_notify_stop (struct thread_fsm *self)
+bool
+call_thread_fsm::should_notify_stop ()
 {
-  if (thread_fsm_finished_p (self))
+  if (finished_p ())
     {
       /* Infcall succeeded.  Be silent and proceed with evaluating the
         expression.  */
-      return 0;
+      return false;
     }
 
   /* Something wrong happened.  E.g., an unexpected breakpoint
      triggered, or a signal was intercepted.  Notify the stop.  */
-  return 1;
+  return true;
 }
 
 /* Subroutine of call_function_by_hand to simplify it.
@@ -606,7 +587,7 @@ run_inferior_call (struct call_thread_fsm *sm,
   /* Associate the FSM with the thread after clear_proceed_status
      (otherwise it'd clear this FSM), and before anything throws, so
      we don't leak it (and any resources it manages).  */
-  call_thread->thread_fsm = &sm->thread_fsm;
+  call_thread->thread_fsm = sm;
 
   disable_watchpoints_before_interactive_call_start ();
 
@@ -1139,7 +1120,7 @@ call_function_by_hand_dummy (struct value *function,
        not report the stop to the user, and captures the return value
        before the dummy frame is popped.  run_inferior_call registers
        it with the thread ASAP.  */
-    sm = new_call_thread_fsm (current_ui, command_interp (),
+    sm = new call_thread_fsm (current_ui, command_interp (),
                              gdbarch, function,
                              values_type,
                              return_method != return_method_normal,
@@ -1152,9 +1133,9 @@ call_function_by_hand_dummy (struct value *function,
     if (call_thread->state != THREAD_EXITED)
       {
        /* The FSM should still be the same.  */
-       gdb_assert (call_thread->thread_fsm == &sm->thread_fsm);
+       gdb_assert (call_thread->thread_fsm == sm);
 
-       if (thread_fsm_finished_p (call_thread->thread_fsm))
+       if (call_thread->thread_fsm->finished_p ())
          {
            struct value *retval;
 
@@ -1170,8 +1151,8 @@ call_function_by_hand_dummy (struct value *function,
 
            /* Clean up / destroy the call FSM, and restore the
               original one.  */
-           thread_fsm_clean_up (call_thread->thread_fsm, call_thread.get ());
-           thread_fsm_delete (call_thread->thread_fsm);
+           call_thread->thread_fsm->clean_up (call_thread.get ());
+           delete call_thread->thread_fsm;
            call_thread->thread_fsm = saved_sm;
 
            maybe_remove_breakpoints ();
@@ -1182,8 +1163,8 @@ call_function_by_hand_dummy (struct value *function,
 
        /* Didn't complete.  Clean up / destroy the call FSM, and restore the
           previous state machine, and handle the error.  */
-       thread_fsm_clean_up (call_thread->thread_fsm, call_thread.get ());
-       thread_fsm_delete (call_thread->thread_fsm);
+       call_thread->thread_fsm->clean_up (call_thread.get ());
+       delete call_thread->thread_fsm;
        call_thread->thread_fsm = saved_sm;
       }
   }
index dc533bf..c5977c4 100644 (file)
@@ -950,11 +950,8 @@ nexti_command (const char *count_string, int from_tty)
 /* Data for the FSM that manages the step/next/stepi/nexti
    commands.  */
 
-struct step_command_fsm
+struct step_command_fsm : public thread_fsm
 {
-  /* The base class.  */
-  struct thread_fsm thread_fsm;
-
   /* How many steps left in a "step N"-like command.  */
   int count;
 
@@ -963,39 +960,17 @@ struct step_command_fsm
 
   /* If true, this is a stepi/nexti, otherwise a step/step.  */
   int single_inst;
-};
 
-static void step_command_fsm_clean_up (struct thread_fsm *self,
-                                      struct thread_info *thread);
-static int step_command_fsm_should_stop (struct thread_fsm *self,
-                                        struct thread_info *thread);
-static enum async_reply_reason
-  step_command_fsm_async_reply_reason (struct thread_fsm *self);
-
-/* step_command_fsm's vtable.  */
+  explicit step_command_fsm (struct interp *cmd_interp)
+    : thread_fsm (cmd_interp)
+  {
+  }
 
-static struct thread_fsm_ops step_command_fsm_ops =
-{
-  NULL,
-  step_command_fsm_clean_up,
-  step_command_fsm_should_stop,
-  NULL,        /* return_value */
-  step_command_fsm_async_reply_reason,
+  void clean_up (struct thread_info *thread) override;
+  bool should_stop (struct thread_info *thread) override;
+  enum async_reply_reason do_async_reply_reason () override;
 };
 
-/* Allocate a new step_command_fsm.  */
-
-static struct step_command_fsm *
-new_step_command_fsm (struct interp *cmd_interp)
-{
-  struct step_command_fsm *sm;
-
-  sm = XCNEW (struct step_command_fsm);
-  thread_fsm_ctor (&sm->thread_fsm, &step_command_fsm_ops, cmd_interp);
-
-  return sm;
-}
-
 /* Prepare for a step/next/etc. command.  Any target resource
    allocated here is undone in the FSM's clean_up method.  */
 
@@ -1043,8 +1018,8 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string)
   /* Setup the execution command state machine to handle all the COUNT
      steps.  */
   thr = inferior_thread ();
-  step_sm = new_step_command_fsm (command_interp ());
-  thr->thread_fsm = &step_sm->thread_fsm;
+  step_sm = new step_command_fsm (command_interp ());
+  thr->thread_fsm = step_sm;
 
   step_command_fsm_prepare (step_sm, skip_subroutines,
                            single_inst, count, thr);
@@ -1061,7 +1036,7 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string)
 
       /* Stepped into an inline frame.  Pretend that we've
         stopped.  */
-      thread_fsm_clean_up (thr->thread_fsm, thr);
+      thr->thread_fsm->clean_up (thr);
       proceeded = normal_stop ();
       if (!proceeded)
        inferior_event_handler (INF_EXEC_COMPLETE, NULL);
@@ -1075,40 +1050,36 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string)
    return control to the user.  If count is > 1, returns false, as we
    will need to keep going.  */
 
-static int
-step_command_fsm_should_stop (struct thread_fsm *self, struct thread_info *tp)
+bool
+step_command_fsm::should_stop (struct thread_info *tp)
 {
-  struct step_command_fsm *sm = (struct step_command_fsm *) self;
-
   if (tp->control.stop_step)
     {
       /* There are more steps to make, and we did stop due to
         ending a stepping range.  Do another step.  */
-      if (--sm->count > 0)
-       return prepare_one_step (sm);
+      if (--count > 0)
+       return prepare_one_step (this);
 
-      thread_fsm_set_finished (self);
+      set_finished ();
     }
 
-  return 1;
+  return true;
 }
 
 /* Implementation of the 'clean_up' FSM method for stepping commands.  */
 
-static void
-step_command_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread)
+void
+step_command_fsm::clean_up (struct thread_info *thread)
 {
-  struct step_command_fsm *sm = (struct step_command_fsm *) self;
-
-  if (!sm->single_inst || sm->skip_subroutines)
+  if (!single_inst || skip_subroutines)
     delete_longjmp_breakpoint (thread->global_num);
 }
 
 /* Implementation of the 'async_reply_reason' FSM method for stepping
    commands.  */
 
-static enum async_reply_reason
-step_command_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+step_command_fsm::do_async_reply_reason ()
 {
   return EXEC_ASYNC_END_STEPPING_RANGE;
 }
@@ -1198,7 +1169,7 @@ prepare_one_step (struct step_command_fsm *sm)
     }
 
   /* Done.  */
-  thread_fsm_set_finished (&sm->thread_fsm);
+  sm->set_finished ();
   return 1;
 }
 
@@ -1420,66 +1391,39 @@ queue_signal_command (const char *signum_exp, int from_tty)
 /* Data for the FSM that manages the until (with no argument)
    command.  */
 
-struct until_next_fsm
+struct until_next_fsm : public thread_fsm
 {
-  /* The base class.  */
-  struct thread_fsm thread_fsm;
-
   /* The thread that as current when the command was executed.  */
   int thread;
-};
-
-static int until_next_fsm_should_stop (struct thread_fsm *self,
-                                      struct thread_info *thread);
-static void until_next_fsm_clean_up (struct thread_fsm *self,
-                                    struct thread_info *thread);
-static enum async_reply_reason
-  until_next_fsm_async_reply_reason (struct thread_fsm *self);
 
-/* until_next_fsm's vtable.  */
+  until_next_fsm (struct interp *cmd_interp, int thread)
+    : thread_fsm (cmd_interp),
+      thread (thread)
+  {
+  }
 
-static struct thread_fsm_ops until_next_fsm_ops =
-{
-  NULL, /* dtor */
-  until_next_fsm_clean_up,
-  until_next_fsm_should_stop,
-  NULL, /* return_value */
-  until_next_fsm_async_reply_reason,
+  bool should_stop (struct thread_info *thread) override;
+  void clean_up (struct thread_info *thread) override;
+  enum async_reply_reason do_async_reply_reason () override;
 };
 
-/* Allocate a new until_next_fsm.  */
-
-static struct until_next_fsm *
-new_until_next_fsm (struct interp *cmd_interp, int thread)
-{
-  struct until_next_fsm *sm;
-
-  sm = XCNEW (struct until_next_fsm);
-  thread_fsm_ctor (&sm->thread_fsm, &until_next_fsm_ops, cmd_interp);
-
-  sm->thread = thread;
-
-  return sm;
-}
-
 /* Implementation of the 'should_stop' FSM method for the until (with
    no arg) command.  */
 
-static int
-until_next_fsm_should_stop (struct thread_fsm *self,
-                           struct thread_info *tp)
+bool
+until_next_fsm::should_stop (struct thread_info *tp)
 {
   if (tp->control.stop_step)
-    thread_fsm_set_finished (self);
+    set_finished ();
 
-  return 1;
+  return true;
 }
 
 /* Implementation of the 'clean_up' FSM method for the until (with no
    arg) command.  */
 
-static void
-until_next_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread)
+void
+until_next_fsm::clean_up (struct thread_info *thread)
 {
   delete_longjmp_breakpoint (thread->global_num);
 }
@@ -1487,8 +1431,8 @@ until_next_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread)
 /* Implementation of the 'async_reply_reason' FSM method for the until
    (with no arg) command.  */
 
-static enum async_reply_reason
-until_next_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+until_next_fsm::do_async_reply_reason ()
 {
   return EXEC_ASYNC_END_STEPPING_RANGE;
 }
@@ -1550,8 +1494,8 @@ until_next_command (int from_tty)
   set_longjmp_breakpoint (tp, get_frame_id (frame));
   delete_longjmp_breakpoint_cleanup lj_deleter (thread);
 
-  sm = new_until_next_fsm (command_interp (), tp->global_num);
-  tp->thread_fsm = &sm->thread_fsm;
+  sm = new until_next_fsm (command_interp (), tp->global_num);
+  tp->thread_fsm = sm;
   lj_deleter.release ();
 
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
@@ -1718,77 +1662,48 @@ print_return_value (struct ui_out *uiout, struct return_value_info *rv)
 
 /* Data for the FSM that manages the finish command.  */
 
-struct finish_command_fsm
+struct finish_command_fsm : public thread_fsm
 {
-  /* The base class.  */
-  struct thread_fsm thread_fsm;
-
   /* The momentary breakpoint set at the function's return address in
      the caller.  */
-  struct breakpoint *breakpoint;
+  breakpoint_up breakpoint;
 
   /* The function that we're stepping out of.  */
-  struct symbol *function;
+  struct symbol *function = nullptr;
 
   /* If the FSM finishes successfully, this stores the function's
      return value.  */
-  struct return_value_info return_value;
-};
+  struct return_value_info return_value_info {};
 
-static int finish_command_fsm_should_stop (struct thread_fsm *self,
-                                          struct thread_info *thread);
-static void finish_command_fsm_clean_up (struct thread_fsm *self,
-                                        struct thread_info *thread);
-static struct return_value_info *
-  finish_command_fsm_return_value (struct thread_fsm *self);
-static enum async_reply_reason
-  finish_command_fsm_async_reply_reason (struct thread_fsm *self);
-
-/* finish_command_fsm's vtable.  */
-
-static struct thread_fsm_ops finish_command_fsm_ops =
-{
-  NULL, /* dtor */
-  finish_command_fsm_clean_up,
-  finish_command_fsm_should_stop,
-  finish_command_fsm_return_value,
-  finish_command_fsm_async_reply_reason,
-  NULL, /* should_notify_stop */
-};
-
-/* Allocate a new finish_command_fsm.  */
-
-static struct finish_command_fsm *
-new_finish_command_fsm (struct interp *cmd_interp)
-{
-  struct finish_command_fsm *sm;
-
-  sm = XCNEW (struct finish_command_fsm);
-  thread_fsm_ctor (&sm->thread_fsm, &finish_command_fsm_ops, cmd_interp);
+  explicit finish_command_fsm (struct interp *cmd_interp)
+    : thread_fsm (cmd_interp)
+  {
+  }
 
-  return sm;
-}
+  bool should_stop (struct thread_info *thread) override;
+  void clean_up (struct thread_info *thread) override;
+  struct return_value_info *return_value () override;
+  enum async_reply_reason do_async_reply_reason () override;
+};
 
 /* Implementation of the 'should_stop' FSM method for the finish
    commands.  Detects whether the thread stepped out of the function
    successfully, and if so, captures the function's return value and
    marks the FSM finished.  */
 
-static int
-finish_command_fsm_should_stop (struct thread_fsm *self,
-                               struct thread_info *tp)
+bool
+finish_command_fsm::should_stop (struct thread_info *tp)
 {
-  struct finish_command_fsm *f = (struct finish_command_fsm *) self;
-  struct return_value_info *rv = &f->return_value;
+  struct return_value_info *rv = &return_value_info;
 
-  if (f->function != NULL
+  if (function != NULL
       && bpstat_find_breakpoint (tp->control.stop_bpstat,
-                                f->breakpoint) != NULL)
+                                breakpoint.get ()) != NULL)
     {
       /* We're done.  */
-      thread_fsm_set_finished (self);
+      set_finished ();
 
-      rv->type = TYPE_TARGET_TYPE (SYMBOL_TYPE (f->function));
+      rv->type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
       if (rv->type == NULL)
        internal_error (__FILE__, __LINE__,
                        _("finish_command: function has no target type"));
@@ -1797,7 +1712,7 @@ finish_command_fsm_should_stop (struct thread_fsm *self,
        {
          struct value *func;
 
-         func = read_var_value (f->function, NULL, get_current_frame ());
+         func = read_var_value (function, NULL, get_current_frame ());
          rv->value = get_return_value (func, rv->type);
          if (rv->value != NULL)
            rv->value_history_index = record_latest_value (rv->value);
@@ -1807,45 +1722,36 @@ finish_command_fsm_should_stop (struct thread_fsm *self,
     {
       /* Finishing from an inline frame, or reverse finishing.  In
         either case, there's no way to retrieve the return value.  */
-      thread_fsm_set_finished (self);
+      set_finished ();
     }
 
-  return 1;
+  return true;
 }
 
 /* Implementation of the 'clean_up' FSM method for the finish
    commands.  */
 
-static void
-finish_command_fsm_clean_up (struct thread_fsm *self,
-                            struct thread_info *thread)
+void
+finish_command_fsm::clean_up (struct thread_info *thread)
 {
-  struct finish_command_fsm *f = (struct finish_command_fsm *) self;
-
-  if (f->breakpoint != NULL)
-    {
-      delete_breakpoint (f->breakpoint);
-      f->breakpoint = NULL;
-    }
+  breakpoint.reset ();
   delete_longjmp_breakpoint (thread->global_num);
 }
 
 /* Implementation of the 'return_value' FSM method for the finish
    commands.  */
 
-static struct return_value_info *
-finish_command_fsm_return_value (struct thread_fsm *self)
+struct return_value_info *
+finish_command_fsm::return_value ()
 {
-  struct finish_command_fsm *f = (struct finish_command_fsm *) self;
-
-  return &f->return_value;
+  return &return_value_info;
 }
 
 /* Implementation of the 'async_reply_reason' FSM method for the
    finish commands.  */
 
-static enum async_reply_reason
-finish_command_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+finish_command_fsm::do_async_reply_reason ()
 {
   if (execution_direction == EXEC_REVERSE)
     return EXEC_ASYNC_END_STEPPING_RANGE;
@@ -1920,7 +1826,7 @@ finish_forward (struct finish_command_fsm *sm, struct frame_info *frame)
 
   sm->breakpoint = set_momentary_breakpoint (gdbarch, sal,
                                             get_stack_frame_id (frame),
-                                            bp_finish).release ();
+                                            bp_finish);
 
   /* set_momentary_breakpoint invalidates FRAME.  */
   frame = NULL;
@@ -1990,9 +1896,9 @@ finish_command (const char *arg, int from_tty)
 
   tp = inferior_thread ();
 
-  sm = new_finish_command_fsm (command_interp ());
+  sm = new finish_command_fsm (command_interp ());
 
-  tp->thread_fsm = &sm->thread_fsm;
+  tp->thread_fsm = sm;
 
   /* Finishing from an inline frame is completely different.  We don't
      try to show the "return value" - no way to locate it.  */
index a66c46c..b32635f 100644 (file)
@@ -2710,7 +2710,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   if (!signal_pass_state (tp->suspend.stop_signal))
     tp->suspend.stop_signal = GDB_SIGNAL_0;
 
-  thread_fsm_delete (tp->thread_fsm);
+  delete tp->thread_fsm;
   tp->thread_fsm = NULL;
 
   tp->control.trap_expected = 0;
@@ -3610,8 +3610,7 @@ clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
 {
   if (ecs->event_thread != NULL
       && ecs->event_thread->thread_fsm != NULL)
-    thread_fsm_clean_up (ecs->event_thread->thread_fsm,
-                        ecs->event_thread);
+    ecs->event_thread->thread_fsm->clean_up (ecs->event_thread);
 
   if (!non_stop)
     {
@@ -3623,7 +3622,7 @@ clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
            continue;
 
          switch_to_thread (thr);
-         thread_fsm_clean_up (thr->thread_fsm, thr);
+         thr->thread_fsm->clean_up (thr);
        }
 
       if (ecs->event_thread != NULL)
@@ -3766,7 +3765,7 @@ fetch_inferior_event (void *client_data)
            struct thread_fsm *thread_fsm = thr->thread_fsm;
 
            if (thread_fsm != NULL)
-             should_stop = thread_fsm_should_stop (thread_fsm, thr);
+             should_stop = thread_fsm->should_stop (thr);
          }
 
        if (!should_stop)
@@ -3775,16 +3774,13 @@ fetch_inferior_event (void *client_data)
          }
        else
          {
-           int should_notify_stop = 1;
+           bool should_notify_stop = true;
            int proceeded = 0;
 
            clean_up_just_stopped_threads_fsms (ecs);
 
            if (thr != NULL && thr->thread_fsm != NULL)
-             {
-               should_notify_stop
-                 = thread_fsm_should_notify_stop (thr->thread_fsm);
-             }
+             should_notify_stop = thr->thread_fsm->should_notify_stop ();
 
            if (should_notify_stop)
              {
@@ -7886,11 +7882,11 @@ print_stop_event (struct ui_out *uiout)
 
   tp = inferior_thread ();
   if (tp->thread_fsm != NULL
-      && thread_fsm_finished_p (tp->thread_fsm))
+      && tp->thread_fsm->finished_p ())
     {
       struct return_value_info *rv;
 
-      rv = thread_fsm_return_value (tp->thread_fsm);
+      rv = tp->thread_fsm->return_value ();
       if (rv != NULL)
        print_return_value (uiout, rv);
     }
index e45ddfe..3e9f368 100644 (file)
@@ -632,11 +632,11 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
       tp = inferior_thread ();
 
       if (tp->thread_fsm != NULL
-         && thread_fsm_finished_p (tp->thread_fsm))
+         && tp->thread_fsm->finished_p ())
        {
          enum async_reply_reason reason;
 
-         reason = thread_fsm_async_reply_reason (tp->thread_fsm);
+         reason = tp->thread_fsm->async_reply_reason ();
          mi_uiout->field_string ("reason", async_reason_lookup (reason));
        }
       print_stop_event (mi_uiout);
diff --git a/gdb/thread-fsm.c b/gdb/thread-fsm.c
deleted file mode 100644 (file)
index 1f0eed7..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Thread command's finish-state machine, for GDB, the GNU debugger.
-   Copyright (C) 2015-2019 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/>.  */
-
-#include "defs.h"
-#include "thread-fsm.h"
-
-/* See thread-fsm.h.  */
-
-void
-thread_fsm_ctor (struct thread_fsm *self, struct thread_fsm_ops *ops,
-                struct interp *cmd_interp)
-{
-  self->command_interp = cmd_interp;
-  self->finished = 0;
-  self->ops = ops;
-}
-
-/* See thread-fsm.h.  */
-
-void
-thread_fsm_delete (struct thread_fsm *self)
-{
-  if (self != NULL)
-    {
-      if (self->ops->dtor != NULL)
-       self->ops->dtor (self);
-      xfree (self);
-    }
-}
-
-/* See thread-fsm.h.  */
-
-void
-thread_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread)
-{
-  if (self->ops->clean_up != NULL)
-    self->ops->clean_up (self, thread);
-}
-
-/* See thread-fsm.h.  */
-
-int
-thread_fsm_should_stop (struct thread_fsm *self, struct thread_info *thread)
-{
-  return self->ops->should_stop (self, thread);
-}
-
-/* See thread-fsm.h.  */
-
-struct return_value_info *
-thread_fsm_return_value (struct thread_fsm *self)
-{
-  if (self->ops->return_value != NULL)
-    return self->ops->return_value (self);
-  return NULL;
-}
-
-/* See thread-fsm.h.  */
-
-void
-thread_fsm_set_finished (struct thread_fsm *self)
-{
-  self->finished = 1;
-}
-
-/* See thread-fsm.h.  */
-
-int
-thread_fsm_finished_p (struct thread_fsm *self)
-{
-  return self->finished;
-}
-
-/* See thread-fsm.h.  */
-
-enum async_reply_reason
-thread_fsm_async_reply_reason (struct thread_fsm *self)
-{
-  /* If we didn't finish, then the stop reason must come from
-     elsewhere.  E.g., a breakpoint hit or a signal intercepted.  */
-  gdb_assert (thread_fsm_finished_p (self));
-
-  return self->ops->async_reply_reason (self);
-}
-
-/* See thread-fsm.h.  */
-
-int
-thread_fsm_should_notify_stop (struct thread_fsm *self)
-{
-  if (self->ops->should_notify_stop != NULL)
-    return self->ops->should_notify_stop (self);
-  return 1;
-}
index 3f63dbd..57837bf 100644 (file)
@@ -30,34 +30,24 @@ struct thread_fsm_ops;
 
 struct thread_fsm
 {
-  /* Pointer of the virtual table of methods.  */
-  struct thread_fsm_ops *ops;
+  explicit thread_fsm (struct interp *cmd_interp)
+    : command_interp (cmd_interp)
+  {
+  }
 
-  /* Whether the FSM is done successfully.  */
-  int 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;
-};
-
-/* The virtual table of a thread_fsm.  */
-
-struct thread_fsm_ops
-{
   /* 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.  */
-  void (*dtor) (struct thread_fsm *self);
+  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.  */
-  void (*clean_up) (struct thread_fsm *self, struct thread_info *thread);
+  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
@@ -66,50 +56,58 @@ struct thread_fsm_ops
      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.  */
-  int (*should_stop) (struct thread_fsm *self, struct thread_info *thread);
+  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.  */
-  struct return_value_info *(*return_value) (struct thread_fsm *self);
-
-  /* The async_reply_reason that is broadcast to MI clients if this
-     FSM finishes successfully.  */
-  enum async_reply_reason (*async_reply_reason) (struct thread_fsm *self);
+  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.  */
-  int (*should_notify_stop) (struct thread_fsm *self);
-};
-/* Initialize FSM.  */
-extern void thread_fsm_ctor (struct thread_fsm *self,
-                            struct thread_fsm_ops *ops,
-                            struct interp *cmd_interp);
-
-/* Calls the FSM's dtor method, and then frees FSM.  */
-extern void thread_fsm_delete (struct thread_fsm *fsm);
-
-/* Calls the FSM's clean_up method.  */
-extern void thread_fsm_clean_up (struct thread_fsm *fsm,
-                                struct thread_info *thread);
+  virtual bool should_notify_stop ()
+  {
+    return true;
+  }
 
-/* Calls the FSM's should_stop method.  */
-extern int thread_fsm_should_stop (struct thread_fsm *fsm,
-                                  struct thread_info *thread);
+  void set_finished ()
+  {
+    finished = true;
+  }
 
-/* Calls the FSM's return_value method.  */
-extern struct return_value_info *
-  thread_fsm_return_value (struct thread_fsm *fsm);
+  bool finished_p () const
+  {
+    return finished;
+  }
 
-/* Marks the FSM as completed successfully.  */
-extern void thread_fsm_set_finished (struct thread_fsm *fsm);
+  /* 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;
 
-/* Returns true if the FSM completed successfully.  */
-extern int thread_fsm_finished_p (struct thread_fsm *fsm);
+protected:
 
-/* Calls the FSM's reply_reason method.  */
-extern enum async_reply_reason
-  thread_fsm_async_reply_reason (struct thread_fsm *fsm);
+  /* Whether the FSM is done successfully.  */
+  bool finished = false;
 
-/* Calls the FSM's should_notify_stop method.  */
-extern int thread_fsm_should_notify_stop (struct thread_fsm *self);
+  /* 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 /* THREAD_FSM_H */
index 258fb47..6c23252 100644 (file)
@@ -170,8 +170,8 @@ thread_cancel_execution_command (struct thread_info *thr)
 {
   if (thr->thread_fsm != NULL)
     {
-      thread_fsm_clean_up (thr->thread_fsm, thr);
-      thread_fsm_delete (thr->thread_fsm);
+      thr->thread_fsm->clean_up (thr);
+      delete thr->thread_fsm;
       thr->thread_fsm = NULL;
     }
 }