public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@adacore.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 7/8] Add new Python APIs to support DAP value display
Date: Tue, 22 Aug 2023 09:25:13 -0600	[thread overview]
Message-ID: <20230822-array-and-string-like-v1-7-2dcea29b0567@adacore.com> (raw)
In-Reply-To: <20230822-array-and-string-like-v1-0-2dcea29b0567@adacore.com>

gdb's language code may know how to display values specially.  For
example, the Rust code understands that &str is a string-like type, or
Ada knows how to handle unconstrained arrays.  This knowledge is
exposed via val-print, and via varobj -- but currently not via DAP.

This patch adds some support code to let DAP also handle these cases,
though in a somewhat more generic way.

Type.is_array_like and Value.to_array are added to make Python aware
of the cases where gdb knows that a structure type is really
"array-like".

Type.is_string_like is added to make Python aware of cases where gdb's
language code knows that a type is string-like.

Unlike Value.string, these cases are handled by the type's language,
rather than the current language.
---
 gdb/NEWS              |  8 ++++++++
 gdb/doc/python.texi   | 24 ++++++++++++++++++++++
 gdb/python/py-type.c  | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/python/py-value.c | 37 +++++++++++++++++++++++++++++++++
 4 files changed, 126 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index c4b1f7a7e3b..98ff00d5efc 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -269,6 +269,9 @@ info main
 
   ** gdb.Value now has the 'assign' method.
 
+  ** gdb.Value now has the 'to_array' method.  This converts an
+     array-like Value to an array.
+
   ** gdb.Progspace now has the new method "objfile_for_address".  This
      returns the gdb.Objfile, if any, that covers a given address.
 
@@ -278,6 +281,11 @@ info main
      inferior specific, then this field contains None.  This field can
      be written too.
 
+  ** gdb.Type now has the "is_array_like" and "is_string_like"
+     methods.  These reflect GDB's internal idea of whether a type
+     might be array- or string-like, even if they do not have the
+     corresponding type code.
+
 *** Changes in GDB 13
 
 * MI version 1 is deprecated, and will be removed in GDB 14.
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 7460d6c8e31..e9936991c49 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -1206,6 +1206,13 @@ print frame-arguments scalars} (@pxref{Print Settings}).
 @end table
 @end defun
 
+@defun Value.to_array ()
+If this value is array-like (@pxref{Type.is_array_like}), then this
+method converts it to an array, which is returned.  If this value is
+already an array, it is simply returned.  Otherwise, an exception is
+throw.
+@end defun
+
 @defun Value.string (@r{[}encoding@r{[}, errors@r{[}, length@r{]]]})
 If this @code{gdb.Value} represents a string, then this method
 converts the contents to a Python string.  Otherwise, this method will
@@ -1392,6 +1399,23 @@ which @code{Type.is_scalar} is @code{False}), will raise a
 @code{ValueError}.
 @end defvar
 
+@defvar Type.is_array_like
+@anchor{Type.is_array_like}
+A boolean indicating whether this type is array-like.
+
+Some languages have array-like objects that are represented internally
+as structures.  For example, this is true for a Rust slice type, or
+for an Ada unconstrained array.  @value{GDBN} may know about these
+types.  This determination is done based on the language from which
+the type originated.
+@end defvar
+
+@defvar Type.is_string_like
+A boolean indicating whether this type is string-like.  Like
+@code{Type.is_array_like}, this is determined based on the originating
+language of the type.
+@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 b60875c792e..1fc1308af8e 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -442,6 +442,59 @@ typy_is_signed (PyObject *self, void *closure)
     Py_RETURN_TRUE;
 }
 
