OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [ada-valprint.c] - Diff between revs 834 and 842

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 834 Rev 842
/* Support for printing Ada values for GDB, the GNU debugger.
/* Support for printing Ada values for GDB, the GNU debugger.
 
 
   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1997, 2001, 2002,
   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1997, 2001, 2002,
   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include "defs.h"
#include "defs.h"
#include <ctype.h>
#include <ctype.h>
#include "gdb_string.h"
#include "gdb_string.h"
#include "symtab.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbtypes.h"
#include "expression.h"
#include "expression.h"
#include "value.h"
#include "value.h"
#include "demangle.h"
#include "demangle.h"
#include "valprint.h"
#include "valprint.h"
#include "language.h"
#include "language.h"
#include "annotate.h"
#include "annotate.h"
#include "ada-lang.h"
#include "ada-lang.h"
#include "c-lang.h"
#include "c-lang.h"
#include "infcall.h"
#include "infcall.h"
#include "exceptions.h"
#include "exceptions.h"
#include "objfiles.h"
#include "objfiles.h"
 
 
/* Encapsulates arguments to ada_val_print.  */
/* Encapsulates arguments to ada_val_print.  */
struct ada_val_print_args
struct ada_val_print_args
{
{
  struct type *type;
  struct type *type;
  const gdb_byte *valaddr0;
  const gdb_byte *valaddr0;
  int embedded_offset;
  int embedded_offset;
  CORE_ADDR address;
  CORE_ADDR address;
  struct ui_file *stream;
  struct ui_file *stream;
  int recurse;
  int recurse;
  const struct value_print_options *options;
  const struct value_print_options *options;
};
};
 
 
static void print_record (struct type *, const gdb_byte *, struct ui_file *,
static void print_record (struct type *, const gdb_byte *, struct ui_file *,
                          int, const struct value_print_options *);
                          int, const struct value_print_options *);
 
 
static int print_field_values (struct type *, const gdb_byte *,
static int print_field_values (struct type *, const gdb_byte *,
                               struct ui_file *, int,
                               struct ui_file *, int,
                               const struct value_print_options *,
                               const struct value_print_options *,
                               int, struct type *,
                               int, struct type *,
                               const gdb_byte *);
                               const gdb_byte *);
 
 
static void adjust_type_signedness (struct type *);
static void adjust_type_signedness (struct type *);
 
 
static int ada_val_print_stub (void *args0);
static int ada_val_print_stub (void *args0);
 
 
static int ada_val_print_1 (struct type *, const gdb_byte *, int, CORE_ADDR,
static int ada_val_print_1 (struct type *, const gdb_byte *, int, CORE_ADDR,
                            struct ui_file *, int,
                            struct ui_file *, int,
                            const struct value_print_options *);
                            const struct value_print_options *);


 
 
/* Make TYPE unsigned if its range of values includes no negatives.  */
/* Make TYPE unsigned if its range of values includes no negatives.  */
static void
static void
adjust_type_signedness (struct type *type)
adjust_type_signedness (struct type *type)
{
{
  if (type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE
  if (type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE
      && TYPE_LOW_BOUND (type) >= 0)
      && TYPE_LOW_BOUND (type) >= 0)
    TYPE_UNSIGNED (type) = 1;
    TYPE_UNSIGNED (type) = 1;
}
}
 
 
/* Assuming TYPE is a simple array type, prints its lower bound on STREAM,
/* 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
   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,
   of index type for enumerated type).  Returns 1 if something printed,
   otherwise 0.  */
   otherwise 0.  */
 
 
static int
static int
print_optional_low_bound (struct ui_file *stream, struct type *type,
print_optional_low_bound (struct ui_file *stream, struct type *type,
                          const struct value_print_options *options)
                          const struct value_print_options *options)
{
{
  struct type *index_type;
  struct type *index_type;
  long low_bound;
  long low_bound;
  long high_bound;
  long high_bound;
 
 
  if (options->print_array_indexes)
  if (options->print_array_indexes)
    return 0;
    return 0;
 
 
  if (!get_array_bounds (type, &low_bound, &high_bound))
  if (!get_array_bounds (type, &low_bound, &high_bound))
    return 0;
    return 0;
 
 
  /* If this is an empty array, then don't print the lower bound.
  /* If this is an empty array, then don't print the lower bound.
     That would be confusing, because we would print the lower bound,
     That would be confusing, because we would print the lower bound,
     followed by... nothing!  */
     followed by... nothing!  */
  if (low_bound > high_bound)
  if (low_bound > high_bound)
    return 0;
    return 0;
 
 
  index_type = TYPE_INDEX_TYPE (type);
  index_type = TYPE_INDEX_TYPE (type);
 
 
  if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
  if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
    {
    {
      /* We need to know what the base type is, in order to do the
      /* We need to know what the base type is, in order to do the
         appropriate check below.  Otherwise, if this is a subrange
         appropriate check below.  Otherwise, if this is a subrange
         of an enumerated type, where the underlying value of the
         of an enumerated type, where the underlying value of the
         first element is typically 0, we might test the low bound
         first element is typically 0, we might test the low bound
         against the wrong value.  */
         against the wrong value.  */
      index_type = TYPE_TARGET_TYPE (index_type);
      index_type = TYPE_TARGET_TYPE (index_type);
    }
    }
 
 
  switch (TYPE_CODE (index_type))
  switch (TYPE_CODE (index_type))
    {
    {
    case TYPE_CODE_BOOL:
    case TYPE_CODE_BOOL:
      if (low_bound == 0)
      if (low_bound == 0)
        return 0;
        return 0;
      break;
      break;
    case TYPE_CODE_ENUM:
    case TYPE_CODE_ENUM:
      if (low_bound == TYPE_FIELD_BITPOS (index_type, 0))
      if (low_bound == TYPE_FIELD_BITPOS (index_type, 0))
        return 0;
        return 0;
      break;
      break;
    case TYPE_CODE_UNDEF:
    case TYPE_CODE_UNDEF:
      index_type = NULL;
      index_type = NULL;
      /* FALL THROUGH */
      /* FALL THROUGH */
    default:
    default:
      if (low_bound == 1)
      if (low_bound == 1)
        return 0;
        return 0;
      break;
      break;
    }
    }
 
 
  ada_print_scalar (index_type, (LONGEST) low_bound, stream);
  ada_print_scalar (index_type, (LONGEST) low_bound, stream);
  fprintf_filtered (stream, " => ");
  fprintf_filtered (stream, " => ");
  return 1;
  return 1;
}
}
 
 
/*  Version of val_print_array_elements for GNAT-style packed arrays.
/*  Version of val_print_array_elements for GNAT-style packed arrays.
    Prints elements of packed array of type TYPE at bit offset
    Prints elements of packed array of type TYPE at bit offset
    BITOFFSET from VALADDR on STREAM.  Formats according to OPTIONS and
    BITOFFSET from VALADDR on STREAM.  Formats according to OPTIONS and
    separates with commas.  RECURSE is the recursion (nesting) level.
    separates with commas.  RECURSE is the recursion (nesting) level.
    TYPE must have been decoded (as by ada_coerce_to_simple_array).  */
    TYPE must have been decoded (as by ada_coerce_to_simple_array).  */
 
 
