mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-01 11:59:27 +08:00
Split out ada_ternop_slice
This splits TERNOP_SLICE into a new function for future use. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * ada-lang.c (ada_ternop_slice): New function. (ada_evaluate_subexp): Use it.
This commit is contained in:
153
gdb/ada-lang.c
153
gdb/ada-lang.c
@ -10107,6 +10107,87 @@ ada_equal_binop (struct type *expect_type,
|
||||
return value_from_longest (type, (LONGEST) tem);
|
||||
}
|
||||
|
||||
/* A helper function for TERNOP_SLICE. */
|
||||
|
||||
static value *
|
||||
ada_ternop_slice (struct expression *exp,
|
||||
enum noside noside,
|
||||
struct value *array, struct value *low_bound_val,
|
||||
struct value *high_bound_val)
|
||||
{
|
||||
LONGEST low_bound;
|
||||
LONGEST high_bound;
|
||||
|
||||
low_bound_val = coerce_ref (low_bound_val);
|
||||
high_bound_val = coerce_ref (high_bound_val);
|
||||
low_bound = value_as_long (low_bound_val);
|
||||
high_bound = value_as_long (high_bound_val);
|
||||
|
||||
/* If this is a reference to an aligner type, then remove all
|
||||
the aligners. */
|
||||
if (value_type (array)->code () == TYPE_CODE_REF
|
||||
&& ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array))))
|
||||
TYPE_TARGET_TYPE (value_type (array)) =
|
||||
ada_aligned_type (TYPE_TARGET_TYPE (value_type (array)));
|
||||
|
||||
if (ada_is_any_packed_array_type (value_type (array)))
|
||||
error (_("cannot slice a packed array"));
|
||||
|
||||
/* If this is a reference to an array or an array lvalue,
|
||||
convert to a pointer. */
|
||||
if (value_type (array)->code () == TYPE_CODE_REF
|
||||
|| (value_type (array)->code () == TYPE_CODE_ARRAY
|
||||
&& VALUE_LVAL (array) == lval_memory))
|
||||
array = value_addr (array);
|
||||
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS
|
||||
&& ada_is_array_descriptor_type (ada_check_typedef
|
||||
(value_type (array))))
|
||||
return empty_array (ada_type_of_array (array, 0), low_bound,
|
||||
high_bound);
|
||||
|
||||
array = ada_coerce_to_simple_array_ptr (array);
|
||||
|
||||
/* If we have more than one level of pointer indirection,
|
||||
dereference the value until we get only one level. */
|
||||
while (value_type (array)->code () == TYPE_CODE_PTR
|
||||
&& (TYPE_TARGET_TYPE (value_type (array))->code ()
|
||||
== TYPE_CODE_PTR))
|
||||
array = value_ind (array);
|
||||
|
||||
/* Make sure we really do have an array type before going further,
|
||||
to avoid a SEGV when trying to get the index type or the target
|
||||
type later down the road if the debug info generated by
|
||||
the compiler is incorrect or incomplete. */
|
||||
if (!ada_is_simple_array_type (value_type (array)))
|
||||
error (_("cannot take slice of non-array"));
|
||||
|
||||
if (ada_check_typedef (value_type (array))->code ()
|
||||
== TYPE_CODE_PTR)
|
||||
{
|
||||
struct type *type0 = ada_check_typedef (value_type (array));
|
||||
|
||||
if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound);
|
||||
else
|
||||
{
|
||||
struct type *arr_type0 =
|
||||
to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1);
|
||||
|
||||
return ada_value_slice_from_ptr (array, arr_type0,
|
||||
longest_to_int (low_bound),
|
||||
longest_to_int (high_bound));
|
||||
}
|
||||
}
|
||||
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return array;
|
||||
else if (high_bound < low_bound)
|
||||
return empty_array (value_type (array), low_bound, high_bound);
|
||||
else
|
||||
return ada_value_slice (array, longest_to_int (low_bound),
|
||||
longest_to_int (high_bound));
|
||||
}
|
||||
|
||||
/* Implement the evaluate_exp routine in the exp_descriptor structure
|
||||
for the Ada language. */
|
||||
|
||||
@ -10548,80 +10629,12 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
|
||||
= evaluate_subexp (nullptr, exp, pos, noside);
|
||||
struct value *high_bound_val
|
||||
= evaluate_subexp (nullptr, exp, pos, noside);
|
||||
LONGEST low_bound;
|
||||
LONGEST high_bound;
|
||||
|
||||
low_bound_val = coerce_ref (low_bound_val);
|
||||
high_bound_val = coerce_ref (high_bound_val);
|
||||
low_bound = value_as_long (low_bound_val);
|
||||
high_bound = value_as_long (high_bound_val);
|
||||
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
|
||||
/* If this is a reference to an aligner type, then remove all
|
||||
the aligners. */
|
||||
if (value_type (array)->code () == TYPE_CODE_REF
|
||||
&& ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array))))
|
||||
TYPE_TARGET_TYPE (value_type (array)) =
|
||||
ada_aligned_type (TYPE_TARGET_TYPE (value_type (array)));
|
||||
|
||||
if (ada_is_any_packed_array_type (value_type (array)))
|
||||
error (_("cannot slice a packed array"));
|
||||
|
||||
/* If this is a reference to an array or an array lvalue,
|
||||
convert to a pointer. */
|
||||
if (value_type (array)->code () == TYPE_CODE_REF
|
||||
|| (value_type (array)->code () == TYPE_CODE_ARRAY
|
||||
&& VALUE_LVAL (array) == lval_memory))
|
||||
array = value_addr (array);
|
||||
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS
|
||||
&& ada_is_array_descriptor_type (ada_check_typedef
|
||||
(value_type (array))))
|
||||
return empty_array (ada_type_of_array (array, 0), low_bound,
|
||||
high_bound);
|
||||
|
||||
array = ada_coerce_to_simple_array_ptr (array);
|
||||
|
||||
/* If we have more than one level of pointer indirection,
|
||||
dereference the value until we get only one level. */
|
||||
while (value_type (array)->code () == TYPE_CODE_PTR
|
||||
&& (TYPE_TARGET_TYPE (value_type (array))->code ()
|
||||
== TYPE_CODE_PTR))
|
||||
array = value_ind (array);
|
||||
|
||||
/* Make sure we really do have an array type before going further,
|
||||
to avoid a SEGV when trying to get the index type or the target
|
||||
type later down the road if the debug info generated by
|
||||
the compiler is incorrect or incomplete. */
|
||||
if (!ada_is_simple_array_type (value_type (array)))
|
||||
error (_("cannot take slice of non-array"));
|
||||
|
||||
if (ada_check_typedef (value_type (array))->code ()
|
||||
== TYPE_CODE_PTR)
|
||||
{
|
||||
struct type *type0 = ada_check_typedef (value_type (array));
|
||||
|
||||
if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound);
|
||||
else
|
||||
{
|
||||
struct type *arr_type0 =
|
||||
to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1);
|
||||
|
||||
return ada_value_slice_from_ptr (array, arr_type0,
|
||||
longest_to_int (low_bound),
|
||||
longest_to_int (high_bound));
|
||||
}
|
||||
}
|
||||
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return array;
|
||||
else if (high_bound < low_bound)
|
||||
return empty_array (value_type (array), low_bound, high_bound);
|
||||
else
|
||||
return ada_value_slice (array, longest_to_int (low_bound),
|
||||
longest_to_int (high_bound));
|
||||
return ada_ternop_slice (exp, noside, array, low_bound_val,
|
||||
high_bound_val);
|
||||
}
|
||||
|
||||
case UNOP_IN_RANGE:
|
||||
|
Reference in New Issue
Block a user