aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/NEWS5
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/python.texi14
-rw-r--r--gdb/python/py-type.c35
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.ada/variant.exp10
-rw-r--r--gdb/testsuite/gdb.rust/simple.exp10
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.
diff --git a/gdb/NEWS b/gdb/NEWS
index 6657f6f..01e73c9 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -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"