Change extension language pretty-printers to use value API
authorTom Tromey <tom@tromey.com>
Fri, 13 Mar 2020 23:39:52 +0000 (17:39 -0600)
committerTom Tromey <tom@tromey.com>
Sat, 14 Mar 2020 00:03:42 +0000 (18:03 -0600)
This changes the extension language pretty-printers to use the value
API.

Note that new functions were needed, for both Guile and Python.
Currently both languages always wrap values by removing the values
from the value chain.  This makes sense to avoid strange behavior with
watchpoints, and to avoid excessive memory use.  However, when
printing, it's important to leave the passed-in value untouched, in
case pretty-printing does nothing -- that way the caller can still
access it.

gdb/ChangeLog
2020-03-13  Tom Tromey  <tom@tromey.com>

* valprint.c (do_val_print): Update.
* python/python-internal.h (gdbpy_apply_val_pretty_printer): Take
a struct value.
(value_to_value_object_no_release): Declare.
* python/py-value.c (value_to_value_object_no_release): New
function.
* python/py-prettyprint.c (gdbpy_apply_val_pretty_printer): Take a
struct value.
* guile/scm-value.c (vlscm_scm_from_value_no_release): New
function.
* guile/scm-pretty-print.c (gdbscm_apply_val_pretty_printer): Take
a struct value.
* guile/guile-internal.h (vlscm_scm_from_value_no_release):
Declare.
(gdbscm_apply_val_pretty_printer): Take a struct value.
* extension.h (apply_ext_lang_val_pretty_printer): Take a struct
value.
* extension.c (apply_ext_lang_val_pretty_printer): Take a struct
value.
* extension-priv.h (struct extension_language_ops)
<apply_val_pretty_printer>: Take a struct value.
* cp-valprint.c (cp_print_value): Create a struct value.
(cp_print_value): Update.

12 files changed:
gdb/ChangeLog
gdb/cp-valprint.c
gdb/extension-priv.h
gdb/extension.c
gdb/extension.h
gdb/guile/guile-internal.h
gdb/guile/scm-pretty-print.c
gdb/guile/scm-value.c
gdb/python/py-prettyprint.c
gdb/python/py-value.c
gdb/python/python-internal.h
gdb/valprint.c

index 767f3b73e992ce559c3fabc9ff9e003f80e595a0..ac1a4f867ef5396da8c337ad1019c27262fc0a8c 100644 (file)
@@ -1,3 +1,29 @@
+2020-03-13  Tom Tromey  <tom@tromey.com>
+
+       * valprint.c (do_val_print): Update.
+       * python/python-internal.h (gdbpy_apply_val_pretty_printer): Take
+       a struct value.
+       (value_to_value_object_no_release): Declare.
+       * python/py-value.c (value_to_value_object_no_release): New
+       function.
+       * python/py-prettyprint.c (gdbpy_apply_val_pretty_printer): Take a
+       struct value.
+       * guile/scm-value.c (vlscm_scm_from_value_no_release): New
+       function.
+       * guile/scm-pretty-print.c (gdbscm_apply_val_pretty_printer): Take
+       a struct value.
+       * guile/guile-internal.h (vlscm_scm_from_value_no_release):
+       Declare.
+       (gdbscm_apply_val_pretty_printer): Take a struct value.
+       * extension.h (apply_ext_lang_val_pretty_printer): Take a struct
+       value.
+       * extension.c (apply_ext_lang_val_pretty_printer): Take a struct
+       value.
+       * extension-priv.h (struct extension_language_ops)
+       <apply_val_pretty_printer>: Take a struct value.
+       * cp-valprint.c (cp_print_value): Create a struct value.
+       (cp_print_value): Update.
+
 2020-03-13  Tom Tromey  <tom@tromey.com>
 
        * ada-valprint.c (print_field_values): Call common_val_print.
