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

   Copyright (C) 1986-2022 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 <ctype.h>
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
#include "valprint.h"
#include "language.h"
#include "annotate.h"
#include "ada-lang.h"
#include "target-float.h"
#include "cli/cli-style.h"
#include "gdbarch.h"

static int print_field_values (struct value *, struct value *,
			       struct ui_file *, int,
			       const struct value_print_options *,
			       int, const struct language_defn *);



/* Make TYPE unsigned if its range of values includes no negatives.  */
static void
adjust_type_signedness (struct type *type)
{
  if (type != NULL && type->code () == TYPE_CODE_RANGE
      && type->bounds ()->low.const_val () >= 0)
    type->set_is_unsigned (true);
}

/* Assuming TYPE is a simple array type, prints its lower bound on STREAM,
   if non-standard (i.e., other than 1 for numbers, other than lower bound
   of index type for enumerated type).  Returns 1 if something printed,
   otherwise 0.  */

static int
print_optional_low_bound (struct ui_file *stream, struct type *type,
			  const struct value_print_options *options)
{
  struct type *index_type;
  LONGEST low_bound;
  LONGEST high_bound;

  if (options->print_array_indexes)
    return 0;

  if (!get_array_bounds (type, &low_bound, &high_bound))
    return 0;

  /* If this is an empty array, then don't print the lower bound.
     That would be confusing, because we would print the lower bound,
     followed by... nothing!  */
  if (low_bound > high_bound)
    return 0;

  index_type = type->index_type ();

  while (index_type->code () == TYPE_CODE_RANGE)
    {
      /* We need to know what the base type is, in order to do the
	 appropriate check below.  Otherwise, if this is a subrange
	 of an enumerated type, where the underlying value of the
	 first element is typically 0, we might test the low bound
	 against the wrong value.  */
      index_type = index_type->target_type ();
    }

  /* Don't print the lower bound if it's the default one.  */
  switch (index_type->code ())
    {
    case TYPE_CODE_BOOL:
    case TYPE_CODE_CHAR:
      if (low_bound == 0)
	return 0;
      break;
    case TYPE_CODE_ENUM:
      if (low_bound == 0)
	return 0;
      low_bound = index_type->field (low_bound).loc_enumval ();
      break;
    case TYPE_CODE_UNDEF:
      index_type = NULL;
      /* FALL THROUGH */
    default:
      if (low_bound == 1)
	return 0;
      break;
    }

  ada_print_scalar (index_type, low_bound, stream);
  gdb_printf (stream, " => ");
  return 1;
}

/*  Version of val_print_array_elements for GNAT-style packed arrays.
    Prints elements of packed array of type TYPE from VALADDR on
    STREAM.  Formats according to OPTIONS and separates with commas.
    RECURSE is the recursion (nesting) level.  TYPE must have been
    decoded (as by ada_coerce_to_simple_array).  */

