Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes.
[binutils-gdb.git] / gdb / f-lang.c
index 1b66ae341598605957de656f3b8b01297e81e802..0f3de163c90683c63fd1c615cbd49ea3efdba451 100644 (file)
@@ -1,6 +1,6 @@
 /* Fortran language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1993-2021 Free Software Foundation, Inc.
+   Copyright (C) 1993-2022 Free Software Foundation, Inc.
 
    Contributed by Motorola.  Adapted from the C parser by Farooq Butt
    (fmbutt@engage.sps.mot.com).
@@ -50,8 +50,8 @@ static void
 show_repack_array_slices (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Repacking of Fortran array slices is %s.\n"),
-                   value);
+  gdb_printf (file, _("Repacking of Fortran array slices is %s.\n"),
+             value);
 }
 
 /* Debugging of Fortran's array slicing.  */
@@ -63,8 +63,8 @@ show_fortran_array_slicing_debug (struct ui_file *file, int from_tty,
                                  struct cmd_list_element *c,
                                  const char *value)
 {
-  fprintf_filtered (file, _("Debugging of Fortran array slicing is %s.\n"),
-                   value);
+  gdb_printf (file, _("Debugging of Fortran array slicing is %s.\n"),
+             value);
 }
 
 /* Local functions */
@@ -101,8 +101,6 @@ f_language::get_encoding (struct type *type)
   return encoding;
 }
 
-\f
-
 /* A helper function for the "bound" intrinsics that checks that TYPE
    is an array.  LBOUND_P is true for lower bound; this is used for
    the error message, if any.  */
