119370Spst/* Support for printing C++ values for GDB, the GNU debugger.
298944Sobrien   Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3130803Smarcel   2000, 2001, 2002, 2003
419370Spst   Free Software Foundation, Inc.
519370Spst
698944Sobrien   This file is part of GDB.
719370Spst
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1219370Spst
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1719370Spst
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2219370Spst
2319370Spst#include "defs.h"
24130803Smarcel#include "gdb_obstack.h"
2519370Spst#include "symtab.h"
2619370Spst#include "gdbtypes.h"
2719370Spst#include "expression.h"
2819370Spst#include "value.h"
2919370Spst#include "command.h"
3019370Spst#include "gdbcmd.h"
3119370Spst#include "demangle.h"
3219370Spst#include "annotate.h"
3319370Spst#include "gdb_string.h"
3419370Spst#include "c-lang.h"
3546283Sdfr#include "target.h"
3698944Sobrien#include "cp-abi.h"
37130803Smarcel#include "valprint.h"
3819370Spst
3998944Sobrien/* Indication of presence of HP-compiled object files */
4098944Sobrienextern int hp_som_som_object_present;	/* defined in symtab.c */
4146283Sdfr
4246283Sdfr
4319370Spstint vtblprint;			/* Controls printing of vtbl's */
4419370Spstint objectprint;		/* Controls looking up an object's derived type
4519370Spst				   using what we find in its vtables.  */
4698944Sobrienint static_field_print;		/* Controls printing of static fields. */
4719370Spst
4819370Spststatic struct obstack dont_print_vb_obstack;
4919370Spststatic struct obstack dont_print_statmem_obstack;
5019370Spst
5198944Sobrienextern void _initialize_cp_valprint (void);
5219370Spst
5398944Sobrienstatic void cp_print_static_field (struct type *, struct value *,
5498944Sobrien				   struct ui_file *, int, int,
5598944Sobrien				   enum val_prettyprint);
5619370Spst
5798944Sobrienstatic void cp_print_value (struct type *, struct type *, char *, int,
5898944Sobrien			    CORE_ADDR, struct ui_file *, int, int,
5998944Sobrien			    enum val_prettyprint, struct type **);
6046283Sdfr
6198944Sobrienstatic void cp_print_hpacc_virtual_table_entries (struct type *, int *,
6298944Sobrien						  struct value *,
6398944Sobrien						  struct ui_file *, int,
6498944Sobrien						  int,
6598944Sobrien						  enum val_prettyprint);
6646283Sdfr
6798944Sobrien
6819370Spstvoid
6998944Sobriencp_print_class_method (char *valaddr,
7098944Sobrien		       struct type *type,
7198944Sobrien		       struct ui_file *stream)
7219370Spst{
7319370Spst  struct type *domain;
7419370Spst  struct fn_field *f = NULL;
7519370Spst  int j = 0;
7619370Spst  int len2;
7719370Spst  int offset;
7819370Spst  char *kind = "";
7919370Spst  CORE_ADDR addr;
8019370Spst  struct symbol *sym;
8119370Spst  unsigned len;
8219370Spst  unsigned int i;
8319370Spst  struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
8419370Spst
8519370Spst  domain = TYPE_DOMAIN_TYPE (target_type);
8698944Sobrien  if (domain == (struct type *) NULL)
8719370Spst    {
8819370Spst      fprintf_filtered (stream, "<unknown>");
8919370Spst      return;
9019370Spst    }
91130803Smarcel  addr = unpack_pointer (type, valaddr);
9219370Spst  if (METHOD_PTR_IS_VIRTUAL (addr))
9319370Spst    {
9419370Spst      offset = METHOD_PTR_TO_VOFFSET (addr);
9519370Spst      len = TYPE_NFN_FIELDS (domain);
9619370Spst      for (i = 0; i < len; i++)
9719370Spst	{
9819370Spst	  f = TYPE_FN_FIELDLIST1 (domain, i);
9919370Spst	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
10098944Sobrien
101130803Smarcel	  check_stub_method_group (domain, i);
10219370Spst	  for (j = 0; j < len2; j++)
10319370Spst	    {
10419370Spst	      if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
10519370Spst		{
10619370Spst		  kind = "virtual ";
10719370Spst		  goto common;
10819370Spst		}
10919370Spst	    }
11019370Spst	}
11119370Spst    }
11219370Spst  else
11319370Spst    {
11419370Spst      sym = find_pc_function (addr);
11519370Spst      if (sym == 0)
11619370Spst	{
11798944Sobrien	  /* 1997-08-01 Currently unsupported with HP aCC */
11898944Sobrien	  if (hp_som_som_object_present)
11998944Sobrien	    {
12098944Sobrien	      fputs_filtered ("?? <not supported with HP aCC>", stream);
12198944Sobrien	      return;
12298944Sobrien	    }
12319370Spst	  error ("invalid pointer to member function");
12419370Spst	}
12519370Spst      len = TYPE_NFN_FIELDS (domain);
12619370Spst      for (i = 0; i < len; i++)
12719370Spst	{
12819370Spst	  f = TYPE_FN_FIELDLIST1 (domain, i);
12919370Spst	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
13098944Sobrien
131130803Smarcel	  check_stub_method_group (domain, i);
13219370Spst	  for (j = 0; j < len2; j++)
13319370Spst	    {
134130803Smarcel	      if (strcmp (DEPRECATED_SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))
135130803Smarcel		  == 0)
136130803Smarcel		goto common;
13719370Spst	    }
13819370Spst	}
13919370Spst    }
14098944Sobrien common:
14119370Spst  if (i < len)
14219370Spst    {
14346283Sdfr      char *demangled_name;
14446283Sdfr
14519370Spst      fprintf_filtered (stream, "&");
146130803Smarcel      fputs_filtered (kind, stream);
14746283Sdfr      demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
14846283Sdfr				       DMGL_ANSI | DMGL_PARAMS);
14946283Sdfr      if (demangled_name == NULL)
15046283Sdfr	fprintf_filtered (stream, "<badly mangled name %s>",
15146283Sdfr			  TYPE_FN_FIELD_PHYSNAME (f, j));
15219370Spst      else
15319370Spst	{
15446283Sdfr	  fputs_filtered (demangled_name, stream);
15598944Sobrien	  xfree (demangled_name);
15619370Spst	}
15719370Spst    }
15819370Spst  else
15919370Spst    {
16019370Spst      fprintf_filtered (stream, "(");
16119370Spst      type_print (type, "", stream, -1);
16219370Spst      fprintf_filtered (stream, ") %d", (int) addr >> 3);
16319370Spst    }
16419370Spst}
16519370Spst
166130803Smarcel/* GCC versions after 2.4.5 use this.  */
16798944Sobrienconst char vtbl_ptr_name[] = "__vtbl_ptr_type";
16819370Spst
169130803Smarcel/* HP aCC uses different names.  */
17098944Sobrienconst char hpacc_vtbl_ptr_name[] = "__vfp";
17198944Sobrienconst char hpacc_vtbl_ptr_type_name[] = "__vftyp";
17246283Sdfr
17319370Spst/* Return truth value for assertion that TYPE is of the type
17419370Spst   "pointer to virtual function".  */
17519370Spst
17619370Spstint
17798944Sobriencp_is_vtbl_ptr_type (struct type *type)
17819370Spst{
17919370Spst  char *typename = type_name_no_tag (type);
18019370Spst
181130803Smarcel  return (typename != NULL && !strcmp (typename, vtbl_ptr_name));
18219370Spst}
18319370Spst
18419370Spst/* Return truth value for the assertion that TYPE is of the type
18519370Spst   "pointer to virtual function table".  */
18619370Spst
18719370Spstint
18898944Sobriencp_is_vtbl_member (struct type *type)
18919370Spst{
190130803Smarcel  /* With older versions of g++, the vtbl field pointed to an array
191130803Smarcel     of structures.  Nowadays it points directly to the structure. */
19219370Spst  if (TYPE_CODE (type) == TYPE_CODE_PTR)
19319370Spst    {
19419370Spst      type = TYPE_TARGET_TYPE (type);
19519370Spst      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
19619370Spst	{
19719370Spst	  type = TYPE_TARGET_TYPE (type);
19898944Sobrien	  if (TYPE_CODE (type) == TYPE_CODE_STRUCT	/* if not using thunks */
19998944Sobrien	      || TYPE_CODE (type) == TYPE_CODE_PTR)	/* if using thunks */
20019370Spst	    {
20119370Spst	      /* Virtual functions tables are full of pointers
20298944Sobrien	         to virtual functions. */
20319370Spst	      return cp_is_vtbl_ptr_type (type);
20419370Spst	    }
20519370Spst	}
206130803Smarcel      else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)  /* if not using thunks */
207130803Smarcel	{
208130803Smarcel	  return cp_is_vtbl_ptr_type (type);
209130803Smarcel	}
210130803Smarcel      else if (TYPE_CODE (type) == TYPE_CODE_PTR)     /* if using thunks */
211130803Smarcel	{
212130803Smarcel	  /* The type name of the thunk pointer is NULL when using dwarf2.
213130803Smarcel	     We could test for a pointer to a function, but there is
214130803Smarcel	     no type info for the virtual table either, so it wont help.  */
215130803Smarcel	  return cp_is_vtbl_ptr_type (type);
216130803Smarcel	}
21719370Spst    }
21819370Spst  return 0;
21919370Spst}
22019370Spst
22119370Spst/* Mutually recursive subroutines of cp_print_value and c_val_print to
22219370Spst   print out a structure's fields: cp_print_value_fields and cp_print_value.
22398944Sobrien
22419370Spst   TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
22519370Spst   same meanings as in cp_print_value and c_val_print.
22619370Spst
22746283Sdfr   2nd argument REAL_TYPE is used to carry over the type of the derived
22846283Sdfr   class across the recursion to base classes.
22946283Sdfr
23019370Spst   DONT_PRINT is an array of baseclass types that we
23119370Spst   should not print, or zero if called from top level.  */
23219370Spst
23319370Spstvoid
23498944Sobriencp_print_value_fields (struct type *type, struct type *real_type, char *valaddr,
23598944Sobrien		       int offset, CORE_ADDR address, struct ui_file *stream,
23698944Sobrien		       int format, int recurse, enum val_prettyprint pretty,
23798944Sobrien		       struct type **dont_print_vb, int dont_print_statmem)
23819370Spst{
23919370Spst  int i, len, n_baseclasses;
24019370Spst  struct obstack tmp_obstack;
24119370Spst  char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
24246283Sdfr  int fields_seen = 0;
24319370Spst
24419370Spst  CHECK_TYPEDEF (type);
24519370Spst
24619370Spst  fprintf_filtered (stream, "{");
24719370Spst  len = TYPE_NFIELDS (type);
24819370Spst  n_baseclasses = TYPE_N_BASECLASSES (type);
24919370Spst
25046283Sdfr  /* First, print out baseclasses such that we don't print
25119370Spst     duplicates of virtual baseclasses.  */
25246283Sdfr
25319370Spst  if (n_baseclasses > 0)
25446283Sdfr    cp_print_value (type, real_type, valaddr, offset, address, stream,
25598944Sobrien		    format, recurse + 1, pretty, dont_print_vb);
25619370Spst
25746283Sdfr  /* Second, print out data fields */
25846283Sdfr
25946283Sdfr  /* If there are no data fields, or if the only field is the
26098944Sobrien   * vtbl pointer, skip this part */
26198944Sobrien  if ((len == n_baseclasses)
26298944Sobrien      || ((len - n_baseclasses == 1)
26398944Sobrien	  && TYPE_HAS_VTABLE (type)
264130803Smarcel	  && strncmp (TYPE_FIELD_NAME (type, n_baseclasses),
265130803Smarcel		      hpacc_vtbl_ptr_name, 5) == 0)
26698944Sobrien      || !len)
26719370Spst    fprintf_filtered (stream, "<No data fields>");
26819370Spst  else
26919370Spst    {
27019370Spst      if (dont_print_statmem == 0)
27119370Spst	{
27219370Spst	  /* If we're at top level, carve out a completely fresh
27319370Spst	     chunk of the obstack and use that until this particular
27419370Spst	     invocation returns.  */
27519370Spst	  tmp_obstack = dont_print_statmem_obstack;
27619370Spst	  obstack_finish (&dont_print_statmem_obstack);
27719370Spst	}
27819370Spst
27919370Spst      for (i = n_baseclasses; i < len; i++)
28019370Spst	{
28119370Spst	  /* If requested, skip printing of static fields.  */
28219370Spst	  if (!static_field_print && TYPE_FIELD_STATIC (type, i))
28319370Spst	    continue;
28446283Sdfr
28598944Sobrien	  /* If a vtable pointer appears, we'll print it out later */
28698944Sobrien	  if (TYPE_HAS_VTABLE (type)
287130803Smarcel	      && strncmp (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name,
288130803Smarcel			  5) == 0)
28998944Sobrien	    continue;
29098944Sobrien
29119370Spst	  if (fields_seen)
29219370Spst	    fprintf_filtered (stream, ", ");
29319370Spst	  else if (n_baseclasses > 0)
29419370Spst	    {
29519370Spst	      if (pretty)
29619370Spst		{
29719370Spst		  fprintf_filtered (stream, "\n");
29819370Spst		  print_spaces_filtered (2 + 2 * recurse, stream);
29919370Spst		  fputs_filtered ("members of ", stream);
30019370Spst		  fputs_filtered (type_name_no_tag (type), stream);
30119370Spst		  fputs_filtered (": ", stream);
30219370Spst		}
30319370Spst	    }
30419370Spst	  fields_seen = 1;
30519370Spst
30619370Spst	  if (pretty)
30719370Spst	    {
30819370Spst	      fprintf_filtered (stream, "\n");
30919370Spst	      print_spaces_filtered (2 + 2 * recurse, stream);
31019370Spst	    }
31198944Sobrien	  else
31219370Spst	    {
31319370Spst	      wrap_here (n_spaces (2 + 2 * recurse));
31419370Spst	    }
31519370Spst	  if (inspect_it)
31619370Spst	    {
31719370Spst	      if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
31819370Spst		fputs_filtered ("\"( ptr \"", stream);
31919370Spst	      else
32019370Spst		fputs_filtered ("\"( nodef \"", stream);
32119370Spst	      if (TYPE_FIELD_STATIC (type, i))
32219370Spst		fputs_filtered ("static ", stream);
32319370Spst	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
32419370Spst				       language_cplus,
32519370Spst				       DMGL_PARAMS | DMGL_ANSI);
32619370Spst	      fputs_filtered ("\" \"", stream);
32719370Spst	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
32819370Spst				       language_cplus,
32919370Spst				       DMGL_PARAMS | DMGL_ANSI);
33019370Spst	      fputs_filtered ("\") \"", stream);
33119370Spst	    }
33219370Spst	  else
33319370Spst	    {
33419370Spst	      annotate_field_begin (TYPE_FIELD_TYPE (type, i));
33519370Spst
33619370Spst	      if (TYPE_FIELD_STATIC (type, i))
33719370Spst		fputs_filtered ("static ", stream);
33819370Spst	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
33919370Spst				       language_cplus,
34019370Spst				       DMGL_PARAMS | DMGL_ANSI);
34119370Spst	      annotate_field_name_end ();
34246283Sdfr	      /* do not print leading '=' in case of anonymous unions */
34346283Sdfr	      if (strcmp (TYPE_FIELD_NAME (type, i), ""))
34446283Sdfr		fputs_filtered (" = ", stream);
34519370Spst	      annotate_field_value ();
34619370Spst	    }
34719370Spst
34819370Spst	  if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
34919370Spst	    {
35098944Sobrien	      struct value *v;
35119370Spst
35219370Spst	      /* Bitfields require special handling, especially due to byte
35398944Sobrien	         order problems.  */
35419370Spst	      if (TYPE_FIELD_IGNORE (type, i))
35519370Spst		{
35698944Sobrien		  fputs_filtered ("<optimized out or zero length>", stream);
35719370Spst		}
35819370Spst	      else
35919370Spst		{
36098944Sobrien		  v = value_from_longest
36198944Sobrien		    (TYPE_FIELD_TYPE (type, i),
36298944Sobrien		     unpack_field_as_long (type, valaddr + offset, i));
36319370Spst
364242936Semaste		  common_val_print (v, stream, format, 0, recurse + 1, pretty);
36519370Spst		}
36619370Spst	    }
36719370Spst	  else
36819370Spst	    {
36919370Spst	      if (TYPE_FIELD_IGNORE (type, i))
37019370Spst		{
37198944Sobrien		  fputs_filtered ("<optimized out or zero length>", stream);
37219370Spst		}
37319370Spst	      else if (TYPE_FIELD_STATIC (type, i))
37419370Spst		{
37598944Sobrien		  struct value *v = value_static_field (type, i);
37646283Sdfr		  if (v == NULL)
37719370Spst		    fputs_filtered ("<optimized out>", stream);
37819370Spst		  else
37946283Sdfr		    cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
38046283Sdfr					   stream, format, recurse + 1,
38146283Sdfr					   pretty);
38219370Spst		}
38319370Spst	      else
38419370Spst		{
38598944Sobrien		  val_print (TYPE_FIELD_TYPE (type, i),
38698944Sobrien			     valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
38798944Sobrien			     address + TYPE_FIELD_BITPOS (type, i) / 8,
38898944Sobrien			     stream, format, 0, recurse + 1, pretty);
38919370Spst		}
39019370Spst	    }
39119370Spst	  annotate_field_end ();
39219370Spst	}
39319370Spst
39419370Spst      if (dont_print_statmem == 0)
39519370Spst	{
39619370Spst	  /* Free the space used to deal with the printing
39719370Spst	     of the members from top level.  */
39819370Spst	  obstack_free (&dont_print_statmem_obstack, last_dont_print);
39919370Spst	  dont_print_statmem_obstack = tmp_obstack;
40019370Spst	}
40119370Spst
40219370Spst      if (pretty)
40319370Spst	{
40419370Spst	  fprintf_filtered (stream, "\n");
40519370Spst	  print_spaces_filtered (2 * recurse, stream);
40619370Spst	}
40798944Sobrien    }				/* if there are data fields */
40898944Sobrien  /* Now print out the virtual table pointer if there is one */
40998944Sobrien  if (TYPE_HAS_VTABLE (type)
410130803Smarcel      && strncmp (TYPE_FIELD_NAME (type, n_baseclasses),
411130803Smarcel		  hpacc_vtbl_ptr_name, 5) == 0)
41246283Sdfr    {
41398944Sobrien      struct value *v;
41498944Sobrien      /* First get the virtual table pointer and print it out */
41546283Sdfr
41646283Sdfr#if 0
41746283Sdfr      fputs_filtered ("__vfp = ", stream);
41846283Sdfr#endif
41946283Sdfr
42046283Sdfr      fputs_filtered (", Virtual table at ", stream);
42146283Sdfr
42246283Sdfr      /* pai: FIXME 32x64 problem? */
42346283Sdfr      /* Not sure what the best notation is in the case where there is no
42446283Sdfr         baseclass name.  */
42598944Sobrien      v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
42698944Sobrien			      *(unsigned long *) (valaddr + offset));
42746283Sdfr
428242936Semaste      common_val_print (v, stream, format, 0, recurse + 1, pretty);
42946283Sdfr      fields_seen = 1;
43046283Sdfr
43146283Sdfr      if (vtblprint)
43298944Sobrien	{
43398944Sobrien	  /* Print out function pointers in vtable. */
43446283Sdfr
43598944Sobrien	  /* FIXME: then-clause is for non-RRBC layout of virtual
43698944Sobrien	   * table.  The RRBC case in the else-clause is yet to be
43798944Sobrien	   * implemented.  The if (1) below should be changed to a
43898944Sobrien	   * test for whether the executable we have was compiled
43998944Sobrien	   * with a version of HP aCC that doesn't have RRBC
44098944Sobrien	   * support. */
44146283Sdfr
44298944Sobrien	  if (1)
44398944Sobrien	    {
44498944Sobrien	      /* no RRBC support; function pointers embedded directly
44598944Sobrien                 in vtable */
44646283Sdfr
44798944Sobrien	      int vfuncs = count_virtual_fns (real_type);
44846283Sdfr
44998944Sobrien	      fputs_filtered (" {", stream);
45046283Sdfr
45198944Sobrien	      /* FIXME : doesn't work at present */
45246283Sdfr#if 0
45398944Sobrien	      fprintf_filtered (stream, "%d entr%s: ", vfuncs,
45498944Sobrien				vfuncs == 1 ? "y" : "ies");
45546283Sdfr#else
45698944Sobrien	      fputs_filtered ("not implemented", stream);
45746283Sdfr
45846283Sdfr
45946283Sdfr#endif
46046283Sdfr
46198944Sobrien	      /* recursive function that prints all virtual function entries */
46246283Sdfr#if 0
46398944Sobrien	      cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v,
46498944Sobrien						    stream, format, recurse,
46598944Sobrien						    pretty);
46646283Sdfr#endif
46798944Sobrien	      fputs_filtered ("}", stream);
46898944Sobrien	    }			/* non-RRBC case */
46998944Sobrien	  else
47098944Sobrien	    {
47198944Sobrien	      /* FIXME -- see comments above */
47298944Sobrien	      /* RRBC support present; function pointers are found
47398944Sobrien	       * by indirection through the class segment entries. */
47446283Sdfr
47546283Sdfr
47698944Sobrien	    }			/* RRBC case */
47798944Sobrien	}			/* if vtblprint */
47898944Sobrien
47946283Sdfr      if (pretty)
48046283Sdfr	{
48146283Sdfr	  fprintf_filtered (stream, "\n");
48246283Sdfr	  print_spaces_filtered (2 * recurse, stream);
48346283Sdfr	}
48446283Sdfr
48598944Sobrien    }				/* if vtable exists */
48698944Sobrien
48719370Spst  fprintf_filtered (stream, "}");
48819370Spst}
48919370Spst
49019370Spst/* Special val_print routine to avoid printing multiple copies of virtual
49119370Spst   baseclasses.  */
49219370Spst
49319370Spststatic void
49498944Sobriencp_print_value (struct type *type, struct type *real_type, char *valaddr,
49598944Sobrien		int offset, CORE_ADDR address, struct ui_file *stream,
49698944Sobrien		int format, int recurse, enum val_prettyprint pretty,
49798944Sobrien		struct type **dont_print_vb)
49819370Spst{
49919370Spst  struct obstack tmp_obstack;
50019370Spst  struct type **last_dont_print
50198944Sobrien    = (struct type **) obstack_next_free (&dont_print_vb_obstack);
50219370Spst  int i, n_baseclasses = TYPE_N_BASECLASSES (type);
50398944Sobrien  int thisoffset;
50498944Sobrien  struct type *thistype;
50519370Spst
50619370Spst  if (dont_print_vb == 0)
50719370Spst    {
50819370Spst      /* If we're at top level, carve out a completely fresh
50998944Sobrien         chunk of the obstack and use that until this particular
51098944Sobrien         invocation returns.  */
51119370Spst      tmp_obstack = dont_print_vb_obstack;
51219370Spst      /* Bump up the high-water mark.  Now alpha is omega.  */
51319370Spst      obstack_finish (&dont_print_vb_obstack);
51419370Spst    }
51519370Spst
51619370Spst  for (i = 0; i < n_baseclasses; i++)
51719370Spst    {
51819370Spst      int boffset;
51946283Sdfr      int skip;
52019370Spst      struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
52119370Spst      char *basename = TYPE_NAME (baseclass);
52246283Sdfr      char *base_valaddr;
52319370Spst
52419370Spst      if (BASETYPE_VIA_VIRTUAL (type, i))
52519370Spst	{
52619370Spst	  struct type **first_dont_print
52798944Sobrien	    = (struct type **) obstack_base (&dont_print_vb_obstack);
52819370Spst
52998944Sobrien	  int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
53019370Spst	    - first_dont_print;
53119370Spst
53219370Spst	  while (--j >= 0)
53319370Spst	    if (baseclass == first_dont_print[j])
53419370Spst	      goto flush_it;
53519370Spst
53619370Spst	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
53719370Spst	}
53819370Spst
53998944Sobrien      thisoffset = offset;
54098944Sobrien      thistype = real_type;
54146283Sdfr      if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i))
54298944Sobrien	{
54398944Sobrien	  /* Assume HP/Taligent runtime convention */
54498944Sobrien	  find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
54598944Sobrien				valaddr, offset, &boffset, &skip);
54698944Sobrien	  if (skip >= 0)
54798944Sobrien	    error ("Virtual base class offset not found from vtable while"
54898944Sobrien		   " printing");
54998944Sobrien	  base_valaddr = valaddr;
55098944Sobrien	}
55146283Sdfr      else
55298944Sobrien	{
55398944Sobrien	  boffset = baseclass_offset (type, i,
55498944Sobrien				      valaddr + offset,
555130803Smarcel				      address);
55698944Sobrien	  skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
55719370Spst
55898944Sobrien	  if (BASETYPE_VIA_VIRTUAL (type, i))
55998944Sobrien	    {
56098944Sobrien	      /* The virtual base class pointer might have been
56198944Sobrien	         clobbered by the user program. Make sure that it
56298944Sobrien	         still points to a valid memory location.  */
56346283Sdfr
56498944Sobrien	      if (boffset != -1
56598944Sobrien		  && ((boffset + offset) < 0
56698944Sobrien		      || (boffset + offset) >= TYPE_LENGTH (type)))
56798944Sobrien		{
56898944Sobrien		  /* FIXME (alloca): unsafe if baseclass is really really large. */
56998944Sobrien		  base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
570130803Smarcel		  if (target_read_memory (address + boffset, base_valaddr,
57198944Sobrien					  TYPE_LENGTH (baseclass)) != 0)
57298944Sobrien		    skip = 1;
573130803Smarcel		  address = address + boffset;
57498944Sobrien		  thisoffset = 0;
57598944Sobrien		  boffset = 0;
57698944Sobrien		  thistype = baseclass;
57798944Sobrien		}
57898944Sobrien	      else
57998944Sobrien		base_valaddr = valaddr;
58098944Sobrien	    }
58198944Sobrien	  else
58298944Sobrien	    base_valaddr = valaddr;
58346283Sdfr	}
58446283Sdfr
58546283Sdfr      /* now do the printing */
58619370Spst      if (pretty)
58719370Spst	{
58819370Spst	  fprintf_filtered (stream, "\n");
58919370Spst	  print_spaces_filtered (2 * recurse, stream);
59019370Spst	}
59119370Spst      fputs_filtered ("<", stream);
59219370Spst      /* Not sure what the best notation is in the case where there is no
59398944Sobrien         baseclass name.  */
59419370Spst      fputs_filtered (basename ? basename : "", stream);
59519370Spst      fputs_filtered ("> = ", stream);
59646283Sdfr
59746283Sdfr
59846283Sdfr      if (skip >= 1)
59919370Spst	fprintf_filtered (stream, "<invalid address>");
60019370Spst      else
60198944Sobrien	cp_print_value_fields (baseclass, thistype, base_valaddr,
602130803Smarcel			       thisoffset + boffset, address + boffset,
603130803Smarcel			       stream, format,
60498944Sobrien			       recurse, pretty,
60598944Sobrien			       ((struct type **)
60698944Sobrien				obstack_base (&dont_print_vb_obstack)),
60719370Spst			       0);
60819370Spst      fputs_filtered (", ", stream);
60919370Spst
61019370Spst    flush_it:
61119370Spst      ;
61219370Spst    }
61319370Spst
61419370Spst  if (dont_print_vb == 0)
61519370Spst    {
61619370Spst      /* Free the space used to deal with the printing
61798944Sobrien         of this type from top level.  */
61819370Spst      obstack_free (&dont_print_vb_obstack, last_dont_print);
61919370Spst      /* Reset watermark so that we can continue protecting
62098944Sobrien         ourselves from whatever we were protecting ourselves.  */
62119370Spst      dont_print_vb_obstack = tmp_obstack;
62219370Spst    }
62319370Spst}
62419370Spst
62519370Spst/* Print value of a static member.
62619370Spst   To avoid infinite recursion when printing a class that contains
62719370Spst   a static instance of the class, we keep the addresses of all printed
62819370Spst   static member classes in an obstack and refuse to print them more
62919370Spst   than once.
63019370Spst
63119370Spst   VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
63219370Spst   have the same meanings as in c_val_print.  */
63319370Spst
63419370Spststatic void
63598944Sobriencp_print_static_field (struct type *type,
63698944Sobrien		       struct value *val,
63798944Sobrien		       struct ui_file *stream,
63898944Sobrien		       int format,
63998944Sobrien		       int recurse,
64098944Sobrien		       enum val_prettyprint pretty)
64119370Spst{
64219370Spst  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
64319370Spst    {
64419370Spst      CORE_ADDR *first_dont_print;
64519370Spst      int i;
64619370Spst
64719370Spst      first_dont_print
64898944Sobrien	= (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
64998944Sobrien      i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
65019370Spst	- first_dont_print;
65119370Spst
65219370Spst      while (--i >= 0)
65319370Spst	{
65419370Spst	  if (VALUE_ADDRESS (val) == first_dont_print[i])
65519370Spst	    {
65698944Sobrien	      fputs_filtered ("<same as static member of an already"
65798944Sobrien			      " seen type>",
65819370Spst			      stream);
65919370Spst	      return;
66019370Spst	    }
66119370Spst	}
66219370Spst
66319370Spst      obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
66419370Spst		    sizeof (CORE_ADDR));
66519370Spst
66619370Spst      CHECK_TYPEDEF (type);
66798944Sobrien      cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val),
66898944Sobrien			     VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
66919370Spst			     stream, format, recurse, pretty, NULL, 1);
67019370Spst      return;
67119370Spst    }
67298944Sobrien  val_print (type, VALUE_CONTENTS_ALL (val),
67398944Sobrien	     VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
67419370Spst	     stream, format, 0, recurse, pretty);
67519370Spst}
67619370Spst
67719370Spstvoid
67898944Sobriencp_print_class_member (char *valaddr, struct type *domain,
67998944Sobrien		       struct ui_file *stream, char *prefix)
68019370Spst{
68198944Sobrien
68219370Spst  /* VAL is a byte offset into the structure type DOMAIN.
68319370Spst     Find the name of the field for that offset and
68419370Spst     print it.  */
68519370Spst  int extra = 0;
68619370Spst  int bits = 0;
687130803Smarcel  unsigned int i;
68819370Spst  unsigned len = TYPE_NFIELDS (domain);
68946283Sdfr
69019370Spst  /* @@ Make VAL into bit offset */
69146283Sdfr
69246283Sdfr  /* Note: HP aCC generates offsets that are the real byte offsets added
69346283Sdfr     to a constant bias 0x20000000 (1 << 29).  This constant bias gets
69446283Sdfr     shifted out in the code below -- joyous happenstance! */
69546283Sdfr
69646283Sdfr  /* Note: HP cfront uses a constant bias of 1; if we support this
69798944Sobrien     compiler ever, we will have to adjust the computation below */
69898944Sobrien
69919370Spst  LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
70019370Spst  for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
70119370Spst    {
70219370Spst      int bitpos = TYPE_FIELD_BITPOS (domain, i);
70319370Spst      QUIT;
70419370Spst      if (val == bitpos)
70519370Spst	break;
70619370Spst      if (val < bitpos && i != 0)
70719370Spst	{
70819370Spst	  /* Somehow pointing into a field.  */
70919370Spst	  i -= 1;
71019370Spst	  extra = (val - TYPE_FIELD_BITPOS (domain, i));
71119370Spst	  if (extra & 0x7)
71219370Spst	    bits = 1;
71319370Spst	  else
71419370Spst	    extra >>= 3;
71519370Spst	  break;
71619370Spst	}
71719370Spst    }
71819370Spst  if (i < len)
71919370Spst    {
72019370Spst      char *name;
721130803Smarcel      fputs_filtered (prefix, stream);
72219370Spst      name = type_name_no_tag (domain);
72319370Spst      if (name)
72498944Sobrien	fputs_filtered (name, stream);
72519370Spst      else
72619370Spst	c_type_print_base (domain, stream, 0, 0);
72719370Spst      fprintf_filtered (stream, "::");
72819370Spst      fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
72919370Spst      if (extra)
73019370Spst	fprintf_filtered (stream, " + %d bytes", extra);
73119370Spst      if (bits)
73219370Spst	fprintf_filtered (stream, " (offset in bits)");
73319370Spst    }
73419370Spst  else
73598944Sobrien    fprintf_filtered (stream, "%ld", (long) (val >> 3));
73619370Spst}
73719370Spst
73846283Sdfr
73946283Sdfr/* This function prints out virtual table entries for a class; it
74046283Sdfr * recurses on the base classes to find all virtual functions
74146283Sdfr * available in a class.
74246283Sdfr *
74346283Sdfr * pai/1997-05-21 Note: As the name suggests, it's currently
74446283Sdfr * implemented for HP aCC runtime only. g++ objects are handled
74546283Sdfr * differently and I have made no attempt to fold that logic in
74646283Sdfr * here. The runtime layout is different for the two cases.  Also,
74746283Sdfr * this currently has only the code for non-RRBC layouts generated by
74846283Sdfr * the HP aCC compiler; RRBC code is stubbed out and will have to be
74946283Sdfr * added later. */
75046283Sdfr
75198944Sobrien
75246283Sdfrstatic void
75398944Sobriencp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs,
75498944Sobrien				      struct value *v, struct ui_file *stream,
75598944Sobrien				      int format, int recurse,
75698944Sobrien				      enum val_prettyprint pretty)
75746283Sdfr{
75846283Sdfr  int fn, oi;
75946283Sdfr
76046283Sdfr  /* pai: FIXME this function doesn't work. It should handle a given
76146283Sdfr   * virtual function only once (latest redefinition in class hierarchy)
76246283Sdfr   */
76346283Sdfr
76498944Sobrien  /* Recursion on other classes that can share the same vtable */
76598944Sobrien  struct type *pbc = primary_base_class (type);
76646283Sdfr  if (pbc)
76798944Sobrien    cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format,
76898944Sobrien					  recurse, pretty);
76998944Sobrien
77046283Sdfr  /* Now deal with vfuncs declared in this class */
77146283Sdfr  for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++)
77246283Sdfr    for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++)
77346283Sdfr      if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi))
77498944Sobrien	{
77598944Sobrien	  char *vf_name;
77698944Sobrien	  const char *field_physname;
77746283Sdfr
77898944Sobrien	  /* virtual function offset */
77998944Sobrien	  int vx = (TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi)
78098944Sobrien		    - 1);
78146283Sdfr
78298944Sobrien	  /* Get the address of the vfunction entry */
78398944Sobrien	  struct value *vf = value_copy (v);
78498944Sobrien	  if (VALUE_LAZY (vf))
78598944Sobrien	    (void) value_fetch_lazy (vf);
78698944Sobrien	  /* adjust by offset */
78798944Sobrien	  vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx);
78898944Sobrien	  vf = value_ind (vf);	/* get the entry */
78998944Sobrien	  VALUE_TYPE (vf) = VALUE_TYPE (v);	/* make it a pointer */
79046283Sdfr
79198944Sobrien	  /* print out the entry */
792242936Semaste	  common_val_print (vf, stream, format, 0, recurse + 1, pretty);
79398944Sobrien	  field_physname
79498944Sobrien	    = TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi);
79598944Sobrien	  /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
79698944Sobrien	  vf_name = cplus_demangle (field_physname, DMGL_ARM);
79798944Sobrien	  fprintf_filtered (stream, " %s", vf_name);
79898944Sobrien	  if (--(*vfuncs) > 0)
79998944Sobrien	    fputs_filtered (", ", stream);
80098944Sobrien	}
80146283Sdfr}
80246283Sdfr
80346283Sdfr
80446283Sdfr
80519370Spstvoid
80698944Sobrien_initialize_cp_valprint (void)
80719370Spst{
80819370Spst  add_show_from_set
80919370Spst    (add_set_cmd ("static-members", class_support, var_boolean,
81098944Sobrien		  (char *) &static_field_print,
81119370Spst		  "Set printing of C++ static members.",
81219370Spst		  &setprintlist),
81319370Spst     &showprintlist);
81419370Spst  /* Turn on printing of static fields.  */
81519370Spst  static_field_print = 1;
81619370Spst
81719370Spst  add_show_from_set
81898944Sobrien    (add_set_cmd ("vtbl", class_support, var_boolean, (char *) &vtblprint,
81919370Spst		  "Set printing of C++ virtual function tables.",
82019370Spst		  &setprintlist),
82119370Spst     &showprintlist);
82219370Spst
82319370Spst  add_show_from_set
82498944Sobrien    (add_set_cmd ("object", class_support, var_boolean, (char *) &objectprint,
82598944Sobrien	      "Set printing of object's derived type based on vtable info.",
82619370Spst		  &setprintlist),
82719370Spst     &showprintlist);
82819370Spst
82919370Spst  /* Give people the defaults which they are used to.  */
83019370Spst  objectprint = 0;
83119370Spst  vtblprint = 0;
83219370Spst  obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *));
83319370Spst  obstack_specify_allocation (&dont_print_statmem_obstack,
83419370Spst			      32 * sizeof (CORE_ADDR), sizeof (CORE_ADDR),
83598944Sobrien			      xmalloc, xfree);
83619370Spst}
837