From 5ce19db80f15af66a17acf02e1d831b387220ca7 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 8 Mar 2021 07:27:57 -0700 Subject: [PATCH] Split out ada_ternop_slice This splits TERNOP_SLICE into a new function for future use. gdb/ChangeLog 2021-03-08 Tom Tromey * ada-lang.c (ada_ternop_slice): New function. (ada_evaluate_subexp): Use it. --- gdb/ChangeLog | 5 ++ gdb/ada-lang.c | 153 +++++++++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 70 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0edd02dfd2b..f0c62cf2014 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2021-03-08 Tom Tromey + + * ada-lang.c (ada_ternop_slice): New function. + (ada_evaluate_subexp): Use it. + 2021-03-08 Tom Tromey * ada-lang.c (ada_equal_binop): New function. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 39e8b8535bd..c039183373f 100644 --- a/gdb/ada-lang.c +++ b/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: -- 2.30.2