/* Copyright (C) 2020-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Support classes to wrap up the process of iterating over a
   multi-dimensional Fortran array.  */

#ifndef GDB_F_ARRAY_WALKER_H
#define GDB_F_ARRAY_WALKER_H

#include "gdbtypes.h"
#include "f-lang.h"

/* Class for calculating the byte offset for elements within a single
   dimension of a Fortran array.  */
class fortran_array_offset_calculator
{
public:
  /* Create a new offset calculator for TYPE, which is either an array or a
     string.  */
  explicit fortran_array_offset_calculator (struct type *type)
  {
    /* Validate the type.  */
    type = check_typedef (type);
    if (type->code () != TYPE_CODE_ARRAY
	&& (type->code () != TYPE_CODE_STRING))
      error (_("can only compute offsets for arrays and strings"));

    /* Get the range, and extract the bounds.  */
    struct type *range_type = type->index_type ();
    if (!get_discrete_bounds (range_type, &m_lowerbound, &m_upperbound))
      error ("unable to read array bounds");

    /* Figure out the stride for this array.  */
    struct type *elt_type = check_typedef (type->target_type ());
    m_stride = type->index_type ()->bounds ()->bit_stride ();
    if (m_stride == 0)
      m_stride = type_length_units (elt_type);
    else
      {
	int unit_size
	  = gdbarch_addressable_memory_unit_size (elt_type->arch ());
	m_stride /= (unit_size * 8);
      }
  };

  /* Get the byte offset for element INDEX within the type we are working
     on.  There is no bounds checking done on INDEX.  If the stride is
     negative then we still assume that the base address (for the array
     object) points to the element with the lowest memory address, we then
     calculate an offset assuming that index 0 will be the element at the
     highest address, index 1 the next highest, and so on.  This is not
     quite how Fortran works in reality; in reality the base address of
     the object would point at the element with the highest address, and
     we would index backwards from there in the "normal" way, however,
     GDB's current value contents model doesn't support having the base
     address be near to the end of the value contents, so we currently
     adjust the base address of Fortran arrays with negative strides so
     their base address points at the lowest memory address.  This code
     here is part of working around this weirdness.  */
  LONGEST index_offset (LONGEST index)
  {
    LONGEST offset;
    if (m_stride < 0)
      offset = std::abs (m_stride) * (m_upperbound - index);
    else
      offset = std::abs (m_stride) * (index - m_lowerbound);
    return offset;
  }

private:

  /* The stride for the type we are working with.  */
  LONGEST m_stride;

  /* The upper bound for the type we are working with.  */
  LONGEST m_upperbound;

  /* The lower bound for the type we are working with.  */
  LONGEST m_lowerbound;
};

/* A base class used by fortran_array_walker.  There's no virtual methods
   here, sub-classes should just override the functions they want in order
   to specialise the behavior to their needs.  The functionality
   provided in these default implementations will visit every array
   element, but do nothing for each element.  */

struct fortran_array_walker_base_impl
{
  /* Called when iterating between the lower and upper bounds of each
     dimension of the array.  Return true if GDB should continue iterating,
     otherwise, return false.

     SHOULD_CONTINUE indicates if GDB is going to stop anyway, and should
     be taken into consideration when deciding what to return.  If
     SHOULD_CONTINUE is false then this function must also return false,
     the function is still called though in case extra work needs to be
     done as part of the stopping process.  */
  bool continue_walking (bool should_continue)
  { return should_continue; }

  /* Called when GDB starts iterating over a dimension of the array.  The
     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
     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.  LAST_P is true for the last call at a particular
     dimension.  For a concrete example of how this function is called
     see the comment on process_element below.  */
  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.  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 (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 (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,
			LONGEST index, bool last_p)
  { /* Nothing.  */ }
};

/* A class to wrap up the process of iterating over a multi-dimensional
   Fortran array.  IMPL is used to specialise what happens as we walk over
   the array.  See class FORTRAN_ARRAY_WALKER_BASE_IMPL (above) for the
   methods than can be used to customise the array walk.  */
template<typename Impl>
class fortran_array_walker
{
  /* Ensure that Impl is derived from the required base class.  This just
     ensures that all of the required API methods are available and have a
     sensible default implementation.  */
  static_assert ((std::is_base_of<fortran_array_walker_base_impl,Impl>::value));

public:
  /* Create a new array walker.  TYPE is the type of the array being walked
     over, and ADDRESS is the base address for the object of TYPE in
     memory.  All other arguments are forwarded to the constructor of the
     template parameter class IMPL.  */
  template <typename ...Args>
  fortran_array_walker (struct type *type, CORE_ADDR address,
			Args... args)
    : m_type (type),
      m_address (address),
      m_impl (type, address, args...),
      m_ndimensions (calc_f77_array_dims (m_type)),
      m_nss (0)
  { /* Nothing.  */ }

  /* Walk the array.  */
  void
  walk ()
  {
    walk_1 (m_type, 0, false);
  }

private:
  /* 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 (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 ();
    LONGEST lowerbound, upperbound;
    if (!get_discrete_bounds (range_type, &lowerbound, &upperbound))
      error ("failed to get range bounds");

    /* CALC is used to calculate the offsets for each element in this
       dimension.  */
    fortran_array_offset_calculator calc (type);

    m_nss++;
    gdb_assert (range_type->code () == TYPE_CODE_RANGE);
    m_impl.start_dimension (range_type->target_type (),
			    upperbound - lowerbound + 1,
			    m_nss == m_ndimensions);

    if (m_nss != m_ndimensions)
      {
	struct type *subarray_type = check_typedef (type)->target_type ();

	/* For dimensions other than the inner most, walk each element and
	   recurse while peeling off one more dimension of the array.  */
	for (LONGEST i = lowerbound;
	     m_impl.continue_walking (i < upperbound + 1);
	     i++)
	  {
	    /* Use the index and the stride to work out a new offset.  */
	    LONGEST new_offset = offset + calc.index_offset (i);

	    /* Now print the lower dimension.  */
	    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
      {
	struct type *elt_type = check_typedef (type)->target_type ();

	/* For the inner most dimension of the array, process each element
	   within this dimension.  */
	for (LONGEST i = lowerbound;
	     m_impl.continue_walking (i < upperbound + 1);
	     i++)
	  {
	    LONGEST elt_off = offset + calc.index_offset (i);

	    if (is_dynamic_type (elt_type))
	      {
		CORE_ADDR e_address = m_address + elt_off;
		elt_type = resolve_dynamic_type (elt_type, {}, e_address);
	      }

	    m_impl.process_element (elt_type, elt_off, i, i == upperbound);
	  }
      }

    m_impl.finish_dimension (m_nss == m_ndimensions, last_p || m_nss == 1);
    m_nss--;
  }

  /* The array type being processed.  */
  struct type *m_type;

  /* The address in target memory for the object of M_TYPE being
     processed.  This is required in order to resolve dynamic types.  */
  CORE_ADDR m_address;

  /* An instance of the template specialisation class.  */
  Impl m_impl;

  /* The total number of dimensions in M_TYPE.  */
  int m_ndimensions;

  /* The current dimension number being processed.  */
  int m_nss;
};

#endif /* GDB_F_ARRAY_WALKER_H */
