Add Python support for dynamic types

This changes the gdb Python API to add support for dynamic types.  In
particular, this adds an attribute to gdb.Type, and updates some
attributes to reflect dynamic sizes and field offsets.

There's still no way to get the dynamic type from one of its concrete
instances.  This could perhaps be added if needed.

gdb/ChangeLog
2020-04-24  Tom Tromey  <tromey@adacore.com>

	PR python/23662:
	* python/py-type.c (convert_field): Handle
	FIELD_LOC_KIND_DWARF_BLOCK.
	(typy_get_sizeof): Handle TYPE_HAS_DYNAMIC_LENGTH.
	(typy_get_dynamic): Nw function.
	(type_object_getset): Add "dynamic".
	* NEWS: Add entry.

gdb/doc/ChangeLog
2020-04-24  Tom Tromey  <tromey@adacore.com>

	PR python/23662:
	* python.texi (Types In Python): Document new features.

gdb/testsuite/ChangeLog
2020-04-24  Tom Tromey  <tromey@adacore.com>

	PR python/23662:
	* gdb.ada/variant.exp: Add Python checks.
	* gdb.rust/simple.exp: Add dynamic type checks.
This commit is contained in:
Tom Tromey 2020-04-24 13:40:31 -06:00
parent adfb981595
commit 1acda8039b
8 changed files with 91 additions and 4 deletions

View file

@ -189,8 +189,11 @@ convert_field (struct type *type, int field)
}
else
{
arg.reset (gdb_py_long_from_longest (TYPE_FIELD_BITPOS (type,
field)));
if (TYPE_FIELD_LOC_KIND (type, field) == FIELD_LOC_KIND_DWARF_BLOCK)
arg = gdbpy_ref<>::new_reference (Py_None);
else
arg.reset (gdb_py_long_from_longest (TYPE_FIELD_BITPOS (type,
field)));
attrstring = "bitpos";
}
@ -710,9 +713,12 @@ typy_get_sizeof (PyObject *self, void *closure)
{
struct type *type = ((type_object *) self)->type;
bool size_varies = false;
try
{
check_typedef (type);
size_varies = TYPE_HAS_DYNAMIC_LENGTH (type);
}
catch (const gdb_exception &except)
{
@ -720,6 +726,8 @@ typy_get_sizeof (PyObject *self, void *closure)
/* Ignore exceptions. */
if (size_varies)
Py_RETURN_NONE;
return gdb_py_long_from_longest (TYPE_LENGTH (type));
}
@ -744,6 +752,27 @@ typy_get_alignof (PyObject *self, void *closure)
return gdb_py_object_from_ulongest (align).release ();
}
/* Return whether or not the type is dynamic. */
static PyObject *
typy_get_dynamic (PyObject *self, void *closure)
{
struct type *type = ((type_object *) self)->type;
bool result = false;
try
{
result = is_dynamic_type (type);
}
catch (const gdb_exception &except)
{
/* Ignore exceptions. */
}
if (result)
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
static struct type *
typy_lookup_typename (const char *type_name, const struct block *block)
{
@ -1436,6 +1465,8 @@ static gdb_PyGetSetDef type_object_getset[] =
"The alignment of this type, in bytes.", NULL },
{ "code", typy_get_code, NULL,
"The code for this type.", NULL },
{ "dynamic", typy_get_dynamic, NULL,
"Whether this type is dynamic.", NULL },
{ "name", typy_get_name, NULL,
"The name for this type, or None.", NULL },
{ "sizeof", typy_get_sizeof, NULL,