OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [cp-valprint.c] - Blame information for rev 1767

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Support for printing C++ values for GDB, the GNU debugger.
2
   Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3
   2000
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 "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
 
37
/* Indication of presence of HP-compiled object files */
38
extern int hp_som_som_object_present;   /* defined in symtab.c */
39
 
40
 
41
int vtblprint;                  /* Controls printing of vtbl's */
42
int objectprint;                /* Controls looking up an object's derived type
43
                                   using what we find in its vtables.  */
44
int static_field_print;         /* Controls printing of static fields. */
45
 
46
static struct obstack dont_print_vb_obstack;
47
static struct obstack dont_print_statmem_obstack;
48
 
49
extern void _initialize_cp_valprint (void);
50
 
51
static void cp_print_static_field (struct type *, value_ptr,
52
                                   struct ui_file *, int, int,
53
                                   enum val_prettyprint);
54
 
55
static void cp_print_value (struct type *, struct type *, char *, int,
56
                            CORE_ADDR, struct ui_file *, int, int,
57
                            enum val_prettyprint, struct type **);
58
 
59
static void cp_print_hpacc_virtual_table_entries (struct type *, int *,
60
                                                  value_ptr,
61
                                                  struct ui_file *, int,
62
                                                  int,
63
                                                  enum val_prettyprint);
64
 
65
 