static void
val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
				 int offset, struct ui_file *stream,
				 int recurse,
				 const struct value_print_options *options)
{
  unsigned int i;
  unsigned int things_printed = 0;
  unsigned len;
  struct type *elttype, *index_type;
  unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0);
  LONGEST low = 0;

  scoped_value_mark mark;

  elttype = type->target_type ();
  index_type = type->index_type ();

  {
    LONGEST high;

    if (!get_discrete_bounds (index_type, &low, &high))
      len = 1;
    else if (low > high)
      {
	/* The array length should normally be HIGH_POS - LOW_POS + 1.
	   But in Ada we allow LOW_POS to be greater than HIGH_POS for
	   empty arrays.  In that situation, the array length is just zero,
	   not negative!  */
	len = 0;
      }
    else
      len = high - low + 1;
  }

  if (index_type->code () == TYPE_CODE_RANGE)
    index_type = index_type->target_type ();

  i = 0;
  annotate_array_section_begin (i, elttype);

  while (i < len && things_printed < options->print_max)
    {
      struct value *v0, *v1;
      int i0;

      if (i != 0)
	{
	  if (options->prettyformat_arrays)
	    {
	      gdb_printf (stream, ",\n");
	      print_spaces (2 + 2 * recurse, stream);
	    }
	  else
	    {
	      gdb_printf (stream, ", ");
	    }
	}
      else if (options->prettyformat_arrays)
	{
	  gdb_printf (stream, "\n");
	  print_spaces (2 + 2 * recurse, stream);
	}
      stream->wrap_here (2 + 2 * recurse);
      maybe_print_array_index (index_type, i + low, stream, options);

      i0 = i;
      v0 = ada_value_primitive_packed_val (NULL, valaddr + offset,
					   (i0 * bitsize) / HOST_CHAR_BIT,
					   (i0 * bitsize) % HOST_CHAR_BIT,
					   bitsize, elttype);
      while (1)
	{
	  i += 1;
	  if (i >= len)
	    break;
	  v1 = ada_value_primitive_packed_val (NULL, valaddr + offset,
					       (i * bitsize) / HOST_CHAR_BIT,
					       (i * bitsize) % HOST_CHAR_BIT,
					       bitsize, elttype);
	  if (check_typedef (value_type (v0))->length ()
	      != check_typedef (value_type (v1))->length ())
	    break;
	  if (!value_contents_eq (v0, value_embedded_offset (v0),
				  v1, value_embedded_offset (v1),
				  check_typedef (value_type (v0))->length ()))
	    break;
	}

      if (i - i0 > options->repeat_count_threshold)
	{
	  struct value_print_options opts = *options;

	  opts.deref_ref = 0;
	  common_val_print (v0, stream, recurse + 1, &opts, current_language);
	  annotate_elt_rep (i - i0);
	  gdb_printf (stream, _(" %p[<repeats %u times>%p]"),
		      metadata_style.style ().ptr (), i - i0, nullptr);
	  annotate_elt_rep_end ();

	}
      else
	{
	  int j;
	  struct value_print_options opts = *options;

	  opts.deref_ref = 0;
	  for (j = i0; j < i; j += 1)
	    {
	      if (j > i0)
		{
		  if (options->prettyformat_arrays)
		    {
		      gdb_printf (stream, ",\n");
		      print_spaces (2 + 2 * recurse, stream);
		    }
		  else
		    {
		      gdb_printf (stream, ", ");
		    }
		  stream->wrap_here (2 + 2 * recurse);
		  maybe_print_array_index (index_type, j + low,
					   stream, options);
		}
	      common_val_print (v0, stream, recurse + 1, &opts,
				current_language);
	      annotate_elt ();
	    }
	}
      things_printed += i - i0;
    }
  annotate_array_section_end ();
  if (i < len)
    {
      gdb_printf (stream, "...");
    }
}

/* Print the character C on STREAM as part of the contents of a literal
   string whose delimiter is QUOTER.  TYPE_LEN is the length in bytes
   of the character.  */

void
ada_emit_char (int c, struct type *type, struct ui_file *stream,
	       int quoter, int type_len)
{
  /* If this character fits in the normal ASCII range, and is
     a printable character, then print the character as if it was
     an ASCII character, even if this is a wide character.
     The UCHAR_MAX check is necessary because the isascii function
     requires that its argument have a value of an unsigned char,
     or EOF (EOF is obviously not printable).  */
  if (c <= UCHAR_MAX && isascii (c) && isprint (c))
    {
      if (c == quoter && c == '"')
	gdb_printf (stream, "\"\"");
      else
	gdb_printf (stream, "%c", c);
    }
  else
    {
      /* Follow GNAT's lead here and only use 6 digits for
	 wide_wide_character.  */
      gdb_printf (stream, "[\"%0*x\"]", std::min (6, type_len * 2), c);
    }
}

/* Character #I of STRING, given that TYPE_LEN is the size in bytes
   of a character.  */

static int
char_at (const gdb_byte *string, int i, int type_len,
	 enum bfd_endian byte_order)
{
  if (type_len == 1)
    return string[i];
  else
    return (int) extract_unsigned_integer (string + type_len * i,
					   type_len, byte_order);
}

