From: Pedro Alves Date: Wed, 21 Nov 2018 11:55:12 +0000 (+0000) Subject: invoke_xmethod & array_view X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6b1747cd135ff9859fceb6043179b1ef94363996;p=binutils-gdb.git 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 * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e315f34dc15..27da6431b32 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,36 @@ +2018-11-21 Pedro Alves + + * 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 * ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view. 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 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 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 +xmethod_worker::get_arg_types () { - type **type_array = NULL; + std::vector 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 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 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 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 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_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 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 parms, + gdb::array_view 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 parms, + gdb::array_view 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 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_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 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 *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 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 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 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 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 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 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 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 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 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 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 args, int, struct fn_field *, const std::vector *, 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 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 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 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 args, int num_fns, struct fn_field *fns_ptr, const std::vector *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 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 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 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 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 argv); extern struct value *call_xmethod (struct value *method, - int argc, struct value **argv); + gdb::array_view argv); /* Given a discriminated union type and some corresponding value contents, this will return the field index of the currently active