66
void
67
cp_print_class_method (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
          xfree (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
{
172
  CPLUS_MARKER, 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_',
173
  't', 'y', 'p', 'e', 0
174
};
175
 
176
/* It was changed to this after 2.4.5.  */
177
const char vtbl_ptr_name[] = "__vtbl_ptr_type";
178
 
179
/* HP aCC uses different names */
180
const char hpacc_vtbl_ptr_name[] = "__vfp";
181
const char hpacc_vtbl_ptr_type_name[] = "__vftyp";
182
 
183
 
184
/* Return truth value for assertion that TYPE is of the type
185
   "pointer to virtual function".  */
186
 
187
int
188
cp_is_vtbl_ptr_type (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 (struct type *type)
202
{
203
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
204
    {
205
      type = TYPE_TARGET_TYPE (type);
206
      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
207
        {
208
          type = TYPE_TARGET_TYPE (type);
209
          if (TYPE_CODE (type) == TYPE_CODE_STRUCT      /* if not using thunks */
210
              || TYPE_CODE (type) == TYPE_CODE_PTR)     /* if using thunks */
211
            {
212
              /* Virtual functions tables are full of pointers
213
                 to virtual functions. */
214
              return cp_is_vtbl_ptr_type (type);
215
            }
216
        }
217
    }
218
  return 0;
219
}
220
 
221
/* Mutually recursive subroutines of cp_print_value and c_val_print to
222
   print out a structure's fields: cp_print_value_fields and cp_print_value.
223
 
224
   TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
225
   same meanings as in cp_print_value and c_val_print.
226
 
227
   2nd argument REAL_TYPE is used to carry over the type of the derived
228
   class across the recursion to base classes.
229
 
230
   DONT_PRINT is an array of baseclass types that we
231
   should not print, or zero if called from top level.  */
232
 
233
void
234
cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr,
235
                       int offset, CORE_ADDR address, struct ui_file *stream,
236
                       int format, int recurse, enum val_prettyprint pretty,
237
                       struct type **dont_print_vb, int dont_print_statmem)
238
{
239
  int i, len, n_baseclasses;
240
  struct obstack tmp_obstack;
241
  char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
242
  int fields_seen = 0;
243
 
244
  CHECK_TYPEDEF (type);
245
 
246
  fprintf_filtered (stream, "{");
247
  len = TYPE_NFIELDS (type);
248
  n_baseclasses = TYPE_N_BASECLASSES (type);
249
 
250
  /* First, print out baseclasses such that we don't print
251
     duplicates of virtual baseclasses.  */
252
 
253
  if (n_baseclasses > 0)
254
    cp_print_value (type, real_type, valaddr, offset, address, stream,
255
                    format, recurse + 1, pretty, dont_print_vb);
256
 
257
  /* Second, print out data fields */
258
 
259
  /* If there are no data fields, or if the only field is the
260
   * vtbl pointer, skip this part */
261
  if ((len == n_baseclasses)
262
      || ((len - n_baseclasses == 1)
263
          && TYPE_HAS_VTABLE (type)
264
          && STREQN (TYPE_FIELD_NAME (type, n_baseclasses),
265
                     hpacc_vtbl_ptr_name, 5))
266
      || !len)
267
    fprintf_filtered (stream, "<No data fields>");
268
  else
269
    {
270
      extern int inspect_it;
271
 
272
      if (dont_print_statmem == 0)
273
        {
274
          /* If we're at top level, carve out a completely fresh
275
             chunk of the obstack and use that until this particular
276
             invocation returns.  */
277
          tmp_obstack = dont_print_statmem_obstack;
278
          obstack_finish (&dont_print_statmem_obstack);
279
        }
280
 
281
      for (i = n_baseclasses; i < len; i++)
282
        {
283
          /* If requested, skip printing of static fields.  */
284
          if (!static_field_print && TYPE_FIELD_STATIC (type, i))
285
            continue;
286
 
287
          /* If a vtable pointer appears, we'll print it out later */
288
          if (TYPE_HAS_VTABLE (type)
289
              && STREQN (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5))
290
            continue;
291
 
292
          if (fields_seen)
293
            fprintf_filtered (stream, ", ");
294
          else if (n_baseclasses > 0)
295
            {
296
              if (pretty)
297
                {
298
                  fprintf_filtered (stream, "\n");
299
                  print_spaces_filtered (2 + 2 * recurse, stream);
300
                  fputs_filtered ("members of ", stream);
301
                  fputs_filtered (type_name_no_tag (type), stream);
302
                  fputs_filtered (": ", stream);
303
                }
304
            }
305
          fields_seen = 1;
306
 
307
          if (pretty)
308
            {
309
              fprintf_filtered (stream, "\n");
310
              print_spaces_filtered (2 + 2 * recurse, stream);
311
            }
312
          else
313
            {
314
              wrap_here (n_spaces (2 + 2 * recurse));
315
            }
316
          if (inspect_it)
317
            {
318
              if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
319
                fputs_filtered ("\"( ptr \"", stream);
320
              else
321
                fputs_filtered ("\"( nodef \"", stream);
322
              if (TYPE_FIELD_STATIC (type, i))
323
                fputs_filtered ("static ", stream);
324
              fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
325
                                       language_cplus,
326
                                       DMGL_PARAMS | DMGL_ANSI);
327
              fputs_filtered ("\" \"", stream);
328
              fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
329
                                       language_cplus,
330
                                       DMGL_PARAMS | DMGL_ANSI);
331
              fputs_filtered ("\") \"", stream);
332
            }
333
          else
334
            {
335
              annotate_field_begin (TYPE_FIELD_TYPE (type, i));
336
 
337
              if (TYPE_FIELD_STATIC (type, i))
338
                fputs_filtered ("static ", stream);
339
              fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
340
                                       language_cplus,
341
                                       DMGL_PARAMS | DMGL_ANSI);
342
              annotate_field_name_end ();
343
              /* do not print leading '=' in case of anonymous unions */
344
              if (strcmp (TYPE_FIELD_NAME (type, i), ""))
345
                fputs_filtered (" = ", stream);
346
              annotate_field_value ();
347
            }
348
 
349
          if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
350
            {
351
              value_ptr v;
352
 
353
              /* Bitfields require special handling, especially due to byte
354
                 order problems.  */
355
              if (TYPE_FIELD_IGNORE (type, i))
356
                {
357
                  fputs_filtered ("<optimized out or zero length>", stream);
358
                }
359
              else
360
                {
361
                  v = value_from_longest
362
                    (TYPE_FIELD_TYPE (type, i),
363
                     unpack_field_as_long (type, valaddr + offset, i));
364
 
365
                  val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v),
366
                             0, 0, stream, format, 0, recurse + 1, pretty);
367
                }
368
            }
369
          else
370
            {
371
              if (TYPE_FIELD_IGNORE (type, i))
372
                {
373
                  fputs_filtered ("<optimized out or zero length>", stream);
374
                }
375
              else if (TYPE_FIELD_STATIC (type, i))
376
                {
377
                  value_ptr v = value_static_field (type, i);
378
                  if (v == NULL)
379
                    fputs_filtered ("<optimized out>", stream);
380
                  else
381
                    cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
382
                                           stream, format, recurse + 1,
383
                                           pretty);
384
                }
