aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2020-10-08 16:34:58 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2020-10-22 09:24:43 +0100
commit6b4c676cc7f48f656cf235dd0507c41ab11d7cb5 (patch)
tree2aaee877ea0ddba4b3c99541a394833252b44b6d
parentf2d8e4c59770975415585af20b3d4249ff57b36e (diff)
downloadgdb-6b4c676cc7f48f656cf235dd0507c41ab11d7cb5.zip
gdb-6b4c676cc7f48f656cf235dd0507c41ab11d7cb5.tar.gz
gdb-6b4c676cc7f48f656cf235dd0507c41ab11d7cb5.tar.bz2
gdb/fortran: add support for parsing array strides in expressions
With this commit GDB now understands the syntax of Fortran array strides, a user can type an expression including an array stride, but they will only get an error informing them that array strides are not supported. This alone is an improvement on what we had before in GDB, better to give the user a helpful message that a particular feature is not supported than to just claim a syntax error. Before: (gdb) p array (1:10:2, 2:10:2) A syntax error in expression, near `:2, 2:10:2)'. Now: (gdb) p array (1:10:2, 2:10:2) Fortran array strides are not currently supported Later commits will allow GDB to handle array strides correctly. gdb/ChangeLog: * expprint.c (dump_subexp_body_standard): Print RANGE_HAS_STRIDE. * expression.h (enum range_type): Add RANGE_HAS_STRIDE. * f-exp.y (arglist): Allow for a series of subranges. (subrange): Add cases for subranges with strides. * f-lang.c (value_f90_subarray): Catch use of array strides and throw an error. * parse.c (operator_length_standard): Handle RANGE_HAS_STRIDE. gdb/testsuite/ChangeLog: * gdb.fortran/array-slices.exp: Add a new test.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/expprint.c4
-rw-r--r--gdb/expression.h3
-rw-r--r--gdb/f-exp.y36
-rw-r--r--gdb/f-lang.c10
-rw-r--r--gdb/parse.c2
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.fortran/array-slices.exp16
8 files changed, 84 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d67de7c..bf93e1b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2020-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
+ * expprint.c (dump_subexp_body_standard): Print RANGE_HAS_STRIDE.
+ * expression.h (enum range_type): Add RANGE_HAS_STRIDE.
+ * f-exp.y (arglist): Allow for a series of subranges.
+ (subrange): Add cases for subranges with strides.
+ * f-lang.c (value_f90_subarray): Catch use of array strides and
+ throw an error.
+ * parse.c (operator_length_standard): Handle RANGE_HAS_STRIDE.
+
+2020-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
+
* expprint.c (print_subexp_standard): Change enum range_type to
range_flag and rename variables to match.
(dump_subexp_body_standard): Likewise.
diff --git a/gdb/expprint.c b/gdb/expprint.c
index 2dee2bb..a14eeb0 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -1120,12 +1120,16 @@ dump_subexp_body_standard (struct expression *exp,
fputs_filtered ("..", stream);
if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
fputs_filtered ("EXP", stream);
+ if (range_flag & RANGE_HAS_STRIDE)
+ fputs_filtered (":EXP", stream);
fputs_filtered ("'", stream);
if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
elt = dump_subexp (exp, stream, elt);
if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
elt = dump_subexp (exp, stream, elt);
+ if (range_flag & RANGE_HAS_STRIDE)
+ elt = dump_subexp (exp, stream, elt);
}
break;
diff --git a/gdb/expression.h b/gdb/expression.h
index fd483e5..8de7123 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -199,6 +199,9 @@ enum range_flag : unsigned
/* The high bound of this range is exclusive. */
RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
+
+ /* The range has a stride. */
+ RANGE_HAS_STRIDE = 1 << 3,
};
DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index a331408..eaa7214 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -284,6 +284,10 @@ arglist : arglist ',' exp %prec ABOVE_COMMA
{ pstate->arglist_len++; }
;
+arglist : arglist ',' subrange %prec ABOVE_COMMA
+ { pstate->arglist_len++; }
+ ;
+
/* There are four sorts of subrange types in F90. */
subrange: exp ':' exp %prec ABOVE_COMMA
@@ -314,6 +318,38 @@ subrange: ':' %prec ABOVE_COMMA
write_exp_elt_opcode (pstate, OP_RANGE); }
;
+/* And each of the four subrange types can also have a stride. */
+subrange: exp ':' exp ':' exp %prec ABOVE_COMMA
+ { write_exp_elt_opcode (pstate, OP_RANGE);
+ write_exp_elt_longcst (pstate, RANGE_HAS_STRIDE);
+ write_exp_elt_opcode (pstate, OP_RANGE); }
+ ;
+
+subrange: exp ':' ':' exp %prec ABOVE_COMMA
+ { write_exp_elt_opcode (pstate, OP_RANGE);
+ write_exp_elt_longcst (pstate,
+ (RANGE_HIGH_BOUND_DEFAULT
+ | RANGE_HAS_STRIDE));
+ write_exp_elt_opcode (pstate, OP_RANGE); }
+ ;
+
+subrange: ':' exp ':' exp %prec ABOVE_COMMA
+ { write_exp_elt_opcode (pstate, OP_RANGE);
+ write_exp_elt_longcst (pstate,
+ (RANGE_LOW_BOUND_DEFAULT
+ | RANGE_HAS_STRIDE));
+ write_exp_elt_opcode (pstate, OP_RANGE); }
+ ;
+
+subrange: ':' ':' exp %prec ABOVE_COMMA
+ { write_exp_elt_opcode (pstate, OP_RANGE);
+ write_exp_elt_longcst (pstate,
+ (RANGE_LOW_BOUND_DEFAULT
+ | RANGE_HIGH_BOUND_DEFAULT
+ | RANGE_HAS_STRIDE));
+ write_exp_elt_opcode (pstate, OP_RANGE); }
+ ;
+
complexnum: exp ',' exp
{ }
;
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 37d05b2..f7c54b4 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -124,7 +124,7 @@ value_f90_subarray (struct value *array,
struct expression *exp, int *pos, enum noside noside)
{
int pc = (*pos) + 1;
- LONGEST low_bound, high_bound;
+ LONGEST low_bound, high_bound, stride;
struct type *range = check_typedef (value_type (array)->index_type ());
enum range_flag range_flag
= (enum range_flag) longest_to_int (exp->elts[pc].longconst);
@@ -141,6 +141,14 @@ value_f90_subarray (struct value *array,
else
high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
+ if (range_flag & RANGE_HAS_STRIDE)
+ stride = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
+ else
+ stride = 1;
+
+ if (stride != 1)
+ error (_("Fortran array strides are not currently supported"));
+
return value_slice (array, low_bound, high_bound - low_bound + 1);
}
diff --git a/gdb/parse.c b/gdb/parse.c
index 4a15de8..359ab62 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -924,6 +924,8 @@ operator_length_standard (const struct expression *expr, int endpos,
/* Assume the range has 2 arguments (low bound and high bound), then
reduce the argument count if any bounds are set to default. */
args = 2;
+ if (range_flag & RANGE_HAS_STRIDE)
+ ++args;
if (range_flag & RANGE_LOW_BOUND_DEFAULT)
--args;
if (range_flag & RANGE_HIGH_BOUND_DEFAULT)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 4061d17..19b423b 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdb.fortran/array-slices.exp: Add a new test.
+
2020-10-21 Gary Benson <gbenson@redhat.com>
* gdb.mi/mi-fullname-deleted.exp: Fix substituted
diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp
index 31f95a3..aa6bc63 100644
--- a/gdb/testsuite/gdb.fortran/array-slices.exp
+++ b/gdb/testsuite/gdb.fortran/array-slices.exp
@@ -69,3 +69,19 @@ foreach result $array_contents msg $message_strings {
}
gdb_continue_to_breakpoint "continue to Final Breakpoint"
+
+# Next test that asking for an array with stride at the CLI gives an
+# error.
+clean_restart ${testfile}
+
+if ![fortran_runto_main] then {
+ perror "couldn't run to main"
+ continue
+}
+
+gdb_breakpoint "show"
+gdb_continue_to_breakpoint "show"
+gdb_test "up" ".*"
+gdb_test "p array (1:10:2, 1:10:2)" \
+ "Fortran array strides are not currently supported" \
+ "using array stride gives an error"