Replace free() with xfree().
[platform/upstream/binutils.git] / gdb / cp-valprint.c
1 /* Support for printing C++ values for GDB, the GNU debugger.
2    Copyright 1986, 1988, 1989, 1991, 1994-1996, 2000
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "obstack.h"
24 #include "symtab.h"
25 #include "gdbtypes.h"
26 #include "expression.h"
27 #include "value.h"
28 #include "command.h"
29 #include "gdbcmd.h"
30 #include "demangle.h"
31 #include "annotate.h"
32 #include "gdb_string.h"
33 #include "c-lang.h"
34 #include "target.h"
35
36 /* Indication of presence of HP-compiled object files */
37 extern int hp_som_som_object_present;   /* defined in symtab.c */
38
39
40 int vtblprint;                  /* Controls printing of vtbl's */
41 int objectprint;                /* Controls looking up an object's derived type
42                                    using what we find in its vtables.  */
43 int static_field_print;         /* Controls printing of static fields. */
44
45 static struct obstack dont_print_vb_obstack;
46 static struct obstack dont_print_statmem_obstack;
47
48 extern void _initialize_cp_valprint (void);
49
50 static void cp_print_static_field (struct type *, value_ptr,
51                                    struct ui_file *, int, int,
52                                    enum val_prettyprint);
53
54 static void cp_print_value (struct type *, struct type *, char *, int,
55                             CORE_ADDR, struct ui_file *, int, int,
56                             enum val_prettyprint, struct type **);
57
58 static void cp_print_hpacc_virtual_table_entries (struct type *, int *,
59                                                   value_ptr,
60                                                   struct ui_file *, int,
61                                                   int,
62                                                   enum val_prettyprint);
63
64
65 void
66 cp_print_class_method (char *valaddr, struct type *type, struct ui_file *stream)
67 {
68   struct type *domain;
69   struct fn_field *f = NULL;
70   int j = 0;
71   int len2;
72   int offset;
73   char *kind = "";
74   CORE_ADDR addr;
75   struct symbol *sym;
76   unsigned len;
77   unsigned int i;
78   struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
79
80   domain = TYPE_DOMAIN_TYPE (target_type);
81   if (domain == (struct type *) NULL)
82     {
83       fprintf_filtered (stream, "<unknown>");
84       return;
85     }
86   addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
87   if (METHOD_PTR_IS_VIRTUAL (addr))
88     {
89       offset = METHOD_PTR_TO_VOFFSET (addr);
90       len = TYPE_NFN_FIELDS (domain);
91       for (i = 0; i < len; i++)
92         {
93           f = TYPE_FN_FIELDLIST1 (domain, i);
94           len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
95
96           for (j = 0; j < len2; j++)
97             {
98               QUIT;
99               if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
100                 {
101                   if (TYPE_FN_FIELD_STUB (f, j))
102                     check_stub_method (domain, i, j);
103                   kind = "virtual ";
104                   goto common;
105                 }
106             }
107         }
108     }
109   else
110     {
111       sym = find_pc_function (addr);
112       if (sym == 0)
113         {
114           /* 1997-08-01 Currently unsupported with HP aCC */
115           if (hp_som_som_object_present)
116             {
117               fputs_filtered ("?? <not supported with HP aCC>", stream);
118               return;
119             }
120           error ("invalid pointer to member function");
121         }
122       len = TYPE_NFN_FIELDS (domain);
123       for (i = 0; i < len; i++)
124         {
125           f = TYPE_FN_FIELDLIST1 (domain, i);
126           len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
127
128           for (j = 0; j < len2; j++)
129             {
130               QUIT;
131               if (TYPE_FN_FIELD_STUB (f, j))
132                 check_stub_method (domain, i, j);
133               if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
134                 {
135                   goto common;
136                 }
137             }
138         }
139     }
140 common:
141   if (i < len)
142     {
143       char *demangled_name;
144
145       fprintf_filtered (stream, "&");
146       fprintf_filtered (stream, kind);
147       demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
148                                        DMGL_ANSI | DMGL_PARAMS);
149       if (demangled_name == NULL)
150         fprintf_filtered (stream, "<badly mangled name %s>",
151                           TYPE_FN_FIELD_PHYSNAME (f, j));
152       else
153         {
154           fputs_filtered (demangled_name, stream);
155           xfree (demangled_name);
156         }
157     }
158   else
159     {
160       fprintf_filtered (stream, "(");
161       type_print (type, "", stream, -1);
162       fprintf_filtered (stream, ") %d", (int) addr >> 3);
163     }
164 }
165
166 /* This was what it was for gcc 2.4.5 and earlier.  */
167 static const char vtbl_ptr_name_old[] =
168 {CPLUS_MARKER, 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0};
169 /* It was changed to this after 2.4.5.  */
170 const char vtbl_ptr_name[] =
171 {'_', '_', 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0};
172
173 /* HP aCC uses different names */
174 const char hpacc_vtbl_ptr_name[] =
175 {'_', '_', 'v', 'f', 'p', 0};
176 const char hpacc_vtbl_ptr_type_name[] =
177 {'_', '_', 'v', 'f', 't', 'y', 'p', 0};
178
179
180 /* Return truth value for assertion that TYPE is of the type
181    "pointer to virtual function".  */
182
183 int
184 cp_is_vtbl_ptr_type (struct type *type)
185 {
186   char *typename = type_name_no_tag (type);
187
188   return (typename != NULL
189           && (STREQ (typename, vtbl_ptr_name)
190               || STREQ (typename, vtbl_ptr_name_old)));
191 }
192
193 /* Return truth value for the assertion that TYPE is of the type
194    "pointer to virtual function table".  */
195
196 int
197 cp_is_vtbl_member (struct type *type)
198 {
199   if (TYPE_CODE (type) == TYPE_CODE_PTR)
200     {
201       type = TYPE_TARGET_TYPE (type);
202       if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
203         {
204           type = TYPE_TARGET_TYPE (type);
205           if (TYPE_CODE (type) == TYPE_CODE_STRUCT      /* if not using thunks */
206               || TYPE_CODE (type) == TYPE_CODE_PTR)     /* if using thunks */
207             {
208               /* Virtual functions tables are full of pointers
209                  to virtual functions. */
210               return cp_is_vtbl_ptr_type (type);
211             }
212         }
213     }
214   return 0;
215 }
216
217 /* Mutually recursive subroutines of cp_print_value and c_val_print to
218    print out a structure's fields: cp_print_value_fields and cp_print_value.
219
220    TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
221    same meanings as in cp_print_value and c_val_print.
222
223    2nd argument REAL_TYPE is used to carry over the type of the derived
224    class across the recursion to base classes. 
225
226    DONT_PRINT is an array of baseclass types that we
227    should not print, or zero if called from top level.  */
228
229 void
230 cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr,
231                        int offset, CORE_ADDR address, struct ui_file *stream,
232                        int format, int recurse, enum val_prettyprint pretty,
233                        struct type **dont_print_vb, int dont_print_statmem)
234 {
235   int i, len, n_baseclasses;
236   struct obstack tmp_obstack;
237   char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
238   int fields_seen = 0;
239
240   CHECK_TYPEDEF (type);
241
242   fprintf_filtered (stream, "{");
243   len = TYPE_NFIELDS (type);
244   n_baseclasses = TYPE_N_BASECLASSES (type);
245
246   /* First, print out baseclasses such that we don't print
247      duplicates of virtual baseclasses.  */
248
249   if (n_baseclasses > 0)
250     cp_print_value (type, real_type, valaddr, offset, address, stream,
251                     format, recurse + 1, pretty, dont_print_vb);
252
253   /* Second, print out data fields */
254
255   /* If there are no data fields, or if the only field is the
256    * vtbl pointer, skip this part */
257   if ((len == n_baseclasses) ||
258       ((len - n_baseclasses == 1) &&
259        TYPE_HAS_VTABLE (type) &&
260   STREQN (TYPE_FIELD_NAME (type, n_baseclasses), hpacc_vtbl_ptr_name, 5)) ||
261       !len)
262     fprintf_filtered (stream, "<No data fields>");
263   else
264     {
265       extern int inspect_it;
266
267       if (dont_print_statmem == 0)
268         {
269           /* If we're at top level, carve out a completely fresh
270              chunk of the obstack and use that until this particular
271              invocation returns.  */
272           tmp_obstack = dont_print_statmem_obstack;
273           obstack_finish (&dont_print_statmem_obstack);
274         }
275
276       for (i = n_baseclasses; i < len; i++)
277         {
278           /* If requested, skip printing of static fields.  */
279           if (!static_field_print && TYPE_FIELD_STATIC (type, i))
280             continue;
281
282           /* If a vtable pointer appears, we'll print it out later */
283           if (TYPE_HAS_VTABLE (type) && STREQN (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5))
284             continue;
285
286           if (fields_seen)
287             fprintf_filtered (stream, ", ");
288           else if (n_baseclasses > 0)
289             {
290               if (pretty)
291                 {
292                   fprintf_filtered (stream, "\n");
293                   print_spaces_filtered (2 + 2 * recurse, stream);
294                   fputs_filtered ("members of ", stream);
295                   fputs_filtered (type_name_no_tag (type), stream);
296                   fputs_filtered (": ", stream);
297                 }
298             }
299           fields_seen = 1;
300
301           if (pretty)
302             {
303               fprintf_filtered (stream, "\n");
304               print_spaces_filtered (2 + 2 * recurse, stream);
305             }
306           else
307             {
308               wrap_here (n_spaces (2 + 2 * recurse));
309             }
310           if (inspect_it)
311             {
312               if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
313                 fputs_filtered ("\"( ptr \"", stream);
314               else
315                 fputs_filtered ("\"( nodef \"", stream);
316               if (TYPE_FIELD_STATIC (type, i))
317                 fputs_filtered ("static ", stream);
318               fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
319                                        language_cplus,
320                                        DMGL_PARAMS | DMGL_ANSI);
321               fputs_filtered ("\" \"", stream);
322               fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
323                                        language_cplus,
324                                        DMGL_PARAMS | DMGL_ANSI);
325               fputs_filtered ("\") \"", stream);
326             }
327           else
328             {
329               annotate_field_begin (TYPE_FIELD_TYPE (type, i));
330
331               if (TYPE_FIELD_STATIC (type, i))
332                 fputs_filtered ("static ", stream);
333               fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
334                                        language_cplus,
335                                        DMGL_PARAMS | DMGL_ANSI);
336               annotate_field_name_end ();
337               /* do not print leading '=' in case of anonymous unions */
338               if (strcmp (TYPE_FIELD_NAME (type, i), ""))
339                 fputs_filtered (" = ", stream);
340               annotate_field_value ();
341             }
342
343           if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
344             {
345               value_ptr v;
346
347               /* Bitfields require special handling, especially due to byte
348                  order problems.  */
349               if (TYPE_FIELD_IGNORE (type, i))
350                 {
351                   fputs_filtered ("<optimized out or zero length>", stream);
352                 }
353               else
354                 {
355                   v = value_from_longest (TYPE_FIELD_TYPE (type, i),
356                           unpack_field_as_long (type, valaddr + offset, i));
357
358                   val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
359                              stream, format, 0, recurse + 1, pretty);
360                 }
361             }
362           else
363             {
364               if (TYPE_FIELD_IGNORE (type, i))
365                 {
366                   fputs_filtered ("<optimized out or zero length>", stream);
367                 }
368               else if (TYPE_FIELD_STATIC (type, i))
369                 {
370                   value_ptr v = value_static_field (type, i);
371                   if (v == NULL)
372                     fputs_filtered ("<optimized out>", stream);
373                   else
374                     cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
375                                            stream, format, recurse + 1,
376                                            pretty);
377                 }
378               else
379                 {
380                   val_print (TYPE_FIELD_TYPE (type, i),
381                           valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
382                              address + TYPE_FIELD_BITPOS (type, i) / 8,
383                              stream, format, 0, recurse + 1, pretty);
384                 }
385             }
386           annotate_field_end ();
387         }
388
389       if (dont_print_statmem == 0)
390         {
391           /* Free the space used to deal with the printing
392              of the members from top level.  */
393           obstack_free (&dont_print_statmem_obstack, last_dont_print);
394           dont_print_statmem_obstack = tmp_obstack;
395         }
396
397       if (pretty)
398         {
399           fprintf_filtered (stream, "\n");
400           print_spaces_filtered (2 * recurse, stream);
401         }
402     }                           /* if there are data fields */
403   /* Now print out the virtual table pointer if there is one */
404   if (TYPE_HAS_VTABLE (type) && STREQN (TYPE_FIELD_NAME (type, n_baseclasses), hpacc_vtbl_ptr_name, 5))
405     {
406       value_ptr v;
407       /* First get the virtual table pointer and print it out */
408
409 #if 0
410       fputs_filtered ("__vfp = ", stream);
411 #endif
412
413       fputs_filtered (", Virtual table at ", stream);
414
415       /* pai: FIXME 32x64 problem? */
416       /* Not sure what the best notation is in the case where there is no
417          baseclass name.  */
418       v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
419                               *(unsigned long *) (valaddr + offset));
420
421       val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
422                  stream, format, 0, recurse + 1, pretty);
423       fields_seen = 1;
424
425       if (vtblprint)
426         {
427           /* Print out function pointers in vtable. */
428
429           /* FIXME: then-clause is for non-RRBC layout of virtual
430            * table.  The RRBC case in the else-clause is yet to be
431            * implemented.  The if (1) below should be changed to a
432            * test for whether the executable we have was compiled
433            * with a version of HP aCC that doesn't have RRBC
434            * support. */
435
436           if (1)
437             {
438               /* no RRBC support; function pointers embedded directly in vtable */
439
440               int vfuncs = count_virtual_fns (real_type);
441
442               fputs_filtered (" {", stream);
443
444               /* FIXME : doesn't work at present */
445 #if 0
446               fprintf_filtered (stream, "%d entr%s: ", vfuncs, vfuncs == 1 ? "y" : "ies");
447 #else
448               fputs_filtered ("not implemented", stream);
449
450
451 #endif
452
453               /* recursive function that prints all virtual function entries */
454 #if 0
455               cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v, stream, format, recurse, pretty);
456 #endif
457               fputs_filtered ("}", stream);
458             }                   /* non-RRBC case */
459           else
460             {
461               /* FIXME -- see comments above */
462               /* RRBC support present; function pointers are found
463                * by indirection through the class segment entries. */
464
465
466             }                   /* RRBC case */
467         }                       /* if vtblprint */
468
469       if (pretty)
470         {
471           fprintf_filtered (stream, "\n");
472           print_spaces_filtered (2 * recurse, stream);
473         }
474
475     }                           /* if vtable exists */
476
477   fprintf_filtered (stream, "}");
478 }
479
480 /* Special val_print routine to avoid printing multiple copies of virtual
481    baseclasses.  */
482
483 static void
484 cp_print_value (struct type *type, struct type *real_type, char *valaddr,
485                 int offset, CORE_ADDR address, struct ui_file *stream,
486                 int format, int recurse, enum val_prettyprint pretty,
487                 struct type **dont_print_vb)
488 {
489   struct obstack tmp_obstack;
490   struct type **last_dont_print
491   = (struct type **) obstack_next_free (&dont_print_vb_obstack);
492   int i, n_baseclasses = TYPE_N_BASECLASSES (type);
493
494   if (dont_print_vb == 0)
495     {
496       /* If we're at top level, carve out a completely fresh
497          chunk of the obstack and use that until this particular
498          invocation returns.  */
499       tmp_obstack = dont_print_vb_obstack;
500       /* Bump up the high-water mark.  Now alpha is omega.  */
501       obstack_finish (&dont_print_vb_obstack);
502     }
503
504   for (i = 0; i < n_baseclasses; i++)
505     {
506       int boffset;
507       int skip;
508       struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
509       char *basename = TYPE_NAME (baseclass);
510       char *base_valaddr;
511
512       if (BASETYPE_VIA_VIRTUAL (type, i))
513         {
514           struct type **first_dont_print
515           = (struct type **) obstack_base (&dont_print_vb_obstack);
516
517           int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
518           - first_dont_print;
519
520           while (--j >= 0)
521             if (baseclass == first_dont_print[j])
522               goto flush_it;
523
524           obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
525         }
526
527       if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i))
528         {
529           /* Assume HP/Taligent runtime convention */
530           find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
531                                 valaddr, offset, &boffset, &skip);
532           if (skip >= 0)
533             error ("Virtual base class offset not found from vtable while printing");
534           base_valaddr = valaddr;
535         }
536       else
537         {
538           boffset = baseclass_offset (type, i, valaddr + offset, address + offset);
539           skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
540
541           if (BASETYPE_VIA_VIRTUAL (type, i))
542             {
543               /* The virtual base class pointer might have been clobbered by the
544                  user program. Make sure that it still points to a valid memory
545                  location.  */
546
547               if (boffset != -1 && ((boffset + offset) < 0 || (boffset + offset) >= TYPE_LENGTH (type)))
548                 {
549                   base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
550                   if (target_read_memory (address + boffset, base_valaddr,
551                                           TYPE_LENGTH (baseclass)) != 0)
552                     skip = 1;
553                 }
554               else
555                 base_valaddr = valaddr;
556             }
557           else
558             base_valaddr = valaddr;
559         }
560
561       /* now do the printing */
562       if (pretty)
563         {
564           fprintf_filtered (stream, "\n");
565           print_spaces_filtered (2 * recurse, stream);
566         }
567       fputs_filtered ("<", stream);
568       /* Not sure what the best notation is in the case where there is no
569          baseclass name.  */
570       fputs_filtered (basename ? basename : "", stream);
571       fputs_filtered ("> = ", stream);
572
573
574       if (skip >= 1)
575         fprintf_filtered (stream, "<invalid address>");
576       else
577         cp_print_value_fields (baseclass, real_type, base_valaddr, offset + boffset, address,
578                                stream, format, recurse, pretty,
579                      (struct type **) obstack_base (&dont_print_vb_obstack),
580                                0);
581       fputs_filtered (", ", stream);
582
583     flush_it:
584       ;
585     }
586
587   if (dont_print_vb == 0)
588     {
589       /* Free the space used to deal with the printing
590          of this type from top level.  */
591       obstack_free (&dont_print_vb_obstack, last_dont_print);
592       /* Reset watermark so that we can continue protecting
593          ourselves from whatever we were protecting ourselves.  */
594       dont_print_vb_obstack = tmp_obstack;
595     }
596 }
597
598 /* Print value of a static member.
599    To avoid infinite recursion when printing a class that contains
600    a static instance of the class, we keep the addresses of all printed
601    static member classes in an obstack and refuse to print them more
602    than once.
603
604    VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
605    have the same meanings as in c_val_print.  */
606
607 static void
608 cp_print_static_field (struct type *type, value_ptr val, struct ui_file *stream,
609                        int format, int recurse, enum val_prettyprint pretty)
610 {
611   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
612     {
613       CORE_ADDR *first_dont_print;
614       int i;
615
616       first_dont_print
617         = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
618       i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
619         - first_dont_print;
620
621       while (--i >= 0)
622         {
623           if (VALUE_ADDRESS (val) == first_dont_print[i])
624             {
625               fputs_filtered ("<same as static member of an already seen type>",
626                               stream);
627               return;
628             }
629         }
630
631       obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
632                     sizeof (CORE_ADDR));
633
634       CHECK_TYPEDEF (type);
635       cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
636                              stream, format, recurse, pretty, NULL, 1);
637       return;
638     }
639   val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
640              stream, format, 0, recurse, pretty);
641 }
642
643 void
644 cp_print_class_member (char *valaddr, struct type *domain,
645                        struct ui_file *stream, char *prefix)
646 {
647
648   /* VAL is a byte offset into the structure type DOMAIN.
649      Find the name of the field for that offset and
650      print it.  */
651   int extra = 0;
652   int bits = 0;
653   register unsigned int i;
654   unsigned len = TYPE_NFIELDS (domain);
655
656   /* @@ Make VAL into bit offset */
657
658   /* Note: HP aCC generates offsets that are the real byte offsets added
659      to a constant bias 0x20000000 (1 << 29).  This constant bias gets
660      shifted out in the code below -- joyous happenstance! */
661
662   /* Note: HP cfront uses a constant bias of 1; if we support this
663      compiler ever, we will have to adjust the computation below */
664
665   LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
666   for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
667     {
668       int bitpos = TYPE_FIELD_BITPOS (domain, i);
669       QUIT;
670       if (val == bitpos)
671         break;
672       if (val < bitpos && i != 0)
673         {
674           /* Somehow pointing into a field.  */
675           i -= 1;
676           extra = (val - TYPE_FIELD_BITPOS (domain, i));
677           if (extra & 0x7)
678             bits = 1;
679           else
680             extra >>= 3;
681           break;
682         }
683     }
684   if (i < len)
685     {
686       char *name;
687       fprintf_filtered (stream, prefix);
688       name = type_name_no_tag (domain);
689       if (name)
690         fputs_filtered (name, stream);
691       else
692         c_type_print_base (domain, stream, 0, 0);
693       fprintf_filtered (stream, "::");
694       fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
695       if (extra)
696         fprintf_filtered (stream, " + %d bytes", extra);
697       if (bits)
698         fprintf_filtered (stream, " (offset in bits)");
699     }
700   else
701     fprintf_filtered (stream, "%ld", (long) (val >> 3));
702 }
703
704
705 /* This function prints out virtual table entries for a class; it
706  * recurses on the base classes to find all virtual functions
707  * available in a class.
708  *
709  * pai/1997-05-21 Note: As the name suggests, it's currently
710  * implemented for HP aCC runtime only. g++ objects are handled
711  * differently and I have made no attempt to fold that logic in
712  * here. The runtime layout is different for the two cases.  Also,
713  * this currently has only the code for non-RRBC layouts generated by
714  * the HP aCC compiler; RRBC code is stubbed out and will have to be
715  * added later. */
716
717
718 static void
719 cp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs,
720                                       value_ptr v, struct ui_file *stream,
721                                       int format, int recurse,
722                                       enum val_prettyprint pretty)
723 {
724   int fn, oi;
725
726   /* pai: FIXME this function doesn't work. It should handle a given
727    * virtual function only once (latest redefinition in class hierarchy)
728    */
729
730   /* Recursion on other classes that can share the same vtable */
731   struct type *pbc = primary_base_class (type);
732   if (pbc)
733     cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format, recurse, pretty);
734
735   /* Now deal with vfuncs declared in this class */
736   for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++)
737     for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++)
738       if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi))
739         {
740           char *vf_name;
741
742           /* virtual function offset */
743           int vx = TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi) - 1;
744
745           /* Get the address of the vfunction entry */
746           value_ptr vf = value_copy (v);
747           if (VALUE_LAZY (vf))
748             (void) value_fetch_lazy (vf);
749           vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx);     /* adjust by offset */
750           vf = value_ind (vf);  /* get the entry */
751           VALUE_TYPE (vf) = VALUE_TYPE (v);     /* make it a pointer */
752
753           /* print out the entry */
754           val_print (VALUE_TYPE (vf), VALUE_CONTENTS (vf), 0, 0,
755                      stream, format, 0, recurse + 1, pretty);
756           vf_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi),
757                                     DMGL_ARM);  /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
758           fprintf_filtered (stream, " %s", vf_name);
759           if (--(*vfuncs) > 0)
760             fputs_filtered (", ", stream);
761         }
762 }
763
764
765
766 void
767 _initialize_cp_valprint (void)
768 {
769   add_show_from_set
770     (add_set_cmd ("static-members", class_support, var_boolean,
771                   (char *) &static_field_print,
772                   "Set printing of C++ static members.",
773                   &setprintlist),
774      &showprintlist);
775   /* Turn on printing of static fields.  */
776   static_field_print = 1;
777
778   add_show_from_set
779     (add_set_cmd ("vtbl", class_support, var_boolean, (char *) &vtblprint,
780                   "Set printing of C++ virtual function tables.",
781                   &setprintlist),
782      &showprintlist);
783
784   add_show_from_set
785     (add_set_cmd ("object", class_support, var_boolean, (char *) &objectprint,
786               "Set printing of object's derived type based on vtable info.",
787                   &setprintlist),
788      &showprintlist);
789
790   /* Give people the defaults which they are used to.  */
791   objectprint = 0;
792   vtblprint = 0;
793   obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *));
794   obstack_specify_allocation (&dont_print_statmem_obstack,
795                               32 * sizeof (CORE_ADDR), sizeof (CORE_ADDR),
796                               xmalloc, xfree);
797 }