static void
static void
val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
                                 int bitoffset, struct ui_file *stream,
                                 int bitoffset, struct ui_file *stream,
                                 int recurse,
                                 int recurse,
                                 const struct value_print_options *options)
                                 const struct value_print_options *options)
{
{
  unsigned int i;
  unsigned int i;
  unsigned int things_printed = 0;
  unsigned int things_printed = 0;
  unsigned len;
  unsigned len;
  struct type *elttype, *index_type;
  struct type *elttype, *index_type;
  unsigned eltlen;
  unsigned eltlen;
  unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0);
  unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0);
  struct value *mark = value_mark ();
  struct value *mark = value_mark ();
  LONGEST low = 0;
  LONGEST low = 0;
 
 
  elttype = TYPE_TARGET_TYPE (type);
  elttype = TYPE_TARGET_TYPE (type);
  eltlen = TYPE_LENGTH (check_typedef (elttype));
  eltlen = TYPE_LENGTH (check_typedef (elttype));
  index_type = TYPE_INDEX_TYPE (type);
  index_type = TYPE_INDEX_TYPE (type);
 
 
  {
  {
    LONGEST high;
    LONGEST high;
    if (get_discrete_bounds (index_type, &low, &high) < 0)
    if (get_discrete_bounds (index_type, &low, &high) < 0)
      len = 1;
      len = 1;
    else
    else
      len = high - low + 1;
      len = high - low + 1;
  }
  }
 
 
  i = 0;
  i = 0;
  annotate_array_section_begin (i, elttype);
  annotate_array_section_begin (i, elttype);
 
 
  while (i < len && things_printed < options->print_max)
  while (i < len && things_printed < options->print_max)
    {
    {
      struct value *v0, *v1;
      struct value *v0, *v1;
      int i0;
      int i0;
 
 
      if (i != 0)
      if (i != 0)
        {
        {
          if (options->prettyprint_arrays)
          if (options->prettyprint_arrays)
            {
            {
              fprintf_filtered (stream, ",\n");
              fprintf_filtered (stream, ",\n");
              print_spaces_filtered (2 + 2 * recurse, stream);
              print_spaces_filtered (2 + 2 * recurse, stream);
            }
            }
          else
          else
            {
            {
              fprintf_filtered (stream, ", ");
              fprintf_filtered (stream, ", ");
            }
            }
        }
        }
      wrap_here (n_spaces (2 + 2 * recurse));
      wrap_here (n_spaces (2 + 2 * recurse));
      maybe_print_array_index (index_type, i + low, stream, options);
      maybe_print_array_index (index_type, i + low, stream, options);
 
 
      i0 = i;
      i0 = i;
      v0 = ada_value_primitive_packed_val (NULL, valaddr,
      v0 = ada_value_primitive_packed_val (NULL, valaddr,
                                           (i0 * bitsize) / HOST_CHAR_BIT,
                                           (i0 * bitsize) / HOST_CHAR_BIT,
                                           (i0 * bitsize) % HOST_CHAR_BIT,
                                           (i0 * bitsize) % HOST_CHAR_BIT,
                                           bitsize, elttype);
                                           bitsize, elttype);
      while (1)
      while (1)
        {
        {
          i += 1;
          i += 1;
          if (i >= len)
          if (i >= len)
            break;
            break;
          v1 = ada_value_primitive_packed_val (NULL, valaddr,
          v1 = ada_value_primitive_packed_val (NULL, valaddr,
                                               (i * bitsize) / HOST_CHAR_BIT,
                                               (i * bitsize) / HOST_CHAR_BIT,
                                               (i * bitsize) % HOST_CHAR_BIT,
                                               (i * bitsize) % HOST_CHAR_BIT,
                                               bitsize, elttype);
                                               bitsize, elttype);
          if (memcmp (value_contents (v0), value_contents (v1), eltlen) != 0)
          if (memcmp (value_contents (v0), value_contents (v1), eltlen) != 0)
            break;
            break;
        }
        }
 
 
      if (i - i0 > options->repeat_count_threshold)
      if (i - i0 > options->repeat_count_threshold)
        {
        {
          struct value_print_options opts = *options;
          struct value_print_options opts = *options;
          opts.deref_ref = 0;
          opts.deref_ref = 0;
          val_print (elttype, value_contents (v0), 0, 0, stream,
          val_print (elttype, value_contents (v0), 0, 0, stream,
                     recurse + 1, &opts, current_language);
                     recurse + 1, &opts, current_language);
          annotate_elt_rep (i - i0);
          annotate_elt_rep (i - i0);
          fprintf_filtered (stream, _(" <repeats %u times>"), i - i0);
          fprintf_filtered (stream, _(" <repeats %u times>"), i - i0);
          annotate_elt_rep_end ();
          annotate_elt_rep_end ();
 
 
        }
        }
      else
      else
        {
        {
          int j;
          int j;
          struct value_print_options opts = *options;
          struct value_print_options opts = *options;
          opts.deref_ref = 0;
          opts.deref_ref = 0;
          for (j = i0; j < i; j += 1)
          for (j = i0; j < i; j += 1)
            {
            {
              if (j > i0)
              if (j > i0)
                {
                {
                  if (options->prettyprint_arrays)
                  if (options->prettyprint_arrays)
                    {
                    {
                      fprintf_filtered (stream, ",\n");
                      fprintf_filtered (stream, ",\n");
                      print_spaces_filtered (2 + 2 * recurse, stream);
                      print_spaces_filtered (2 + 2 * recurse, stream);
                    }
                    }
                  else
                  else
                    {
                    {
                      fprintf_filtered (stream, ", ");
                      fprintf_filtered (stream, ", ");
                    }
                    }
                  wrap_here (n_spaces (2 + 2 * recurse));
                  wrap_here (n_spaces (2 + 2 * recurse));
                  maybe_print_array_index (index_type, j + low,
                  maybe_print_array_index (index_type, j + low,
                                           stream, options);
                                           stream, options);
                }
                }
              val_print (elttype, value_contents (v0), 0, 0, stream,
              val_print (elttype, value_contents (v0), 0, 0, stream,
                         recurse + 1, &opts, current_language);
                         recurse + 1, &opts, current_language);
              annotate_elt ();
              annotate_elt ();
            }
            }
        }
        }
      things_printed += i - i0;
      things_printed += i - i0;
    }
    }
  annotate_array_section_end ();
  annotate_array_section_end ();
  if (i < len)
  if (i < len)
    {
    {
      fprintf_filtered (stream, "...");
      fprintf_filtered (stream, "...");
    }
    }
 
 
  value_free_to_mark (mark);
  value_free_to_mark (mark);
}
}
 
 
static struct type *
static struct type *
printable_val_type (struct type *type, const gdb_byte *valaddr)
printable_val_type (struct type *type, const gdb_byte *valaddr)
{
{
  return ada_to_fixed_type (ada_aligned_type (type), valaddr, 0, NULL, 1);
  return ada_to_fixed_type (ada_aligned_type (type), valaddr, 0, NULL, 1);
}
}
 
 
/* Print the character C on STREAM as part of the contents of a literal
/* 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
   string whose delimiter is QUOTER.  TYPE_LEN is the length in bytes
   (1 or 2) of the character.  */
   (1 or 2) of the character.  */
 
 
void
void
ada_emit_char (int c, struct type *type, struct ui_file *stream,
ada_emit_char (int c, struct type *type, struct ui_file *stream,
               int quoter, int type_len)
               int quoter, int type_len)
{
{
  if (type_len != 2)
  if (type_len != 2)
    type_len = 1;
    type_len = 1;
 
 
  c &= (1 << (type_len * TARGET_CHAR_BIT)) - 1;
  c &= (1 << (type_len * TARGET_CHAR_BIT)) - 1;
 
 
  if (isascii (c) && isprint (c))
  if (isascii (c) && isprint (c))
    {
    {
      if (c == quoter && c == '"')
      if (c == quoter && c == '"')
        fprintf_filtered (stream, "\"\"");
        fprintf_filtered (stream, "\"\"");
      else
      else
        fprintf_filtered (stream, "%c", c);
        fprintf_filtered (stream, "%c", c);
    }
    }
  else
  else
    fprintf_filtered (stream, "[\"%0*x\"]", type_len * 2, c);
    fprintf_filtered (stream, "[\"%0*x\"]", type_len * 2, c);
}
}
 
 
/* Character #I of STRING, given that TYPE_LEN is the size in bytes (1
/* Character #I of STRING, given that TYPE_LEN is the size in bytes (1
   or 2) of a character.  */
   or 2) of a character.  */
 
 
