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

   Copyright (C) 1986-2023 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 *);



/* 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 (0).bitsize ();
  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 (v0->type ())->length ()
	      != check_typedef (v1->type ())->length ())
	    break;
	  if (!v0->contents_eq (v0->embedded_offset (),
				v1, v1->embedded_offset (),
				check_typedef (v0->type ())->length ()))
	    break;
	}

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

	  opts.deref_ref = false;
	  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 = false;
	  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)
{
  if (!type)
    {
      print_longest (stream, 'd', 0, val);
      return;
    }

  type = ada_check_typedef (type);

  switch (type->code ())
    {

    case TYPE_CODE_ENUM:
      {
	gdb::optional<LONGEST> posn = discrete_position (type, val);
	if (posn.has_value ())
	  fputs_styled (ada_enum_name (type->field (*posn).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;
    }

  unsigned int print_max_chars = get_print_max_chars (options);
  for (i = 0; i < length && things_printed < print_max_chars; 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 ();
  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 ();
  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 (i).is_packed ())
	{
	  /* 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 (i).bitsize ();
	      struct value_print_options opts;

	      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 = false;
	      common_val_print (v, stream, recurse + 1, &opts, language);
	    }
	}
      else
	{
	  struct value_print_options opts = *options;

	  opts.deref_ref = false;

	  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)
    {
      unsigned int print_max_chars = get_print_max_chars (options);
      int temp_len;

      /* Look for a NULL char.  */
      for (temp_len = 0;
	   (temp_len < len
	    && temp_len < print_max_chars
	    && 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
      && val->type ()->target_type ()->code () == TYPE_CODE_INT
      && val->type ()->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 (val->type ());
  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 (val->type ());
  const gdb_byte *valaddr = val->contents_for_printing ().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 recurse 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)
{
  LONGEST val;

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

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

  val = unpack_long (type, valaddr + offset_aligned);
  gdb::optional<LONGEST> posn = discrete_position (type, val);
  if (posn.has_value ())
    {
      const char *name = ada_enum_name (type->field (*posn).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)
{
  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 (val->type ());

  /* 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 = val->contents_for_printing ().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 (val->entirely_optimized_out ())
    val_print_optimized_out (val, stream);
  else if (type->field (0).bitsize () > 0)
    {
      const gdb_byte *valaddr = val->contents_for_printing ().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 (deref_val->type (), 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 (deref_val->type (), 1))
    deref_val = ada_tag_value_at_base_address (deref_val);

  if (deref_val->lazy ())
    deref_val->fetch_lazy ();

  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 (val->type ());

  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 = val->type ();
  struct type *saved_type = type;

  const gdb_byte *valaddr = val->contents_for_printing ().data ();
  CORE_ADDR address = val->address ();
  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 = val->copy ();
      val->deprecated_set_type (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 (val->type ());
  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, ") ");
	}
    }

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