diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/NEWS | 5 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/python.texi | 14 | ||||
-rw-r--r-- | gdb/python/py-type.c | 35 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/variant.exp | 10 | ||||
-rw-r--r-- | gdb/testsuite/gdb.rust/simple.exp | 10 |
8 files changed, 91 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7cccdd0..8911ff5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,15 @@ 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. + +2020-04-24 Tom Tromey <tromey@adacore.com> + * ada-typeprint.c (print_choices, print_variant_part) (print_record_field_types_dynamic): New functions. (print_record_field_types): Use print_record_field_types_dynamic. @@ -68,6 +68,11 @@ GNU/Linux/RISC-V (gdbserver) riscv*-*-linux* ** gdb.register_window_type can be used to implement new TUI windows in Python. + ** Dynamic types can now be queried. gdb.Type has a new attribute, + "dynamic", and gdb.Type.sizeof can be None for a dynamic type. A + field of a dynamic type may have None for its "bitpos" attribute + as well. + *** Changes in GDB 9 * 'thread-exited' event is now available in the annotations interface. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 0dc6476..7073c17 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2020-04-24 Tom Tromey <tromey@adacore.com> + + PR python/23662: + * python.texi (Types In Python): Document new features. + 2020-04-15 Artur Shepilko <nomadbyte@gmail.com> * gdb.texinfo: Transform @var{[host]} to [@var{host}]; this diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 31e8995..cfa8131 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -1068,6 +1068,12 @@ The type code for this type. The type code will be one of the @code{TYPE_CODE_} constants defined below. @end defvar +@defvar Type.dynamic +A boolean indicating whether this type is dynamic. In some +situations, such as Rust @code{enum} types or Ada variant records, the +concrete type of a value may vary depending on its contents. +@end defvar + @defvar Type.name The name of this type. If this type has no name, then @code{None} is returned. @@ -1076,7 +1082,9 @@ is returned. @defvar Type.sizeof The size of this type, in target @code{char} units. Usually, a target's @code{char} type will be an 8-bit byte. However, on some -unusual platforms, this type may have a different size. +unusual platforms, this type may have a different size. A dynamic +type may not have a fixed size; in this case, this attribute's value +will be @code{None}. @end defvar @defvar Type.tag @@ -1106,7 +1114,9 @@ Each field is a @code{gdb.Field} object, with some pre-defined attributes: @item bitpos This attribute is not available for @code{enum} or @code{static} (as in C@t{++}) fields. The value is the position, counting -in bits, from the start of the containing type. +in bits, from the start of the containing type. Note that, in a +dynamic type, the position of a field may not be constant. In this +case, the value will be @code{None}. @item enumval This attribute is only available for @code{enum} fields, and its value 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, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index daeed54..862d8b0 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,11 @@ 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. + +2020-04-24 Tom Tromey <tromey@adacore.com> + * gdb.ada/mi_var_array.exp: Try all -fgnat-encodings settings. Make array type matching more lax. * gdb.ada/mi_var_union.exp: Try all -fgnat-encodings settings. diff --git a/gdb/testsuite/gdb.ada/variant.exp b/gdb/testsuite/gdb.ada/variant.exp index 490956a..da51f7b 100644 --- a/gdb/testsuite/gdb.ada/variant.exp +++ b/gdb/testsuite/gdb.ada/variant.exp @@ -14,6 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. load_lib "ada.exp" +load_lib "gdb-python.exp" standard_ada_testfile pkg @@ -43,4 +44,13 @@ foreach_with_prefix scenario {none all minimal} { " = \\(one => 3, two => 0, str => \"zzz\", onevalue => 33, str2 => \"\"\\)" gdb_test "print nav3" \ " = \\(one => 3, two => 7, str => \"zzz\", onevalue => 33, str2 => \"qqqqqqq\", twovalue => 88\\)" + + # This is only supported for the DWARF encoding. + if {$scenario == "minimal" && ![skip_python_tests]} { + gdb_test_no_output \ + "python t = gdb.lookup_type('nested_and_variable')" \ + "fetch type for python" + gdb_test "python print(t.dynamic)" "True" + gdb_test "python print(t\['onevalue'\].bitpos)" "None" + } } diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp index 92b3666..6daaf84 100644 --- a/gdb/testsuite/gdb.rust/simple.exp +++ b/gdb/testsuite/gdb.rust/simple.exp @@ -364,3 +364,13 @@ if {[skip_python_tests]} { } gdb_test "python print(gdb.lookup_type('simple::HiBob'))" "simple::HiBob" + +gdb_test_no_output "python e = gdb.parse_and_eval('e')" \ + "get value of e for python" +gdb_test "python print(len(e.type.fields()))" "2" +gdb_test "python print(e.type.fields()\[0\].artificial)" "True" +gdb_test "python print(e.type.fields()\[1\].name)" "Two" + +gdb_test "python print(e.type.dynamic)" "False" +gdb_test "python print(gdb.lookup_type('simple::MoreComplicated').dynamic)" \ + "True" |