From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 55657 invoked by alias); 21 Nov 2018 12:47:01 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 55608 invoked by uid 89); 21 Nov 2018 12:47:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,KAM_STOCKGEN,SPF_HELO_PASS,T_FILL_THIS_FORM_SHORT,UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=trip, METHOD, nearby, inclusive X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 21 Nov 2018 12:46:55 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DCC4E13AA1; Wed, 21 Nov 2018 12:46:53 +0000 (UTC) Received: from [127.0.0.1] (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id D519D5C221; Wed, 21 Nov 2018 12:46:52 +0000 (UTC) Subject: Re: [PATCH 2/6] invoke_xmethod & array_view To: Simon Marchi , "gdb-patches@sourceware.org" References: <20181015151115.6356-1-palves@redhat.com> <20181015151115.6356-3-palves@redhat.com> <245315f6-dd74-b533-f998-762dbf181a54@ericsson.com> From: Pedro Alves Message-ID: <8947e861-0974-f6b4-f5a8-a181df210e08@redhat.com> Date: Wed, 21 Nov 2018 12:47:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <245315f6-dd74-b533-f998-762dbf181a54@ericsson.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2018-11/txt/msg00351.txt.bz2 On 10/17/2018 05:21 PM, Simon Marchi wrote: > On 2018-10-15 11:11 a.m., Pedro Alves wrote: >> This replaces more pointer+length with gdb::array_view. This time, >> around invoke_xmethod, and then propagating the fallout around, which >> inevitably leads to the overload resolution code. >> >> There are several places in the code that want to grab a slice of an >> array, by advanting the array pointer, and decreasing the length > > "advanting" Fixed. > >> pointer. This patch introduces a pair of new >> gdb::array_view::slice(...) methods to make that convenient and clear. >> Unit test included. > > Cool! > > Just some minor comments. > > I noticed some lines > 80 columns: > > $ git show | grep ^\+ | tr '\t' ' ' | egrep '.{81}' > + return call_xmethod (argvec[0], gdb::make_array_view (argvec + 1, nargs)); > +value_user_defined_op (struct value **argp, gdb::array_view args, char *name, > + && classify_oload_match (new_oload_champ_bv, args.size (), 0) == STANDARD) > Fixed the middle one, thanks. The others are actually at 80 cols. > >> diff --git a/gdb/common/array-view.h b/gdb/common/array-view.h >> index 45d1a4720e..679d2e95c7 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_t size) const noexcept >> + { return {m_array + start, size}; } > > I'm sure there's a logic for using size_type for one parameter and size_t for the other > (instead of size_type for both), but what is it? There's no logic, just some copy&pasting&editing, I guess. > >> + >> + /* 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}; } > > It would perhaps be good to have some asserts (that are only there in development > mode, maybe) to make sure we don't do stupid things, like take a slice > past the end of the array, things like that. A bit like those asserts enabled by > __GLIBCXX_DEBUG. Doing it in development mode might be useful. In that case, it would better be done to e.g., operator[] too, I think. Also, not sure we already have a development vs release preprocessor macro? Thus I'd rather see it in a separate patch. > >> diff --git a/gdb/extension.h b/gdb/extension.h >> index 0c8c4ee934..4716d6f360 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; > > Could you change this to be a pointer to the std::vector? > > https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards#Avoid_non-const_reference_parameters.2C_use_pointers_instead > I changed it, though I'm not a big fan of that rule. As I wrote at , I used to prefer avoiding non-const reference output parameters too back in my earlier C++ days, but I no longer do so much nowadays. The main point of avoiding non-const reference parameters is that supposedly they make function callers unclearer, with no visual indication that the function modified the argument. The idea is that "&foo" instead of "foo" is that visual distinction. But, that point can easily become moot because the visual distinction can be easily lost with pointers too: // the usual argument is that using pointers for output parameters shows // clearly that bar is going to be modified: function (foo, &bar); // but well, we often works with pointers, and if "bar" is a pointer, // we don't get any visual clue anyway either: function (foo, bar); // which suggests that what really helps is seeing the output // variable nearby, suggesting to define it right before the // function call that fills it in, and I would go as far // as saying that clearer symbol names help even more. For e.g.: B bar_out; fill_bar (foo, bar_out); I think that symbol and function naming above is much more important than "&bar" vs "bar". A function called "fill_bar" is clearly going to write to its "bar_out" argument. Also, a pointer can be null, while a reference can not. So a reference parameter automatically implies that you can't pass a NULL pointer to the function (which makes the function's implementation a little bit clearer too), while with a pointer parameter you have to document that, and maybe assert it. With a reference, the compiler is free to optimize accordingly (assume non-null), while with a pointer, you have to use gcc's attribute nonnull if you want that, which no one does. Also, for std::vector parameters in particular, passing by pointer leads to uglier code in the function's implementation, like e.g., (*vec)[idx] = 0; instead of: vec[idx] = 0; We end up with a few instances like that in the series, though admittedly not that many, otherwise I think I'd add something like: auto &vec = *vec_param; at the top of the function and then use vec throughout. So in sum, I nowadays tend to look at reference vs parameter more from the "pointer: optional, can be NULL", vs "reference: non-optional" angle. Though, given GDB's history, we definetely use pointers pervasively in function parameters even when they're not supposed to be optional, that's for sure. Maybe we could come up with some middle ground rule, like always putting in-out and output parameters last, and stressing to use clear symbol names. Anyway, I don't want to block on that discussion (my 1 month round trip time not helping! :-D), so I did the change. >> @@ -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); >> } > > Maybe remove the extra braces, while touching this. This is from : "Any two or more lines in code should be wrapped in braces, even if they are comments, as they look like separate statements: " Here's what I merged. >From 6b1747cd135ff9859fceb6043179b1ef94363996 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 21 Nov 2018 11:55:12 +0000 Subject: [PATCH 2/6] 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. --- gdb/ChangeLog | 33 +++++++++++ gdb/common/array-view.h | 11 ++++ gdb/eval.c | 14 +++-- gdb/extension.c | 12 ++-- gdb/extension.h | 32 +++++------ gdb/gdbtypes.c | 21 ++++--- gdb/gdbtypes.h | 5 +- gdb/python/py-xmethods.c | 40 ++++++-------- gdb/unittests/array-view-selftests.c | 22 ++++++++ gdb/valarith.c | 50 ++++++++--------- gdb/valops.c | 104 +++++++++++++++++------------------ gdb/value.c | 13 ++--- gdb/value.h | 6 +- 13 files changed, 212 insertions(+), 151 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e315f34dc1..27da6431b3 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 9c5fa2a971..d7293c7c5f 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 6eb210d109..cb408678a2 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 e5c014667a..31d19b5b09 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 0c8c4ee934..b9314c0efb 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 9e87b8f4c5..4160d996de 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 a115857c0a..731b18d082 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 8e616cd4e2..1c96b585f7 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 74defa1b40..746062c75a 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 875f5477c2..3a59ada2d5 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 4758b5cdfc..f0e53a7ce9 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 38fc18e0f6..c7b8468b39 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 4d75c966ed..54caa58e7f 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 -- 2.14.4