index 77725b7f3c4117a8ee162fc9b8b293dc3cdbe894..5e4cb3cad643ace548acec4097d933c6dde29be1 100644 (file)
@@ -848,13 +848,15 @@ cp_print_value (struct type *type, struct type *real_type,
              /* Attempt to run an extension language pretty-printer on the
                 baseclass if possible.  */
              if (!options->raw)
-               result
-                 = apply_ext_lang_val_pretty_printer (baseclass,
-                                                      thisoffset + boffset,
-                                                      value_address (base_val),
-                                                      stream, recurse,
-                                                      base_val, options,
-                                                      current_language);
+               {
+                 struct value *v
+                   = value_from_component (base_val, baseclass,
+                                           thisoffset + boffset);
+                 result
+                   = apply_ext_lang_val_pretty_printer (v, stream, recurse,
+                                                        options,
+                                                        current_language);
+               }
 
              if (!result)
                cp_print_value_fields (baseclass, thistype,
@@ -1006,19 +1008,19 @@ cp_print_value (struct value *val, struct ui_file *stream,
            }
          else
            {
+             struct value *baseclass_val = value_primitive_field (val, 0,
+                                                                  i, type);
+
              /* Attempt to run an extension language pretty-printer on the
                 baseclass if possible.  */
              if (!options->raw)
                result
-                 = apply_ext_lang_val_pretty_printer (baseclass, boffset,
-                                                      value_address (base_val),
-                                                      stream, recurse,
-                                                      base_val, options,
+                 = apply_ext_lang_val_pretty_printer (baseclass_val, stream,
+                                                      recurse, options,
                                                       current_language);
 
              if (!result)
-               cp_print_value_fields (value_primitive_field (val, 0, i, type),
-                                      stream, recurse, options,
+               cp_print_value_fields (baseclass_val, stream, recurse, options,
                                       ((struct type **)
                                        obstack_base (&dont_print_vb_obstack)),
                                       0);
index c35671013d9ca146b3f24660baf06bf91f626111..8596e0a95f5216366547874edf4f6a7a33f9d9de 100644 (file)
@@ -152,19 +152,14 @@ struct extension_language_ops
   void (*free_type_printers) (const struct extension_language_defn *,
                              struct ext_lang_type_printers *);
 
-  /* Try to pretty-print a value of type TYPE located at VAL's contents
-     buffer + EMBEDDED_OFFSET, which came from the inferior at address
-     ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to
-     OPTIONS.
-     VAL is the whole object that came from ADDRESS.
-     Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the value
-     is not recognized, and EXT_LANG_RC_ERROR if an error was encountered.  */
+  /* Try to pretty-print a value, onto stdio stream STREAM according
+     to OPTIONS.  VAL is the object to print.  Returns EXT_LANG_RC_OK
+     upon success, EXT_LANG_RC_NOP if the value is not recognized, and
+     EXT_LANG_RC_ERROR if an error was encountered.  */
   enum ext_lang_rc (*apply_val_pretty_printer)
     (const struct extension_language_defn *,
-     struct type *type,
-     LONGEST embedded_offset, CORE_ADDR address,
-     struct ui_file *stream, int recurse,
-     struct value *val, const struct value_print_options *options,
+     struct value *val, struct ui_file *stream, int recurse,
+     const struct value_print_options *options,
      const struct language_defn *language);
 
   /* GDB access to the "frame filter" feature.
index e2efe0b0d836fe12aeb7aa115110d9a33930ba02..09aa7d91c315e54aedcb027add6f61e1af806ead 100644 (file)
@@ -470,12 +470,9 @@ ext_lang_type_printers::~ext_lang_type_printers ()
     }
 }
 \f
-/* Try to pretty-print a value of type TYPE located at VAL's contents
-   buffer + EMBEDDED_OFFSET, which came from the inferior at address
-   ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to
-   OPTIONS.
-   VAL is the whole object that came from ADDRESS.
-   Returns non-zero if the value was successfully pretty-printed.
+/* Try to pretty-print a value onto stdio stream STREAM according to
+   OPTIONS.  VAL is the object to print.  Returns non-zero if the
+   value was successfully pretty-printed.
 
    Extension languages are tried in the order specified by
    extension_languages.  The first one to provide a pretty-printed
@@ -488,10 +485,8 @@ ext_lang_type_printers::~ext_lang_type_printers ()
    errors that trigger an exception in the extension language.  */
 
 int
-apply_ext_lang_val_pretty_printer (struct type *type,
-                                  LONGEST embedded_offset, CORE_ADDR address,
+apply_ext_lang_val_pretty_printer (struct value *val,
                                   struct ui_file *stream, int recurse,
-                                  struct value *val,
                                   const struct value_print_options *options,
                                   const struct language_defn *language)
 {
@@ -504,10 +499,8 @@ apply_ext_lang_val_pretty_printer (struct type *type,
 
       if (extlang->ops->apply_val_pretty_printer == NULL)
        continue;
-      rc = extlang->ops->apply_val_pretty_printer (extlang, type,
-                                                  embedded_offset, address,
-                                                  stream, recurse, val,
-                                                  options, language);
+      rc = extlang->ops->apply_val_pretty_printer (extlang, val, stream,
+                                                  recurse, options, language);
       switch (rc)
        {
        case EXT_LANG_RC_OK:
index ca3fc14bd0fb3a3a89b4fea2e6385a374f93d497..c840dbc70436321599220f69783e9e81155a8e27 100644 (file)
@@ -283,10 +283,8 @@ extern char *apply_ext_lang_type_printers (struct ext_lang_type_printers *,
                                           struct type *);
 
 extern int apply_ext_lang_val_pretty_printer
-  (struct type *type,
-   LONGEST embedded_offset, CORE_ADDR address,
-   struct ui_file *stream, int recurse,
-   struct value *val, const struct value_print_options *options,
+  (struct value *value, struct ui_file *stream, int recurse,
+   const struct value_print_options *options,
    const struct language_defn *language);
 
 extern enum ext_lang_bt_status apply_ext_lang_frame_filter
index 08fcb33098be943eaecb771774c4b0c369530710..c501e2bc4a54923ee334ae8342f7c900beda9e66 100644 (file)
@@ -579,6 +579,7 @@ extern struct value *vlscm_scm_to_value (SCM scm);
 extern int vlscm_is_value (SCM scm);
 
 extern SCM vlscm_scm_from_value (struct value *value);
+extern SCM vlscm_scm_from_value_no_release (struct value *value);
 
 extern struct value *vlscm_convert_typed_value_from_scheme
   (const char *func_name, int obj_arg_pos, SCM obj,
@@ -602,10 +603,8 @@ extern void gdbscm_preserve_values
 
 extern enum ext_lang_rc gdbscm_apply_val_pretty_printer
   (const struct extension_language_defn *,
-   struct type *type,
-   LONGEST embedded_offset, CORE_ADDR address,
-   struct ui_file *stream, int recurse,
    struct value *val,
+   struct ui_file *stream, int recurse,
    const struct value_print_options *options,
    const struct language_defn *language);
 
index 3ab1bd1c7a778063025512413c4a64a540034d3e..ccc616445138be550d2ee7d738a420cb2f4f61ac 100644 (file)
@@ -943,36 +943,32 @@ ppscm_print_children (SCM printer, enum display_hint hint,
 
 enum ext_lang_rc
 gdbscm_apply_val_pretty_printer (const struct extension_language_defn *extlang,
-                                struct type *type,
-                                LONGEST embedded_offset, CORE_ADDR address,
+                                struct value *value,
                                 struct ui_file *stream, int recurse,
-                                struct value *val,
                                 const struct value_print_options *options,
                                 const struct language_defn *language)
 {
+  struct type *type = value_type (value);
   struct gdbarch *gdbarch = get_type_arch (type);
   SCM exception = SCM_BOOL_F;
   SCM printer = SCM_BOOL_F;
   SCM val_obj = SCM_BOOL_F;
-  struct value *value;
   enum display_hint hint;
   enum ext_lang_rc result = EXT_LANG_RC_NOP;
   enum string_repr_result print_result;
 
-  if (value_lazy (val))
-    value_fetch_lazy (val);
+  if (value_lazy (value))
+    value_fetch_lazy (value);
 
   /* No pretty-printer support for unavailable values.  */
-  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+  if (!value_bytes_available (value, 0, TYPE_LENGTH (type)))
     return EXT_LANG_RC_NOP;
 
   if (!gdb_scheme_initialized)
     return EXT_LANG_RC_NOP;
 
   /* Instantiate the printer.  */
-  value = value_from_component (val, type, embedded_offset);
-
-  val_obj = vlscm_scm_from_value (value);
+  val_obj = vlscm_scm_from_value_no_release (value);
   if (gdbscm_is_exception (val_obj))
     {
       exception = val_obj;
index 020b5e12f90317152405f049ef2b989a3a59a329..53b373e19deb2c0fcc57c65c4cde4c802c94d7c2 100644 (file)
@@ -261,6 +261,24 @@ vlscm_scm_from_value (struct value *value)
   return v_scm;
 }
 
+/* Create a new <gdb:value> object that encapsulates VALUE.
+   The value is not released from the all_values chain.  */
+
+SCM
+vlscm_scm_from_value_no_release (struct value *value)
+{
+  /* N.B. It's important to not cause any side-effects until we know the
+     conversion worked.  */
+  SCM v_scm = vlscm_make_value_smob ();
+  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (v_scm);
+
+  value_incref (value);
+  v_smob->value = value;
+  vlscm_remember_scheme_value (v_smob);
+
+  return v_scm;
+}
+
 /* Returns the <gdb:value> object in SELF.
    Throws an exception if SELF is not a <gdb:value> object.  */
 
index deecb1295c0037cc21ea29f20812dd009e7af782..7cb20df7f26729b137d1499f9c8ce1ff61cf728a 100644 (file)
@@ -558,22 +558,20 @@ print_children (PyObject *printer, const char *hint,
 
 enum ext_lang_rc
 gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
-                               struct type *type,
-                               LONGEST embedded_offset, CORE_ADDR address,
+                               struct value *value,
                                struct ui_file *stream, int recurse,
-                               struct value *val,
                                const struct value_print_options *options,
                                const struct language_defn *language)
 {
+  struct type *type = value_type (value);
   struct gdbarch *gdbarch = get_type_arch (type);
-  struct value *value;
   enum string_repr_result print_result;
 
-  if (value_lazy (val))
-    value_fetch_lazy (val);
+  if (value_lazy (value))
+    value_fetch_lazy (value);
 
   /* No pretty-printer support for unavailable values.  */
-  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+  if (!value_bytes_available (value, 0, TYPE_LENGTH (type)))
     return EXT_LANG_RC_NOP;
 
   if (!gdb_python_initialized)
@@ -581,10 +579,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
 
   gdbpy_enter enter_py (gdbarch, language);
 
-  /* Instantiate the printer.  */
-  value = value_from_component (val, type, embedded_offset);
-
-  gdbpy_ref<> val_obj (value_to_value_object (value));
+  gdbpy_ref<> val_obj (value_to_value_object_no_release (value));
   if (val_obj == NULL)
     {
       print_stack_unless_memory_error (stream);
index 497696a7d3a8af7da55d5ed5de8f453e22b52b85..bc75a68326e620b0f357216cc5c1a3dfc6d47713 100644 (file)
@@ -1788,6 +1788,27 @@ value_to_value_object (struct value *val)
   return (PyObject *) val_obj;
 }
 
+/* Returns an object for a value, but without releasing it from the
+   all_values chain.  */
+PyObject *
+value_to_value_object_no_release (struct value *val)
+{
+  value_object *val_obj;
+
+  val_obj = PyObject_New (value_object, &value_object_type);
+  if (val_obj != NULL)
+    {
+      value_incref (val);
+      val_obj->value = val;
+      val_obj->address = NULL;
+      val_obj->type = NULL;
+      val_obj->dynamic_type = NULL;
+      note_value (val_obj);
+    }
+
+  return (PyObject *) val_obj;
+}
+
 /* Returns a borrowed reference to the struct value corresponding to
    the given value object.  */
 struct value *
index bbb66bd0f5c145452bdbcba00aa0f28d540fe9db..e352b30382804cfc293f065c5c5a70de4cb25268 100644 (file)
@@ -391,10 +391,8 @@ extern int gdbpy_auto_load_enabled (const struct extension_language_defn *);
 
 extern enum ext_lang_rc gdbpy_apply_val_pretty_printer
   (const struct extension_language_defn *,
-   struct type *type,
-   LONGEST embedded_offset, CORE_ADDR address,
+   struct value *value,
    struct ui_file *stream, int recurse,
-   struct value *val,
    const struct value_print_options *options,
    const struct language_defn *language);
 extern enum ext_lang_bt_status gdbpy_apply_frame_filter
@@ -456,6 +454,7 @@ PyObject *symbol_to_symbol_object (struct symbol *sym);
 PyObject *block_to_block_object (const struct block *block,
                                 struct objfile *objfile);
 PyObject *value_to_value_object (struct value *v);
+PyObject *value_to_value_object_no_release (struct value *v);
 PyObject *type_to_type_object (struct type *);
 PyObject *frame_info_to_frame_object (struct frame_info *frame);
 PyObject *symtab_to_linetable_object (PyObject *symtab);
index 5bf874eab99398f94b34978a9e821deb2c294bd4..07f5c5775304cfbef8bce65f740bff66e01a6bfd 100644 (file)
@@ -1279,9 +1279,13 @@ do_val_print (struct value *full_value,
 
   if (!options->raw)
     {
-      ret = apply_ext_lang_val_pretty_printer (type, embedded_offset,
-                                              address, stream, recurse,
-                                              val, options, language);
+      struct value *v = full_value;
+
+      if (v == nullptr)
+       v = value_from_component (val, type, embedded_offset);
+
+      ret = apply_ext_lang_val_pretty_printer (v, stream, recurse, options,
+                                              language);
       if (ret)
        return;
     }
@@ -1477,11 +1481,8 @@ value_print (struct value *val, struct ui_file *stream,
   if (!options->raw)
     {
       int r
-       = apply_ext_lang_val_pretty_printer (value_type (val),
-                                            value_embedded_offset (val),
-                                            value_address (val),
-                                            stream, 0,
-                                            val, options, current_language);
+       = apply_ext_lang_val_pretty_printer (val, stream, 0, options,
+                                            current_language);
 
       if (r)
        return;