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

   Copyright (C) 2008-2012 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
   the number of string characters printed, or -1 if TYPE is not
   a dynamic array.  */
static int
dynamic_array_type (struct type *type, const gdb_byte *valaddr,
		    int embedded_offset, CORE_ADDR address,
		    struct ui_file *stream, int recurse,
		    const struct value *val,
		    const struct value_print_options *options)
{
  if (TYPE_NFIELDS (type) == 2
      && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_INT
      && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0
      && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0
      && value_bits_valid (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;

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

      ptr_type = TYPE_FIELD_TYPE (type, 1);
      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);

      return d_val_print (true_type,
			  value_contents_for_printing (ival),
			  value_embedded_offset (ival), addr,
			  stream, recurse + 1, ival, options);
    }
  return -1;
}

/* Implements the la_val_print routine for language D.  */
int
d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
             CORE_ADDR address, struct ui_file *stream, int recurse,
	     const struct value *val,
             const struct value_print_options *options)
{
  int ret;

  CHECK_TYPEDEF (type);
  switch (TYPE_CODE (type))
    {
      case TYPE_CODE_STRUCT:
        ret = dynamic_array_type (type, valaddr, embedded_offset, address,
				  stream, recurse, val, options);
	if (ret != -1)
	   break;
      default:
	ret = c_val_print (type, valaddr, embedded_offset, address, stream,
			   recurse, val, options);
    }

  return ret;
}
