From 83228e93efa82f84a132f7cec44d0e760d4ad22b Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Mon, 1 Apr 2019 21:01:09 +0100 Subject: [PATCH] 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. --- gdb/ChangeLog | 18 +++++++ gdb/expprint.c | 1 - gdb/expression.h | 1 + gdb/f-exp.y | 2 +- gdb/f-lang.c | 131 ++++++++++++++++++++++++++++++++++++++++++++--- gdb/fortran-operator.def | 22 ++++++++ gdb/parse.c | 1 - gdb/std-operator.def | 1 - 8 files changed, 167 insertions(+), 10 deletions(-) create mode 100644 gdb/fortran-operator.def diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 15568b7..3e3ea93 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,23 @@ 2019-04-30 Andrew Burgess + * 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. + +2019-04-30 Andrew Burgess + * std-operator.def: Remove unbalanced, stray double quote character. diff --git a/gdb/expprint.c b/gdb/expprint.c index a22499f..d7ad1a7 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -869,7 +869,6 @@ dump_subexp_body_standard (struct expression *exp, case UNOP_MIN: case UNOP_ODD: case UNOP_TRUNC: - case UNOP_KIND: elt = dump_subexp (exp, stream, elt); break; case OP_LONG: diff --git a/gdb/expression.h b/gdb/expression.h index 10e5f3e..841bf98 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -66,6 +66,7 @@ enum exp_opcode : uint8_t /* Language specific operators. */ #include "ada-operator.def" +#include "fortran-operator.def" #undef OP diff --git a/gdb/f-exp.y b/gdb/f-exp.y index b326d09..dec8848 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -240,7 +240,7 @@ exp : SIZEOF exp %prec UNARY ; exp : KIND '(' exp ')' %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_KIND); } + { write_exp_elt_opcode (pstate, UNOP_FORTRAN_KIND); } ; /* No more explicit array operators, we treat everything in F77 as diff --git a/gdb/f-lang.c b/gdb/f-lang.c index e501d5c..ecb69e7 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 }; diff --git a/gdb/fortran-operator.def b/gdb/fortran-operator.def new file mode 100644 index 0000000..c3176de --- /dev/null +++ b/gdb/fortran-operator.def @@ -0,0 +1,22 @@ +/* Fortran language operator definitions for GDB, the GNU debugger. + + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Single operand builtins. */ +OP (UNOP_FORTRAN_KIND) + diff --git a/gdb/parse.c b/gdb/parse.c index 52f2975..6f777e6 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -857,7 +857,6 @@ operator_length_standard (const struct expression *expr, int endpos, case UNOP_CHR: case UNOP_FLOAT: case UNOP_HIGH: - case UNOP_KIND: case UNOP_ODD: case UNOP_ORD: case UNOP_TRUNC: diff --git a/gdb/std-operator.def b/gdb/std-operator.def index 001ae61..a5247ab 100644 --- a/gdb/std-operator.def +++ b/gdb/std-operator.def @@ -244,7 +244,6 @@ OP (UNOP_ORD) OP (UNOP_ABS) OP (UNOP_FLOAT) OP (UNOP_HIGH) -OP (UNOP_KIND) /* Fortran KIND function. */ OP (UNOP_MAX) OP (UNOP_MIN) OP (UNOP_ODD) -- 2.7.4