gdb/python: add Type.is_scalar property
authorAndrew Burgess <aburgess@redhat.com>
Fri, 25 Feb 2022 10:54:04 +0000 (10:54 +0000)
committerAndrew Burgess <aburgess@redhat.com>
Mon, 7 Mar 2022 19:42:07 +0000 (19:42 +0000)
Add a new read-only property which is True for scalar types,
otherwise, it's False.

gdb/NEWS
gdb/doc/python.texi
gdb/python/py-type.c
gdb/testsuite/gdb.python/py-type.c
gdb/testsuite/gdb.python/py-type.exp

index e0c55e8274ff1943231a537282f068aca6cc9c75..168b6f465a5def9b91cbc8e29809bb78012830af 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -232,6 +232,9 @@ GNU/Linux/LoongArch    loongarch*-*-linux*
      state information, or None, if there is no such additional
      information.
 
+  ** New read-only attribute gdb.Type.is_scalar, which is True for
+     scalar types, and False for all other types.
+
 * New features in the GDB remote stub, GDBserver
 
   ** GDBserver is now supported on OpenRISC GNU/Linux.
index 4d9e77bf12cf9ff26ce7c9f560b132979d9ac028..2a7a4e8e3aaa61d9c3277d2a74440747b5ceb092 100644 (file)
@@ -1263,6 +1263,12 @@ The @code{gdb.Objfile} that this type was defined in, or @code{None} if
 there is no associated objfile.
 @end defvar
 
+@defvar Type.is_scalar
+This property is @code{True} if the type is a scalar type, otherwise,
+this property is @code{False}.  Examples of non-scalar types include
+structures, unions, and classes.
+@end defvar
+
 The following methods are provided:
 
 @defun Type.fields ()
index 13dae1e255940ab7116b9c41a2a816e57fd5913c..54761236d52998ba23520842b2969c7a04cf21b6 100644 (file)
@@ -433,6 +433,19 @@ typy_get_objfile (PyObject *self, void *closure)
   return objfile_to_objfile_object (objfile).release ();
 }
 
+/* Return true if this is a scalar type, otherwise, returns false.  */
+
+static PyObject *
+typy_is_scalar (PyObject *self, void *closure)
+{
+  struct type *type = ((type_object *) self)->type;
+
+  if (is_scalar_type (type))
+    Py_RETURN_TRUE;
+  else
+    Py_RETURN_FALSE;
+}
+
 /* Return the type, stripped of typedefs. */
 static PyObject *
 typy_strip_typedefs (PyObject *self, PyObject *args)
@@ -1487,6 +1500,8 @@ static gdb_PyGetSetDef type_object_getset[] =
     "The tag name for this type, or None.", NULL },
   { "objfile", typy_get_objfile, NULL,
     "The objfile this type was defined in, or None.", NULL },
+  { "is_scalar", typy_is_scalar, nullptr,
+    "Is this a scalar type?", nullptr },
   { NULL }
 };
 
index 10cbd3b087580cad381246dc76e5a518fb0cf10d..92297d5ad4ba75e19d4c9fac59f3c316b621c7f4 100644 (file)
@@ -32,6 +32,13 @@ TS ts;
 
 int aligncheck;
 
+union UU
+{
+  int i;
+  float f;
+  int a[5];
+};
+
 #ifdef __cplusplus
 struct C
 {
@@ -72,6 +79,14 @@ Temargs<D, 23, &C::c> temvar;
 
 #endif
 
+unsigned char global_unsigned_char;
+char global_char;
+signed char global_signed_char;
+
+unsigned int global_unsigned_int;
+int global_int;
+signed int global_signed_int;
+
 enum E
 { v1, v2, v3
 };
@@ -91,6 +106,7 @@ main ()
   int ar[2] = {1,2};
   struct s st;
   struct SS ss;
+  union UU uu;
 #ifdef __cplusplus
   C c;
   c.c = 1;
index 4990eeb7ddb4e7d8779902724a60282f50a419b8..2bb2bf6721886e1fbe697fb510357cb8f2a901fb 100644 (file)
@@ -270,6 +270,29 @@ proc test_template {} {
     gdb_test "python print (ttype.template_argument(2))" "&C::c"
 }
 
+# Test the gdb.Type.is_scalar property.
+proc test_is_scalar { lang } {
+    if {$lang == "c++"} {
+       gdb_test "python print(gdb.parse_and_eval ('c').type.is_scalar)" "False"
+       gdb_test "python print(gdb.parse_and_eval ('&c').type.is_scalar)" "True"
+    }
+
+    foreach type { char int } {
+       gdb_test "python print(gdb.parse_and_eval('global_unsigned_${type}').type.is_scalar)" "True"
+       gdb_test "python print(gdb.parse_and_eval('global_${type}').type.is_scalar)" "True"
+       gdb_test "python print(gdb.parse_and_eval('global_signed_${type}').type.is_scalar)" "True"
+    }
+
+    gdb_test "python print(gdb.parse_and_eval ('ss.x').type.is_scalar)" "True"
+    gdb_test "python print(gdb.parse_and_eval ('ss').type.is_scalar)" "False"
+    gdb_test "python print(gdb.parse_and_eval ('uu').type.is_scalar)" "False"
+
+    gdb_test "python print(gdb.parse_and_eval ('uu.i').type.is_scalar)" "True"
+    gdb_test "python print(gdb.parse_and_eval ('uu.f').type.is_scalar)" "True"
+    gdb_test "python print(gdb.parse_and_eval ('uu.a').type.is_scalar)"  "False"
+    gdb_test "python print(gdb.parse_and_eval ('&ss.x').type.is_scalar)" "True"
+}
+
 # Perform C Tests.
 if { [build_inferior "${binfile}" "c"] == 0 } {
   restart_gdb "${binfile}"
@@ -296,10 +319,10 @@ if { [build_inferior "${binfile}" "c"] == 0 } {
       runto_bp "break to inspect struct and array."
       test_fields "c"
       test_enums
+      test_is_scalar "c"
   }
 }
 
-
 # Perform C++ Tests.
 if { [build_inferior "${binfile}-cxx" "c++"] == 0 } {
   restart_gdb "${binfile}-cxx"
@@ -310,5 +333,6 @@ if { [build_inferior "${binfile}-cxx" "c++"] == 0 } {
       test_range
       test_template
       test_enums
+      test_is_scalar "c++"
   }
 }