gdb
authorTom Tromey <tromey@redhat.com>
Mon, 23 Aug 2010 20:29:19 +0000 (20:29 +0000)
committerTom Tromey <tromey@redhat.com>
Mon, 23 Aug 2010 20:29:19 +0000 (20:29 +0000)
PR python/11145:
* python/py-value.c: Include expression.h.
(valpy_do_cast): New function.
(valpy_cast): Use it.
(valpy_dynamic_cast): New function.
(valpy_reinterpret_cast): Likewise.
(value_object_methods): Add dynamic_cast, reinterpret_cast.
gdb/doc
PR python/11145:
* gdb.texinfo (Values From Inferior): Document dynamic_cast and
reinterpret_cast methods.
gdb/testsuite
PR python/11145:
* gdb.python/py-value.c (Base, Derived): New types.
(base): New global.
* gdb.python/py-value.exp (test_subscript_regression): Add
dynamic_cast test.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/py-value.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-value.c
gdb/testsuite/gdb.python/py-value.exp

index 3e614f9c8e2cb50334b97948c96f77f0bdf929c0..2f0de7c9330f12427acb78044c99dba0c1ad1dd5 100644 (file)
@@ -1,3 +1,13 @@
+2010-08-23  Tom Tromey  <tromey@redhat.com>
+
+       PR python/11145:
+       * python/py-value.c: Include expression.h.
+       (valpy_do_cast): New function.
+       (valpy_cast): Use it.
+       (valpy_dynamic_cast): New function.
+       (valpy_reinterpret_cast): Likewise.
+       (value_object_methods): Add dynamic_cast, reinterpret_cast.
+
 2010-08-23  Tom Tromey  <tromey@redhat.com>
 
        PR python/11391:
index 82e73e58c287ab457b30f8825f6d1d927132d0ec..a864e2f5c7bc998537b27c068d853095e4adcbea 100644 (file)
@@ -1,3 +1,9 @@
+2010-08-23  Tom Tromey  <tromey@redhat.com>
+
+       PR python/11145:
+       * gdb.texinfo (Values From Inferior): Document dynamic_cast and
+       reinterpret_cast methods.
+
 2010-08-23  Tom Tromey  <tromey@redhat.com>
 
        PR python/11915:
index d1eba6f268f5300d6ee27322c7a51680aad36c0c..d0c7dddac4bb6f850aa4d19e86baf5aa32a68bb1 100644 (file)
@@ -20792,6 +20792,16 @@ The result @code{bar} will be a @code{gdb.Value} object holding the
 value pointed to by @code{foo}.
 @end defmethod
 
+@defmethod Value dynamic_cast type
+Like @code{Value.cast}, but works as if the C@t{++} @code{dynamic_cast}
+operator were used.  Consult a C@t{++} reference for details.
+@end defmethod
+
+@defmethod Value reinterpret_cast type
+Like @code{Value.cast}, but works as if the C@t{++} @code{reinterpret_cast}
+operator were used.  Consult a C@t{++} reference for details.
+@end defmethod
+
 @defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]} @r{[}length@r{]}
 If this @code{gdb.Value} represents a string, then this method
 converts the contents to a Python string.  Otherwise, this method will
index 75ee0de4db3f0c1869cea73c65465c2745493991..aa180428574a3ae7d4412255442581cea7ef0d03 100644 (file)
@@ -26,6 +26,7 @@
 #include "dfp.h"
 #include "valprint.h"
 #include "infcall.h"
+#include "expression.h"
 
 #ifdef HAVE_PYTHON
 
@@ -295,9 +296,10 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
   return unicode;
 }
 
-/* Cast a value to a given type.  */
+/* A helper function that implements the various cast operators.  */
+
 static PyObject *
