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