Use gdb:array_view in call_function_by_hand & friends

This replaces a few uses of pointer+length with gdb::array_view, in
call_function_by_hand and related code.

Unfortunately, due to -Wnarrowing, there are places where we can't
brace-initialize an gdb::array_view without an ugly-ish cast.  To
avoid the cast, this patch introduces a gdb::make_array_view function.
Unit tests included.

This patch in isolation may not look so interesting, due to
gdb::make_array_view uses, but I think it's still worth it.  Some of
the gdb::make_array_view calls disappear down the series, and others
could be eliminated with more (non-trivial) gdb::array_view
detangling/conversion (e.g. code around eval_call).  See this as a "we
have to start somewhere" patch.

gdb/ChangeLog:
2018-11-21  Pedro Alves  <palves@redhat.com>

	* ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view.
	* common/array-view.h (make_array_view): New.
	* compile/compile-object-run.c (compile_object_run): Adjust to
	pass an array_view.
	* elfread.c (elf_gnu_ifunc_resolve_addr): Adjust.
	* eval.c (eval_call): Adjust to pass an array_view.
	(evaluate_subexp_standard): Adjust to pass an array_view.
	* gcore.c (call_target_sbrk): Adjust to pass an array_view.
	* guile/scm-value.c (gdbscm_value_call): Likewise.
	* infcall.c (push_dummy_code): Replace pointer + size parameters
	with an array_view parameter.
	(call_function_by_hand, call_function_by_hand_dummy): Likewise and
	adjust.
	* infcall.h: Include "common/array-view.h".
	(call_function_by_hand, call_function_by_hand_dummy): Replace
	pointer + size parameters with an array_view parameter.
	* linux-fork.c (inferior_call_waitpid): Adjust to use array_view.
	* linux-tdep.c (linux_infcall_mmap): Likewise.
	* objc-lang.c (lookup_objc_class, lookup_child_selector)
	(value_nsstring, print_object_command): Likewise.
	* python/py-value.c (valpy_call): Likewise.
	* rust-lang.c (rust_evaluate_funcall): Likewise.
	* spu-tdep.c (flush_ea_cache): Likewise.
	* valarith.c (value_x_binop, value_x_unop): Likewise.
	* valops.c (value_allocate_space_in_inferior): Likewise.
	* unittests/array-view-selftests.c (run_tests): Add
	gdb::make_array_view test.
This commit is contained in:
Pedro Alves 2018-11-21 11:55:11 +00:00
parent 1b288e9bbf
commit e71585ffe2
19 changed files with 146 additions and 60 deletions

View file

@ -1,3 +1,33 @@
2018-11-21 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view.
* common/array-view.h (make_array_view): New.
* compile/compile-object-run.c (compile_object_run): Adjust to
pass an array_view.
* elfread.c (elf_gnu_ifunc_resolve_addr): Adjust.
* eval.c (eval_call): Adjust to pass an array_view.
(evaluate_subexp_standard): Adjust to pass an array_view.
* gcore.c (call_target_sbrk): Adjust to pass an array_view.
* guile/scm-value.c (gdbscm_value_call): Likewise.
* infcall.c (push_dummy_code): Replace pointer + size parameters
with an array_view parameter.
(call_function_by_hand, call_function_by_hand_dummy): Likewise and
adjust.
* infcall.h: Include "common/array-view.h".
(call_function_by_hand, call_function_by_hand_dummy): Replace
pointer + size parameters with an array_view parameter.
* linux-fork.c (inferior_call_waitpid): Adjust to use array_view.
* linux-tdep.c (linux_infcall_mmap): Likewise.
* objc-lang.c (lookup_objc_class, lookup_child_selector)
(value_nsstring, print_object_command): Likewise.
* python/py-value.c (valpy_call): Likewise.
* rust-lang.c (rust_evaluate_funcall): Likewise.
* spu-tdep.c (flush_ea_cache): Likewise.
* valarith.c (value_x_binop, value_x_unop): Likewise.
* valops.c (value_allocate_space_in_inferior): Likewise.
* unittests/array-view-selftests.c (run_tests): Add
gdb::make_array_view test.
2018-11-20 Andrew Burgess <andrew.burgess@embecosm.com> 2018-11-20 Andrew Burgess <andrew.burgess@embecosm.com>
* cli-out.c (cli_ui_out::do_field_int): Use string_printf rather * cli-out.c (cli_ui_out::do_field_int): Use string_printf rather