/* Print a floating-point value of type TYPE, pointed to in GDB by
   VALADDR, on STREAM.  Use Ada formatting conventions: there must be
   a decimal point, and at least one digit before and after the
   point.  We use the GNAT format for NaNs and infinities.  */

static void
ada_print_floating (const gdb_byte *valaddr, struct type *type,
		    struct ui_file *stream)
{
  string_file tmp_stream;

  print_floating (valaddr, type, &tmp_stream);

  std::string s = tmp_stream.release ();
  size_t skip_count = 0;

  /* Don't try to modify a result representing an error.  */
  if (s[0] == '<')
    {
      gdb_puts (s.c_str (), stream);
      return;
    }

  /* Modify for Ada rules.  */

  size_t pos = s.find ("inf");
  if (pos == std::string::npos)
    pos = s.find ("Inf");
  if (pos == std::string::npos)
    pos = s.find ("INF");
  if (pos != std::string::npos)
    s.replace (pos, 3, "Inf");

  if (pos == std::string::npos)
    {
      pos = s.find ("nan");
      if (pos == std::string::npos)
	pos = s.find ("NaN");
      if (pos == std::string::npos)
	pos = s.find ("Nan");
      if (pos != std::string::npos)
	{
	  s[pos] = s[pos + 2] = 'N';
	  if (s[0] == '-')
	    skip_count = 1;
	}
    }

  if (pos == std::string::npos
      && s.find ('.') == std::string::npos)
    {
      pos = s.find ('e');
      if (pos == std::string::npos)
	gdb_printf (stream, "%s.0", s.c_str ());
      else
	gdb_printf (stream, "%.*s.0%s", (int) pos, s.c_str (), &s[pos]);
    }
  else
    gdb_printf (stream, "%s", &s[skip_count]);
}

void
ada_printchar (int c, struct type *type, struct ui_file *stream)
{
  gdb_puts ("'", stream);
  ada_emit_char (c, type, stream, '\'', type->length ());
  gdb_puts ("'", stream);
}

/* [From print_type_scalar in typeprint.c].   Print VAL on STREAM in a
   form appropriate for TYPE, if non-NULL.  If TYPE is NULL, print VAL
   like a default signed integer.  */

void
ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream)
{
  unsigned int i;
  unsigned len;

  if (!type)
    {
      print_longest (stream, 'd', 0, val);
      return;
    }

  type = ada_check_typedef (type);

  switch (type->code ())
    {

    case TYPE_CODE_ENUM:
      len = type->num_fields ();
      for (i = 0; i < len; i++)
	{
	  if (type->field (i).loc_enumval () == val)
	    {
	      break;
	    }
	}
      if (i < len)
	{
	  fputs_styled (ada_enum_name (type->field (i).name ()),
			variable_name_style.style (), stream);
	}
      else
	{
	  print_longest (stream, 'd', 0, val);
	}
      break;

    case TYPE_CODE_INT:
      print_longest (stream, type->is_unsigned () ? 'u' : 'd', 0, val);
      break;

    case TYPE_CODE_CHAR:
      current_language->printchar (val, type, stream);
      break;

    case TYPE_CODE_BOOL:
      gdb_printf (stream, val ? "true" : "false");
      break;

    case TYPE_CODE_RANGE:
      ada_print_scalar (type->target_type (), val, stream);
      return;

    case TYPE_CODE_UNDEF:
    case TYPE_CODE_PTR:
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_FLT:
    case TYPE_CODE_VOID:
    case TYPE_CODE_SET:
    case TYPE_CODE_STRING:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_METHOD:
    case TYPE_CODE_REF:
      warning (_("internal error: unhandled type in ada_print_scalar"));
      break;

    default:
      error (_("Invalid type code in symbol table."));
    }
}

/* Print the character string STRING, printing at most LENGTH characters.
   Printing stops early if the number hits print_max; repeat counts
   are printed as appropriate.  Print ellipses at the end if we
   had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
   TYPE_LEN is the length (1 or 2) of the character type.  */

