gdb: Convert language la_post_parser field to a method
[deliverable/binutils-gdb.git] / gdb / f-lang.c
index d127a50a06b234fb8a3ecc0a03105a91d53b04ef..1b545b27b3b9273cb217bdd102189202d731dd88 100644 (file)
@@ -1,5 +1,7 @@
 /* Fortran language support routines for GDB, the GNU debugger.
-   Copyright 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
+
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
+
    Contributed by Motorola.  Adapted from the C parser by Farooq Butt
    (fmbutt@engage.sps.mot.com).
 
@@ -7,7 +9,7 @@
 
    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 2 of the License, or
+   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,
    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, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "expression.h"
 #include "parser-defs.h"
 #include "language.h"
+#include "varobj.h"
+#include "gdbcore.h"
 #include "f-lang.h"
 #include "valprint.h"
+#include "value.h"
+#include "cp-support.h"
+#include "charset.h"
+#include "c-lang.h"
+#include "target-float.h"
+#include "gdbarch.h"
 
-/* The built-in types of F77.  FIXME: integer*4 is missing, plain
-   logical is missing (builtin_type_logical is logical*4).  */
-
-struct type *builtin_type_f_character;
-struct type *builtin_type_f_logical;
-struct type *builtin_type_f_logical_s1;
-struct type *builtin_type_f_logical_s2;
-struct type *builtin_type_f_integer;
-struct type *builtin_type_f_integer_s2;
-struct type *builtin_type_f_real;
-struct type *builtin_type_f_real_s8;
-struct type *builtin_type_f_real_s16;
-struct type *builtin_type_f_complex_s8;
-struct type *builtin_type_f_complex_s16;
-struct type *builtin_type_f_complex_s32;
-struct type *builtin_type_f_void;
-
-/* Following is dubious stuff that had been in the xcoff reader. */
-
-struct saved_fcn
-  {
-    long line_offset;          /* Line offset for function */
-    struct saved_fcn *next;
-  };
+#include <math.h>
+
+/* Local functions */
 
+static void f_printchar (int c, struct type *type, struct ui_file * stream);
+static void f_emit_char (int c, struct type *type,
+                        struct ui_file * stream, int quoter);
 
-struct saved_bf_symnum
-  {
-    long symnum_fcn;           /* Symnum of function (i.e. .function directive) */
-    long symnum_bf;            /* Symnum of .bf for this function */
-    struct saved_bf_symnum *next;
-  };
+/* Return the encoding that should be used for the character type
+   TYPE.  */
 
-typedef struct saved_fcn SAVED_FUNCTION, *SAVED_FUNCTION_PTR;
-typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR;
+static const char *
+f_get_encoding (struct type *type)
+{
+  const char *encoding;
 
-/* Local functions */
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      encoding = target_charset (get_type_arch (type));
+      break;
+    case 4:
+      if (type_byte_order (type) == BFD_ENDIAN_BIG)
+       encoding = "UTF-32BE";
+      else
+       encoding = "UTF-32LE";
+      break;
 
-extern void _initialize_f_language (void);
-#if 0
-static void clear_function_list (void);
-static long get_bf_for_fcn (long);
-static void clear_bf_list (void);
-static void patch_all_commons_by_name (char *, CORE_ADDR, int);
-static SAVED_F77_COMMON_PTR find_first_common_named (char *);
-static void add_common_entry (struct symbol *);
-static void add_common_block (char *, CORE_ADDR, int, char *);
-static SAVED_FUNCTION *allocate_saved_function_node (void);
-static SAVED_BF_PTR allocate_saved_bf_node (void);
-static COMMON_ENTRY_PTR allocate_common_entry_node (void);
-static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node (void);
-static void patch_common_entries (SAVED_F77_COMMON_PTR, CORE_ADDR, int);
-#endif
-
-static struct type *f_create_fundamental_type (struct objfile *, int);
-static void f_printstr (struct ui_file * stream, char *string,
-                       unsigned int length, int width,
-                       int force_ellipses);
-static void f_printchar (int c, struct ui_file * stream);
-static void f_emit_char (int c, struct ui_file * stream, int quoter);
+    default:
+      error (_("unrecognized character type"));
+    }
+
+  return encoding;
+}
 
 /* Print the character C on STREAM as part of the contents of a literal
    string whose delimiter is QUOTER.  Note that that format for printing
@@ -98,56 +79,20 @@ static void f_emit_char (int c, struct ui_file * stream, int quoter);
    be replaced with a true F77 version.  */
 
 static void
-f_emit_char (register int c, struct ui_file *stream, int quoter)
+f_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
 {
-  c &= 0xFF;                   /* Avoid sign bit follies */
+  const char *encoding = f_get_encoding (type);
 
-  if (PRINT_LITERAL_FORM (c))
-    {
-      if (c == '\\' || c == quoter)
-       fputs_filtered ("\\", stream);
-      fprintf_filtered (stream, "%c", c);
-    }
-  else
-    {
-      switch (c)
-       {
-       case '\n':
-         fputs_filtered ("\\n", stream);
-         break;
-       case '\b':
-         fputs_filtered ("\\b", stream);
-         break;
-       case '\t':
-         fputs_filtered ("\\t", stream);
-         break;
-       case '\f':
-         fputs_filtered ("\\f", stream);
-         break;
-       case '\r':
-         fputs_filtered ("\\r", stream);
-         break;
-       case '\033':
-         fputs_filtered ("\\e", stream);
-         break;
-       case '\007':
-         fputs_filtered ("\\a", stream);
-         break;
-       default:
-         fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
-         break;
-       }
-    }
+  generic_emit_char (c, type, stream, quoter, encoding);
 }
 
-/* FIXME:  This is a copy of the same function from c-exp.y.  It should
-   be replaced with a true F77version. */
+/* Implementation of la_printchar.  */
 
 static void
-f_printchar (int c, struct ui_file *stream)
+f_printchar (int c, struct type *type, struct ui_file *stream)
 {
   fputs_filtered ("'", stream);
-  LA_EMIT_CHAR (c, stream, '\'');
+  LA_EMIT_CHAR (c, type, stream, '\'');
   fputs_filtered ("'", stream);
 }
 
