524607bcfa
Resolves: rhbz#1971746
210 lines
6.6 KiB
Diff
210 lines
6.6 KiB
Diff
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"));
|
|
|