From 9bcb1f1630b05594fa86bfd017639cfcc966b11c Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 19 Apr 2017 13:12:23 +0100 Subject: Make inferior::detaching a bool, and introduce scoped_restore::release() I left making inferior::detaching a bool to a separate patch, because doing that makes a make_cleanup_restore_integer call in infrun.c:prepare_for_detach no longer compile (passing a 'bool *' when an 'int *' is expected). Since we want to get rid of cleanups anyway, I looked at converting that to a scoped_restore. However, prepare_for_detach wants to discard the cleanup on success, and scoped_restore doesn't have an equivalent for that. So I added one -- I called it "release()" because it seems like a natural fit in the way standard components call similarly-spirited methods, and, it's also what the proposal for a generic scope guard calls it too, AFAICS: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189.pdf I've added some scoped_guard unit tests, while at it. gdb/ChangeLog: 2017-04-19 Pedro Alves * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add unittests/scoped_restore-selftests.c. (SUBDIR_UNITTESTS_OBS): Add scoped_restore-selftests.o. * common/scoped_restore.h (scoped_restore_base): Make "class". (scoped_restore_base::release): New public method. (scoped_restore_base::scoped_restore_base): New protected ctor. (scoped_restore_base::m_saved_var): New protected field. (scoped_restore_tmpl::scoped_restore_tmpl(T*)): Initialize the scoped_restore_base base class instead of m_saved_var directly. (scoped_restore_tmpl::scoped_restore_tmpl(T*, T2)): Likewise. (scoped_restore_tmpl::scoped_restore_tmpl(const scoped_restore_tmpl&)): Likewise. (scoped_restore_tmpl::~scoped_restore_tmpl): Use the saved_var method. (scoped_restore_tmpl::saved_var): New method. (scoped_restore_tmpl::m_saved_var): Delete. * inferior.h (inferior::detaching): Now a bool. * infrun.c (prepare_for_detach): Use a scoped_restore instead of a cleanup. * unittests/scoped_restore-selftests.c: New file. --- gdb/common/scoped_restore.h | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'gdb/common') diff --git a/gdb/common/scoped_restore.h b/gdb/common/scoped_restore.h index ae7a49f..e7dbca9 100644 --- a/gdb/common/scoped_restore.h +++ b/gdb/common/scoped_restore.h @@ -21,8 +21,23 @@ #define SCOPED_RESTORE_H /* Base class for scoped_restore_tmpl. */ -struct scoped_restore_base +class scoped_restore_base { +public: + /* This informs the (scoped_restore_tmpl) dtor that you no longer + want the original value restored. */ + void release () const + { m_saved_var = NULL; } + +protected: + scoped_restore_base (void *saved_var) + : m_saved_var (saved_var) + {} + + /* The type-erased saved variable. This is here so that clients can + call release() on a "scoped_restore" local, which is a typedef to + a scoped_restore_base. See below. */ + mutable void *m_saved_var; }; /* A convenience typedef. Users of make_scoped_restore declare the @@ -40,7 +55,7 @@ class scoped_restore_tmpl : public scoped_restore_base of *VAR. *VAR will be restored when this scoped_restore object is destroyed. */ scoped_restore_tmpl (T *var) - : m_saved_var (var), + : scoped_restore_base (var), m_saved_value (*var) { } @@ -52,14 +67,14 @@ class scoped_restore_tmpl : public scoped_restore_base E.g.: T='base'; T2='derived'. */ template scoped_restore_tmpl (T *var, T2 value) - : m_saved_var (var), + : scoped_restore_base (var), m_saved_value (*var) { *var = value; } scoped_restore_tmpl (const scoped_restore_tmpl &other) - : m_saved_var (other.m_saved_var), + : scoped_restore_base {other.m_saved_var}, m_saved_value (other.m_saved_value) { other.m_saved_var = NULL; @@ -67,18 +82,19 @@ class scoped_restore_tmpl : public scoped_restore_base ~scoped_restore_tmpl () { - if (m_saved_var != NULL) - *m_saved_var = m_saved_value; + if (saved_var () != NULL) + *saved_var () = m_saved_value; } - private: +private: + /* Return a pointer to the saved variable with its type + restored. */ + T *saved_var () + { return static_cast (m_saved_var); } /* 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; }; -- cgit v1.1