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> 2018-11-21 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view. * 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 size_type size () const noexcept { return m_size; }
constexpr bool empty () const noexcept { return m_size == 0; } 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: private:
T *m_array; T *m_array;
size_type m_size; 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) else if (TYPE_CODE (ftype) == TYPE_CODE_XMETHOD)
{ {
type *return_type 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) if (return_type == NULL)
error (_("Xmethod is missing return type.")); 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, return call_internal_function (exp->gdbarch, exp->language_defn,
argvec[0], nargs, argvec + 1); argvec[0], nargs, argvec + 1);
case TYPE_CODE_XMETHOD: 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: default:
return call_function_by_hand (argvec[0], default_return_type, return call_function_by_hand (argvec[0], default_return_type,
gdb::make_array_view (argvec + 1, nargs)); 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); func_name = (char *) alloca (name_len + 1);
strcpy (func_name, &exp->elts[string_pc + 1].string); 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 */ NON_METHOD, /* not method */
NULL, NULL, /* pass NULL symbol since NULL, NULL, /* pass NULL symbol since
symbol is unknown */ symbol is unknown */
@ -1136,7 +1139,8 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
evaluation. */ evaluation. */
struct value *valp = NULL; 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 */ METHOD, /* method */
&arg2, /* the object */ &arg2, /* the object */
NULL, &valp, NULL, NULL, &valp, NULL,
@ -1207,7 +1211,7 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
if (op == OP_VAR_VALUE) if (op == OP_VAR_VALUE)
function = exp->elts[save_pos1+2].symbol; 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 */ NULL, /* no need for name */
NON_METHOD, /* not method */ NON_METHOD, /* not method */
NULL, function, /* the function */ NULL, function, /* the function */

View file

