From 1acda8039ba681e88416a7da6a6e3abdcae6b86b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 24 Apr 2020 13:40:31 -0600 Subject: 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 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 PR python/23662: * python.texi (Types In Python): Document new features. gdb/testsuite/ChangeLog 2020-04-24 Tom Tromey PR python/23662: * gdb.ada/variant.exp: Add Python checks. * gdb.rust/simple.exp: Add dynamic type checks. --- gdb/python/py-type.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 6172049..db031e0 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -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, -- cgit v1.1