Jan Kratochvil fdbd5e3
http://sourceware.org/ml/gdb-patches/2016-02/msg00843.html
Jan Kratochvil fdbd5e3
Subject: [PATCH v2 1/6] fortran: allow multi-dimensional subarrays
Jan Kratochvil fdbd5e3
Jan Kratochvil 046f33b
From: Christoph Weinmann <christoph.t.weinmann@intel.com>
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
Add an argument count for subrange expressions in Fortran.
Jan Kratochvil 046f33b
Based on the counted value calculate a new array with the
Jan Kratochvil 046f33b
elements specified by the user.  First parse the user input,
Jan Kratochvil 046f33b
secondly copy the desired array values into the return
Jan Kratochvil 046f33b
array, thirdly re-create the necessary ranges and bounds.
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
1|  program prog
Jan Kratochvil 046f33b
2|    integer :: ary(10,5) = (/ (i,i=1,10) (j, j=1,5) /)
Jan Kratochvil 046f33b
3|  end program prog
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
(gdb) print ary(2:4,1:3)
Jan Kratochvil 046f33b
old> Syntax error in expression near ':3'
Jan Kratochvil 046f33b
new> $3 = ( ( 21, 31, 41) ( 22, 32, 42) ( 23, 33, 43) )
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
2013-11-25  Christoph Weinmann  <christoph.t.weinmann@intel.com>
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
	* eval.c (multi_f77_subscript): Remove function.
Jan Kratochvil 046f33b
	* eval.c (evaluate_subrange_expr): When evaluating
Jan Kratochvil 046f33b
	an array or string expression, call
Jan Kratochvil 046f33b
	value_f90_subarray.
Jan Kratochvil 046f33b
	* eval.c (value_f90_subarray): Add argument parsing
Jan Kratochvil 046f33b
	and compute result array based on user input.
Jan Kratochvil 046f33b
	* f-exp.y: Increment argument counter for every subrange
Jan Kratochvil 046f33b
	expression entered by the user.
Jan Kratochvil 046f33b
	* valops.c (value_slice): Call value_slice_1 with
Jan Kratochvil 046f33b
	additional default argument.
Jan Kratochvil 046f33b
	* valops.c (value_slice_1): Add functionality to
Jan Kratochvil 046f33b
	copy and return result values based on input.
Jan Kratochvil 046f33b
	* value.h: Add function definition.
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
Signed-off-by: Christoph Weinmann <christoph.t.weinmann@intel.com>
Jan Kratochvil 046f33b
---
Jan Kratochvil fdbd5e3
 gdb/eval.c   | 309 ++++++++++++++++++++++++++++++++++++++++++++++-------------
Jan Kratochvil fdbd5e3
 gdb/f-exp.y  |   2 +
Jan Kratochvil fdbd5e3
 gdb/valops.c | 157 ++++++++++++++++++++++++------
Jan Kratochvil fdbd5e3
 gdb/value.h  |   2 +
Jan Kratochvil 046f33b
 4 files changed, 375 insertions(+), 95 deletions(-)
Jan Kratochvil 046f33b
Jan Kratochvil 046f33b
diff --git a/gdb/eval.c b/gdb/eval.c
Jan Kratochvil fdbd5e3
index 78ad946..c9f325f 100644
Jan Kratochvil 046f33b
--- a/gdb/eval.c
Jan Kratochvil 046f33b
+++ b/gdb/eval.c
Jan Kratochvil 046f33b
@@ -399,29 +399,253 @@ init_array_element (struct value *array, struct value *element,
Jan Kratochvil 046f33b
   return index;
Jan Kratochvil 046f33b
 }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
+/* Evaluates any operation on Fortran arrays or strings with at least
Jan Kratochvil 046f33b
+   one user provided parameter.  Expects the input ARRAY to be either
Jan Kratochvil 046f33b
+   an array, or a string.  Evaluates EXP by incrementing POS, and
Jan Kratochvil 046f33b
+   writes the content from the elt stack into a local struct.  NARGS
Jan Kratochvil 046f33b
+   specifies number of literal or range arguments the user provided.
Jan Kratochvil 046f33b
+   NARGS must be the same number as ARRAY has dimensions.  */
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
 static struct value *
