[14/55] Introduce value_print_array_elements

Message ID 20191208182958.10181-15-tom@tromey.com
State New
Headers show
Series
  • Remove val_print
Related show

Commit Message

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

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

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

Change-Id: I82d7666ce30b8cae3689fbf392177b08ef861a3b
---
 gdb/ChangeLog  |   5 ++
 gdb/valprint.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/valprint.h |   6 +++
 3 files changed, 137 insertions(+)

-- 
2.17.2

Comments

Simon Marchi Jan. 15, 2020, 5:15 a.m. | #1
On 2019-12-08 1:29 p.m., Tom Tromey wrote:
> This introduces value_print_array_elements, which is an analogue of

> val_print_array_elements that uses the value API.

> 

> gdb/ChangeLog

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

> 

> 	* valprint.c (value_print_array_elements): New function.

> 	* valprint.h (value_print_array_elements): Declare.

> 

> Change-Id: I82d7666ce30b8cae3689fbf392177b08ef861a3b

> ---

>  gdb/ChangeLog  |   5 ++

>  gdb/valprint.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++

>  gdb/valprint.h |   6 +++

>  3 files changed, 137 insertions(+)

> 

> diff --git a/gdb/valprint.c b/gdb/valprint.c

> index d09a42926e2..b2506dc6fc4 100644

> --- a/gdb/valprint.c

> +++ b/gdb/valprint.c

> @@ -2184,6 +2184,132 @@ val_print_array_elements (struct type *type,

>      }

>  }

>  

> +/* See valprint.h.  */

> +

> +void

> +value_print_array_elements (struct value *val, struct ui_file *stream,

> +			    int recurse,

> +			    const struct value_print_options *options,

> +			    unsigned int i)

> +{

> +  unsigned int things_printed = 0;

> +  unsigned len;

> +  struct type *elttype, *index_type, *base_index_type;

> +  unsigned eltlen;

> +  /* Position of the array element we are examining to see

> +     whether it is repeated.  */

> +  unsigned int rep1;

> +  /* Number of repetitions we have detected so far.  */

> +  unsigned int reps;

> +  LONGEST low_bound, high_bound;

> +  LONGEST low_pos, high_pos;

> +

> +  struct type *type = check_typedef (value_type (val));

> +

> +  elttype = TYPE_TARGET_TYPE (type);

> +  eltlen = type_length_units (check_typedef (elttype));

> +  index_type = TYPE_INDEX_TYPE (type);

> +

> +  if (get_array_bounds (type, &low_bound, &high_bound))

> +    {

> +      if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)

> +	base_index_type = TYPE_TARGET_TYPE (index_type);

> +      else

> +	base_index_type = index_type;

> +

> +      /* Non-contiguous enumerations types can by used as index types

> +	 in some languages (e.g. Ada).  In this case, the array length

> +	 shall be computed from the positions of the first and last

> +	 literal in the enumeration type, and not from the values

> +	 of these literals.  */

> +      if (!discrete_position (base_index_type, low_bound, &low_pos)

> +	  || !discrete_position (base_index_type, high_bound, &high_pos))

> +	{

> +	  warning (_("unable to get positions in array, use bounds instead"));

> +	  low_pos = low_bound;

> +	  high_pos = high_bound;

> +	}

> +

> +      /* The array length should normally be HIGH_POS - LOW_POS + 1.

> +         But we have to be a little extra careful, because some languages

> +	 such as Ada allow LOW_POS to be greater than HIGH_POS for

> +	 empty arrays.  In that situation, the array length is just zero,

> +	 not negative!  */

> +      if (low_pos > high_pos)

> +	len = 0;

> +      else

> +	len = high_pos - low_pos + 1;

> +    }

> +  else

> +    {

> +      warning (_("unable to get bounds of array, assuming null array"));

> +      low_bound = 0;

> +      len = 0;

> +    }

> +

> +  annotate_array_section_begin (i, elttype);

> +

> +  for (; i < len && things_printed < options->print_max; i++)