static void
printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
	  unsigned int length, int force_ellipses, int type_len,
	  const struct value_print_options *options)
{
  enum bfd_endian byte_order = type_byte_order (elttype);
  unsigned int i;
  unsigned int things_printed = 0;
  int in_quotes = 0;
  int need_comma = 0;

  if (length == 0)
    {
      gdb_puts ("\"\"", stream);
      return;
    }

  for (i = 0; i < length && things_printed < options->print_max; i += 1)
    {
      /* Position of the character we are examining
	 to see whether it is repeated.  */
      unsigned int rep1;
      /* Number of repetitions we have detected so far.  */
      unsigned int reps;

      QUIT;

      if (need_comma)
	{
	  gdb_puts (", ", stream);
	  need_comma = 0;
	}

      rep1 = i + 1;
      reps = 1;
      while (rep1 < length
	     && char_at (string, rep1, type_len, byte_order)
		== char_at (string, i, type_len, byte_order))
	{
	  rep1 += 1;
	  reps += 1;
	}

      if (reps > options->repeat_count_threshold)
	{
	  if (in_quotes)
	    {
	      gdb_puts ("\", ", stream);
	      in_quotes = 0;
	    }
	  gdb_puts ("'", stream);
	  ada_emit_char (char_at (string, i, type_len, byte_order),
			 elttype, stream, '\'', type_len);
	  gdb_puts ("'", stream);
	  gdb_printf (stream, _(" %p[<repeats %u times>%p]"),
		      metadata_style.style ().ptr (), reps, nullptr);
	  i = rep1 - 1;
	  things_printed += options->repeat_count_threshold;
	  need_comma = 1;
	}
      else
	{
	  if (!in_quotes)
	    {
	      gdb_puts ("\"", stream);
	      in_quotes = 1;
	    }
	  ada_emit_char (char_at (string, i, type_len, byte_order),
			 elttype, stream, '"', type_len);
	  things_printed += 1;
	}
    }

  /* Terminate the quotes if necessary.  */
  if (in_quotes)
    gdb_puts ("\"", stream);

  if (force_ellipses || i < length)
    gdb_puts ("...", stream);
}

void
ada_printstr (struct ui_file *stream, struct type *type,
	      const gdb_byte *string, unsigned int length,
	      const char *encoding, int force_ellipses,
	      const struct value_print_options *options)
{
  printstr (stream, type, string, length, force_ellipses, type->length (),
	    options);
}

static int
print_variant_part (struct value *value, int field_num,
		    struct value *outer_value,
		    struct ui_file *stream, int recurse,
		    const struct value_print_options *options,
		    int comma_needed,
		    const struct language_defn *language)
{
  struct type *type = value_type (value);
  struct type *var_type = type->field (field_num).type ();
  int which = ada_which_variant_applies (var_type, outer_value);

  if (which < 0)
    return 0;

  struct value *variant_field = value_field (value, field_num);
  struct value *active_component = value_field (variant_field, which);
  return print_field_values (active_component, outer_value, stream, recurse,
			     options, comma_needed, language);
}

/* Print out fields of VALUE.

   STREAM, RECURSE, and OPTIONS have the same meanings as in
   ada_print_value and ada_value_print.

   OUTER_VALUE gives the enclosing record (used to get discriminant
   values when printing variant parts).

   COMMA_NEEDED is 1 if fields have been printed at the current recursion
   level, so that a comma is needed before any field printed by this
   call.

   Returns 1 if COMMA_NEEDED or any fields were printed.  */