View file

@ -10928,7 +10928,9 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
error_call_unknown_return_type (NULL); error_call_unknown_return_type (NULL);
return allocate_value (TYPE_TARGET_TYPE (type)); return allocate_value (TYPE_TARGET_TYPE (type));
} }
return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1); return call_function_by_hand (argvec[0], NULL,
gdb::make_array_view (argvec + 1,
nargs));
case TYPE_CODE_INTERNAL_FUNCTION: case TYPE_CODE_INTERNAL_FUNCTION:
if (noside == EVAL_AVOID_SIDE_EFFECTS) if (noside == EVAL_AVOID_SIDE_EFFECTS)
/* We don't know anything about what the internal /* We don't know anything about what the internal

View file

@ -201,6 +201,48 @@ operator!= (const gdb::array_view<T> &lhs, const gdb::array_view<T> &rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
/* Create an array view from a pointer to an array and an element
count.
This is useful as alternative to constructing an array_view using
brace initialization when the size variable you have handy is of
signed type, since otherwise without an explicit cast the code
would be ill-formed.
For example, with:
extern void foo (int, int, gdb::array_view<value *>);
value *args[2];
int nargs;
foo (1, 2, {values, nargs});
You'd get:
source.c:10: error: narrowing conversion of nargs from int to
size_t {aka long unsigned int} inside { } [-Werror=narrowing]
You could fix it by writing the somewhat distracting explicit cast:
foo (1, 2, {values, (size_t) nargs});
Or by instantiating an array_view explicitly:
foo (1, 2, gdb::array_view<value *>(values, nargs));
Or, better, using make_array_view, which has the advantage of
inferring the arrav_view element's type:
foo (1, 2, gdb::make_array_view (values, nargs));
*/
template<typename U>
constexpr inline array_view<U>
make_array_view (U *array, size_t size) noexcept
{
return {array, size};
}
} /* namespace gdb */ } /* namespace gdb */
#endif #endif

View file

@ -170,8 +170,8 @@ compile_object_run (struct compile_module *module)
++current_arg; ++current_arg;
} }
gdb_assert (current_arg == TYPE_NFIELDS (func_type)); gdb_assert (current_arg == TYPE_NFIELDS (func_type));
call_function_by_hand_dummy (func_val, auto args = gdb::make_array_view (vargs, TYPE_NFIELDS (func_type));
NULL, TYPE_NFIELDS (func_type), vargs, call_function_by_hand_dummy (func_val, NULL, args,
do_module_cleanup, data); do_module_cleanup, data);
} }
CATCH (ex, RETURN_MASK_ERROR) CATCH (ex, RETURN_MASK_ERROR)

View file

@ -904,7 +904,7 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
target_auxv_search (current_top_target (), AT_HWCAP, &hwcap); target_auxv_search (current_top_target (), AT_HWCAP, &hwcap);
hwcap_val = value_from_longest (builtin_type (gdbarch) hwcap_val = value_from_longest (builtin_type (gdbarch)
->builtin_unsigned_long, hwcap); ->builtin_unsigned_long, hwcap);
address_val = call_function_by_hand (function, NULL, 1, &hwcap_val); address_val = call_function_by_hand (function, NULL, hwcap_val);
address = value_as_address (address_val); address = value_as_address (address_val);
address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, current_top_target ()); address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, current_top_target ());
address = gdbarch_addr_bits_remove (gdbarch, address); address = gdbarch_addr_bits_remove (gdbarch, address);

View file

