On 2017-10-08 01:07 PM, Tom Tromey wrote:
> This changes pv_area::scan to use gdb::function_view and updates all
> the callers. The primary gain from this change is type-safety in the
> calling code.
>
> gdb/ChangeLog
> 2017-10-07 Tom Tromey <tom@tromey.com>
>
> * rl78-tdep.c (rl78_analyze_prologue): Update.
> (check_for_saved): Change type of "result".
> * msp430-tdep.c (check_for_saved): Change type of "result".
> (msp430_analyze_prologue): Update.
> * rx-tdep.c (rx_analyze_prologue): Update.
> (check_for_saved): Change type of "result".
> * mn10300-tdep.c (mn10300_analyze_prologue): Update.
> (check_for_saved): Change type of "result".
> * m32c-tdep.c (m32c_analyze_prologue): Update.
> (check_for_saved): Change type of "prologue".
> * s390-linux-tdep.c (s390_check_for_saved): Change type of
> "data".
> (s390_analyze_prologue): Update.
> * mep-tdep.c (check_for_saved): Change type of "result".
> (mep_analyze_prologue): Update.
> * prologue-value.h (pv_area::scan): Use gdb::function_view.
> ---
> gdb/ChangeLog | 19 +++++++++++++++++++
> gdb/m32c-tdep.c | 8 +++++---
> gdb/mep-tdep.c | 9 +++++----
> gdb/mn10300-tdep.c | 9 +++++----
> gdb/msp430-tdep.c | 9 +++++----
> gdb/prologue-value.c | 10 ++++------
> gdb/prologue-value.h | 14 +++++++-------
> gdb/rl78-tdep.c | 8 ++++----
> gdb/rx-tdep.c | 9 +++++----
> gdb/s390-linux-tdep.c | 7 ++++---
> 10 files changed, 63 insertions(+), 39 deletions(-)
>
> diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
> index 39f9ec0e5a..62d575b3ef 100644
> --- a/gdb/m32c-tdep.c
> +++ b/gdb/m32c-tdep.c
> @@ -36,6 +36,7 @@
> #include "prologue-value.h"
> #include "target.h"
> #include "objfiles.h"
> +#include <functional>
>
>
> /* The m32c tdep structure. */
> @@ -1499,9 +1500,9 @@ m32c_pushm_is_reg_save (struct m32c_pv_state *st, int src)
> offset from the frame base, and SIZE indicates that the whole
> register was saved, record its offset in RESULT_UNTYPED. */
> static void
> -check_for_saved (void *prologue_untyped, pv_t addr, CORE_ADDR size, pv_t value)
> +check_for_saved (struct m32c_prologue *prologue, pv_t addr, CORE_ADDR size,
> + pv_t value)
> {
> - struct m32c_prologue *prologue = (struct m32c_prologue *) prologue_untyped;
> struct gdbarch *arch = prologue->arch;
> struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
>
> @@ -1811,7 +1812,8 @@ m32c_analyze_prologue (struct gdbarch *arch,
> prologue->kind = prologue_first_frame;
>
> /* Record where all the registers were saved. */
> - st.stack->scan (check_for_saved, (void *) prologue);
> + using namespace std::placeholders;
> + stack.scan (std::bind (check_for_saved, prologue, _1, _2, _3));
For readability, I would be inclined to use lambdas for these. For performance,
I have read that lambdas were preferable to std::bind, in that they were always
at least as efficient, often more. But I don't know about that specific case,
since we go through a function_view. If we put the scan method in the header,
then we could use a template parameter for the callback type instead of
gdb::function_vew. I think that would be the most efficient, since it would
allow the compiler to optimize through the callback, as the whole call chain
would be known at compile-time.
It would be interesting if somebody with more C++-fu looked at it.
Simon
@@ -36,6 +36,7 @@
#include "prologue-value.h"
#include "target.h"
#include "objfiles.h"
+#include <functional>
/* The m32c tdep structure. */
@@ -1499,9 +1500,9 @@ m32c_pushm_is_reg_save (struct m32c_pv_state *st, int src)
offset from the frame base, and SIZE indicates that the whole
register was saved, record its offset in RESULT_UNTYPED. */
static void
-check_for_saved (void *prologue_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+check_for_saved (struct m32c_prologue *prologue, pv_t addr, CORE_ADDR size,
+ pv_t value)
{
- struct m32c_prologue *prologue = (struct m32c_prologue *) prologue_untyped;
struct gdbarch *arch = prologue->arch;
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
@@ -1811,7 +1812,8 @@ m32c_analyze_prologue (struct gdbarch *arch,
prologue->kind = prologue_first_frame;
/* Record where all the registers were saved. */
- st.stack->scan (check_for_saved, (void *) prologue);
+ using namespace std::placeholders;
+ stack.scan (std::bind (check_for_saved, prologue, _1, _2, _3));
prologue->prologue_end = after_last_frame_related_insn;
}
@@ -45,6 +45,7 @@
#include "prologue-value.h"
#include "cgen/bitset.h"
#include "infcall.h"
+#include <functional>
/* Get the user's customized MeP coprocessor register names from
libopcodes. */
@@ -1651,10 +1652,9 @@ is_arg_spill (struct gdbarch *gdbarch, pv_t value, pv_t addr,
offset from the frame base, and SIZE indicates that the whole
register was saved, record its offset in RESULT_UNTYPED. */
static void
-check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+check_for_saved (struct mep_prologue *result, pv_t addr, CORE_ADDR size,
+ pv_t value)
{
- struct mep_prologue *result = (struct mep_prologue *) result_untyped;
-
if (value.kind == pvk_register
&& value.k == 0
&& pv_is_register (addr, MEP_SP_REGNUM)
@@ -1884,7 +1884,8 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
}
/* Record where all the registers were saved. */
- stack.scan (check_for_saved, (void *) result);
+ using namespace std::placeholders;
+ stack.scan (std::bind (check_for_saved, result, _1, _2, _3));
result->prologue_end = after_last_frame_setup_insn;
}
@@ -33,6 +33,7 @@
#include "infcall.h"
#include "prologue-value.h"
#include "target.h"
+#include <functional>
#include "mn10300-tdep.h"
@@ -362,10 +363,9 @@ translate_rreg (int rreg)
offset from the frame base, and SIZE indicates that the whole
register was saved, record its offset in RESULT_UNTYPED. */
static void
-check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+check_for_saved (struct mn10300_prologue *result, pv_t addr, CORE_ADDR size,
+ pv_t value)
{
- struct mn10300_prologue *result = (struct mn10300_prologue *) result_untyped;
-
if (value.kind == pvk_register
&& value.k == 0
&& pv_is_register (addr, E_SP_REGNUM)
@@ -1034,7 +1034,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
}
/* Record where all the registers were saved. */
- stack.scan (check_for_saved, (void *) result);
+ using namespace std::placeholders;
+ stack.scan (std::bind (check_for_saved, result, _1, _2, _3));
result->prologue_end = after_last_frame_setup_insn;
}
@@ -34,6 +34,7 @@
#include "gdbcore.h"
#include "dwarf2-frame.h"
#include "reggroups.h"
+#include <functional>
#include "elf/msp430.h"
#include "opcode/msp430-decode.h"
@@ -318,10 +319,9 @@ msp430_get_opcode_byte (void *handle)
register was saved, record its offset. */
static void
-check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+check_for_saved (struct msp430_prologue *result, pv_t addr, CORE_ADDR size,
+ pv_t value)
{
- struct msp430_prologue *result = (struct msp430_prologue *) result_untyped;
-
if (value.kind == pvk_register
&& value.k == 0
&& pv_is_register (addr, MSP430_SP_REGNUM)
@@ -425,7 +425,8 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
result->frame_size = reg[MSP430_SP_REGNUM].k;
/* Record where all the registers were saved. */
- stack.scan (check_for_saved, result);
+ using namespace std::placeholders;
+ stack.scan (std::bind (check_for_saved, result, _1, _2, _3));
result->prologue_end = after_last_frame_setup_insn;
}
@@ -505,11 +505,9 @@ pv_area::find_reg (struct gdbarch *gdbarch, int reg, CORE_ADDR *offset_p)
void
-pv_area::scan (void (*func) (void *closure,
- pv_t addr,
- CORE_ADDR size,
- pv_t value),
- void *closure)
+pv_area::scan (gdb::function_view<void (pv_t addr,
+ CORE_ADDR size,
+ pv_t value)> func)
{
struct area_entry *e = m_entry;
pv_t addr;
@@ -521,7 +519,7 @@ pv_area::scan (void (*func) (void *closure,
do
{
addr.k = e->offset;
- func (closure, addr, e->size, e->value);
+ func (addr, e->size, e->value);
e = e->next;
}
while (e != m_entry);
@@ -19,6 +19,8 @@
#ifndef PROLOGUE_VALUE_H
#define PROLOGUE_VALUE_H
+#include "common/function-view.h"
+
/* What sort of value is this? This determines the interpretation
of subsequent fields. */
enum prologue_value_kind
@@ -283,13 +285,11 @@ public:
bool find_reg (struct gdbarch *gdbarch, int reg, CORE_ADDR *offset_p);
- /* For every part of AREA whose value we know, apply FUNC to CLOSURE,
- the value's address, its size, and the value itself. */
- void scan (void (*func) (void *closure,
- pv_t addr,
- CORE_ADDR size,
- pv_t value),
- void *closure);
+ /* For every part of AREA whose value we know, apply FUNC to the
+ value's address, its size, and the value itself. */
+ void scan (gdb::function_view<void (pv_t addr,
+ CORE_ADDR size,
+ pv_t value)>);
private:
@@ -34,6 +34,7 @@
#include "gdbcore.h"
#include "dwarf2-frame.h"
#include "reggroups.h"
+#include <functional>
#include "elf/rl78.h"
#include "elf-bfd.h"
@@ -890,11 +891,9 @@ rl78_get_opcode_byte (void *handle)
register was saved, record its offset. */
static void
-check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size,
+check_for_saved (struct rl78_prologue *result, pv_t addr, CORE_ADDR size,
pv_t value)
{
- struct rl78_prologue *result = (struct rl78_prologue *) result_untyped;
-
if (value.kind == pvk_register
&& value.k == 0
&& pv_is_register (addr, RL78_SP_REGNUM)
@@ -1013,7 +1012,8 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
result->frame_size = reg[RL78_SP_REGNUM].k;
/* Record where all the registers were saved. */
- stack.scan (check_for_saved, (void *) result);
+ using namespace std::placeholders;
+ stack.scan (std::bind (check_for_saved, result, _1, _2, _3));
result->prologue_end = after_last_frame_setup_insn;
}
@@ -37,6 +37,7 @@
#include "elf/rx.h"
#include "elf-bfd.h"
#include <algorithm>
+#include <functional>
/* Certain important register numbers. */
enum
@@ -236,10 +237,9 @@ rx_register_type (struct gdbarch *gdbarch, int reg_nr)
offset from the frame base, and SIZE indicates that the whole
register was saved, record its offset. */
static void
-check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+check_for_saved (struct rx_prologue *result, pv_t addr, CORE_ADDR size,
+ pv_t value)
{
- struct rx_prologue *result = (struct rx_prologue *) result_untyped;
-
if (value.kind == pvk_register
&& value.k == 0
&& pv_is_register (addr, RX_SP_REGNUM)
@@ -453,7 +453,8 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
}
/* Record where all the registers were saved. */
- stack.scan (check_for_saved, (void *) result);
+ using namespace std::placeholders;
+ stack.scan (std::bind (check_for_saved, result, _1, _2, _3));
result->prologue_end = after_last_frame_setup_insn;
}
@@ -58,6 +58,7 @@
#include "elf/s390.h"
#include "elf-bfd.h"
#include <algorithm>
+#include <functional>
#include "features/s390-linux32.c"
#include "features/s390-linux32v1.c"
@@ -1424,10 +1425,9 @@ s390_load (struct s390_prologue_data *data,
register was saved, record its offset in the reg_offset table in
PROLOGUE_UNTYPED. */
static void
-s390_check_for_saved (void *data_untyped, pv_t addr,
+s390_check_for_saved (struct s390_prologue_data *data, pv_t addr,
CORE_ADDR size, pv_t value)
{
- struct s390_prologue_data *data = (struct s390_prologue_data *) data_untyped;
int i, offset;
if (!pv_is_register (addr, S390_SP_REGNUM))
@@ -1731,7 +1731,8 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
}
/* Record where all the registers were saved. */
- data->stack->scan (s390_check_for_saved, data);
+ using namespace std::placeholders;
+ data->stack->scan (std::bind (s390_check_for_saved, data, _1, _2, _3));
return result;
}