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) <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
This commit is contained in:
Simon Marchi 2020-07-12 23:05:08 -04:00 committed by Simon Marchi
parent 509971ae76
commit cf88be6855
17 changed files with 68 additions and 43 deletions

View 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

View 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)
{

View 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",

View 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;

View 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

View 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
{

View 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;

View 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);
switch (this->code ())
{
case TYPE_CODE_RANGE:
return this->main_type->flds_bnds.bounds;
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. */

View 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 ();

View 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);

View 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"));

View 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;

View 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 ();;

View 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",

View 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

View 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

View 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);