385
              else
386
                {
387
                  val_print (TYPE_FIELD_TYPE (type, i),
388
                             valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
389
                             address + TYPE_FIELD_BITPOS (type, i) / 8,
390
                             stream, format, 0, recurse + 1, pretty);
391
                }
392
            }
393
          annotate_field_end ();
394
        }
395
 
396
      if (dont_print_statmem == 0)
397
        {
398
          /* Free the space used to deal with the printing
399
             of the members from top level.  */
400
          obstack_free (&dont_print_statmem_obstack, last_dont_print);
401
          dont_print_statmem_obstack = tmp_obstack;
402
        }
403
 
404
      if (pretty)
405
        {
406
          fprintf_filtered (stream, "\n");
407
          print_spaces_filtered (2 * recurse, stream);
408
        }
409
    }                           /* if there are data fields */
410
  /* Now print out the virtual table pointer if there is one */
411
  if (TYPE_HAS_VTABLE (type)
412
      && STREQN (TYPE_FIELD_NAME (type, n_baseclasses),
413
                 hpacc_vtbl_ptr_name,
414
                 5))
415
    {
416
      value_ptr v;
417
      /* First get the virtual table pointer and print it out */
418
 
419
#if 0
420
      fputs_filtered ("__vfp = ", stream);
421
#endif
422
 
423
      fputs_filtered (", Virtual table at ", stream);
424
 
425
      /* pai: FIXME 32x64 problem? */
426
      /* Not sure what the best notation is in the case where there is no
427
         baseclass name.  */
428
      v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
429
                              *(unsigned long *) (valaddr + offset));
430
 
431
      val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
432
                 stream, format, 0, recurse + 1, pretty);
433
      fields_seen = 1;
434
 
435
      if (vtblprint)
436
        {
437
          /* Print out function pointers in vtable. */
438
 
439
          /* FIXME: then-clause is for non-RRBC layout of virtual
440
           * table.  The RRBC case in the else-clause is yet to be
441
           * implemented.  The if (1) below should be changed to a
442
           * test for whether the executable we have was compiled
443
           * with a version of HP aCC that doesn't have RRBC
444
           * support. */
445
 
446
          if (1)
447
            {
448
              /* no RRBC support; function pointers embedded directly
449
                 in vtable */
450
 
451
              int vfuncs = count_virtual_fns (real_type);
452
 
453
              fputs_filtered (" {", stream);
454
 
455
              /* FIXME : doesn't work at present */
456
#if 0
457
              fprintf_filtered (stream, "%d entr%s: ", vfuncs,
458
                                vfuncs == 1 ? "y" : "ies");
459
#else
460
              fputs_filtered ("not implemented", stream);
461
 
462
 
463
#endif
464
 
465
              /* recursive function that prints all virtual function entries */
466
#if 0
467
              cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v,
468
                                                    stream, format, recurse,
469
                                                    pretty);
470
#endif
471
              fputs_filtered ("}", stream);
472
            }                   /* non-RRBC case */
473
          else
474
            {
475
              /* FIXME -- see 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 (struct type *type, struct type *real_type, char *valaddr,
499
                int offset, CORE_ADDR address, struct ui_file *stream,
500
                int format, int recurse, enum val_prettyprint pretty,
501
                struct type **dont_print_vb)
502
{
503
  struct obstack tmp_obstack;
504
  struct type **last_dont_print
505
    = (struct type **) obstack_next_free (&dont_print_vb_obstack);
506
  int i, n_baseclasses = TYPE_N_BASECLASSES (type);
507
 
508
  if (dont_print_vb == 0)
509
    {
510
      /* If we're at top level, carve out a completely fresh
511
         chunk of the obstack and use that until this particular
512
         invocation returns.  */
513
      tmp_obstack = dont_print_vb_obstack;
514
      /* Bump up the high-water mark.  Now alpha is omega.  */
515
      obstack_finish (&dont_print_vb_obstack);
516
    }
517
 
518
  for (i = 0; i < n_baseclasses; i++)
