You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
6.6 KiB
209 lines
6.6 KiB
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 |
|
From: Kevin Buettner <kevinb@redhat.com> |
|
Date: Mon, 24 May 2021 16:53:22 -0700 |
|
Subject: gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch |
|
|
|
;; [fortran] Backport Andrew Burgess's commit which cleans up |
|
;; array/string expression evaluation. |
|
|
|
gdb/fortran: Clean up array/string expression evaluation |
|
|
|
This commit is a refactor of part of the Fortran array and string |
|
handling code. |
|
|
|
The current code is split into two blocks, linked, weirdly, with a |
|
goto. After this commit all the code is moved to its own function, |
|
and arrays and strings are now handled using the same code; this will |
|
be useful later when I want to add array stride support where strings |
|
will want to be treated just like arrays, but is a good clean up even |
|
without the array stride work, which is why I'm merging it now. |
|
|
|
For now the new function is added as a static within eval.c, even |
|
though the function is Fortran only. A following commit will remove |
|
some of the Fortran specific code from eval.c into one of the Fortran |
|
specific files, including this new function. |
|
|
|
There should be no user visible changes after this commit. |
|
|
|
gdb/ChangeLog: |
|
|
|
* eval.c (fortran_value_subarray): New function, content is taken |
|
from... |
|
(evaluate_subexp_standard): ...here, in two places. Now arrays |
|
and strings both call the new function. |
|
(calc_f77_array_dims): Add header comment, handle strings. |
|
|
|
diff --git a/gdb/eval.c b/gdb/eval.c |
|
--- a/gdb/eval.c |
|
+++ b/gdb/eval.c |
|
@@ -1260,6 +1260,67 @@ is_integral_or_integral_reference (struct type *type) |
|
&& is_integral_type (TYPE_TARGET_TYPE (type))); |
|
} |
|
|
|
+/* Called from evaluate_subexp_standard to perform array indexing, and |
|
+ sub-range extraction, for Fortran. As well as arrays this function |
|
+ also handles strings as they can be treated like arrays of characters. |
|
+ ARRAY is the array or string being accessed. EXP, POS, and NOSIDE are |
|
+ as for evaluate_subexp_standard, and NARGS is the number of arguments |
|
+ in this access (e.g. 'array (1,2,3)' would be NARGS 3). */ |
|
+ |
|
+static struct value * |
|
+fortran_value_subarray (struct value *array, struct expression *exp, |
|
+ int *pos, int nargs, enum noside noside) |
|
+{ |
|
+ if (exp->elts[*pos].opcode == OP_RANGE) |
|
+ return value_f90_subarray (array, exp, pos, noside); |
|
+ |
|
+ if (noside == EVAL_SKIP) |
|
+ { |
|
+ skip_undetermined_arglist (nargs, exp, pos, noside); |
|
+ /* Return the dummy value with the correct type. */ |
|
+ return array; |
|
+ } |
|
+ |
|
+ LONGEST subscript_array[MAX_FORTRAN_DIMS]; |
|
+ int ndimensions = 1; |
|
+ struct type *type = check_typedef (value_type (array)); |
|
+ |
|
+ if (nargs > MAX_FORTRAN_DIMS) |
|
+ error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS); |
|
+ |
|
+ ndimensions = calc_f77_array_dims (type); |
|
+ |
|
+ if (nargs != ndimensions) |
|
+ error (_("Wrong number of subscripts")); |
|
+ |
|
+ gdb_assert (nargs > 0); |
|
+ |
|
+ /* Now that we know we have a legal array subscript expression let us |
|
+ actually find out where this element exists in the array. */ |
|
+ |
|
+ /* Take array indices left to right. */ |
|
+ for (int i = 0; i < nargs; i++) |
|
+ { |
|
+ /* Evaluate each subscript; it must be a legal integer in F77. */ |
|
+ value *arg2 = evaluate_subexp_with_coercion (exp, pos, noside); |
|
+ |
|
+ /* Fill in the subscript array. */ |
|
+ subscript_array[i] = value_as_long (arg2); |
|
+ } |
|
+ |
|
+ /* Internal type of array is arranged right to left. */ |
|
+ for (int i = nargs; i > 0; i--) |
|
+ { |
|
+ struct type *array_type = check_typedef (value_type (array)); |
|
+ LONGEST index = subscript_array[i - 1]; |
|
+ |
|
+ array = value_subscripted_rvalue (array, index, |
|
+ f77_get_lowerbound (array_type)); |
|
+ } |
|
+ |
|
+ return array; |
|
+} |
|
+ |
|
struct value * |
|
evaluate_subexp_standard (struct type *expect_type, |
|
struct expression *exp, int *pos, |
|
@@ -1953,33 +2014,8 @@ evaluate_subexp_standard (struct type *expect_type, |
|
switch (code) |
|
{ |
|
case TYPE_CODE_ARRAY: |
|
- if (exp->elts[*pos].opcode == OP_RANGE) |
|
- return value_f90_subarray (arg1, exp, pos, noside); |
|
- else |
|
- { |
|
- if (noside == EVAL_SKIP) |
|
- { |
|
- skip_undetermined_arglist (nargs, exp, pos, noside); |
|
- /* Return the dummy value with the correct type. */ |
|
- return arg1; |
|
- } |
|
- goto multi_f77_subscript; |
|
- } |
|
- |
|
case TYPE_CODE_STRING: |
|
- if (exp->elts[*pos].opcode == OP_RANGE) |
|
- return value_f90_subarray (arg1, exp, pos, noside); |
|
- else |
|
- { |
|
- if (noside == EVAL_SKIP) |
|
- { |
|
- skip_undetermined_arglist (nargs, exp, pos, noside); |
|
- /* Return the dummy value with the correct type. */ |
|
- return arg1; |
|
- } |
|
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside); |
|
- return value_subscript (arg1, value_as_long (arg2)); |
|
- } |
|
+ return fortran_value_subarray (arg1, exp, pos, nargs, noside); |
|
|
|
case TYPE_CODE_PTR: |
|
case TYPE_CODE_FUNC: |
|
@@ -2400,49 +2436,6 @@ evaluate_subexp_standard (struct type *expect_type, |
|
} |
|
return (arg1); |
|
|
|
- multi_f77_subscript: |
|
- { |
|
- LONGEST subscript_array[MAX_FORTRAN_DIMS]; |
|
- int ndimensions = 1, i; |
|
- struct value *array = arg1; |
|
- |
|
- if (nargs > MAX_FORTRAN_DIMS) |
|
- error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS); |
|
- |
|
- ndimensions = calc_f77_array_dims (type); |
|
- |
|
- if (nargs != ndimensions) |
|
- error (_("Wrong number of subscripts")); |
|
- |
|
- gdb_assert (nargs > 0); |
|
- |
|
- /* Now that we know we have a legal array subscript expression |
|
- let us actually find out where this element exists in the array. */ |
|
- |
|
- /* Take array indices left to right. */ |
|
- for (i = 0; i < nargs; i++) |
|
- { |
|
- /* Evaluate each subscript; it must be a legal integer in F77. */ |
|
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside); |
|
- |
|
- /* Fill in the subscript array. */ |
|
- |
|
- subscript_array[i] = value_as_long (arg2); |
|
- } |
|
- |
|
- /* Internal type of array is arranged right to left. */ |
|
- for (i = nargs; i > 0; i--) |
|
- { |
|
- struct type *array_type = check_typedef (value_type (array)); |
|
- LONGEST index = subscript_array[i - 1]; |
|
- |
|
- array = value_subscripted_rvalue (array, index, |
|
- f77_get_lowerbound (array_type)); |
|
- } |
|
- |
|
- return array; |
|
- } |
|
- |
|
case BINOP_LOGICAL_AND: |
|
arg1 = evaluate_subexp (nullptr, exp, pos, noside); |
|
if (noside == EVAL_SKIP) |
|
@@ -3354,12 +3347,17 @@ parse_and_eval_type (char *p, int length) |
|
return expr->elts[1].type; |
|
} |
|
|
|
+/* Return the number of dimensions for a Fortran array or string. */ |
|
+ |
|
int |
|
calc_f77_array_dims (struct type *array_type) |
|
{ |
|
int ndimen = 1; |
|
struct type *tmp_type; |
|
|
|
+ if ((array_type->code () == TYPE_CODE_STRING)) |
|
+ return 1; |
|
+ |
|
if ((array_type->code () != TYPE_CODE_ARRAY)) |
|
error (_("Can't get dimensions for a non-array type")); |
|
|
|
|