static int
static int
char_at (const gdb_byte *string, int i, int type_len,
char_at (const gdb_byte *string, int i, int type_len,
         enum bfd_endian byte_order)
         enum bfd_endian byte_order)
{
{
  if (type_len == 1)
  if (type_len == 1)
    return string[i];
    return string[i];
  else
  else
    return (int) extract_unsigned_integer (string + 2 * i, 2, byte_order);
    return (int) extract_unsigned_integer (string + 2 * i, 2, byte_order);
}
}
 
 
/* Wrapper around memcpy to make it legal argument to ui_file_put */
/* Wrapper around memcpy to make it legal argument to ui_file_put */
static void
static void
ui_memcpy (void *dest, const char *buffer, long len)
ui_memcpy (void *dest, const char *buffer, long len)
{
{
  memcpy (dest, buffer, (size_t) len);
  memcpy (dest, buffer, (size_t) len);
  ((char *) dest)[len] = '\0';
  ((char *) dest)[len] = '\0';
}
}
 
 
/* Print a floating-point value of type TYPE, pointed to in GDB by
/* Print a floating-point value of type TYPE, pointed to in GDB by
   VALADDR, on STREAM.  Use Ada formatting conventions: there must be
   VALADDR, on STREAM.  Use Ada formatting conventions: there must be
   a decimal point, and at least one digit before and after the
   a decimal point, and at least one digit before and after the
   point.  We use GNAT format for NaNs and infinities.  */
   point.  We use GNAT format for NaNs and infinities.  */
static void
static void
ada_print_floating (const gdb_byte *valaddr, struct type *type,
ada_print_floating (const gdb_byte *valaddr, struct type *type,
                    struct ui_file *stream)
                    struct ui_file *stream)
{
{
  char buffer[64];
  char buffer[64];
  char *s, *result;
  char *s, *result;
  int len;
  int len;
  struct ui_file *tmp_stream = mem_fileopen ();
  struct ui_file *tmp_stream = mem_fileopen ();
  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream);
  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream);
 
 
  print_floating (valaddr, type, tmp_stream);
  print_floating (valaddr, type, tmp_stream);
  ui_file_put (tmp_stream, ui_memcpy, buffer);
  ui_file_put (tmp_stream, ui_memcpy, buffer);
  do_cleanups (cleanups);
  do_cleanups (cleanups);
 
 
  result = buffer;
  result = buffer;
  len = strlen (result);
  len = strlen (result);
 
 
  /* Modify for Ada rules.  */
  /* Modify for Ada rules.  */
 
 
  s = strstr (result, "inf");
  s = strstr (result, "inf");
  if (s == NULL)
  if (s == NULL)
    s = strstr (result, "Inf");
    s = strstr (result, "Inf");
  if (s == NULL)
  if (s == NULL)
    s = strstr (result, "INF");
    s = strstr (result, "INF");
  if (s != NULL)
  if (s != NULL)
    strcpy (s, "Inf");
    strcpy (s, "Inf");
 
 
  if (s == NULL)
  if (s == NULL)
    {
    {
      s = strstr (result, "nan");
      s = strstr (result, "nan");
      if (s == NULL)
      if (s == NULL)
        s = strstr (result, "NaN");
        s = strstr (result, "NaN");
      if (s == NULL)
      if (s == NULL)
        s = strstr (result, "Nan");
        s = strstr (result, "Nan");
      if (s != NULL)
      if (s != NULL)
        {
        {
          s[0] = s[2] = 'N';
          s[0] = s[2] = 'N';
          if (result[0] == '-')
          if (result[0] == '-')
            result += 1;
            result += 1;
        }
        }
    }
    }
 
 
  if (s == NULL && strchr (result, '.') == NULL)
  if (s == NULL && strchr (result, '.') == NULL)
    {
    {
      s = strchr (result, 'e');
      s = strchr (result, 'e');
      if (s == NULL)
      if (s == NULL)
        fprintf_filtered (stream, "%s.0", result);
        fprintf_filtered (stream, "%s.0", result);
      else
      else
        fprintf_filtered (stream, "%.*s.0%s", (int) (s-result), result, s);
        fprintf_filtered (stream, "%.*s.0%s", (int) (s-result), result, s);
      return;
      return;
    }
    }
  fprintf_filtered (stream, "%s", result);
  fprintf_filtered (stream, "%s", result);
}
}
 
 
void
void
ada_printchar (int c, struct type *type, struct ui_file *stream)
ada_printchar (int c, struct type *type, struct ui_file *stream)
{
{
  fputs_filtered ("'", stream);
  fputs_filtered ("'", stream);
  ada_emit_char (c, type, stream, '\'', 1);
  ada_emit_char (c, type, stream, '\'', 1);
  fputs_filtered ("'", stream);
  fputs_filtered ("'", stream);
}
}
 
 
/* [From print_type_scalar in typeprint.c].   Print VAL on STREAM in a
/* [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
   form appropriate for TYPE, if non-NULL.  If TYPE is NULL, print VAL
   like a default signed integer.  */
   like a default signed integer.  */
 
 
void
void
ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream)
ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream)
{
{
  unsigned int i;
  unsigned int i;
  unsigned len;
  unsigned len;
 
 
  if (!type)
  if (!type)
    {
    {
      print_longest (stream, 'd', 0, val);
      print_longest (stream, 'd', 0, val);
      return;
      return;
    }
    }
 
 
  type = ada_check_typedef (type);
  type = ada_check_typedef (type);
 
 
  switch (TYPE_CODE (type))
  switch (TYPE_CODE (type))
    {
    {
 
 
    case TYPE_CODE_ENUM:
    case TYPE_CODE_ENUM:
      len = TYPE_NFIELDS (type);
      len = TYPE_NFIELDS (type);
      for (i = 0; i < len; i++)
      for (i = 0; i < len; i++)
        {
        {
          if (TYPE_FIELD_BITPOS (type, i) == val)
          if (TYPE_FIELD_BITPOS (type, i) == val)
            {
            {
              break;
              break;
            }
            }
        }
        }
      if (i < len)
      if (i < len)
        {
        {
          fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
          fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
        }
        }
      else
      else
        {
        {
          print_longest (stream, 'd', 0, val);
          print_longest (stream, 'd', 0, val);
        }
        }
      break;
      break;
 
 
    case TYPE_CODE_INT:
    case TYPE_CODE_INT:
      print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val);
      print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val);
      break;
      break;
 
 
    case TYPE_CODE_CHAR:
    case TYPE_CODE_CHAR:
      LA_PRINT_CHAR ((unsigned char) val, type, stream);
      LA_PRINT_CHAR ((unsigned char) val, type, stream);
      break;
      break;
 
 
    case TYPE_CODE_BOOL:
    case TYPE_CODE_BOOL:
      fprintf_filtered (stream, val ? "true" : "false");
      fprintf_filtered (stream, val ? "true" : "false");
      break;
      break;
 
 
    case TYPE_CODE_RANGE:
    case TYPE_CODE_RANGE:
      ada_print_scalar (TYPE_TARGET_TYPE (type), val, stream);
      ada_print_scalar (TYPE_TARGET_TYPE (type), val, stream);
      return;
      return;
 
 
    case TYPE_CODE_UNDEF:
    case TYPE_CODE_UNDEF:
    case TYPE_CODE_PTR:
    case TYPE_CODE_PTR:
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_UNION:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_FLT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_VOID:
    case TYPE_CODE_VOID:
    case TYPE_CODE_SET:
    case TYPE_CODE_SET:
    case TYPE_CODE_STRING:
    case TYPE_CODE_STRING:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_METHOD:
    case TYPE_CODE_METHOD:
    case TYPE_CODE_REF:
    case TYPE_CODE_REF:
      warning (_("internal error: unhandled type in ada_print_scalar"));
      warning (_("internal error: unhandled type in ada_print_scalar"));
      break;
      break;
 
 
    default:
    default:
      error (_("Invalid type code in symbol table."));
      error (_("Invalid type code in symbol table."));
    }
    }
  gdb_flush (stream);
  gdb_flush (stream);
}
}
 
 
/* Print the character string STRING, printing at most LENGTH characters.
/* Print the character string STRING, printing at most LENGTH characters.
   Printing stops early if the number hits print_max; repeat counts
   Printing stops early if the number hits print_max; repeat counts
   are printed as appropriate.  Print ellipses at the end if we
   are printed as appropriate.  Print ellipses at the end if we
   had to stop before printing LENGTH characters, or if
   had to stop before printing LENGTH characters, or if
   FORCE_ELLIPSES.   TYPE_LEN is the length (1 or 2) of the character type.
   FORCE_ELLIPSES.   TYPE_LEN is the length (1 or 2) of the character type.
 */
 */
 
 
