Patchwork [12/55] Introduce value_print_scalar_formatted

login
register
mail settings
Submitter Tom Tromey
Date Dec. 8, 2019, 6:29 p.m.
Message ID <20191208182958.10181-13-tom@tromey.com>
Download mbox | patch
Permalink /patch/36616/
State New
Headers show

Comments

Tom Tromey - Dec. 8, 2019, 6:29 p.m.
This introduces a value_print_scalar_formatted, which is an analogue
of val_print_scalar_formatted that uses the value API.

gdb/ChangeLog
2019-12-08  Tom Tromey  <tom@tromey.com>

	* valprint.h (value_print_scalar_formatted): Declare.
	* valprint.c (value_print_scalar_formatted): New function.

Change-Id: Ie2b9ee80d53af8a99116b4b7a93dc16f420fb404
---
 gdb/ChangeLog  |  5 +++++
 gdb/valprint.c | 40 ++++++++++++++++++++++++++++++++++++++++
 gdb/valprint.h | 10 ++++++++++
 3 files changed, 55 insertions(+)
Simon Marchi - Jan. 15, 2020, 5:09 a.m.
On 2019-12-08 1:29 p.m., Tom Tromey wrote:
> diff --git a/gdb/valprint.h b/gdb/valprint.h
> index e4b90404fa2..f1c93aa26b6 100644
> --- a/gdb/valprint.h
> +++ b/gdb/valprint.h
> @@ -141,6 +141,16 @@ extern void val_print_scalar_formatted (struct type *,
>  					int,
>  					struct ui_file *);
>  
> +/* Print a scalar according to OPTIONS and SIZE on STREAM.  Format i
> +   is not supported at this level.

There seems to be a typo above, "Format i".

> +
> +   This is how the elements of an array or structure are printed
> +   with a format.  */
> +
> +extern void value_print_scalar_formatted (struct value *,
> +					  const struct value_print_options *,
> +					  int, struct ui_file *);
> +

I think you should add the parameter names here, especially since the comment
refers to them.

Simon

Patch

diff --git a/gdb/valprint.c b/gdb/valprint.c
index 0e13e2b2d62..d09a42926e2 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1365,6 +1365,46 @@  val_print_scalar_formatted (struct type *type,
 			    options, size, stream);
 }
 
+/* See valprint.h.  */
+
+void
+value_print_scalar_formatted (struct value *val,
+			      const struct value_print_options *options,
+			      int size,
+			      struct ui_file *stream)
+{
+  struct type *type = check_typedef (value_type (val));
+
+  gdb_assert (val != NULL);
+
+  /* If we get here with a string format, try again without it.  Go
+     all the way back to the language printers, which may call us
+     again.  */
+  if (options->format == 's')
+    {
+      struct value_print_options opts = *options;
+      opts.format = 0;
+      opts.deref_ref = 0;
+      common_val_print (val, stream, 0, &opts, current_language);
+      return;
+    }
+
+  /* value_contents_for_printing fetches all VAL's contents.  They are
+     needed to check whether VAL is optimized-out or unavailable
+     below.  */
+  const gdb_byte *valaddr = value_contents_for_printing (val);
+
+  /* A scalar object that does not have all bits available can't be
+     printed, because all bits contribute to its representation.  */
+  if (value_bits_any_optimized_out (val, 0,
+				    TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+    val_print_optimized_out (val, stream);
+  else if (!value_bytes_available (val, 0, TYPE_LENGTH (type)))
+    val_print_unavailable (stream);
+  else
+    print_scalar_formatted (valaddr, type, options, size, stream);
+}
+
 /* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
    The raison d'etre of this function is to consolidate printing of 
    LONG_LONG's into this one function.  The format chars b,h,w,g are 
diff --git a/gdb/valprint.h b/gdb/valprint.h
index e4b90404fa2..f1c93aa26b6 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -141,6 +141,16 @@  extern void val_print_scalar_formatted (struct type *,
 					int,
 					struct ui_file *);
 
+/* Print a scalar according to OPTIONS and SIZE on STREAM.  Format i
+   is not supported at this level.
+
+   This is how the elements of an array or structure are printed
+   with a format.  */
+
+extern void value_print_scalar_formatted (struct value *,
+					  const struct value_print_options *,
+					  int, struct ui_file *);
+
 extern void print_binary_chars (struct ui_file *, const gdb_byte *,
 				unsigned int, enum bfd_endian, bool);