From cf88be6855e5bb3d43e1fd78f28aeb2ec5fc11a1 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Sun, 12 Jul 2020 23:05:08 -0400 Subject: [PATCH] gdb: make type::bounds work for array and string types 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) : 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 --- gdb/ChangeLog | 26 ++++++++++++++++++++++++++ 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 +-- 17 files changed, 69 insertions(+), 44 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0d54f5eb729..57b37b8872b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,29 @@ +2020-07-12 Simon Marchi + + * gdbtypes.h (struct type) : 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 * gdbtypes.c (TYPE_ARRAY_BIT_STRIDE): Remove. Update all diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 3d85a5a014d..8b437a2a9cd 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 9e408e15a1e..91d9ef8209e 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 2bcfe8672eb..56354e5f066 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 dacd46da44f..c62c35f3183 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 df83a481386..80dbfe11167 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 17e15f9bdff..fabdf458616 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 d8ddc416139..eaa4cff608d 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 fe6f493aa7f..19b7996c946 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 474e58725c7..521d9260322 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 175c53adacf..b0a3ce3ec3e 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 d52358aa4bb..7842b63081c 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 e99ee415e2f..d0dfb52811b 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 cedb15f555d..ddd4b57d294 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 fae3216ba65..f8661d75653 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 775c603a8c3..0221bc6e939 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 cfa0f5415d2..033fd42036a 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); -- 2.30.2