@@ -156,248 +101,23 @@ f_printchar (int c, struct ui_file *stream)
    are printed as appropriate.  Print ellipses at the end if we
    had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
    FIXME:  This is a copy of the same function from c-exp.y.  It should
-   be replaced with a true F77 version. */
+   be replaced with a true F77 version.  */
 
 static void
-f_printstr (struct ui_file *stream, char *string, unsigned int length,
-           int width, int force_ellipses)
+f_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
+           unsigned int length, const char *encoding, int force_ellipses,
+           const struct value_print_options *options)
 {
-  register unsigned int i;
-  unsigned int things_printed = 0;
-  int in_quotes = 0;
-  int need_comma = 0;
-  extern int inspect_it;
-
-  if (length == 0)
-    {
-      fputs_filtered ("''", gdb_stdout);
-      return;
-    }
-
-  for (i = 0; i < length && things_printed < print_max; ++i)
-    {
-      /* Position of the character we are examining
-         to see whether it is repeated.  */
-      unsigned int rep1;
-      /* Number of repetitions we have detected so far.  */
-      unsigned int reps;
-
-      QUIT;
+  const char *type_encoding = f_get_encoding (type);
 
-      if (need_comma)
-       {
-         fputs_filtered (", ", stream);
-         need_comma = 0;
-       }
-
-      rep1 = i + 1;
-      reps = 1;
-      while (rep1 < length && string[rep1] == string[i])
-       {
-         ++rep1;
-         ++reps;
-       }
+  if (TYPE_LENGTH (type) == 4)
+    fputs_filtered ("4_", stream);
 
-      if (reps > repeat_count_threshold)
-       {
-         if (in_quotes)
-           {
-             if (inspect_it)
-               fputs_filtered ("\\', ", stream);
-             else
-               fputs_filtered ("', ", stream);
-             in_quotes = 0;
-           }
-         f_printchar (string[i], stream);
-         fprintf_filtered (stream, " <repeats %u times>", reps);
-         i = rep1 - 1;
-         things_printed += repeat_count_threshold;
-         need_comma = 1;
-       }
-      else
-       {
-         if (!in_quotes)
-           {
-             if (inspect_it)
-               fputs_filtered ("\\'", stream);
-             else
-               fputs_filtered ("'", stream);
-             in_quotes = 1;
-           }
-         LA_EMIT_CHAR (string[i], stream, '"');
-         ++things_printed;
-       }
-    }
+  if (!encoding || !*encoding)
+    encoding = type_encoding;
 
-  /* Terminate the quotes if necessary.  */
-  if (in_quotes)
-    {
-      if (inspect_it)
-       fputs_filtered ("\\'", stream);
-      else
-       fputs_filtered ("'", stream);
-    }
-
-  if (force_ellipses || i < length)
-    fputs_filtered ("...", stream);
-}
-
-/* FIXME:  This is a copy of c_create_fundamental_type(), before
-   all the non-C types were stripped from it.  Needs to be fixed
-   by an experienced F77 programmer. */
-
-static struct type *
-f_create_fundamental_type (struct objfile *objfile, int typeid)
-{
-  register struct type *type = NULL;
-
-  switch (typeid)
-    {
-    case FT_VOID:
-      type = init_type (TYPE_CODE_VOID,
-                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                       0, "VOID", objfile);
-      break;
-    case FT_BOOLEAN:
-      type = init_type (TYPE_CODE_BOOL,
-                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                       TYPE_FLAG_UNSIGNED, "boolean", objfile);
-      break;
-    case FT_STRING:
-      type = init_type (TYPE_CODE_STRING,
-                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                       0, "string", objfile);
-      break;
-    case FT_CHAR:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                       0, "character", objfile);
-      break;
-    case FT_SIGNED_CHAR:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                       0, "integer*1", objfile);
-      break;
-    case FT_UNSIGNED_CHAR:
-      type = init_type (TYPE_CODE_BOOL,
-                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-                       TYPE_FLAG_UNSIGNED, "logical*1", objfile);
-      break;
-    case FT_SHORT:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-                       0, "integer*2", objfile);
-      break;
-    case FT_SIGNED_SHORT:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-                       0, "short", objfile);   /* FIXME-fnf */
-      break;
-    case FT_UNSIGNED_SHORT:
-      type = init_type (TYPE_CODE_BOOL,
-                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-                       TYPE_FLAG_UNSIGNED, "logical*2", objfile);
-      break;
-    case FT_INTEGER:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_INT_BIT / TARGET_CHAR_BIT,
-                       0, "integer*4", objfile);
-      break;
-    case FT_SIGNED_INTEGER:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_INT_BIT / TARGET_CHAR_BIT,
-                       0, "integer", objfile);         /* FIXME -fnf */
-      break;
-    case FT_UNSIGNED_INTEGER:
-      type = init_type (TYPE_CODE_BOOL,
-                       TARGET_INT_BIT / TARGET_CHAR_BIT,
-                       TYPE_FLAG_UNSIGNED, "logical*4", objfile);
-      break;
-    case FT_FIXED_DECIMAL:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_INT_BIT / TARGET_CHAR_BIT,
-                       0, "fixed decimal", objfile);
-      break;
-    case FT_LONG:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
-                       0, "long", objfile);
-      break;
-    case FT_SIGNED_LONG:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
-                       0, "long", objfile);    /* FIXME -fnf */
-      break;
-    case FT_UNSIGNED_LONG:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
-                       TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
-      break;
-    case FT_LONG_LONG:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
-                       0, "long long", objfile);
-      break;
-    case FT_SIGNED_LONG_LONG:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
-                       0, "signed long long", objfile);
-      break;
-    case FT_UNSIGNED_LONG_LONG:
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
-                       TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
-      break;
-    case FT_FLOAT:
-      type = init_type (TYPE_CODE_FLT,
-                       TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
-                       0, "real", objfile);
-      break;
-    case FT_DBL_PREC_FLOAT:
-      type = init_type (TYPE_CODE_FLT,
-                       TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-                       0, "real*8", objfile);
-      break;
-    case FT_FLOAT_DECIMAL:
-      type = init_type (TYPE_CODE_FLT,
-                       TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-                       0, "floating decimal", objfile);
-      break;
-    case FT_EXT_PREC_FLOAT:
-      type = init_type (TYPE_CODE_FLT,
-                       TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
-                       0, "real*16", objfile);
-      break;
-    case FT_COMPLEX:
-      type = init_type (TYPE_CODE_COMPLEX,
-                       2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
-                       0, "complex*8", objfile);
-      TYPE_TARGET_TYPE (type) = builtin_type_f_real;
-      break;
-    case FT_DBL_PREC_COMPLEX:
-      type = init_type (TYPE_CODE_COMPLEX,
-                       2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-                       0, "complex*16", objfile);
-      TYPE_TARGET_TYPE (type) = builtin_type_f_real_s8;
-      break;
-    case FT_EXT_PREC_COMPLEX:
-      type = init_type (TYPE_CODE_COMPLEX,
-                       2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
-                       0, "complex*32", objfile);
-      TYPE_TARGET_TYPE (type) = builtin_type_f_real_s16;
-      break;
-    default:
-      /* FIXME:  For now, if we are asked to produce a type not in this
-         language, create the equivalent of a C integer type with the
-         name "<?type?>".  When all the dust settles from the type
-         reconstruction work, this should probably become an error. */
-      type = init_type (TYPE_CODE_INT,
-                       TARGET_INT_BIT / TARGET_CHAR_BIT,
-                       0, "<?type?>", objfile);
-      warning ("internal error: no F77 fundamental type %d", typeid);
-      break;
-    }
-  return (type);
+  generic_printstr (stream, type, string, length, encoding,
+                   force_ellipses, '\'', 0, options);
 }
 \f
 
