gdb: make type::bounds work for array and string types
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 13 Jul 2020 03:05:08 +0000 (23:05 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Mon, 13 Jul 2020 03:06:12 +0000 (23:06 -0400)
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.

gdb/ChangeLog:

* gdbtypes.h (struct type) <bounds>: Handle array and string
types.
* ada-lang.c (assign_aggregate): Use type::bounds on
array/string type.
* c-typeprint.c (c_type_print_varspec_suffix): Likewise.
* c-varobj.c (c_number_of_children): Likewise.
(c_describe_child): Likewise.
* eval.c (evaluate_subexp_for_sizeof): Likewise.
* f-typeprint.c (f_type_print_varspec_suffix): Likewise.
(f_type_print_base): Likewise.
* f-valprint.c (f77_array_offset_tbl): Likewise.
(f77_get_upperbound): Likewise.
(f77_print_array_1): Likewise.
* guile/scm-type.c (gdbscm_type_range): Likewise.
* m2-typeprint.c (m2_array): Likewise.
(m2_is_long_set_of_type): Likewise.
* m2-valprint.c (get_long_set_bounds): Likewise.
* p-typeprint.c (pascal_type_print_varspec_prefix): Likewise.
* python/py-type.c (typy_range): Likewise.
* rust-lang.c (rust_internal_print_type): Likewise.
* type-stack.c (type_stack::follow_types): Likewise.
* valarith.c (value_subscripted_rvalue): Likewise.
* valops.c (value_cast): Likewise.

Change-Id: I5c0c08930bffe42fd69cb4bfcece28944dd88d1f

17 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/c-typeprint.c
gdb/c-varobj.c
gdb/eval.c
gdb/f-typeprint.c
gdb/f-valprint.c
gdb/gdbtypes.h
gdb/guile/scm-type.c
gdb/m2-typeprint.c
gdb/m2-valprint.c
gdb/p-typeprint.c
gdb/python/py-type.c
gdb/rust-lang.c
gdb/type-stack.c
gdb/valarith.c
gdb/valops.c

index 0d54f5eb7292411f18ed7ad908699c3cda473f82..57b37b8872b95956e86786ef0172996b14a3014b 100644 (file)
@@ -1,3 +1,29 @@
+2020-07-12  Simon Marchi  <simon.marchi@efficios.com>
+
+       * gdbtypes.h (struct type) <bounds>: Handle array and string
+       types.
+       * ada-lang.c (assign_aggregate): Use type::bounds on
+       array/string type.
+       * c-typeprint.c (c_type_print_varspec_suffix): Likewise.
+       * c-varobj.c (c_number_of_children): Likewise.
+       (c_describe_child): Likewise.
+       * eval.c (evaluate_subexp_for_sizeof): Likewise.
+       * f-typeprint.c (f_type_print_varspec_suffix): Likewise.
+       (f_type_print_base): Likewise.
+       * f-valprint.c (f77_array_offset_tbl): Likewise.
+       (f77_get_upperbound): Likewise.
+       (f77_print_array_1): Likewise.
+       * guile/scm-type.c (gdbscm_type_range): Likewise.
+       * m2-typeprint.c (m2_array): Likewise.
+       (m2_is_long_set_of_type): Likewise.
+       * m2-valprint.c (get_long_set_bounds): Likewise.
+       * p-typeprint.c (pascal_type_print_varspec_prefix): Likewise.
+       * python/py-type.c (typy_range): Likewise.
+       * rust-lang.c (rust_internal_print_type): Likewise.
+       * type-stack.c (type_stack::follow_types): Likewise.
+       * valarith.c (value_subscripted_rvalue): Likewise.
+       * valops.c (value_cast): Likewise.
+
 2020-07-12  Simon Marchi  <simon.marchi@efficios.com>
 
        * gdbtypes.c (TYPE_ARRAY_BIT_STRIDE): Remove.  Update all
index 3d85a5a014d4692973b0f7b09d8d10651109e0c8..8b437a2a9cdc2382f80f9c81071e71afcb0be4cf 100644 (file)
@@ -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)
     {
index 9e408e15a1e2315148d8766ab4b1ad1aa89c027e..91d9ef8209e8ada82e646fe4677bff2f582f9fa2 100644 (file)
@@ -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", 
index 2bcfe8672eb712dabc3c481aa6a935b84114dfc9..56354e5f06656a6f280a744a0cdc51192a982664 100644 (file)
@@ -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;
index dacd46da44fa303a32b830a901c0b6611788d441..c62c35f31835e33cd7d817aa921d7cdce0ebee8b 100644 (file)
@@ -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
index df83a481386a4e28a7a0f72240883d203046d0d6..80dbfe1116742aada78cd02d22d3e0dfcac45ca9 100644 (file)
@@ -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
        {
index 17e15f9bdff651ae6d17e4bcb9475af211af1652..fabdf4586168d17dc4dc944ce14bc9e194fa2f6b 100644 (file)
@@ -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;
index d8ddc41613914a78064b0165e4737ac68276bfb9..eaa4cff608d7754f1c2cc4aeb1a299bd0b57496d 100644 (file)
@@ -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.  */
index fe6f493aa7f5cfffad2995dda8dddc9eaf5d26b6..19b7996c9467a301a0eb30cba719bee02cc2c651 100644 (file)
@@ -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 ();
index 474e58725c7f58e7292359bdcf401feb9f4f16d6..521d9260322ad8cb806e389966ea2c45450a9ab4 100644 (file)
@@ -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);
index 175c53adacfa426da4e3c51341ad1f909cc63345..b0a3ce3ec3e072af7acf2db2632640c743e365d6 100644 (file)
@@ -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"));
index d52358aa4bb4526c18135eca1cceeea92ddd2dc5..7842b63081c73cf5bbc329f2da5adfcf1954c3e5 100644 (file)
@@ -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;
 
index e99ee415e2f921a16802f1518da59cd8a112b868..d0dfb52811b272d22013dccb6e0bda8844b5f441 100644 (file)
@@ -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 ();;
index cedb15f555d3d64a8ef02c2b133dd6c7f4a3a4a0..ddd4b57d29442f9702eecc9c058b009115fedd32 100644 (file)
@@ -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",
index fae3216ba65c2c78ac4c7689322435b958962685..f8661d756534ff5187b3dee371cd58fbb52cf311 100644 (file)
@@ -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
index 775c603a8c32b4559e37869681ca0d4c31a34af2..0221bc6e939e6e18ef485deec27719a8257910c4 100644 (file)
@@ -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
index cfa0f5415d2e6c6f4c8d998bbda74c42d9c734d0..033fd42036ac0692ef4ceb14d19d3389090a8738 100644 (file)
@@ -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);