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

   Copyright (C) 1986-2019 Free Software Foundation, Inc.

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "gdb_obstack.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
#include "command.h"
#include "gdbcmd.h"
#include "demangle.h"
#include "annotate.h"
#include "c-lang.h"
#include "target.h"
#include "cp-abi.h"
#include "valprint.h"
#include "cp-support.h"
#include "language.h"
#include "extension.h"
#include "typeprint.h"
#include "common/byte-vector.h"

/* Controls printing of vtbl's.  */
static void
show_vtblprint (struct ui_file *file, int from_tty,
		struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("\
Printing of C++ virtual function tables is %s.\n"),
		    value);
}

/* Controls looking up an object's derived type using what we find in
   its vtables.  */
static void
show_objectprint (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c,
		  const char *value)
{
  fprintf_filtered (file, _("\
Printing of object's derived type based on vtable info is %s.\n"),
		    value);
}

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


static struct obstack dont_print_vb_obstack;
static struct obstack dont_print_statmem_obstack;
static struct obstack dont_print_stat_array_obstack;

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

static void cp_print_value (struct type *, struct type *,
			    LONGEST,
			    CORE_ADDR, struct ui_file *,
			    int, struct value *,
			    const struct value_print_options *,
			    struct type **);


/* GCC versions after 2.4.5 use this.  */
extern const char vtbl_ptr_name[] = "__vtbl_ptr_type";

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

int
cp_is_vtbl_ptr_type (struct type *type)
{
  const char *type_name = TYPE_NAME (type);

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

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

int
cp_is_vtbl_member (struct type *type)
{
  /* With older versions of g++, the vtbl field pointed to an array of
     structures.  Nowadays it points directly to the structure.  */
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
    {
      type = TYPE_TARGET_TYPE (type);
      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
	{
	  type = TYPE_TARGET_TYPE (type);
	  if (TYPE_CODE (type) == TYPE_CODE_STRUCT    /* if not using thunks */
	      || TYPE_CODE (type) == TYPE_CODE_PTR)   /* if using thunks */
	    {
	      /* Virtual functions tables are full of pointers
	         to virtual functions.  */
	      return cp_is_vtbl_ptr_type (type);
	    }
	}
      else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)  /* if not using thunks */
	{
	  return cp_is_vtbl_ptr_type (type);
	}
      else if (TYPE_CODE (type) == TYPE_CODE_PTR)     /* if using thunks */
	{
	  /* The type name of the thunk pointer is NULL when using
	     dwarf2.  We could test for a pointer to a function, but
	     there is no type info for the virtual table either, so it
	     wont help.  */
	  return cp_is_vtbl_ptr_type (type);
	}
    }
  return 0;
}