@@ -425,530 +145,714 @@ static const struct op_print f_op_print_tab[] =
   {".LT.", BINOP_LESS, PREC_ORDER, 0},
   {"**", UNOP_IND, PREC_PREFIX, 0},
   {"@", BINOP_REPEAT, PREC_REPEAT, 0},
-  {NULL, 0, 0, 0}
+  {NULL, OP_NULL, PREC_REPEAT, 0}
 };
 \f
-struct type **CONST_PTR (f_builtin_types[]) =
-{
-  &builtin_type_f_character,
-    &builtin_type_f_logical,
-    &builtin_type_f_logical_s1,
-    &builtin_type_f_logical_s2,
-    &builtin_type_f_integer,
-    &builtin_type_f_integer_s2,
-    &builtin_type_f_real,
-    &builtin_type_f_real_s8,
-    &builtin_type_f_real_s16,
-    &builtin_type_f_complex_s8,
-    &builtin_type_f_complex_s16,
-#if 0
-    &builtin_type_f_complex_s32,
-#endif
-    &builtin_type_f_void,
-    0
+enum f_primitive_types {
+  f_primitive_type_character,
+  f_primitive_type_logical,
+  f_primitive_type_logical_s1,
+  f_primitive_type_logical_s2,
+  f_primitive_type_logical_s8,
+  f_primitive_type_integer,
+  f_primitive_type_integer_s2,
+  f_primitive_type_real,
+  f_primitive_type_real_s8,
+  f_primitive_type_real_s16,
+  f_primitive_type_complex_s8,
+  f_primitive_type_complex_s16,
+  f_primitive_type_void,
+  nr_f_primitive_types
 };
 
-/* This is declared in c-lang.h but it is silly to import that file for what
-   is already just a hack. */
-extern int c_value_print (struct value *, struct ui_file *, int,
-                         enum val_prettyprint);
+/* Special expression evaluation cases for Fortran.  */
 
-const struct language_defn f_language_defn =
+static struct value *
+evaluate_subexp_f (struct type *expect_type, struct expression *exp,
+                  int *pos, enum noside noside)
 {
-  "fortran",
-  language_fortran,
-  f_builtin_types,
-  range_check_on,
-  type_check_on,
-  f_parse,                     /* parser */
-  f_error,                     /* parser error function */
-  evaluate_subexp_standard,
-  f_printchar,                 /* Print character constant */
-  f_printstr,                  /* function to print string constant */
-  f_emit_char,                 /* Function to print a single character */
-  f_create_fundamental_type,   /* Create fundamental type in this language */
-  f_print_type,                        /* Print a type using appropriate syntax */
-  f_val_print,                 /* Print a value using appropriate syntax */
-  c_value_print,               /* FIXME */
-  {"", "", "", ""},            /* Binary format info */
-  {"0%o", "0", "o", ""},       /* Octal format info */
-  {"%d", "", "d", ""},         /* Decimal format info */
-  {"0x%x", "0x", "x", ""},     /* Hex format info */
-  f_op_print_tab,              /* expression operators for printing */
-  0,                           /* arrays are first-class (not c-style) */
-  1,                           /* String lower bound */
-  &builtin_type_f_character,   /* Type of string elements */
-  LANG_MAGIC
-};
+  struct value *arg1 = NULL, *arg2 = NULL;
+  enum exp_opcode op;
+  int pc;
+  struct type *type;
 
-void
-_initialize_f_language (void)
-{
-  builtin_type_f_void =
-    init_type (TYPE_CODE_VOID, 1,
-              0,
-              "VOID", (struct objfile *) NULL);
-
-  builtin_type_f_character =
-    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-              0,
-              "character", (struct objfile *) NULL);
-
-  builtin_type_f_logical_s1 =
-    init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-              TYPE_FLAG_UNSIGNED,
-              "logical*1", (struct objfile *) NULL);
-
-  builtin_type_f_integer_s2 =
-    init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-              0,
-              "integer*2", (struct objfile *) NULL);
-
-  builtin_type_f_logical_s2 =
-    init_type (TYPE_CODE_BOOL, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
-              TYPE_FLAG_UNSIGNED,
-              "logical*2", (struct objfile *) NULL);
-
-  builtin_type_f_integer =
-    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
-              0,
-              "integer", (struct objfile *) NULL);
-
-  builtin_type_f_logical =
-    init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
-              TYPE_FLAG_UNSIGNED,
-              "logical*4", (struct objfile *) NULL);
-
-  builtin_type_f_real =
-    init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
-              0,
-              "real", (struct objfile *) NULL);
-
-  builtin_type_f_real_s8 =
-    init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-              0,
-              "real*8", (struct objfile *) NULL);
-
-  builtin_type_f_real_s16 =
-    init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
-              0,
-              "real*16", (struct objfile *) NULL);
-
-  builtin_type_f_complex_s8 =
-    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
-              0,
-              "complex*8", (struct objfile *) NULL);
-  TYPE_TARGET_TYPE (builtin_type_f_complex_s8) = builtin_type_f_real;
-
-  builtin_type_f_complex_s16 =
-    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
-              0,
-              "complex*16", (struct objfile *) NULL);
-  TYPE_TARGET_TYPE (builtin_type_f_complex_s16) = builtin_type_f_real_s8;
-
-  /* We have a new size == 4 double floats for the
-     complex*32 data type */
-
-  builtin_type_f_complex_s32 =
-    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
-              0,
-              "complex*32", (struct objfile *) NULL);
-  TYPE_TARGET_TYPE (builtin_type_f_complex_s32) = builtin_type_f_real_s16;
-
-  builtin_type_string =
-    init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-              0,
-              "character string", (struct objfile *) NULL);
-
-  add_language (&f_language_defn);
-}
+  pc = *pos;
+  *pos += 1;
+  op = exp->elts[pc].opcode;
 