Jan Kratochvil 046f33b
-value_f90_subarray (struct value *array,
Jan Kratochvil 046f33b
-		    struct expression *exp, int *pos, enum noside noside)
Jan Kratochvil 046f33b
+value_f90_subarray (struct value *array, struct expression *exp,
Jan Kratochvil 046f33b
+		    int *pos, int nargs, enum noside noside)
Jan Kratochvil 046f33b
 {
Jan Kratochvil 046f33b
-  int pc = (*pos) + 1;
Jan Kratochvil 046f33b
+  int i, dim_count = 0;
Jan Kratochvil 046f33b
   LONGEST low_bound, high_bound;
Jan Kratochvil 046f33b
   struct type *range = check_typedef (TYPE_INDEX_TYPE (value_type (array)));
Jan Kratochvil 046f33b
-  enum f90_range_type range_type
Jan Kratochvil 046f33b
-    = (enum f90_range_type) longest_to_int (exp->elts[pc].longconst);
Jan Kratochvil 046f33b
- 
Jan Kratochvil 046f33b
-  *pos += 3;
Jan Kratochvil 046f33b
+  struct value *new_array = array;
Jan Kratochvil 046f33b
+  struct type *array_type = check_typedef (value_type (new_array));
Jan Kratochvil 046f33b
+  struct type *temp_type;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* Local struct to hold user data for Fortran subarray dimensions.  */
Jan Kratochvil 046f33b
+  struct subscript_store
Jan Kratochvil 046f33b
+  {
Jan Kratochvil 046f33b
+    /* For every dimension, we are either working on a range or an index
Jan Kratochvil 046f33b
+       expression, so we store this info separately for later.  */
Jan Kratochvil 046f33b
+    enum
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      SUBSCRIPT_RANGE,    /* e.g. "(lowbound:highbound)"  */
Jan Kratochvil 046f33b
+      SUBSCRIPT_INDEX    /* e.g. "(literal)"  */
Jan Kratochvil 046f33b
+    } kind;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+    /* We also store either the lower and upper bound info, or the index
Jan Kratochvil 046f33b
+       number.  Before evaluation of the input values, we do not know if we are
Jan Kratochvil 046f33b
+       actually working on a range of ranges, or an index in a range.  So as a
Jan Kratochvil 046f33b
+       first step we store all input in a union.  The array calculation itself
Jan Kratochvil 046f33b
+       deals with this later on.  */
Jan Kratochvil 046f33b
+    union
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      struct subscript_range
Jan Kratochvil 046f33b
+      {
Jan Kratochvil 046f33b
+        enum f90_range_type f90_range_type;
Jan Kratochvil 046f33b
+        LONGEST low, high;
Jan Kratochvil 046f33b
+      }
Jan Kratochvil 046f33b
+      range;
Jan Kratochvil 046f33b
+      LONGEST number;
Jan Kratochvil 046f33b
+    };
Jan Kratochvil 046f33b
+  } *subscript_array;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* Check if the number of arguments provided by the user matches
Jan Kratochvil 046f33b
+     the number of dimension of the array.  A string has only one
Jan Kratochvil 046f33b
+     dimension.  */
Jan Kratochvil 046f33b
+  if (nargs != calc_f77_array_dims (value_type (new_array)))
Jan Kratochvil 046f33b
+    error (_("Wrong number of subscripts"));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  subscript_array = alloca (sizeof (*subscript_array) * nargs);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* Parse the user input into the SUBSCRIPT_ARRAY to store it.  We need
Jan Kratochvil 046f33b
+     to evaluate it first, as the input is from left-to-right.  The
Jan Kratochvil 046f33b
+     array is stored from right-to-left.  So we have to use the user
Jan Kratochvil 046f33b
+     input in reverse order.  Later on, we need the input information to
Jan Kratochvil 046f33b
+     re-calculate the output array.  For multi-dimensional arrays, we
Jan Kratochvil 046f33b
+     can be dealing with any possible combination of ranges and indices
Jan Kratochvil 046f33b
+     for every dimension.  */
Jan Kratochvil 046f33b
+  for (i = 0; i < nargs; i++)
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      struct subscript_store *index = &subscript_array[i];
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
Jan Kratochvil 046f33b
-    low_bound = TYPE_LOW_BOUND (range);
Jan Kratochvil 046f33b
-  else
Jan Kratochvil 046f33b
-    low_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
Jan Kratochvil 046f33b
+      /* The user input is a range, with or without lower and upper bound.
Jan Kratochvil 046f33b
+	 E.g.: "p arry(2:5)", "p arry( :5)", "p arry( : )", etc.  */
Jan Kratochvil 046f33b
+      if (exp->elts[*pos].opcode == OP_F90_RANGE)
Jan Kratochvil 046f33b
+	{
Jan Kratochvil 046f33b
+	  int pc = (*pos) + 1;
Jan Kratochvil 046f33b
+	  struct subscript_range *range;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	  index->kind = SUBSCRIPT_RANGE;
Jan Kratochvil 046f33b
+	  range = &index->range;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	  *pos += 3;
Jan Kratochvil 046f33b
+	  range->f90_range_type = longest_to_int (exp->elts[pc].longconst);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	  /* If a lower bound was provided by the user, the bit has been
Jan Kratochvil 046f33b
+	     set and we can assign the value from the elt stack.  Same for
Jan Kratochvil 046f33b
+	     upper bound.  */
Jan Kratochvil 046f33b
+	  if ((range->f90_range_type == HIGH_BOUND_DEFAULT)
Jan Kratochvil 046f33b
+	      || range->f90_range_type == NONE_BOUND_DEFAULT)
Jan Kratochvil 046f33b
+	    range->low = value_as_long (evaluate_subexp (NULL_TYPE, exp,
Jan Kratochvil 046f33b
+							 pos, noside));
Jan Kratochvil 046f33b
+	  if ((range->f90_range_type == LOW_BOUND_DEFAULT)
Jan Kratochvil 046f33b
+	      || range->f90_range_type == NONE_BOUND_DEFAULT)
Jan Kratochvil 046f33b
+	    range->high = value_as_long (evaluate_subexp (NULL_TYPE, exp,
Jan Kratochvil 046f33b
+							  pos, noside));
Jan Kratochvil 046f33b
+	}
Jan Kratochvil 046f33b
+      /* User input is an index.  E.g.: "p arry(5)".  */
Jan Kratochvil 046f33b
+      else
Jan Kratochvil 046f33b
+	{
Jan Kratochvil 046f33b
+	  struct value *val;
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
Jan Kratochvil 046f33b
-    high_bound = TYPE_HIGH_BOUND (range);
Jan Kratochvil 046f33b
-  else
Jan Kratochvil 046f33b
-    high_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
Jan Kratochvil 046f33b
+	  index->kind = SUBSCRIPT_INDEX;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	  /* Evaluate each subscript; it must be a legal integer in F77.  This
Jan Kratochvil 046f33b
+	     ensures the validity of the provided index.  */
Jan Kratochvil 046f33b
+	  val = evaluate_subexp_with_coercion (exp, pos, noside);
Jan Kratochvil 046f33b
+	  index->number = value_as_long (val);
Jan Kratochvil 046f33b
+	}
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+    }
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* Traverse the array from right to left and evaluate each corresponding
Jan Kratochvil 046f33b
+     user input.  VALUE_SUBSCRIPT is called for every index, until a range
Jan Kratochvil 046f33b
+     expression is evaluated.  After a range expression has been evaluated,
Jan Kratochvil 046f33b
+     every subsequent expression is also treated as a range.  */
Jan Kratochvil 046f33b
+  for (i = nargs - 1; i >= 0; i--)
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      struct subscript_store *index = &subscript_array[i];
Jan Kratochvil 046f33b
+      struct type *index_type = TYPE_INDEX_TYPE (array_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+      switch (index->kind)
Jan Kratochvil 046f33b
+	{
Jan Kratochvil 046f33b
+	case SUBSCRIPT_RANGE:
Jan Kratochvil 046f33b
+	  {
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	    /* When we hit the first range specified by the user, we must
Jan Kratochvil 046f33b
+	       treat any subsequent user entry as a range.  We simply
Jan Kratochvil 046f33b
+	       increment DIM_COUNT which tells us how many times we are
Jan Kratochvil 046f33b
+	       calling VALUE_SLICE_1.  */
Jan Kratochvil 046f33b
+	    struct subscript_range *range = &index->range;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	    /* If no lower bound was provided by the user, we take the
Jan Kratochvil 046f33b
+	       default boundary.  Same for the high bound.  */
Jan Kratochvil 046f33b
+	    if ((range->f90_range_type == LOW_BOUND_DEFAULT)
Jan Kratochvil 046f33b
+		|| (range->f90_range_type == BOTH_BOUND_DEFAULT))
Jan Kratochvil 046f33b
+	      range->low = TYPE_LOW_BOUND (index_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	    if ((range->f90_range_type == HIGH_BOUND_DEFAULT)
Jan Kratochvil 046f33b
+		|| (range->f90_range_type == BOTH_BOUND_DEFAULT))
Jan Kratochvil 046f33b
+	      range->high = TYPE_HIGH_BOUND (index_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	    /* Both user provided low and high bound have to be inside the
Jan Kratochvil 046f33b
+	       array bounds.  Throw an error if not.  */
Jan Kratochvil 046f33b
+	    if (range->low < TYPE_LOW_BOUND (index_type)
Jan Kratochvil 046f33b
+		|| range->low > TYPE_HIGH_BOUND (index_type)
Jan Kratochvil 046f33b
+		|| range->high < TYPE_LOW_BOUND (index_type)
Jan Kratochvil 046f33b
+		|| range->high > TYPE_HIGH_BOUND (index_type))
Jan Kratochvil 046f33b
+	      error (_("provided bound(s) outside array bound(s)"));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	    /* DIM_COUNT counts every user argument that is treated as a range.
Jan Kratochvil 046f33b
+	       This is necessary for expressions like 'print array(7, 8:9).
Jan Kratochvil 046f33b
+	       Here the first argument is a literal, but must be treated as a
Jan Kratochvil 046f33b
+	       range argument to allow the correct output representation.  */
Jan Kratochvil 046f33b
+	    dim_count++;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	    new_array
Jan Kratochvil 046f33b
+	      = value_slice_1 (new_array,
Jan Kratochvil 046f33b
+			       longest_to_int (range->low),
Jan Kratochvil 046f33b
+			       longest_to_int (range->high - range->low + 1),
Jan Kratochvil 046f33b
+			       dim_count);
Jan Kratochvil 046f33b
+	  }
Jan Kratochvil 046f33b
+	  break;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	case SUBSCRIPT_INDEX:
Jan Kratochvil 046f33b
+	  {
Jan Kratochvil 046f33b
+	    /* DIM_COUNT only stays '0' when no range argument was processed
Jan Kratochvil 046f33b
+	       before, starting from the last dimension.  This way we can
Jan Kratochvil 046f33b
+	       reduce the number of dimensions from the result array.
Jan Kratochvil 046f33b
+	       However, if a range has been processed before an index, we
Jan Kratochvil 046f33b
+	       treat the index like a range with equal low- and high bounds
Jan Kratochvil 046f33b
+	       to get the value offset right.  */
Jan Kratochvil 046f33b
+	    if (dim_count == 0)
Jan Kratochvil 046f33b
+	      new_array
Jan Kratochvil 046f33b
+	        = value_subscripted_rvalue (new_array, index->number,
Jan Kratochvil 046f33b
+					    f77_get_lowerbound (value_type
Jan Kratochvil 046f33b
+								  (new_array)));
Jan Kratochvil 046f33b
+	    else
Jan Kratochvil 046f33b
+	      {
Jan Kratochvil 046f33b
+		/* Check for valid index input.  */
Jan Kratochvil 046f33b
+		if (index->number < TYPE_LOW_BOUND (index_type)
Jan Kratochvil 046f33b
+		    || index->number > TYPE_HIGH_BOUND (index_type))
Jan Kratochvil 046f33b
+		  error (_("error no such vector element"));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+		dim_count++;
Jan Kratochvil 046f33b
+		new_array = value_slice_1 (new_array,
Jan Kratochvil 046f33b
+					   longest_to_int (index->number),
Jan Kratochvil 046f33b
+					   1, /* length is '1' element  */
Jan Kratochvil 046f33b
+					   dim_count);
Jan Kratochvil 046f33b
+	      }
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	  }
Jan Kratochvil 046f33b
+	  break;
Jan Kratochvil 046f33b
+	}
Jan Kratochvil 046f33b
+    }
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* With DIM_COUNT > 1 we currently have a one dimensional array, but expect
Jan Kratochvil 046f33b
+     an array of arrays, depending on how many ranges have been provided by
Jan Kratochvil 046f33b
+     the user.  So we need to rebuild the array dimensions for printing it
Jan Kratochvil 046f33b
+     correctly.
Jan Kratochvil 046f33b
+     Starting from right to left in the user input, after we hit the first
Jan Kratochvil 046f33b
+     range argument every subsequent argument is also treated as a range.
Jan Kratochvil 046f33b
+     E.g.:
Jan Kratochvil 046f33b
+     "p ary(3, 7, 2:15)" in Fortran has only 1 dimension, but we calculated 3
Jan Kratochvil 046f33b
+     ranges.
Jan Kratochvil 046f33b
+     "p ary(3, 7:12, 4)" in Fortran has only 1 dimension, but we calculated 2
Jan Kratochvil 046f33b
+     ranges.
Jan Kratochvil 046f33b
+     "p ary(2:4, 5, 7)" in Fortran has only 1 dimension, and we calculated 1
Jan Kratochvil 046f33b
+     range.  */
Jan Kratochvil 046f33b
+  if (dim_count > 1)
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      struct value *v = NULL;
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  return value_slice (array, low_bound, high_bound - low_bound + 1);
Jan Kratochvil 046f33b
+      temp_type = TYPE_TARGET_TYPE (value_type (new_array));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+      /* Every SUBSCRIPT_RANGE in the user input signifies an actual range in
Jan Kratochvil 046f33b
+	 the output array.  So we traverse the SUBSCRIPT_ARRAY again, looking
Jan Kratochvil 046f33b
+	 for a range entry.  When we find one, we use the range info to create
Jan Kratochvil 046f33b
+	 an additional range_type to set the correct bounds and dimensions for
Jan Kratochvil 046f33b
+	 the output array.  */
Jan Kratochvil 046f33b
+      for (i = 0; i < nargs; i++)
Jan Kratochvil 046f33b
+	{
Jan Kratochvil 046f33b
+	  struct subscript_store *index = &subscript_array[i];
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	  if (index->kind == SUBSCRIPT_RANGE)
Jan Kratochvil 046f33b
+	    {
Jan Kratochvil 046f33b
+	      struct type *range_type, *interim_array_type;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	      range_type
Jan Kratochvil 046f33b
+		= create_static_range_type (NULL,
Jan Kratochvil 046f33b
+				     temp_type,
Jan Kratochvil 046f33b
+				     1,
Jan Kratochvil 046f33b
+				     index->range.high - index->range.low + 1);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	      interim_array_type = create_array_type (NULL,
Jan Kratochvil 046f33b
+						      temp_type,
Jan Kratochvil 046f33b
+						      range_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	      /* For some reason the type code of the contents is missing, so
Jan Kratochvil 046f33b
+		 reset it from the original array.  */
Jan Kratochvil 046f33b
+	      TYPE_CODE (interim_array_type)
Jan Kratochvil 046f33b
+		= TYPE_CODE (value_type (new_array));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	      v = allocate_value (interim_array_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	      temp_type = value_type (v);
Jan Kratochvil 046f33b
+	    }
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	}
Jan Kratochvil 046f33b
+      value_contents_copy (v, 0, new_array, 0, TYPE_LENGTH (temp_type));
Jan Kratochvil 046f33b
+      return v;
Jan Kratochvil 046f33b
+    }
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  return new_array;
Jan Kratochvil 046f33b
 }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
@@ -1810,14 +2034,11 @@ evaluate_subexp_standard (struct type *expect_type,
Jan Kratochvil 046f33b
       switch (code)
Jan Kratochvil 046f33b
 	{
Jan Kratochvil 046f33b
 	case TYPE_CODE_ARRAY:
Jan Kratochvil 046f33b
-	  if (exp->elts[*pos].opcode == OP_F90_RANGE)
Jan Kratochvil 046f33b
-	    return value_f90_subarray (arg1, exp, pos, noside);
Jan Kratochvil 046f33b
-	  else
Jan Kratochvil 046f33b
-	    goto multi_f77_subscript;
Jan Kratochvil 046f33b
+	  return value_f90_subarray (arg1, exp, pos, nargs, noside);
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
 	case TYPE_CODE_STRING:
Jan Kratochvil 046f33b
 	  if (exp->elts[*pos].opcode == OP_F90_RANGE)
Jan Kratochvil 046f33b
-	    return value_f90_subarray (arg1, exp, pos, noside);
Jan Kratochvil 046f33b
+	    return value_f90_subarray (arg1, exp, pos, 1, noside);
Jan Kratochvil 046f33b
 	  else
Jan Kratochvil 046f33b
 	    {
Jan Kratochvil 046f33b
 	      arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
Jan Kratochvil 046f33b
@@ -2222,49 +2443,6 @@ evaluate_subexp_standard (struct type *expect_type,
Jan Kratochvil 046f33b
 	}
Jan Kratochvil 046f33b
       return (arg1);
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-    multi_f77_subscript:
Jan Kratochvil 046f33b
-      {
Jan Kratochvil 046f33b
-	LONGEST subscript_array[MAX_FORTRAN_DIMS];
Jan Kratochvil 046f33b
-	int ndimensions = 1, i;
Jan Kratochvil 046f33b
-	struct value *array = arg1;
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	if (nargs > MAX_FORTRAN_DIMS)
Jan Kratochvil 046f33b
-	  error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	ndimensions = calc_f77_array_dims (type);
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	if (nargs != ndimensions)
Jan Kratochvil 046f33b
-	  error (_("Wrong number of subscripts"));
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	gdb_assert (nargs > 0);
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	/* Now that we know we have a legal array subscript expression 
Jan Kratochvil 046f33b
-	   let us actually find out where this element exists in the array.  */
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	/* Take array indices left to right.  */
Jan Kratochvil 046f33b
-	for (i = 0; i < nargs; i++)
Jan Kratochvil 046f33b
-	  {
Jan Kratochvil 046f33b
-	    /* Evaluate each subscript; it must be a legal integer in F77.  */
Jan Kratochvil 046f33b
-	    arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	    /* Fill in the subscript array.  */
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	    subscript_array[i] = value_as_long (arg2);
Jan Kratochvil 046f33b
-	  }
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	/* Internal type of array is arranged right to left.  */
Jan Kratochvil 046f33b
-	for (i = nargs; i > 0; i--)
Jan Kratochvil 046f33b
-	  {
Jan Kratochvil 046f33b
-	    struct type *array_type = check_typedef (value_type (array));
Jan Kratochvil 046f33b
-	    LONGEST index = subscript_array[i - 1];
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	    array = value_subscripted_rvalue (array, index,
Jan Kratochvil 046f33b
-					      f77_get_lowerbound (array_type));
Jan Kratochvil 046f33b
-	  }
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
-	return array;
Jan Kratochvil 046f33b
-      }
Jan Kratochvil 046f33b
-
Jan Kratochvil 046f33b
     case BINOP_LOGICAL_AND:
Jan Kratochvil 046f33b
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
Jan Kratochvil 046f33b
       if (noside == EVAL_SKIP)
Jan Kratochvil 046f33b
@@ -3121,6 +3299,9 @@ calc_f77_array_dims (struct type *array_type)
Jan Kratochvil 046f33b
   int ndimen = 1;
Jan Kratochvil 046f33b
   struct type *tmp_type;
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
+  if (TYPE_CODE (array_type) == TYPE_CODE_STRING)
Jan Kratochvil 046f33b
+    return 1;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
   if ((TYPE_CODE (array_type) != TYPE_CODE_ARRAY))
Jan Kratochvil 046f33b
     error (_("Can't get dimensions for a non-array type"));
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
Jan Kratochvil fdbd5e3
index 4faac32..9343abb 100644
Jan Kratochvil 046f33b
--- a/gdb/f-exp.y
Jan Kratochvil 046f33b
+++ b/gdb/f-exp.y
Jan Kratochvil 046f33b
@@ -308,6 +308,8 @@ arglist :	subrange
Jan Kratochvil 046f33b
    
Jan Kratochvil 046f33b
 arglist	:	arglist ',' exp   %prec ABOVE_COMMA
Jan Kratochvil 046f33b
 			{ arglist_len++; }
Jan Kratochvil 046f33b
+	|	arglist ',' subrange	%prec ABOVE_COMMA
Jan Kratochvil 046f33b
+			{ arglist_len++; }
Jan Kratochvil 046f33b
 	;
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
 /* There are four sorts of subrange types in F90.  */
Jan Kratochvil 046f33b
diff --git a/gdb/valops.c b/gdb/valops.c
Jan Kratochvil fdbd5e3
index 5a244a9..09ea877 100644
Jan Kratochvil 046f33b
--- a/gdb/valops.c
Jan Kratochvil 046f33b
+++ b/gdb/valops.c
Jan Kratochvil 046f33b
@@ -3759,56 +3759,151 @@ value_of_this_silent (const struct language_defn *lang)
Jan Kratochvil 046f33b
 struct value *
Jan Kratochvil 046f33b
 value_slice (struct value *array, int lowbound, int length)
Jan Kratochvil 046f33b
 {
Jan Kratochvil 046f33b
+  /* Pass unaltered arguments to VALUE_SLICE_1, plus a CALL_COUNT of '1' as we
Jan Kratochvil 046f33b
+     are only considering the highest dimension, or we are working on a one
Jan Kratochvil 046f33b
+     dimensional array.  So we call VALUE_SLICE_1 exactly once.  */
Jan Kratochvil 046f33b
+  return value_slice_1 (array, lowbound, length, 1);
Jan Kratochvil 046f33b
+}
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+/* CALL_COUNT is used to determine if we are calling the function once, e.g.
Jan Kratochvil 046f33b
+   we are working on the current dimension of ARRAY, or if we are calling
Jan Kratochvil 046f33b
+   the function repeatedly.  In the later case we need to take elements
Jan Kratochvil 046f33b
+   from the TARGET_TYPE of ARRAY.
Jan Kratochvil 046f33b
+   With a CALL_COUNT greater than 1 we calculate the offsets for every element
Jan Kratochvil 046f33b
+   that should be in the result array.  Then we fetch the contents and then
Jan Kratochvil 046f33b
+   copy them into the result array.  The result array will have one dimension
Jan Kratochvil 046f33b
+   less than the input array, so later on we need to recreate the indices and
Jan Kratochvil 046f33b
+   ranges in the calling function.  */
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+struct value *
Jan Kratochvil 046f33b
+value_slice_1 (struct value *array, int lowbound, int length, int call_count)
Jan Kratochvil 046f33b
+{
Jan Kratochvil 046f33b
   struct type *slice_range_type, *slice_type, *range_type;
Jan Kratochvil 046f33b
-  LONGEST lowerbound, upperbound;
Jan Kratochvil 046f33b
-  struct value *slice;
Jan Kratochvil 046f33b
-  struct type *array_type;
Jan Kratochvil 046f33b
+  struct type *array_type = check_typedef (value_type (array));
Jan Kratochvil 046f33b
+  struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
Jan Kratochvil 046f33b
+  unsigned int elt_size, elt_offs;
Jan Kratochvil 046f33b
+  LONGEST elt_stride, ary_high_bound, ary_low_bound;
Jan Kratochvil 046f33b
+  struct value *v;
Jan Kratochvil 046f33b
+  int slice_range_size, i = 0, row_count = 1, elem_count = 1;
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  array_type = check_typedef (value_type (array));
Jan Kratochvil 046f33b
+  /* Check for legacy code if we are actually dealing with an array or
Jan Kratochvil 046f33b
+     string.  */
Jan Kratochvil 046f33b
   if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
Jan Kratochvil 046f33b
       && TYPE_CODE (array_type) != TYPE_CODE_STRING)
Jan Kratochvil 046f33b
     error (_("cannot take slice of non-array"));
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  range_type = TYPE_INDEX_TYPE (array_type);
Jan Kratochvil 046f33b
-  if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
Jan Kratochvil 046f33b
-    error (_("slice from bad array or bitstring"));
Jan Kratochvil 046f33b
+  ary_low_bound = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (array_type));
Jan Kratochvil 046f33b
+  ary_high_bound = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (array_type));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* When we are working on a multi-dimensional array, we need to get the
Jan Kratochvil 046f33b
+     attributes of the underlying type.  */
Jan Kratochvil 046f33b
+  if (call_count > 1)
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type));
Jan Kratochvil 046f33b
+      row_count = TYPE_LENGTH (array_type)
Jan Kratochvil 046f33b
+		    / TYPE_LENGTH (TYPE_TARGET_TYPE (array_type));
Jan Kratochvil 046f33b
+    }
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  elem_count = length;
Jan Kratochvil 046f33b
+  elt_size = TYPE_LENGTH (elt_type);
Jan Kratochvil 046f33b
+  elt_offs = longest_to_int (lowbound - ary_low_bound);
Jan Kratochvil 046f33b
+  elt_stride = TYPE_LENGTH (TYPE_INDEX_TYPE (array_type));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  elt_offs *= elt_size;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+  /* Check for valid user input.  In case of Fortran this was already done
Jan Kratochvil 046f33b
+     in the calling function.  */
Jan Kratochvil 046f33b
+  if (call_count == 1
Jan Kratochvil 046f33b
+	&& (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)
Jan Kratochvil 046f33b
+	      && elt_offs >= TYPE_LENGTH (array_type)))
Jan Kratochvil 046f33b
+    error (_("no such vector element"));
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  if (lowbound < lowerbound || length < 0
Jan Kratochvil 046f33b
-      || lowbound + length - 1 > upperbound)
Jan Kratochvil 046f33b
-    error (_("slice out of range"));
Jan Kratochvil 046f33b
+  /* CALL_COUNT is 1 when we are dealing either with the highest dimension
Jan Kratochvil 046f33b
+     of the array, or a one dimensional array.  Set RANGE_TYPE accordingly.
Jan Kratochvil 046f33b
+     In both cases we calculate how many rows/elements will be in the output
Jan Kratochvil 046f33b
+     array by setting slice_range_size.  */
Jan Kratochvil 046f33b
+  if (call_count == 1)
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      range_type = TYPE_INDEX_TYPE (array_type);
Jan Kratochvil 046f33b
+      slice_range_size = elem_count;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+      /* Check if the array bounds are valid.  */
Jan Kratochvil 046f33b
+      if (get_discrete_bounds (range_type, &ary_low_bound, &ary_high_bound) < 0)
Jan Kratochvil 046f33b
+	error (_("slice from bad array or bitstring"));
Jan Kratochvil 046f33b
+    }
Jan Kratochvil 046f33b
+  /* When CALL_COUNT is greater than 1, we are dealing with an array of arrays.
Jan Kratochvil 046f33b
+     So we need to get the type below the current one and set the RANGE_TYPE
Jan Kratochvil 046f33b
+     accordingly.  */
Jan Kratochvil 046f33b
+  else
Jan Kratochvil 046f33b
+    {
Jan Kratochvil 046f33b
+      range_type = TYPE_INDEX_TYPE (TYPE_TARGET_TYPE (array_type));
Jan Kratochvil 046f33b
+      slice_range_size = (ary_low_bound + row_count - 1) * (elem_count);
Jan Kratochvil 046f33b
+      ary_low_bound = TYPE_LOW_BOUND (range_type);
Jan Kratochvil 046f33b
+    }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
   /* FIXME-type-allocation: need a way to free this type when we are
Jan Kratochvil 046f33b
-     done with it.  */
Jan Kratochvil 046f33b
-  slice_range_type = create_static_range_type ((struct type *) NULL,
Jan Kratochvil 046f33b
-					       TYPE_TARGET_TYPE (range_type),
Jan Kratochvil 046f33b
-					       lowbound,
Jan Kratochvil 046f33b
-					       lowbound + length - 1);
Jan Kratochvil 046f33b
+      done with it.  */
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
+  slice_range_type = create_static_range_type (NULL, TYPE_TARGET_TYPE (range_type),
Jan Kratochvil 046f33b
+					ary_low_bound, slice_range_size);
Jan Kratochvil 046f33b
   {
Jan Kratochvil 046f33b
-    struct type *element_type = TYPE_TARGET_TYPE (array_type);
Jan Kratochvil 046f33b
-    LONGEST offset
Jan Kratochvil 046f33b
-      = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
Jan Kratochvil 046f33b
+    struct type *element_type;
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+    /* When CALL_COUNT equals 1 we can use the legacy code for subarrays.  */
Jan Kratochvil 046f33b
+    if (call_count == 1)
Jan Kratochvil 046f33b
+      {
Jan Kratochvil 046f33b
+	element_type = TYPE_TARGET_TYPE (array_type);
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-    slice_type = create_array_type ((struct type *) NULL,
Jan Kratochvil 046f33b
-				    element_type,
Jan Kratochvil 046f33b
-				    slice_range_type);
Jan Kratochvil 046f33b
-    TYPE_CODE (slice_type) = TYPE_CODE (array_type);
Jan Kratochvil 046f33b
+	slice_type = create_array_type (NULL, element_type, slice_range_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	TYPE_CODE (slice_type) = TYPE_CODE (array_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
Jan Kratochvil 046f33b
+	  v = allocate_value_lazy (slice_type);
Jan Kratochvil 046f33b
+	else
Jan Kratochvil 046f33b
+	  {
Jan Kratochvil 046f33b
+	    v = allocate_value (slice_type);
Jan Kratochvil 046f33b
+	    value_contents_copy (v,
Jan Kratochvil 046f33b
+				 value_embedded_offset (v),
Jan Kratochvil 046f33b
+				 array,
Jan Kratochvil 046f33b
+				 value_embedded_offset (array) + elt_offs,
Jan Kratochvil 046f33b
+				 elt_size * longest_to_int (length));
Jan Kratochvil 046f33b
+	  }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-    if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
Jan Kratochvil 046f33b
-      slice = allocate_value_lazy (slice_type);
Jan Kratochvil 046f33b
+      }
Jan Kratochvil 046f33b
+    /* When CALL_COUNT is larger than 1 we are working on a range of ranges.
Jan Kratochvil 046f33b
+       So we copy the relevant elements into the new array we return.  */
Jan Kratochvil 046f33b
     else
Jan Kratochvil 046f33b
       {
Jan Kratochvil 046f33b
-	slice = allocate_value (slice_type);
Jan Kratochvil 046f33b
-	value_contents_copy (slice, 0, array, offset,
Jan Kratochvil 046f33b
-			     type_length_units (slice_type));
Jan Kratochvil 046f33b
+	LONGEST dst_offset = 0;
Jan Kratochvil 046f33b
+	LONGEST src_row_length = TYPE_LENGTH (TYPE_TARGET_TYPE (array_type));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	element_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (array_type));
Jan Kratochvil 046f33b
+	slice_type = create_array_type (NULL, element_type, slice_range_type);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	TYPE_CODE (slice_type) = TYPE_CODE (TYPE_TARGET_TYPE (array_type));
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
+	v = allocate_value (slice_type);
Jan Kratochvil 046f33b
+	for (i = 0; i < longest_to_int (row_count); i++)
Jan Kratochvil 046f33b
+	  {
Jan Kratochvil 046f33b
+	    /* Fetches the contents of ARRAY and copies them into V.  */
Jan Kratochvil 046f33b
+	    value_contents_copy (v,
Jan Kratochvil 046f33b
+				 dst_offset,
Jan Kratochvil 046f33b
+				 array,
Jan Kratochvil 046f33b
+				 elt_offs,
Jan Kratochvil 046f33b
+				 elt_size * elem_count);
Jan Kratochvil 046f33b
+	    elt_offs += src_row_length;
Jan Kratochvil 046f33b
+	    dst_offset += elt_size * elem_count;
Jan Kratochvil 046f33b
+	  }
Jan Kratochvil 046f33b
       }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-    set_value_component_location (slice, array);
Jan Kratochvil 046f33b
-    VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
Jan Kratochvil 046f33b
-    set_value_offset (slice, value_offset (array) + offset);
Jan Kratochvil 046f33b
+    set_value_component_location (v, array);
Jan Kratochvil 046f33b
+    VALUE_REGNUM (v) = VALUE_REGNUM (array);
Jan Kratochvil 046f33b
+    VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array);
Jan Kratochvil 046f33b
+    set_value_offset (v, value_offset (array) + elt_offs);
Jan Kratochvil 046f33b
   }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-  return slice;
Jan Kratochvil 046f33b
+  return v;
Jan Kratochvil 046f33b
 }
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
 /* Create a value for a FORTRAN complex number.  Currently most of the
Jan Kratochvil 046f33b
diff --git a/gdb/value.h b/gdb/value.h
Jan Kratochvil fdbd5e3
index 2eac5ef..3400460 100644
Jan Kratochvil 046f33b
--- a/gdb/value.h
Jan Kratochvil 046f33b
+++ b/gdb/value.h
Jan Kratochvil 046f33b
@@ -1056,6 +1056,8 @@ extern struct value *varying_to_slice (struct value *);
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
 extern struct value *value_slice (struct value *, int, int);
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
+extern struct value *value_slice_1 (struct value *, int, int, int);
Jan Kratochvil 046f33b
+
Jan Kratochvil 046f33b
 extern struct value *value_literal_complex (struct value *, struct value *,
Jan Kratochvil 046f33b
 					    struct type *);
Jan Kratochvil 046f33b
 
Jan Kratochvil 046f33b
-- 
Jan Kratochvil fdbd5e3
2.5.0
Jan Kratochvil fdbd5e3