static void
static void
printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
          unsigned int length, int force_ellipses, int type_len,
          unsigned int length, int force_ellipses, int type_len,
          const struct value_print_options *options)
          const struct value_print_options *options)
{
{
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype));
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype));
  unsigned int i;
  unsigned int i;
  unsigned int things_printed = 0;
  unsigned int things_printed = 0;
  int in_quotes = 0;
  int in_quotes = 0;
  int need_comma = 0;
  int need_comma = 0;
 
 
  if (length == 0)
  if (length == 0)
    {
    {
      fputs_filtered ("\"\"", stream);
      fputs_filtered ("\"\"", stream);
      return;
      return;
    }
    }
 
 
  for (i = 0; i < length && things_printed < options->print_max; i += 1)
  for (i = 0; i < length && things_printed < options->print_max; i += 1)
    {
    {
      /* Position of the character we are examining
      /* Position of the character we are examining
         to see whether it is repeated.  */
         to see whether it is repeated.  */
      unsigned int rep1;
      unsigned int rep1;
      /* Number of repetitions we have detected so far.  */
      /* Number of repetitions we have detected so far.  */
      unsigned int reps;
      unsigned int reps;
 
 
      QUIT;
      QUIT;
 
 
      if (need_comma)
      if (need_comma)
        {
        {
          fputs_filtered (", ", stream);
          fputs_filtered (", ", stream);
          need_comma = 0;
          need_comma = 0;
        }
        }
 
 
      rep1 = i + 1;
      rep1 = i + 1;
      reps = 1;
      reps = 1;
      while (rep1 < length
      while (rep1 < length
             && char_at (string, rep1, type_len, byte_order)
             && char_at (string, rep1, type_len, byte_order)
                == char_at (string, i, type_len, byte_order))
                == char_at (string, i, type_len, byte_order))
        {
        {
          rep1 += 1;
          rep1 += 1;
          reps += 1;
          reps += 1;
        }
        }
 
 
      if (reps > options->repeat_count_threshold)
      if (reps > options->repeat_count_threshold)
        {
        {
          if (in_quotes)
          if (in_quotes)
            {
            {
              if (options->inspect_it)
              if (options->inspect_it)
                fputs_filtered ("\\\", ", stream);
                fputs_filtered ("\\\", ", stream);
              else
              else
                fputs_filtered ("\", ", stream);
                fputs_filtered ("\", ", stream);
              in_quotes = 0;
              in_quotes = 0;
            }
            }
          fputs_filtered ("'", stream);
          fputs_filtered ("'", stream);
          ada_emit_char (char_at (string, i, type_len, byte_order),
          ada_emit_char (char_at (string, i, type_len, byte_order),
                         elttype, stream, '\'', type_len);
                         elttype, stream, '\'', type_len);
          fputs_filtered ("'", stream);
          fputs_filtered ("'", stream);
          fprintf_filtered (stream, _(" <repeats %u times>"), reps);
          fprintf_filtered (stream, _(" <repeats %u times>"), reps);
          i = rep1 - 1;
          i = rep1 - 1;
          things_printed += options->repeat_count_threshold;
          things_printed += options->repeat_count_threshold;
          need_comma = 1;
          need_comma = 1;
        }
        }
      else
      else
        {
        {
          if (!in_quotes)
          if (!in_quotes)
            {
            {
              if (options->inspect_it)
              if (options->inspect_it)
                fputs_filtered ("\\\"", stream);
                fputs_filtered ("\\\"", stream);
              else
              else
                fputs_filtered ("\"", stream);
                fputs_filtered ("\"", stream);
              in_quotes = 1;
              in_quotes = 1;
            }
            }
          ada_emit_char (char_at (string, i, type_len, byte_order),
          ada_emit_char (char_at (string, i, type_len, byte_order),
                         elttype, stream, '"', type_len);
                         elttype, stream, '"', type_len);
          things_printed += 1;
          things_printed += 1;
        }
        }
    }
    }
 
 
  /* Terminate the quotes if necessary.  */
  /* Terminate the quotes if necessary.  */
  if (in_quotes)
  if (in_quotes)
    {
    {
      if (options->inspect_it)
      if (options->inspect_it)
        fputs_filtered ("\\\"", stream);
        fputs_filtered ("\\\"", stream);
      else
      else
        fputs_filtered ("\"", stream);
        fputs_filtered ("\"", stream);
    }
    }
 
 
  if (force_ellipses || i < length)
  if (force_ellipses || i < length)
    fputs_filtered ("...", stream);
    fputs_filtered ("...", stream);
}
}
 
 
void
void
ada_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
ada_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
              unsigned int length, const char *encoding, int force_ellipses,
              unsigned int length, const char *encoding, int force_ellipses,
              const struct value_print_options *options)
              const struct value_print_options *options)
{
{
  printstr (stream, type, string, length, force_ellipses, TYPE_LENGTH (type),
  printstr (stream, type, string, length, force_ellipses, TYPE_LENGTH (type),
            options);
            options);
}
}
 
 
 
 
/* Print data of type TYPE located at VALADDR (within GDB), which came from
/* Print data of type TYPE located at VALADDR (within GDB), which came from
   the inferior at address ADDRESS, onto stdio stream STREAM according to
   the inferior at address ADDRESS, onto stdio stream STREAM according to
   OPTIONS.  The data at VALADDR is in target byte order.
   OPTIONS.  The data at VALADDR is in target byte order.
 
 
   If the data is printed as a string, returns the number of string characters
   If the data is printed as a string, returns the number of string characters
   printed.
   printed.
 
 
   RECURSE indicates the amount of indentation to supply before
   RECURSE indicates the amount of indentation to supply before
   continuation lines; this amount is roughly twice the value of RECURSE.  */
   continuation lines; this amount is roughly twice the value of RECURSE.  */
 
 
int
int
ada_val_print (struct type *type, const gdb_byte *valaddr0,
ada_val_print (struct type *type, const gdb_byte *valaddr0,
               int embedded_offset, CORE_ADDR address,
               int embedded_offset, CORE_ADDR address,
               struct ui_file *stream, int recurse,
               struct ui_file *stream, int recurse,
               const struct value_print_options *options)
               const struct value_print_options *options)
{
{
  struct ada_val_print_args args;
  struct ada_val_print_args args;
  args.type = type;
  args.type = type;
  args.valaddr0 = valaddr0;
  args.valaddr0 = valaddr0;
  args.embedded_offset = embedded_offset;
  args.embedded_offset = embedded_offset;
  args.address = address;
  args.address = address;
  args.stream = stream;
  args.stream = stream;
  args.recurse = recurse;
  args.recurse = recurse;
  args.options = options;
  args.options = options;
 
 
  return catch_errors (ada_val_print_stub, &args, NULL, RETURN_MASK_ALL);
  return catch_errors (ada_val_print_stub, &args, NULL, RETURN_MASK_ALL);
}
}
 
 
/* Helper for ada_val_print; used as argument to catch_errors to
/* Helper for ada_val_print; used as argument to catch_errors to
   unmarshal the arguments to ada_val_print_1, which does the work.  */
   unmarshal the arguments to ada_val_print_1, which does the work.  */