519
    {
520
      int boffset;
521
      int skip;
522
      struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
523
      char *basename = TYPE_NAME (baseclass);
524
      char *base_valaddr;
525
 
526
      if (BASETYPE_VIA_VIRTUAL (type, i))
527
        {
528
          struct type **first_dont_print
529
            = (struct type **) obstack_base (&dont_print_vb_obstack);
530
 
531
          int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
532
            - first_dont_print;
533
 
534
          while (--j >= 0)
535
            if (baseclass == first_dont_print[j])
536
              goto flush_it;
537
 
538
          obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
539
        }
540
 
541
      if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i))
542
        {
543
          /* Assume HP/Taligent runtime convention */
544
          find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
545
                                valaddr, offset, &boffset, &skip);
546
          if (skip >= 0)
547
            error ("Virtual base class offset not found from vtable while"
548
                   " printing");
549
          base_valaddr = valaddr;
550
        }
551
      else
552
        {
553
          boffset = baseclass_offset (type, i,
554
                                      valaddr + offset,
555
                                      address + offset);
556
          skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
557
 
558
          if (BASETYPE_VIA_VIRTUAL (type, i))
559
            {
560
              /* The virtual base class pointer might have been
561
                 clobbered by the user program. Make sure that it
562
                 still points to a valid memory location.  */
563
 
564
              if (boffset != -1
565
                  && ((boffset + offset) < 0
566
                      || (boffset + offset) >= TYPE_LENGTH (type)))
567
                {
568
                  base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
569
                  if (target_read_memory (address + boffset, base_valaddr,
570
                                          TYPE_LENGTH (baseclass)) != 0)
571
                    skip = 1;
572
                }
573
              else
574
                base_valaddr = valaddr;
575
            }
576
          else
577
            base_valaddr = valaddr;
578
        }
579
 
580
      /* now do the printing */
581
      if (pretty)
582
        {
583
          fprintf_filtered (stream, "\n");
584
          print_spaces_filtered (2 * recurse, stream);
585
        }
586
      fputs_filtered ("<", stream);
587
      /* Not sure what the best notation is in the case where there is no
588
         baseclass name.  */
589
      fputs_filtered (basename ? basename : "", stream);
590
      fputs_filtered ("> = ", stream);
591
 
592
 
593
      if (skip >= 1)
594
        fprintf_filtered (stream, "<invalid address>");
595
      else
596
        cp_print_value_fields (baseclass, real_type, base_valaddr,
597
                               offset + boffset, address, stream, format,
598
                               recurse, pretty,
599
                               ((struct type **)
600
                                obstack_base (&dont_print_vb_obstack)),
601
                               0);
602
      fputs_filtered (", ", stream);
603
 
604
    flush_it:
605
      ;
606
    }
607
 
608
  if (dont_print_vb == 0)
609
    {
610
      /* Free the space used to deal with the printing
611
         of this type from top level.  */
612
      obstack_free (&dont_print_vb_obstack, last_dont_print);
613
      /* Reset watermark so that we can continue protecting
614
         ourselves from whatever we were protecting ourselves.  */
615
      dont_print_vb_obstack = tmp_obstack;
616
    }
617
}
618
 
619
/* Print value of a static member.
620
   To avoid infinite recursion when printing a class that contains
621
   a static instance of the class, we keep the addresses of all printed
622
   static member classes in an obstack and refuse to print them more
623
   than once.
624
 
625
   VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
626
   have the same meanings as in c_val_print.  */
627
 
628
static void
629
cp_print_static_field (struct type *type,
630
                       value_ptr val,
631
                       struct ui_file *stream,
632
                       int format,
633
                       int recurse,
634
                       enum val_prettyprint pretty)
635
{
636
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
637
    {
638
      CORE_ADDR *first_dont_print;
639
      int i;
640
 
641
      first_dont_print
642
        = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
643
      i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
644
        - first_dont_print;
645
 
646
      while (--i >= 0)
647
        {
648
          if (VALUE_ADDRESS (val) == first_dont_print[i])
649
            {
650
              fputs_filtered ("<same as static member of an already"
651
                              " seen type>",
652
                              stream);
653
              return;
654
            }
655
        }
656
 
657
      obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
658
                    sizeof (CORE_ADDR));
659
 
660
      CHECK_TYPEDEF (type);
661
      cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val),
662
                             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),
667
             VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
668
             stream, format, 0, recurse, pretty);
669
}
670
 
