]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/f-lang.c
gdb: Represent all languages as sub-classes of language_defn
[thirdparty/binutils-gdb.git] / gdb / f-lang.c
index 3368d01c105ee0c3a8b5e9258c13a4afeb29297d..46d386e0477c3cef7687c094dfb4cbdb1bf98562 100644 (file)
@@ -1,7 +1,6 @@
 /* Fortran language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1993-1996, 1998-2005, 2007-2012 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).
    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"
 
-
-/* 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;
-  };
-
-
-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;
-  };
-
-typedef struct saved_fcn SAVED_FUNCTION, *SAVED_FUNCTION_PTR;
-typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR;
+#include <math.h>
 
 /* Local functions */
 
-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 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);
@@ -92,7 +59,7 @@ f_get_encoding (struct type *type)
       encoding = target_charset (get_type_arch (type));
       break;
     case 4:
-      if (gdbarch_byte_order (get_type_arch (type)) == BFD_ENDIAN_BIG)
+      if (type_byte_order (type) == BFD_ENDIAN_BIG)
        encoding = "UTF-32BE";
       else
        encoding = "UTF-32LE";
@@ -178,7 +145,7 @@ 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
 enum f_primitive_types {
@@ -238,7 +205,7 @@ f_language_arch_info (struct gdbarch *gdbarch,
 
 /* Remove the modules separator :: from the default break list.  */
 
-static char *
+static const char *
 f_word_break_characters (void)
 {
   static char *retval;
@@ -263,54 +230,475 @@ f_word_break_characters (void)
 /* Consider the modules separator :: as a valid symbol name character
    class.  */
 
-static char **
-f_make_symbol_completion_list (char *text, char *word)
+static void
+f_collect_symbol_completion_matches (completion_tracker &tracker,
+                                    complete_symbol_mode mode,
+                                    symbol_name_match_type compare_name,
+                                    const char *text, const char *word,
+                                    enum type_code code)
+{
+  default_collect_symbol_completion_matches_break_on (tracker, mode,
+                                                     compare_name,
+                                                     text, word, ":", code);
+}
+
+/* Special expression evaluation cases for Fortran.  */
+
+static struct value *
+evaluate_subexp_f (struct type *expect_type, struct expression *exp,
+                  int *pos, enum noside noside)
+{
+  struct value *arg1 = NULL, *arg2 = NULL;
+  enum exp_opcode op;
+  int pc;
+  struct type *type;
+
+  pc = *pos;
+  *pos += 1;
+  op = exp->elts[pc].opcode;
+
+  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));
+
+    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);
+      }
+
+    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);
+      }
+
+    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));
+      }
+
+    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)));
+    }
+
+  /* Should be unreachable.  */
+  return nullptr;
+}
+
+/* Return true if TYPE is a string.  */
+
+static bool
+f_is_string_type_p (struct type *type)
 {
-  return default_make_symbol_completion_list_break_on (text, word, ":");
+  type = check_typedef (type);
+  return (type->code () == TYPE_CODE_STRING
+         || (type->code () == TYPE_CODE_ARRAY
+             && TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR));
 }
 
