diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-04-01 21:01:09 +0100 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-04-30 10:09:27 +0100 |
commit | 83228e93efa82f84a132f7cec44d0e760d4ad22b (patch) | |
tree | dbfdc49164342ae98d9bc119c5f5ea2d952181f0 /gdb/f-lang.c | |
parent | 6fdcd7cc87a5e345a1c09fcf898012d80eb43ee1 (diff) | |
download | binutils-gdb-83228e93efa82f84a132f7cec44d0e760d4ad22b.tar.gz |
gdb/fortran: Introduce fortran-operator.def file
Future commits will add more Fortran specific expression operators.
In preparation for these new operators, this commit adds a new
fortran-operator.def file similar to how GDB already has
ada-operator.def.
I've moved UNOP_KIND the Fortran specific operator I introduced in
commit 4d00f5d8f6c4 into this file, and renamed it to make it clearer
that the operator is Fortran specific. I've then updated the Fortran
exp_descriptor table (exp_descriptor_f) to use entirely Fortran
specific functions that now handle UNOP_FORTRAN_KIND (the new name for
UNOP_KIND).
There should be no visible changes for standard users after this
commit, though for developers, the output when 'set debug expression
1' is now better, before:
(gdb) p kind (l1)
Dump of expression @ 0x2ccc7a0, before conversion to prefix form:
Language fortran, 5 elements, 16 bytes each.
Index Opcode Hex Value String Value
0 OP_VAR_VALUE 42 *...............
1 OP_NULL 47730176 .N..............
2 BINOP_INTDIV 47729184 J..............
3 OP_VAR_VALUE 42 *...............
4 UNOP_KIND 78 N...............
Dump of expression @ 0x2ccc7a0, after conversion to prefix form:
Expression: `Invalid expression
(gdb)
and after:
(gdb) p kind (l1)
Dump of expression @ 0x294d0b0, before conversion to prefix form:
Language fortran, 5 elements, 16 bytes each.
Index Opcode Hex Value String Value
0 OP_VAR_VALUE 40 (...............
1 unknown opcode: 224 44088544 ................
2 unknown opcode: 208 44087504 ................
3 OP_VAR_VALUE 40 (...............
4 UNOP_FORTRAN_KIND 119 w...............
Dump of expression @ 0x294d0b0, after conversion to prefix form:
Expression: `KIND(test::l1)'
Language fortran, 5 elements, 16 bytes each.
0 UNOP_FORTRAN_KIND
1 OP_VAR_VALUE Block @0x2a0bce0, symbol @0x2a0b8d0 (l1)
$1 = 1
(gdb)
gdb/ChangeLog:
* gdb/expprint.c (dump_subexp_body_standard): Remove use of
UNOP_KIND.
* gdb/expression.h (exp_opcode): Include 'fortran-operator.def'.
* gdb/f-exp.y (exp): Rename UNOP_KIND to UNOP_FORTRAN_KIND.
* gdb/f-lang.c (evaluate_subexp_f): Likewise.
(operator_length_f): New fuction.
(print_subexp_f): New function.
(op_name_f): New function.
(dump_subexp_body_f): New function.
(operator_check_f): New function.
(exp_descriptor_f): Replace standard expression handling functions
with new functions.
* gdb/fortran-operator.def: New file.
* gdb/parse.c (operator_length_standard): Remove use of UNOP_KIND.
* gdb/std-operator.def: Remove UNOP_KIND.
Diffstat (limited to 'gdb/f-lang.c')
-rw-r--r-- | gdb/f-lang.c | 131 |
1 files changed, 125 insertions, 6 deletions
diff --git a/gdb/f-lang.c b/gdb/f-lang.c index e501d5cc355..ecb69e76e61 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -284,7 +284,7 @@ evaluate_subexp_f (struct type *expect_type, struct expression *exp, } error (_("ABS of type %s not supported"), TYPE_SAFE_NAME (type)); - case UNOP_KIND: + case UNOP_FORTRAN_KIND: arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); type = value_type (arg1); @@ -319,6 +319,125 @@ f_is_string_type_p (struct type *type) && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CHAR)); } +/* Special expression lengths for Fortran. */ + +static void +operator_length_f (const struct expression *exp, int pc, int *oplenp, + int *argsp) +{ + int oplen = 1; + int args = 0; + + switch (exp->elts[pc - 1].opcode) + { + default: + operator_length_standard (exp, pc, oplenp, argsp); + return; + + case UNOP_FORTRAN_KIND: + oplen = 1; + args = 1; + break; + } + + *oplenp = oplen; + *argsp = args; +} + +/* Special expression printing for Fortran. */ + +static void +print_subexp_f (struct expression *exp, int *pos, + struct ui_file *stream, enum precedence prec) +{ + int pc = *pos; + enum exp_opcode op = exp->elts[pc].opcode; + + switch (op) + { + default: + print_subexp_standard (exp, pos, stream, prec); + return; + + case UNOP_FORTRAN_KIND: + (*pos)++; + fputs_filtered ("KIND(", stream); + print_subexp (exp, pos, stream, PREC_SUFFIX); + fputs_filtered (")", stream); + return; + } +} + +/* Special expression names for Fortran. */ + +static const char * +op_name_f (enum exp_opcode opcode) +{ + switch (opcode) + { + default: + return op_name_standard (opcode); + +#define OP(name) \ + case name: \ + return #name ; +#include "fortran-operator.def" +#undef OP + } +} + +/* Special expression dumping for Fortran. */ + +static int +dump_subexp_body_f (struct expression *exp, + struct ui_file *stream, int elt) +{ + int opcode = exp->elts[elt].opcode; + int oplen, nargs, i; + + switch (opcode) + { + default: + return dump_subexp_body_standard (exp, stream, elt); + + case UNOP_FORTRAN_KIND: + operator_length_f (exp, (elt + 1), &oplen, &nargs); + break; + } + + elt += oplen; + for (i = 0; i < nargs; i += 1) + elt = dump_subexp (exp, stream, elt); + + return elt; +} + +/* Special expression checking for Fortran. */ + +static int +operator_check_f (struct expression *exp, int pos, + int (*objfile_func) (struct objfile *objfile, + void *data), + void *data) +{ + const union exp_element *const elts = exp->elts; + + switch (elts[pos].opcode) + { + case UNOP_FORTRAN_KIND: + /* Any references to objfiles are held in the arguments to this + expression, not within the expression itself, so no additional + checking is required here, the outer expression iteration code + will take care of checking each argument. */ + break; + + default: + return operator_check_standard (exp, pos, objfile_func, data); + } + + return 0; +} + static const char *f_extensions[] = { ".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP", @@ -329,11 +448,11 @@ static const char *f_extensions[] = /* Expression processing for Fortran. */ static const struct exp_descriptor exp_descriptor_f = { - print_subexp_standard, - operator_length_standard, - operator_check_standard, - op_name_standard, - dump_subexp_body_standard, + print_subexp_f, + operator_length_f, + operator_check_f, + op_name_f, + dump_subexp_body_f, evaluate_subexp_f }; |