@ -870,12 +870,12 @@ get_matching_xmethod_workers (struct type *type, const char *method_name,
/* See extension.h. */ /* See extension.h. */
type ** std::vector<type *>
xmethod_worker::get_arg_types (int *nargs) 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) if (rc == EXT_LANG_RC_ERROR)
error (_("Error while looking for arg types of a xmethod worker " error (_("Error while looking for arg types of a xmethod worker "
"defined in %s."), m_extlang->capitalized_name); "defined in %s."), m_extlang->capitalized_name);
@ -886,11 +886,11 @@ xmethod_worker::get_arg_types (int *nargs)
/* See extension.h. */ /* See extension.h. */
struct type * 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; 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) if (rc == EXT_LANG_RC_ERROR)
{ {
error (_("Error while fetching result type of an xmethod worker " 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 "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc. */
#include "common/vec.h" #include "common/vec.h"
#include "common/array-view.h"
struct breakpoint; struct breakpoint;
struct command_line; struct command_line;
@ -186,38 +187,35 @@ struct xmethod_worker
virtual ~xmethod_worker () = default; virtual ~xmethod_worker () = default;
/* Invoke the xmethod encapsulated in this worker and return the result. /* 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 method is invoked on OBJ with arguments in the ARGS array. */
the length of the this 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. /* 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 The type of the 'this' object is returned as the first element of
NARGS. The type of the 'this' object is returned as the first element of the vector. */
array. */
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. /* 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: private:
/* Return the types of the arguments the method takes. The number of /* Return the types of the arguments the method takes. The types
arguments is returned in NARGS, and their types are returned in the array are returned in TYPE_ARGS, one per argument. */
ARGTYPES. */
virtual enum ext_lang_rc do_get_arg_types 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. /* Fetch the type of the result of the method implemented by this
OBJECT, ARGS, NARGS are the same as for the invoked method. The result worker. OBJECT and ARGS are the same as for the invoked method.
type is stored in *RESULT_TYPE. */ The result type is stored in *RESULT_TYPE. */
virtual enum ext_lang_rc do_get_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; struct type **result_type_ptr) = 0;
/* The language the xmethod worker is implemented in. */ /* 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 /* Rank a function by comparing its parameter types (PARMS), to the
NPARMS), to the types of an argument list (ARGS, length NARGS). types of an argument list (ARGS). Return a pointer to a badness
Return a pointer to a badness vector. This has NARGS + 1 vector. This has ARGS.size() + 1 entries. */
entries. */
struct badness_vector * struct badness_vector *
rank_function (struct type **parms, int nparms, rank_function (gdb::array_view<type *> parms,
struct value **args, int nargs) gdb::array_view<value *> args)
{ {
int i; int i;
struct badness_vector *bv = XNEW (struct badness_vector); 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->length = args.size () + 1; /* add 1 for the length-match rank. */
bv->rank = XNEWVEC (struct rank, nargs + 1); bv->rank = XNEWVEC (struct rank, args.size () + 1);
/* First compare the lengths of the supplied lists. /* First compare the lengths of the supplied lists.
If there is a mismatch, set it to a high value. */ 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 arguments and ellipsis parameter lists, we should consider those
and rank the length-match more finely. */ and rank the length-match more finely. */
LENGTH_MATCH (bv) = (nargs != nparms) LENGTH_MATCH (bv) = (args.size () != parms.size ())
? LENGTH_MISMATCH_BADNESS ? LENGTH_MISMATCH_BADNESS
: EXACT_MATCH_BADNESS; : EXACT_MATCH_BADNESS;
@ -3497,7 +3496,7 @@ rank_function (struct type **parms, int nparms,
args[i - 1]); args[i - 1]);
/* If more arguments than parameters, add dummy entries. */ /* 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; bv->rank[i] = TOO_FEW_PARAMS_BADNESS;
return bv; return bv;

View file

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

View file

@ -46,11 +46,11 @@ struct python_xmethod_worker : xmethod_worker
/* Implementation of xmethod_worker::invoke for Python. */ /* 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. */ /* 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. /* 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 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. */ 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; type **result_type_ptr) override;
private: private:
@ -293,7 +293,7 @@ gdbpy_get_matching_xmethod_workers
/* See declaration. */ /* See declaration. */
ext_lang_rc 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 /* The gdbpy_enter object needs to be placed first, so that it's the last to
be destroyed. */ be destroyed. */
@ -302,10 +302,6 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
int i = 1, arg_count; int i = 1, arg_count;
gdbpy_ref<> list_iter; 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 gdbpy_ref<> get_arg_types_method
(PyObject_GetAttrString (m_py_worker, get_arg_types_method_name)); (PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
if (get_arg_types_method == NULL) 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; arg_count = 1;
/* Include the 'this' argument in the size. */ /* Include the 'this' argument in the size. */
gdb::unique_xmalloc_ptr<struct type *> type_array arg_types->resize (arg_count + 1);
(XCNEWVEC (struct type *, arg_count + 1));
i = 1; i = 1;
if (list_iter != NULL) 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; return EXT_LANG_RC_ERROR;
} }
(type_array.get ())[i] = arg_type; (*arg_types)[i] = arg_type;
i++; i++;
} }
} }
@ -393,7 +388,7 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
} }
else else
{ {
(type_array.get ())[i] = arg_type; (*arg_types)[i] = arg_type;
i++; 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 be a 'const' value. Hence, create a 'const' variant of the 'this' pointer
type. */ type. */
obj_type = type_object_to_type (m_this_type); obj_type = type_object_to_type (m_this_type);
(type_array.get ())[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type), (*arg_types)[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
NULL); NULL);
*nargs = i;
*arg_types = type_array.release ();
return EXT_LANG_RC_OK; return EXT_LANG_RC_OK;
} }
@ -413,7 +406,8 @@ python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
/* See declaration. */ /* See declaration. */
ext_lang_rc 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) type **result_type_ptr)
{ {
struct type *obj_type, *this_type; 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; 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) if (py_arg_tuple == NULL)
{ {
gdbpy_print_stack (); gdbpy_print_stack ();
@ -472,7 +466,7 @@ python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
release. */ release. */
PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.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]); 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. */ /* See declaration. */
struct value * struct value *
python_xmethod_worker::invoke (struct value *obj, struct value **args, python_xmethod_worker::invoke (struct value *obj,
int nargs) gdb::array_view<value *> args)
{ {
gdbpy_enter enter_py (get_current_arch (), current_language); 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.")); 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) if (py_arg_tuple == NULL)
{ {
gdbpy_print_stack (); gdbpy_print_stack ();
@ -557,7 +551,7 @@ python_xmethod_worker::invoke (struct value *obj, struct value **args,
release. */ release. */
PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.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]); 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++) for (size_t i = 0; i < len; i++)
SELF_CHECK (view[i] == data[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 */ } /* 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. */ situations or combinations thereof. */
static struct value * 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) int *static_memfuncp, enum noside noside)
{ {
struct symbol *symp = NULL; struct symbol *symp = NULL;
struct value *valp = 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 */, &args[0] /* objp */,
NULL /* pass NULL symbol since symbol is unknown */, NULL /* pass NULL symbol since symbol is unknown */,
&valp, &symp, static_memfuncp, 0, noside); &valp, &symp, static_memfuncp, 0, noside);
@ -312,18 +312,18 @@ value_user_defined_cpp_op (struct value **args, int nargs, char *oper,
function, otherwise return NULL. */ function, otherwise return NULL. */
static struct value * static struct value *
value_user_defined_op (struct value **argp, struct value **args, char *name, value_user_defined_op (struct value **argp, gdb::array_view<value *> args,
int *static_memfuncp, int nargs, enum noside noside) char *name, int *static_memfuncp, enum noside noside)
{ {
struct value *result = NULL; struct value *result = NULL;
if (current_language->la_language == language_cplus) 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); noside);
} }
else else
result = value_struct_elt (argp, args, name, static_memfuncp, result = value_struct_elt (argp, args.data (), name, static_memfuncp,
"structure"); "structure");
return result; return result;
@ -342,7 +342,6 @@ struct value *
value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
enum exp_opcode otherop, enum noside noside) enum exp_opcode otherop, enum noside noside)
{ {
struct value **argvec;
char *ptr; char *ptr;
char tstr[13]; char tstr[13];
int static_memfuncp; 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) if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
error (_("Can't do that binary op on that type")); /* FIXME be explicit */ 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[1] = value_addr (arg1);
argvec[2] = arg2; argvec[2] = arg2;
argvec[3] = 0;
/* Make the right function name up. */ /* Make the right function name up. */
strcpy (tstr, "operator__"); 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.")); error (_("Invalid binary operation specified."));
} }
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr, argvec[0] = value_user_defined_op (&arg1, argvec.slice (1), tstr,
&static_memfuncp, 2, noside); &static_memfuncp, noside);
if (argvec[0]) if (argvec[0])
{ {
if (static_memfuncp) if (static_memfuncp)
{ {
argvec[1] = argvec[0]; argvec[1] = argvec[0];
argvec++; argvec = argvec.slice (1);
} }
if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD) 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) if (noside == EVAL_AVOID_SIDE_EFFECTS)
{ {
struct type *return_type 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) if (return_type == NULL)
error (_("Xmethod is missing return type.")); error (_("Xmethod is missing return type."));
return value_zero (return_type, VALUE_LVAL (arg1)); 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) 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 value_zero (return_type, VALUE_LVAL (arg1));
} }
return call_function_by_hand (argvec[0], NULL, return call_function_by_hand (argvec[0], NULL,
{argvec + 1, 2u - static_memfuncp}); argvec.slice (1, 2 - static_memfuncp));
} }
throw_error (NOT_FOUND_ERROR, throw_error (NOT_FOUND_ERROR,
_("member function %s not found"), tstr); _("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) value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
{ {
struct gdbarch *gdbarch = get_type_arch (value_type (arg1)); struct gdbarch *gdbarch = get_type_arch (value_type (arg1));
struct value **argvec;
char *ptr; char *ptr;
char tstr[13], mangle_tstr[13]; char tstr[13], mangle_tstr[13];
int static_memfuncp, nargs; 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) if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
error (_("Can't do that unary op on that type")); /* FIXME be explicit */ 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[1] = value_addr (arg1);
argvec[2] = 0; 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.")); error (_("Invalid unary operation specified."));
} }
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr, argvec[0] = value_user_defined_op (&arg1, argvec.slice (1, nargs), tstr,
&static_memfuncp, nargs, noside); &static_memfuncp, noside);
if (argvec[0]) if (argvec[0])
{ {
if (static_memfuncp) if (static_memfuncp)
{ {
argvec[1] = argvec[0]; argvec[1] = argvec[0];
nargs --; argvec = argvec.slice (1);
argvec++;
} }
if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD) 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) if (noside == EVAL_AVOID_SIDE_EFFECTS)
{ {
struct type *return_type 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) if (return_type == NULL)
error (_("Xmethod is missing return type.")); error (_("Xmethod is missing return type."));
return value_zero (return_type, VALUE_LVAL (arg1)); 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) 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 value_zero (return_type, VALUE_LVAL (arg1));
} }
return call_function_by_hand (argvec[0], NULL, return call_function_by_hand (argvec[0], NULL,
gdb::make_array_view (argvec + 1, nargs)); argvec.slice (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

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