]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR python/18285
authorDoug Evans <dje@google.com>
Tue, 12 May 2015 16:18:06 +0000 (09:18 -0700)
committerDoug Evans <dje@google.com>
Tue, 12 May 2015 16:18:06 +0000 (09:18 -0700)
gdb/ChangeLog:

PR python/18285
* NEWS: Document new gdb.XMethodWorker.get_result_type method.
* eval.c (evaluate_subexp_standard) <OP_FUNCALL>: Handle
EVAL_AVOID_SIDE_EFFECTS for xmethods.
* extension-priv.h (struct extension_language_ops)
<get_xmethod_result_type>: New member.
* extension.c (get_xmethod_result_type): New function.
* extension.h (get_xmethod_result_type): Declare.
* python/py-xmethods.c (get_result_type_method_name): New static
global.
(py_get_result_type_method_name): Ditto.
(gdbpy_get_xmethod_result_type): New function.
(gdbpy_initialize_xmethods): Initialize py_get_result_type_method_name.
* python/python-internal.h (gdbpy_get_xmethod_result_type): Declare.
* python/python.c (python_extension_ops): Add
gdbpy_get_xmethod_result_type.
* python/lib/gdb/xmethod.py (XMethodWorker): Add get_result_type.
* valarith.c (value_x_binop): Handle EVAL_AVOID_SIDE_EFFECTS for
xmethods.
(value_x_unop): Ditto.
* value.c (result_type_of_xmethod): New function.
* value.h (result_type_of_xmethod): Declare.

gdb/testsuite/ChangeLog:

* gdb.python/py-xmethods.exp: Add ptype tests.
* gdb.python/py-xmethods.py (E_method_char_worker): Add
get_result_type method.

gdb/doc/ChangeLog:

* python.texi (Xmethod API) <gdb.XMethodWorker.get_result_type>:
Document.
(Writing an Xmethod): Add get_result_type to example.

18 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/python.texi
gdb/eval.c
gdb/extension-priv.h
gdb/extension.c
gdb/extension.h
gdb/python/lib/gdb/xmethod.py
gdb/python/py-xmethods.c
gdb/python/python-internal.h
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-xmethods.exp
gdb/testsuite/gdb.python/py-xmethods.py
gdb/valarith.c
gdb/value.c
gdb/value.h

index ff6fd5063dbc3987de3ca50ed61c3670da09802e..d7d8b169e41b27ca074a93cd4fcdcdb31990dd74 100644 (file)
@@ -1,3 +1,28 @@
+2015-05-12  Doug Evans  <dje@google.com>
+
+       PR python/18285
+       * NEWS: Document new gdb.XMethodWorker.get_result_type method.
+       * eval.c (evaluate_subexp_standard) <OP_FUNCALL>: Handle
+       EVAL_AVOID_SIDE_EFFECTS for xmethods.
+       * extension-priv.h (struct extension_language_ops)
+       <get_xmethod_result_type>: New member.
+       * extension.c (get_xmethod_result_type): New function.
+       * extension.h (get_xmethod_result_type): Declare.
+       * python/py-xmethods.c (get_result_type_method_name): New static
+       global.
+       (py_get_result_type_method_name): Ditto.
+       (gdbpy_get_xmethod_result_type): New function.
+       (gdbpy_initialize_xmethods): Initialize py_get_result_type_method_name.
+       * python/python-internal.h (gdbpy_get_xmethod_result_type): Declare.
+       * python/python.c (python_extension_ops): Add
+       gdbpy_get_xmethod_result_type.
+       * python/lib/gdb/xmethod.py (XMethodWorker): Add get_result_type.
+       * valarith.c (value_x_binop): Handle EVAL_AVOID_SIDE_EFFECTS for
+       xmethods.
+       (value_x_unop): Ditto.
+       * value.c (result_type_of_xmethod): New function.
+       * value.h (result_type_of_xmethod): Declare.
+
 2015-05-02  Pierre Muller  <muller@sourceware.org>
 
        PR pascal/17815
index 9848dbb2629b5e93dcfbf8188a92f0b0d3e1528e..446f13d5cc8b34b9a0f963c8c7d7e300ea904ba4 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -1,6 +1,12 @@
                What has changed in GDB?
             (Organized release by release)
 