-const struct language_defn f_language_defn =
+/* 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:
+    case UNOP_FORTRAN_FLOOR:
+    case UNOP_FORTRAN_CEILING:
+      oplen = 1;
+      args = 1;
+      break;
+
+    case BINOP_FORTRAN_CMPLX:
+    case BINOP_FORTRAN_MODULO:
+      oplen = 1;
+      args = 2;
+      break;
+    }
+
+  *oplenp = oplen;
+  *argsp = args;
+}
+
+/* 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_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);
+}
+
+/* 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);
+}
+
+/* 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:
+      print_unop_subexp_f (exp, pos, stream, prec, "KIND");
+      return;
+
+    case UNOP_FORTRAN_FLOOR:
+      print_unop_subexp_f (exp, pos, stream, prec, "FLOOR");
+      return;
+
+    case UNOP_FORTRAN_CEILING:
+      print_unop_subexp_f (exp, pos, stream, prec, "CEILING");
+      return;
+
+    case BINOP_FORTRAN_CMPLX:
+      print_binop_subexp_f (exp, pos, stream, prec, "CMPLX");
+      return;
+
+    case BINOP_FORTRAN_MODULO:
+      print_binop_subexp_f (exp, pos, stream, prec, "MODULO");
+      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:
+    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;
+    }
+
+  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:
+    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 0;
+}
+
+static const char *f_extensions[] =
+{
+  ".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
+  ".f90", ".F90", ".f95", ".F95", ".f03", ".F03", ".f08", ".F08",
+  NULL
+};
+
+/* 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
+};
+
+/* Constant data that describes the Fortran language.  */
+
+extern const struct language_data f_language_data =
 {
   "fortran",
+  "Fortran",
   language_fortran,
   range_check_on,
-  type_check_on,
   case_sensitive_off,
   array_column_major,
   macro_expansion_no,
-  &exp_descriptor_standard,
+  f_extensions,
+  &exp_descriptor_f,
   f_parse,                     /* parser */
-  f_error,                     /* parser error function */
   null_post_parser,
   f_printchar,                 /* Print character constant */
   f_printstr,                  /* function to print string constant */
   f_emit_char,                 /* Function to print a single character */
   f_print_type,                        /* Print a type using appropriate syntax */
-  default_print_typedef,       /* Print a typedef using appropriate syntax */
-  f_val_print,                 /* Print a value using appropriate syntax */
+  f_print_typedef,             /* Print a typedef using appropriate syntax */
+  f_value_print_innner,                /* la_value_print_inner */
   c_value_print,               /* FIXME */
   default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                        /* name_of_this */
+  false,                       /* la_store_sym_names_in_linkage_form_p */
   cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
+
+  /* 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.  */
   NULL,                                /* Language specific symbol demangler */
+  NULL,
   NULL,                                /* Language specific
                                   class_name_from_physname */
   f_op_print_tab,              /* expression operators for printing */
   0,                           /* arrays are first-class (not c-style) */
   1,                           /* String lower bound */
   f_word_break_characters,
-  f_make_symbol_completion_list,
+  f_collect_symbol_completion_matches,
   f_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
-  default_get_string,
-  NULL,                                /* la_get_symbol_name_cmp */
+  c_watch_location_expression,
+  cp_get_symbol_name_matcher,  /* la_get_symbol_name_matcher */
   iterate_over_symbols,
-  LANG_MAGIC
+  cp_search_name_hash,
+  &default_varobj_ops,
+  NULL,
+  NULL,
+  f_is_string_type_p,
+  "(...)"                      /* la_struct_too_deep_ellipsis */
+};
+
+/* Class representing the Fortran language.  */
+
+class f_language : public language_defn
+{
+public:
+  f_language ()
+    : language_defn (language_fortran, f_language_data)
+  { /* Nothing.  */ }
 };
 
+/* Single instance of the Fortran language class.  */
+
+static f_language f_language_defn;
+
 static void *
 build_fortran_types (struct gdbarch *gdbarch)
 {
@@ -318,10 +706,10 @@ build_fortran_types (struct gdbarch *gdbarch)
     = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_f_type);
 
   builtin_f_type->builtin_void
-    = arch_type (gdbarch, TYPE_CODE_VOID, 1, "VOID");
+    = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
 
   builtin_f_type->builtin_character
-    = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "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");
@@ -330,6 +718,10 @@ build_fortran_types (struct gdbarch *gdbarch)
     = 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");
@@ -348,23 +740,33 @@ build_fortran_types (struct gdbarch *gdbarch)
 
   builtin_f_type->builtin_real
     = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
-                      "real", NULL);
+                      "real", gdbarch_float_format (gdbarch));
   builtin_f_type->builtin_real_s8
     = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
-                      "real*8", NULL);
-  builtin_f_type->builtin_real_s16
-    = arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
-                      "real*16", NULL);
+                      "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");
 
   builtin_f_type->builtin_complex_s8
-    = arch_complex_type (gdbarch, "complex*8",
-                        builtin_f_type->builtin_real);
+    = init_complex_type ("complex*8", builtin_f_type->builtin_real);
   builtin_f_type->builtin_complex_s16
-    = arch_complex_type (gdbarch, "complex*16",
-                        builtin_f_type->builtin_real_s8);
-  builtin_f_type->builtin_complex_s32
-    = arch_complex_type (gdbarch, "complex*32",
-                        builtin_f_type->builtin_real_s16);
+    = init_complex_type ("complex*16", builtin_f_type->builtin_real_s8);
+
+  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);
 
   return builtin_f_type;
 }