static int
print_field_values (struct value *value, struct value *outer_value,
		    struct ui_file *stream, int recurse,
		    const struct value_print_options *options,
		    int comma_needed,
		    const struct language_defn *language)
{
  int i, len;

  struct type *type = value_type (value);
  len = type->num_fields ();

  for (i = 0; i < len; i += 1)
    {
      if (ada_is_ignored_field (type, i))
	continue;

      if (ada_is_wrapper_field (type, i))
	{
	  struct value *field_val = ada_value_primitive_field (value, 0,
							       i, type);
	  comma_needed =
	    print_field_values (field_val, field_val,
				stream, recurse, options,
				comma_needed, language);
	  continue;
	}
      else if (ada_is_variant_part (type, i))
	{
	  comma_needed =
	    print_variant_part (value, i, outer_value, stream, recurse,
				options, comma_needed, language);
	  continue;
	}

      if (comma_needed)
	gdb_printf (stream, ", ");
      comma_needed = 1;

      if (options->prettyformat)
	{
	  gdb_printf (stream, "\n");
	  print_spaces (2 + 2 * recurse, stream);
	}
      else
	{
	  stream->wrap_here (2 + 2 * recurse);
	}

      annotate_field_begin (type->field (i).type ());
      gdb_printf (stream, "%.*s",
		  ada_name_prefix_len (type->field (i).name ()),
		  type->field (i).name ());
      annotate_field_name_end ();
      gdb_puts (" => ", stream);
      annotate_field_value ();

      if (TYPE_FIELD_PACKED (type, i))
	{
	  /* Bitfields require special handling, especially due to byte
	     order problems.  */
	  if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i))
	    {
	      fputs_styled (_("<optimized out or zero length>"),
			    metadata_style.style (), stream);
	    }
	  else
	    {
	      struct value *v;
	      int bit_pos = type->field (i).loc_bitpos ();
	      int bit_size = TYPE_FIELD_BITSIZE (type, i);
	      struct value_print_options opts;

	      adjust_type_signedness (type->field (i).type ());
	      v = ada_value_primitive_packed_val
		    (value, nullptr,
		     bit_pos / HOST_CHAR_BIT,
		     bit_pos % HOST_CHAR_BIT,
		     bit_size, type->field (i).type ());
	      opts = *options;
	      opts.deref_ref = 0;
	      common_val_print (v, stream, recurse + 1, &opts, language);
	    }
	}
      else
	{
	  struct value_print_options opts = *options;

	  opts.deref_ref = 0;

	  struct value *v = value_field (value, i);
	  common_val_print (v, stream, recurse + 1, &opts, language);
	}
      annotate_field_end ();
    }

  return comma_needed;
}

/* Implement Ada val_print'ing for the case where TYPE is
   a TYPE_CODE_ARRAY of characters.  */

static void
ada_val_print_string (struct type *type, const gdb_byte *valaddr,
		      int offset_aligned,
		      struct ui_file *stream, int recurse,
		      const struct value_print_options *options)
{
  enum bfd_endian byte_order = type_byte_order (type);
  struct type *elttype = type->target_type ();
  unsigned int eltlen;
  unsigned int len;

  /* We know that ELTTYPE cannot possibly be null, because we assume
     that we're called only when TYPE is a string-like type.
     Similarly, the size of ELTTYPE should also be non-null, since
     it's a character-like type.  */
  gdb_assert (elttype != NULL);
  gdb_assert (elttype->length () != 0);

  eltlen = elttype->length ();
  len = type->length () / eltlen;

  /* If requested, look for the first null char and only print
     elements up to it.  */
  if (options->stop_print_at_null)
    {
      int temp_len;

      /* Look for a NULL char.  */
      for (temp_len = 0;
	   (temp_len < len
	    && temp_len < options->print_max
	    && char_at (valaddr + offset_aligned,
			temp_len, eltlen, byte_order) != 0);
	   temp_len += 1);
      len = temp_len;
    }

  printstr (stream, elttype, valaddr + offset_aligned, len, 0,
	    eltlen, options);
}

/* Implement Ada value_print'ing for the case where TYPE is a
   TYPE_CODE_PTR.  */

