invoke_xmethod & array_view

This replaces more pointer+length with gdb::array_view.  This time,
around invoke_xmethod, and then propagating the fallout around, which
inevitably leaks to the overload resolution code.

There are several places in the code that want to grab a slice of an
array, by advancing the array pointer, and decreasing the length
pointer.  This patch introduces a pair of new
gdb::array_view::slice(...) methods to make that convenient and clear.
Unit test included.

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

	* common/array-view.h (array_view::splice(size_type, size_t)): New.
	(array_view::splice(size_type)): New.
	* eval.c (eval_call, evaluate_funcall): Adjust to use array_view.
	* extension.c (xmethod_worker::get_arg_types): Adjust to return an
	std::vector.
	(xmethod_worker::get_result_type): Adjust to use gdb::array_view.
	* extension.h: Include "common/array-view.h".
	(xmethod_worker::invoke): Adjust to use gdb::array_view.
	(xmethod_worker::get_arg_types): Adjust to return an std::vector.
	(xmethod_worker::get_result_type): Adjust to use gdb::array_view.
	(xmethod_worker::do_get_arg_types): Adjust to use std::vector.
	(xmethod_worker::do_get_result_type): Adjust to use
	gdb::array_view.
	* gdbtypes.c (rank_function): Adjust to use gdb::array_view.
	* gdbtypes.h: Include "common/array-view.h".
	(rank_function): Adjust to use gdb::array_view.
	* python/py-xmethods.c (python_xmethod_worker::invoke)
	(python_xmethod_worker::do_get_arg_types)
	(python_xmethod_worker::do_get_result_type)
	(python_xmethod_worker::invoke): Adjust to new interfaces.
	* valarith.c (value_user_defined_cpp_op, value_user_defined_op)
	(value_x_binop, value_x_unop): Adjust to use gdb::array_view.
	* valops.c (find_overload_match, find_oload_champ_namespace)
	(find_oload_champ_namespace_loop, find_oload_champ): Adjust to use
	gdb:array_view and the new xmethod_worker interfaces.
	* value.c (result_type_of_xmethod, call_xmethod): Adjust to use
	gdb::array_view.
	* value.h (find_overload_match, result_type_of_xmethod)
	(call_xmethod): Adjust to use gdb::array_view.
	* unittests/array-view-selftests.c: Add slicing tests.
This commit is contained in:
Pedro Alves 2018-11-21 11:55:12 +00:00
parent e71585ffe2
commit 6b1747cd13
13 changed files with 212 additions and 151 deletions

View File

@ -1,3 +1,36 @@
2018-11-21 Pedro Alves <palves@redhat.com>
* common/array-view.h (array_view::splice(size_type, size_t)): New.
(array_view::splice(size_type)): New.
* eval.c (eval_call, evaluate_funcall): Adjust to use array_view.
* extension.c (xmethod_worker::get_arg_types): Adjust to return an
std::vector.
(xmethod_worker::get_result_type): Adjust to use gdb::array_view.
* extension.h: Include "common/array-view.h".
(xmethod_worker::invoke): Adjust to use gdb::array_view.
(xmethod_worker::get_arg_types): Adjust to return an std::vector.
(xmethod_worker::get_result_type): Adjust to use gdb::array_view.
(xmethod_worker::do_get_arg_types): Adjust to use std::vector.
(xmethod_worker::do_get_result_type): Adjust to use
gdb::array_view.
* gdbtypes.c (rank_function): Adjust to use gdb::array_view.
* gdbtypes.h: Include "common/array-view.h".
(rank_function): Adjust to use gdb::array_view.
* python/py-xmethods.c (python_xmethod_worker::invoke)
(python_xmethod_worker::do_get_arg_types)
(python_xmethod_worker::do_get_result_type)
(python_xmethod_worker::invoke): Adjust to new interfaces.
* valarith.c (value_user_defined_cpp_op, value_user_defined_op)
(value_x_binop, value_x_unop): Adjust to use gdb::array_view.
* valops.c (find_overload_match, find_oload_champ_namespace)
(find_oload_champ_namespace_loop, find_oload_champ): Adjust to use
gdb:array_view and the new xmethod_worker interfaces.
* value.c (result_type_of_xmethod, call_xmethod): Adjust to use
gdb::array_view.
* value.h (find_overload_match, result_type_of_xmethod)
(call_xmethod): Adjust to use gdb::array_view.
* unittests/array-view-selftests.c: Add slicing tests.
2018-11-21 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view.

View File