/* Mutually recursive subroutines of cp_print_value and c_val_print to
   print out a structure's fields: cp_print_value_fields and
   cp_print_value.

   TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and OPTIONS have the same
   meanings as in cp_print_value and c_val_print.

   2nd argument REAL_TYPE is used to carry over the type of the
   derived class across the recursion to base classes.

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

void
cp_print_value_fields (struct type *type, struct type *real_type,
		       LONGEST offset,
		       CORE_ADDR address, struct ui_file *stream,
		       int recurse, struct value *val,
		       const struct value_print_options *options,
		       struct type **dont_print_vb,
		       int dont_print_statmem)
{
  int i, len, n_baseclasses;
  int fields_seen = 0;
  static int last_set_recurse = -1;

  type = check_typedef (type);
  
  if (recurse == 0)
    {
      /* Any object can be left on obstacks only during an unexpected
	 error.  */

      if (obstack_object_size (&dont_print_statmem_obstack) > 0)
	{
	  obstack_free (&dont_print_statmem_obstack, NULL);
	  obstack_begin (&dont_print_statmem_obstack,
			 32 * sizeof (CORE_ADDR));
	}
      if (obstack_object_size (&dont_print_stat_array_obstack) > 0)
	{
	  obstack_free (&dont_print_stat_array_obstack, NULL);
	  obstack_begin (&dont_print_stat_array_obstack,
			 32 * sizeof (struct type *));
	}
    }

  fprintf_filtered (stream, "{");
  len = TYPE_NFIELDS (type);
  n_baseclasses = TYPE_N_BASECLASSES (type);

  /* First, print out baseclasses such that we don't print
     duplicates of virtual baseclasses.  */

  if (n_baseclasses > 0)
    cp_print_value (type, real_type,
		    offset, address, stream,
		    recurse + 1, val, options,
		    dont_print_vb);

  /* Second, print out data fields */

  /* If there are no data fields, skip this part */
  if (len == n_baseclasses || !len)
    fprintf_filtered (stream, "<No data fields>");
  else
    {
      size_t statmem_obstack_initial_size = 0;
      size_t stat_array_obstack_initial_size = 0;
      struct type *vptr_basetype = NULL;
      int vptr_fieldno;

      if (dont_print_statmem == 0)
	{
	  statmem_obstack_initial_size =
	    obstack_object_size (&dont_print_statmem_obstack);

	  if (last_set_recurse != recurse)
	    {
	      stat_array_obstack_initial_size =
		obstack_object_size (&dont_print_stat_array_obstack);

	      last_set_recurse = recurse;
	    }
	}

      vptr_fieldno = get_vptr_fieldno (type, &vptr_basetype);
      for (i = n_baseclasses; i < len; i++)
	{
	  const gdb_byte *valaddr = value_contents_for_printing (val);

	  /* If requested, skip printing of static fields.  */
	  if (!options->static_field_print
	      && field_is_static (&TYPE_FIELD (type, i)))
	    continue;

	  if (fields_seen)
	    {
	      fputs_filtered (",", stream);
	      if (!options->prettyformat)
		fputs_filtered (" ", stream);
	    }
	  else if (n_baseclasses > 0)
	    {
	      if (options->prettyformat)
		{
		  fprintf_filtered (stream, "\n");
		  print_spaces_filtered (2 + 2 * recurse, stream);
		  fputs_filtered ("members of ", stream);
		  fputs_filtered (TYPE_NAME (type), stream);
		  fputs_filtered (":", stream);
		}
	    }
	  fields_seen = 1;

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

	  annotate_field_begin (TYPE_FIELD_TYPE (type, i));

	  if (field_is_static (&TYPE_FIELD (type, i)))
	    fputs_filtered ("static ", stream);
	  fprintf_symbol_filtered (stream,
				   TYPE_FIELD_NAME (type, i),
				   current_language->la_language,
				   DMGL_PARAMS | DMGL_ANSI);
	  annotate_field_name_end ();

	  /* We tweak various options in a few cases below.  */
	  value_print_options options_copy = *options;
	  value_print_options *opts = &options_copy;

	  /* Do not print leading '=' in case of anonymous
	     unions.  */
	  if (strcmp (TYPE_FIELD_NAME (type, i), ""))
	    fputs_filtered (" = ", stream);
	  else
	    {
	      /* If this is an anonymous field then we want to consider it
		 as though it is at its parent's depth when it comes to the
		 max print depth.  */
	      if (opts->max_depth != -1 && opts->max_depth < INT_MAX)
		++opts->max_depth;
	    }
	  annotate_field_value ();

	  if (!field_is_static (&TYPE_FIELD (type, 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_filtered ("<optimized out or zero length>", stream);
		}
	      else if (value_bits_synthetic_pointer (val,
						     TYPE_FIELD_BITPOS (type,
									i),
						     TYPE_FIELD_BITSIZE (type,
									 i)))
		{
		  fputs_filtered (_("<synthetic pointer>"), stream);
		}
	      else
		{
		  opts->deref_ref = 0;

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

		  common_val_print (v, stream, recurse + 1,
				    opts, current_language);
		}
	    }
	  else
	    {
	      if (TYPE_FIELD_IGNORE (type, i))
		{
		  fputs_filtered ("<optimized out or zero length>",
				  stream);
		}
	      else if (field_is_static (&TYPE_FIELD (type, i)))
		{
		  struct value *v = NULL;

		  try
		    {
		      v = value_static_field (type, i);
		    }

		  catch (const gdb_exception_error &ex)
		    {
		      fprintf_filtered (stream,
					_("<error reading variable: %s>"),
					ex.what ());
		    }

		  cp_print_static_field (TYPE_FIELD_TYPE (type, i),
					 v, stream, recurse + 1, opts);
		}
	      else if (i == vptr_fieldno && type == vptr_basetype)
		{
		  int i_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8;
		  struct type *i_type = TYPE_FIELD_TYPE (type, i);

		  if (valprint_check_validity (stream, i_type, i_offset, val))
		    {
		      CORE_ADDR addr;
		      
		      addr = extract_typed_address (valaddr + i_offset, i_type);
		      print_function_pointer_address (opts,
						      get_type_arch (type),
						      addr, stream);
		    }
		}
	      else
		{
		  opts->deref_ref = 0;
		  val_print (TYPE_FIELD_TYPE (type, i),
			     offset + TYPE_FIELD_BITPOS (type, i) / 8,
			     address,
			     stream, recurse + 1, val, opts,
			     current_language);
		}
	    }
	  annotate_field_end ();
	}

      if (dont_print_statmem == 0)
	{
	  size_t obstack_final_size =
           obstack_object_size (&dont_print_statmem_obstack);

	  if (obstack_final_size > statmem_obstack_initial_size)
	    {
	      /* In effect, a pop of the printed-statics stack.  */
	      size_t shrink_bytes
		= statmem_obstack_initial_size - obstack_final_size;
	      obstack_blank_fast (&dont_print_statmem_obstack, shrink_bytes);
	    }

	  if (last_set_recurse != recurse)
	    {
	      obstack_final_size =
		obstack_object_size (&dont_print_stat_array_obstack);
	      
	      if (obstack_final_size > stat_array_obstack_initial_size)
		{
		  void *free_to_ptr =
		    (char *) obstack_next_free (&dont_print_stat_array_obstack)
		    - (obstack_final_size
		       - stat_array_obstack_initial_size);

		  obstack_free (&dont_print_stat_array_obstack,
				free_to_ptr);
		}
	      last_set_recurse = -1;
	    }
	}

      if (options->prettyformat)
	{
	  fprintf_filtered (stream, "\n");
	  print_spaces_filtered (2 * recurse, stream);
	}
    }				/* if there are data fields */

  fprintf_filtered (stream, "}");
}