-valpy_cast (PyObject *self, PyObject *args)
+valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
 {
   PyObject *type_obj;
   struct type *type;
@@ -317,13 +319,47 @@ valpy_cast (PyObject *self, PyObject *args)
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      res_val = value_cast (type, ((value_object *) self)->value);
+      struct value *val = ((value_object *) self)->value;
+
+      if (op == UNOP_DYNAMIC_CAST)
+       res_val = value_dynamic_cast (type, val);
+      else if (op == UNOP_REINTERPRET_CAST)
+       res_val = value_reinterpret_cast (type, val);
+      else
+       {
+         gdb_assert (op == UNOP_CAST);
+         res_val = value_cast (type, val);
+       }
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
   return value_to_value_object (res_val);
 }
 
+/* Implementation of the "cast" method.  */
+
+static PyObject *
+valpy_cast (PyObject *self, PyObject *args)
+{
+  return valpy_do_cast (self, args, UNOP_CAST);
+}
+
+/* Implementation of the "dynamic_cast" method.  */
+
+static PyObject *
+valpy_dynamic_cast (PyObject *self, PyObject *args)
+{
+  return valpy_do_cast (self, args, UNOP_DYNAMIC_CAST);
+}
+
+/* Implementation of the "reinterpret_cast" method.  */
+
+static PyObject *
+valpy_reinterpret_cast (PyObject *self, PyObject *args)
+{
+  return valpy_do_cast (self, args, UNOP_REINTERPRET_CAST);
+}
+
 static Py_ssize_t
 valpy_length (PyObject *self)
 {
@@ -1138,6 +1174,15 @@ static PyGetSetDef value_object_getset[] = {
 
 static PyMethodDef value_object_methods[] = {
   { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
+  { "dynamic_cast", valpy_dynamic_cast, METH_VARARGS,
+    "dynamic_cast (gdb.Type) -> gdb.Value\n\
+Cast the value to the supplied type, as if by the C++ dynamic_cast operator."
+  },
+  { "reinterpret_cast", valpy_reinterpret_cast, METH_VARARGS,
+    "reinterpret_cast (gdb.Type) -> gdb.Value\n\
+Cast the value to the supplied type, as if by the C++\n\
+reinterpret_cast operator."
+  },
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string, METH_VARARGS | METH_KEYWORDS,
     "lazy_string ([encoding]  [, length]) -> lazy_string\n\
index d9cf95369e70a11b20aca190425f12062b0cf6df..3749928e89c9cc8fd6bf4d0560d1ff8ca079ff01 100644 (file)
@@ -1,3 +1,11 @@
+2010-08-23  Tom Tromey  <tromey@redhat.com>
+
+       PR python/11145:
+       * gdb.python/py-value.c (Base, Derived): New types.
+       (base): New global.
+       * gdb.python/py-value.exp (test_subscript_regression): Add
+       dynamic_cast test.
+
 2010-08-23  Tom Tromey  <tromey@redhat.com>
 
        PR python/10676:
index 7481bd528104138bb6d4018936c5bafae940042d..5ac7d761e409df16c95ce7071447c8521dd7114f 100644 (file)
@@ -40,6 +40,16 @@ typedef struct s *PTR;
 enum e evalue = TWO;
 
 #ifdef __cplusplus
+
+struct Base {
+  virtual int x() { return 5; }
+};
+
+struct Derived : public Base {
+};
+
+Base *base = new Derived ();
+
 void ptr_ref(int*& rptr_int)
 {
   return; /* break to inspect pointer by reference. */
index eaed9c7a6b41754554c8e345fb97f7f85c1e0621..13bce9a05efb1819723f0681c70aff97d6f6f2d7 100644 (file)
@@ -374,6 +374,11 @@ proc test_subscript_regression {lang} {
      gdb_py_test_silent_cmd "python rptr = gdb.history(0)" \
         "Obtains value from GDB" 1
      gdb_test "python print rptr\[0\]" "2" "Check pointer passed as reference"
+
+     # Just the most basic test of dynamic_cast -- it is checked in
+     # the C++ tests.
+     gdb_test "python print bool(gdb.parse_and_eval('base').dynamic_cast(gdb.lookup_type('Derived').pointer()))" \
+        True
  }
 
  gdb_breakpoint [gdb_get_line_number "break to inspect struct and union"]