> +    {

> +      scoped_value_mark free_values;

> +

> +      if (i != 0)

> +	{

> +	  if (options->prettyformat_arrays)

> +	    {

> +	      fprintf_filtered (stream, ",\n");

> +	      print_spaces_filtered (2 + 2 * recurse, stream);

> +	    }

> +	  else

> +	    {

> +	      fprintf_filtered (stream, ", ");

> +	    }


You could remove these extra braces.

Simon
Tom Tromey Jan. 23, 2020, 11:37 p.m. | #2
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:


>> +	  else

>> +	    {

>> +	      fprintf_filtered (stream, ", ");

>> +	    }


Simon> You could remove these extra braces.

Done.

Tom

Patch

diff --git a/gdb/valprint.c b/gdb/valprint.c
index d09a42926e2..b2506dc6fc4 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -2184,6 +2184,132 @@  val_print_array_elements (struct type *type,
     }
 }
 
+/* See valprint.h.  */
+
+void
+value_print_array_elements (struct value *val, struct ui_file *stream,
+			    int recurse,
+			    const struct value_print_options *options,
+			    unsigned int i)
+{
+  unsigned int things_printed = 0;
+  unsigned len;
+  struct type *elttype, *index_type, *base_index_type;
+  unsigned eltlen;
+  /* Position of the array element we are examining to see
+     whether it is repeated.  */
+  unsigned int rep1;
+  /* Number of repetitions we have detected so far.  */
+  unsigned int reps;
+  LONGEST low_bound, high_bound;
+  LONGEST low_pos, high_pos;
+
+  struct type *type = check_typedef (value_type (val));
+
+  elttype = TYPE_TARGET_TYPE (type);
+  eltlen = type_length_units (check_typedef (elttype));
+  index_type = TYPE_INDEX_TYPE (type);
+
+  if (get_array_bounds (type, &low_bound, &high_bound))
+    {
+      if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
+	base_index_type = TYPE_TARGET_TYPE (index_type);
+      else
+	base_index_type = index_type;
+
+      /* Non-contiguous enumerations types can by used as index types
+	 in some languages (e.g. Ada).  In this case, the array length
+	 shall be computed from the positions of the first and last
+	 literal in the enumeration type, and not from the values
+	 of these literals.  */
+      if (!discrete_position (base_index_type, low_bound, &low_pos)
+	  || !discrete_position (base_index_type, high_bound, &high_pos))
+	{
+	  warning (_("unable to get positions in array, use bounds instead"));
+	  low_pos = low_bound;
+	  high_pos = high_bound;
+	}
+
+      /* The array length should normally be HIGH_POS - LOW_POS + 1.
+         But we have to be a little extra careful, because some languages
+	 such as Ada allow LOW_POS to be greater than HIGH_POS for
+	 empty arrays.  In that situation, the array length is just zero,
+	 not negative!  */
+      if (low_pos > high_pos)
+	len = 0;
+      else
+	len = high_pos - low_pos + 1;
+    }
+  else
+    {
+      warning (_("unable to get bounds of array, assuming null array"));
+      low_bound = 0;
+      len = 0;
+    }
+
+  annotate_array_section_begin (i, elttype);
+
+  for (; i < len && things_printed < options->print_max; i++)
+    {
+      scoped_value_mark free_values;
+
+      if (i != 0)
+	{
+	  if (options->prettyformat_arrays)
+	    {
+	      fprintf_filtered (stream, ",\n");
+	      print_spaces_filtered (2 + 2 * recurse, stream);
+	    }
+	  else
+	    {
+	      fprintf_filtered (stream, ", ");
+	    }
+	}
+      wrap_here (n_spaces (2 + 2 * recurse));
+      maybe_print_array_index (index_type, i + low_bound,
+                               stream, options);
+
+      rep1 = i + 1;
+      reps = 1;
+      /* Only check for reps if repeat_count_threshold is not set to
+	 UINT_MAX (unlimited).  */
+      if (options->repeat_count_threshold < UINT_MAX)
+	{
+	  while (rep1 < len
+		 && value_contents_eq (val, i * eltlen,
+				       val, rep1 * eltlen,
+				       eltlen))
+	    {
+	      ++reps;
+	      ++rep1;
+	    }
+	}
+
+      struct value *element = value_from_component (val, elttype, eltlen * i);
+      common_val_print (element, stream, recurse + 1, options,
+			current_language);
+
+      if (reps > options->repeat_count_threshold)
+	{
+	  annotate_elt_rep (reps);
+	  fprintf_filtered (stream, " %p[<repeats %u times>%p]",
+			    metadata_style.style ().ptr (), reps, nullptr);
+	  annotate_elt_rep_end ();
+
+	  i = rep1 - 1;
+	  things_printed += options->repeat_count_threshold;
+	}
+      else
+	{
+	  annotate_elt ();
+	  things_printed++;
+	}
+    }
+  annotate_array_section_end ();
+  if (i < len)
+    fprintf_filtered (stream, "...");
+}
+
 /* Read LEN bytes of target memory at address MEMADDR, placing the
    results in GDB's memory at MYADDR.  Returns a count of the bytes
    actually read, and optionally a target_xfer_status value in the
diff --git a/gdb/valprint.h b/gdb/valprint.h
index f1c93aa26b6..68b1083c742 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -134,6 +134,12 @@  extern void val_print_array_elements (struct type *, LONGEST,
 				      const struct value_print_options *,
 				      unsigned int);
 
+/* Print elements of an array.  */
+
+extern void value_print_array_elements (struct value *, struct ui_file *, int,
+					const struct value_print_options *,
+					unsigned int);
+
 extern void val_print_scalar_formatted (struct type *,
 					LONGEST,
 					struct value *,