-#if 0
-static SAVED_BF_PTR
-allocate_saved_bf_node (void)
-{
-  SAVED_BF_PTR new;
+  switch (op)
+    {
+    default:
+      *pos -= 1;
+      return evaluate_subexp_standard (expect_type, exp, pos, noside);
+
+    case UNOP_ABS:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       return eval_skip_value (exp);
+      type = value_type (arg1);
+      switch (type->code ())
+       {
+       case TYPE_CODE_FLT:
+         {
+           double d
+             = fabs (target_float_to_host_double (value_contents (arg1),
+                                                  value_type (arg1)));
+           return value_from_host_double (type, d);
+         }
+       case TYPE_CODE_INT:
+         {
+           LONGEST l = value_as_long (arg1);
+           l = llabs (l);
+           return value_from_longest (type, l);
+         }
+       }
+      error (_("ABS of type %s not supported"), TYPE_SAFE_NAME (type));
+
+    case BINOP_MOD:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       return eval_skip_value (exp);
+      type = value_type (arg1);
+      if (type->code () != value_type (arg2)->code ())
+       error (_("non-matching types for parameters to MOD ()"));
+      switch (type->code ())
+       {
+       case TYPE_CODE_FLT:
+         {
+           double d1
+             = target_float_to_host_double (value_contents (arg1),
+                                            value_type (arg1));
+           double d2
+             = target_float_to_host_double (value_contents (arg2),
+                                            value_type (arg2));
+           double d3 = fmod (d1, d2);
+           return value_from_host_double (type, d3);
+         }
+       case TYPE_CODE_INT:
+         {
+           LONGEST v1 = value_as_long (arg1);
+           LONGEST v2 = value_as_long (arg2);
+           if (v2 == 0)
+             error (_("calling MOD (N, 0) is undefined"));
+           LONGEST v3 = v1 - (v1 / v2) * v2;
+           return value_from_longest (value_type (arg1), v3);
+         }
+       }
+      error (_("MOD of type %s not supported"), TYPE_SAFE_NAME (type));
 
-  new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF));
-  return (new);
-}
+    case UNOP_FORTRAN_CEILING:
+      {
+       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+       if (noside == EVAL_SKIP)
+         return eval_skip_value (exp);
+       type = value_type (arg1);
+       if (type->code () != TYPE_CODE_FLT)
+         error (_("argument to CEILING must be of type float"));
+       double val
+         = target_float_to_host_double (value_contents (arg1),
+                                        value_type (arg1));
+       val = ceil (val);
+       return value_from_host_double (type, val);
+      }
 
-static SAVED_FUNCTION *
-allocate_saved_function_node (void)
-{
-  SAVED_FUNCTION *new;
+    case UNOP_FORTRAN_FLOOR:
+      {
+       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+       if (noside == EVAL_SKIP)
+         return eval_skip_value (exp);
+       type = value_type (arg1);
+       if (type->code () != TYPE_CODE_FLT)
+         error (_("argument to FLOOR must be of type float"));
+       double val
+         = target_float_to_host_double (value_contents (arg1),
+                                        value_type (arg1));
+       val = floor (val);
+       return value_from_host_double (type, val);
+      }
 
-  new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION));
-  return (new);
-}
+    case BINOP_FORTRAN_MODULO:
+      {
+       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+       arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
+       if (noside == EVAL_SKIP)
+         return eval_skip_value (exp);
+       type = value_type (arg1);
+       if (type->code () != value_type (arg2)->code ())
+         error (_("non-matching types for parameters to MODULO ()"));
+        /* MODULO(A, P) = A - FLOOR (A / P) * P */
+       switch (type->code ())
+         {
+         case TYPE_CODE_INT:
+           {
+             LONGEST a = value_as_long (arg1);
+             LONGEST p = value_as_long (arg2);
+             LONGEST result = a - (a / p) * p;
+             if (result != 0 && (a < 0) != (p < 0))
+               result += p;
+             return value_from_longest (value_type (arg1), result);
+           }
+         case TYPE_CODE_FLT:
+           {
+             double a
+               = target_float_to_host_double (value_contents (arg1),
+                                              value_type (arg1));
+             double p
+               = target_float_to_host_double (value_contents (arg2),
+                                              value_type (arg2));
+             double result = fmod (a, p);
+             if (result != 0 && (a < 0.0) != (p < 0.0))
+               result += p;
+             return value_from_host_double (type, result);
+           }
+         }
+       error (_("MODULO of type %s not supported"), TYPE_SAFE_NAME (type));
+      }
 
-static SAVED_F77_COMMON_PTR
-allocate_saved_f77_common_node (void)
-{
-  SAVED_F77_COMMON_PTR new;
+    case BINOP_FORTRAN_CMPLX:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       return eval_skip_value (exp);
+      type = builtin_f_type(exp->gdbarch)->builtin_complex_s16;
+      return value_literal_complex (arg1, arg2, type);
+
+    case UNOP_FORTRAN_KIND:
+      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type = value_type (arg1);
+
+      switch (type->code ())
+        {
+          case TYPE_CODE_STRUCT:
+          case TYPE_CODE_UNION:
+          case TYPE_CODE_MODULE:
+          case TYPE_CODE_FUNC:
+            error (_("argument to kind must be an intrinsic type"));
+        }
+
+      if (!TYPE_TARGET_TYPE (type))
+        return value_from_longest (builtin_type (exp->gdbarch)->builtin_int,
+                                  TYPE_LENGTH (type));
+      return value_from_longest (builtin_type (exp->gdbarch)->builtin_int,
+                                TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
+    }
 
-  new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON));
-  return (new);
+  /* Should be unreachable.  */
+  return nullptr;
 }
 
