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.
gdb/doc
	PR python/11792:
	* gdb.texinfo (Values From Inferior): Document dynamic_type.
gdb/testsuite
	PR python/11792:
	* gdb.python/py-value.exp (test_subscript_regression): Add
	dynamic_type test.
This commit is contained in:
Tom Tromey 2010-08-30 20:28:31 +00:00
parent 640617ad17
commit 03f17ccfe1
6 changed files with 111 additions and 4 deletions

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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 */
};

View File

@ -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

View File

@ -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"]