Use RAII to save and restore scalars
authorTom Tromey <tom@tromey.com>
Fri, 23 Sep 2016 02:29:11 +0000 (20:29 -0600)
committerTom Tromey <tom@tromey.com>
Fri, 21 Oct 2016 20:17:31 +0000 (14:17 -0600)
This patch replaces many (but not all) uses of
make_cleanup_restore_integer with a simple RAII-based template class.
It also removes the similar restore_execution_direction cleanup in
favor of this new class.  Subsequent patches will replace other
similar cleanups with this class.

The class is typically instantiated using make_scoped_restore.  This
allows for template argument deduction.

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

* common/scoped_restore.h: New file.
* utils.h: Include scoped_restore.h.
* top.c (execute_command_to_string): Use scoped_restore.
* python/python.c (python_interactive_command): Use
scoped_restore.
(python_command, execute_gdb_command): Likewise.
* printcmd.c (do_one_display): Use scoped_restore.
* mi/mi-main.c (exec_continue): Use scoped_restore.
* mi/mi-cmd-var.c (mi_cmd_var_assign): Use scoped_restore.
* linux-fork.c (checkpoint_command): Use scoped_restore.
* infrun.c (restore_execution_direction): Remove.
(fetch_inferior_event): Use scoped_restore.
* compile/compile.c (compile_file_command): Use
scoped_restore.
(compile_code_command, compile_print_command): Likewise.
* cli/cli-script.c (execute_user_command): Use
scoped_restore.
(while_command, if_command, script_from_file): Likewise.
* arm-tdep.c (arm_insert_single_step_breakpoint): Use
scoped_restore.

13 files changed:
gdb/ChangeLog
gdb/arm-tdep.c
gdb/cli/cli-script.c
gdb/common/scoped_restore.h [new file with mode: 0644]
gdb/compile/compile.c
gdb/infrun.c
gdb/linux-fork.c
gdb/mi/mi-cmd-var.c
gdb/mi/mi-main.c
gdb/printcmd.c
gdb/python/python.c
gdb/top.c
gdb/utils.h

index 1f94dc6384e7292d6991a87e70114205c48d456c..b6290c7b3764fad9efbd690846a90baf74d4a343 100644 (file)
@@ -1,3 +1,26 @@
+2016-10-21  Tom Tromey  <tom@tromey.com>
+
+       * common/scoped_restore.h: New file.
+       * utils.h: Include scoped_restore.h.
+       * top.c (execute_command_to_string): Use scoped_restore.
+       * python/python.c (python_interactive_command): Use
+       scoped_restore.
+       (python_command, execute_gdb_command): Likewise.
+       * printcmd.c (do_one_display): Use scoped_restore.
+       * mi/mi-main.c (exec_continue): Use scoped_restore.
+       * mi/mi-cmd-var.c (mi_cmd_var_assign): Use scoped_restore.
+       * linux-fork.c (checkpoint_command): Use scoped_restore.
+       * infrun.c (restore_execution_direction): Remove.
+       (fetch_inferior_event): Use scoped_restore.
+       * compile/compile.c (compile_file_command): Use
+       scoped_restore.
+       (compile_code_command, compile_print_command): Likewise.
+       * cli/cli-script.c (execute_user_command): Use
+       scoped_restore.
+       (while_command, if_command, script_from_file): Likewise.
+       * arm-tdep.c (arm_insert_single_step_breakpoint): Use
+       scoped_restore.
+
 2016-10-21  Tom Tromey  <tom@tromey.com>
 
        * xcoffread.c (read_xcoff_symtab): Make "filestring" const.
index 27a3ebe1722f0904146e6d0c0313c6d026bc7984..645825f74262fafe3a0ebe6b3d349fcff06be46d 100644 (file)
@@ -4255,15 +4255,12 @@ arm_insert_single_step_breakpoint (struct gdbarch *gdbarch,
                                   struct address_space *aspace,
                                   CORE_ADDR pc)
 {
-  struct cleanup *old_chain
-    = make_cleanup_restore_integer (&arm_override_mode);
-
-  arm_override_mode = IS_THUMB_ADDR (pc);
+  scoped_restore save_override_mode
+    = make_scoped_restore (&arm_override_mode,
+                          (int) IS_THUMB_ADDR (pc));
   pc = gdbarch_addr_bits_remove (gdbarch, pc);
 
   insert_single_step_breakpoint (gdbarch, aspace, pc);
-
-  do_cleanups (old_chain);
 }
 
 /* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand
index 579d0a49a74e918a68a1f85caf37827985311a27..12a976a4f9bf2a4bd71aa597e7ce00f4c6c17d46 100644 (file)
@@ -380,8 +380,7 @@ execute_user_command (struct cmd_list_element *c, char *args)
      not confused with Insight.  */
   in_user_command = 1;
 