static void
ada_value_print_ptr (struct value *val,
		     struct ui_file *stream, int recurse,
		     const struct value_print_options *options)
{
  if (!options->format
      && value_type (val)->target_type ()->code () == TYPE_CODE_INT
      && value_type (val)->target_type ()->length () == 0)
    {
      gdb_puts ("null", stream);
      return;
    }

  common_val_print (val, stream, recurse, options, language_def (language_c));

  struct type *type = ada_check_typedef (value_type (val));
  if (ada_is_tag_type (type))
    {
      gdb::unique_xmalloc_ptr<char> name = ada_tag_name (val);

      if (name != NULL)
	gdb_printf (stream, " (%s)", name.get ());
    }
}

/* Implement Ada val_print'ing for the case where TYPE is
   a TYPE_CODE_INT or TYPE_CODE_RANGE.  */

static void
ada_value_print_num (struct value *val, struct ui_file *stream, int recurse,
		     const struct value_print_options *options)
{
  struct type *type = ada_check_typedef (value_type (val));
  const gdb_byte *valaddr = value_contents_for_printing (val).data ();

  if (type->code () == TYPE_CODE_RANGE
      && (type->target_type ()->code () == TYPE_CODE_ENUM
	  || type->target_type ()->code () == TYPE_CODE_BOOL
	  || type->target_type ()->code () == TYPE_CODE_CHAR))
    {
      /* For enum-valued ranges, we want to recurse, because we'll end
	 up printing the constant's name rather than its numeric
	 value.  Character and fixed-point types are also printed
	 differently, so recuse for those as well.  */
      struct type *target_type = type->target_type ();
      val = value_cast (target_type, val);
      common_val_print (val, stream, recurse + 1, options,
			language_def (language_ada));
      return;
    }
  else
    {
      int format = (options->format ? options->format
		    : options->output_format);

      if (format)
	{
	  struct value_print_options opts = *options;

	  opts.format = format;
	  value_print_scalar_formatted (val, &opts, 0, stream);
	}
      else if (ada_is_system_address_type (type))
	{
	  /* FIXME: We want to print System.Address variables using
	     the same format as for any access type.  But for some
	     reason GNAT encodes the System.Address type as an int,
	     so we have to work-around this deficiency by handling
	     System.Address values as a special case.  */

	  struct gdbarch *gdbarch = type->arch ();
	  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
	  CORE_ADDR addr = extract_typed_address (valaddr, ptr_type);

	  gdb_printf (stream, "(");
	  type_print (type, "", stream, -1);
	  gdb_printf (stream, ") ");
	  gdb_puts (paddress (gdbarch, addr), stream);
	}
      else
	{
	  value_print_scalar_formatted (val, options, 0, stream);
	  if (ada_is_character_type (type))
	    {
	      LONGEST c;

	      gdb_puts (" ", stream);
	      c = unpack_long (type, valaddr);
	      ada_printchar (c, type, stream);
	    }
	}
      return;
    }
}

/* Implement Ada val_print'ing for the case where TYPE is
   a TYPE_CODE_ENUM.  */

static void
ada_val_print_enum (struct value *value, struct ui_file *stream, int recurse,
		    const struct value_print_options *options)
{
  int i;
  unsigned int len;
  LONGEST val;

  if (options->format)
    {
      value_print_scalar_formatted (value, options, 0, stream);
      return;
    }

  struct type *type = ada_check_typedef (value_type (value));
  const gdb_byte *valaddr = value_contents_for_printing (value).data ();
  int offset_aligned = ada_aligned_value_addr (type, valaddr) - valaddr;

  len = type->num_fields ();
  val = unpack_long (type, valaddr + offset_aligned);
  for (i = 0; i < len; i++)
    {
      QUIT;
      if (val == type->field (i).loc_enumval ())
	break;
    }

  if (i < len)
    {
      const char *name = ada_enum_name (type->field (i).name ());

      if (name[0] == '\'')
	gdb_printf (stream, "%ld %ps", (long) val,
		    styled_string (variable_name_style.style (),
				   name));
      else
	fputs_styled (name, variable_name_style.style (), stream);
    }
  else
    print_longest (stream, 'd', 0, val);
}

/* Implement Ada val_print'ing for the case where the type is
   TYPE_CODE_STRUCT or TYPE_CODE_UNION.  */

