From: Tom Tromey <tromey@redhat.com>
To: gdb-patches@sourceware.org
Subject: RFA: fix PR python/11792
Date: Mon, 23 Aug 2010 20:13:00 -0000 [thread overview]
Message-ID: <m3zkwdozop.fsf@fleche.redhat.com> (raw)
This fixes PR python/11792, which is a feature request asking for a new
Value.dynamic_type method. The PR includes a patch (Andre has an
assignment via his company), but I've tweaked it here and there and also
added docs and a test case.
This needs a doc review.
Built and regtested on x86-64 (compile farm).
Tom
2010-08-23 Andre Poenitz <andre.poenitz@nokia.com>
Tom Tromey <tromey@redhat.com>
PR python/11792:
* python/py-value.c (valpy_get_dynamic_type): New function.
(value_object_getset): Add "dynamic_type".
(valpy_get_type): Fail on error.
2010-08-23 Tom Tromey <tromey@redhat.com>
PR python/11792:
* gdb.texinfo (Values From Inferior): Document dynamic_type.
2010-08-23 Tom Tromey <tromey@redhat.com>
PR python/11792:
* gdb.python/py-value.exp (test_subscript_regression): Add
dynamic_type test.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d7ff5aa..7e9c0c1 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -20737,6 +20737,16 @@ this value, thus it is not available for fetching from the inferior.
The type of this @code{gdb.Value}. The value of this attribute is a
@code{gdb.Type} object.
@end defivar
+
+@defivar Value dynamic_type
+The dynamic type of this @code{gdb.Value}. This uses C@t{++} run-time
+type information to determine the dynamic type of the value. If this
+value is of class type, it will return the class in which the value is
+embedded, if any. If this value is of pointer or reference to a class
+type, it will compute the dynamic type of the referenced object, and
+return a pointer or reference to that type, respectively. In all
+other cases, it will return the value's static type.
+@end defivar
@end table
The following methods are provided:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index aa18042..0aeea7c 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -27,6 +27,7 @@
#include "valprint.h"
#include "infcall.h"
#include "expression.h"
+#include "cp-abi.h"
#ifdef HAVE_PYTHON
@@ -62,6 +63,7 @@ typedef struct value_object {
struct value *value;
PyObject *address;
PyObject *type;
+ PyObject *dynamic_type;
} value_object;
/* List of all values which are currently exposed to Python. It is
@@ -101,6 +103,8 @@ valpy_dealloc (PyObject *obj)
Py_DECREF (self->type);
}
+ Py_XDECREF (self->dynamic_type);
+
self->ob_type->tp_free (self);
}
@@ -148,6 +152,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
value_incref (value);
value_obj->address = NULL;
value_obj->type = NULL;
+ value_obj->dynamic_type = NULL;
note_value (value_obj);
return (PyObject *) value_obj;
@@ -218,15 +223,78 @@ valpy_get_type (PyObject *self, void *closure)
{
obj->type = type_to_type_object (value_type (obj->value));
if (!obj->type)
- {
- obj->type = Py_None;
- Py_INCREF (obj->type);
- }
+ return NULL;
}
Py_INCREF (obj->type);
return obj->type;
}
+/* Return dynamic type of the value. */
+
+static PyObject *
+valpy_get_dynamic_type (PyObject *self, void *closure)
+{
+ value_object *obj = (value_object *) self;
+ volatile struct gdb_exception except;
+ struct type *type = NULL;
+
+ if (obj->dynamic_type != NULL)
+ {
+ Py_INCREF (obj->dynamic_type);
+ return obj->dynamic_type;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct value *val = obj->value;
+
+ type = value_type (val);
+ CHECK_TYPEDEF (type);
+
+ if (((TYPE_CODE (type) == TYPE_CODE_PTR)
+ || (TYPE_CODE (type) == TYPE_CODE_REF))
+ && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+ {
+ struct value *target;
+ int was_pointer = TYPE_CODE (type) == TYPE_CODE_PTR;
+
+ target = value_ind (val);
+ type = value_rtti_type (target, NULL, NULL, NULL);
+
+ if (type)
+ {
+ if (was_pointer)
+ type = lookup_pointer_type (type);
+ else
+ type = lookup_reference_type (type);
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_CLASS)
+ type = value_rtti_type (val, NULL, NULL, NULL);
+ else
+ {
+ /* Re-use object's static type. */
+ type = NULL;
+ }
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ if (type == NULL)
+ {
+ /* Ensure that the TYPE field is ready. */
+ if (!valpy_get_type (self, NULL))
+ return NULL;
+ /* We don't need to incref here, because valpy_get_type already
+ did it for us. */
+ obj->dynamic_type = obj->type;
+ }
+ else
+ obj->dynamic_type = type_to_type_object (type);
+
+ Py_INCREF (obj->dynamic_type);
+ return obj->dynamic_type;
+}
+
/* Implementation of gdb.Value.lazy_string ([encoding] [, length]) ->
string. Return a PyObject representing a lazy_string_object type.
A lazy string is a pointer to a string with an optional encoding and
@@ -994,6 +1062,7 @@ value_to_value_object (struct value *val)
value_incref (val);
val_obj->address = NULL;
val_obj->type = NULL;
+ val_obj->dynamic_type = NULL;
note_value (val_obj);
}
@@ -1169,6 +1238,8 @@ static PyGetSetDef value_object_getset[] = {
"Boolean telling whether the value is optimized out (i.e., not available).",
NULL },
{ "type", valpy_get_type, NULL, "Type of the value.", NULL },
+ { "dynamic_type", valpy_get_dynamic_type, NULL,
+ "Dynamic type of the value.", NULL },
{NULL} /* Sentinel */
};
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index 13bce9a..0ecb57c 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -379,6 +379,13 @@ proc test_subscript_regression {lang} {
# the C++ tests.
gdb_test "python print bool(gdb.parse_and_eval('base').dynamic_cast(gdb.lookup_type('Derived').pointer()))" \
True
+
+ # Likewise.
+ gdb_test "python print gdb.parse_and_eval('base').dynamic_type" \
+ "Derived \[*\]"
+ # A static type case.
+ gdb_test "python print gdb.parse_and_eval('5').dynamic_type" \
+ "int"
}
gdb_breakpoint [gdb_get_line_number "break to inspect struct and union"]
next reply other threads:[~2010-08-23 20:13 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-23 20:13 Tom Tromey [this message]
2010-08-30 18:01 ` Tom Tromey
2010-08-30 18:24 ` Eli Zaretskii
2010-08-30 20:24 ` Tom Tromey
2010-08-30 20:43 ` Eli Zaretskii
2010-09-01 23:01 ` Tom Tromey
2010-09-02 10:32 ` Eli Zaretskii
2010-09-02 15:48 ` Tom Tromey
2010-09-02 18:40 ` Eli Zaretskii
2010-09-07 21:01 ` Tom Tromey
2010-09-22 16:33 ` Eli Zaretskii
2010-09-22 18:47 ` Tom Tromey
2010-09-22 19:15 ` Eli Zaretskii
2010-09-22 19:17 ` Joel Brobecker
2010-09-22 19:19 ` Eli Zaretskii
2010-09-22 19:26 ` Tom Tromey
2010-09-22 19:59 ` Eli Zaretskii
2010-09-22 20:57 ` Tom Tromey
2010-09-23 12:42 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3zkwdozop.fsf@fleche.redhat.com \
--to=tromey@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox