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