+*** Changes in GDB 7.9.1
+
+* Python Scripting
+
+  ** Xmethods can now specify a result type.
+
 *** Changes in GDB 7.9
 
 * GDB now supports hardware watchpoints on x86 GNU Hurd.
index 6c4d5cf8729518b9d631331d0626f92d59268e76..bfbda9ef390dd0b14f842835490674bec27b79b5 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-12  Doug Evans  <dje@google.com>
+
+       * python.texi (Xmethod API) <gdb.XMethodWorker.get_result_type>:
+       Document.
+       (Writing an Xmethod): Add get_result_type to example.
+
 2015-02-20  David Taylor  <dtaylor@emc.com>
 
        * agentexpr.texi (Bytecode Descriptions): Fix summary line for setv.
index b9a50d0d55ecc86008e159375a1365503b25e1af..376c2bdbef471d894a651580332e8e9af80a396c 100644 (file)
@@ -2307,6 +2307,13 @@ If the xmethod takes a single argument, then a single
 @code{gdb.Type} object corresponding to it can be returned.
 @end defun
 
+@defun XMethodWorker.get_result_type (self, *args)
+This method returns a @code{gdb.Type} object representing the type
+of the result of invoking this xmethod.
+The @var{args} argument is the same tuple of arguments that would be
+passed to the @code{__call__} method of this worker.
+@end defun
+
 @defun XMethodWorker.__call__ (self, *args)
 This is the method which does the @emph{work} of the xmethod.  The
 @var{args} arguments is the tuple of arguments to the xmethod.  Each
@@ -2423,6 +2430,9 @@ above is as follows:
 class MyClassWorker_geta(gdb.xmethod.XMethodWorker):
     def get_arg_types(self):
         return None
+
+    def get_result_type(self, obj):
+        return gdb.lookup_type('int')
  
     def __call__(self, obj):
         return obj['a_']
@@ -2431,6 +2441,9 @@ class MyClassWorker_geta(gdb.xmethod.XMethodWorker):
 class MyClassWorker_plus(gdb.xmethod.XMethodWorker):
     def get_arg_types(self):
         return gdb.lookup_type('MyClass')
+
+    def get_result_type(self, obj):
+        return gdb.lookup_type('int')
  
     def __call__(self, obj, other):
         return obj['a_'] + other['a_']
@@ -2494,10 +2507,13 @@ of the xmethod workers and xmethod matchers is as follows:
 class MyTemplateWorker_footprint(gdb.xmethod.XMethodWorker):
     def __init__(self, class_type):
         self.class_type = class_type
+
     def get_arg_types(self):
         return None
+
+    def get_result_type(self):
+        return gdb.lookup_type('int')
+
     def __call__(self, obj):
         return (self.class_type.sizeof +
                 obj['dsize_'] *
index 72ac69f29ca22c7e0094acd1e2cda1cda1de20a3..ec05bb238caedffca4533f3a502386a562bd9fb1 100644 (file)
@@ -1739,6 +1739,15 @@ evaluate_subexp_standard (struct type *expect_type,
              return value_zero (builtin_type (exp->gdbarch)->builtin_int,
                                 not_lval);
            }
+         else if (TYPE_CODE (ftype) == TYPE_CODE_XMETHOD)
+           {
+             struct type *return_type
+               = result_type_of_xmethod (argvec[0], nargs, argvec + 1);
+
+             if (return_type == NULL)
+               error (_("Xmethod is missing return type."));
+             return value_zero (return_type, not_lval);
+           }
          else if (TYPE_GNU_IFUNC (ftype))
            return allocate_value (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)));
          else if (TYPE_TARGET_TYPE (ftype))
index fc0513711e2f06250cadd1a3c2ce4dc3f11f11cf..b7bc12ae344b0b145580f795f56748e5d8f9a4ea 100644 (file)
@@ -260,7 +260,7 @@ struct extension_language_ops
   /* xmethod support:
      clone_xmethod_worker_data, free_xmethod_worker_data,
      get_matching_xmethod_workers, get_xmethod_arg_types,
-     invoke_xmethod.
+     get_xmethod_return_type, invoke_xmethod.
      These methods are optional and may be NULL, but if one of them is
      implemented then they all must be.  */
 
