diff mbox

[RFA,v2,07/17] Remove make_cleanup_restore_current_ui

Message ID 1476393012-29987-8-git-send-email-tom@tromey.com
State New
Headers show

Commit Message

Tom Tromey Oct. 13, 2016, 9:10 p.m. UTC
This removes make_cleanup_restore_current_ui by converting the last
use.  The last use was in a few functions used to iterate over all
UIs.  This patch replaces these functions with a class, and arranges
for the class destructor to do the needed cleanup.

2016-10-10  Tom Tromey  <tom@tromey.com>

	* tui/tui-interp.c (tui_on_normal_stop, tui_on_signal_received)
	(tui_on_end_stepping_range, tui_on_signal_exited, tui_on_exited)
	(tui_on_no_history, tui_on_user_selected_context_changed):
	Update.
	* top.h (switch_thru_all_uis): New class.
	(SWITCH_THRU_ALL_UIS): Rewrite.
	(make_cleanup_restore_current_ui, switch_thru_all_uis_init)
	(switch_thru_all_uis_cond, switch_thru_all_uis_next): Don't
	declare.
	* mi/mi-interp.c (mi_new_thread, mi_thread_exit)
	(mi_record_changed, mi_inferior_added, mi_inferior_appeared)
	(mi_inferior_exit, mi_inferior_removed, mi_on_signal_received)
	(mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited)
	(mi_on_no_history, mi_on_normal_stop, mi_traceframe_changed)
	(mi_tsv_created, mi_tsv_deleted, mi_tsv_modified)
	(mi_breakpoint_created, mi_breakpoint_deleted)
	(mi_breakpoint_modified, mi_output_running_pid, mi_on_resume)
	(mi_solib_loaded, mi_solib_unloaded, mi_command_param_changed)
	(mi_memory_changed, mi_user_selected_context_changed): Update.
	* infrun.c (all_uis_check_sync_execution_done)
	(all_uis_on_sync_execution_starting, normal_stop): Update.
	* event-top.c (restore_ui_cleanup)
	(make_cleanup_restore_current_ui, switch_thru_all_uis_init)
	(switch_thru_all_uis_cond, switch_thru_all_uis_next): Remove.
	* cli/cli-interp.c (cli_on_normal_stop, cli_on_signal_received)
	(cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited)
	(cli_on_no_history, cli_on_user_selected_context_changed):
	Update.
	* breakpoint.c (watchpoint_check): Update.
---
 gdb/ChangeLog        |  32 ++++++++++++++++
 gdb/breakpoint.c     |   8 +---
 gdb/cli/cli-interp.c |  27 ++++---------
 gdb/event-top.c      |  50 -------------------------
 gdb/infrun.c         |  15 +++-----
 gdb/mi/mi-interp.c   | 104 +++++++++++++--------------------------------------
 gdb/top.h            |  56 +++++++++++++++++----------
 gdb/tui/tui-interp.c |  27 ++++---------
 8 files changed, 117 insertions(+), 202 deletions(-)

Comments

Pedro Alves Oct. 13, 2016, 10:37 p.m. UTC | #1
On 10/13/2016 10:10 PM, Tom Tromey wrote:

> --- a/gdb/top.h
> +++ b/gdb/top.h
> @@ -155,27 +155,48 @@ extern struct ui *current_ui;
>  /* The list of all UIs.  */
>  extern struct ui *ui_list;
>  
> -/* State for SWITCH_THRU_ALL_UIS.  Declared here because it is meant
> -   to be created on the stack, but should be treated as opaque.  */
> -struct switch_thru_all_uis
> +/* State for SWITCH_THRU_ALL_UIS.  */
> +class switch_thru_all_uis
>  {
> -  struct ui *iter;
> -  struct cleanup *old_chain;
> +public:
> +
> +  switch_thru_all_uis () : m_iter (ui_list), m_save_ui (&current_ui)
> +  {
> +    current_ui = ui_list;
> +  }
> +
> +  // If done iterating, return true; otherwise return false.
> +  bool done () const
> +  {
> +    return m_iter == NULL;
> +  }
> +
> +  // Move to the next UI, setting current_ui if iteration is not yet
> +  // complete.
> +  void next ()
> +  {
> +    m_iter = m_iter->next;
> +    if (m_iter != NULL)
> +      current_ui = m_iter;
> +  }
> +
> + private:
> +
> +  // No need for these.  They are intentionally not defined anywhere.
> +  switch_thru_all_uis &operator= (const switch_thru_all_uis &);
> +  switch_thru_all_uis (const switch_thru_all_uis &);
> +
> +  // Used to iterate through the UIs.
> +  struct ui *m_iter;
> +
> +  // Save and restore current_ui.
> +  scoped_restore_tmpl<struct ui *> m_save_ui;
>  };

