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

   Copyright (C) 2000-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* This file is derived from c-valprint.c */

#include "defs.h"
#include "gdbsupport/gdb_obstack.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
#include "command.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "demangle.h"
#include "valprint.h"
#include "typeprint.h"
#include "language.h"
#include "target.h"
#include "annotate.h"
#include "p-lang.h"
#include "cp-abi.h"
#include "cp-support.h"
#include "objfiles.h"
#include "gdbsupport/byte-vector.h"
#include "cli/cli-style.h"


static void pascal_object_print_value_fields (struct value *, struct ui_file *,
					      int,
					      const struct value_print_options *,
					      struct type **, int);

/* Decorations for Pascal.  */

static const struct generic_val_print_decorations p_decorations =
{
  "",
  " + ",
  " * I",
  "true",
  "false",
  "void",
  "{",
  "}"
};

/* See p-lang.h.  */

void
pascal_language::value_print_inner (struct value *val,
				    struct ui_file *stream, int recurse,
				    const struct value_print_options *options) const

{
  struct type *type = check_typedef (value_type (val));
  struct gdbarch *gdbarch = type->arch ();
  enum bfd_endian byte_order = type_byte_order (type);
  unsigned int i = 0;	/* Number of characters printed */
  unsigned len;
  struct type *elttype;
  unsigned eltlen;
  int length_pos, length_size, string_pos;
  struct type *char_type;
  CORE_ADDR addr;
  int want_space = 0;
  const gdb_byte *valaddr = value_contents_for_printing (val).data ();

  switch (type->code ())
    {
    case TYPE_CODE_ARRAY:
      {
	LONGEST low_bound, high_bound;

	if (get_array_bounds (type, &low_bound, &high_bound))
	  {
	    len = high_bound - low_bound + 1;
	    elttype = check_typedef (TYPE_TARGET_TYPE (type));
	    eltlen = TYPE_LENGTH (elttype);
	    /* If 's' format is used, try to print out as string.
	       If no format is given, print as string if element type
	       is of TYPE_CODE_CHAR and element size is 1,2 or 4.  */
	    if (options->format == 's'
		|| ((eltlen == 1 || eltlen == 2 || eltlen == 4)
		    && elttype->code () == TYPE_CODE_CHAR
		    && options->format == 0))
	      {
		/* If requested, look for the first null char and only print
		   elements up to it.  */
		if (options->stop_print_at_null)
		  {
		    unsigned int temp_len;

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

		printstr (stream, TYPE_TARGET_TYPE (type), valaddr, len,
			  NULL, 0, options);
		i = len;
	      }
	    else
	      {
		gdb_printf (stream, "{");
		/* If this is a virtual function table, print the 0th
		   entry specially, and the rest of the members normally.  */
		if (pascal_object_is_vtbl_ptr_type (elttype))
		  {
		    i = 1;
		    gdb_printf (stream, "%d vtable entries", len - 1);
		  }
		else
		  {
		    i = 0;
		  }
		value_print_array_elements (val, stream, recurse, options, i);
		gdb_printf (stream, "}");
	      }
	    break;
	  }
	/* Array of unspecified length: treat like pointer to first elt.  */
	addr = value_address (val);
      }
      goto print_unpacked_pointer;

    case TYPE_CODE_PTR:
      if (options->format && options->format != 's')
	{
	  value_print_scalar_formatted (val, options, 0, stream);
	  break;
	}
      if (options->vtblprint && pascal_object_is_vtbl_ptr_type (type))
	{
	  /* Print the unmangled name if desired.  */
	  /* Print vtable entry - we only get here if we ARE using
	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.)  */
	  /* Extract the address, assume that it is unsigned.  */
	  addr = extract_unsigned_integer (valaddr,
					   TYPE_LENGTH (type), byte_order);
	  print_address_demangle (options, gdbarch, addr, stream, demangle);
	  break;
	}
      check_typedef (TYPE_TARGET_TYPE (type));

      addr = unpack_pointer (type, valaddr);
    print_unpacked_pointer:
      elttype = check_typedef (TYPE_TARGET_TYPE (type));

      if (elttype->code () == TYPE_CODE_FUNC)
	{
	  /* Try to print what function it points to.  */
	  print_address_demangle (options, gdbarch, addr, stream, demangle);
	  return;
	}

      if (options->addressprint && options->format != 's')
	{
	  gdb_puts (paddress (gdbarch, addr), stream);
	  want_space = 1;
	}

      /* For a pointer to char or unsigned char, also print the string
	 pointed to, unless pointer is null.  */
      if (((TYPE_LENGTH (elttype) == 1
	   && (elttype->code () == TYPE_CODE_INT
	       || elttype->code () == TYPE_CODE_CHAR))
	   || ((TYPE_LENGTH (elttype) == 2 || TYPE_LENGTH (elttype) == 4)
	       && elttype->code () == TYPE_CODE_CHAR))
	  && (options->format == 0 || options->format == 's')
	  && addr != 0)
	{
	  if (want_space)
	    gdb_puts (" ", stream);
	  /* No wide string yet.  */
	  i = val_print_string (elttype, NULL, addr, -1, stream, options);
	}
      /* Also for pointers to pascal strings.  */
      /* Note: this is Free Pascal specific:
	 as GDB does not recognize stabs pascal strings
	 Pascal strings are mapped to records
	 with lowercase names PM.  */
      if (pascal_is_string_type (elttype, &length_pos, &length_size,
				 &string_pos, &char_type, NULL) > 0
	  && addr != 0)
	{
	  ULONGEST string_length;
	  gdb_byte *buffer;

	  if (want_space)
	    gdb_puts (" ", stream);
	  buffer = (gdb_byte *) xmalloc (length_size);
	  read_memory (addr + length_pos, buffer, length_size);
	  string_length = extract_unsigned_integer (buffer, length_size,
						    byte_order);
	  xfree (buffer);
	  i = val_print_string (char_type, NULL,
				addr + string_pos, string_length,
				stream, options);
	}
      else if (pascal_object_is_vtbl_member (type))
	{
	  /* Print vtbl's nicely.  */
	  CORE_ADDR vt_address = unpack_pointer (type, valaddr);
	  struct bound_minimal_symbol msymbol =
	    lookup_minimal_symbol_by_pc (vt_address);

	  /* If 'symbol_print' is set, we did the work above.  */
	  if (!options->symbol_print
	      && (msymbol.minsym != NULL)
	      && (vt_address == msymbol.value_address ()))
	    {
	      if (want_space)
		gdb_puts (" ", stream);
	      gdb_puts ("<", stream);
	      gdb_puts (msymbol.minsym->print_name (), stream);
	      gdb_puts (">", stream);
	      want_space = 1;
	    }
	  if (vt_address && options->vtblprint)
	    {
	      struct value *vt_val;
	      struct symbol *wsym = NULL;
	      struct type *wtype;

	      if (want_space)
		gdb_puts (" ", stream);

	      if (msymbol.minsym != NULL)
		{
		  const char *search_name = msymbol.minsym->search_name ();
		  wsym = lookup_symbol_search_name (search_name, NULL,
						    VAR_DOMAIN).symbol;
		}

	      if (wsym)
		{
		  wtype = wsym->type ();
		}
	      else
		{
		  wtype = TYPE_TARGET_TYPE (type);
		}
	      vt_val = value_at (wtype, vt_address);
	      common_val_print (vt_val, stream, recurse + 1, options,
				current_language);
	      if (options->prettyformat)
		{
		  gdb_printf (stream, "\n");
		  print_spaces (2 + 2 * recurse, stream);
		}
	    }
	}

      return;

    case TYPE_CODE_REF:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_INT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_VOID:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_UNDEF:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_CHAR:
      generic_value_print (val, stream, recurse, options, &p_decorations);
      break;

    case TYPE_CODE_UNION:
      if (recurse && !options->unionprint)
	{
	  gdb_printf (stream, "{...}");
	  break;
	}
      /* Fall through.  */
    case TYPE_CODE_STRUCT:
      if (options->vtblprint && pascal_object_is_vtbl_ptr_type (type))
	{
	  /* Print the unmangled name if desired.  */
	  /* Print vtable entry - we only get here if NOT using
	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_PTR.)  */
	  /* Extract the address, assume that it is unsigned.  */
	  print_address_demangle
	    (options, gdbarch,
	     extract_unsigned_integer
	       (valaddr + type->field (VTBL_FNADDR_OFFSET).loc_bitpos () / 8,
		TYPE_LENGTH (type->field (VTBL_FNADDR_OFFSET).type ()),
		byte_order),
	     stream, demangle);
	}
      else
	{
	  if (pascal_is_string_type (type, &length_pos, &length_size,
				     &string_pos, &char_type, NULL) > 0)
	    {
	      len = extract_unsigned_integer (valaddr + length_pos,
					      length_size, byte_order);
	      printstr (stream, char_type, valaddr + string_pos, len,
			NULL, 0, options);
	    }
	  else
	    pascal_object_print_value_fields (val, stream, recurse,
					      options, NULL, 0);
	}
      break;

    case TYPE_CODE_SET:
      elttype = type->index_type ();
      elttype = check_typedef (elttype);
      if (elttype->is_stub ())
	{
	  fprintf_styled (stream, metadata_style.style (), "<incomplete type>");
	  break;
	}
      else
	{
	  struct type *range = elttype;
	  LONGEST low_bound, high_bound;
	  int need_comma = 0;

	  gdb_puts ("[", stream);

	  int bound_info = (get_discrete_bounds (range, &low_bound, &high_bound)
			    ? 0 : -1);
	  if (low_bound == 0 && high_bound == -1 && TYPE_LENGTH (type) > 0)
	    {
	      /* If we know the size of the set type, we can figure out the
	      maximum value.  */
	      bound_info = 0;
	      high_bound = TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1;
	      range->bounds ()->high.set_const_val (high_bound);
	    }
	maybe_bad_bstring:
	  if (bound_info < 0)
	    {
	      fputs_styled ("<error value>", metadata_style.style (), stream);
	      goto done;
	    }

	  for (i = low_bound; i <= high_bound; i++)
	    {
	      int element = value_bit_index (type, valaddr, i);

	      if (element < 0)
		{
		  i = element;
		  goto maybe_bad_bstring;
		}
	      if (element)
		{
		  if (need_comma)
		    gdb_puts (", ", stream);
		  print_type_scalar (range, i, stream);
		  need_comma = 1;

		  if (i + 1 <= high_bound
		      && value_bit_index (type, valaddr, ++i))
		    {
		      int j = i;

		      gdb_puts ("..", stream);
		      while (i + 1 <= high_bound
			     && value_bit_index (type, valaddr, ++i))
			j = i;
		      print_type_scalar (range, j, stream);
		    }
		}
	    }
	done:
	  gdb_puts ("]", stream);
	}
      break;

    default:
      error (_("Invalid pascal type code %d in symbol table."),
	     type->code ());
    }
}


void
pascal_language::value_print (struct value *val, struct ui_file *stream,
			      const struct value_print_options *options) const
{
  struct type *type = value_type (val);
  struct value_print_options opts = *options;

  opts.deref_ref = 1;

  /* If it is a pointer, indicate what it points to.

     Print type also if it is a reference.

     Object pascal: if it is a member pointer, we will take care
     of that when we print it.  */
  if (type->code () == TYPE_CODE_PTR
      || type->code () == TYPE_CODE_REF)
    {
      /* Hack:  remove (char *) for char strings.  Their
	 type is indicated by the quoted string anyway.  */
      if (type->code () == TYPE_CODE_PTR
	  && type->name () == NULL
	  && TYPE_TARGET_TYPE (type)->name () != NULL
	  && strcmp (TYPE_TARGET_TYPE (type)->name (), "char") == 0)
	{
	  /* Print nothing.  */
	}
      else
	{
	  gdb_printf (stream, "(");
	  type_print (type, "", stream, -1);
	  gdb_printf (stream, ") ");
	}
    }
  common_val_print (val, stream, 0, &opts, current_language);
}


static void
show_pascal_static_field_print (struct ui_file *file, int from_tty,
				struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Printing of pascal static members is %s.\n"),
	      value);
}