-static COMMON_ENTRY_PTR
-allocate_common_entry_node (void)
-{
-  COMMON_ENTRY_PTR new;
+/* Return true if TYPE is a string.  */
 
-  new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY));
-  return (new);
+static bool
+f_is_string_type_p (struct type *type)
+{
+  type = check_typedef (type);
+  return (type->code () == TYPE_CODE_STRING
+         || (type->code () == TYPE_CODE_ARRAY
+             && TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR));
 }
-#endif
-
-SAVED_F77_COMMON_PTR head_common_list = NULL;  /* Ptr to 1st saved COMMON  */
-SAVED_F77_COMMON_PTR tail_common_list = NULL;  /* Ptr to last saved COMMON  */
-SAVED_F77_COMMON_PTR current_common = NULL;    /* Ptr to current COMMON */
 
-#if 0
-static SAVED_BF_PTR saved_bf_list = NULL;      /* Ptr to (.bf,function) 
-                                                  list */
-static SAVED_BF_PTR saved_bf_list_end = NULL;  /* Ptr to above list's end */
-static SAVED_BF_PTR current_head_bf_list = NULL;       /* Current head of above list
-                                                        */
-
-static SAVED_BF_PTR tmp_bf_ptr;        /* Generic temporary for use 
-                                  in macros */
-
-/* The following function simply enters a given common block onto 
-   the global common block chain */
+/* Special expression lengths for Fortran.  */
 
 static void
-add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab)
+operator_length_f (const struct expression *exp, int pc, int *oplenp,
+                  int *argsp)
 {
-  SAVED_F77_COMMON_PTR tmp;
-  char *c, *local_copy_func_stab;
-
-  /* If the COMMON block we are trying to add has a blank 
-     name (i.e. "#BLNK_COM") then we set it to __BLANK
-     because the darn "#" character makes GDB's input 
-     parser have fits. */
-
+  int oplen = 1;
+  int args = 0;
 
-  if (STREQ (name, BLANK_COMMON_NAME_ORIGINAL) ||
-      STREQ (name, BLANK_COMMON_NAME_MF77))
+  switch (exp->elts[pc - 1].opcode)
     {
+    default:
+      operator_length_standard (exp, pc, oplenp, argsp);
+      return;
+
+    case UNOP_FORTRAN_KIND:
+    case UNOP_FORTRAN_FLOOR:
+    case UNOP_FORTRAN_CEILING:
+      oplen = 1;
+      args = 1;
+      break;
 
-      free (name);
-      name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
-      strcpy (name, BLANK_COMMON_NAME_LOCAL);
+    case BINOP_FORTRAN_CMPLX:
+    case BINOP_FORTRAN_MODULO:
+      oplen = 1;
+      args = 2;
+      break;
     }
 
-  tmp = allocate_saved_f77_common_node ();
+  *oplenp = oplen;
+  *argsp = args;
+}
 
-  local_copy_func_stab = xmalloc (strlen (func_stab) + 1);
-  strcpy (local_copy_func_stab, func_stab);
+/* Helper for PRINT_SUBEXP_F.  Arguments are as for PRINT_SUBEXP_F, except
+   the extra argument NAME which is the text that should be printed as the
+   name of this operation.  */
 
-  tmp->name = xmalloc (strlen (name) + 1);
+static void
+print_unop_subexp_f (struct expression *exp, int *pos,
+                    struct ui_file *stream, enum precedence prec,
+                    const char *name)
+{
+  (*pos)++;
+  fprintf_filtered (stream, "%s(", name);
+  print_subexp (exp, pos, stream, PREC_SUFFIX);
+  fputs_filtered (")", stream);
+}
 
-  /* local_copy_func_stab is a stabstring, let us first extract the 
-     function name from the stab by NULLing out the ':' character. */
+/* Helper for PRINT_SUBEXP_F.  Arguments are as for PRINT_SUBEXP_F, except
+   the extra argument NAME which is the text that should be printed as the
+   name of this operation.  */
 
+static void
+print_binop_subexp_f (struct expression *exp, int *pos,
+                     struct ui_file *stream, enum precedence prec,
+                     const char *name)
+{
+  (*pos)++;
+  fprintf_filtered (stream, "%s(", name);
+  print_subexp (exp, pos, stream, PREC_SUFFIX);
+  fputs_filtered (",", stream);
+  print_subexp (exp, pos, stream, PREC_SUFFIX);
+  fputs_filtered (")", stream);
+}
 
-  c = NULL;
-  c = strchr (local_copy_func_stab, ':');
+/* Special expression printing for Fortran.  */
 
-  if (c)
-    *c = '\0';
-  else
-    error ("Malformed function STAB found in add_common_block()");
+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;
 
-  tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1);
+    case UNOP_FORTRAN_KIND:
+      print_unop_subexp_f (exp, pos, stream, prec, "KIND");
+      return;
 
-  strcpy (tmp->owning_function, local_copy_func_stab);
+    case UNOP_FORTRAN_FLOOR:
+      print_unop_subexp_f (exp, pos, stream, prec, "FLOOR");
+      return;
 
-  strcpy (tmp->name, name);
-  tmp->offset = offset;
-  tmp->next = NULL;
-  tmp->entries = NULL;
-  tmp->secnum = secnum;
+    case UNOP_FORTRAN_CEILING:
+      print_unop_subexp_f (exp, pos, stream, prec, "CEILING");
+      return;
 
-  current_common = tmp;
+    case BINOP_FORTRAN_CMPLX:
+      print_binop_subexp_f (exp, pos, stream, prec, "CMPLX");
+      return;
 
-  if (head_common_list == NULL)
-    {
-      head_common_list = tail_common_list = tmp;
-    }
-  else
-    {
-      tail_common_list->next = tmp;
-      tail_common_list = tmp;
+    case BINOP_FORTRAN_MODULO:
+      print_binop_subexp_f (exp, pos, stream, prec, "MODULO");
+      return;
     }
 }
-#endif
 