@@ -135,9 +133,9 @@ fortran_bounds_all_dims (bool lbound_p,
   /* Allocate a result value of the correct type.  */
   struct type *range
     = create_static_range_type (nullptr,
-                               builtin_type (gdbarch)->builtin_int,
+                               builtin_f_type (gdbarch)->builtin_integer,
                                1, ndimensions);
-  struct type *elm_type = builtin_type (gdbarch)->builtin_long_long;
+  struct type *elm_type = builtin_f_type (gdbarch)->builtin_integer;
   struct type *result_type = create_array_type (nullptr, elm_type, range);
   struct value *result = allocate_value (result_type);
 
@@ -172,13 +170,12 @@ fortran_bounds_all_dims (bool lbound_p,
 
 /* Return the lower bound (when LBOUND_P is true) or the upper bound (when
    LBOUND_P is false) for dimension DIM_VAL (which must be an integer) of
-   ARRAY (which must be an array).  GDBARCH is the current architecture.  */
+   ARRAY (which must be an array).  RESULT_TYPE corresponds to the type kind
+   the function should be evaluated in.  */
 
-static struct value *
-fortran_bounds_for_dimension (bool lbound_p,
-                             struct gdbarch *gdbarch,
-                             struct value *array,
-                             struct value *dim_val)
+static value *
+fortran_bounds_for_dimension (bool lbound_p, value *array, value *dim_val,
+                             type* result_type)
 {
   /* Check the requested dimension is valid for this array.  */
   type *array_type = check_typedef (value_type (array));
@@ -192,9 +189,6 @@ fortran_bounds_for_dimension (bool lbound_p,
        error (_("UBOUND dimension must be from 1 to %d"), ndimensions);
     }
 
-  /* The type for the result.  */
-  struct type *bound_type = builtin_type (gdbarch)->builtin_long_long;
-
   /* Walk the dimensions backwards, due to the ordering in which arrays are
      laid out the first dimension is the most inner.  */
   for (int i = ndimensions - 1; i >= 0; --i)
@@ -210,7 +204,7 @@ fortran_bounds_for_dimension (bool lbound_p,
          else
            b = f77_get_upperbound (array_type);
 
-         return value_from_longest (bound_type, b);
+         return value_from_longest (result_type, b);
        }
 
       /* Peel off another dimension of the array.  */
@@ -219,7 +213,6 @@ fortran_bounds_for_dimension (bool lbound_p,
 
   gdb_assert_not_reached ("failed to find matching dimension");
 }
-\f
 
 /* Return the number of dimensions for a Fortran array or string.  */
 
@@ -263,7 +256,7 @@ public:
      will be creating values for each element as we load them and then copy
      them into the M_DEST value.  Set a value mark so we can free these
      temporary values.  */
-  void start_dimension (bool inner_p)
+  void start_dimension (struct type *index_type, LONGEST nelts, bool inner_p)
   {
     if (inner_p)
       {
@@ -330,7 +323,8 @@ public:
   /* Create a lazy value in target memory representing a single element,
      then load the element into GDB's memory and copy the contents into the
      destination value.  */
-  void process_element (struct type *elt_type, LONGEST elt_off, bool last_p)
+  void process_element (struct type *elt_type, LONGEST elt_off,
+                       LONGEST index, bool last_p)
   {
     copy_element_to_dest (value_at_lazy (elt_type, m_addr + elt_off));
   }
@@ -368,7 +362,8 @@ public:
   /* Extract an element of ELT_TYPE at offset (M_BASE_OFFSET + ELT_OFF)
      from the content buffer of M_VAL then copy this extracted value into
      the repacked destination value.  */
-  void process_element (struct type *elt_type, LONGEST elt_off, bool last_p)
+  void process_element (struct type *elt_type, LONGEST elt_off,
+                       LONGEST index, bool last_p)
   {
     struct value *elt
       = value_from_component (m_val, elt_type, (elt_off + m_base_offset));
@@ -578,6 +573,197 @@ eval_op_f_associated (struct type *expect_type,
   return fortran_associated (exp->gdbarch, exp->language_defn, arg1, arg2);
 }
 
+/* Implement FORTRAN_ARRAY_SIZE expression, this corresponds to the 'SIZE'
+   keyword.  RESULT_TYPE corresponds to the type kind the function should be
+   evaluated in, ARRAY is the value that should be an array, though this will
+   not have been checked before calling this function.  DIM is optional, if
+   present then it should be an integer identifying a dimension of the
+   array to ask about.  As with ARRAY the validity of DIM is not checked
+   before calling this function.
+
+   Return either the total number of elements in ARRAY (when DIM is
+   nullptr), or the number of elements in dimension DIM.  */
+
+static value *
+fortran_array_size (value *array, value *dim_val, type *result_type)
+{
+  /* Check that ARRAY is the correct type.  */
+  struct type *array_type = check_typedef (value_type (array));
+  if (array_type->code () != TYPE_CODE_ARRAY)
+    error (_("SIZE can only be applied to arrays"));
+  if (type_not_allocated (array_type) || type_not_associated (array_type))
+    error (_("SIZE can only be used on allocated/associated arrays"));
+
+  int ndimensions = calc_f77_array_dims (array_type);
+  int dim = -1;
+  LONGEST result = 0;
+
+  if (dim_val != nullptr)
+    {
+      if (check_typedef (value_type (dim_val))->code () != TYPE_CODE_INT)
+       error (_("DIM argument to SIZE must be an integer"));
+      dim = (int) value_as_long (dim_val);
+
+      if (dim < 1 || dim > ndimensions)
+       error (_("DIM argument to SIZE must be between 1 and %d"),
+              ndimensions);
+    }
+
+  /* Now walk over all the dimensions of the array totalling up the
+     elements in each dimension.  */
+  for (int i = ndimensions - 1; i >= 0; --i)
+    {
+      /* If this is the requested dimension then we're done.  Grab the
+        bounds and return.  */
+      if (i == dim - 1 || dim == -1)
+       {
+         LONGEST lbound, ubound;
+         struct type *range = array_type->index_type ();
+
+         if (!get_discrete_bounds (range, &lbound, &ubound))
+           error (_("failed to find array bounds"));
+
+         LONGEST dim_size = (ubound - lbound + 1);
+         if (result == 0)
+           result = dim_size;
+         else
+           result *= dim_size;
+
+         if (dim != -1)
+           break;
+       }
+
+      /* Peel off another dimension of the array.  */
+      array_type = TYPE_TARGET_TYPE (array_type);
+    }
+
+  return value_from_longest (result_type, result);
+}
+
+/* See f-exp.h.  */
+
+struct value *
+eval_op_f_array_size (struct type *expect_type,
+                     struct expression *exp,
+                     enum noside noside,
+                     enum exp_opcode opcode,
+                     struct value *arg1)
+{
+  gdb_assert (opcode == FORTRAN_ARRAY_SIZE);
+
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_integer;
+  return fortran_array_size (arg1, nullptr, result_type);
+}
+
+/* See f-exp.h.  */
+
+struct value *
+eval_op_f_array_size (struct type *expect_type,
+                     struct expression *exp,
+                     enum noside noside,
+                     enum exp_opcode opcode,
+                     struct value *arg1,
+                     struct value *arg2)
+{
+  gdb_assert (opcode == FORTRAN_ARRAY_SIZE);
+
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_integer;
+  return fortran_array_size (arg1, arg2, result_type);
+}
+
+/* See f-exp.h.  */
+
+value *eval_op_f_array_size (type *expect_type, expression *exp, noside noside,
+                            exp_opcode opcode, value *arg1, value *arg2,
+                            type *kind_arg)
+{
+  gdb_assert (opcode == FORTRAN_ARRAY_SIZE);
+  gdb_assert (kind_arg->code () == TYPE_CODE_INT);
+
+  return fortran_array_size (arg1, arg2, kind_arg);
+}
+
+/* Implement UNOP_FORTRAN_SHAPE expression.  Both GDBARCH and LANG are
+   extracted from the expression being evaluated.  VAL is the value on
+   which 'shape' was used, this can be any type.
+
+   Return an array of integers.  If VAL is not an array then the returned
+   array should have zero elements.  If VAL is an array then the returned
+   array should have one element per dimension, with the element
+   containing the extent of that dimension from VAL.  */
+
+static struct value *
+fortran_array_shape (struct gdbarch *gdbarch, const language_defn *lang,
+                    struct value *val)
+{
+  struct type *val_type = check_typedef (value_type (val));
+
+  /* If we are passed an array that is either not allocated, or not
+     associated, then this is explicitly not allowed according to the
+     Fortran specification.  */
+  if (val_type->code () == TYPE_CODE_ARRAY
+      && (type_not_associated (val_type) || type_not_allocated (val_type)))
+    error (_("The array passed to SHAPE must be allocated or associated"));
+
+  /* The Fortran specification allows non-array types to be passed to this
+     function, in which case we get back an empty array.
+
+     Calculate the number of dimensions for the resulting array.  */
+  int ndimensions = 0;
+  if (val_type->code () == TYPE_CODE_ARRAY)
+    ndimensions = calc_f77_array_dims (val_type);
+
+  /* Allocate a result value of the correct type.  */
+  struct type *range
+    = create_static_range_type (nullptr,
+                               builtin_type (gdbarch)->builtin_int,
+                               1, ndimensions);
+  struct type *elm_type = builtin_f_type (gdbarch)->builtin_integer;
+  struct type *result_type = create_array_type (nullptr, elm_type, range);
+  struct value *result = allocate_value (result_type);
+  LONGEST elm_len = TYPE_LENGTH (elm_type);
+
+  /* Walk the array dimensions backwards due to the way the array will be
+     laid out in memory, the first dimension will be the most inner.
+
+     If VAL was not an array then ndimensions will be 0, in which case we
+     will never go around this loop.  */
+  for (LONGEST dst_offset = elm_len * (ndimensions - 1);
+       dst_offset >= 0;
+       dst_offset -= elm_len)
+    {
+      LONGEST lbound, ubound;
+
+      if (!get_discrete_bounds (val_type->index_type (), &lbound, &ubound))
+       error (_("failed to find array bounds"));
+
+      LONGEST dim_size = (ubound - lbound + 1);
+
+      /* And copy the value into the result value.  */
+      struct value *v = value_from_longest (elm_type, dim_size);
+      gdb_assert (dst_offset + TYPE_LENGTH (value_type (v))
+                 <= TYPE_LENGTH (value_type (result)));
+      gdb_assert (TYPE_LENGTH (value_type (v)) == elm_len);
+      value_contents_copy (result, dst_offset, v, 0, elm_len);
+
+      /* Peel another dimension of the array.  */
+      val_type = TYPE_TARGET_TYPE (val_type);
+    }
+
+  return result;
+}
+
+/* See f-exp.h.  */
+
+struct value *
+eval_op_f_array_shape (struct type *expect_type, struct expression *exp,
+                      enum noside noside, enum exp_opcode opcode,
+                      struct value *arg1)
+{
+  gdb_assert (opcode == UNOP_FORTRAN_SHAPE);
+  return fortran_array_shape (exp->gdbarch, exp->language_defn, arg1);
+}
+
 /* A helper function for UNOP_ABS.  */
 
 struct value *
@@ -592,7 +778,7 @@ eval_op_f_abs (struct type *expect_type, struct expression *exp,
     case TYPE_CODE_FLT:
       {
        double d
-         = fabs (target_float_to_host_double (value_contents (arg1),
+         = fabs (target_float_to_host_double (value_contents (arg1).data (),
                                               value_type (arg1)));
        return value_from_host_double (type, d);
       }
@@ -622,10 +808,10 @@ eval_op_f_mod (struct type *expect_type, struct expression *exp,
     case TYPE_CODE_FLT:
       {
        double d1
-         = target_float_to_host_double (value_contents (arg1),
+         = target_float_to_host_double (value_contents (arg1).data (),
                                         value_type (arg1));
        double d2
-         = target_float_to_host_double (value_contents (arg2),
+         = target_float_to_host_double (value_contents (arg2).data (),
                                         value_type (arg2));
        double d3 = fmod (d1, d2);
        return value_from_host_double (type, d3);
@@ -643,7 +829,22 @@ eval_op_f_mod (struct type *expect_type, struct expression *exp,
   error (_("MOD of type %s not supported"), TYPE_SAFE_NAME (type));
 }
 
-/* A helper function for UNOP_FORTRAN_CEILING.  */
+/* A helper function for the different FORTRAN_CEILING overloads.  Calculates
+   CEILING for ARG1 (a float type) and returns it in the requested kind type
+   RESULT_TYPE.  */
+
+static value *
+fortran_ceil_operation (value *arg1, type *result_type)
+{
+  if (value_type (arg1)->code () != TYPE_CODE_FLT)
+    error (_("argument to CEILING must be of type float"));
+  double val = target_float_to_host_double (value_contents (arg1).data (),
+                                           value_type (arg1));
+  val = ceil (val);
+  return value_from_longest (result_type, val);
+}
+
+/* A helper function for FORTRAN_CEILING.  */
 
 struct value *
 eval_op_f_ceil (struct type *expect_type, struct expression *exp,
@@ -651,32 +852,59 @@ eval_op_f_ceil (struct type *expect_type, struct expression *exp,
                enum exp_opcode opcode,
                struct value *arg1)
 {
-  struct type *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);
+  gdb_assert (opcode == FORTRAN_CEILING);
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_integer;
+  return fortran_ceil_operation (arg1, result_type);
 }
 
-/* A helper function for UNOP_FORTRAN_FLOOR.  */
+/* A helper function for FORTRAN_CEILING.  */
 
-struct value *
-eval_op_f_floor (struct type *expect_type, struct expression *exp,
-                enum noside noside,
-                enum exp_opcode opcode,
-                struct value *arg1)
+value *
+eval_op_f_ceil (type *expect_type, expression *exp, noside noside,
+               exp_opcode opcode, value *arg1, type *kind_arg)
 {
-  struct type *type = value_type (arg1);
-  if (type->code () != TYPE_CODE_FLT)
+  gdb_assert (opcode == FORTRAN_CEILING);
+  gdb_assert (kind_arg->code () == TYPE_CODE_INT);
+  return fortran_ceil_operation (arg1, kind_arg);
+}
+
+/* A helper function for the different FORTRAN_FLOOR overloads.  Calculates
+   FLOOR for ARG1 (a float type) and returns it in the requested kind type
+   RESULT_TYPE.  */
+
+static value *
+fortran_floor_operation (value *arg1, type *result_type)
+{
+  if (value_type (arg1)->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));
+  double val = target_float_to_host_double (value_contents (arg1).data (),
+                                           value_type (arg1));
   val = floor (val);
-  return value_from_host_double (type, val);
+  return value_from_longest (result_type, val);
+}
+
+/* A helper function for FORTRAN_FLOOR.  */
+
+struct value *
+eval_op_f_floor (struct type *expect_type, struct expression *exp,
+               enum noside noside,
+               enum exp_opcode opcode,
+               struct value *arg1)
+{
+  gdb_assert (opcode == FORTRAN_FLOOR);
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_integer;
+  return fortran_floor_operation (arg1, result_type);
+}
+
+/* A helper function for FORTRAN_FLOOR.  */
+
+struct value *
+eval_op_f_floor (type *expect_type, expression *exp, noside noside,
+                exp_opcode opcode, value *arg1, type *kind_arg)
+{
+  gdb_assert (opcode == FORTRAN_FLOOR);
+  gdb_assert (kind_arg->code () == TYPE_CODE_INT);
+  return fortran_floor_operation (arg1, kind_arg);
 }
 
 /* A helper function for BINOP_FORTRAN_MODULO.  */
@@ -705,10 +933,10 @@ eval_op_f_modulo (struct type *expect_type, struct expression *exp,
     case TYPE_CODE_FLT:
       {
        double a
-         = target_float_to_host_double (value_contents (arg1),
+         = target_float_to_host_double (value_contents (arg1).data (),
                                         value_type (arg1));
        double p
-         = target_float_to_host_double (value_contents (arg2),
+         = target_float_to_host_double (value_contents (arg2).data (),
                                         value_type (arg2));
        double result = fmod (a, p);
        if (result != 0 && (a < 0.0) != (p < 0.0))
@@ -719,7 +947,25 @@ eval_op_f_modulo (struct type *expect_type, struct expression *exp,
   error (_("MODULO of type %s not supported"), TYPE_SAFE_NAME (type));
 }
 
-/* A helper function for BINOP_FORTRAN_CMPLX.  */
+/* A helper function for FORTRAN_CMPLX.  */
+
+value *
+eval_op_f_cmplx (type *expect_type, expression *exp, noside noside,
+                exp_opcode opcode, value *arg1)
+{
+  gdb_assert (opcode == FORTRAN_CMPLX);
+
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_complex;
+
+  if (value_type (arg1)->code () == TYPE_CODE_COMPLEX)
+    return value_cast (result_type, arg1);
+  else
+    return value_literal_complex (arg1,
+                                 value_zero (value_type (arg1), not_lval),
+                                 result_type);
+}
+
+/* A helper function for FORTRAN_CMPLX.  */
 
 struct value *
 eval_op_f_cmplx (struct type *expect_type, struct expression *exp,
@@ -727,8 +973,28 @@ eval_op_f_cmplx (struct type *expect_type, struct expression *exp,
                 enum exp_opcode opcode,
                 struct value *arg1, struct value *arg2)
 {
-  struct type *type = builtin_f_type(exp->gdbarch)->builtin_complex_s16;
-  return value_literal_complex (arg1, arg2, type);
+  if (value_type (arg1)->code () == TYPE_CODE_COMPLEX
+      || value_type (arg2)->code () == TYPE_CODE_COMPLEX)
+    error (_("Types of arguments for CMPLX called with more then one argument "
+            "must be REAL or INTEGER"));
+
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_complex;
+  return value_literal_complex (arg1, arg2, result_type);
+}
+
+/* A helper function for FORTRAN_CMPLX.  */
+
+value *
+eval_op_f_cmplx (type *expect_type, expression *exp, noside noside,
+                exp_opcode opcode, value *arg1, value *arg2, type *kind_arg)
+{
+  gdb_assert (kind_arg->code () == TYPE_CODE_COMPLEX);
+  if (value_type (arg1)->code () == TYPE_CODE_COMPLEX
+      || value_type (arg2)->code () == TYPE_CODE_COMPLEX)
+    error (_("Types of arguments for CMPLX called with more then one argument "
+            "must be REAL or INTEGER"));
+
+  return value_literal_complex (arg1, arg2, kind_arg);
 }
 
 /* A helper function for UNOP_FORTRAN_KIND.  */
@@ -773,6 +1039,45 @@ eval_op_f_allocated (struct type *expect_type, struct expression *exp,
   return value_from_longest (result_type, result_value);
 }
 
+/* See f-exp.h.  */
+
+struct value *
+eval_op_f_rank (struct type *expect_type,
+               struct expression *exp,
+               enum noside noside,
+               enum exp_opcode op,
+               struct value *arg1)
+{
+  gdb_assert (op == UNOP_FORTRAN_RANK);
+
+  struct type *result_type
+    = builtin_f_type (exp->gdbarch)->builtin_integer;
+  struct type *type = check_typedef (value_type (arg1));
+  if (type->code () != TYPE_CODE_ARRAY)
+    return value_from_longest (result_type, 0);
+  LONGEST ndim = calc_f77_array_dims (type);
+  return value_from_longest (result_type, ndim);
+}
+
+/* A helper function for UNOP_FORTRAN_LOC.  */
+
+struct value *
+eval_op_f_loc (struct type *expect_type, struct expression *exp,
+                    enum noside noside, enum exp_opcode op,
+                    struct value *arg1)
+{
+  struct type *result_type;
+  if (gdbarch_ptr_bit (exp->gdbarch) == 16)
+    result_type = builtin_f_type (exp->gdbarch)->builtin_integer_s2;
+  else if (gdbarch_ptr_bit (exp->gdbarch) == 32)
+    result_type = builtin_f_type (exp->gdbarch)->builtin_integer;
+  else
+    result_type = builtin_f_type (exp->gdbarch)->builtin_integer_s8;
+
+  LONGEST result_value = value_address (arg1);
+  return value_from_longest (result_type, result_value);
+}
+
 namespace expr
 {
 
@@ -1167,11 +1472,9 @@ fortran_undetermined::value_subarray (value *array,
            array = value_at_lazy (array_slice_type,
                                   value_address (array) + total_offset);
          else
-           array = value_from_contents_and_address (array_slice_type,
-                                                    (value_contents (array)
-                                                     + total_offset),
-                                                    (value_address (array)
-                                                     + total_offset));
+           array = value_from_contents_and_address
+             (array_slice_type, value_contents (array).data () + total_offset,
+              value_address (array) + total_offset);
        }
       else if (!value_lazy (array))
        array = value_from_component (array, array_slice_type, total_offset);
@@ -1188,6 +1491,9 @@ fortran_undetermined::evaluate (struct type *expect_type,
                                enum noside noside)
 {
   value *callee = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+  if (noside == EVAL_AVOID_SIDE_EFFECTS
+      && is_dynamic_type (value_type (callee)))
+    callee = std::get<0> (m_storage)->evaluate (nullptr, exp, EVAL_NORMAL);
   struct type *type = check_typedef (value_type (callee));
   enum type_code code = type->code ();
 
@@ -1261,8 +1567,8 @@ fortran_bound_2arg::evaluate (struct type *expect_type,
 
   /* User asked for the bounds of a specific dimension of the array.  */
   value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
-  struct type *type = check_typedef (value_type (arg2));
-  if (type->code () != TYPE_CODE_INT)
+  type *type_arg2 = check_typedef (value_type (arg2));
+  if (type_arg2->code () != TYPE_CODE_INT)
     {
       if (lbound_p)
        error (_("LBOUND second argument should be an integer"));
@@ -1270,13 +1576,91 @@ fortran_bound_2arg::evaluate (struct type *expect_type,
        error (_("UBOUND second argument should be an integer"));
     }
 
-  return fortran_bounds_for_dimension (lbound_p, exp->gdbarch, arg1, arg2);
+  type *result_type = builtin_f_type (exp->gdbarch)->builtin_integer;
+  return fortran_bounds_for_dimension (lbound_p, arg1, arg2, result_type);
+}
+
+value *
+fortran_bound_3arg::evaluate (type *expect_type,
+                             expression *exp,
+                             noside noside)
+{
+  const bool lbound_p = std::get<0> (m_storage) == FORTRAN_LBOUND;
+  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+  fortran_require_array (value_type (arg1), lbound_p);
+
+  /* User asked for the bounds of a specific dimension of the array.  */
+  value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
+  type *type_arg2 = check_typedef (value_type (arg2));
+  if (type_arg2->code () != TYPE_CODE_INT)
+    {
+      if (lbound_p)
+       error (_("LBOUND second argument should be an integer"));
+      else
+       error (_("UBOUND second argument should be an integer"));
+    }
+
+  type *kind_arg = std::get<3> (m_storage);
+  gdb_assert (kind_arg->code () == TYPE_CODE_INT);
+
+  return fortran_bounds_for_dimension (lbound_p, arg1, arg2, kind_arg);
+}
+
+/* Implement STRUCTOP_STRUCT for Fortran.  See operation::evaluate in
+   expression.h for argument descriptions.  */
+
+value *
+fortran_structop_operation::evaluate (struct type *expect_type,
+                                     struct expression *exp,
+                                     enum noside noside)
+{
+  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+  const char *str = std::get<1> (m_storage).c_str ();
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    {
+      struct type *type = lookup_struct_elt_type (value_type (arg1), str, 1);
+
+      if (type != nullptr && is_dynamic_type (type))
+       arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, EVAL_NORMAL);
+    }
+
+  value *elt = value_struct_elt (&arg1, {}, str, NULL, "structure");
+
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    {
+      struct type *elt_type = value_type (elt);
+      if (is_dynamic_type (elt_type))
+       {
+         const gdb_byte *valaddr = value_contents_for_printing (elt).data ();
+         CORE_ADDR address = value_address (elt);
+         gdb::array_view<const gdb_byte> view
+           = gdb::make_array_view (valaddr, TYPE_LENGTH (elt_type));
+         elt_type = resolve_dynamic_type (elt_type, view, address);
+       }
+      elt = value_zero (elt_type, VALUE_LVAL (elt));
+    }
+
+  return elt;
 }
 
 } /* namespace expr */
 
 /* See language.h.  */
 
+void
+f_language::print_array_index (struct type *index_type, LONGEST index,
+                              struct ui_file *stream,
+                              const value_print_options *options) const
+{
+  struct value *index_value = value_from_longest (index_type, index);
+
+  gdb_printf (stream, "(");
+  value_print (index_value, stream, options);
+  gdb_printf (stream, ") = ");
+}
+
+/* See language.h.  */
+
 void
 f_language::language_arch_info (struct gdbarch *gdbarch,
                                struct language_arch_info *lai) const
@@ -1297,12 +1681,12 @@ f_language::language_arch_info (struct gdbarch *gdbarch,
   add (builtin->builtin_real);
   add (builtin->builtin_real_s8);
   add (builtin->builtin_real_s16);
+  add (builtin->builtin_complex);
   add (builtin->builtin_complex_s8);
-  add (builtin->builtin_complex_s16);
   add (builtin->builtin_void);
 
   lai->set_string_char_type (builtin->builtin_character);
-  lai->set_bool_type (builtin->builtin_logical_s2, "logical");
+  lai->set_bool_type (builtin->builtin_logical, "logical");
 }
 
 /* See language.h.  */
@@ -1351,36 +1735,37 @@ build_fortran_types (struct gdbarch *gdbarch)
   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");
+    = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1, "logical*2");
+
+  builtin_f_type->builtin_logical
+    = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "logical*4");
 
   builtin_f_type->builtin_logical_s8
     = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1,
                         "logical*8");
 
+  builtin_f_type->builtin_integer_s1
+    = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "integer*1");
+
+  builtin_f_type->builtin_integer_s2
+    = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch), 0, "integer*2");
+
   builtin_f_type->builtin_integer
-    = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0,
-                        "integer");
+    = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "integer*4");
 
-  builtin_f_type->builtin_logical
-    = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1,
-                        "logical*4");
+  builtin_f_type->builtin_integer_s8
+    = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch), 0,
+                        "integer*8");
 
   builtin_f_type->builtin_real
     = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
-                      "real", gdbarch_float_format (gdbarch));
+                      "real*4", 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
@@ -1393,17 +1778,18 @@ build_fortran_types (struct gdbarch *gdbarch)
     builtin_f_type->builtin_real_s16
       = arch_type (gdbarch, TYPE_CODE_ERROR, 128, "real*16");
 
+  builtin_f_type->builtin_complex
+    = init_complex_type ("complex*4", builtin_f_type->builtin_real);
+
   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);
+    = init_complex_type ("complex*8", 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");
+    builtin_f_type->builtin_complex_s16
+      = arch_type (gdbarch, TYPE_CODE_ERROR, 256, "complex*16");
   else
-    builtin_f_type->builtin_complex_s32
-      = init_complex_type ("complex*32", builtin_f_type->builtin_real_s16);
+    builtin_f_type->builtin_complex_s16
+      = init_complex_type ("complex*16", builtin_f_type->builtin_real_s16);
 
   return builtin_f_type;
 }
@@ -1426,13 +1812,12 @@ _initialize_f_language ()
 {
   f_type_data = gdbarch_data_register_post_init (build_fortran_types);
 
-  add_basic_prefix_cmd ("fortran", no_class,
-                       _("Prefix command for changing Fortran-specific settings."),
-                       &set_fortran_list, "set fortran ", 0, &setlist);
-
-  add_show_prefix_cmd ("fortran", no_class,
-                      _("Generic command for showing Fortran-specific settings."),
-                      &show_fortran_list, "show fortran ", 0, &showlist);
+  add_setshow_prefix_cmd
+    ("fortran", no_class,
+     _("Prefix command for changing Fortran-specific settings."),
+     _("Generic command for showing Fortran-specific settings."),
+     &set_fortran_list, &show_fortran_list,
+     &setlist, &showlist);
 
   add_setshow_boolean_cmd ("repack-array-slices", class_vars,
                           &repack_array_slices, _("\
@@ -1489,10 +1874,9 @@ fortran_argument_convert (struct value *value, bool is_artificial)
          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);
+         write_memory (addr, value_contents (value).data (), length);
+         struct value *val = value_from_contents_and_address
+           (type, value_contents (value).data (), addr);
          return value_addr (val);
        }
       else