static struct obstack dont_print_vb_obstack;
static struct obstack dont_print_statmem_obstack;

static void pascal_object_print_static_field (struct value *,
					      struct ui_file *, int,
					      const struct value_print_options *);

static void pascal_object_print_value (struct value *, struct ui_file *, int,
				       const struct value_print_options *,
				       struct type **);

/* It was changed to this after 2.4.5.  */
const char pascal_vtbl_ptr_name[] =
{'_', '_', 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0};

/* Return truth value for assertion that TYPE is of the type
   "pointer to virtual function".  */

int
pascal_object_is_vtbl_ptr_type (struct type *type)
{
  const char *type_name = type->name ();

  return (type_name != NULL
	  && strcmp (type_name, pascal_vtbl_ptr_name) == 0);
}

/* Return truth value for the assertion that TYPE is of the type
   "pointer to virtual function table".  */

int
pascal_object_is_vtbl_member (struct type *type)
{
  if (type->code () == TYPE_CODE_PTR)
    {
      type = TYPE_TARGET_TYPE (type);
      if (type->code () == TYPE_CODE_ARRAY)
	{
	  type = TYPE_TARGET_TYPE (type);
	  if (type->code () == TYPE_CODE_STRUCT	/* If not using
							   thunks.  */
	      || type->code () == TYPE_CODE_PTR)	/* If using thunks.  */
	    {
	      /* Virtual functions tables are full of pointers
		 to virtual functions.  */
	      return pascal_object_is_vtbl_ptr_type (type);
	    }
	}
    }
  return 0;
}

