[PATCHv2,2/8] gdb/fortran: Introduce fortran-operator.def file

Message ID bf849208040e85c3cd141c2ed9ae862b3032962f.1554249182.git.andrew.burgess@embecosm.com
State New, archived
Headers

Commit Message

Andrew Burgess April 2, 2019, 11:58 p.m. UTC
  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             | 126 ++++++++++++++++++++++++++++++++++++++++++++---
 gdb/fortran-operator.def |  22 +++++++++
 gdb/parse.c              |   1 -
 gdb/std-operator.def     |   1 -
 8 files changed, 162 insertions(+), 10 deletions(-)
 create mode 100644 gdb/fortran-operator.def
  

Patch

diff --git a/gdb/expprint.c b/gdb/expprint.c
index a22499f4833..d7ad1a71878 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 8db4b9d7e26..beb8aad92b2 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 f99c26d326e..06851a0aa7c 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -233,7 +233,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 7bd119690b4..91bf73b800a 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);
 
@@ -308,6 +308,120 @@  evaluate_subexp_f (struct type *expect_type, struct expression *exp,
   return nullptr;
 }
 
+/* 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",
@@ -318,11 +432,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 00000000000..c3176de428e
--- /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 <http://www.gnu.org/licenses/>.  */
+
+/* Single operand builtins.  */
+OP (UNOP_FORTRAN_KIND)
+
diff --git a/gdb/parse.c b/gdb/parse.c
index 63cbc746aaa..6b5acac8c7f 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -924,7 +924,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 001ae61e481..a5247ab9409 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)