-/* The following function simply enters a given common entry onto 
-   the "current_common" block that has been saved away. */
+/* Special expression names for Fortran.  */
 
-#if 0
-static void
-add_common_entry (struct symbol *entry_sym_ptr)
+static const char *
+op_name_f (enum exp_opcode opcode)
 {
-  COMMON_ENTRY_PTR tmp;
-
-
+  switch (opcode)
+    {
+    default:
+      return op_name_standard (opcode);
 
-  /* The order of this list is important, since 
-     we expect the entries to appear in decl.
-     order when we later issue "info common" calls */
+#define OP(name)       \
+    case name:         \
+      return #name ;
+#include "fortran-operator.def"
+#undef OP
+    }
+}
 
-  tmp = allocate_common_entry_node ();
+/* Special expression dumping for Fortran.  */
 
-  tmp->next = NULL;
-  tmp->symbol = entry_sym_ptr;
+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;
 
-  if (current_common == NULL)
-    error ("Attempt to add COMMON entry with no block open!");
-  else
+  switch (opcode)
     {
-      if (current_common->entries == NULL)
-       {
-         current_common->entries = tmp;
-         current_common->end_of_entries = tmp;
-       }
-      else
-       {
-         current_common->end_of_entries->next = tmp;
-         current_common->end_of_entries = tmp;
-       }
+    default:
+      return dump_subexp_body_standard (exp, stream, elt);
+
+    case UNOP_FORTRAN_KIND:
+    case UNOP_FORTRAN_FLOOR:
+    case UNOP_FORTRAN_CEILING:
+    case BINOP_FORTRAN_CMPLX:
+    case BINOP_FORTRAN_MODULO:
+      operator_length_f (exp, (elt + 1), &oplen, &nargs);
+      break;
     }
-}
-#endif
 
-/* This routine finds the first encountred COMMON block named "name" */
+  elt += oplen;
+  for (i = 0; i < nargs; i += 1)
+    elt = dump_subexp (exp, stream, elt);
 
-#if 0
-static SAVED_F77_COMMON_PTR
-find_first_common_named (char *name)
-{
+  return elt;
+}
 
-  SAVED_F77_COMMON_PTR tmp;
+/* Special expression checking for Fortran.  */
 
-  tmp = head_common_list;
+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;
 
-  while (tmp != NULL)
+  switch (elts[pos].opcode)
     {
-      if (STREQ (tmp->name, name))
-       return (tmp);
-      else
-       tmp = tmp->next;
+    case UNOP_FORTRAN_KIND:
+    case UNOP_FORTRAN_FLOOR:
+    case UNOP_FORTRAN_CEILING:
+    case BINOP_FORTRAN_CMPLX:
+    case BINOP_FORTRAN_MODULO:
+      /* 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 (NULL);
+
+  return 0;
 }
-#endif
 
-/* This routine finds the first encountred COMMON block named "name" 
-   that belongs to function funcname */
+static const char *f_extensions[] =
+{
+  ".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
+  ".f90", ".F90", ".f95", ".F95", ".f03", ".F03", ".f08", ".F08",
+  NULL
+};
 
-SAVED_F77_COMMON_PTR
-find_common_for_function (char *name, char *funcname)
+/* Expression processing for Fortran.  */
+static const struct exp_descriptor exp_descriptor_f =
 {
+  print_subexp_f,
+  operator_length_f,
+  operator_check_f,
+  op_name_f,
+  dump_subexp_body_f,
+  evaluate_subexp_f
+};
 
-  SAVED_F77_COMMON_PTR tmp;
+/* Constant data that describes the Fortran language.  */
 
-  tmp = head_common_list;
+extern const struct language_data f_language_data =
+{
+  "fortran",
+  "Fortran",
+  language_fortran,
+  range_check_on,
+  case_sensitive_off,
+  array_column_major,
+  macro_expansion_no,
+  f_extensions,
+  &exp_descriptor_f,
+  f_printchar,                 /* Print character constant */
+  f_printstr,                  /* function to print string constant */
+  f_emit_char,                 /* Function to print a single character */
+  f_print_typedef,             /* Print a typedef using appropriate syntax */
+  NULL,                        /* name_of_this */
+  false,                       /* la_store_sym_names_in_linkage_form_p */
+  f_op_print_tab,              /* expression operators for printing */
+  0,                           /* arrays are first-class (not c-style) */
+  1,                           /* String lower bound */
+  &default_varobj_ops,
+  f_is_string_type_p,
+  "(...)"                      /* la_struct_too_deep_ellipsis */
+};
 
-  while (tmp != NULL)
-    {
-      if (STREQ (tmp->name, name) && STREQ (tmp->owning_function, funcname))
-       return (tmp);
-      else
-       tmp = tmp->next;
-    }
-  return (NULL);
-}
+/* Class representing the Fortran language.  */
 
+class f_language : public language_defn
+{
+public:
+  f_language ()
+    : language_defn (language_fortran, f_language_data)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    const struct builtin_f_type *builtin = builtin_f_type (gdbarch);
+
+    lai->string_char_type = builtin->builtin_character;
+    lai->primitive_type_vector
+      = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_f_primitive_types + 1,
+                               struct type *);
+
+    lai->primitive_type_vector [f_primitive_type_character]
+      = builtin->builtin_character;
+    lai->primitive_type_vector [f_primitive_type_logical]
+      = builtin->builtin_logical;
+    lai->primitive_type_vector [f_primitive_type_logical_s1]
+      = builtin->builtin_logical_s1;
+    lai->primitive_type_vector [f_primitive_type_logical_s2]
+      = builtin->builtin_logical_s2;
+    lai->primitive_type_vector [f_primitive_type_logical_s8]
+      = builtin->builtin_logical_s8;
+    lai->primitive_type_vector [f_primitive_type_real]
+      = builtin->builtin_real;
+    lai->primitive_type_vector [f_primitive_type_real_s8]
+      = builtin->builtin_real_s8;
+    lai->primitive_type_vector [f_primitive_type_real_s16]
+      = builtin->builtin_real_s16;
+    lai->primitive_type_vector [f_primitive_type_complex_s8]
+      = builtin->builtin_complex_s8;
+    lai->primitive_type_vector [f_primitive_type_complex_s16]
+      = builtin->builtin_complex_s16;
+    lai->primitive_type_vector [f_primitive_type_void]
+      = builtin->builtin_void;
+
+    lai->bool_type_symbol = "logical";
+    lai->bool_type_default = builtin->builtin_logical_s2;
+  }
+
+  /* See language.h.  */
+  unsigned int search_name_hash (const char *name) const override
+  {
+    return cp_search_name_hash (name);
+  }
 
