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

   Copyright (C) 1986-2016 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"

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

extern void _initialize_cp_valprint (void);

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 *,
			    const gdb_byte *, LONGEST,
			    CORE_ADDR, struct ui_file *,
			    int, const struct value *,
			    const struct value_print_options *,
			    struct type **);


/* GCC versions after 2.4.5 use this.  */
EXPORTED_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_no_tag (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,
		       const gdb_byte *valaddr, LONGEST offset,
		       CORE_ADDR address, struct ui_file *stream,
		       int recurse, const 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, valaddr, 
		    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++)
	{
	  /* If requested, skip printing of static fields.  */
	  if (!options->static_field_print
	      && field_is_static (&TYPE_FIELD (type, i)))
	    continue;

	  if (fields_seen)
	    fprintf_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_no_tag (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 ();
	  /* Do not print leading '=' in case of anonymous
	     unions.  */
	  if (strcmp (TYPE_FIELD_NAME (type, i), ""))
	    fputs_filtered (" = ", stream);
	  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
		{
		  struct value_print_options opts = *options;

		  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 (ex, RETURN_MASK_ERROR)
		    {
		      fprintf_filtered (stream,
					_("<error reading variable: %s>"),
					ex.message);
		    }
		  END_CATCH

		  cp_print_static_field (TYPE_FIELD_TYPE (type, i),
					 v, stream, recurse + 1,
					 options);
		}
	      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 (options,
						      get_type_arch (type),
						      addr, stream);
		    }
		}
	      else
		{
		  struct value_print_options opts = *options;

		  opts.deref_ref = 0;
		  val_print (TYPE_FIELD_TYPE (type, i),
			     valaddr, 
			     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.  */

	      void *free_to_ptr =
		(char *) obstack_next_free (&dont_print_statmem_obstack) -
		(obstack_final_size - statmem_obstack_initial_size);

	      obstack_free (&dont_print_statmem_obstack,
			    free_to_ptr);
	    }

	  if (last_set_recurse != recurse)
	    {
	      size_t 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,
			    const 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, valaddr, 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,
		const gdb_byte *valaddr, LONGEST offset,
		CORE_ADDR address, struct ui_file *stream,
		int recurse, const 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;

  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);
      const gdb_byte *base_valaddr = NULL;
      const 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 (ex, RETURN_MASK_ERROR)
	{
	  if (ex.error == NOT_AVAILABLE_ERROR)
	    skip = -1;
	  else
	    skip = 1;
	}
      END_CATCH

      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 *buf;
		  struct cleanup *back_to;

		  buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass));
		  back_to = make_cleanup (xfree, buf);

		  if (target_read_memory (address + boffset, buf,
					  TYPE_LENGTH (baseclass)) != 0)
		    skip = 1;
		  base_val = value_from_contents_and_address (baseclass,
							      buf,
							      address + boffset);
		  baseclass = value_type (base_val);
		  thisoffset = 0;
		  boffset = 0;
		  thistype = baseclass;
		  base_valaddr = value_contents_for_printing_const (base_val);
		  do_cleanups (back_to);
		}
	      else
		{
		  base_valaddr = valaddr;
		  base_val = val;
		}
	    }
	  else
	    {
	      base_valaddr = valaddr;
	      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;

	  /* Attempt to run an extension language pretty-printer on the
	     baseclass if possible.  */
	  if (!options->raw)
	    result
	      = apply_ext_lang_val_pretty_printer (baseclass, base_valaddr,
						   thisoffset + boffset,
						   value_address (base_val),
						   stream, recurse,
						   base_val, options,
						   current_language);

	  if (!result)
	    cp_print_value_fields (baseclass, thistype, base_valaddr,
				   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;
    }

  if (TYPE_CODE (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));
      type = check_typedef (type);
      cp_print_value_fields (type, value_enclosing_type (val),
			     value_contents_for_printing (val),
			     value_embedded_offset (val), addr,
			     stream, recurse, val,
			     options, NULL, 1);
      return;
    }

  if (TYPE_CODE (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_contents_for_printing (val), 
	     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, 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_no_tag (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 *));
}