@@ -374,405 +776,49 @@ static struct gdbarch_data *f_type_data;
 const struct builtin_f_type *
 builtin_f_type (struct gdbarch *gdbarch)
 {
-  return gdbarch_data (gdbarch, f_type_data);
+  return (const struct builtin_f_type *) gdbarch_data (gdbarch, f_type_data);
 }
 
+void _initialize_f_language ();
 void
-_initialize_f_language (void)
+_initialize_f_language ()
 {
   f_type_data = gdbarch_data_register_post_init (build_fortran_types);
-
-  add_language (&f_language_defn);
 }
 
-#if 0
-static SAVED_BF_PTR
-allocate_saved_bf_node (void)
-{
-  SAVED_BF_PTR new;
-
-  new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF));
-  return (new);
-}
-
-static SAVED_FUNCTION *
-allocate_saved_function_node (void)
-{
-  SAVED_FUNCTION *new;
-
-  new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION));
-  return (new);
-}
+/* See f-lang.h.  */
 
-static SAVED_F77_COMMON_PTR
-allocate_saved_f77_common_node (void)
+struct value *
+fortran_argument_convert (struct value *value, bool is_artificial)
 {
-  SAVED_F77_COMMON_PTR new;
-
-  new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON));
-  return (new);
-}
-
-static COMMON_ENTRY_PTR
-allocate_common_entry_node (void)
-{
-  COMMON_ENTRY_PTR new;
-
-  new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY));
-  return (new);
-}
-#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.  */
-
-static void
-add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab)
-{
-  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.  */
-
-
-  if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0
-      || strcmp (name, BLANK_COMMON_NAME_MF77) == 0)
+  if (!is_artificial)
     {
-
-      xfree (name);
-      name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
-      strcpy (name, BLANK_COMMON_NAME_LOCAL);
-    }
-
-  tmp = allocate_saved_f77_common_node ();
-
-  local_copy_func_stab = xmalloc (strlen (func_stab) + 1);
-  strcpy (local_copy_func_stab, func_stab);
-
-  tmp->name = xmalloc (strlen (name) + 1);
-
-  /* local_copy_func_stab is a stabstring, let us first extract the 
-     function name from the stab by NULLing out the ':' character.  */
-
-
-  c = NULL;
-  c = strchr (local_copy_func_stab, ':');
-
-  if (c)
-    *c = '\0';
-  else
-    error (_("Malformed function STAB found in add_common_block()"));
-
-
-  tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1);
-
-  strcpy (tmp->owning_function, local_copy_func_stab);
-
-  strcpy (tmp->name, name);
-  tmp->offset = offset;
-  tmp->next = NULL;
-  tmp->entries = NULL;
-  tmp->secnum = secnum;
-
-  current_common = tmp;
-
-  if (head_common_list == NULL)
-    {
-      head_common_list = tail_common_list = tmp;
-    }
-  else
-    {
-      tail_common_list->next = tmp;
-      tail_common_list = tmp;
-    }
-}
-#endif
-
-/* The following function simply enters a given common entry onto 
-   the "current_common" block that has been saved away.  */
-
-#if 0
-static void
-add_common_entry (struct symbol *entry_sym_ptr)
-{
-  COMMON_ENTRY_PTR tmp;
-
-
-
-  /* The order of this list is important, since 
-     we expect the entries to appear in decl.
-     order when we later issue "info common" calls.  */
-
-  tmp = allocate_common_entry_node ();
-
-  tmp->next = NULL;
-  tmp->symbol = entry_sym_ptr;
-
-  if (current_common == NULL)
-    error (_("Attempt to add COMMON entry with no block open!"));
-  else
-    {
-      if (current_common->entries == NULL)
+      /* If the value is not in the inferior e.g. registers values,
+        convenience variables and user input.  */
+      if (VALUE_LVAL (value) != lval_memory)
        {
-         current_common->entries = tmp;
-         current_common->end_of_entries = tmp;
+         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);
        }
       else
-       {
-         current_common->end_of_entries->next = tmp;
-         current_common->end_of_entries = tmp;
-       }
-    }
-}
-#endif
-
-/* This routine finds the first encountred COMMON block named "name".  */
-
-#if 0
-static SAVED_F77_COMMON_PTR
-find_first_common_named (char *name)
-{
-
-  SAVED_F77_COMMON_PTR tmp;
-
-  tmp = head_common_list;
-
-  while (tmp != NULL)
-    {
-      if (strcmp (tmp->name, name) == 0)
-       return (tmp);
-      else
-       tmp = tmp->next;
-    }
-  return (NULL);
-}
-#endif
-
-/* This routine finds the first encountred COMMON block named "name" 
-   that belongs to function funcname.  */
-
-SAVED_F77_COMMON_PTR
-find_common_for_function (const char *name, const char *funcname)
-{
-
-  SAVED_F77_COMMON_PTR tmp;
-
-  tmp = head_common_list;
-
-  while (tmp != NULL)
-    {
-      if (strcmp (tmp->name, name) == 0
-         && strcmp (tmp->owning_function, funcname) == 0)
-       return (tmp);
-      else
-       tmp = tmp->next;
+       return value_addr (value); /* Program variables, e.g. arrays.  */
     }
-  return (NULL);
+    return value;
 }
 