-#if 0
+  /* See language.h.  */
 
-/* The following function is called to patch up the offsets 
-   for the statics contained in the COMMON block named
-   "name."  */
+  char *demangle (const char *mangled, int options) const override
+  {
+      /* We could support demangling here to provide module namespaces
+        also for inferiors with only minimal symbol table (ELF symbols).
+        Just the mangling standard is not standardized across compilers
+        and there is no DW_AT_producer available for inferiors with only
+        the ELF symbols to check the mangling kind.  */
+    return nullptr;
+  }
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    f_print_type (type, varstring, stream, show, level, flags);
+  }
 
-static void
-patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum)
-{
-  COMMON_ENTRY_PTR entry;
+  /* See language.h.  This just returns default set of word break
+     characters but with the modules separator `::' removed.  */
 
-  blk->offset = offset;                /* Keep this around for future use. */
+  const char *word_break_characters (void) const override
+  {
+    static char *retval;
 
-  entry = blk->entries;
+    if (!retval)
+      {
+       char *s;
 
-  while (entry != NULL)
-    {
-      SYMBOL_VALUE (entry->symbol) += offset;
-      SYMBOL_SECTION (entry->symbol) = secnum;
+       retval = xstrdup (language_defn::word_break_characters ());
+       s = strchr (retval, ':');
+       if (s)
+         {
+           char *last_char = &s[strlen (s) - 1];
 
-      entry = entry->next;
-    }
-  blk->secnum = secnum;
-}
+           *s = *last_char;
+           *last_char = 0;
+         }
+      }
+    return retval;
+  }
 
-/* Patch all commons named "name" that need patching.Since COMMON
-   blocks occur with relative infrequency, we simply do a linear scan on
-   the name.  Eventually, the best way to do this will be a
-   hashed-lookup.  Secnum is the section number for the .bss section
-   (which is where common data lives). */
 
-static void
-patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum)
-{
+  /* See language.h.  */
 
-  SAVED_F77_COMMON_PTR tmp;
+  void collect_symbol_completion_matches (completion_tracker &tracker,
+                                         complete_symbol_mode mode,
+                                         symbol_name_match_type name_match_type,
+                                         const char *text, const char *word,
+                                         enum type_code code) const override
+  {
+    /* Consider the modules separator :: as a valid symbol name character
+       class.  */
+    default_collect_symbol_completion_matches_break_on (tracker, mode,
+                                                       name_match_type,
+                                                       text, word, ":",
+                                                       code);
+  }
+
+  /* See language.h.  */
+
+  void value_print_inner
+       (struct value *val, struct ui_file *stream, int recurse,
+        const struct value_print_options *options) const override
+  {
+    return f_value_print_inner (val, stream, recurse, options);
+  }
 
-  /* For blank common blocks, change the canonical reprsentation 
-     of a blank name */
+  /* See language.h.  */
 
-  if ((STREQ (name, BLANK_COMMON_NAME_ORIGINAL)) ||
-      (STREQ (name, BLANK_COMMON_NAME_MF77)))
-    {
-      free (name);
-      name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
-      strcpy (name, BLANK_COMMON_NAME_LOCAL);
-    }
+  struct block_symbol lookup_symbol_nonlocal
+       (const char *name, const struct block *block,
+        const domain_enum domain) const override
+  {
+    return cp_lookup_symbol_nonlocal (this, name, block, domain);
+  }
 
-  tmp = head_common_list;
+  /* See language.h.  */
 
-  while (tmp != NULL)
-    {
-      if (COMMON_NEEDS_PATCHING (tmp))
-       if (STREQ (tmp->name, name))
-         patch_common_entries (tmp, offset, secnum);
+  int parser (struct parser_state *ps) const override
+  {
+    return f_parse (ps);
+  }
 
-      tmp = tmp->next;
-    }
-}
-#endif
-
-/* This macro adds the symbol-number for the start of the function 
-   (the symbol number of the .bf) referenced by symnum_fcn to a 
-   list.  This list, in reality should be a FIFO queue but since 
-   #line pragmas sometimes cause line ranges to get messed up 
-   we simply create a linear list.  This list can then be searched 
-   first by a queueing algorithm and upon failure fall back to 
-   a linear scan. */
-
-#if 0
-#define ADD_BF_SYMNUM(bf_sym,fcn_sym) \
-  \
-  if (saved_bf_list == NULL) \
-{ \
-    tmp_bf_ptr = allocate_saved_bf_node(); \
-      \
-       tmp_bf_ptr->symnum_bf = (bf_sym); \
-         tmp_bf_ptr->symnum_fcn = (fcn_sym);  \
-           tmp_bf_ptr->next = NULL; \
-             \
-               current_head_bf_list = saved_bf_list = tmp_bf_ptr; \
-                 saved_bf_list_end = tmp_bf_ptr; \
-                 } \
-else \
-{  \
-     tmp_bf_ptr = allocate_saved_bf_node(); \
-       \
-         tmp_bf_ptr->symnum_bf = (bf_sym);  \
-          tmp_bf_ptr->symnum_fcn = (fcn_sym);  \
-            tmp_bf_ptr->next = NULL;  \
-              \
-                saved_bf_list_end->next = tmp_bf_ptr;  \
-                  saved_bf_list_end = tmp_bf_ptr; \
-                  }
-#endif
-
-/* This function frees the entire (.bf,function) list */
-
-#if 0
-static void
-clear_bf_list (void)
-{
+protected:
 
-  SAVED_BF_PTR tmp = saved_bf_list;
-  SAVED_BF_PTR next = NULL;
+  /* See language.h.  */
 
-  while (tmp != NULL)
-    {
-      next = tmp->next;
-      free (tmp);
-      tmp = next;
-    }
-  saved_bf_list = NULL;
-}
-#endif
+  symbol_name_matcher_ftype *get_symbol_name_matcher_inner
+       (const lookup_name_info &lookup_name) const override
+  {
+    return cp_get_symbol_name_matcher (lookup_name);
+  }
+};
 
