]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Allow calling of C++ methods from python
authorHannes Domani <ssbssa@yahoo.de>
Thu, 8 Feb 2024 19:09:25 +0000 (20:09 +0100)
committerHannes Domani <ssbssa@yahoo.de>
Thu, 8 Feb 2024 19:09:56 +0000 (20:09 +0100)
Currently it's not possible to call C++ methods from python.
Using this example:
```
class B
{
  static int static_func ();
  int arg0_func ();
  int arg1_func (int arg1);
  int arg2_func (int arg1, int arg2);
};

B *b_obj = new B;
```

Trying to call B::static_func gives this error:
```
(gdb) py b_obj = gdb.parse_and_eval('b_obj')
(gdb) py print(b_obj['static_func']())
Traceback (most recent call last):
  File "<string>", line 1, in <module>
RuntimeError: Value is not callable (not TYPE_CODE_FUNC).
Error while executing Python code.
```

TYPE_CODE_METHOD was simply missing as a possible type in
valpy_call, now the same is possible:
```
(gdb) py b_obj = gdb.parse_and_eval('b_obj')
(gdb) py print(b_obj['static_func']())
1111
```

Note that it's necessary to explicitely add the this pointer
as the first argument in a call of non-static methods:
```
(gdb) py print(b_obj['arg0_func']())
Traceback (most recent call last):
  File "<string>", line 1, in <module>
gdb.error: Too few arguments in function call.
Error while executing Python code.
(gdb) py print(b_obj['arg0_func'](b_obj))
198
```

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13326
Approved-By: Tom Tromey <tom@tromey.com>
gdb/python/py-value.c
gdb/testsuite/gdb.python/py-value-cc.cc
gdb/testsuite/gdb.python/py-value-cc.exp

index 151b8801b88e907db70a1c7ce30b74abff15f552..89ca0982e59f23452fbd1140b68e03f51f69cd9b 100644 (file)
@@ -1214,10 +1214,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  if (ftype->code () != TYPE_CODE_FUNC)
+  if (ftype->code () != TYPE_CODE_FUNC && ftype->code () != TYPE_CODE_METHOD)
     {
       PyErr_SetString (PyExc_RuntimeError,
-                      _("Value is not callable (not TYPE_CODE_FUNC)."));
+                      _("Value is not callable (not TYPE_CODE_FUNC"
+                        " or TYPE_CODE_METHOD)."));
       return NULL;
     }
 
index c0e68c1174a8a16361d064ed645e4fe71cf2abe8..2d38a26d948da2adfcaf9df343a5ac28bb27ff9b 100644 (file)
@@ -37,8 +37,33 @@ union U {
 class B : public A {
  public:
   char a;
+
+  static int static_func ();
+  int arg0_func ();
+  int arg1_func (int arg1);
+  int arg2_func (int arg1, int arg2);
 };
 
+int B::static_func ()
+{
+  return 1111;
+}
+
+int B::arg0_func ()
+{
+  return A::a + a;
+}
+
+int B::arg1_func (int arg1)
+{
+  return a * arg1;
+}
+
+int B::arg2_func (int arg1, int arg2)
+{
+  return a * arg1 + arg2;
+}
+
 struct X
 {
   union { int x; char y; };
index f58acd21ccf3860b19f31d1b5573ef965d341294..17a67e20c1cfde36d64a6976a0feff212ac0e5e9 100644 (file)
@@ -99,3 +99,15 @@ gdb_test "python print(uu\[uu_fields\[1\]\]\['a'\])" "1000" "uu.a via field"
 # Test overloaded operators.
 gdb_test_no_output "python a = gdb.parse_and_eval('a')" "init a"
 gdb_test "python print(a + 5)" "10" "a + 5"
+
+# Test inferior function calls of methods.
+gdb_test "py print(b_obj\['static_func'\]())" "1111"
+gdb_test "py print(b_obj\['arg0_func'\]())" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg0_func'\](b_obj))" "198"
+gdb_test "py print(b_obj\['arg1_func'\]())" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg1_func'\](b_obj))" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg1_func'\](b_obj, 3))" "294"
+gdb_test "py print(b_obj\['arg2_func'\]())" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg2_func'\](b_obj))" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg2_func'\](b_obj, 4))" ".*Too few arguments in function call.*"
+gdb_test "py print(b_obj\['arg2_func'\](b_obj, 5, 6))" "496"