671
void
672
cp_print_class_member (char *valaddr, struct type *domain,
673
                       struct ui_file *stream, char *prefix)
674
{
675
 
676
  /* VAL is a byte offset into the structure type DOMAIN.
677
     Find the name of the field for that offset and
678
     print it.  */
679
  int extra = 0;
680
  int bits = 0;
681
  register unsigned int i;
682
  unsigned len = TYPE_NFIELDS (domain);
683
 
684
  /* @@ Make VAL into bit offset */
685
 
686
  /* Note: HP aCC generates offsets that are the real byte offsets added
687
     to a constant bias 0x20000000 (1 << 29).  This constant bias gets
688
     shifted out in the code below -- joyous happenstance! */
689
 
690
  /* Note: HP cfront uses a constant bias of 1; if we support this
691
     compiler ever, we will have to adjust the computation below */
692
 
693
  LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
694
  for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
695
    {
696
      int bitpos = TYPE_FIELD_BITPOS (domain, i);
697
      QUIT;
698
      if (val == bitpos)
699
        break;
700
      if (val < bitpos && i != 0)
701
        {
702
          /* Somehow pointing into a field.  */
703
          i -= 1;
704
          extra = (val - TYPE_FIELD_BITPOS (domain, i));
705
          if (extra & 0x7)
706
            bits = 1;
707
          else
708
            extra >>= 3;
709
          break;
710
        }
711
    }
712
  if (i < len)
713
    {
714
      char *name;
715
      fprintf_filtered (stream, prefix);
716
      name = type_name_no_tag (domain);
717
      if (name)
718
        fputs_filtered (name, stream);
719
      else
720
        c_type_print_base (domain, stream, 0, 0);
721
      fprintf_filtered (stream, "::");
722
      fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
723
      if (extra)
724
        fprintf_filtered (stream, " + %d bytes", extra);
725
      if (bits)
726
        fprintf_filtered (stream, " (offset in bits)");
727
    }
728
  else
729
    fprintf_filtered (stream, "%ld", (long) (val >> 3));
730
}
731
 
732
 
733
/* This function prints out virtual table entries for a class; it
734
 * recurses on the base classes to find all virtual functions
735
 * available in a class.
736
 *
737
 * pai/1997-05-21 Note: As the name suggests, it's currently
738
 * implemented for HP aCC runtime only. g++ objects are handled
739
 * differently and I have made no attempt to fold that logic in
740
 * here. The runtime layout is different for the two cases.  Also,
741
 * this currently has only the code for non-RRBC layouts generated by
742
 * the HP aCC compiler; RRBC code is stubbed out and will have to be
743
 * added later. */
744
 
745
 
746
static void
747
cp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs,
748
                                      value_ptr v, struct ui_file *stream,
749
                                      int format, int recurse,
750
                                      enum val_prettyprint pretty)
751
{
752
  int fn, oi;
753
 
754
  /* pai: FIXME this function doesn't work. It should handle a given
755
   * virtual function only once (latest redefinition in class hierarchy)
756
   */
757
 
758
  /* Recursion on other classes that can share the same vtable */
759
  struct type *pbc = primary_base_class (type);
760
  if (pbc)
761
    cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format,
762
                                          recurse, pretty);
763
 
764
  /* Now deal with vfuncs declared in this class */
765
  for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++)
766
    for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++)
767
      if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi))
768
        {
769
          char *vf_name;
770
          const char *field_physname;
771
 
772
          /* virtual function offset */
773
          int vx = (TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi)
774
                    - 1);
775
 
776
          /* Get the address of the vfunction entry */
777
          value_ptr vf = value_copy (v);
778
          if (VALUE_LAZY (vf))
779
            (void) value_fetch_lazy (vf);
780
          /* adjust by offset */
781
          vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx);
782
          vf = value_ind (vf);  /* get the entry */
783
          VALUE_TYPE (vf) = VALUE_TYPE (v);     /* make it a pointer */
784
 
785
          /* print out the entry */
786
          val_print (VALUE_TYPE (vf), VALUE_CONTENTS (vf), 0, 0,
787
                     stream, format, 0, recurse + 1, pretty);
788
          field_physname
789
            = TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi);
790
          /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
791
          vf_name = cplus_demangle (field_physname, DMGL_ARM);
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 (void)
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, xfree);
831
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.