+/* Return true if this type is array-like.  */
+
+static PyObject *
+typy_is_array_like (PyObject *self, void *closure)
+{
+  struct type *type = ((type_object *) self)->type;
+
+  try
+    {
+      type = check_typedef (type);
+    }
+  catch (const gdb_exception &except)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  if (type->is_array_like ())
+    Py_RETURN_TRUE;
+  else
+    Py_RETURN_FALSE;
+}
+
+/* Return true if this type is string-like.  */
+
+static PyObject *
+typy_is_string_like (PyObject *self, void *closure)
+{
+  struct type *type = ((type_object *) self)->type;
+  bool result = false;
+
+  try
+    {
+      type = check_typedef (type);
+
+      const language_defn *lang = nullptr;
+      if (HAVE_GNAT_AUX_INFO (type))
+	lang = language_def (language_ada);
+      else if (HAVE_RUST_SPECIFIC (type))
+	lang = language_def (language_rust);
+      if (lang != nullptr)
+	result = lang->is_string_type_p (type);
+    }
+  catch (const gdb_exception &except)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  if (result)
+    Py_RETURN_TRUE;
+  else
+    Py_RETURN_FALSE;
+}
+
 /* Return the type, stripped of typedefs. */
 static PyObject *
 typy_strip_typedefs (PyObject *self, PyObject *args)
@@ -1525,6 +1578,10 @@ static gdb_PyGetSetDef type_object_getset[] =
     "Is this a scalar type?", nullptr },
   { "is_signed", typy_is_signed, nullptr,
     "Is this a signed type?", nullptr },
+  { "is_array_like", typy_is_array_like, nullptr,
+    "Is this an array-like type?", nullptr },
+  { "is_string_like", typy_is_string_like, nullptr,
+    "Is this a string-like type?", nullptr },
   { NULL }
 };
 
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index e1178de89e9..ee492fd9af6 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -330,6 +330,40 @@ valpy_rvalue_reference_value (PyObject *self, PyObject *args)
   return valpy_reference_value (self, args, TYPE_CODE_RVALUE_REF);
 }
 
+/* Implement Value.to_array.  */
+
+static PyObject *
+valpy_to_array (PyObject *self, PyObject *args)
+{
+  PyObject *result = nullptr;
+
+  try
+    {
+      struct value *val = ((value_object *) self)->value;
+      struct type *type = check_typedef (val->type ());
+
+      if (type->code () == TYPE_CODE_ARRAY)
+	{
+	  result = self;
+	  Py_INCREF (result);
+	}
+      else
+	{
+	  val = value_to_array (val);
+	  if (val == nullptr)
+	    PyErr_SetString (PyExc_TypeError, _("Value is not array-like."));
+	  else
+	    result = value_to_value_object (val);
+	}
+    }
+  catch (const gdb_exception &except)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  return result;
+}
+
 /* Return a "const" qualified version of the value.  */
 
 static PyObject *
@@ -2152,6 +2186,9 @@ formatting options" },
   { "assign", (PyCFunction) valpy_assign, METH_VARARGS,
     "assign (VAL) -> None\n\
 Assign VAL to this value." },
+  { "to_array", valpy_to_array, METH_NOARGS,
+    "to_array () -> Value\n\
+Return value as an array, if possible." },
   {NULL}  /* Sentinel */
 };
 

-- 
2.40.1


  parent reply	other threads:[~2023-08-22 15:25 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-22 15:25 [PATCH 0/8] Handle array- and string-like types in DAP Tom Tromey
2023-08-22 15:25 ` [PATCH 1/8] Move rust_language::lookup_symbol_nonlocal Tom Tromey
2023-08-22 15:25 ` [PATCH 2/8] Refactor Rust code for slice-to-array operation Tom Tromey
2023-08-22 15:25 ` [PATCH 3/8] Introduce TYPE_SPECIFIC_RUST_STUFF Tom Tromey
2023-08-22 15:25 ` [PATCH 4/8] Use ada_value_subscript in valpy_getitem Tom Tromey
2023-08-22 15:25 ` [PATCH 5/8] Introduce type::is_array_like and value_to_array Tom Tromey
2023-08-22 15:25 ` [PATCH 6/8] Select frame when fetching a frame variable in DAP Tom Tromey
2023-08-22 15:25 ` Tom Tromey [this message]
2023-08-22 15:46   ` [PATCH 7/8] Add new Python APIs to support DAP value display Eli Zaretskii
2023-08-22 15:25 ` [PATCH 8/8] Handle array- and string-like values in no-op pretty printers Tom Tromey
2023-09-05 17:22 ` [PATCH 0/8] Handle array- and string-like types in DAP Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230822-array-and-string-like-v1-7-2dcea29b0567@adacore.com \
    --to=tromey@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).