@ -830,7 +830,7 @@ eval_call (expression *exp, enum noside noside,
return call_xmethod (argvec[0], nargs, argvec + 1); return call_xmethod (argvec[0], nargs, argvec + 1);
default: default:
return call_function_by_hand (argvec[0], default_return_type, return call_function_by_hand (argvec[0], default_return_type,
nargs, argvec + 1); gdb::make_array_view (argvec + 1, nargs));
} }
} }
@ -1728,12 +1728,12 @@ evaluate_subexp_standard (struct type *expect_type,
argvec[3] = value_from_longest (long_type, selector); argvec[3] = value_from_longest (long_type, selector);
argvec[4] = 0; argvec[4] = 0;
ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
if (gnu_runtime) if (gnu_runtime)
{ {
/* Function objc_msg_lookup returns a pointer. */ /* Function objc_msg_lookup returns a pointer. */
argvec[0] = ret; argvec[0] = ret;
ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
} }
if (value_as_long (ret) == 0) if (value_as_long (ret) == 0)
error (_("Target does not respond to this message selector.")); error (_("Target does not respond to this message selector."));
@ -1750,11 +1750,11 @@ evaluate_subexp_standard (struct type *expect_type,
argvec[3] = value_from_longest (long_type, selector); argvec[3] = value_from_longest (long_type, selector);
argvec[4] = 0; argvec[4] = 0;
ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
if (gnu_runtime) if (gnu_runtime)
{ {
argvec[0] = ret; argvec[0] = ret;
ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
} }
/* ret should now be the selector. */ /* ret should now be the selector. */
@ -1890,17 +1890,17 @@ evaluate_subexp_standard (struct type *expect_type,
argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside); argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside);
argvec[tem + 3] = 0; argvec[tem + 3] = 0;
auto call_args = gdb::make_array_view (argvec + 1, nargs + 2);
if (gnu_runtime && (method != NULL)) if (gnu_runtime && (method != NULL))
{ {
/* Function objc_msg_lookup returns a pointer. */ /* Function objc_msg_lookup returns a pointer. */
deprecated_set_value_type (argvec[0], deprecated_set_value_type (argvec[0],
lookup_pointer_type (lookup_function_type (value_type (argvec[0])))); lookup_pointer_type (lookup_function_type (value_type (argvec[0]))));
argvec[0] argvec[0] = call_function_by_hand (argvec[0], NULL, call_args);
= call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1);
} }
ret = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1); return call_function_by_hand (argvec[0], NULL, call_args);
return ret;
} }
break; break;

View file

@ -300,7 +300,7 @@ call_target_sbrk (int sbrk_arg)
target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int,
sbrk_arg); sbrk_arg);
gdb_assert (target_sbrk_arg); gdb_assert (target_sbrk_arg);
ret = call_function_by_hand (sbrk_fn, NULL, 1, &target_sbrk_arg); ret = call_function_by_hand (sbrk_fn, NULL, target_sbrk_arg);
if (ret == NULL) if (ret == NULL)
return (bfd_vma) 0; return (bfd_vma) 0;

View file

@ -730,8 +730,8 @@ gdbscm_value_call (SCM self, SCM args)
{ {
scoped_value_mark free_values; scoped_value_mark free_values;
value *return_value = call_function_by_hand (function, NULL, auto av = gdb::make_array_view (vargs, args_count);
args_count, vargs); value *return_value = call_function_by_hand (function, NULL, av);
return vlscm_scm_from_value (return_value); return vlscm_scm_from_value (return_value);
}); });
} }

View file