-  make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   command_nest_depth++;
   while (cmdlines)
@@ -654,7 +653,6 @@ static void
 while_command (char *arg, int from_tty)
 {
   struct command_line *command = NULL;
-  struct cleanup *old_chain;
 
   control_level = 1;
   command = get_command_line (while_control, arg);
@@ -662,13 +660,10 @@ while_command (char *arg, int from_tty)
   if (command == NULL)
     return;
 
-  old_chain = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   execute_control_command_untraced (command);
   free_command_lines (&command);
-
-  do_cleanups (old_chain);
 }
 
 /* "if" command support.  Execute either the true or false arm depending
@@ -686,13 +681,10 @@ if_command (char *arg, int from_tty)
   if (command == NULL)
     return;
 
-  old_chain = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   execute_control_command_untraced (command);
   free_command_lines (&command);
-
-  do_cleanups (old_chain);
 }
 
 /* Cleanup */
@@ -1693,10 +1685,8 @@ script_from_file (FILE *stream, const char *file)
   source_line_number = 0;
   source_file_name = file;
 
-  make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
-
   {
+    scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
     TRY
       {
diff --git a/gdb/common/scoped_restore.h b/gdb/common/scoped_restore.h
new file mode 100644 (file)
index 0000000..8c2a5b0
--- /dev/null
@@ -0,0 +1,99 @@
+/* scoped_restore, a simple class for saving and restoring a value
+
+   Copyright (C) 2016 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 SCOPED_RESTORE_H
+#define SCOPED_RESTORE_H
+
+/* Base class for scoped_restore_tmpl.  */
+struct scoped_restore_base
+{
+};
+
+/* A convenience typedef.  Users of make_scoped_restore declare the
+   local RAII object as having this type.  */
+typedef const scoped_restore_base &scoped_restore;
+
+/* An RAII-based object that saves a variable's value, and then
+   restores it again when this object is destroyed. */
+template<typename T>
+class scoped_restore_tmpl : public scoped_restore_base
+{
+ public:
+
+  /* Create a new scoped_restore object that saves the current value
+     of *VAR.  *VAR will be restored when this scoped_restore object
+     is destroyed.  */
+  scoped_restore_tmpl (T *var)
+    : m_saved_var (var),
+      m_saved_value (*var)
+  {
+  }
+
+  /* Create a new scoped_restore object that saves the current value
+     of *VAR, and sets *VAR to VALUE.  *VAR will be restored when this
+     scoped_restore object is destroyed.  */
+  scoped_restore_tmpl (T *var, T value)
+    : m_saved_var (var),
+      m_saved_value (*var)
+  {
+    *var = value;
+  }
+
+  scoped_restore_tmpl (const scoped_restore_tmpl<T> &other)
+    : m_saved_var (other.m_saved_var),
+      m_saved_value (other.m_saved_value)
+  {
+    other.m_saved_var = NULL;
+  }
+
+  ~scoped_restore_tmpl ()
+  {
+    if (m_saved_var != NULL)
+      *m_saved_var = m_saved_value;
+  }
+
+ private:
+
+  /* No need for this.  It is intentionally not defined anywhere.  */
+  scoped_restore_tmpl &operator= (const scoped_restore_tmpl &);
+
+  /* The saved variable.  */
+  mutable T *m_saved_var;
+
+  /* The saved value.  */
+  const T m_saved_value;
+};
+
+/* Make a scoped_restore.  This is useful because it lets template
+   argument deduction work.  */
+template<typename T>
+scoped_restore_tmpl<T> make_scoped_restore (T *var)
+{
+  return scoped_restore_tmpl<T> (var);
+}
+
+/* Make a scoped_restore.  This is useful because it lets template
+   argument deduction work.  */
+template<typename T>
+scoped_restore_tmpl<T> make_scoped_restore (T *var, T value)
+{
+  return scoped_restore_tmpl<T> (var, value);
+}
+
+#endif /* SCOPED_RESTORE_H */
index 0c4a7387ade1122e0219d61b4201ec17fb6a180c..73fae22d1a5227e7e1e041f06875481f3c64196a 100644 (file)
@@ -91,8 +91,7 @@ compile_file_command (char *arg, int from_tty)
   char *buffer;
   struct cleanup *cleanup;
 
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   /* Check the user did not just <enter> after command.  */
   if (arg == NULL)
@@ -115,7 +114,7 @@ compile_file_command (char *arg, int from_tty)
 
   arg = skip_spaces (arg);
   arg = gdb_abspath (arg);
-  make_cleanup (xfree, arg);
+  cleanup = make_cleanup (xfree, arg);
   buffer = xstrprintf ("#include \"%s\"\n", arg);
   make_cleanup (xfree, buffer);
   eval_compile_command (NULL, buffer, scope, NULL);
@@ -130,11 +129,9 @@ compile_file_command (char *arg, int from_tty)
 static void
 compile_code_command (char *arg, int from_tty)
 {
-  struct cleanup *cleanup;
   enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE;
 
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   if (arg != NULL && check_raw_argument (&arg))
     {
@@ -155,13 +152,12 @@ compile_code_command (char *arg, int from_tty)
   else
     {
       struct command_line *l = get_command_line (compile_control, "");
+      struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
 
-      make_cleanup_free_command_lines (&l);
       l->control_u.compile.scope = scope;
       execute_control_command_untraced (l);
+      do_cleanups (cleanup);
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Callback for compile_print_command.  */
@@ -183,12 +179,10 @@ static void
 compile_print_command (char *arg_param, int from_tty)
 {
   const char *arg = arg_param;
-  struct cleanup *cleanup;
   enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
   struct format_data fmt;
 
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   /* Passing &FMT as SCOPE_DATA is safe as do_module_cleanup will not
      touch the stale pointer if compile_object_run has already quit.  */
@@ -199,14 +193,13 @@ compile_print_command (char *arg_param, int from_tty)
   else
     {
       struct command_line *l = get_command_line (compile_control, "");
+      struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
 
-      make_cleanup_free_command_lines (&l);
       l->control_u.compile.scope = scope;
       l->control_u.compile.scope_data = &fmt;
       execute_control_command_untraced (l);
+      do_cleanups (cleanup);
     }
-
-  do_cleanups (cleanup);
 }
 
 /* A cleanup function to remove a directory and all its contents.  */
index 2636a19f9b129cbb940199b1928932581f8593d6..6fc1acf77ffe0cb490d2c60a576736014a07baac 100644 (file)
@@ -3879,17 +3879,6 @@ all_uis_on_sync_execution_starting (void)
     }
 }
 
-/* A cleanup that restores the execution direction to the value saved
-   in *ARG.  */
-
-static void
-restore_execution_direction (void *arg)
-{
-  enum exec_direction_kind *save_exec_dir = (enum exec_direction_kind *) arg;
-
-  execution_direction = *save_exec_dir;
-}
-
 /* Asynchronous version of wait_for_inferior.  It is called by the
    event loop whenever a change of state is detected on the file
    descriptor corresponding to the target.  It can be called more than
@@ -3906,7 +3895,6 @@ fetch_inferior_event (void *client_data)
   struct execution_control_state *ecs = &ecss;
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   struct cleanup *ts_old_chain;
-  enum exec_direction_kind save_exec_dir = execution_direction;
   int cmd_done = 0;
   ptid_t waiton_ptid = minus_one_ptid;
 
@@ -3945,8 +3933,8 @@ fetch_inferior_event (void *client_data)
      event.  */
   target_dcache_invalidate ();
 
-  make_cleanup (restore_execution_direction, &save_exec_dir);
-  execution_direction = target_execution_direction ();
+  scoped_restore save_exec_dir
+    = make_scoped_restore (&execution_direction, target_execution_direction ());
 
   ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
                              target_can_async_p () ? TARGET_WNOHANG : 0);
index e7202dd8a53e0b3a430fd3f6853dded7ca727480..e4be59352a5fd8cb944a28f5c49994a2f5672b88 100644 (file)
@@ -680,7 +680,6 @@ checkpoint_command (char *args, int from_tty)
   struct value *fork_fn = NULL, *ret;
   struct fork_info *fp;
   pid_t retpid;
-  struct cleanup *old_chain;
 
   if (!target_has_execution) 
     error (_("The program is not being run."));
@@ -704,11 +703,13 @@ checkpoint_command (char *args, int from_tty)
   ret = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
 
   /* Tell linux-nat.c that we're checkpointing this inferior.  */
-  old_chain = make_cleanup_restore_integer (&checkpointing_pid);
-  checkpointing_pid = ptid_get_pid (inferior_ptid);
+  {
+    scoped_restore save_pid
+      = make_scoped_restore (&checkpointing_pid, ptid_get_pid (inferior_ptid));
+
+    ret = call_function_by_hand (fork_fn, 0, &ret);
+  }
 
-  ret = call_function_by_hand (fork_fn, 0, &ret);
-  do_cleanups (old_chain);
   if (!ret)    /* Probably can't happen.  */
     error (_("checkpoint: call_function_by_hand returned null."));
 
index 3bfe4f07e0a673afb09de8ad55c8c329959fbb4b..16d51f9c86be77d4a03afe9d3b11df6aa7732f52 100644 (file)
@@ -608,7 +608,6 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
   struct ui_out *uiout = current_uiout;
   struct varobj *var;
   char *expression, *val;
-  struct cleanup *cleanup;
 
   if (argc != 2)
     error (_("-var-assign: Usage: NAME EXPRESSION."));
@@ -623,9 +622,8 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
 
   /* MI command '-var-assign' may write memory, so suppress memory
      changed notification if it does.  */
-  cleanup
-    = make_cleanup_restore_integer (&mi_suppress_notification.memory);
-  mi_suppress_notification.memory = 1;
+  scoped_restore save_suppress
+    = make_scoped_restore (&mi_suppress_notification.memory, 1);
 
   if (!varobj_set_value (var, expression))
     error (_("-var-assign: Could not assign "
@@ -634,8 +632,6 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
   val = varobj_get_value (var);
   ui_out_field_string (uiout, "value", val);
   xfree (val);
-
-  do_cleanups (cleanup);
 }
 
 /* Type used for parameters passing to mi_cmd_var_update_iter.  */
index 81e82edcf959728d33a62ccf629188c9837a9e61..1bc8241db0e9b3276e4c5d40efadf59426d06421 100644 (file)
@@ -301,7 +301,7 @@ exec_continue (char **argv, int argc)
     }
   else
     {
-      struct cleanup *back_to = make_cleanup_restore_integer (&sched_multi);
+      scoped_restore save_multi = make_scoped_restore (&sched_multi);
 
       if (current_context->all)
        {
@@ -316,7 +316,6 @@ exec_continue (char **argv, int argc)
             same.  */
          continue_1 (1);
        }
-      do_cleanups (back_to);
     }
 }
 
index c7f477bc96165e15e683e9682b81e50bea3f7242..7180fdafc53dd0039dde6978d4058d2e758d29d1 100644 (file)
@@ -1937,7 +1937,6 @@ undisplay_command (char *args, int from_tty)
 static void
 do_one_display (struct display *d)
 {
-  struct cleanup *old_chain;
   int within_current_scope;
 
   if (d->enabled_p == 0)
@@ -1989,8 +1988,8 @@ do_one_display (struct display *d)
   if (!within_current_scope)
     return;
 
-  old_chain = make_cleanup_restore_integer (&current_display_number);
-  current_display_number = d->number;
+  scoped_restore save_display_number
+    = make_scoped_restore (&current_display_number, d->number);
 
   annotate_display_begin ();
   printf_filtered ("%d", d->number);
@@ -2078,7 +2077,6 @@ do_one_display (struct display *d)
   annotate_display_end ();
 
   gdb_flush (gdb_stdout);
-  do_cleanups (old_chain);
 }
 
 /* Display all of the values on the auto-display chain which can be
index 7e34d2638cc28aa9658439637eb1b376324c14cc..e478ec955ca5837abc47be0954b8ec1f3ab5f8e0 100644 (file)
@@ -319,11 +319,9 @@ static void
 python_interactive_command (char *arg, int from_tty)
 {
   struct ui *ui = current_ui;
-  struct cleanup *cleanup;
   int err;
 
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   arg = skip_spaces (arg);
 
@@ -351,8 +349,6 @@ python_interactive_command (char *arg, int from_tty)
       gdbpy_print_stack ();
       error (_("Error while executing Python code."));
     }
-
-  do_cleanups (cleanup);
 }
 
 /* A wrapper around PyRun_SimpleFile.  FILE is the Python script to run
@@ -467,8 +463,7 @@ python_command (char *arg, int from_tty)
 
   cleanup = ensure_python_env (get_current_arch (), current_language);
 
-  make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   arg = skip_spaces (arg);
   if (arg && *arg)
@@ -651,8 +646,7 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
       struct cleanup *cleanup = make_cleanup (xfree, copy);
       struct interp *interp;
 
-      make_cleanup_restore_integer (&current_ui->async);
-      current_ui->async = 0;
+      scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
       make_cleanup_restore_current_uiout ();
 
index 3cfa113adaac978fa1930ae00e0928b73e09d041..120d751d0ec2abde8741409f086d1e557708f953 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -701,8 +701,7 @@ execute_command_to_string (char *p, int from_tty)
      restoration callbacks.  */
   cleanup = set_batch_flag_and_make_cleanup_restore_page_info ();
 
-  make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
   str_file = mem_fileopen ();
 
index 86350750a2487de2bb4f12682757af3afbe08beb..c4944e1337cc74afb1ff905de99c5caae0be412b 100644 (file)
@@ -22,6 +22,7 @@
 #define UTILS_H
 
 #include "exceptions.h"
+#include "common/scoped_restore.h"
 
 extern void initialize_utils (void);