/* Like cp_print_value_fields, but find the runtime type of the object
   and pass it as the `real_type' argument to cp_print_value_fields.
   This function is a hack to work around the fact that
   common_val_print passes the embedded offset to val_print, but not
   the enclosing type.  */

void
cp_print_value_fields_rtti (struct type *type,
			    const gdb_byte *valaddr, LONGEST offset,
			    CORE_ADDR address,
			    struct ui_file *stream, int recurse,
			    struct value *val,
			    const struct value_print_options *options,
			    struct type **dont_print_vb, 
			    int dont_print_statmem)
{
  struct type *real_type = NULL;

  /* We require all bits to be valid in order to attempt a
     conversion.  */
  if (!value_bits_any_optimized_out (val,
				     TARGET_CHAR_BIT * offset,
				     TARGET_CHAR_BIT * TYPE_LENGTH (type)))
    {
      struct value *value;
      int full, using_enc;
      LONGEST top;

      /* Ugh, we have to convert back to a value here.  */
      value = value_from_contents_and_address (type, valaddr + offset,
					       address + offset);
      type = value_type (value);
      /* We don't actually care about most of the result here -- just
	 the type.  We already have the correct offset, due to how
	 val_print was initially called.  */
      real_type = value_rtti_type (value, &full, &top, &using_enc);
    }

  if (!real_type)
    real_type = type;

  cp_print_value_fields (type, real_type, offset,
			 address, stream, recurse, val, options,
			 dont_print_vb, dont_print_statmem);
}

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

