/* 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 *);



/* 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 = 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)
{
  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;
    }

  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 (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 = 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
      && 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 = true;
  common_val_print (val, stream, 0, &opts, current_language);
}
