gdb/linux-tdep.c: Add Perms to the 'info proc mappings' output
[binutils-gdb.git] / gdb / f-array-walker.h
index 24b53ff76972fdf11212e831dac9d6f90006eee9..ad97dd51cd34bb9d53c64ccb2300cae8ac717dfa 100644 (file)
@@ -115,11 +115,13 @@ struct fortran_array_walker_base_impl
   { return should_continue; }
 
   /* Called when GDB starts iterating over a dimension of the array.  The
-     argument INNER_P is true for the inner most dimension (the dimension
-     containing the actual elements of the array), and false for more outer
-     dimensions.  For a concrete example of how this function is called
-     see the comment on process_element below.  */
-  void start_dimension (bool inner_p)
+     argument INDEX_TYPE is the type of the index used to address elements
+     in the dimension, NELTS holds the number of the elements there, and
+     INNER_P is true for the inner most dimension (the dimension containing
+     the actual elements of the array), and false for more outer dimensions.
+     For a concrete example of how this function is called see the comment
+     on process_element below.  */
+  void start_dimension (struct type *index_type, LONGEST nelts, bool inner_p)
   { /* Nothing.  */ }
 
   /* Called when GDB finishes iterating over a dimension of the array.  The
@@ -131,26 +133,47 @@ struct fortran_array_walker_base_impl
   void finish_dimension (bool inner_p, bool last_p)
   { /* Nothing.  */ }
 
+  /* Called when processing dimensions of the array other than the
+     innermost one.  WALK_1 is the walker to normally call, ELT_TYPE is
+     the type of the element being extracted, and ELT_OFF is the offset
+     of the element from the start of array being walked.  INDEX is the
+     value of the index the current element is at in the upper dimension.
+     Finally LAST_P is true only when this is the last element that will
+     be processed in this dimension.  */
+  void process_dimension (gdb::function_view<void (struct type *,
+                                                  int, bool)> walk_1,
+                         struct type *elt_type, LONGEST elt_off,
+                         LONGEST index, bool last_p)
+  {
+    walk_1 (elt_type, elt_off, last_p);
+  }
+
   /* Called when processing the inner most dimension of the array, for
      every element in the array.  ELT_TYPE is the type of the element being
      extracted, and ELT_OFF is the offset of the element from the start of
-     array being walked, and LAST_P is true only when this is the last
-     element that will be processed in this dimension.
+     array being walked.  INDEX is the value of the index the current
+     element is at in the upper dimension.  Finally LAST_P is true only
+     when this is the last element that will be processed in this dimension.
 
-     Given this two dimensional array ((1, 2) (3, 4)), the calls to
+     Given this two dimensional array ((1, 2) (3, 4) (5, 6)), the calls to
      start_dimension, process_element, and finish_dimension look like this:
 
-     start_dimension (false);
-       start_dimension (true);
+     start_dimension (INDEX_TYPE, 3, false);
+       start_dimension (INDEX_TYPE, 2, true);
          process_element (TYPE, OFFSET, false);
          process_element (TYPE, OFFSET, true);
        finish_dimension (true, false);
-       start_dimension (true);
+       start_dimension (INDEX_TYPE, 2, true);
+         process_element (TYPE, OFFSET, false);
+         process_element (TYPE, OFFSET, true);
+       finish_dimension (true, true);
+       start_dimension (INDEX_TYPE, 2, true);
          process_element (TYPE, OFFSET, false);
          process_element (TYPE, OFFSET, true);
        finish_dimension (true, true);
      finish_dimension (false, true);  */
-  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)
   { /* Nothing.  */ }
 };
 
@@ -177,22 +200,23 @@ public:
     : m_type (type),
       m_address (address),
       m_impl (type, address, args...),
-      m_ndimensions (calc_f77_array_dims (m_type))
+      m_ndimensions (calc_f77_array_dims (m_type)),
+      m_nss (0)
   { /* Nothing.  */ }
 
   /* Walk the array.  */
   void
   walk ()
   {
-    walk_1 (1, m_type, 0, false);
+    walk_1 (m_type, 0, false);
   }
 
 private:
-  /* The core of the array walking algorithm.  NSS is the current
-     dimension number being processed, TYPE is the type of this dimension,
-     and OFFSET is the offset (in bytes) for the start of this dimension.  */
+  /* The core of the array walking algorithm.  TYPE is the type of
+     the current dimension being processed and OFFSET is the offset
+     (in bytes) for the start of this dimension.  */
   void
-  walk_1 (int nss, struct type *type, int offset, bool last_p)
+  walk_1 (struct type *type, int offset, bool last_p)
   {
     /* Extract the range, and get lower and upper bounds.  */
     struct type *range_type = check_typedef (type)->index_type ();
@@ -204,9 +228,13 @@ private:
        dimension.  */
     fortran_array_offset_calculator calc (type);
 
-    m_impl.start_dimension (nss == m_ndimensions);
+    m_nss++;
+    gdb_assert (range_type->code () == TYPE_CODE_RANGE);
+    m_impl.start_dimension (TYPE_TARGET_TYPE (range_type),
+                           upperbound - lowerbound + 1,
+                           m_nss == m_ndimensions);
 
-    if (nss != m_ndimensions)
+    if (m_nss != m_ndimensions)
       {
        struct type *subarray_type = TYPE_TARGET_TYPE (check_typedef (type));
 
@@ -220,7 +248,12 @@ private:
            LONGEST new_offset = offset + calc.index_offset (i);
 
            /* Now print the lower dimension.  */
-           walk_1 (nss + 1, subarray_type, new_offset, (i == upperbound));
+           m_impl.process_dimension
+             ([this] (struct type *w_type, int w_offset, bool w_last_p) -> void
+               {
+                 this->walk_1 (w_type, w_offset, w_last_p);
+               },
+              subarray_type, new_offset, i, i == upperbound);
          }
       }
     else
@@ -241,11 +274,12 @@ private:
                elt_type = resolve_dynamic_type (elt_type, {}, e_address);
              }
 
-           m_impl.process_element (elt_type, elt_off, (i == upperbound));
+           m_impl.process_element (elt_type, elt_off, i, i == upperbound);
          }
       }
 
-    m_impl.finish_dimension (nss == m_ndimensions, last_p || nss == 1);
+    m_impl.finish_dimension (m_nss == m_ndimensions, last_p || m_nss == 1);
+    m_nss--;
   }
 
   /* The array type being processed.  */
@@ -260,6 +294,9 @@ private:
 
   /* The total number of dimensions in M_TYPE.  */
   int m_ndimensions;
+
+  /* The current dimension number being processed.  */
+  int m_nss;
 };
 
 #endif /* F_ARRAY_WALKER_H */