@@ -293,6 +293,18 @@ struct extension_language_ops
      int *nargs,
      struct type ***arg_types);
 
+  /* Given a WORKER servicing a particular method, fetch the type of the
+     result of the method.  OBJECT, ARGS, NARGS are the same as for
+     invoke_xmethod.  The result type is stored in *RESULT_TYPE.
+     For backward compatibility with 7.9, which did not support getting the
+     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.  */
+  enum ext_lang_rc (*get_xmethod_result_type)
+    (const struct extension_language_defn *extlang,
+     struct xmethod_worker *worker,
+     struct value *object, struct value **args, int nargs,
+     struct type **result_type);
+
   /* Invoke the xmethod serviced by WORKER.  The xmethod is invoked
      on OBJECT with arguments in the array ARGS.  NARGS is the length of
      this array.  Returns the value returned by the xmethod.  */
index 853ef67cce38201c14c75f60955c69a9683239f9..fe62918e382a8d8208ca32cf8ec5a5847a2a3a03 100644 (file)
@@ -948,6 +948,31 @@ get_xmethod_arg_types (struct xmethod_worker *worker, int *nargs)
   return type_array;
 }
 
+/* Return the type of the result of the xmethod encapsulated in WORKER.
+   OBJECT, ARGS, NARGS are the same as for invoke_xmethod.  */
+
+struct type *
+get_xmethod_result_type (struct xmethod_worker *worker,
+                        struct value *object, struct value **args, int nargs)
+{
+  enum ext_lang_rc rc;
+  struct type *result_type;
+  const struct extension_language_defn *extlang = worker->extlang;
+
+  gdb_assert (extlang->ops->get_xmethod_arg_types != NULL);
+
+  rc = extlang->ops->get_xmethod_result_type (extlang, worker,
+                                             object, args, nargs,
+                                             &result_type);
+  if (rc == EXT_LANG_RC_ERROR)
+    {
+      error (_("Error while fetching result type of an xmethod worker "
+              "defined in %s."), extlang->capitalized_name);
+    }
+
+  return result_type;
+}
+
 /* Invokes the xmethod encapsulated in WORKER and returns the result.
    The method is invoked on OBJ with arguments in the ARGS array.  NARGS is
    the length of the this array.  */
index a53f0a7c6ef85104188aa471dfcbc19a7cf6706b..099b8c3aad02fd592db0f93438aaab7b31ee918f 100644 (file)
@@ -251,4 +251,8 @@ extern xmethod_worker_vec *get_matching_xmethod_workers
 
 extern struct type **get_xmethod_arg_types (struct xmethod_worker *, int *);
 
+extern struct type *get_xmethod_result_type (struct xmethod_worker *,
+                                            struct value *object,
+                                            struct value **args, int nargs);
+
 #endif /* EXTENSION_H */
index 672b2d8ea5de762ef57f4e50e7f4719754b4938f..6acc23c7000f32c4c0a266bc7fdd7772ffef3f56 100644 (file)
@@ -101,9 +101,11 @@ class XMethodWorker(object):
     invokes the method when GDB wants it to.  Internally, GDB first invokes the
     'get_arg_types' method to perform overload resolution.  If GDB selects to
     invoke this Python xmethod, then it invokes it via the overridden
-    '__call__' method.
+    '__call__' method.  The 'get_result_type' method is used to implement
+    'ptype' on the xmethod.
 
-    Derived classes should override the 'get_arg_types' and '__call__' methods.
+    Derived classes should override the 'get_arg_types', 'get_result_type'
+    and '__call__' methods.
     """
 
     def get_arg_types(self):
@@ -117,6 +119,20 @@ class XMethodWorker(object):
         """
         raise NotImplementedError("XMethodWorker get_arg_types")
 
