summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2018-11-21 11:55:12 +0000
committerPedro Alves <palves@redhat.com>2018-11-21 12:06:20 +0000
commit6b1747cd135ff9859fceb6043179b1ef94363996 (patch)
tree9dd00eb42169b61747d43efeec410c66ba7070e3
parente71585ffe2e1394858f0fcf809e86f1b324fe4e6 (diff)
downloadbinutils-gdb-6b1747cd135ff9859fceb6043179b1ef94363996.tar.gz
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.
-rw-r--r--gdb/ChangeLog33
-rw-r--r--gdb/common/array-view.h11
-rw-r--r--gdb/eval.c14
-rw-r--r--gdb/extension.c12
-rw-r--r--gdb/extension.h32
-rw-r--r--gdb/gdbtypes.c21
-rw-r--r--gdb/gdbtypes.h5
-rw-r--r--gdb/python/py-xmethods.c40
-rw-r--r--gdb/unittests/array-view-selftests.c22
-rw-r--r--gdb/valarith.c50
-rw-r--r--gdb/valops.c104
-rw-r--r--gdb/value.c13
-rw-r--r--gdb/value.h6
13 files changed, 212 insertions, 151 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e315f34dc15..27da6431b32 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,38 @@
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.
* common/array-view.h (make_array_view): New.
* compile/compile-object-run.c (compile_object_run): Adjust to
diff --git a/gdb/common/array-view.h b/gdb/common/array-view.h
index 9c5fa2a9718..d7293c7c5f3 100644
--- a/gdb/common/array-view.h
+++ b/gdb/common/array-view.h
@@ -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;
diff --git a/gdb/eval.c b/gdb/eval.c
index 6eb210d1096..cb408678a27 100644
--- a/gdb/eval.c
+++ b/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 */
diff --git a/gdb/extension.c b/gdb/extension.c
index e5c014667a3..31d19b5b095 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -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 "
diff --git a/gdb/extension.h b/gdb/extension.h
index 0c8c4ee9343..b9314c0efb7 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -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. */
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 9e87b8f4c5a..4160d996de5 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -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;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index a115857c0ad..731b18d0823 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -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 *);
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 8e616cd4e2d..1c96b585f74 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -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]);
diff --git a/gdb/unittests/array-view-selftests.c b/gdb/unittests/array-view-selftests.c
index 74defa1b403..746062c75a7 100644
--- a/gdb/unittests/array-view-selftests.c
+++ b/gdb/unittests/array-view-selftests.c
@@ -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 */
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 875f5477c23..3a59ada2d56 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -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);
diff --git a/gdb/valops.c b/gdb/valops.c
index 4758b5cdfc6..f0e53a7ce9b 100644
--- a/gdb/valops.c
+++ b/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);
diff --git a/gdb/value.c b/gdb/value.c
index 38fc18e0f69..c7b8468b394 100644
--- a/gdb/value.c
+++ b/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).
diff --git a/gdb/value.h b/gdb/value.h
index 4d75c966edd..54caa58e7ff 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -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