aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo10
-rw-r--r--gdb/python/py-value.c79
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.python/py-value.exp7
6 files changed, 111 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 7312034..102bdb1 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2010-08-30 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-30 Yao Qi <yao@codesourcery.com>
* arm-linux-tdep.c (arm_linux_sigreturn_return_addr): New.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 634cc9d..ac8f6e9 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2010-08-30 Tom Tromey <tromey@redhat.com>
+
+ PR python/11792:
+ * gdb.texinfo (Values From Inferior): Document dynamic_type.
+
2010-08-24 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (ARM Features): Document
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3418eb2..393c8b7 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -20759,6 +20759,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/ChangeLog b/gdb/testsuite/ChangeLog
index 00c599a..433cfa2 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-08-30 Tom Tromey <tromey@redhat.com>
+
+ PR python/11792:
+ * gdb.python/py-value.exp (test_subscript_regression): Add
+ dynamic_type test.
+
2010-08-30 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.cp/cpexprs.exp (test_breakpoint): Continue to test_function
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"]