mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 17:18:55 +00:00
Handle biased types
In Ada, the programmer can request that a range type with a non-zero base be stored in the minimal number of bits required for the range. This is done by biasing the values; so, for example, a range of -7..-4 may be stored as two bits with a bias of -7. This patch implements this for gdb. It is done by adding a bias to struct range_bounds and then adjusting a few spots to handle this. The test case is written to use -fgnat-encodings=minimal, but a future compiler patch will change the compiler to emit DW_AT_GNU_bias with -fgnat-encodings=gdb. It seemed good to get the gdb patch in first. Tested on x86-64 Fedora 29; plus a variety of targets using AdaCore's internal test suite. gdb/ChangeLog 2019-09-03 Tom Tromey <tromey@adacore.com> * ada-valprint.c (ada_val_print_num): Don't recurse for range types. (has_negatives): Unbias a range type bound. * dwarf2read.c (read_subrange_type): Handle DW_AT_GNU_bias. * gdbtypes.c (operator==): Handle new field. (create_range_type): Add "bias" parameter. (create_static_range_type, resolve_dynamic_range): Update. * gdbtypes.h (struct range_bounds) <bias>: New member. (create_range_type): Add bias parameter. * printcmd.c (print_scalar_formatted): Unbias range types. * value.c (unpack_long): Unbias range types. (pack_long): Bias range types. gdb/testsuite/ChangeLog 2019-09-03 Tom Tromey <tromey@adacore.com> * gdb.ada/bias.exp: New file. * gdb.ada/bias/bias.adb: New file. * gdb.ada/print_chars.exp: Add regression test. * gdb.ada/print_chars/foo.adb (My_Character): New type. (MC): New variable.
This commit is contained in:
@@ -901,7 +901,8 @@ operator== (const range_bounds &l, const range_bounds &r)
|
||||
return (FIELD_EQ (low)
|
||||
&& FIELD_EQ (high)
|
||||
&& FIELD_EQ (flag_upper_bound_is_count)
|
||||
&& FIELD_EQ (flag_bound_evaluated));
|
||||
&& FIELD_EQ (flag_bound_evaluated)
|
||||
&& FIELD_EQ (bias));
|
||||
|
||||
#undef FIELD_EQ
|
||||
}
|
||||
@@ -912,7 +913,8 @@ operator== (const range_bounds &l, const range_bounds &r)
|
||||
struct type *
|
||||
create_range_type (struct type *result_type, struct type *index_type,
|
||||
const struct dynamic_prop *low_bound,
|
||||
const struct dynamic_prop *high_bound)
|
||||
const struct dynamic_prop *high_bound,
|
||||
LONGEST bias)
|
||||
{
|
||||
/* The INDEX_TYPE should be a type capable of holding the upper and lower
|
||||
bounds, as such a zero sized, or void type makes no sense. */
|
||||
@@ -932,6 +934,7 @@ create_range_type (struct type *result_type, struct type *index_type,
|
||||
TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
|
||||
TYPE_RANGE_DATA (result_type)->low = *low_bound;
|
||||
TYPE_RANGE_DATA (result_type)->high = *high_bound;
|
||||
TYPE_RANGE_DATA (result_type)->bias = bias;
|
||||
|
||||
if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0)
|
||||
TYPE_UNSIGNED (result_type) = 1;
|
||||
@@ -968,7 +971,7 @@ create_static_range_type (struct type *result_type, struct type *index_type,
|
||||
high.kind = PROP_CONST;
|
||||
high.data.const_val = high_bound;
|
||||
|
||||
result_type = create_range_type (result_type, index_type, &low, &high);
|
||||
result_type = create_range_type (result_type, index_type, &low, &high, 0);
|
||||
|
||||
return result_type;
|
||||
}
|
||||
@@ -2015,9 +2018,10 @@ resolve_dynamic_range (struct type *dyn_range_type,
|
||||
static_target_type
|
||||
= resolve_dynamic_type_internal (TYPE_TARGET_TYPE (dyn_range_type),
|
||||
addr_stack, 0);
|
||||
LONGEST bias = TYPE_RANGE_DATA (dyn_range_type)->bias;
|
||||
static_range_type = create_range_type (copy_type (dyn_range_type),
|
||||
static_target_type,
|
||||
&low_bound, &high_bound);
|
||||
&low_bound, &high_bound, bias);
|
||||
TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1;
|
||||
return static_range_type;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user