static int
static int
ada_val_print_stub (void *args0)
ada_val_print_stub (void *args0)
{
{
  struct ada_val_print_args *argsp = (struct ada_val_print_args *) args0;
  struct ada_val_print_args *argsp = (struct ada_val_print_args *) args0;
  return ada_val_print_1 (argsp->type, argsp->valaddr0,
  return ada_val_print_1 (argsp->type, argsp->valaddr0,
                          argsp->embedded_offset, argsp->address,
                          argsp->embedded_offset, argsp->address,
                          argsp->stream, argsp->recurse, argsp->options);
                          argsp->stream, argsp->recurse, argsp->options);
}
}
 
 
/* Assuming TYPE is a simple array, print the value of this array located
/* Assuming TYPE is a simple array, print the value of this array located
   at VALADDR.  See ada_val_print for a description of the various
   at VALADDR.  See ada_val_print for a description of the various
   parameters of this function; they are identical.  The semantics
   parameters of this function; they are identical.  The semantics
   of the return value is also identical to ada_val_print.  */
   of the return value is also identical to ada_val_print.  */
 
 
static int
static int
ada_val_print_array (struct type *type, const gdb_byte *valaddr,
ada_val_print_array (struct type *type, const gdb_byte *valaddr,
                     CORE_ADDR address, struct ui_file *stream, int recurse,
                     CORE_ADDR address, struct ui_file *stream, int recurse,
                     const struct value_print_options *options)
                     const struct value_print_options *options)
{
{
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
  struct type *elttype = TYPE_TARGET_TYPE (type);
  struct type *elttype = TYPE_TARGET_TYPE (type);
  unsigned int eltlen;
  unsigned int eltlen;
  unsigned int len;
  unsigned int len;
  int result = 0;
  int result = 0;
 
 
  if (elttype == NULL)
  if (elttype == NULL)
    eltlen = 0;
    eltlen = 0;
  else
  else
    eltlen = TYPE_LENGTH (elttype);
    eltlen = TYPE_LENGTH (elttype);
  if (eltlen == 0)
  if (eltlen == 0)
    len = 0;
    len = 0;
  else
  else
    len = TYPE_LENGTH (type) / eltlen;
    len = TYPE_LENGTH (type) / eltlen;
 
 
  /* For an array of chars, print with string syntax.  */
  /* For an array of chars, print with string syntax.  */
  if (ada_is_string_type (type)
  if (ada_is_string_type (type)
      && (options->format == 0 || options->format == 's'))
      && (options->format == 0 || options->format == 's'))
    {
    {
      if (options->prettyprint_arrays)
      if (options->prettyprint_arrays)
        print_spaces_filtered (2 + 2 * recurse, stream);
        print_spaces_filtered (2 + 2 * recurse, stream);
 
 
      /* If requested, look for the first null char and only print
      /* If requested, look for the first null char and only print
         elements up to it.  */
         elements up to it.  */
      if (options->stop_print_at_null)
      if (options->stop_print_at_null)
        {
        {
          int temp_len;
          int temp_len;
 
 
          /* Look for a NULL char.  */
          /* Look for a NULL char.  */
          for (temp_len = 0;
          for (temp_len = 0;
               (temp_len < len
               (temp_len < len
                && temp_len < options->print_max
                && temp_len < options->print_max
                && char_at (valaddr, temp_len, eltlen, byte_order) != 0);
                && char_at (valaddr, temp_len, eltlen, byte_order) != 0);
               temp_len += 1);
               temp_len += 1);
          len = temp_len;
          len = temp_len;
        }
        }
 
 
      printstr (stream, elttype, valaddr, len, 0, eltlen, options);
      printstr (stream, elttype, valaddr, len, 0, eltlen, options);
      result = len;
      result = len;
    }
    }
  else
  else
    {
    {
      fprintf_filtered (stream, "(");
      fprintf_filtered (stream, "(");
      print_optional_low_bound (stream, type, options);
      print_optional_low_bound (stream, type, options);
      if (TYPE_FIELD_BITSIZE (type, 0) > 0)
      if (TYPE_FIELD_BITSIZE (type, 0) > 0)
        val_print_packed_array_elements (type, valaddr, 0, stream,
        val_print_packed_array_elements (type, valaddr, 0, stream,
                                         recurse, options);
                                         recurse, options);
      else
      else
        val_print_array_elements (type, valaddr, address, stream,
        val_print_array_elements (type, valaddr, address, stream,
                                  recurse, options, 0);
                                  recurse, options, 0);
      fprintf_filtered (stream, ")");
      fprintf_filtered (stream, ")");
    }
    }
 
 
  return result;
  return result;
}
}
 
 
/* See the comment on ada_val_print.  This function differs in that it
/* See the comment on ada_val_print.  This function differs in that it
   does not catch evaluation errors (leaving that to ada_val_print).  */
   does not catch evaluation errors (leaving that to ada_val_print).  */
 
 
