[12/12] gdb: make type::bounds work for array and string types

Message ID 20200706133950.145851-13-simon.marchi@polymtl.ca
State New
Headers show
Series
  • More type macros removal
Related show

Commit Message

From: Simon Marchi <simon.marchi@efficios.com>


Getting the bounds of an array (or string) type is a common operation,
and is currently done through its index type:

    my_array_type->index_type ()->bounds ()

I think it would make sense to let the `type::bounds` methods work for
arrays and strings, as a shorthand for this.  It's natural that when
asking for the bounds of an array, we get the bounds of the range type
used as its index type.  In a way, it's equivalent as the now-removed
TYPE_ARRAY_{LOWER,UPPER}_BOUND_IS_UNDEFINED and
TYPE_ARRAY_{LOWER,UPPER}_BOUND_VALUE, except it returns the
`range_bounds` object.  The caller is then responsible for getting the
property it needs in it.

I updated all the spots I could find that could take advantage of this.

Note that this also makes `type::bit_stride` work on array types, since
`type::bit_stride` uses `type::bounds`.  `my_array_type->bit_stride ()`
now returns the bit stride of the array's index type.  So some spots
are also changed to take advantage of this.

Change-Id: I5c0c08930bffe42fd69cb4bfcece28944dd88d1f
---
 gdb/ada-lang.c       |  4 ++--
 gdb/c-typeprint.c    |  4 ++--
 gdb/c-varobj.c       |  9 ++++-----
 gdb/eval.c           |  3 +--
 gdb/f-typeprint.c    |  4 ++--
 gdb/f-valprint.c     | 11 +++++------
 gdb/gdbtypes.h       | 16 +++++++++++++---
 gdb/guile/scm-type.c |  3 ---
 gdb/m2-typeprint.c   |  6 +++---
 gdb/m2-valprint.c    |  5 ++---
 gdb/p-typeprint.c    |  6 +++---
 gdb/python/py-type.c |  3 ---
 gdb/rust-lang.c      |  4 ++--
 gdb/type-stack.c     |  2 +-
 gdb/valarith.c       |  4 ++--
 gdb/valops.c         |  3 +--
 16 files changed, 43 insertions(+), 44 deletions(-)

-- 
2.27.0