static void
ada_val_print_struct_union (struct value *value,
			    struct ui_file *stream,
			    int recurse,
			    const struct value_print_options *options)
{
  if (ada_is_bogus_array_descriptor (value_type (value)))
    {
      gdb_printf (stream, "(...?)");
      return;
    }

  gdb_printf (stream, "(");

  if (print_field_values (value, value, stream, recurse, options,
			  0, language_def (language_ada)) != 0
      && options->prettyformat)
    {
      gdb_printf (stream, "\n");
      print_spaces (2 * recurse, stream);
    }

  gdb_printf (stream, ")");
}

/* Implement Ada value_print'ing for the case where TYPE is a
   TYPE_CODE_ARRAY.  */

static void
ada_value_print_array (struct value *val, struct ui_file *stream, int recurse,
		       const struct value_print_options *options)
{
  struct type *type = ada_check_typedef (value_type (val));

  /* For an array of characters, print with string syntax.  */
  if (ada_is_string_type (type)
      && (options->format == 0 || options->format == 's'))
    {
      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
      int offset_aligned = ada_aligned_value_addr (type, valaddr) - valaddr;

      ada_val_print_string (type, valaddr, offset_aligned, stream, recurse,
			    options);
      return;
    }

  gdb_printf (stream, "(");
  print_optional_low_bound (stream, type, options);

  if (value_entirely_optimized_out (val))
    val_print_optimized_out (val, stream);
  else if (TYPE_FIELD_BITSIZE (type, 0) > 0)
    {
      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
      int offset_aligned = ada_aligned_value_addr (type, valaddr) - valaddr;
      val_print_packed_array_elements (type, valaddr, offset_aligned,
				       stream, recurse, options);
    }
  else
    value_print_array_elements (val, stream, recurse, options, 0);
  gdb_printf (stream, ")");
}

/* Implement Ada val_print'ing for the case where TYPE is
   a TYPE_CODE_REF.  */

static void
ada_val_print_ref (struct type *type, const gdb_byte *valaddr,
		   int offset, int offset_aligned, CORE_ADDR address,
		   struct ui_file *stream, int recurse,
		   struct value *original_value,
		   const struct value_print_options *options)
{
  /* For references, the debugger is expected to print the value as
     an address if DEREF_REF is null.  But printing an address in place
     of the object value would be confusing to an Ada programmer.
     So, for Ada values, we print the actual dereferenced value
     regardless.  */
  struct type *elttype = check_typedef (type->target_type ());
  struct value *deref_val;
  CORE_ADDR deref_val_int;

  if (elttype->code () == TYPE_CODE_UNDEF)
    {
      fputs_styled ("<ref to undefined type>", metadata_style.style (),
		    stream);
      return;
    }

  deref_val = coerce_ref_if_computed (original_value);
  if (deref_val)
    {
      if (ada_is_tagged_type (value_type (deref_val), 1))
	deref_val = ada_tag_value_at_base_address (deref_val);

      common_val_print (deref_val, stream, recurse + 1, options,
			language_def (language_ada));
      return;
    }

  deref_val_int = unpack_pointer (type, valaddr + offset_aligned);
  if (deref_val_int == 0)
    {
      gdb_puts ("(null)", stream);
      return;
    }

  deref_val
    = ada_value_ind (value_from_pointer (lookup_pointer_type (elttype),
					 deref_val_int));
  if (ada_is_tagged_type (value_type (deref_val), 1))
    deref_val = ada_tag_value_at_base_address (deref_val);

  if (value_lazy (deref_val))
    value_fetch_lazy (deref_val);

  common_val_print (deref_val, stream, recurse + 1,
		    options, language_def (language_ada));
}

/* See the comment on ada_value_print.  This function differs in that
   it does not catch evaluation errors (leaving that to its
   caller).  */

