Respect `set print array-indexes' with Fortran arrays

Add `set print array-indexes' handling for Fortran arrays.  Currently
the setting is ignored and indices are never shown.

Keep track of the most recent index handled so that any outstanding
repeated elements printed when the limit set by `set print elements' is
hit have the correct index shown.

Output now looks like:

(gdb) set print array-indexes on
(gdb) print array_1d
$1 = ((-2) = 1, (-1) = 1, (0) = 1, (1) = 1, (2) = 1)
(gdb) set print repeats 4
(gdb) set print elements 12
(gdb) print array_2d
$2 = ((-2) = ((-2) = 2, <repeats 5 times>) (-1) = ((-2) = 2, <repeats 5 times>) (0) = ((-2) = 2, (-1) = 2, ...) ...)
(gdb)

for a 5-element vector and a 5 by 5 array filled with the value of 2.
This commit is contained in:
Maciej W. Rozycki 2022-01-19 21:55:10 +00:00
parent 6b4338c868
commit 5d4c63a635
5 changed files with 279 additions and 27 deletions

View file

@ -115,12 +115,13 @@ struct fortran_array_walker_base_impl
{ return should_continue; }
/* Called when GDB starts iterating over a dimension of the array. The
argument NELTS holds the number of the elements in the dimension and
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 (LONGEST nelts, bool inner_p)
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
@ -135,12 +136,14 @@ struct fortran_array_walker_base_impl
/* 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, and LAST_P is
true only when this is the last element that will be processed in
this dimension. */
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, bool last_p)
struct type *elt_type, LONGEST elt_off,
LONGEST index, bool last_p)
{
walk_1 (elt_type, elt_off, last_p);
}
@ -148,27 +151,29 @@ struct fortran_array_walker_base_impl
/* 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) (5, 6)), the calls to
start_dimension, process_element, and finish_dimension look like this:
start_dimension (3, false);
start_dimension (2, 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 (2, true);
start_dimension (INDEX_TYPE, 2, true);
process_element (TYPE, OFFSET, false);
process_element (TYPE, OFFSET, true);
finish_dimension (true, true);
start_dimension (2, 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. */ }
};
@ -224,7 +229,9 @@ private:
fortran_array_offset_calculator calc (type);
m_nss++;
m_impl.start_dimension (upperbound - lowerbound + 1,
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 (m_nss != m_ndimensions)
@ -246,7 +253,7 @@ private:
{
this->walk_1 (w_type, w_offset, w_last_p);
},
subarray_type, new_offset, i == upperbound);
subarray_type, new_offset, i, i == upperbound);
}
}
else
@ -267,7 +274,7 @@ 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);
}
}