// vs /**/ comments.

OK with that change.  Thanks much!

Thanks,
Pedro Alves
diff mbox

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a1e2f6e..04e550a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,35 @@ 
+2016-10-10  Tom Tromey  <tom@tromey.com>
+
+	* tui/tui-interp.c (tui_on_normal_stop, tui_on_signal_received)
+	(tui_on_end_stepping_range, tui_on_signal_exited, tui_on_exited)
+	(tui_on_no_history, tui_on_user_selected_context_changed):
+	Update.
+	* top.h (switch_thru_all_uis): New class.
+	(SWITCH_THRU_ALL_UIS): Rewrite.
+	(make_cleanup_restore_current_ui, switch_thru_all_uis_init)
+	(switch_thru_all_uis_cond, switch_thru_all_uis_next): Don't
+	declare.
+	* mi/mi-interp.c (mi_new_thread, mi_thread_exit)
+	(mi_record_changed, mi_inferior_added, mi_inferior_appeared)
+	(mi_inferior_exit, mi_inferior_removed, mi_on_signal_received)
+	(mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited)
+	(mi_on_no_history, mi_on_normal_stop, mi_traceframe_changed)
+	(mi_tsv_created, mi_tsv_deleted, mi_tsv_modified)
+	(mi_breakpoint_created, mi_breakpoint_deleted)
+	(mi_breakpoint_modified, mi_output_running_pid, mi_on_resume)
+	(mi_solib_loaded, mi_solib_unloaded, mi_command_param_changed)
+	(mi_memory_changed, mi_user_selected_context_changed): Update.
+	* infrun.c (all_uis_check_sync_execution_done)
+	(all_uis_on_sync_execution_starting, normal_stop): Update.
+	* event-top.c (restore_ui_cleanup)
+	(make_cleanup_restore_current_ui, switch_thru_all_uis_init)
+	(switch_thru_all_uis_cond, switch_thru_all_uis_next): Remove.
+	* cli/cli-interp.c (cli_on_normal_stop, cli_on_signal_received)
+	(cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited)
+	(cli_on_no_history, cli_on_user_selected_context_changed):
+	Update.
+	* breakpoint.c (watchpoint_check): Update.
+
 2016-09-26  Tom Tromey  <tom@tromey.com>
 
 	* xcoffread.c (record_minimal_symbol, scan_xcoff_symtab): Add
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index b9bb797..ea4d29a 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5219,8 +5219,6 @@  watchpoint_check (void *p)
     }
   else
     {
-      struct switch_thru_all_uis state;
-
       /* This seems like the only logical thing to do because
          if we temporarily ignored the watchpoint, then when
          we reenter the block in which it is valid it contains
@@ -5235,7 +5233,7 @@  watchpoint_check (void *p)
 	 already.  So we have no choice but print the information
 	 here.  */
 
-      SWITCH_THRU_ALL_UIS (state)
+      SWITCH_THRU_ALL_UIS ()
         {
 	  struct ui_out *uiout = current_uiout;
 
@@ -5416,9 +5414,7 @@  bpstat_check_watchpoint (bpstat bs)
 	    case 0:
 	      /* Error from catch_errors.  */
 	      {
-		struct switch_thru_all_uis state;
-
-		SWITCH_THRU_ALL_UIS (state)
+		SWITCH_THRU_ALL_UIS ()
 	          {
 		    printf_filtered (_("Watchpoint %d deleted.\n"),
 				     b->base.number);
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index cc556a4..dfa96d6 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -99,12 +99,10 @@  should_print_stop_to_console (struct interp *console_interp,
 static void
 cli_on_normal_stop (struct bpstats *bs, int print_frame)
 {
-  struct switch_thru_all_uis state;
-
   if (!print_frame)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *interp = top_level_interpreter ();
       struct cli_interp *cli = as_cli_interp (interp);
@@ -124,9 +122,7 @@  cli_on_normal_stop (struct bpstats *bs, int print_frame)
 static void
 cli_on_signal_received (enum gdb_signal siggnal)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
 
@@ -142,9 +138,7 @@  cli_on_signal_received (enum gdb_signal siggnal)
 static void
 cli_on_end_stepping_range (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
 
@@ -160,9 +154,7 @@  cli_on_end_stepping_range (void)
 static void
 cli_on_signal_exited (enum gdb_signal siggnal)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
 
@@ -178,9 +170,7 @@  cli_on_signal_exited (enum gdb_signal siggnal)
 static void
 cli_on_exited (int exitstatus)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
 
@@ -196,9 +186,7 @@  cli_on_exited (int exitstatus)
 static void
 cli_on_no_history (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
 
@@ -240,7 +228,6 @@  cli_on_command_error (void)
 static void
 cli_on_user_selected_context_changed (user_selected_what selection)
 {
-  struct switch_thru_all_uis state;
   struct thread_info *tp;
 
   /* This event is suppressed.  */
@@ -249,7 +236,7 @@  cli_on_user_selected_context_changed (user_selected_what selection)
 
   tp = find_thread_ptid (inferior_ptid);
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
 
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 576eded..9b0ccbc 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -447,56 +447,6 @@  struct ui *main_ui;
 struct ui *current_ui;
 struct ui *ui_list;
 
-/* A cleanup handler that restores the current UI.  */
-
-static void
-restore_ui_cleanup (void *data)
-{
-  current_ui = (struct ui *) data;
-}
-
-/* See top.h.  */
-
-struct cleanup *
-make_cleanup_restore_current_ui (void)
-{
-  return make_cleanup (restore_ui_cleanup, current_ui);
-}
-
-/* See top.h.  */
-
-void
-switch_thru_all_uis_init (struct switch_thru_all_uis *state)
-{
-  state->iter = ui_list;
-  state->old_chain = make_cleanup_restore_current_ui ();
-}
-
-/* See top.h.  */
-
-int
-switch_thru_all_uis_cond (struct switch_thru_all_uis *state)
-{
-  if (state->iter != NULL)
-    {
-      current_ui = state->iter;
-      return 1;
-    }
-  else
-    {
-      do_cleanups (state->old_chain);
-      return 0;
-    }
-}
-
-/* See top.h.  */
-
-void
-switch_thru_all_uis_next (struct switch_thru_all_uis *state)
-{
-  state->iter = state->iter->next;
-}
-
 /* Get a pointer to the current UI's line buffer.  This is used to
    construct a whole line of input from partial input.  */
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 2883717..1864019 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3855,9 +3855,7 @@  check_curr_ui_sync_execution_done (void)
 void
 all_uis_check_sync_execution_done (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       check_curr_ui_sync_execution_done ();
     }
@@ -3868,9 +3866,7 @@  all_uis_check_sync_execution_done (void)
 void
 all_uis_on_sync_execution_starting (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       if (current_ui->prompt_state == PROMPT_NEEDED)
 	async_disable_stdin ();
@@ -8215,7 +8211,6 @@  normal_stop (void)
   ptid_t last_ptid;
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   ptid_t pid_ptid;
-  struct switch_thru_all_uis state;
 
   get_last_target_status (&last_ptid, &last);
 
@@ -8280,7 +8275,7 @@  normal_stop (void)
       && last.kind != TARGET_WAITKIND_EXITED
       && last.kind != TARGET_WAITKIND_NO_RESUMED)
     {
-      SWITCH_THRU_ALL_UIS (state)
+      SWITCH_THRU_ALL_UIS ()
 	{
 	  target_terminal_ours_for_output ();
 	  printf_filtered (_("[Switching to %s]\n"),
@@ -8292,7 +8287,7 @@  normal_stop (void)
 
   if (last.kind == TARGET_WAITKIND_NO_RESUMED)
     {
-      SWITCH_THRU_ALL_UIS (state)
+      SWITCH_THRU_ALL_UIS ()
 	if (current_ui->prompt_state == PROMPT_BLOCKED)
 	  {
 	    target_terminal_ours_for_output ();
@@ -8309,7 +8304,7 @@  normal_stop (void)
   if (stopped_by_random_signal)
     disable_current_display ();
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       async_enable_stdin ();
     }
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index d7db499..72d63d0 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -344,11 +344,10 @@  static void
 mi_new_thread (struct thread_info *t)
 {
   struct inferior *inf = find_inferior_ptid (t->ptid);
-  struct switch_thru_all_uis state;
 
   gdb_assert (inf);
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -371,12 +370,10 @@  mi_new_thread (struct thread_info *t)
 static void
 mi_thread_exit (struct thread_info *t, int silent)
 {
-  struct switch_thru_all_uis state;
-
   if (silent)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -401,9 +398,7 @@  static void
 mi_record_changed (struct inferior *inferior, int started, const char *method,
 		   const char *format)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -447,9 +442,7 @@  mi_record_changed (struct inferior *inferior, int started, const char *method,
 static void
 mi_inferior_added (struct inferior *inf)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *interp;
       struct mi_interp *mi;
@@ -480,9 +473,7 @@  mi_inferior_added (struct inferior *inf)
 static void
 mi_inferior_appeared (struct inferior *inf)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -504,9 +495,7 @@  mi_inferior_appeared (struct inferior *inf)
 static void
 mi_inferior_exit (struct inferior *inf)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -533,9 +522,7 @@  mi_inferior_exit (struct inferior *inf)
 static void
 mi_inferior_removed (struct inferior *inf)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -584,9 +571,7 @@  find_mi_interp (void)
 static void
 mi_on_signal_received (enum gdb_signal siggnal)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = find_mi_interp ();
 
@@ -603,9 +588,7 @@  mi_on_signal_received (enum gdb_signal siggnal)
 static void
 mi_on_end_stepping_range (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = find_mi_interp ();
 
@@ -622,9 +605,7 @@  mi_on_end_stepping_range (void)
 static void
 mi_on_signal_exited (enum gdb_signal siggnal)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = find_mi_interp ();
 
@@ -641,9 +622,7 @@  mi_on_signal_exited (enum gdb_signal siggnal)
 static void
 mi_on_exited (int exitstatus)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = find_mi_interp ();
 
@@ -660,9 +639,7 @@  mi_on_exited (int exitstatus)
 static void
 mi_on_no_history (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = find_mi_interp ();
 
@@ -734,9 +711,7 @@  mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
 static void
 mi_on_normal_stop (struct bpstats *bs, int print_frame)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       if (as_mi_interp (top_level_interpreter ()) == NULL)
 	continue;
@@ -777,12 +752,10 @@  struct mi_suppress_notification mi_suppress_notification =
 static void
 mi_traceframe_changed (int tfnum, int tpnum)
 {
-  struct switch_thru_all_uis state;
-
   if (mi_suppress_notification.traceframe)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -811,9 +784,7 @@  mi_traceframe_changed (int tfnum, int tpnum)
 static void
 mi_tsv_created (const struct trace_state_variable *tsv)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -839,9 +810,7 @@  mi_tsv_created (const struct trace_state_variable *tsv)
 static void
 mi_tsv_deleted (const struct trace_state_variable *tsv)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -869,9 +838,7 @@  mi_tsv_deleted (const struct trace_state_variable *tsv)
 static void
 mi_tsv_modified (const struct trace_state_variable *tsv)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *mi_uiout;
@@ -909,15 +876,13 @@  mi_tsv_modified (const struct trace_state_variable *tsv)
 static void
 mi_breakpoint_created (struct breakpoint *b)
 {
-  struct switch_thru_all_uis state;
-
   if (mi_suppress_notification.breakpoint)
     return;
 
   if (b->number <= 0)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *mi_uiout;
@@ -963,15 +928,13 @@  mi_breakpoint_created (struct breakpoint *b)
 static void
 mi_breakpoint_deleted (struct breakpoint *b)
 {
-  struct switch_thru_all_uis state;
-
   if (mi_suppress_notification.breakpoint)
     return;
 
   if (b->number <= 0)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -996,15 +959,13 @@  mi_breakpoint_deleted (struct breakpoint *b)
 static void
 mi_breakpoint_modified (struct breakpoint *b)
 {
-  struct switch_thru_all_uis state;
-
   if (mi_suppress_notification.breakpoint)
     return;
 
   if (b->number <= 0)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -1045,9 +1006,8 @@  static int
 mi_output_running_pid (struct thread_info *info, void *arg)
 {
   ptid_t *ptid = (ptid_t *) arg;
-  struct switch_thru_all_uis state;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
 
@@ -1133,7 +1093,6 @@  static void
 mi_on_resume (ptid_t ptid)
 {
   struct thread_info *tp = NULL;
-  struct switch_thru_all_uis state;
 
   if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
     tp = inferior_thread ();
@@ -1144,7 +1103,7 @@  mi_on_resume (ptid_t ptid)
   if (tp->control.in_infcall)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct cleanup *old_chain;
@@ -1164,9 +1123,7 @@  mi_on_resume (ptid_t ptid)
 static void
 mi_solib_loaded (struct so_list *solib)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *uiout;
@@ -1205,9 +1162,7 @@  mi_solib_loaded (struct so_list *solib)
 static void
 mi_solib_unloaded (struct so_list *solib)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *uiout;
@@ -1247,12 +1202,10 @@  mi_solib_unloaded (struct so_list *solib)
 static void
 mi_command_param_changed (const char *param, const char *value)
 {
-  struct switch_thru_all_uis state;
-
   if (mi_suppress_notification.cmd_param_changed)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *mi_uiout;
@@ -1287,12 +1240,10 @@  static void
 mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
 		   ssize_t len, const bfd_byte *myaddr)
 {
-  struct switch_thru_all_uis state;
-
   if (mi_suppress_notification.memory)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *mi_uiout;
@@ -1341,7 +1292,6 @@  mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
 static void
 mi_user_selected_context_changed (user_selected_what selection)
 {
-  struct switch_thru_all_uis state;
   struct thread_info *tp;
 
   /* Don't send an event if we're responding to an MI command.  */
@@ -1350,7 +1300,7 @@  mi_user_selected_context_changed (user_selected_what selection)
 
   tp = find_thread_ptid (inferior_ptid);
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
       struct ui_out *mi_uiout;
diff --git a/gdb/top.h b/gdb/top.h
index acdb8e9..fcf16eb 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -155,27 +155,48 @@  extern struct ui *current_ui;
 /* The list of all UIs.  */
 extern struct ui *ui_list;
 
-/* State for SWITCH_THRU_ALL_UIS.  Declared here because it is meant
-   to be created on the stack, but should be treated as opaque.  */
-struct switch_thru_all_uis
+/* State for SWITCH_THRU_ALL_UIS.  */
+class switch_thru_all_uis
 {
-  struct ui *iter;
-  struct cleanup *old_chain;
+public:
+
+  switch_thru_all_uis () : m_iter (ui_list), m_save_ui (&current_ui)
+  {
+    current_ui = ui_list;
+  }
+
+  // If done iterating, return true; otherwise return false.
+  bool done () const
+  {
+    return m_iter == NULL;
+  }
+
+  // Move to the next UI, setting current_ui if iteration is not yet
+  // complete.
+  void next ()
+  {
+    m_iter = m_iter->next;
+    if (m_iter != NULL)
+      current_ui = m_iter;
+  }
+
+ private:
+
+  // No need for these.  They are intentionally not defined anywhere.
+  switch_thru_all_uis &operator= (const switch_thru_all_uis &);
+  switch_thru_all_uis (const switch_thru_all_uis &);
+
+  // Used to iterate through the UIs.
+  struct ui *m_iter;
+
+  // Save and restore current_ui.
+  scoped_restore_tmpl<struct ui *> m_save_ui;
 };
 
-/* Functions to drive SWITCH_THRU_ALL_UIS.  Though declared here by
-   necessity, these functions should not be used other than via the
-   SWITCH_THRU_ALL_UIS macro defined below.  */
-extern void switch_thru_all_uis_init (struct switch_thru_all_uis *state);
-extern int switch_thru_all_uis_cond (struct switch_thru_all_uis *state);
-extern void switch_thru_all_uis_next (struct switch_thru_all_uis *state);
-
   /* Traverse through all UI, and switch the current UI to the one
      being iterated.  */
-#define SWITCH_THRU_ALL_UIS(STATE)		\
-  for (switch_thru_all_uis_init (&STATE);		\
-       switch_thru_all_uis_cond (&STATE);		\
-       switch_thru_all_uis_next (&STATE))
+#define SWITCH_THRU_ALL_UIS()		\
+  for (switch_thru_all_uis stau_state; !stau_state.done (); stau_state.next ())
 
 /* Traverse over all UIs.  */
 #define ALL_UIS(UI)				\
@@ -188,9 +209,6 @@  extern void delete_ui (struct ui *todel);
 /* Cleanup that deletes a UI.  */
 extern struct cleanup *make_delete_ui_cleanup (struct ui *ui);
 
-/* Make a cleanup that restores the current UI.  */
-extern struct cleanup *make_cleanup_restore_current_ui (void);
-
 /* Register the UI's input file descriptor in the event loop.  */
 extern void ui_register_input_event_handler (struct ui *ui);
 
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index e06d679..8d35124 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -70,12 +70,10 @@  tui_exit (void)
 static void
 tui_on_normal_stop (struct bpstats *bs, int print_frame)
 {
-  struct switch_thru_all_uis state;
-
   if (!print_frame)
     return;
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *interp = top_level_interpreter ();
       struct interp *tui = as_tui_interp (interp);
@@ -95,9 +93,7 @@  tui_on_normal_stop (struct bpstats *bs, int print_frame)
 static void
 tui_on_signal_received (enum gdb_signal siggnal)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *tui = as_tui_interp (top_level_interpreter ());
 
@@ -113,9 +109,7 @@  tui_on_signal_received (enum gdb_signal siggnal)
 static void
 tui_on_end_stepping_range (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *tui = as_tui_interp (top_level_interpreter ());
 
@@ -131,9 +125,7 @@  tui_on_end_stepping_range (void)
 static void
 tui_on_signal_exited (enum gdb_signal siggnal)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *tui = as_tui_interp (top_level_interpreter ());
 
@@ -149,9 +141,7 @@  tui_on_signal_exited (enum gdb_signal siggnal)
 static void
 tui_on_exited (int exitstatus)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *tui = as_tui_interp (top_level_interpreter ());
 
@@ -167,9 +157,7 @@  tui_on_exited (int exitstatus)
 static void
 tui_on_no_history (void)
 {
-  struct switch_thru_all_uis state;
-
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *tui = as_tui_interp (top_level_interpreter ());
 
@@ -211,7 +199,6 @@  tui_on_command_error (void)
 static void
 tui_on_user_selected_context_changed (user_selected_what selection)
 {
-  struct switch_thru_all_uis state;
   struct thread_info *tp;
 
   /* This event is suppressed.  */
@@ -220,7 +207,7 @@  tui_on_user_selected_context_changed (user_selected_what selection)
 
   tp = find_thread_ptid (inferior_ptid);
 
-  SWITCH_THRU_ALL_UIS (state)
+  SWITCH_THRU_ALL_UIS ()
     {
       struct interp *tui = as_tui_interp (top_level_interpreter ());