mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
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:
parent
509971ae76
commit
cf88be6855
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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 ();
|
||||
|
@ -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);
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 ();;
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user