From f9ffd4bb11c401df4c0c5733e946c48d6b295c5e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 23 Aug 2010 20:29:19 +0000 Subject: [PATCH] gdb 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 | 10 +++++++ gdb/doc/ChangeLog | 6 +++++ gdb/doc/gdb.texinfo | 10 +++++++ gdb/python/py-value.c | 51 ++++++++++++++++++++++++++++++++--- gdb/testsuite/ChangeLog | 8 ++++++ gdb/testsuite/gdb.python/py-value.c | 10 +++++++ gdb/testsuite/gdb.python/py-value.exp | 5 ++++ 7 files changed, 97 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3e614f9..2f0de7c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,15 @@ 2010-08-23 Tom Tromey + 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 + PR python/11391: * python/py-value.c (valpy_nonzero): Don't throw error for other Value types. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 82e73e5..a864e2f 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,11 @@ 2010-08-23 Tom Tromey + PR python/11145: + * gdb.texinfo (Values From Inferior): Document dynamic_cast and + reinterpret_cast methods. + +2010-08-23 Tom Tromey + PR python/11915: * gdb.texinfo (Types In Python): Document array method. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d1eba6f..d0c7ddd 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 75ee0de..aa18042 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -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\ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index d9cf953..3749928 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,13 @@ 2010-08-23 Tom Tromey + 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 + PR python/10676: * gdb.python/py-type.exp (test_fields): Add tests for type equality. diff --git a/gdb/testsuite/gdb.python/py-value.c b/gdb/testsuite/gdb.python/py-value.c index 7481bd5..5ac7d76 100644 --- a/gdb/testsuite/gdb.python/py-value.c +++ b/gdb/testsuite/gdb.python/py-value.c @@ -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. */ diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp index eaed9c7..13bce9a 100644 --- a/gdb/testsuite/gdb.python/py-value.exp +++ b/gdb/testsuite/gdb.python/py-value.exp @@ -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"] -- 2.7.4