From b7b633e9b13fc5697af035f4504c9790c612a8c7 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 22 Sep 2016 20:29:11 -0600 Subject: [PATCH] Use RAII to save and restore scalars 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 * 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. --- gdb/ChangeLog | 23 +++++++++ gdb/arm-tdep.c | 9 ++-- gdb/cli/cli-script.c | 18 ++----- gdb/common/scoped_restore.h | 99 +++++++++++++++++++++++++++++++++++++ gdb/compile/compile.c | 23 +++------ gdb/infrun.c | 16 +----- gdb/linux-fork.c | 11 +++-- gdb/mi/mi-cmd-var.c | 8 +-- gdb/mi/mi-main.c | 3 +- gdb/printcmd.c | 6 +-- gdb/python/python.c | 12 ++--- gdb/top.c | 3 +- gdb/utils.h | 1 + 13 files changed, 155 insertions(+), 77 deletions(-) create mode 100644 gdb/common/scoped_restore.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1f94dc6384e..b6290c7b376 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,26 @@ +2016-10-21 Tom Tromey + + * 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 * xcoffread.c (read_xcoff_symtab): Make "filestring" const. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 27a3ebe1722..645825f7426 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -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 diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index 579d0a49a74..12a976a4f9b 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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 (¤t_ui->async); - current_ui->async = 0; - { + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); TRY { diff --git a/gdb/common/scoped_restore.h b/gdb/common/scoped_restore.h new file mode 100644 index 00000000000..8c2a5b0272b --- /dev/null +++ b/gdb/common/scoped_restore.h @@ -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 . */ + +#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 +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 &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 +scoped_restore_tmpl make_scoped_restore (T *var) +{ + return scoped_restore_tmpl (var); +} + +/* Make a scoped_restore. This is useful because it lets template + argument deduction work. */ +template +scoped_restore_tmpl make_scoped_restore (T *var, T value) +{ + return scoped_restore_tmpl (var, value); +} + +#endif /* SCOPED_RESTORE_H */ diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index 0c4a7387ade..73fae22d1a5 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -91,8 +91,7 @@ compile_file_command (char *arg, int from_tty) char *buffer; struct cleanup *cleanup; - cleanup = make_cleanup_restore_integer (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); /* Check the user did not just 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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 2636a19f9b1..6fc1acf77ff 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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); diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index e7202dd8a53..e4be59352a5 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -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.")); diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c index 3bfe4f07e0a..16d51f9c86b 100644 --- a/gdb/mi/mi-cmd-var.c +++ b/gdb/mi/mi-cmd-var.c @@ -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. */ diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 81e82edcf95..1bc8241db0e 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -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); } } diff --git a/gdb/printcmd.c b/gdb/printcmd.c index c7f477bc961..7180fdafc53 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -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 (¤t_display_number); - current_display_number = d->number; + scoped_restore save_display_number + = make_scoped_restore (¤t_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 diff --git a/gdb/python/python.c b/gdb/python/python.c index 7e34d2638cc..e478ec955ca 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); make_cleanup_restore_current_uiout (); diff --git a/gdb/top.c b/gdb/top.c index 3cfa113adaa..120d751d0ec 100644 --- 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 (¤t_ui->async); - current_ui->async = 0; + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); str_file = mem_fileopen (); diff --git a/gdb/utils.h b/gdb/utils.h index 86350750a24..c4944e1337c 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -22,6 +22,7 @@ #define UTILS_H #include "exceptions.h" +#include "common/scoped_restore.h" extern void initialize_utils (void); -- 2.30.2