static int
static int
ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
                 int embedded_offset, CORE_ADDR address,
                 int embedded_offset, CORE_ADDR address,
                 struct ui_file *stream, int recurse,
                 struct ui_file *stream, int recurse,
                 const struct value_print_options *options)
                 const struct value_print_options *options)
{
{
  unsigned int len;
  unsigned int len;
  int i;
  int i;
  struct type *elttype;
  struct type *elttype;
  unsigned int eltlen;
  unsigned int eltlen;
  LONGEST val;
  LONGEST val;
  const gdb_byte *valaddr = valaddr0 + embedded_offset;
  const gdb_byte *valaddr = valaddr0 + embedded_offset;
 
 
  type = ada_check_typedef (type);
  type = ada_check_typedef (type);
 
 
  if (ada_is_array_descriptor_type (type)
  if (ada_is_array_descriptor_type (type)
      || ada_is_constrained_packed_array_type (type))
      || ada_is_constrained_packed_array_type (type))
    {
    {
      int retn;
      int retn;
      struct value *mark = value_mark ();
      struct value *mark = value_mark ();
      struct value *val;
      struct value *val;
      val = value_from_contents_and_address (type, valaddr, address);
      val = value_from_contents_and_address (type, valaddr, address);
      val = ada_coerce_to_simple_array_ptr (val);
      val = ada_coerce_to_simple_array_ptr (val);
      if (val == NULL)
      if (val == NULL)
        {
        {
          fprintf_filtered (stream, "(null)");
          fprintf_filtered (stream, "(null)");
          retn = 0;
          retn = 0;
        }
        }
      else
      else
        retn = ada_val_print_1 (value_type (val), value_contents (val), 0,
        retn = ada_val_print_1 (value_type (val), value_contents (val), 0,
                                value_address (val), stream, recurse, options);
                                value_address (val), stream, recurse, options);
      value_free_to_mark (mark);
      value_free_to_mark (mark);
      return retn;
      return retn;
    }
    }
 
 
  valaddr = ada_aligned_value_addr (type, valaddr);
  valaddr = ada_aligned_value_addr (type, valaddr);
  embedded_offset -= valaddr - valaddr0 - embedded_offset;
  embedded_offset -= valaddr - valaddr0 - embedded_offset;
  type = printable_val_type (type, valaddr);
  type = printable_val_type (type, valaddr);
 
 
  switch (TYPE_CODE (type))
  switch (TYPE_CODE (type))
    {
    {
    default:
    default:
      return c_val_print (type, valaddr0, embedded_offset, address, stream,
      return c_val_print (type, valaddr0, embedded_offset, address, stream,
                          recurse, options);
                          recurse, options);
 
 
    case TYPE_CODE_PTR:
    case TYPE_CODE_PTR:
      {
      {
        int ret = c_val_print (type, valaddr0, embedded_offset, address,
        int ret = c_val_print (type, valaddr0, embedded_offset, address,
                               stream, recurse, options);
                               stream, recurse, options);
        if (ada_is_tag_type (type))
        if (ada_is_tag_type (type))
          {
          {
            struct value *val =
            struct value *val =
              value_from_contents_and_address (type, valaddr, address);
              value_from_contents_and_address (type, valaddr, address);
            const char *name = ada_tag_name (val);
            const char *name = ada_tag_name (val);
            if (name != NULL)
            if (name != NULL)
              fprintf_filtered (stream, " (%s)", name);
              fprintf_filtered (stream, " (%s)", name);
            return 0;
            return 0;
        }
        }
        return ret;
        return ret;
      }
      }
 
 
    case TYPE_CODE_INT:
    case TYPE_CODE_INT:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_RANGE:
      if (ada_is_fixed_point_type (type))
      if (ada_is_fixed_point_type (type))
        {
        {
          LONGEST v = unpack_long (type, valaddr);
          LONGEST v = unpack_long (type, valaddr);
          int len = TYPE_LENGTH (type);
          int len = TYPE_LENGTH (type);
 
 
          fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g",
          fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g",
                            (double) ada_fixed_to_float (type, v));
                            (double) ada_fixed_to_float (type, v));
          return 0;
          return 0;
        }
        }
      else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
      else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
        {
        {
          struct type *target_type = TYPE_TARGET_TYPE (type);
          struct type *target_type = TYPE_TARGET_TYPE (type);
          if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type))
          if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type))
            {
            {
              /* Obscure case of range type that has different length from
              /* Obscure case of range type that has different length from
                 its base type.  Perform a conversion, or we will get a
                 its base type.  Perform a conversion, or we will get a
                 nonsense value.  Actually, we could use the same
                 nonsense value.  Actually, we could use the same
                 code regardless of lengths; I'm just avoiding a cast.  */
                 code regardless of lengths; I'm just avoiding a cast.  */
              struct value *v = value_cast (target_type,
              struct value *v = value_cast (target_type,
                                            value_from_contents_and_address
                                            value_from_contents_and_address
                                            (type, valaddr, 0));
                                            (type, valaddr, 0));
              return ada_val_print_1 (target_type, value_contents (v), 0, 0,
              return ada_val_print_1 (target_type, value_contents (v), 0, 0,
                                      stream, recurse + 1, options);
                                      stream, recurse + 1, options);
            }
            }
          else
          else
            return ada_val_print_1 (TYPE_TARGET_TYPE (type),
            return ada_val_print_1 (TYPE_TARGET_TYPE (type),
                                    valaddr0, embedded_offset,
                                    valaddr0, embedded_offset,
                                    address, stream, recurse, options);
                                    address, stream, recurse, options);
        }
        }
      else
      else
        {
        {
          int format = (options->format ? options->format
          int format = (options->format ? options->format
                        : options->output_format);
                        : options->output_format);
          if (format)
          if (format)
            {
            {
              struct value_print_options opts = *options;
              struct value_print_options opts = *options;
              opts.format = format;
              opts.format = format;
              print_scalar_formatted (valaddr, type, &opts, 0, stream);
              print_scalar_formatted (valaddr, type, &opts, 0, stream);
            }
            }
          else if (ada_is_system_address_type (type))
          else if (ada_is_system_address_type (type))
            {
            {
              /* FIXME: We want to print System.Address variables using
              /* FIXME: We want to print System.Address variables using
                 the same format as for any access type.  But for some
                 the same format as for any access type.  But for some
                 reason GNAT encodes the System.Address type as an int,
                 reason GNAT encodes the System.Address type as an int,
                 so we have to work-around this deficiency by handling
                 so we have to work-around this deficiency by handling
                 System.Address values as a special case.  */
                 System.Address values as a special case.  */
 
 
              struct gdbarch *gdbarch = get_type_arch (type);
              struct gdbarch *gdbarch = get_type_arch (type);
              struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
              struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
              CORE_ADDR addr = extract_typed_address (valaddr, ptr_type);
              CORE_ADDR addr = extract_typed_address (valaddr, ptr_type);
 
 
              fprintf_filtered (stream, "(");
              fprintf_filtered (stream, "(");
              type_print (type, "", stream, -1);
              type_print (type, "", stream, -1);
              fprintf_filtered (stream, ") ");
              fprintf_filtered (stream, ") ");
              fputs_filtered (paddress (gdbarch, addr), stream);
              fputs_filtered (paddress (gdbarch, addr), stream);
            }
            }
          else
          else
            {
            {
              val_print_type_code_int (type, valaddr, stream);
              val_print_type_code_int (type, valaddr, stream);
              if (ada_is_character_type (type))
              if (ada_is_character_type (type))
                {
                {
                  fputs_filtered (" ", stream);
                  fputs_filtered (" ", stream);
                  ada_printchar ((unsigned char) unpack_long (type, valaddr),
                  ada_printchar ((unsigned char) unpack_long (type, valaddr),
                                 type, stream);
                                 type, stream);
                }
                }
            }
            }
          return 0;
          return 0;
        }
        }
 
 
    case TYPE_CODE_ENUM:
    case TYPE_CODE_ENUM:
      if (options->format)
      if (options->format)
        {
        {
          print_scalar_formatted (valaddr, type, options, 0, stream);
          print_scalar_formatted (valaddr, type, options, 0, stream);
          break;
          break;
        }
        }
      len = TYPE_NFIELDS (type);
      len = TYPE_NFIELDS (type);
      val = unpack_long (type, valaddr);
      val = unpack_long (type, valaddr);
      for (i = 0; i < len; i++)
      for (i = 0; i < len; i++)
        {
        {
          QUIT;
          QUIT;
          if (val == TYPE_FIELD_BITPOS (type, i))
          if (val == TYPE_FIELD_BITPOS (type, i))
            {
            {
              break;
              break;
            }
            }
        }
        }
      if (i < len)
      if (i < len)
        {
        {
          const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i));
          const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i));
          if (name[0] == '\'')
          if (name[0] == '\'')
            fprintf_filtered (stream, "%ld %s", (long) val, name);
            fprintf_filtered (stream, "%ld %s", (long) val, name);
          else
          else
            fputs_filtered (name, stream);
            fputs_filtered (name, stream);
        }
        }
      else
      else
        {
        {
          print_longest (stream, 'd', 0, val);
          print_longest (stream, 'd', 0, val);
        }
        }
      break;
      break;
 
 
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_FLAGS:
      if (options->format)
      if (options->format)
        print_scalar_formatted (valaddr, type, options, 0, stream);
        print_scalar_formatted (valaddr, type, options, 0, stream);
      else
      else
        val_print_type_code_flags (type, valaddr, stream);
        val_print_type_code_flags (type, valaddr, stream);
      break;
      break;
 
 
    case TYPE_CODE_FLT:
    case TYPE_CODE_FLT:
      if (options->format)
      if (options->format)
        return c_val_print (type, valaddr0, embedded_offset, address, stream,
        return c_val_print (type, valaddr0, embedded_offset, address, stream,
                            recurse, options);
                            recurse, options);
      else
      else
        ada_print_floating (valaddr0 + embedded_offset, type, stream);
        ada_print_floating (valaddr0 + embedded_offset, type, stream);
      break;
      break;
 
 
    case TYPE_CODE_UNION:
    case TYPE_CODE_UNION:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_STRUCT:
      if (ada_is_bogus_array_descriptor (type))
      if (ada_is_bogus_array_descriptor (type))
        {
        {
          fprintf_filtered (stream, "(...?)");
          fprintf_filtered (stream, "(...?)");
          return 0;
          return 0;
        }
        }
      else
      else
        {
        {
          print_record (type, valaddr, stream, recurse, options);
          print_record (type, valaddr, stream, recurse, options);
          return 0;
          return 0;
        }
        }
 
 
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_ARRAY:
      return ada_val_print_array (type, valaddr, address, stream,
      return ada_val_print_array (type, valaddr, address, stream,
                                  recurse, options);
                                  recurse, options);
 
 
    case TYPE_CODE_REF:
    case TYPE_CODE_REF:
      /* For references, the debugger is expected to print the value as
      /* For references, the debugger is expected to print the value as
         an address if DEREF_REF is null.  But printing an address in place
         an address if DEREF_REF is null.  But printing an address in place
         of the object value would be confusing to an Ada programmer.
         of the object value would be confusing to an Ada programmer.
         So, for Ada values, we print the actual dereferenced value
         So, for Ada values, we print the actual dereferenced value
         regardless.  */
         regardless.  */
      elttype = check_typedef (TYPE_TARGET_TYPE (type));
      elttype = check_typedef (TYPE_TARGET_TYPE (type));
 
 
      if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
      if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
        {
        {
          LONGEST deref_val_int = (LONGEST) unpack_pointer (type, valaddr);
          LONGEST deref_val_int = (LONGEST) unpack_pointer (type, valaddr);
          if (deref_val_int != 0)
          if (deref_val_int != 0)
            {
            {
              struct value *deref_val =
              struct value *deref_val =
                ada_value_ind (value_from_longest
                ada_value_ind (value_from_longest
                               (lookup_pointer_type (elttype),
                               (lookup_pointer_type (elttype),
                                deref_val_int));
                                deref_val_int));
              val_print (value_type (deref_val),
              val_print (value_type (deref_val),
                         value_contents (deref_val), 0,
                         value_contents (deref_val), 0,
                         value_address (deref_val), stream, recurse + 1,
                         value_address (deref_val), stream, recurse + 1,
                         options, current_language);
                         options, current_language);
            }
            }
          else
          else
            fputs_filtered ("(null)", stream);
            fputs_filtered ("(null)", stream);
        }
        }
      else
      else
        fputs_filtered ("???", stream);
        fputs_filtered ("???", stream);
 
 
      break;
      break;
    }
    }
  gdb_flush (stream);
  gdb_flush (stream);
  return 0;
  return 0;
}
}
 
 
static int
static int
print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr,
print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr,
                    struct ui_file *stream, int recurse,
                    struct ui_file *stream, int recurse,
                    const struct value_print_options *options, int comma_needed,
                    const struct value_print_options *options, int comma_needed,
                    struct type *outer_type, const gdb_byte *outer_valaddr)
                    struct type *outer_type, const gdb_byte *outer_valaddr)
{
{
  struct type *var_type = TYPE_FIELD_TYPE (type, field_num);
  struct type *var_type = TYPE_FIELD_TYPE (type, field_num);
  int which = ada_which_variant_applies (var_type, outer_type, outer_valaddr);
  int which = ada_which_variant_applies (var_type, outer_type, outer_valaddr);
 
 
  if (which < 0)
  if (which < 0)
    return 0;
    return 0;
  else
  else
    return print_field_values
    return print_field_values
      (TYPE_FIELD_TYPE (var_type, which),
      (TYPE_FIELD_TYPE (var_type, which),
       valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT
       valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT
       + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT,
       + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT,
       stream, recurse, options,
       stream, recurse, options,
       comma_needed, outer_type, outer_valaddr);
       comma_needed, outer_type, outer_valaddr);
}
}
 
 
int
int
ada_value_print (struct value *val0, struct ui_file *stream,
ada_value_print (struct value *val0, struct ui_file *stream,
                 const struct value_print_options *options)
                 const struct value_print_options *options)
{
{
  const gdb_byte *valaddr = value_contents (val0);
  const gdb_byte *valaddr = value_contents (val0);
  CORE_ADDR address = value_address (val0);
  CORE_ADDR address = value_address (val0);
  struct type *type =
  struct type *type =
    ada_to_fixed_type (value_type (val0), valaddr, address, NULL, 1);
    ada_to_fixed_type (value_type (val0), valaddr, address, NULL, 1);
  struct value *val =
  struct value *val =
    value_from_contents_and_address (type, valaddr, address);
    value_from_contents_and_address (type, valaddr, address);
  struct value_print_options opts;
  struct value_print_options opts;
 
 
  /* If it is a pointer, indicate what it points to.  */
  /* If it is a pointer, indicate what it points to.  */
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
    {
    {
      /* Hack:  don't print (char *) for char strings.  Their
      /* Hack:  don't print (char *) for char strings.  Their
         type is indicated by the quoted string anyway.  */
         type is indicated by the quoted string anyway.  */
      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) != sizeof (char)
      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) != sizeof (char)
          || TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_INT
          || TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_INT
          || TYPE_UNSIGNED (TYPE_TARGET_TYPE (type)))
          || TYPE_UNSIGNED (TYPE_TARGET_TYPE (type)))
        {
        {
          fprintf_filtered (stream, "(");
          fprintf_filtered (stream, "(");
          type_print (type, "", stream, -1);
          type_print (type, "", stream, -1);
          fprintf_filtered (stream, ") ");
          fprintf_filtered (stream, ") ");
        }
        }
    }
    }
  else if (ada_is_array_descriptor_type (type))
  else if (ada_is_array_descriptor_type (type))
    {
    {
      fprintf_filtered (stream, "(");
      fprintf_filtered (stream, "(");
      type_print (type, "", stream, -1);
      type_print (type, "", stream, -1);
      fprintf_filtered (stream, ") ");
      fprintf_filtered (stream, ") ");
    }
    }
  else if (ada_is_bogus_array_descriptor (type))
  else if (ada_is_bogus_array_descriptor (type))
    {
    {
      fprintf_filtered (stream, "(");
      fprintf_filtered (stream, "(");
      type_print (type, "", stream, -1);
      type_print (type, "", stream, -1);
      fprintf_filtered (stream, ") (...?)");
      fprintf_filtered (stream, ") (...?)");
      return 0;
      return 0;
    }
    }
 
 
  opts = *options;
  opts = *options;
  opts.deref_ref = 1;
  opts.deref_ref = 1;
  return (val_print (type, value_contents (val), 0, address,
  return (val_print (type, value_contents (val), 0, address,
                     stream, 0, &opts, current_language));
                     stream, 0, &opts, current_language));
}
}
 
 
static void
static void
print_record (struct type *type, const gdb_byte *valaddr,
print_record (struct type *type, const gdb_byte *valaddr,
              struct ui_file *stream, int recurse,
              struct ui_file *stream, int recurse,
              const struct value_print_options *options)
              const struct value_print_options *options)
{
{
  type = ada_check_typedef (type);
  type = ada_check_typedef (type);
 
 
  fprintf_filtered (stream, "(");
  fprintf_filtered (stream, "(");
 
 
  if (print_field_values (type, valaddr, stream, recurse, options,
  if (print_field_values (type, valaddr, stream, recurse, options,
                          0, type, valaddr) != 0 && options->pretty)
                          0, type, valaddr) != 0 && options->pretty)
    {
    {
      fprintf_filtered (stream, "\n");
      fprintf_filtered (stream, "\n");
      print_spaces_filtered (2 * recurse, stream);
      print_spaces_filtered (2 * recurse, stream);
    }
    }
 
 
  fprintf_filtered (stream, ")");
  fprintf_filtered (stream, ")");
}
}
 
 
/* Print out fields of value at VALADDR having structure type TYPE.
/* Print out fields of value at VALADDR having structure type TYPE.
 
 
   TYPE, VALADDR, STREAM, RECURSE, and OPTIONS have the
   TYPE, VALADDR, STREAM, RECURSE, and OPTIONS have the
   same meanings as in ada_print_value and ada_val_print.
   same meanings as in ada_print_value and ada_val_print.
 
 
   OUTER_TYPE and OUTER_VALADDR give type and address of enclosing record
   OUTER_TYPE and OUTER_VALADDR give type and address of enclosing record
   (used to get discriminant values when printing variant parts).
   (used to get discriminant values when printing variant parts).
 
 
   COMMA_NEEDED is 1 if fields have been printed at the current recursion
   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
   level, so that a comma is needed before any field printed by this
   call.
   call.
 
 
   Returns 1 if COMMA_NEEDED or any fields were printed.  */
   Returns 1 if COMMA_NEEDED or any fields were printed.  */
 
 