+/* See f-lang.h.  */
 
-#if 0
-
-/* The following function is called to patch up the offsets 
-   for the statics contained in the COMMON block named
-   "name."  */
-
-static void
-patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum)
-{
-  COMMON_ENTRY_PTR entry;
-
-  blk->offset = offset;                /* Keep this around for future use.  */
-
-  entry = blk->entries;
-
-  while (entry != NULL)
-    {
-      SYMBOL_VALUE (entry->symbol) += offset;
-      SYMBOL_SECTION (entry->symbol) = secnum;
-
-      entry = entry->next;
-    }
-  blk->secnum = secnum;
-}
-
-/* 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)
-{
-
-  SAVED_F77_COMMON_PTR tmp;
-
-  /* For blank common blocks, change the canonical reprsentation 
-     of a blank name */
-
-  if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0
-      || strcmp (name, BLANK_COMMON_NAME_MF77) == 0)
-    {
-      xfree (name);
-      name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
-      strcpy (name, BLANK_COMMON_NAME_LOCAL);
-    }
-
-  tmp = head_common_list;
-
-  while (tmp != NULL)
-    {
-      if (COMMON_NEEDS_PATCHING (tmp))
-       if (strcmp (tmp->name, name) == 0)
-         patch_common_entries (tmp, offset, secnum);
-
-      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)
+struct type *
+fortran_preserve_arg_pointer (struct value *arg, struct type *type)
 {
-
-  SAVED_BF_PTR tmp = saved_bf_list;
-  SAVED_BF_PTR next = NULL;
-
-  while (tmp != NULL)
-    {
-      next = tmp->next;
-      xfree (tmp);
-      tmp = next;
-    }
-  saved_bf_list = NULL;
-}
-#endif
-
-int global_remote_debug;
-
-#if 0
-
-static long
-get_bf_for_fcn (long the_function)
-{
-  SAVED_BF_PTR tmp;
-  int nprobes = 0;
-
-  /* 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).  */
-
-  if (saved_bf_list == NULL)
-    internal_error (__FILE__, __LINE__,
-                   _("cannot get .bf node off empty list"));
-
-  if (current_head_bf_list != NULL)
-    if (current_head_bf_list->symnum_fcn == the_function)
-      {
-       if (global_remote_debug)
-         fprintf_unfiltered (gdb_stderr, "*");
-
-       tmp = current_head_bf_list;
-       current_head_bf_list = current_head_bf_list->next;
-       return (tmp->symnum_bf);
-      }
-
-  /* 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.  */
-
-  if (global_remote_debug)
-    fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n");
-
-  nprobes = 0;
-  tmp = saved_bf_list;
-  while (tmp != NULL)
-    {
-      nprobes++;
-      if (tmp->symnum_fcn == the_function)
-       {
-         if (global_remote_debug)
-           fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes);
-         current_head_bf_list = tmp->next;
-         return (tmp->symnum_bf);
-       }
-      tmp = tmp->next;
-    }
-
-  return (-1);
-}
-
-static SAVED_FUNCTION_PTR saved_function_list = NULL;
-static SAVED_FUNCTION_PTR saved_function_list_end = NULL;
-
-static void
-clear_function_list (void)
-{
-  SAVED_FUNCTION_PTR tmp = saved_function_list;
-  SAVED_FUNCTION_PTR next = NULL;
-
-  while (tmp != NULL)
-    {
-      next = tmp->next;
-      xfree (tmp);
-      tmp = next;
-    }
-
-  saved_function_list = NULL;
+  if (value_type (arg)->code () == TYPE_CODE_PTR)
+    return value_type (arg);
+  return type;
 }
-#endif