@ -169,6 +169,17 @@ public:
constexpr size_type size () const noexcept { return m_size; }
constexpr bool empty () const noexcept { return m_size == 0; }
/* Slice an array view. */
/* Return a new array view over SIZE elements starting at START. */
constexpr array_view<T> slice (size_type start, size_type size) const noexcept
{ return {m_array + start, size}; }
/* Return a new array view over all the elements after START,
inclusive. */
constexpr array_view<T> slice (size_type start) const noexcept
{ return {m_array + start, size () - start}; }
private:
T *m_array;
size_type m_size;

View File

@ -789,7 +789,9 @@ eval_call (expression *exp, enum noside noside,
else if (TYPE_CODE (ftype) == TYPE_CODE_XMETHOD)
{
type *return_type
= result_type_of_xmethod (argvec[0], nargs, argvec + 1);
= result_type_of_xmethod (argvec[0],
gdb::make_array_view (argvec + 1,
nargs));
if (return_type == NULL)
error (_("Xmethod is missing return type."));
@ -827,7 +829,7 @@ eval_call (expression *exp, enum noside noside,
return call_internal_function (exp->gdbarch, exp->language_defn,
argvec[0], nargs, argvec + 1);
case TYPE_CODE_XMETHOD:
return call_xmethod (argvec[0], nargs, argvec + 1);
return call_xmethod (argvec[0], gdb::make_array_view (argvec + 1, nargs));
default:
return call_function_by_hand (argvec[0], default_return_type,
gdb::make_array_view (argvec + 1, nargs));
@ -1100,7 +1102,8 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
func_name = (char *) alloca (name_len + 1);
strcpy (func_name, &exp->elts[string_pc + 1].string);
find_overload_match (&argvec[1], nargs, func_name,
find_overload_match (gdb::make_array_view (&argvec[1], nargs),
func_name,
NON_METHOD, /* not method */
NULL, NULL, /* pass NULL symbol since
symbol is unknown */
@ -1136,7 +1139,8 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
evaluation. */
struct value *valp = NULL;
(void) find_overload_match (&argvec[1], nargs, tstr,
(void) find_overload_match (gdb::make_array_view (&argvec[1], nargs),
tstr,
METHOD, /* method */
&arg2, /* the object */
NULL, &valp, NULL,
@ -1207,7 +1211,7 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
if (op == OP_VAR_VALUE)
function = exp->elts[save_pos1+2].symbol;
(void) find_overload_match (&argvec[1], nargs,
(void) find_overload_match (gdb::make_array_view (&argvec[1], nargs),
NULL, /* no need for name */
NON_METHOD, /* not method */
NULL, function, /* the function */

View File

@ -870,12 +870,12 @@ get_matching_xmethod_workers (struct type *type, const char *method_name,
/* See extension.h. */
type **
xmethod_worker::get_arg_types (int *nargs)
std::vector<type *>
xmethod_worker::get_arg_types ()
{
type **type_array = NULL;
std::vector<type *> type_array;
ext_lang_rc rc = do_get_arg_types (nargs, &type_array);
ext_lang_rc rc = do_get_arg_types (&type_array);
if (rc == EXT_LANG_RC_ERROR)
error (_("Error while looking for arg types of a xmethod worker "
"defined in %s."), m_extlang->capitalized_name);
@ -886,11 +886,11 @@ xmethod_worker::get_arg_types (int *nargs)
/* See extension.h. */
struct type *
xmethod_worker::get_result_type (value *object, value **args, int nargs)
xmethod_worker::get_result_type (value *object, gdb::array_view<value *> args)
{
type *result_type;
ext_lang_rc rc = do_get_result_type (object, args, nargs, &result_type);
ext_lang_rc rc = do_get_result_type (object, args, &result_type);
if (rc == EXT_LANG_RC_ERROR)
{
error (_("Error while fetching result type of an xmethod worker "

View File

@ -22,6 +22,7 @@
#include "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc. */
#include "common/vec.h"
#include "common/array-view.h"
struct breakpoint;
struct command_line;
@ -186,38 +187,35 @@ struct xmethod_worker
virtual ~xmethod_worker () = default;
/* Invoke the xmethod encapsulated in this worker and return the result.
The method is invoked on OBJ with arguments in the ARGS array. NARGS is
the length of the this array. */
The method is invoked on OBJ with arguments in the ARGS array. */
virtual value *invoke (value *obj, value **args, int nargs) = 0;
virtual value *invoke (value *obj, gdb::array_view<value *> args) = 0;
/* Return the arg types of the xmethod encapsulated in this worker.
An array of arg types is returned. The length of the array is returned in
NARGS. The type of the 'this' object is returned as the first element of
array. */
The type of the 'this' object is returned as the first element of
the vector. */
type **get_arg_types (int *nargs);
std::vector<type *> get_arg_types ();
/* Return the type of the result of the xmethod encapsulated in this worker.
OBJECT, ARGS, NARGS are the same as for invoke. */
OBJECT and ARGS are the same as for invoke. */
type *get_result_type (value *object, value **args, int nargs);
type *get_result_type (value *object, gdb::array_view<value *> args);
private:
/* Return the types of the arguments the method takes. The number of
arguments is returned in NARGS, and their types are returned in the array
ARGTYPES. */
/* Return the types of the arguments the method takes. The types
are returned in TYPE_ARGS, one per argument. */
virtual enum ext_lang_rc do_get_arg_types
(int *nargs, struct type ***arg_types) = 0;
(std::vector<type *> *type_args) = 0;
/* Fetch the type of the result of the method implemented by this worker.
OBJECT, ARGS, NARGS are the same as for the invoked method. The result
type is stored in *RESULT_TYPE. */
/* Fetch the type of the result of the method implemented by this
worker. OBJECT and ARGS are the same as for the invoked method.
The result type is stored in *RESULT_TYPE. */
virtual enum ext_lang_rc do_get_result_type
(struct value *obj, struct value **args, int nargs,
(struct value *obj, gdb::array_view<value *> args,
struct type **result_type_ptr) = 0;
/* The language the xmethod worker is implemented in. */

View File

@ -3464,21 +3464,20 @@ compare_badness (struct badness_vector *a, struct badness_vector *b)
}
}
/* Rank a function by comparing its parameter types (PARMS, length
NPARMS), to the types of an argument list (ARGS, length NARGS).
Return a pointer to a badness vector. This has NARGS + 1
entries. */
/* Rank a function by comparing its parameter types (PARMS), to the
types of an argument list (ARGS). Return a pointer to a badness
vector. This has ARGS.size() + 1 entries. */
struct badness_vector *
rank_function (struct type **parms, int nparms,
struct value **args, int nargs)
rank_function (gdb::array_view<type *> parms,
gdb::array_view<value *> args)
{
int i;
struct badness_vector *bv = XNEW (struct badness_vector);
int min_len = nparms < nargs ? nparms : nargs;
size_t min_len = std::min (parms.size (), args.size ());
bv->length = nargs + 1; /* add 1 for the length-match rank. */
bv->rank = XNEWVEC (struct rank, nargs + 1);
bv->length = args.size () + 1; /* add 1 for the length-match rank. */
bv->rank = XNEWVEC (struct rank, args.size () + 1);
/* First compare the lengths of the supplied lists.
If there is a mismatch, set it to a high value. */
@ -3487,7 +3486,7 @@ rank_function (struct type **parms, int nparms,
arguments and ellipsis parameter lists, we should consider those
and rank the length-match more finely. */
LENGTH_MATCH (bv) = (nargs != nparms)
LENGTH_MATCH (bv) = (args.size () != parms.size ())
? LENGTH_MISMATCH_BADNESS
: EXACT_MATCH_BADNESS;
@ -3497,7 +3496,7 @@ rank_function (struct type **parms, int nparms,
args[i - 1]);
/* If more arguments than parameters, add dummy entries. */
for (i = min_len + 1; i <= nargs; i++)
for (i = min_len + 1; i <= args.size (); i++)
bv->rank[i] = TOO_FEW_PARAMS_BADNESS;
return bv;

View File

@ -45,6 +45,7 @@
*/
#include "hashtab.h"
#include "common/array-view.h"
#include "common/offset-type.h"
#include "common/enum-flags.h"
#include "common/underlying.h"
@ -2044,8 +2045,8 @@ extern int compare_ranks (struct rank a, struct rank b);
extern int compare_badness (struct badness_vector *, struct badness_vector *);
extern struct badness_vector *rank_function (struct type **, int,
struct value **, int);
extern struct badness_vector *rank_function (gdb::array_view<type *> parms,
gdb::array_view<value *> args);
extern struct rank rank_one_type (struct type *, struct type *,
struct value *);

View File

@ -46,11 +46,11 @@ struct python_xmethod_worker : xmethod_worker
/* Implementation of xmethod_worker::invoke for Python. */
value *invoke (value *obj, value **args, int nargs) override;
value *invoke (value *obj, gdb::array_view<value *> args) override;
/* Implementation of xmethod_worker::do_get_arg_types for Python. */
ext_lang_rc do_get_arg_types (int *nargs, type ***arg_types) override;
ext_lang_rc do_get_arg_types (std::vector<type *> *type_args) override;
/* Implementation of xmethod_worker::do_get_result_type for Python.
@ -58,7 +58,7 @@ struct python_xmethod_worker : xmethod_worker
result type, if the get_result_type operation is not provided by WORKER
then EXT_LANG_RC_OK is returned and NULL is returned in *RESULT_TYPE. */
ext_lang_rc do_get_result_type (value *obj, value **args, int nargs,
ext_lang_rc do_get_result_type (value *obj, gdb::array_view<value *> args,
type **result_type_ptr) override;
private:
@ -293,7 +293,7 @@ gdbpy_get_matching_xmethod_workers
/* See declaration. */
ext_lang_rc
python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
python_xmethod_worker::do_get_arg_types (std::vector<type *> *arg_types)
{
/* The gdbpy_enter object needs to be placed first, so that it's the last to
be destroyed. */
@ -302,10 +302,6 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
int i = 1, arg_count;
gdbpy_ref<> list_iter;
/* Set nargs to -1 so that any premature return from this function returns
an invalid/unusable number of arg types. */
*nargs = -1;
gdbpy_ref<> get_arg_types_method
(PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
if (get_arg_types_method == NULL)
@ -345,8 +341,7 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
arg_count = 1;
/* Include the 'this' argument in the size. */
gdb::unique_xmalloc_ptr<struct type *> type_array
(XCNEWVEC (struct type *, arg_count + 1));
arg_types->resize (arg_count + 1);
i = 1;
if (list_iter != NULL)
{
@ -373,7 +368,7 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
return EXT_LANG_RC_ERROR;
}
(type_array.get ())[i] = arg_type;
(*arg_types)[i] = arg_type;
i++;
}
}
@ -393,7 +388,7 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
}
else
{
(type_array.get ())[i] = arg_type;
(*arg_types)[i] = arg_type;
i++;
}
}
@ -402,10 +397,8 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
be a 'const' value. Hence, create a 'const' variant of the 'this' pointer
type. */
obj_type = type_object_to_type (m_this_type);
(type_array.get ())[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
NULL);
*nargs = i;
*arg_types = type_array.release ();
(*arg_types)[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
NULL);
return EXT_LANG_RC_OK;
}
@ -413,7 +406,8 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
/* See declaration. */
ext_lang_rc
python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
python_xmethod_worker::do_get_result_type (value *obj,
gdb::array_view<value *> args,
type **result_type_ptr)
{
struct type *obj_type, *this_type;
@ -461,7 +455,7 @@ python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
return EXT_LANG_RC_ERROR;
}
gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
gdbpy_ref<> py_arg_tuple (PyTuple_New (args.size () + 1));
if (py_arg_tuple == NULL)
{
gdbpy_print_stack ();
@ -472,7 +466,7 @@ python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
release. */
PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
for (i = 0; i < nargs; i++)
for (i = 0; i < args.size (); i++)
{
PyObject *py_value_arg = value_to_value_object (args[i]);
@ -508,8 +502,8 @@ python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
/* See declaration. */
struct value *
python_xmethod_worker::invoke (struct value *obj, struct value **args,
int nargs)
python_xmethod_worker::invoke (struct value *obj,
gdb::array_view<value *> args)
{
gdbpy_enter enter_py (get_current_arch (), current_language);
@ -546,7 +540,7 @@ python_xmethod_worker::invoke (struct value *obj, struct value **args,
error (_("Error while executing Python code."));
}
gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
gdbpy_ref<> py_arg_tuple (PyTuple_New (args.size () + 1));
if (py_arg_tuple == NULL)
{
gdbpy_print_stack ();
@ -557,7 +551,7 @@ python_xmethod_worker::invoke (struct value *obj, struct value **args,
release. */
PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
for (i = 0; i < nargs; i++)
for (i = 0; i < args.size (); i++)
{
PyObject *py_value_arg = value_to_value_object (args[i]);

View File

@ -496,6 +496,28 @@ run_tests ()
for (size_t i = 0; i < len; i++)
SELF_CHECK (view[i] == data[i]);
}
/* Test slicing. */
{
gdb_byte data[] = {0x55, 0x66, 0x77, 0x88, 0x99};
gdb::array_view<gdb_byte> view = data;
{
auto slc = view.slice (1, 3);
SELF_CHECK (slc.data () == data + 1);
SELF_CHECK (slc.size () == 3);
SELF_CHECK (slc[0] == data[1]);
SELF_CHECK (slc[0] == view[1]);
}
{
auto slc = view.slice (2);
SELF_CHECK (slc.data () == data + 2);
SELF_CHECK (slc.size () == 3);
SELF_CHECK (slc[0] == view[2]);
SELF_CHECK (slc[0] == data[2]);
}
}
}
} /* namespace array_view_tests */

View File

@ -281,14 +281,14 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
situations or combinations thereof. */
static struct value *
value_user_defined_cpp_op (struct value **args, int nargs, char *oper,
value_user_defined_cpp_op (gdb::array_view<value *> args, char *oper,
int *static_memfuncp, enum noside noside)
{
struct symbol *symp = NULL;
struct value *valp = NULL;
find_overload_match (args, nargs, oper, BOTH /* could be method */,
find_overload_match (args, oper, BOTH /* could be method */,
&args[0] /* objp */,
NULL /* pass NULL symbol since symbol is unknown */,
&valp, &symp, static_memfuncp, 0, noside);
@ -312,19 +312,19 @@ value_user_defined_cpp_op (struct value **args, int nargs, char *oper,
function, otherwise return NULL. */
static struct value *
value_user_defined_op (struct value **argp, struct value **args, char *name,
int *static_memfuncp, int nargs, enum noside noside)
value_user_defined_op (struct value **argp, gdb::array_view<value *> args,
char *name, int *static_memfuncp, enum noside noside)
{
struct value *result = NULL;
if (current_language->la_language == language_cplus)
{
result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp,
result = value_user_defined_cpp_op (args, name, static_memfuncp,
noside);
}
else
result = value_struct_elt (argp, args, name, static_memfuncp,
"structure");
result = value_struct_elt (argp, args.data (), name, static_memfuncp,
"structure");
return result;
}
@ -342,7 +342,6 @@ struct value *
value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
enum exp_opcode otherop, enum noside noside)
{
struct value **argvec;
char *ptr;
char tstr[13];
int static_memfuncp;
@ -356,10 +355,11 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
error (_("Can't do that binary op on that type")); /* FIXME be explicit */
argvec = (struct value **) alloca (sizeof (struct value *) * 4);
value *argvec_storage[3];
gdb::array_view<value *> argvec = argvec_storage;
argvec[1] = value_addr (arg1);
argvec[2] = arg2;
argvec[3] = 0;
/* Make the right function name up. */
strcpy (tstr, "operator__");
@ -469,15 +469,15 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
error (_("Invalid binary operation specified."));
}
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
&static_memfuncp, 2, noside);
argvec[0] = value_user_defined_op (&arg1, argvec.slice (1), tstr,
&static_memfuncp, noside);
if (argvec[0])
{
if (static_memfuncp)
{
argvec[1] = argvec[0];
argvec++;
argvec = argvec.slice (1);
}
if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
{
@ -486,13 +486,13 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *return_type
= result_type_of_xmethod (argvec[0], 2, argvec + 1);
= result_type_of_xmethod (argvec[0], argvec.slice (1));
if (return_type == NULL)
error (_("Xmethod is missing return type."));
return value_zero (return_type, VALUE_LVAL (arg1));
}
return call_xmethod (argvec[0], 2, argvec + 1);
return call_xmethod (argvec[0], argvec.slice (1));
}
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
@ -503,7 +503,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
return value_zero (return_type, VALUE_LVAL (arg1));
}
return call_function_by_hand (argvec[0], NULL,
{argvec + 1, 2u - static_memfuncp});
argvec.slice (1, 2 - static_memfuncp));
}
throw_error (NOT_FOUND_ERROR,
_("member function %s not found"), tstr);
@ -519,7 +519,6 @@ struct value *
value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
{
struct gdbarch *gdbarch = get_type_arch (value_type (arg1));
struct value **argvec;
char *ptr;
char tstr[13], mangle_tstr[13];
int static_memfuncp, nargs;
@ -532,7 +531,9 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
error (_("Can't do that unary op on that type")); /* FIXME be explicit */
argvec = (struct value **) alloca (sizeof (struct value *) * 4);
value *argvec_storage[3];
gdb::array_view<value *> argvec = argvec_storage;
argvec[1] = value_addr (arg1);
argvec[2] = 0;
@ -584,16 +585,15 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
error (_("Invalid unary operation specified."));
}
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
&static_memfuncp, nargs, noside);
argvec[0] = value_user_defined_op (&arg1, argvec.slice (1, nargs), tstr,
&static_memfuncp, noside);
if (argvec[0])
{
if (static_memfuncp)
{
argvec[1] = argvec[0];
nargs --;
argvec++;
argvec = argvec.slice (1);
}
if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
{
@ -602,13 +602,13 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *return_type
= result_type_of_xmethod (argvec[0], 1, argvec + 1);
= result_type_of_xmethod (argvec[0], argvec[1]);
if (return_type == NULL)
error (_("Xmethod is missing return type."));
return value_zero (return_type, VALUE_LVAL (arg1));
}
return call_xmethod (argvec[0], 1, argvec + 1);
return call_xmethod (argvec[0], argvec[1]);
}
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
@ -619,7 +619,7 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
return value_zero (return_type, VALUE_LVAL (arg1));
}
return call_function_by_hand (argvec[0], NULL,
gdb::make_array_view (argvec + 1, nargs));
argvec.slice (1, nargs));
}
throw_error (NOT_FOUND_ERROR,
_("member function %s not found"), tstr);

View File

@ -54,20 +54,19 @@ static struct value *search_struct_method (const char *, struct value **,
struct value **,
LONGEST, int *, struct type *);
static int find_oload_champ_namespace (struct value **, int,
static int find_oload_champ_namespace (gdb::array_view<value *> args,
const char *, const char *,
struct symbol ***,
struct badness_vector **,
const int no_adl);
static
int find_oload_champ_namespace_loop (struct value **, int,
const char *, const char *,
int, struct symbol ***,
struct badness_vector **, int *,
const int no_adl);
static int find_oload_champ_namespace_loop (gdb::array_view<value *> args,
const char *, const char *,
int, struct symbol ***,
struct badness_vector **, int *,
const int no_adl);
static int find_oload_champ (struct value **, int, int,
static int find_oload_champ (gdb::array_view<value *> args, int,
struct fn_field *,
const std::vector<xmethod_worker_up> *,
struct symbol **, struct badness_vector **);
@ -2446,11 +2445,11 @@ value_find_oload_method_list (struct value **argp, const char *method,
basetype, boffset);
}
/* Given an array of arguments (ARGS) (which includes an
entry for "this" in the case of C++ methods), the number of
arguments NARGS, the NAME of a function, and whether it's a method or
not (METHOD), find the best function that matches on the argument types
according to the overload resolution rules.
/* Given an array of arguments (ARGS) (which includes an entry for
"this" in the case of C++ methods), the NAME of a function, and
whether it's a method or not (METHOD), find the best function that
matches on the argument types according to the overload resolution
rules.
METHOD can be one of three values:
NON_METHOD for non-member functions.
@ -2493,7 +2492,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
resolution is permitted. */
int
find_overload_match (struct value **args, int nargs,
find_overload_match (gdb::array_view<value *> args,
const char *name, enum oload_search_type method,
struct value **objp, struct symbol *fsym,
struct value **valp, struct symbol **symp,
@ -2578,12 +2577,12 @@ find_overload_match (struct value **args, int nargs,
{
gdb_assert (TYPE_SELF_TYPE (fns_ptr[0].type) != NULL);
src_method_oload_champ = find_oload_champ (args, nargs,
src_method_oload_champ = find_oload_champ (args,
num_fns, fns_ptr, NULL,
NULL, &src_method_badness);
src_method_match_quality = classify_oload_match
(src_method_badness, nargs,
(src_method_badness, args.size (),
oload_method_static_p (fns_ptr, src_method_oload_champ));
make_cleanup (xfree, src_method_badness);
@ -2591,11 +2590,10 @@ find_overload_match (struct value **args, int nargs,
if (!xm_worker_vec.empty ())
{
ext_method_oload_champ = find_oload_champ (args, nargs,
0, NULL, &xm_worker_vec,
ext_method_oload_champ = find_oload_champ (args, 0, NULL, &xm_worker_vec,
NULL, &ext_method_badness);
ext_method_match_quality = classify_oload_match (ext_method_badness,
nargs, 0);
args.size (), 0);
make_cleanup (xfree, ext_method_badness);
}
@ -2708,7 +2706,7 @@ find_overload_match (struct value **args, int nargs,
return 0;
}
func_oload_champ = find_oload_champ_namespace (args, nargs,
func_oload_champ = find_oload_champ_namespace (args,
func_name,
qualified_name,
&oload_syms,
@ -2716,7 +2714,8 @@ find_overload_match (struct value **args, int nargs,
no_adl);
if (func_oload_champ >= 0)
func_match_quality = classify_oload_match (func_badness, nargs, 0);
func_match_quality = classify_oload_match (func_badness,
args.size (), 0);
make_cleanup (xfree, oload_syms);
make_cleanup (xfree, func_badness);
@ -2855,7 +2854,7 @@ find_overload_match (struct value **args, int nargs,
performned. */
static int
find_oload_champ_namespace (struct value **args, int nargs,
find_oload_champ_namespace (gdb::array_view<value *> args,
const char *func_name,
const char *qualified_name,
struct symbol ***oload_syms,
@ -2864,7 +2863,7 @@ find_oload_champ_namespace (struct value **args, int nargs,
{
int oload_champ;
find_oload_champ_namespace_loop (args, nargs,
find_oload_champ_namespace_loop (args,
func_name,
qualified_name, 0,
oload_syms, oload_champ_bv,
@ -2884,7 +2883,7 @@ find_oload_champ_namespace (struct value **args, int nargs,
*OLOAD_CHAMP_BV. */
static int
find_oload_champ_namespace_loop (struct value **args, int nargs,
find_oload_champ_namespace_loop (gdb::array_view<value *> args,
const char *func_name,
const char *qualified_name,
int namespace_len,
@ -2921,7 +2920,7 @@ find_oload_champ_namespace_loop (struct value **args, int nargs,
{
searched_deeper = 1;
if (find_oload_champ_namespace_loop (args, nargs,
if (find_oload_champ_namespace_loop (args,
func_name, qualified_name,
next_namespace_len,
oload_syms, oload_champ_bv,
@ -2956,16 +2955,16 @@ find_oload_champ_namespace_loop (struct value **args, int nargs,
/* Prepare list of argument types for overload resolution. */
arg_types = (struct type **)
alloca (nargs * (sizeof (struct type *)));
for (ix = 0; ix < nargs; ix++)
alloca (args.size () * (sizeof (struct type *)));
for (ix = 0; ix < args.size (); ix++)
arg_types[ix] = value_type (args[ix]);
make_symbol_overload_list_adl (arg_types, nargs, func_name);
make_symbol_overload_list_adl (arg_types, args.size (), func_name);
}
while (new_oload_syms[num_fns])
++num_fns;
new_oload_champ = find_oload_champ (args, nargs, num_fns,
new_oload_champ = find_oload_champ (args, num_fns,
NULL, NULL, new_oload_syms,
&new_oload_champ_bv);
@ -2977,7 +2976,7 @@ find_oload_champ_namespace_loop (struct value **args, int nargs,
it's a bad match. */
if (new_oload_champ != -1
&& classify_oload_match (new_oload_champ_bv, nargs, 0) == STANDARD)
&& classify_oload_match (new_oload_champ_bv, args.size (), 0) == STANDARD)
{
*oload_syms = new_oload_syms;
*oload_champ = new_oload_champ;
@ -3002,11 +3001,10 @@ find_oload_champ_namespace_loop (struct value **args, int nargs,
}
}
/* Look for a function to take NARGS args of ARGS. Find
the best match from among the overloaded methods or functions
given by FNS_PTR or OLOAD_SYMS or XM_WORKER_VEC, respectively.
One, and only one of FNS_PTR, OLOAD_SYMS and XM_WORKER_VEC can be
non-NULL.
/* Look for a function to take ARGS. Find the best match from among
the overloaded methods or functions given by FNS_PTR or OLOAD_SYMS
or XM_WORKER_VEC, respectively. One, and only one of FNS_PTR,
OLOAD_SYMS and XM_WORKER_VEC can be non-NULL.
If XM_WORKER_VEC is NULL, then the length of the arrays FNS_PTR
or OLOAD_SYMS (whichever is non-NULL) is specified in NUM_FNS.
@ -3017,7 +3015,7 @@ find_oload_champ_namespace_loop (struct value **args, int nargs,
It is the caller's responsibility to free *OLOAD_CHAMP_BV. */
static int
find_oload_champ (struct value **args, int nargs,
find_oload_champ (gdb::array_view<value *> args,
int num_fns, struct fn_field *fns_ptr,
const std::vector<xmethod_worker_up> *xm_worker_vec,
struct symbol **oload_syms,
@ -3047,16 +3045,17 @@ find_oload_champ (struct value **args, int nargs,
{
int jj;
int static_offset = 0;
int nparms;
struct type **parm_types;
std::vector<type *> parm_types;
if (xm_worker_vec != NULL)
{
xmethod_worker *worker = (*xm_worker_vec)[ix].get ();
parm_types = worker->get_arg_types (&nparms);
parm_types = worker->get_arg_types ();
}
else
{
size_t nparms;
if (fns_ptr != NULL)
{
nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
@ -3065,19 +3064,21 @@ find_oload_champ (struct value **args, int nargs,
else
nparms = TYPE_NFIELDS (SYMBOL_TYPE (oload_syms[ix]));
parm_types = XNEWVEC (struct type *, nparms);
parm_types.reserve (nparms);
for (jj = 0; jj < nparms; jj++)
parm_types[jj] = (fns_ptr != NULL
? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type)
: TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]),
jj));
{
type *t = (fns_ptr != NULL
? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type)
: TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]),
jj));
parm_types.push_back (t);
}
}
/* Compare parameter types to supplied argument types. Skip
THIS for static methods. */
bv = rank_function (parm_types, nparms,
args + static_offset,
nargs - static_offset);
bv = rank_function (parm_types,
args.slice (static_offset));
if (!*oload_champ_bv)
{
@ -3103,24 +3104,23 @@ find_oload_champ (struct value **args, int nargs,
default:
break;
}
xfree (parm_types);
if (overload_debug)
{
if (fns_ptr != NULL)
fprintf_filtered (gdb_stderr,
"Overloaded method instance %s, # of parms %d\n",
fns_ptr[ix].physname, nparms);
fns_ptr[ix].physname, (int) parm_types.size ());
else if (xm_worker_vec != NULL)
fprintf_filtered (gdb_stderr,
"Xmethod worker, # of parms %d\n",
nparms);
(int) parm_types.size ());
else
fprintf_filtered (gdb_stderr,
"Overloaded function instance "
"%s # of parms %d\n",
SYMBOL_DEMANGLED_NAME (oload_syms[ix]),
nparms);
for (jj = 0; jj < nargs - static_offset; jj++)
(int) parm_types.size ());
for (jj = 0; jj < args.size () - static_offset; jj++)
fprintf_filtered (gdb_stderr,
"...Badness @ %d : %d\n",
jj, bv->rank[jj].rank);

View File

@ -2583,24 +2583,23 @@ value_from_xmethod (xmethod_worker_up &&worker)
/* Return the type of the result of TYPE_CODE_XMETHOD value METHOD. */
struct type *
result_type_of_xmethod (struct value *method, int argc, struct value **argv)
result_type_of_xmethod (struct value *method, gdb::array_view<value *> argv)
{
gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD
&& method->lval == lval_xcallable && argc > 0);
&& method->lval == lval_xcallable && !argv.empty ());
return method->location.xm_worker->get_result_type
(argv[0], argv + 1, argc - 1);
return method->location.xm_worker->get_result_type (argv[0], argv.slice (1));
}
/* Call the xmethod corresponding to the TYPE_CODE_XMETHOD value METHOD. */
struct value *
call_xmethod (struct value *method, int argc, struct value **argv)
call_xmethod (struct value *method, gdb::array_view<value *> argv)
{
gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD
&& method->lval == lval_xcallable && argc > 0);
&& method->lval == lval_xcallable && !argv.empty ());
return method->location.xm_worker->invoke (argv[0], argv + 1, argc - 1);
return method->location.xm_worker->invoke (argv[0], argv.slice (1));
}
/* Extract a value as a C number (either long or double).

View File

@ -835,7 +835,7 @@ extern struct value *value_static_field (struct type *type, int fieldno);
enum oload_search_type { NON_METHOD, METHOD, BOTH };
extern int find_overload_match (struct value **args, int nargs,
extern int find_overload_match (gdb::array_view<value *> args,
const char *name,
enum oload_search_type method,
struct value **objp, struct symbol *fsym,
@ -1175,10 +1175,10 @@ char *value_internal_function_name (struct value *);
extern struct value *value_from_xmethod (xmethod_worker_up &&worker);
extern struct type *result_type_of_xmethod (struct value *method,
int argc, struct value **argv);
gdb::array_view<value *> argv);
extern struct value *call_xmethod (struct value *method,
int argc, struct value **argv);
gdb::array_view<value *> argv);
/* Given a discriminated union type and some corresponding value
contents, this will return the field index of the currently active