@ -334,7 +334,7 @@ find_function_addr (struct value *function,
static CORE_ADDR static CORE_ADDR
push_dummy_code (struct gdbarch *gdbarch, push_dummy_code (struct gdbarch *gdbarch,
CORE_ADDR sp, CORE_ADDR funaddr, CORE_ADDR sp, CORE_ADDR funaddr,
struct value **args, int nargs, gdb::array_view<value *> args,
struct type *value_type, struct type *value_type,
CORE_ADDR *real_pc, CORE_ADDR *bp_addr, CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
struct regcache *regcache) struct regcache *regcache)
@ -342,7 +342,8 @@ push_dummy_code (struct gdbarch *gdbarch,
gdb_assert (gdbarch_push_dummy_code_p (gdbarch)); gdb_assert (gdbarch_push_dummy_code_p (gdbarch));
return gdbarch_push_dummy_code (gdbarch, sp, funaddr, return gdbarch_push_dummy_code (gdbarch, sp, funaddr,
args, nargs, value_type, real_pc, bp_addr, args.data (), args.size (),
value_type, real_pc, bp_addr,
regcache); regcache);
} }
@ -686,10 +687,10 @@ cleanup_delete_std_terminate_breakpoint (void *ignore)
struct value * struct value *
call_function_by_hand (struct value *function, call_function_by_hand (struct value *function,
type *default_return_type, type *default_return_type,
int nargs, struct value **args) gdb::array_view<value *> args)
{ {
return call_function_by_hand_dummy (function, default_return_type, return call_function_by_hand_dummy (function, default_return_type,
nargs, args, NULL, NULL); args, NULL, NULL);
} }
/* All this stuff with a dummy frame may seem unnecessarily complicated /* All this stuff with a dummy frame may seem unnecessarily complicated
@ -713,7 +714,7 @@ call_function_by_hand (struct value *function,
struct value * struct value *
call_function_by_hand_dummy (struct value *function, call_function_by_hand_dummy (struct value *function,
type *default_return_type, type *default_return_type,
int nargs, struct value **args, gdb::array_view<value *> args,
dummy_frame_dtor_ftype *dummy_dtor, dummy_frame_dtor_ftype *dummy_dtor,
void *dummy_dtor_data) void *dummy_dtor_data)
{ {
@ -912,7 +913,7 @@ call_function_by_hand_dummy (struct value *function,
/* Be careful BP_ADDR is in inferior PC encoding while /* Be careful BP_ADDR is in inferior PC encoding while
BP_ADDR_AS_ADDRESS is a plain memory address. */ BP_ADDR_AS_ADDRESS is a plain memory address. */
sp = push_dummy_code (gdbarch, sp, funaddr, args, nargs, sp = push_dummy_code (gdbarch, sp, funaddr, args,
target_values_type, &real_pc, &bp_addr, target_values_type, &real_pc, &bp_addr,
get_current_regcache ()); get_current_regcache ());
@ -953,14 +954,14 @@ call_function_by_hand_dummy (struct value *function,
internal_error (__FILE__, __LINE__, _("bad switch")); internal_error (__FILE__, __LINE__, _("bad switch"));
} }
if (nargs < TYPE_NFIELDS (ftype)) if (args.size () < TYPE_NFIELDS (ftype))
error (_("Too few arguments in function call.")); error (_("Too few arguments in function call."));
for (int i = nargs - 1; i >= 0; i--) for (int i = args.size () - 1; i >= 0; i--)
{ {
int prototyped; int prototyped;
struct type *param_type; struct type *param_type;
/* FIXME drow/2002-05-31: Should just always mark methods as /* FIXME drow/2002-05-31: Should just always mark methods as
prototyped. Can we respect TYPE_VARARGS? Probably not. */ prototyped. Can we respect TYPE_VARARGS? Probably not. */
if (TYPE_CODE (ftype) == TYPE_CODE_METHOD) if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
@ -1041,19 +1042,19 @@ call_function_by_hand_dummy (struct value *function,
if (return_method == return_method_hidden_param) if (return_method == return_method_hidden_param)
{ {
/* Add the new argument to the front of the argument list. */ /* Add the new argument to the front of the argument list. */
new_args.reserve (args.size ());
new_args.push_back new_args.push_back
(value_from_pointer (lookup_pointer_type (values_type), struct_addr)); (value_from_pointer (lookup_pointer_type (values_type), struct_addr));
std::copy (&args[0], &args[nargs], std::back_inserter (new_args)); new_args.insert (new_args.end (), args.begin (), args.end ());
args = new_args.data (); args = new_args;
nargs++;
} }
/* Create the dummy stack frame. Pass in the call dummy address as, /* Create the dummy stack frame. Pass in the call dummy address as,
presumably, the ABI code knows where, in the call dummy, the presumably, the ABI code knows where, in the call dummy, the
return address should be pointed. */ return address should be pointed. */
sp = gdbarch_push_dummy_call (gdbarch, function, get_current_regcache (), sp = gdbarch_push_dummy_call (gdbarch, function, get_current_regcache (),
bp_addr, nargs, args, sp, return_method, bp_addr, args.size (), args.data (),
struct_addr); sp, return_method, struct_addr);
/* Set up a frame ID for the dummy frame so we can pass it to /* Set up a frame ID for the dummy frame so we can pass it to
set_momentary_breakpoint. We need to give the breakpoint a frame set_momentary_breakpoint. We need to give the breakpoint a frame

View file

@ -21,6 +21,7 @@
#define INFCALL_H #define INFCALL_H
#include "dummy-frame.h" #include "dummy-frame.h"
#include "common/array-view.h"
struct value; struct value;
struct type; struct type;
@ -37,10 +38,10 @@ extern CORE_ADDR find_function_addr (struct value *function,
/* Perform a function call in the inferior. /* Perform a function call in the inferior.
ARGS is a vector of values of arguments (NARGS of them). FUNCTION ARGS is a vector of values of arguments. FUNCTION is a value, the
is a value, the function to be called. Returns a value function to be called. Returns a value representing what the
representing what the function returned. May fail to return, if a function returned. May fail to return, if a breakpoint or signal
breakpoint or signal is hit during the execution of the function. is hit during the execution of the function.
DFEAULT_RETURN_TYPE is used as function return type if the return DFEAULT_RETURN_TYPE is used as function return type if the return
type is unknown. This is used when calling functions with no debug type is unknown. This is used when calling functions with no debug
@ -50,8 +51,7 @@ extern CORE_ADDR find_function_addr (struct value *function,
extern struct value *call_function_by_hand (struct value *function, extern struct value *call_function_by_hand (struct value *function,
type *default_return_type, type *default_return_type,
int nargs, gdb::array_view<value *> args);
struct value **args);
/* Similar to call_function_by_hand and additional call /* Similar to call_function_by_hand and additional call
register_dummy_frame_dtor with DUMMY_DTOR and DUMMY_DTOR_DATA for the register_dummy_frame_dtor with DUMMY_DTOR and DUMMY_DTOR_DATA for the
@ -60,8 +60,7 @@ extern struct value *call_function_by_hand (struct value *function,
extern struct value * extern struct value *
call_function_by_hand_dummy (struct value *function, call_function_by_hand_dummy (struct value *function,
type *default_return_type, type *default_return_type,
int nargs, gdb::array_view<value *> args,
struct value **args,
dummy_frame_dtor_ftype *dummy_dtor, dummy_frame_dtor_ftype *dummy_dtor,
void *dummy_dtor_data); void *dummy_dtor_data);

View file

@ -456,7 +456,7 @@ inferior_call_waitpid (ptid_t pptid, int pid)
{ {
struct objfile *waitpid_objf; struct objfile *waitpid_objf;
struct value *waitpid_fn = NULL; struct value *waitpid_fn = NULL;
struct value *argv[4], *retv; struct value *argv[3], *retv;
struct gdbarch *gdbarch = get_current_arch (); struct gdbarch *gdbarch = get_current_arch ();
struct fork_info *oldfp = NULL, *newfp = NULL; struct fork_info *oldfp = NULL, *newfp = NULL;
struct cleanup *old_cleanup; struct cleanup *old_cleanup;
@ -490,9 +490,8 @@ inferior_call_waitpid (ptid_t pptid, int pid)
argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid); argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid);
argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0); argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0);
argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
argv[3] = 0;
retv = call_function_by_hand (waitpid_fn, NULL, 3, argv); retv = call_function_by_hand (waitpid_fn, NULL, argv);
if (value_as_long (retv) < 0) if (value_as_long (retv) < 0)
goto out; goto out;
@ -704,7 +703,7 @@ checkpoint_command (const char *args, int from_tty)
scoped_restore save_pid scoped_restore save_pid
= make_scoped_restore (&checkpointing_pid, inferior_ptid.pid ()); = make_scoped_restore (&checkpointing_pid, inferior_ptid.pid ());
ret = call_function_by_hand (fork_fn, NULL, 0, &ret); ret = call_function_by_hand (fork_fn, NULL, {});
} }
if (!ret) /* Probably can't happen. */ if (!ret) /* Probably can't happen. */

View file

@ -2400,7 +2400,7 @@ linux_infcall_mmap (CORE_ADDR size, unsigned prot)
arg[ARG_FD] = value_from_longest (builtin_type (gdbarch)->builtin_int, -1); arg[ARG_FD] = value_from_longest (builtin_type (gdbarch)->builtin_int, -1);
arg[ARG_OFFSET] = value_from_longest (builtin_type (gdbarch)->builtin_int64, arg[ARG_OFFSET] = value_from_longest (builtin_type (gdbarch)->builtin_int64,
0); 0);
addr_val = call_function_by_hand (mmap_val, NULL, ARG_LAST, arg); addr_val = call_function_by_hand (mmap_val, NULL, arg);
retval = value_as_address (addr_val); retval = value_as_address (addr_val);
if (retval == (CORE_ADDR) -1) if (retval == (CORE_ADDR) -1)
error (_("Failed inferior mmap call for %s bytes, errno is changed."), error (_("Failed inferior mmap call for %s bytes, errno is changed."),
@ -2429,7 +2429,7 @@ linux_infcall_munmap (CORE_ADDR addr, CORE_ADDR size)
/* Assuming sizeof (unsigned long) == sizeof (size_t). */ /* Assuming sizeof (unsigned long) == sizeof (size_t). */
arg[ARG_LENGTH] = value_from_ulongest arg[ARG_LENGTH] = value_from_ulongest
(builtin_type (gdbarch)->builtin_unsigned_long, size); (builtin_type (gdbarch)->builtin_unsigned_long, size);
retval_val = call_function_by_hand (munmap_val, NULL, ARG_LAST, arg); retval_val = call_function_by_hand (munmap_val, NULL, arg);
retval = value_as_long (retval_val); retval = value_as_long (retval_val);
if (retval != 0) if (retval != 0)
warning (_("Failed inferior munmap call at %s for %s bytes, " warning (_("Failed inferior munmap call at %s for %s bytes, "

View file

@ -132,7 +132,7 @@ lookup_objc_class (struct gdbarch *gdbarch, const char *classname)
classval = value_coerce_array (classval); classval = value_coerce_array (classval);
return (CORE_ADDR) value_as_long (call_function_by_hand (function, return (CORE_ADDR) value_as_long (call_function_by_hand (function,
NULL, NULL,
1, &classval)); classval));
} }
CORE_ADDR CORE_ADDR
@ -160,7 +160,7 @@ lookup_child_selector (struct gdbarch *gdbarch, const char *selname)
selstring = value_coerce_array (value_string (selname, selstring = value_coerce_array (value_string (selname,
strlen (selname) + 1, strlen (selname) + 1,
char_type)); char_type));
return value_as_long (call_function_by_hand (function, NULL, 1, &selstring)); return value_as_long (call_function_by_hand (function, NULL, selstring));
} }
struct value * struct value *
@ -181,13 +181,12 @@ value_nsstring (struct gdbarch *gdbarch, char *ptr, int len)
if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym) if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym)
{ {
function = find_function_in_inferior("_NSNewStringFromCString", NULL); function = find_function_in_inferior("_NSNewStringFromCString", NULL);
nsstringValue = call_function_by_hand(function, nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
NULL, 1, &stringValue[2]);
} }
else if (lookup_minimal_symbol("istr", 0, 0).minsym) else if (lookup_minimal_symbol("istr", 0, 0).minsym)
{ {
function = find_function_in_inferior("istr", NULL); function = find_function_in_inferior("istr", NULL);
nsstringValue = call_function_by_hand(function, NULL, 1, &stringValue[2]); nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
} }
else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym) else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym)
{ {
@ -199,7 +198,7 @@ value_nsstring (struct gdbarch *gdbarch, char *ptr, int len)
(type, lookup_objc_class (gdbarch, "NSString")); (type, lookup_objc_class (gdbarch, "NSString"));
stringValue[1] = value_from_longest stringValue[1] = value_from_longest
(type, lookup_child_selector (gdbarch, "stringWithCString:")); (type, lookup_child_selector (gdbarch, "stringWithCString:"));
nsstringValue = call_function_by_hand(function, NULL, 3, &stringValue[0]); nsstringValue = call_function_by_hand(function, NULL, stringValue);
} }
else else
error (_("NSString: internal error -- no way to create new NSString")); error (_("NSString: internal error -- no way to create new NSString"));
@ -1189,7 +1188,7 @@ print_object_command (const char *args, int from_tty)
if (function == NULL) if (function == NULL)
error (_("Unable to locate _NSPrintForDebugger in child process")); error (_("Unable to locate _NSPrintForDebugger in child process"));
description = call_function_by_hand (function, NULL, 1, &object); description = call_function_by_hand (function, NULL, object);
string_addr = value_as_long (description); string_addr = value_as_long (description);
if (string_addr == 0) if (string_addr == 0)

View file

@ -917,10 +917,10 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
TRY TRY
{ {
scoped_value_mark free_values; scoped_value_mark free_values;
struct value *return_value;
return_value = call_function_by_hand (function, NULL, value *return_value
args_count, vargs); = call_function_by_hand (function, NULL,
gdb::make_array_view (vargs, args_count));
result = value_to_value_object (return_value); result = value_to_value_object (return_value);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)

View file

@ -1172,7 +1172,7 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
if (noside == EVAL_AVOID_SIDE_EFFECTS) if (noside == EVAL_AVOID_SIDE_EFFECTS)
result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval); result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval);
else else
result = call_function_by_hand (function, NULL, num_args + 1, args.data ()); result = call_function_by_hand (function, NULL, args);
return result; return result;
} }

