]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
fortran: enable parsing of stride parameter for subranges
authorChristoph Weinmann <christoph.t.weinmann@intel.com>
Wed, 1 Jun 2016 13:11:24 +0000 (15:11 +0200)
committerBernhard Heckel <bernhard.heckel@intel.com>
Wed, 7 Sep 2016 10:08:47 +0000 (12:08 +0200)
Allow the user to provide a stride parameter for Fortran
subarrays.  The stride parameter can be any integer except
'0'.  The default stride value is '1'.

2013-11-27  Christoph Weinmann  <christoph.t.weinmann@intel.com>

* eval.c (value_f90_subarray): Add expression evaluation
for a stride parameter in a Fortran range expression.
* expression.h (range_type): Add field to enum to show when
a stride value was provided by the user.
* f-exp.y: Add yacc rules for writing info on the elt stack
when the user provided a stride argument.
* parse.c (operator_length_standard): Check if a stride
value was provided, and increment argument counter
accordingly.

Signed-off-by: Christoph Weinmann <christoph.t.weinmann@intel.com>
gdb/eval.c
gdb/expression.h
gdb/f-exp.y
gdb/parse.c
gdb/valops.c

index 2d9eb31b53d9f6f1788c424c9ad614528ffba398..3a8c3efe27455256fbbd4ab289a763dc9dc46f94 100644 (file)
@@ -419,7 +419,7 @@ value_f90_subarray (struct value *array, struct expression *exp,
   typedef struct subscript_range
   {
     enum range_type f90_range_type;
-    LONGEST low, high;
+    LONGEST low, high, stride;
   } subscript_range;
 
   typedef enum subscript_kind
@@ -490,6 +490,15 @@ value_f90_subarray (struct value *array, struct expression *exp,
              == SUBARRAY_HIGH_BOUND)
            range->high = value_as_long (evaluate_subexp (NULL_TYPE, exp,
                                                          pos, noside));
+
+         /* Assign the user's stride value if provided.  */
+         if ((range->f90_range_type & SUBARRAY_STRIDE) == SUBARRAY_STRIDE)
+           range->stride = value_as_long (evaluate_subexp (NULL_TYPE, exp,
+                                                            pos, noside));
+
+         /* Assign the default stride value '1'.  */
+         else
+           range->stride = 1;
        }
       /* User input is an index.  E.g.: "p arry(5)".  */
       else
index 5a6b72093a50f0b32722fe6f96c9babe88201b7c..34ca54b4f09020200826d2c9eeb15e178ed20bdb 100644 (file)
@@ -153,13 +153,16 @@ extern void dump_raw_expression (struct expression *,
 extern void dump_prefix_expression (struct expression *, struct ui_file *);
 
 /* In an OP_RANGE expression, either bound can be provided by the user, or not.
-   This enumeration type is to identify this.  */
+   In addition to this, the user can also specify a stride value to indicated
+   only certain elements of the array.  This enumeration type is to identify
+   this.  */
 
 enum range_type
   {
     SUBARRAY_NONE_BOUND = 0x0,         /* "( : )"  */
     SUBARRAY_LOW_BOUND = 0x1,          /* "(low:)"  */
-    SUBARRAY_HIGH_BOUND = 0x2          /* "(:high)"  */
+    SUBARRAY_HIGH_BOUND = 0x2,         /* "(:high)"  */
+    SUBARRAY_STRIDE = 0x4              /* "(::stride)"  */
   };
 
 #endif /* !defined (EXPRESSION_H) */
index e2c54b608bc978b62b1782213aeb4a3b704a78af..71f1823a9815a4a5fba8c7db9d4ad1b75c2e2227 100644 (file)
@@ -280,7 +280,36 @@ subrange:  ':' exp %prec ABOVE_COMMA
 
 subrange:      ':'     %prec ABOVE_COMMA
                        { write_exp_elt_opcode (pstate, OP_RANGE);
-                         write_exp_elt_longcst (pstate, 0);
+                         write_exp_elt_longcst (pstate, SUBARRAY_NONE_BOUND);
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+/* Each subrange type can have a stride argument.  */
+subrange:      exp ':' exp ':' exp %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate, SUBARRAY_LOW_BOUND
+                                                | SUBARRAY_HIGH_BOUND
+                                                | SUBARRAY_STRIDE);
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+subrange:      exp ':' ':' exp %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate, SUBARRAY_LOW_BOUND
+                                                | SUBARRAY_STRIDE);
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+subrange:      ':' exp ':' exp %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate, SUBARRAY_HIGH_BOUND
+                                                | SUBARRAY_STRIDE);
+                         write_exp_elt_opcode (pstate, OP_RANGE); }
+       ;
+
+subrange:      ':' ':' exp %prec ABOVE_COMMA
+                       { write_exp_elt_opcode (pstate, OP_RANGE);
+                         write_exp_elt_longcst (pstate, SUBARRAY_STRIDE);
                          write_exp_elt_opcode (pstate, OP_RANGE); }
        ;
 
index 6d54a77092a45987a32c7c760801e240dfffa8bc..992af87aa632cb397bb38a2340e51c0708c88924 100644 (file)
@@ -1018,6 +1018,9 @@ operator_length_standard (const struct expression *expr, int endpos,
       if ((range_type & SUBARRAY_HIGH_BOUND) == SUBARRAY_HIGH_BOUND)
        args++;
 
+      if ((range_type & SUBARRAY_STRIDE) == SUBARRAY_STRIDE)
+       args++;
+
       break;
 
     default:
index 877280f9b9d59dc085d0a20505a8a0cbd884356c..479cf8d644cb18f9165f4b0c84fb8c9448bf36f1 100644 (file)
@@ -3842,7 +3842,7 @@ value_slice_1 (struct value *array, int lowbound, int length, int call_count)
   if (call_count == 1)
     {
       range_type = TYPE_INDEX_TYPE (array_type);
-      slice_range_size = elem_count;
+      slice_range_size = ary_low_bound + elem_count - 1;
 
       /* Check if the array bounds are valid.  */
       if (get_discrete_bounds (range_type, &ary_low_bound, &ary_high_bound) < 0)
@@ -3854,7 +3854,7 @@ value_slice_1 (struct value *array, int lowbound, int length, int call_count)
   else
     {
       range_type = TYPE_INDEX_TYPE (TYPE_TARGET_TYPE (array_type));
-      slice_range_size = (ary_low_bound + row_count - 1) * (elem_count);
+      slice_range_size = ary_low_bound + (row_count * elem_count) - 1;
       ary_low_bound = TYPE_LOW_BOUND (range_type);
     }