This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] invoke_xmethod & array_view


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6b1747cd135ff9859fceb6043179b1ef94363996

commit 6b1747cd135ff9859fceb6043179b1ef94363996
Author: Pedro Alves <palves@redhat.com>
Date:   Wed Nov 21 11:55:12 2018 +0000

    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.

Diff:
---
 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 e315f34..27da643 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 9c5fa2a..d7293c7 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 6eb210d..cb40867 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 e5c0146..31d19b5 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 0c8c4ee..b9314c0 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 9e87b8f..4160d99 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 a115857..731b18d 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 8e616cd..1c96b58 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 74defa1..746062c 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 875f547..3a59ada 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 4758b5c..f0e53a7 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 38fc18e..c7b8468 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 4d75c96..54caa58 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]