/* Helper function for print pascal objects.

   VAL, STREAM, RECURSE, and OPTIONS have the same meanings as in
   pascal_object_print_value and c_value_print.

   DONT_PRINT is an array of baseclass types that we
   should not print, or zero if called from top level.  */

static void
pascal_object_print_value_fields (struct value *val, struct ui_file *stream,
				  int recurse,
				  const struct value_print_options *options,
				  struct type **dont_print_vb,
				  int dont_print_statmem)
{
  int i, len, n_baseclasses;
  char *last_dont_print
    = (char *) obstack_next_free (&dont_print_statmem_obstack);

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

  gdb_printf (stream, "{");
  len = type->num_fields ();
  n_baseclasses = TYPE_N_BASECLASSES (type);

  /* Print out baseclasses such that we don't print
     duplicates of virtual baseclasses.  */
  if (n_baseclasses > 0)
    pascal_object_print_value (val, stream, recurse + 1,
			       options, dont_print_vb);

  if (!len && n_baseclasses == 1)
    fprintf_styled (stream, metadata_style.style (), "<No data fields>");
  else
    {
      struct obstack tmp_obstack = dont_print_statmem_obstack;
      int fields_seen = 0;
      const gdb_byte *valaddr = value_contents_for_printing (val).data ();

      if (dont_print_statmem == 0)
	{
	  /* If we're at top level, carve out a completely fresh
	     chunk of the obstack and use that until this particular
	     invocation returns.  */
	  obstack_finish (&dont_print_statmem_obstack);
	}

      for (i = n_baseclasses; i < len; i++)
	{
	  /* If requested, skip printing of static fields.  */
	  if (!options->pascal_static_field_print
	      && field_is_static (&type->field (i)))
	    continue;
	  if (fields_seen)
	    gdb_printf (stream, ", ");
	  else if (n_baseclasses > 0)
	    {
	      if (options->prettyformat)
		{
		  gdb_printf (stream, "\n");
		  print_spaces (2 + 2 * recurse, stream);
		  gdb_puts ("members of ", stream);
		  gdb_puts (type->name (), stream);
		  gdb_puts (": ", stream);
		}
	    }
	  fields_seen = 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 ());

	  if (field_is_static (&type->field (i)))
	    {
	      gdb_puts ("static ", stream);
	      fprintf_symbol (stream,
			      type->field (i).name (),
			      current_language->la_language,
			      DMGL_PARAMS | DMGL_ANSI);
	    }
	  else
	    fputs_styled (type->field (i).name (),
			  variable_name_style.style (), stream);
	  annotate_field_name_end ();
	  gdb_puts (" = ", stream);
	  annotate_field_value ();

	  if (!field_is_static (&type->field (i))
	      && TYPE_FIELD_PACKED (type, i))
	    {
	      struct value *v;

	      /* Bitfields require special handling, especially due to byte
		 order problems.  */
	      if (TYPE_FIELD_IGNORE (type, i))
		{
		  fputs_styled ("<optimized out or zero length>",
				metadata_style.style (), stream);
		}
	      else if (value_bits_synthetic_pointer
			 (val, type->field (i).loc_bitpos (),
			  TYPE_FIELD_BITSIZE (type, i)))
		{
		  fputs_styled (_("<synthetic pointer>"),
				metadata_style.style (), stream);
		}
	      else
		{
		  struct value_print_options opts = *options;

		  v = value_field_bitfield (type, i, valaddr, 0, val);

		  opts.deref_ref = 0;
		  common_val_print (v, stream, recurse + 1, &opts,
				    current_language);
		}
	    }
	  else
	    {
	      if (TYPE_FIELD_IGNORE (type, i))
		{
		  fputs_styled ("<optimized out or zero length>",
				metadata_style.style (), stream);
		}
	      else if (field_is_static (&type->field (i)))
		{
		  /* struct value *v = value_static_field (type, i);
		     v4.17 specific.  */
		  struct value *v;

		  v = value_field_bitfield (type, i, valaddr, 0, val);

		  if (v == NULL)
		    val_print_optimized_out (NULL, stream);
		  else
		    pascal_object_print_static_field (v, stream, recurse + 1,
						      options);
		}
	      else
		{
		  struct value_print_options opts = *options;

		  opts.deref_ref = 0;

		  struct value *v = value_primitive_field (val, 0, i,
							   value_type (val));
		  common_val_print (v, stream, recurse + 1, &opts,
				    current_language);
		}
	    }
	  annotate_field_end ();
	}

      if (dont_print_statmem == 0)
	{
	  /* Free the space used to deal with the printing
	     of the members from top level.  */
	  obstack_free (&dont_print_statmem_obstack, last_dont_print);
	  dont_print_statmem_obstack = tmp_obstack;
	}

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

/* Special val_print routine to avoid printing multiple copies of virtual
   baseclasses.  */

static void
pascal_object_print_value (struct value *val, struct ui_file *stream,
			   int recurse,
			   const struct value_print_options *options,
			   struct type **dont_print_vb)
{
  struct type **last_dont_print
    = (struct type **) obstack_next_free (&dont_print_vb_obstack);
  struct obstack tmp_obstack = dont_print_vb_obstack;
  struct type *type = check_typedef (value_type (val));
  int i, n_baseclasses = TYPE_N_BASECLASSES (type);

  if (dont_print_vb == 0)
    {
      /* If we're at top level, carve out a completely fresh
	 chunk of the obstack and use that until this particular
	 invocation returns.  */
      /* Bump up the high-water mark.  Now alpha is omega.  */
      obstack_finish (&dont_print_vb_obstack);
    }

  for (i = 0; i < n_baseclasses; i++)
    {
      LONGEST boffset = 0;
      struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
      const char *basename = baseclass->name ();
      int skip = 0;

      if (BASETYPE_VIA_VIRTUAL (type, i))
	{
	  struct type **first_dont_print
	    = (struct type **) obstack_base (&dont_print_vb_obstack);

	  int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
	    - first_dont_print;

	  while (--j >= 0)
	    if (baseclass == first_dont_print[j])
	      goto flush_it;

	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
	}

      struct value *base_value;
      try
	{
	  base_value = value_primitive_field (val, 0, i, type);
	}
      catch (const gdb_exception_error &ex)
	{
	  base_value = nullptr;
	  if (ex.error == NOT_AVAILABLE_ERROR)
	    skip = -1;
	  else
	    skip = 1;
	}

      if (skip == 0)
	{
	  /* The virtual base class pointer might have been clobbered by the
	     user program. Make sure that it still points to a valid memory
	     location.  */

	  if (boffset < 0 || boffset >= TYPE_LENGTH (type))
	    {
	      CORE_ADDR address= value_address (val);
	      gdb::byte_vector buf (TYPE_LENGTH (baseclass));

	      if (target_read_memory (address + boffset, buf.data (),
				      TYPE_LENGTH (baseclass)) != 0)
		skip = 1;
	      base_value = value_from_contents_and_address (baseclass,
							    buf.data (),
							    address + boffset);
	      baseclass = value_type (base_value);
	      boffset = 0;
	    }
	}

      if (options->prettyformat)
	{
	  gdb_printf (stream, "\n");
	  print_spaces (2 * recurse, stream);
	}
      gdb_puts ("<", stream);
      /* Not sure what the best notation is in the case where there is no
	 baseclass name.  */

      gdb_puts (basename ? basename : "", stream);
      gdb_puts ("> = ", stream);

      if (skip < 0)
	val_print_unavailable (stream);
      else if (skip > 0)
	val_print_invalid_address (stream);
      else
	pascal_object_print_value_fields
	  (base_value, stream, recurse, options,
	   (struct type **) obstack_base (&dont_print_vb_obstack),
	   0);
      gdb_puts (", ", stream);

    flush_it:
      ;
    }

  if (dont_print_vb == 0)
    {
      /* Free the space used to deal with the printing
	 of this type from top level.  */
      obstack_free (&dont_print_vb_obstack, last_dont_print);
      /* Reset watermark so that we can continue protecting
	 ourselves from whatever we were protecting ourselves.  */
      dont_print_vb_obstack = tmp_obstack;
    }
}

/* Print value of a static member.
   To avoid infinite recursion when printing a class that contains
   a static instance of the class, we keep the addresses of all printed
   static member classes in an obstack and refuse to print them more
   than once.

   VAL contains the value to print, STREAM, RECURSE, and OPTIONS
   have the same meanings as in c_val_print.  */

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

  if (value_entirely_optimized_out (val))
    {
      val_print_optimized_out (val, stream);
      return;
    }

  if (type->code () == TYPE_CODE_STRUCT)
    {
      CORE_ADDR *first_dont_print, addr;
      int i;

      first_dont_print
	= (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
      i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
	- first_dont_print;

      while (--i >= 0)
	{
	  if (value_address (val) == first_dont_print[i])
	    {
	      fputs_styled (_("\
<same as static member of an already seen type>"),
			    metadata_style.style (), stream);
	      return;
	    }
	}

      addr = value_address (val);
      obstack_grow (&dont_print_statmem_obstack, (char *) &addr,
		    sizeof (CORE_ADDR));

      type = check_typedef (type);
      pascal_object_print_value_fields (val, stream, recurse,
					options, NULL, 1);
      return;
    }

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

void _initialize_pascal_valprint ();
void
_initialize_pascal_valprint ()
{
  add_setshow_boolean_cmd ("pascal_static-members", class_support,
			   &user_print_options.pascal_static_field_print, _("\
Set printing of pascal static members."), _("\
Show printing of pascal static members."), NULL,
			   NULL,
			   show_pascal_static_field_print,
			   &setprintlist, &showprintlist);
}