static void
cp_print_value (struct type *type, struct type *real_type,
		LONGEST offset,
		CORE_ADDR address, struct ui_file *stream,
		int recurse, struct value *val,
		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;
  int i, n_baseclasses = TYPE_N_BASECLASSES (type);
  LONGEST thisoffset;
  struct type *thistype;
  const gdb_byte *valaddr = value_contents_for_printing (val);

  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;
      int skip = 0;
      struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
      const char *basename = TYPE_NAME (baseclass);
      struct value *base_val = NULL;

      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);
	}

      thisoffset = offset;
      thistype = real_type;

      try
	{
	  boffset = baseclass_offset (type, i, valaddr, offset, address, val);
	}
      catch (const gdb_exception_error &ex)
	{
	  if (ex.error == NOT_AVAILABLE_ERROR)
	    skip = -1;
	  else
	    skip = 1;
	}

      if (skip == 0)
	{
	  if (BASETYPE_VIA_VIRTUAL (type, i))
	    {
	      /* 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 + offset) < 0
		  || (boffset + offset) >= TYPE_LENGTH (real_type))
		{
		  gdb::byte_vector buf (TYPE_LENGTH (baseclass));

		  if (target_read_memory (address + boffset, buf.data (),
					  TYPE_LENGTH (baseclass)) != 0)
		    skip = 1;
		  base_val = value_from_contents_and_address (baseclass,
							      buf.data (),
							      address + boffset);
		  baseclass = value_type (base_val);
		  thisoffset = 0;
		  boffset = 0;
		  thistype = baseclass;
		}
	      else
		{
		  base_val = val;
		}
	    }
	  else
	    {
	      base_val = val;
	    }
	}

      /* Now do the printing.  */
      if (options->prettyformat)
	{
	  fprintf_filtered (stream, "\n");
	  print_spaces_filtered (2 * recurse, stream);
	}
      fputs_filtered ("<", stream);
      /* Not sure what the best notation is in the case where there is
         no baseclass name.  */
      fputs_filtered (basename ? basename : "", stream);
      fputs_filtered ("> = ", stream);

      if (skip < 0)
	val_print_unavailable (stream);
      else if (skip > 0)
	val_print_invalid_address (stream);
      else
	{
	  int result = 0;

	  if (options->max_depth > -1
	      && recurse >= options->max_depth)
	    {
	      const struct language_defn *language = current_language;
	      gdb_assert (language->la_struct_too_deep_ellipsis != NULL);
	      fputs_filtered (language->la_struct_too_deep_ellipsis, stream);
	    }
	  else
	    {
	      /* Attempt to run an extension language pretty-printer on the
		 baseclass if possible.  */
	      if (!options->raw)
		result
		  = apply_ext_lang_val_pretty_printer (baseclass,
						       thisoffset + boffset,
						       value_address (base_val),
						       stream, recurse,
						       base_val, options,
						       current_language);

	      if (!result)
		cp_print_value_fields (baseclass, thistype,
				       thisoffset + boffset,
				       value_address (base_val),
				       stream, recurse, base_val, options,
				       ((struct type **)
					obstack_base (&dont_print_vb_obstack)),
				       0);
	    }
	}
      fputs_filtered (", ", 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, TYPE, STREAM, RECURSE, and OPTIONS
   have the same meanings as in c_val_print.  */

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

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

  struct type *real_type = check_typedef (type);
  if (TYPE_CODE (real_type) == TYPE_CODE_STRUCT)
    {
      CORE_ADDR *first_dont_print;
      CORE_ADDR addr;
      int i;

      first_dont_print
	= (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
      i = obstack_object_size (&dont_print_statmem_obstack)
	/ sizeof (CORE_ADDR);

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

      addr = value_address (val);
      obstack_grow (&dont_print_statmem_obstack, (char *) &addr,
		    sizeof (CORE_ADDR));
      cp_print_value_fields (type, value_enclosing_type (val),
			     value_embedded_offset (val), addr,
			     stream, recurse, val,
			     options, NULL, 1);
      return;
    }

  if (TYPE_CODE (real_type) == TYPE_CODE_ARRAY)
    {
      struct type **first_dont_print;
      int i;
      struct type *target_type = TYPE_TARGET_TYPE (type);

      first_dont_print
	= (struct type **) obstack_base (&dont_print_stat_array_obstack);
      i = obstack_object_size (&dont_print_stat_array_obstack)
	/ sizeof (struct type *);

      while (--i >= 0)
	{
	  if (target_type == first_dont_print[i])
	    {
	      fputs_filtered ("<same as static member of an already"
			      " seen type>",
			      stream);
	      return;
	    }
	}

      obstack_grow (&dont_print_stat_array_obstack,
		    (char *) &target_type,
		    sizeof (struct type *));
    }

  opts = *options;
  opts.deref_ref = 0;
  val_print (type,
	     value_embedded_offset (val),
	     value_address (val),
	     stream, recurse, val,
	     &opts, current_language);
}

/* Find the field in *SELF, or its non-virtual base classes, with
   bit offset OFFSET.  Set *SELF to the containing type and *FIELDNO
   to the containing field number.  If OFFSET is not exactly at the
   start of some field, set *SELF to NULL.  */

static void
cp_find_class_member (struct type **self_p, int *fieldno,
		      LONGEST offset)
{
  struct type *self;
  unsigned int i;
  unsigned len;

  *self_p = check_typedef (*self_p);
  self = *self_p;
  len = TYPE_NFIELDS (self);

  for (i = TYPE_N_BASECLASSES (self); i < len; i++)
    {
      LONGEST bitpos = TYPE_FIELD_BITPOS (self, i);

      QUIT;
      if (offset == bitpos)
	{
	  *fieldno = i;
	  return;
	}
    }

  for (i = 0; i < TYPE_N_BASECLASSES (self); i++)
    {
      LONGEST bitpos = TYPE_FIELD_BITPOS (self, i);
      LONGEST bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (self, i));

      if (offset >= bitpos && offset < bitpos + bitsize)
	{
	  *self_p = TYPE_FIELD_TYPE (self, i);
	  cp_find_class_member (self_p, fieldno, offset - bitpos);
	  return;
	}
    }

  *self_p = NULL;
}

void
cp_print_class_member (const gdb_byte *valaddr, struct type *type,
		       struct ui_file *stream, const char *prefix)
{
  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));

  /* VAL is a byte offset into the structure type SELF_TYPE.
     Find the name of the field for that offset and
     print it.  */
  struct type *self_type = TYPE_SELF_TYPE (type);
  LONGEST val;
  int fieldno;

  val = extract_signed_integer (valaddr,
				TYPE_LENGTH (type),
				byte_order);

  /* Pointers to data members are usually byte offsets into an object.
     Because a data member can have offset zero, and a NULL pointer to
     member must be distinct from any valid non-NULL pointer to
     member, either the value is biased or the NULL value has a
     special representation; both are permitted by ISO C++.  HP aCC
     used a bias of 0x20000000; HP cfront used a bias of 1; g++ 3.x
     and other compilers which use the Itanium ABI use -1 as the NULL
     value.  GDB only supports that last form; to add support for
     another form, make this into a cp-abi hook.  */

  if (val == -1)
    {
      fprintf_filtered (stream, "NULL");
      return;
    }

  cp_find_class_member (&self_type, &fieldno, val << 3);

  if (self_type != NULL)
    {
      const char *name;

      fputs_filtered (prefix, stream);
      name = TYPE_NAME (self_type);
      if (name)
	fputs_filtered (name, stream);
      else
	c_type_print_base (self_type, stream, 0, 0, &type_print_raw_options);
      fprintf_filtered (stream, "::");
      fputs_filtered (TYPE_FIELD_NAME (self_type, fieldno), stream);
    }
  else
    fprintf_filtered (stream, "%ld", (long) val);
}


void
_initialize_cp_valprint (void)
{
  add_setshow_boolean_cmd ("static-members", class_support,
			   &user_print_options.static_field_print, _("\
Set printing of C++ static members."), _("\
Show printing of C++ static members."), NULL,
			   NULL,
			   show_static_field_print,
			   &setprintlist, &showprintlist);

  add_setshow_boolean_cmd ("vtbl", class_support,
			   &user_print_options.vtblprint, _("\
Set printing of C++ virtual function tables."), _("\
Show printing of C++ virtual function tables."), NULL,
			   NULL,
			   show_vtblprint,
			   &setprintlist, &showprintlist);

  add_setshow_boolean_cmd ("object", class_support,
			   &user_print_options.objectprint, _("\
Set printing of object's derived type based on vtable info."), _("\
Show printing of object's derived type based on vtable info."), NULL,
			   NULL,
			   show_objectprint,
			   &setprintlist, &showprintlist);

  obstack_begin (&dont_print_stat_array_obstack,
		 32 * sizeof (struct type *));
  obstack_begin (&dont_print_statmem_obstack,
		 32 * sizeof (CORE_ADDR));
  obstack_begin (&dont_print_vb_obstack,
		 32 * sizeof (struct type *));
}