void
ada_value_print_inner (struct value *val, struct ui_file *stream, int recurse,
		       const struct value_print_options *options)
{
  struct type *type = ada_check_typedef (value_type (val));

  if (ada_is_array_descriptor_type (type)
      || (ada_is_constrained_packed_array_type (type)
	  && type->code () != TYPE_CODE_PTR))
    {
      /* If this is a reference, coerce it now.  This helps taking
	 care of the case where ADDRESS is meaningless because
	 original_value was not an lval.  */
      val = coerce_ref (val);
      val = ada_get_decoded_value (val);
      if (val == nullptr)
	{
	  gdb_assert (type->code () == TYPE_CODE_TYPEDEF);
	  gdb_printf (stream, "0x0");
	  return;
	}
    }
  else
    val = ada_to_fixed_value (val);

  type = value_type (val);
  struct type *saved_type = type;

  const gdb_byte *valaddr = value_contents_for_printing (val).data ();
  CORE_ADDR address = value_address (val);
  gdb::array_view<const gdb_byte> view
    = gdb::make_array_view (valaddr, type->length ());
  type = ada_check_typedef (resolve_dynamic_type (type, view, address));
  if (type != saved_type)
    {
      val = value_copy (val);
      deprecated_set_value_type (val, type);
    }

  if (is_fixed_point_type (type))
    type = type->fixed_point_type_base_type ();

  switch (type->code ())
    {
    default:
      common_val_print (val, stream, recurse, options,
			language_def (language_c));
      break;

    case TYPE_CODE_PTR:
      ada_value_print_ptr (val, stream, recurse, options);
      break;

    case TYPE_CODE_INT:
    case TYPE_CODE_RANGE:
      ada_value_print_num (val, stream, recurse, options);
      break;

    case TYPE_CODE_ENUM:
      ada_val_print_enum (val, stream, recurse, options);
      break;

    case TYPE_CODE_FLT:
      if (options->format)
	{
	  common_val_print (val, stream, recurse, options,
			    language_def (language_c));
	  break;
	}

      ada_print_floating (valaddr, type, stream);
      break;

    case TYPE_CODE_UNION:
    case TYPE_CODE_STRUCT:
      ada_val_print_struct_union (val, stream, recurse, options);
      break;

    case TYPE_CODE_ARRAY:
      ada_value_print_array (val, stream, recurse, options);
      return;

    case TYPE_CODE_REF:
      ada_val_print_ref (type, valaddr, 0, 0,
			 address, stream, recurse, val,
			 options);
      break;
    }
}

void
ada_value_print (struct value *val0, struct ui_file *stream,
		 const struct value_print_options *options)
{
  struct value *val = ada_to_fixed_value (val0);
  struct type *type = ada_check_typedef (value_type (val));
  struct value_print_options opts;

  /* If it is a pointer, indicate what it points to; but not for
     "void *" pointers.  */
  if (type->code () == TYPE_CODE_PTR
      && !(type->target_type ()->code () == TYPE_CODE_INT
	   && type->target_type ()->length () == 0))
    {
      /* Hack:  don't print (char *) for char strings.  Their
	 type is indicated by the quoted string anyway.  */
      if (type->target_type ()->length () != sizeof (char)
	  || type->target_type ()->code () != TYPE_CODE_INT
	  || type->target_type ()->is_unsigned ())
	{
	  gdb_printf (stream, "(");
	  type_print (type, "", stream, -1);
	  gdb_printf (stream, ") ");
	}
    }
  else if (ada_is_array_descriptor_type (type))
    {
      /* We do not print the type description unless TYPE is an array
	 access type (this is encoded by the compiler as a typedef to
	 a fat pointer - hence the check against TYPE_CODE_TYPEDEF).  */
      if (type->code () == TYPE_CODE_TYPEDEF)
	{
	  gdb_printf (stream, "(");
	  type_print (type, "", stream, -1);
	  gdb_printf (stream, ") ");
	}
    }
  else if (ada_is_bogus_array_descriptor (type))
    {
      gdb_printf (stream, "(");
      type_print (type, "", stream, -1);
      gdb_printf (stream, ") (...?)");
      return;
    }

  opts = *options;
  opts.deref_ref = 1;
  common_val_print (val, stream, 0, &opts, current_language);
}