Patch

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 2fc5fc1fdc2c..fb4bf7ec1ce1 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -9492,8 +9492,8 @@  assign_aggregate (struct value *container,
     {
       lhs = ada_coerce_to_simple_array (lhs);
       lhs_type = check_typedef (value_type (lhs));
-      low_index = lhs_type->index_type ()->bounds ()->low.const_val ();
-      high_index = lhs_type->index_type ()->bounds ()->high.const_val ();
+      low_index = lhs_type->bounds ()->low.const_val ();
+      high_index = lhs_type->bounds ()->high.const_val ();
     }
   else if (lhs_type->code () == TYPE_CODE_STRUCT)
     {
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 9e408e15a1e2..91d9ef8209e8 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -780,8 +780,8 @@  c_type_print_varspec_suffix (struct type *type,
 	fprintf_filtered (stream, (is_vector ?
 				   " __attribute__ ((vector_size(" : "["));
 	/* Bounds are not yet resolved, print a bounds placeholder instead.  */
-	if (type->index_type ()->bounds ()->high.kind () == PROP_LOCEXPR
-	    || type->index_type ()->bounds ()->high.kind () == PROP_LOCLIST)
+	if (type->bounds ()->high.kind () == PROP_LOCEXPR
+	    || type->bounds ()->high.kind () == PROP_LOCLIST)
 	  fprintf_filtered (stream, "variable length");
 	else if (get_array_bounds (type, &low_bound, &high_bound))
 	  fprintf_filtered (stream, "%s", 
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 2bcfe8672eb7..56354e5f0665 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -192,7 +192,7 @@  c_number_of_children (const struct varobj *var)
     {
     case TYPE_CODE_ARRAY:
       if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0
-	  && (type->index_type ()->bounds ()->high.kind () != PROP_UNDEFINED))
+	  && (type->bounds ()->high.kind () != PROP_UNDEFINED))
 	children = TYPE_LENGTH (type) / TYPE_LENGTH (target);
       else
 	/* If we don't know how many elements there are, don't display
@@ -306,14 +306,13 @@  c_describe_child (const struct varobj *parent, int index,
     {
     case TYPE_CODE_ARRAY:
       if (cname)
-	*cname = int_string (index
-			     + type->index_type ()->bounds ()->low.const_val (),
+	*cname = int_string (index + type->bounds ()->low.const_val (),
 			     10, 1, 0, 0);
 
       if (cvalue && value)
 	{
 	  int real_index
-	    = index + type->index_type ()->bounds ()->low.const_val ();
+	    = index + type->bounds ()->low.const_val ();
 
 	  try
 	    {
@@ -330,7 +329,7 @@  c_describe_child (const struct varobj *parent, int index,
       if (cfull_expression)
 	*cfull_expression = string_printf
 	  ("(%s)[%s]", parent_expression.c_str (),
-	   int_string (index + type->index_type ()->bounds ()->low.const_val (),
+	   int_string (index + type->bounds ()->low.const_val (),
 		       10, 1, 0, 0));
 
       break;
diff --git a/gdb/eval.c b/gdb/eval.c
index dacd46da44fa..c62c35f31835 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -3212,8 +3212,7 @@  evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
 	  type = value_type (val);
 	  if (type->code () == TYPE_CODE_ARRAY
               && is_dynamic_type (type->index_type ())
-              && (type->index_type ()->bounds ()->high.kind ()
-		  == PROP_UNDEFINED))
+              && type->bounds ()->high.kind () == PROP_UNDEFINED)
 	    return allocate_optimized_out_value (size_type);
 	}
       else
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index df83a481386a..80dbfe111674 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -223,7 +223,7 @@  f_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
 	  /* Make sure that, if we have an assumed size array, we
 	       print out a warning and print the upperbound as '*'.  */
 
-	  if (type->index_type ()->bounds ()->high.kind () == PROP_UNDEFINED)
+	  if (type->bounds ()->high.kind () == PROP_UNDEFINED)
 	    fprintf_filtered (stream, "*");
 	  else
 	    {
@@ -408,7 +408,7 @@  f_type_print_base (struct type *type, struct ui_file *stream, int show,
     case TYPE_CODE_STRING:
       /* Strings may have dynamic upperbounds (lengths) like arrays.  */
 
-      if (type->index_type ()->bounds ()->high.kind () == PROP_UNDEFINED)
+      if (type->bounds ()->high.kind () == PROP_UNDEFINED)
 	fprintfi_filtered (level, stream, "character*(*)");
       else
 	{
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 17e15f9bdff6..fabdf4586168 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -46,16 +46,16 @@  int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2];
 LONGEST
 f77_get_lowerbound (struct type *type)
 {
-  if (type->index_type ()->bounds ()->low.kind () == PROP_UNDEFINED)
+  if (type->bounds ()->low.kind () == PROP_UNDEFINED)
     error (_("Lower bound may not be '*' in F77"));
 
-  return type->index_type ()->bounds ()->low.const_val ();
+  return type->bounds ()->low.const_val ();
 }
 
 LONGEST
 f77_get_upperbound (struct type *type)
 {
-  if (type->index_type ()->bounds ()->high.kind () == PROP_UNDEFINED)
+  if (type->bounds ()->high.kind () == PROP_UNDEFINED)
     {
       /* We have an assumed size array on our hands.  Assume that
 	 upper_bound == lower_bound so that we show at least 1 element.
@@ -65,7 +65,7 @@  f77_get_upperbound (struct type *type)
       return f77_get_lowerbound (type);
     }
 
-  return type->index_type ()->bounds ()->high.const_val ();
+  return type->bounds ()->high.const_val ();
 }
 
 /* Obtain F77 adjustable array dimensions.  */
@@ -124,8 +124,7 @@  f77_print_array_1 (int nss, int ndimensions, struct type *type,
       struct gdbarch *gdbarch = get_type_arch (type);
       size_t dim_size = type_length_units (TYPE_TARGET_TYPE (type));
       int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
-      size_t byte_stride
-	= type->index_type ()->bounds ()->bit_stride () / (unit_size * 8);
+      size_t byte_stride = type->bit_stride () / (unit_size * 8);
       if (byte_stride == 0)
 	byte_stride = dim_size;
       size_t offs = 0;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index d8ddc4161391..eaa4cff608d7 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1040,9 +1040,19 @@  struct type
   /* Get the bounds bounds of this type.  The type must be a range type.  */
   range_bounds *bounds () const
   {
-    gdb_assert (this->code () == TYPE_CODE_RANGE);
-
-    return this->main_type->flds_bnds.bounds;
+    switch (this->code ())
+      {
+      case TYPE_CODE_RANGE:
+	return this->main_type->flds_bnds.bounds;
+
+      case TYPE_CODE_ARRAY:
+      case TYPE_CODE_STRING:
+	return this->index_type ()->bounds ();
+
+      default:
+	gdb_assert_not_reached
+	  ("type::bounds called on type with invalid code");
+      }
   }
 
   /* Set the bounds of this type.  The type must be a range type.  */
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index fe6f493aa7f5..19b7996c9467 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -826,9 +826,6 @@  gdbscm_type_range (SCM self)
     {
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_STRING:
-      low = type->index_type ()->bounds ()->low.const_val ();
-      high = type->index_type ()->bounds ()->high.const_val ();
-      break;
     case TYPE_CODE_RANGE:
       low = type->bounds ()->low.const_val ();
       high = type->bounds ()->high.const_val ();
diff --git a/gdb/m2-typeprint.c b/gdb/m2-typeprint.c
index 474e58725c7f..521d9260322a 100644
--- a/gdb/m2-typeprint.c
+++ b/gdb/m2-typeprint.c
@@ -226,7 +226,7 @@  static void m2_array (struct type *type, struct ui_file *stream,
 {
   fprintf_filtered (stream, "ARRAY [");
   if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
-      && type->index_type ()->bounds ()->high.kind () != PROP_UNDEFINED)
+      && type->bounds ()->high.kind () != PROP_UNDEFINED)
     {
       if (type->index_type () != 0)
 	{
@@ -416,8 +416,8 @@  m2_is_long_set_of_type (struct type *type, struct type **of_type)
       range = type->field (i).type ()->index_type ();
       target = TYPE_TARGET_TYPE (range);
 
-      l1 = type->field (i).type ()->index_type ()->bounds ()->low.const_val ();
-      h1 = type->field (len - 1).type ()->index_type ()->bounds ()->high.const_val ();
+      l1 = type->field (i).type ()->bounds ()->low.const_val ();
+      h1 = type->field (len - 1).type ()->bounds ()->high.const_val ();
       *of_type = target;
       if (m2_get_discrete_bounds (target, &l2, &h2) >= 0)
 	return (l1 == l2 && h1 == h2);
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
index 175c53adacfa..b0a3ce3ec3e0 100644
--- a/gdb/m2-valprint.c
+++ b/gdb/m2-valprint.c
@@ -55,9 +55,8 @@  get_long_set_bounds (struct type *type, LONGEST *low, LONGEST *high)
       i = TYPE_N_BASECLASSES (type);
       if (len == 0)
 	return 0;
-      *low = type->field (i).type ()->index_type ()->bounds ()->low.const_val ();
-      *high = (type->field (len - 1).type ()->index_type ()->bounds ()
-	       ->high.const_val ());
+      *low = type->field (i).type ()->bounds ()->low.const_val ();
+      *high = type->field (len - 1).type ()->bounds ()->high.const_val ();
       return 1;
     }
   error (_("expecting long_set"));
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
index d52358aa4bb4..7842b63081c7 100644
--- a/gdb/p-typeprint.c
+++ b/gdb/p-typeprint.c
@@ -274,10 +274,10 @@  pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
 	fprintf_filtered (stream, "(");
       fprintf_filtered (stream, "array ");
       if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
-	  && type->index_type ()->bounds ()->high.kind () != PROP_UNDEFINED)
+	  && type->bounds ()->high.kind () != PROP_UNDEFINED)
 	fprintf_filtered (stream, "[%s..%s] ",
-			  plongest (type->index_type ()->bounds ()->low.const_val ()),
-			  plongest (type->index_type ()->bounds ()->high.const_val ()));
+			  plongest (type->bounds ()->low.const_val ()),
+			  plongest (type->bounds ()->high.const_val ()));
       fprintf_filtered (stream, "of ");
       break;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index e99ee415e2f9..d0dfb52811b2 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -592,9 +592,6 @@  typy_range (PyObject *self, PyObject *args)
     {
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_STRING:
-      low = type->index_type ()->bounds ()->low.const_val ();
-      high = type->index_type ()->bounds ()->high.const_val ();
-      break;
     case TYPE_CODE_RANGE:
       low = type->bounds ()->low.const_val ();
       high = type->bounds ()->high.const_val ();;
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index cedb15f555d3..ddd4b57d2944 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -813,8 +813,8 @@  rust_internal_print_type (struct type *type, const char *varstring,
 				  stream, show - 1, level, flags, false,
 				  podata);
 
-	if (type->index_type ()->bounds ()->high.kind () == PROP_LOCEXPR
-	    || type->index_type ()->bounds ()->high.kind () == PROP_LOCLIST)
+	if (type->bounds ()->high.kind () == PROP_LOCEXPR
+	    || type->bounds ()->high.kind () == PROP_LOCLIST)
 	  fprintf_filtered (stream, "; variable length");
 	else if (get_array_bounds (type, &low_bound, &high_bound))
 	  fprintf_filtered (stream, "; %s",
diff --git a/gdb/type-stack.c b/gdb/type-stack.c
index fae3216ba65c..f8661d756534 100644
--- a/gdb/type-stack.c
+++ b/gdb/type-stack.c
@@ -172,7 +172,7 @@  type_stack::follow_types (struct type *follow_type)
 	  lookup_array_range_type (follow_type,
 				   0, array_size >= 0 ? array_size - 1 : 0);
 	if (array_size < 0)
-	  follow_type->index_type ()->bounds ()->high.set_undefined ();
+	  follow_type->bounds ()->high.set_undefined ();
 	break;
       case tp_function:
 	/* FIXME-type-allocation: need a way to free this type when we are
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 775c603a8c32..0221bc6e939e 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -191,7 +191,7 @@  value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound
 
   /* Fetch the bit stride and convert it to a byte stride, assuming 8 bits
      in a byte.  */
-  LONGEST stride = array_type->index_type ()->bounds ()->bit_stride ();
+  LONGEST stride = array_type->bit_stride ();
   if (stride != 0)
     {
       struct gdbarch *arch = get_type_arch (elt_type);
@@ -201,7 +201,7 @@  value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound
 
   LONGEST elt_offs = elt_size * (index - lowerbound);
   bool array_upper_bound_undefined
-    = array_type->index_type ()->bounds ()->high.kind () == PROP_UNDEFINED;
+    = array_type->bounds ()->high.kind () == PROP_UNDEFINED;
 
   if (index < lowerbound
       || (!array_upper_bound_undefined
diff --git a/gdb/valops.c b/gdb/valops.c
index cfa0f5415d2e..033fd42036ac 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -388,8 +388,7 @@  value_cast (struct type *type, struct value *arg2)
       struct type *element_type = TYPE_TARGET_TYPE (type);
       unsigned element_length = TYPE_LENGTH (check_typedef (element_type));
 
-      if (element_length > 0
-	  && type->index_type ()->bounds ()->high.kind () == PROP_UNDEFINED)
+      if (element_length > 0 && type->bounds ()->high.kind () == PROP_UNDEFINED)
 	{
 	  struct type *range_type = type->index_type ();
 	  int val_length = TYPE_LENGTH (type2);