mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
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:
parent
e71585ffe2
commit
6b1747cd13
@ -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.
|
||||
|
@ -169,6 +169,17 @@ class array_view
|
||||
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;
|
||||
|
14
gdb/eval.c
14
gdb/eval.c
@ -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 */
|
||||
|
@ -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 "
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
@ -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]);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
104
gdb/valops.c
104
gdb/valops.c
@ -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);
|
||||
|
13
gdb/value.c
13
gdb/value.c
@ -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).
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user