From: Andrew Burgess Date: Tue, 30 Nov 2021 14:35:44 +0000 (+0000) Subject: gdb/python: add Type.is_signed property X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=551b380fbdad4082bc8520b1b61de883e8e4bf49;p=binutils-gdb.git gdb/python: add Type.is_signed property Add a new read-only property, Type.is_signed, which is True for signed types, and False otherwise. This property should only be read on types for which Type.is_scalar is true, attempting to read this property for non-scalar types will raise a ValueError. I chose 'is_signed' rather than 'is_unsigned' in order to match the existing Architecture.integer_type method, which takes a 'signed' parameter. As far as I could find, that was the only existing signed/unsigned selector in the Python API, so it seemed reasonable to stay consistent. --- diff --git a/gdb/NEWS b/gdb/NEWS index 168b6f465a5..cf1e084fed6 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -235,6 +235,11 @@ GNU/Linux/LoongArch loongarch*-*-linux* ** New read-only attribute gdb.Type.is_scalar, which is True for scalar types, and False for all other types. + ** New read-only attribute gdb.Type.is_signed. This attribute + should only be read when Type.is_scalar is True, and will be True + for signed types, and False for all other types. Attempting to + read this attribute for non-scalar types will raise a ValueError. + * New features in the GDB remote stub, GDBserver ** GDBserver is now supported on OpenRISC GNU/Linux. diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 2a7a4e8e3aa..b6acda49b39 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -1269,6 +1269,16 @@ this property is @code{False}. Examples of non-scalar types include structures, unions, and classes. @end defvar +@defvar Type.is_signed +For scalar types (those for which @code{Type.is_scalar} is +@code{True}), this property is @code{True} if the type is signed, +otherwise this property is @code{False}. + +Attempting to read this property for a non-scalar type (a type for +which @code{Type.is_scalar} is @code{False}), will raise a +@code{ValueError}. +@end defvar + The following methods are provided: @defun Type.fields () diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 54761236d52..7be3f3276c2 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -446,6 +446,27 @@ typy_is_scalar (PyObject *self, void *closure) Py_RETURN_FALSE; } +/* Return true if this type is signed. Raises a ValueError if this type + is not a scalar type. */ + +static PyObject * +typy_is_signed (PyObject *self, void *closure) +{ + struct type *type = ((type_object *) self)->type; + + if (!is_scalar_type (type)) + { + PyErr_SetString (PyExc_ValueError, + _("Type must be a scalar type")); + return nullptr; + } + + if (type->is_unsigned ()) + Py_RETURN_FALSE; + else + Py_RETURN_TRUE; +} + /* Return the type, stripped of typedefs. */ static PyObject * typy_strip_typedefs (PyObject *self, PyObject *args) @@ -1502,6 +1523,8 @@ static gdb_PyGetSetDef type_object_getset[] = "The objfile this type was defined in, or None.", NULL }, { "is_scalar", typy_is_scalar, nullptr, "Is this a scalar type?", nullptr }, + { "is_signed", typy_is_signed, nullptr, + "Is this an signed type?", nullptr }, { NULL } }; diff --git a/gdb/testsuite/gdb.python/py-arch.exp b/gdb/testsuite/gdb.python/py-arch.exp index b55778b0b72..58f6cb06b3e 100644 --- a/gdb/testsuite/gdb.python/py-arch.exp +++ b/gdb/testsuite/gdb.python/py-arch.exp @@ -64,12 +64,25 @@ if { ![is_address_zero_readable] } { } foreach size {0 1 2 3 4 8 16} { - foreach sign {"" ", True" ", False" ", None" ", \"blah\""} { + foreach sign_data {{"" True} \ + {", True" True} \ + {", False" False} \ + {", None" False} \ + {", \"blah\"" True}} { + set sign [lindex $sign_data 0] + # GDB's 0 bit type is always signed. + if { $size == 0 } { + set sign_result True + } else { + set sign_result [lindex $sign_data 1] + } set fullsize [expr 8 * $size] gdb_test_no_output "python t = arch.integer_type($fullsize$sign)" \ "get integer type for $size$sign" gdb_test "python print(t.sizeof)" "$size" \ "print size of integer type for $size$sign" + gdb_test "python print(t.is_signed == ${sign_result})" "True" \ + "check signedness of type for $size$sign" } } diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index 2bb2bf67218..86cf8f3ff69 100644 --- a/gdb/testsuite/gdb.python/py-type.exp +++ b/gdb/testsuite/gdb.python/py-type.exp @@ -270,6 +270,32 @@ proc test_template {} { gdb_test "python print (ttype.template_argument(2))" "&C::c" } +# Check the is_signed property of some types. +proc test_is_signed {lang} { + if {$lang == "c++"} { + gdb_test "python print(gdb.parse_and_eval ('c').type.is_signed)" \ + "ValueError: Type must be a scalar type.*" + gdb_test "python print(gdb.parse_and_eval ('&c').type.is_signed == False)" "True" + } + + gdb_test "python print(gdb.parse_and_eval('global_unsigned_char').type.is_signed == False)" "True" + gdb_test "python print(gdb.parse_and_eval('global_char').type.is_signed)" "True|False" + gdb_test "python print(gdb.parse_and_eval('global_signed_char').type.is_signed == True)" "True" + + gdb_test "python print(gdb.parse_and_eval ('ss.x').type.is_signed == True)" "True" + gdb_test "python print(gdb.parse_and_eval ('ss').type.is_signed)" \ + "ValueError: Type must be a scalar type.*" + gdb_test "python print(gdb.parse_and_eval ('uu').type.is_signed)" \ + "ValueError: Type must be a scalar type.*" + gdb_test "python print(gdb.parse_and_eval ('uu.i').type.is_signed == True)" "True" + gdb_test "python print(gdb.parse_and_eval ('uu.f').type.is_signed == True)" "True" + gdb_test "python print(gdb.parse_and_eval ('uu.a').type.is_signed)" \ + "ValueError: Type must be a scalar type.*" + + gdb_test "python print(gdb.parse_and_eval ('&ss.x').type.is_signed == False)" "True" + gdb_test "python print(gdb.parse_and_eval ('&uu').type.is_signed == False)" "True" +} + # Test the gdb.Type.is_scalar property. proc test_is_scalar { lang } { if {$lang == "c++"} { @@ -320,6 +346,7 @@ if { [build_inferior "${binfile}" "c"] == 0 } { test_fields "c" test_enums test_is_scalar "c" + test_is_signed "c" } } @@ -334,5 +361,6 @@ if { [build_inferior "${binfile}-cxx" "c++"] == 0 } { test_template test_enums test_is_scalar "c++" + test_is_signed "c++" } }