+    def get_result_type(self, *args):
+        """Return the type of the result of the xmethod.
+
+        Args:
+            args: Arguments to the method.  Each element of the tuple is a
+                gdb.Value object.  The first element is the 'this' pointer
+                value.  These are the same arguments passed to '__call__'.
+
+        Returns:
+            A gdb.Type object representing the type of the result of the
+            xmethod.
+        """
+        raise NotImplementedError("XMethodWorker get_result_type")
+
     def __call__(self, *args):
         """Invoke the xmethod.
 
index 0a7fc381e61736678e4f5e459766e91143439418..91e2691d418144296955b56aed5ae068490ff2b1 100644 (file)
 static const char enabled_field_name[] = "enabled";
 static const char match_method_name[] = "match";
 static const char get_arg_types_method_name[] = "get_arg_types";
+static const char get_result_type_method_name[] = "get_result_type";
 static const char invoke_method_name[] = "invoke";
 static const char matchers_attr_str[] = "xmethods";
 
 static PyObject *py_match_method_name = NULL;
 static PyObject *py_get_arg_types_method_name = NULL;
+static PyObject *py_get_result_type_method_name = NULL;
 static PyObject *py_invoke_method_name = NULL;
 
 struct gdbpy_worker_data
@@ -502,6 +504,106 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
   return EXT_LANG_RC_OK;
 }
 
+/* Implementation of get_xmethod_result_type for Python.  */
+
+enum ext_lang_rc
+gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
+                              struct xmethod_worker *worker,
+                              struct value *obj,
+                              struct value **args, int nargs,
+                              struct type **result_type_ptr)
+{
+  struct gdbpy_worker_data *worker_data = worker->data;
+  PyObject *py_worker = worker_data->worker;
+  PyObject *py_value_obj, *py_arg_tuple, *py_result_type;
+  PyObject *get_result_type_method;
+  struct type *obj_type, *this_type;
+  struct cleanup *cleanups;
+  int i;
+
+  cleanups = ensure_python_env (get_current_arch (), current_language);
+
+  /* First see if there is a get_result_type method.
+     If not this could be an old xmethod (pre 7.9.1).  */
+  get_result_type_method
+    = PyObject_GetAttrString (py_worker, get_result_type_method_name);
+  if (get_result_type_method == NULL)
+    {
+      PyErr_Clear ();
+      do_cleanups (cleanups);
+      *result_type_ptr = NULL;
+      return EXT_LANG_RC_OK;
+    }
+  make_cleanup_py_decref (get_result_type_method);
+
+  obj_type = check_typedef (value_type (obj));
+  this_type = check_typedef (type_object_to_type (worker_data->this_type));
+  if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
+    {
+      struct type *this_ptr = lookup_pointer_type (this_type);
+
+      if (!types_equal (obj_type, this_ptr))
+       obj = value_cast (this_ptr, obj);
+    }
+  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+    {
+      struct type *this_ref = lookup_reference_type (this_type);
+
+      if (!types_equal (obj_type, this_ref))
+       obj = value_cast (this_ref, obj);
+    }
+  else
+    {
+      if (!types_equal (obj_type, this_type))
+       obj = value_cast (this_type, obj);
+    }
+  py_value_obj = value_to_value_object (obj);
+  if (py_value_obj == NULL)
+    goto Fail;
+  make_cleanup_py_decref (py_value_obj);
+
+  py_arg_tuple = PyTuple_New (nargs + 1);
+  if (py_arg_tuple == NULL)
+    goto Fail;
+  make_cleanup_py_decref (py_arg_tuple);
+
+  /* PyTuple_SET_ITEM steals the reference of the element.  Hence INCREF the
+     reference to the 'this' object as we have a cleanup to DECREF it.  */
+  Py_INCREF (py_value_obj);
+  PyTuple_SET_ITEM (py_arg_tuple, 0, py_value_obj);
+
+  for (i = 0; i < nargs; i++)
+    {
+      PyObject *py_value_arg = value_to_value_object (args[i]);
+
+      if (py_value_arg == NULL)
+       goto Fail;
+      PyTuple_SET_ITEM (py_arg_tuple, i + 1, py_value_arg);
+    }
+
+  py_result_type = PyObject_CallObject (get_result_type_method, py_arg_tuple);
+  if (py_result_type == NULL)
+    goto Fail;
+  make_cleanup_py_decref (py_result_type);
+
+  *result_type_ptr = type_object_to_type (py_result_type);
+  if (*result_type_ptr == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError,
+                      _("Type returned by the get_result_type method of an"
+                        " xmethod worker object is not a gdb.Type object."));
+      goto Fail;
+    }
+
+  do_cleanups (cleanups);
+  return EXT_LANG_RC_OK;
+
+ Fail:
+  gdbpy_print_stack ();
+  do_cleanups (cleanups);
+  return EXT_LANG_RC_ERROR;
+}
+
 /* Implementation of invoke_xmethod for Python.  */
 
 struct value *
@@ -638,5 +740,10 @@ gdbpy_initialize_xmethods (void)
   if (py_get_arg_types_method_name == NULL)
     return -1;
 
+  py_get_result_type_method_name
+    = PyString_FromString (get_result_type_method_name);
+  if (py_get_result_type_method_name == NULL)
+    return -1;
+
   return 1;
 }
index 0ee85440fb436de496424ccdc7c7eee472bd6c1f..67460637a976a95d2eaef3429f63c89ec10f18d9 100644 (file)
@@ -343,6 +343,11 @@ extern enum ext_lang_rc gdbpy_get_xmethod_arg_types
    struct xmethod_worker *worker,
    int *nargs,
    struct type ***arg_types);
+extern enum ext_lang_rc gdbpy_get_xmethod_result_type
+  (const struct extension_language_defn *extlang,
+   struct xmethod_worker *worker,
+   struct value *object, struct value **args, int nargs,
+   struct type **result_type);
 extern struct value *gdbpy_invoke_xmethod
   (const struct extension_language_defn *extlang,
    struct xmethod_worker *worker,
index f4b8fcf534ca540fff46ac04c93cac9cdd6f28ff..9497f093431257dfbe12f52c75eb06ef7bacf171 100644 (file)
@@ -190,6 +190,7 @@ static const struct extension_language_ops python_extension_ops =
   gdbpy_free_xmethod_worker_data,
   gdbpy_get_matching_xmethod_workers,
   gdbpy_get_xmethod_arg_types,
+  gdbpy_get_xmethod_result_type,
   gdbpy_invoke_xmethod
 };
 
index 727afe3a81464a06b0858cc1741cbc0c50736471..4758e5b5afd0b6a8a85bf5e2db6e4aca1fb22901 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-12  Doug Evans  <dje@google.com>
+
+       * gdb.python/py-xmethods.exp: Add ptype tests.
+       * gdb.python/py-xmethods.py (E_method_char_worker): Add
+       get_result_type method.
+
 2015-05-02  Pierre Muller  <muller@sourceware.org>
 
        PR pascal/17815
index a83b14d284f2ff7184a5cf87a530d75f1feed809..eea1283ba17bf7ff3e942531468cce799a1e73f8 100644 (file)
@@ -107,8 +107,9 @@ gdb_test "p a_ptr->geta()" "From Python <A_geta>.*30" "After: a_ptr->geta()"
 gdb_test "p e.geta()" "From Python <A_geta>.*100" "After: e.geta()"
 gdb_test "p e_ptr->geta()" "From Python <A_geta>.*100" "After: e_ptr->geta()"
 gdb_test "p e_ref.geta()" "From Python <A_geta>.*100" "After: e_ref.geta()"
-gdb_test "p e.method(10)" "From Python <E_method_int>.*" "After: e.method(10)"
-gdb_test "p e.method('a')" "From Python <E_method_char>.*" \
+gdb_test "p e.method(10)" "From Python <E_method_int>.* = void" \
+  "After: e.method(10)"
+gdb_test "p e.method('a')" "From Python <E_method_char>.* = void" \
   "After: e.method('a')"
 gdb_test "p g.size_diff<float>  ()" "From Python G<>::size_diff.*" \
   "After: g.size_diff<float>()"
@@ -149,3 +150,11 @@ gdb_test_no_output "disable xmethod progspace E_methods;method_int" \
   "disable xmethod progspace E_methods;method_int"
 gdb_test "info xmethod progspace E_methods;method_int" ".* \\\[disabled\\\]" \
   "info xmethod xmethods E_methods;method_int"
+
+# PR 18285
+# First make sure both are enabled.
+gdb_test_no_output "enable xmethod progspace E_methods;method_char"
+gdb_test_no_output "enable xmethod progspace E_methods;method_int"
+gdb_test "pt e.method('a')" "type = void"
+gdb_test "pt e.method(10)" \
+    "NotImplementedError.*Error while fetching result type of an xmethod worker defined in Python."
index 78935e14ebe388328e6d9940ffcf571b59aef2d4..3a2f100f3b5c947468cd6a191a46e3482de99785 100644 (file)
@@ -60,6 +60,9 @@ class E_method_char_worker(XMethodWorker):
     def get_arg_types(self):
         return gdb.lookup_type('char')
 
+    def get_result_type(self, obj, arg):
+        return gdb.lookup_type('void')
+
     def __call__(self, obj, arg):
         print('From Python <E_method_char>')
         return None
@@ -72,6 +75,8 @@ class E_method_int_worker(XMethodWorker):
     def get_arg_types(self):
         return gdb.lookup_type('int')
 
+    # Note: get_result_type method elided on purpose
+
     def __call__(self, obj, arg):
         print('From Python <E_method_int>')
         return None
index f33515cd344156aab982b5189f01e9e4ab9fc5e2..1d94cf69cb513b7b30455d11bcf5c98ea4ef8374 100644 (file)
@@ -482,6 +482,21 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
          argvec[1] = argvec[0];
          argvec++;
        }
+      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
+       {
+         /* Static xmethods are not supported yet.  */
+         gdb_assert (static_memfuncp == 0);
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+           {
+             struct type *return_type
+               = result_type_of_xmethod (argvec[0], 2, 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], 2, argvec + 1);
+       }
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          struct type *return_type;
@@ -490,16 +505,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
            = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
          return value_zero (return_type, VALUE_LVAL (arg1));
        }
-
-      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
-       {
-         /* Static xmethods are not supported yet.  */
-         gdb_assert (static_memfuncp == 0);
-         return call_xmethod (argvec[0], 2, argvec + 1);
-       }
-      else
-       return call_function_by_hand (argvec[0], 2 - static_memfuncp,
-                                     argvec + 1);
+      return call_function_by_hand (argvec[0], 2 - static_memfuncp,
+                                   argvec + 1);
     }
   throw_error (NOT_FOUND_ERROR,
                _("member function %s not found"), tstr);
@@ -594,6 +601,21 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
          nargs --;
          argvec++;
        }
+      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
+       {
+         /* Static xmethods are not supported yet.  */
+         gdb_assert (static_memfuncp == 0);
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+           {
+             struct type *return_type
+               = result_type_of_xmethod (argvec[0], 1, 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);
+       }
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          struct type *return_type;
@@ -602,14 +624,7 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
            = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0])));
          return value_zero (return_type, VALUE_LVAL (arg1));
        }
-      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_XMETHOD)
-       {
-         /* Static xmethods are not supported yet.  */
-         gdb_assert (static_memfuncp == 0);
-         return call_xmethod (argvec[0], 1, argvec + 1);
-       }
-      else
-       return call_function_by_hand (argvec[0], nargs, argvec + 1);
+      return call_function_by_hand (argvec[0], nargs, argvec + 1);
     }
   throw_error (NOT_FOUND_ERROR,
                _("member function %s not found"), tstr);
index 9445f25239ef9fb6c0ae0b97a638210f271e3cb7..f4f0f05f84d013bdf263f2f4557b21f918d7c2d1 100644 (file)
@@ -2594,6 +2594,18 @@ value_of_xmethod (struct xmethod_worker *worker)
   return worker->value;
 }
 
+/* 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)
+{
+  gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD
+             && method->lval == lval_xcallable && argc > 0);
+
+  return get_xmethod_result_type (method->location.xm_worker,
+                                 argv[0], argv + 1, argc - 1);
+}
+
 /* Call the xmethod corresponding to the TYPE_CODE_XMETHOD value METHOD.  */
 
 struct value *
index 21baa32442bb197bb0851353198ff011d0533e56..25107a4b12c60613729601c621b92d2a70ef1385 100644 (file)
@@ -1080,7 +1080,10 @@ char *value_internal_function_name (struct value *);
 
 extern struct value *value_of_xmethod (struct xmethod_worker *);
 
-struct value *call_xmethod (struct value *function,
-                           int argc, struct value **argv);
+extern struct type *result_type_of_xmethod (struct value *method,
+                                           int argc, struct value **argv);
+
+extern struct value *call_xmethod (struct value *method,
+                                  int argc, struct value **argv);
 
 #endif /* !defined (VALUE_H) */