/* Support for printing D values for GDB, the GNU debugger.

   Copyright (C) 2008-2021 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/>.  */

#include "defs.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "d-lang.h"
#include "c-lang.h"

/* Assuming that TYPE is a TYPE_CODE_STRUCT, verify that TYPE is a
   dynamic array, and then print its value to STREAM.  Return zero if
   TYPE is a dynamic array, non-zero otherwise.  */

static int
dynamic_array_type (struct type *type,
		    LONGEST embedded_offset, CORE_ADDR address,
		    struct ui_file *stream, int recurse,
		    struct value *val,
		    const struct value_print_options *options)
{
  if (type->num_fields () == 2
      && type->field (0).type ()->code () == TYPE_CODE_INT
      && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0
      && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0
      && !value_bits_any_optimized_out (val,
					TARGET_CHAR_BIT * embedded_offset,
					TARGET_CHAR_BIT * TYPE_LENGTH (type)))
    {
      CORE_ADDR addr;
      struct type *elttype;
      struct type *true_type;
      struct type *ptr_type;
      struct value *ival;
      int length;
      const gdb_byte *valaddr = value_contents_for_printing (val);

      length = unpack_field_as_long (type, valaddr + embedded_offset, 0);

      ptr_type = type->field (1).type ();
      elttype = check_typedef (TYPE_TARGET_TYPE (ptr_type));
      addr = unpack_pointer (ptr_type,
			     valaddr + TYPE_FIELD_BITPOS (type, 1) / 8
			     + embedded_offset);
      true_type = check_typedef (elttype);

      true_type = lookup_array_range_type (true_type, 0, length - 1);
      ival = value_at (true_type, addr);
      true_type = value_type (ival);

      d_value_print_inner (ival, stream, recurse + 1, options);
      return 0;
    }
  return 1;
}

/* See d-lang.h.  */

void
d_value_print_inner (struct value *val, struct ui_file *stream, int recurse,
		     const struct value_print_options *options)
{
  int ret;

  struct type *type = check_typedef (value_type (val));
  switch (type->code ())
    {
      case TYPE_CODE_STRUCT:
	ret = dynamic_array_type (type, value_embedded_offset (val),
				  value_address (val),
				  stream, recurse, val, options);
	if (ret == 0)
	  break;
	/* Fall through.  */
      default:
	c_value_print_inner (val, stream, recurse, options);
	break;
    }
}
