http://sourceware.org/ml/gdb-patches/2016-02/msg00845.html Subject: [PATCH v2 3/6] fortran: change subrange enum to bit field From: Christoph Weinmann Change Fortran subrange enum for subrange expressions to represent a bitfield for easier manipulation. Consequently also change occurences and evaluation of said enum. The behaviour of GDB is unchanged. 2013-11-27 Christoph Weinmann * eval.c (value_f90_subarray): Change evaluation of the subarray boundaries. Set boundaries to be either user provided (bit in f90_range_type was set) or take the default value if the boundary was not provided by the user. * f-exp.y (subrange): Change rules for subrange expressions to write the relevant bit sequence onto the elt stack. * f-lang.h (f90_range_type): Change the enum to use bit values for each boundary, if set by the user. * parse.c (operator_length_standard): In case of OP_F90_RANGE change the calculation of the number of arguments on the elt stack, depending on the number of boundaries provided by the user. Signed-off-by: Christoph Weinmann --- gdb/eval.c | 14 ++++++-------- gdb/f-exp.y | 11 ++++++----- gdb/f-lang.h | 6 ++---- gdb/parse.c | 21 ++++++++------------- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/gdb/eval.c b/gdb/eval.c index 164d7ab..9b8b051 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -480,12 +480,12 @@ value_f90_subarray (struct value *array, struct expression *exp, /* If a lower bound was provided by the user, the bit has been set and we can assign the value from the elt stack. Same for upper bound. */ - if ((range->f90_range_type == HIGH_BOUND_DEFAULT) - || range->f90_range_type == NONE_BOUND_DEFAULT) + if ((range->f90_range_type & SUBARRAY_LOW_BOUND) + == SUBARRAY_LOW_BOUND) range->low = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); - if ((range->f90_range_type == LOW_BOUND_DEFAULT) - || range->f90_range_type == NONE_BOUND_DEFAULT) + if ((range->f90_range_type & SUBARRAY_HIGH_BOUND) + == SUBARRAY_HIGH_BOUND) range->high = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); } @@ -526,12 +526,10 @@ value_f90_subarray (struct value *array, struct expression *exp, /* If no lower bound was provided by the user, we take the default boundary. Same for the high bound. */ - if ((range->f90_range_type == LOW_BOUND_DEFAULT) - || (range->f90_range_type == BOTH_BOUND_DEFAULT)) + if ((range->f90_range_type & SUBARRAY_LOW_BOUND) == 0) range->low = TYPE_LOW_BOUND (index_type); - if ((range->f90_range_type == HIGH_BOUND_DEFAULT) - || (range->f90_range_type == BOTH_BOUND_DEFAULT)) + if ((range->f90_range_type & SUBARRAY_HIGH_BOUND) == 0) range->high = TYPE_HIGH_BOUND (index_type); /* Both user provided low and high bound have to be inside the diff --git a/gdb/f-exp.y b/gdb/f-exp.y index 9343abb..b1206de 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -315,26 +315,27 @@ arglist : arglist ',' exp %prec ABOVE_COMMA /* There are four sorts of subrange types in F90. */ subrange: exp ':' exp %prec ABOVE_COMMA - { write_exp_elt_opcode (pstate, OP_F90_RANGE); - write_exp_elt_longcst (pstate, NONE_BOUND_DEFAULT); + { write_exp_elt_opcode (pstate, OP_F90_RANGE); + write_exp_elt_longcst (pstate, + SUBARRAY_LOW_BOUND | SUBARRAY_HIGH_BOUND); write_exp_elt_opcode (pstate, OP_F90_RANGE); } ; subrange: exp ':' %prec ABOVE_COMMA { write_exp_elt_opcode (pstate, OP_F90_RANGE); - write_exp_elt_longcst (pstate, HIGH_BOUND_DEFAULT); + write_exp_elt_longcst (pstate, SUBARRAY_LOW_BOUND); write_exp_elt_opcode (pstate, OP_F90_RANGE); } ; subrange: ':' exp %prec ABOVE_COMMA { write_exp_elt_opcode (pstate, OP_F90_RANGE); - write_exp_elt_longcst (pstate, LOW_BOUND_DEFAULT); + write_exp_elt_longcst (pstate, SUBARRAY_HIGH_BOUND); write_exp_elt_opcode (pstate, OP_F90_RANGE); } ; subrange: ':' %prec ABOVE_COMMA { write_exp_elt_opcode (pstate, OP_F90_RANGE); - write_exp_elt_longcst (pstate, BOTH_BOUND_DEFAULT); + write_exp_elt_longcst (pstate, 0); write_exp_elt_opcode (pstate, OP_F90_RANGE); } ; diff --git a/gdb/f-lang.h b/gdb/f-lang.h index eeca107..4d56bf7 100644 --- a/gdb/f-lang.h +++ b/gdb/f-lang.h @@ -44,10 +44,8 @@ extern void f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, enum f90_range_type { - BOTH_BOUND_DEFAULT, /* "(:)" */ - LOW_BOUND_DEFAULT, /* "(:high)" */ - HIGH_BOUND_DEFAULT, /* "(low:)" */ - NONE_BOUND_DEFAULT /* "(low:high)" */ + SUBARRAY_LOW_BOUND = 0x1, /* "(low:)" */ + SUBARRAY_HIGH_BOUND = 0x2 /* "(:high)" */ }; /* A common block. */ diff --git a/gdb/parse.c b/gdb/parse.c index 4191fc6..d500279 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1006,22 +1006,17 @@ operator_length_standard (const struct expression *expr, int endpos, case OP_F90_RANGE: oplen = 3; + args = 0; range_type = (enum f90_range_type) longest_to_int (expr->elts[endpos - 2].longconst); - switch (range_type) - { - case LOW_BOUND_DEFAULT: - case HIGH_BOUND_DEFAULT: - args = 1; - break; - case BOTH_BOUND_DEFAULT: - args = 0; - break; - case NONE_BOUND_DEFAULT: - args = 2; - break; - } + /* Increment the argument counter for each argument + provided by the user. */ + if ((range_type & SUBARRAY_LOW_BOUND) == SUBARRAY_LOW_BOUND) + args++; + + if ((range_type & SUBARRAY_HIGH_BOUND) == SUBARRAY_HIGH_BOUND) + args++; break; -- 2.5.0