static int
static int
print_field_values (struct type *type, const gdb_byte *valaddr,
print_field_values (struct type *type, const gdb_byte *valaddr,
                    struct ui_file *stream, int recurse,
                    struct ui_file *stream, int recurse,
                    const struct value_print_options *options,
                    const struct value_print_options *options,
                    int comma_needed,
                    int comma_needed,
                    struct type *outer_type, const gdb_byte *outer_valaddr)
                    struct type *outer_type, const gdb_byte *outer_valaddr)
{
{
  int i, len;
  int i, len;
 
 
  len = TYPE_NFIELDS (type);
  len = TYPE_NFIELDS (type);
 
 
  for (i = 0; i < len; i += 1)
  for (i = 0; i < len; i += 1)
    {
    {
      if (ada_is_ignored_field (type, i))
      if (ada_is_ignored_field (type, i))
        continue;
        continue;
 
 
      if (ada_is_wrapper_field (type, i))
      if (ada_is_wrapper_field (type, i))
        {
        {
          comma_needed =
          comma_needed =
            print_field_values (TYPE_FIELD_TYPE (type, i),
            print_field_values (TYPE_FIELD_TYPE (type, i),
                                valaddr
                                valaddr
                                + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
                                + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
                                stream, recurse, options,
                                stream, recurse, options,
                                comma_needed, type, valaddr);
                                comma_needed, type, valaddr);
          continue;
          continue;
        }
        }
      else if (ada_is_variant_part (type, i))
      else if (ada_is_variant_part (type, i))
        {
        {
          comma_needed =
          comma_needed =
            print_variant_part (type, i, valaddr,
            print_variant_part (type, i, valaddr,
                                stream, recurse, options, comma_needed,
                                stream, recurse, options, comma_needed,
                                outer_type, outer_valaddr);
                                outer_type, outer_valaddr);
          continue;
          continue;
        }
        }
 
 
      if (comma_needed)
      if (comma_needed)
        fprintf_filtered (stream, ", ");
        fprintf_filtered (stream, ", ");
      comma_needed = 1;
      comma_needed = 1;
 
 
      if (options->pretty)
      if (options->pretty)
        {
        {
          fprintf_filtered (stream, "\n");
          fprintf_filtered (stream, "\n");
          print_spaces_filtered (2 + 2 * recurse, stream);
          print_spaces_filtered (2 + 2 * recurse, stream);
        }
        }
      else
      else
        {
        {
          wrap_here (n_spaces (2 + 2 * recurse));
          wrap_here (n_spaces (2 + 2 * recurse));
        }
        }
      if (options->inspect_it)
      if (options->inspect_it)
        {
        {
          if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
          if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
            fputs_filtered ("\"( ptr \"", stream);
            fputs_filtered ("\"( ptr \"", stream);
          else
          else
            fputs_filtered ("\"( nodef \"", stream);
            fputs_filtered ("\"( nodef \"", stream);
          fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
          fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
                                   language_cplus, DMGL_NO_OPTS);
                                   language_cplus, DMGL_NO_OPTS);
          fputs_filtered ("\" \"", stream);
          fputs_filtered ("\" \"", stream);
          fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
          fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
                                   language_cplus, DMGL_NO_OPTS);
                                   language_cplus, DMGL_NO_OPTS);
          fputs_filtered ("\") \"", stream);
          fputs_filtered ("\") \"", stream);
        }
        }
      else
      else
        {
        {
          annotate_field_begin (TYPE_FIELD_TYPE (type, i));
          annotate_field_begin (TYPE_FIELD_TYPE (type, i));
          fprintf_filtered (stream, "%.*s",
          fprintf_filtered (stream, "%.*s",
                            ada_name_prefix_len (TYPE_FIELD_NAME (type, i)),
                            ada_name_prefix_len (TYPE_FIELD_NAME (type, i)),
                            TYPE_FIELD_NAME (type, i));
                            TYPE_FIELD_NAME (type, i));
          annotate_field_name_end ();
          annotate_field_name_end ();
          fputs_filtered (" => ", stream);
          fputs_filtered (" => ", stream);
          annotate_field_value ();
          annotate_field_value ();
        }
        }
 
 
      if (TYPE_FIELD_PACKED (type, i))
      if (TYPE_FIELD_PACKED (type, i))
        {
        {
          struct value *v;
          struct value *v;
 
 
          /* Bitfields require special handling, especially due to byte
          /* Bitfields require special handling, especially due to byte
             order problems.  */
             order problems.  */
          if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i))
          if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i))
            {
            {
              fputs_filtered (_("<optimized out or zero length>"), stream);
              fputs_filtered (_("<optimized out or zero length>"), stream);
            }
            }
          else
          else
            {
            {
              int bit_pos = TYPE_FIELD_BITPOS (type, i);
              int bit_pos = TYPE_FIELD_BITPOS (type, i);
              int bit_size = TYPE_FIELD_BITSIZE (type, i);
              int bit_size = TYPE_FIELD_BITSIZE (type, i);
              struct value_print_options opts;
              struct value_print_options opts;
 
 
              adjust_type_signedness (TYPE_FIELD_TYPE (type, i));
              adjust_type_signedness (TYPE_FIELD_TYPE (type, i));
              v = ada_value_primitive_packed_val (NULL, valaddr,
              v = ada_value_primitive_packed_val (NULL, valaddr,
                                                  bit_pos / HOST_CHAR_BIT,
                                                  bit_pos / HOST_CHAR_BIT,
                                                  bit_pos % HOST_CHAR_BIT,
                                                  bit_pos % HOST_CHAR_BIT,
                                                  bit_size,
                                                  bit_size,
                                                  TYPE_FIELD_TYPE (type, i));
                                                  TYPE_FIELD_TYPE (type, i));
              opts = *options;
              opts = *options;
              opts.deref_ref = 0;
              opts.deref_ref = 0;
              val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0,
              val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0,
                         stream, recurse + 1, &opts, current_language);
                         stream, recurse + 1, &opts, current_language);
            }
            }
        }
        }
      else
      else
        {
        {
          struct value_print_options opts = *options;
          struct value_print_options opts = *options;
          opts.deref_ref = 0;
          opts.deref_ref = 0;
          ada_val_print (TYPE_FIELD_TYPE (type, i),
          ada_val_print (TYPE_FIELD_TYPE (type, i),
                         valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
                         valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
                         0, 0, stream, recurse + 1, &opts);
                         0, 0, stream, recurse + 1, &opts);
        }
        }
      annotate_field_end ();
      annotate_field_end ();
    }
    }
 
 
  return comma_needed;
  return comma_needed;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.