View file

@ -2041,7 +2041,7 @@ flush_ea_cache (void)
type = lookup_pointer_type (type); type = lookup_pointer_type (type);
addr = BMSYMBOL_VALUE_ADDRESS (msymbol); addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
call_function_by_hand (value_from_pointer (type, addr), NULL, 0, NULL); call_function_by_hand (value_from_pointer (type, addr), NULL, {});
} }
} }

View file

@ -483,6 +483,19 @@ run_tests ()
gdb::array_view<Vec> view_elem = elem; gdb::array_view<Vec> view_elem = elem;
SELF_CHECK (view_elem.size () == 1); SELF_CHECK (view_elem.size () == 1);
} }
/* gdb::make_array_view, int length. */
{
gdb_byte data[] = {0x55, 0x66, 0x77, 0x88};
int len = sizeof (data) / sizeof (data[0]);
auto view = gdb::make_array_view (data, len);
SELF_CHECK (view.data () == data);
SELF_CHECK (view.size () == len);
for (size_t i = 0; i < len; i++)
SELF_CHECK (view[i] == data[i]);
}
} }
} /* namespace array_view_tests */ } /* namespace array_view_tests */

View file

@ -502,8 +502,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
= TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
return value_zero (return_type, VALUE_LVAL (arg1)); return value_zero (return_type, VALUE_LVAL (arg1));
} }
return call_function_by_hand (argvec[0], NULL, 2 - static_memfuncp, return call_function_by_hand (argvec[0], NULL,
argvec + 1); {argvec + 1, 2u - static_memfuncp});
} }
throw_error (NOT_FOUND_ERROR, throw_error (NOT_FOUND_ERROR,
_("member function %s not found"), tstr); _("member function %s not found"), tstr);
@ -618,7 +618,8 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
= TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
return value_zero (return_type, VALUE_LVAL (arg1)); return value_zero (return_type, VALUE_LVAL (arg1));
} }
return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1); return call_function_by_hand (argvec[0], NULL,
gdb::make_array_view (argvec + 1, nargs));
} }
throw_error (NOT_FOUND_ERROR, throw_error (NOT_FOUND_ERROR,
_("member function %s not found"), tstr); _("member function %s not found"), tstr);

View file

@ -184,7 +184,7 @@ value_allocate_space_in_inferior (int len)
struct value *blocklen; struct value *blocklen;
blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len); blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len);
val = call_function_by_hand (val, NULL, 1, &blocklen); val = call_function_by_hand (val, NULL, blocklen);
if (value_logical_not (val)) if (value_logical_not (val))
{ {
if (!target_has_execution) if (!target_has_execution)