-int global_remote_debug;
+/* Single instance of the Fortran language class.  */
 
-#if 0
+static f_language f_language_defn;
 
-static long
-get_bf_for_fcn (long the_function)
+static void *
+build_fortran_types (struct gdbarch *gdbarch)
 {
-  SAVED_BF_PTR tmp;
-  int nprobes = 0;
+  struct builtin_f_type *builtin_f_type
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_f_type);
+
+  builtin_f_type->builtin_void
+    = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
+
+  builtin_f_type->builtin_character
+    = arch_type (gdbarch, TYPE_CODE_CHAR, TARGET_CHAR_BIT, "character");
+
+  builtin_f_type->builtin_logical_s1
+    = arch_boolean_type (gdbarch, TARGET_CHAR_BIT, 1, "logical*1");
+
+  builtin_f_type->builtin_integer_s2
+    = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch), 0,
+                        "integer*2");
+
+  builtin_f_type->builtin_integer_s8
+    = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch), 0,
+                        "integer*8");
+
+  builtin_f_type->builtin_logical_s2
+    = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1,
+                        "logical*2");
+
+  builtin_f_type->builtin_logical_s8
+    = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1,
+                        "logical*8");
+
+  builtin_f_type->builtin_integer
+    = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0,
+                        "integer");
+
+  builtin_f_type->builtin_logical
+    = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1,
+                        "logical*4");
+
+  builtin_f_type->builtin_real
+    = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
+                      "real", gdbarch_float_format (gdbarch));
+  builtin_f_type->builtin_real_s8
+    = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
+                      "real*8", gdbarch_double_format (gdbarch));
+  auto fmt = gdbarch_floatformat_for_type (gdbarch, "real(kind=16)", 128);
+  if (fmt != nullptr)
+    builtin_f_type->builtin_real_s16
+      = arch_float_type (gdbarch, 128, "real*16", fmt);
+  else if (gdbarch_long_double_bit (gdbarch) == 128)
+    builtin_f_type->builtin_real_s16
+      = arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
+                        "real*16", gdbarch_long_double_format (gdbarch));
+  else
+    builtin_f_type->builtin_real_s16
+      = arch_type (gdbarch, TYPE_CODE_ERROR, 128, "real*16");
 
-  /* First use a simple queuing algorithm (i.e. look and see if the 
-     item at the head of the queue is the one you want)  */
+  builtin_f_type->builtin_complex_s8
+    = init_complex_type ("complex*8", builtin_f_type->builtin_real);
+  builtin_f_type->builtin_complex_s16
+    = init_complex_type ("complex*16", builtin_f_type->builtin_real_s8);
 
-  if (saved_bf_list == NULL)
-    internal_error ("cannot get .bf node off empty list");
+  if (builtin_f_type->builtin_real_s16->code () == TYPE_CODE_ERROR)
+    builtin_f_type->builtin_complex_s32
+      = arch_type (gdbarch, TYPE_CODE_ERROR, 256, "complex*32");
+  else
+    builtin_f_type->builtin_complex_s32
+      = init_complex_type ("complex*32", builtin_f_type->builtin_real_s16);
 
-  if (current_head_bf_list != NULL)
-    if (current_head_bf_list->symnum_fcn == the_function)
-      {
-       if (global_remote_debug)
-         fprintf (stderr, "*");
+  return builtin_f_type;
+}
 
-       tmp = current_head_bf_list;
-       current_head_bf_list = current_head_bf_list->next;
-       return (tmp->symnum_bf);
-      }
+static struct gdbarch_data *f_type_data;
+
+const struct builtin_f_type *
+builtin_f_type (struct gdbarch *gdbarch)
+{
+  return (const struct builtin_f_type *) gdbarch_data (gdbarch, f_type_data);
+}
 
-  /* If the above did not work (probably because #line directives were 
-     used in the sourcefile and they messed up our internal tables) we now do
-     the ugly linear scan */
+void _initialize_f_language ();
+void
+_initialize_f_language ()
+{
+  f_type_data = gdbarch_data_register_post_init (build_fortran_types);
+}
 
-  if (global_remote_debug)
-    fprintf (stderr, "\ndefaulting to linear scan\n");
+/* See f-lang.h.  */
 
-  nprobes = 0;
-  tmp = saved_bf_list;
-  while (tmp != NULL)
+struct value *
+fortran_argument_convert (struct value *value, bool is_artificial)
+{
+  if (!is_artificial)
     {
-      nprobes++;
-      if (tmp->symnum_fcn == the_function)
+      /* If the value is not in the inferior e.g. registers values,
+        convenience variables and user input.  */
+      if (VALUE_LVAL (value) != lval_memory)
        {
-         if (global_remote_debug)
-           fprintf (stderr, "Found in %d probes\n", nprobes);
-         current_head_bf_list = tmp->next;
-         return (tmp->symnum_bf);
+         struct type *type = value_type (value);
+         const int length = TYPE_LENGTH (type);
+         const CORE_ADDR addr
+           = value_as_long (value_allocate_space_in_inferior (length));
+         write_memory (addr, value_contents (value), length);
+         struct value *val
+           = value_from_contents_and_address (type, value_contents (value),
+                                              addr);
+         return value_addr (val);
        }
-      tmp = tmp->next;
+      else
+       return value_addr (value); /* Program variables, e.g. arrays.  */
     }
-
-  return (-1);
+    return value;
 }
 
-static SAVED_FUNCTION_PTR saved_function_list = NULL;
-static SAVED_FUNCTION_PTR saved_function_list_end = NULL;
+/* See f-lang.h.  */
 
-static void
-clear_function_list (void)
+struct type *
+fortran_preserve_arg_pointer (struct value *arg, struct type *type)
 {
-  SAVED_FUNCTION_PTR tmp = saved_function_list;
-  SAVED_FUNCTION_PTR next = NULL;
-
-  while (tmp != NULL)
-    {
-      next = tmp->next;
-      free (tmp);
-      tmp = next;
-    }
-
-  saved_function_list = NULL;
+  if (value_type (arg)->code () == TYPE_CODE_PTR)
+    return value_type (arg);
+  return type;
 }
-#endif
This page took 0.04153 seconds and 4 git commands to generate.