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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [cp-valprint.c] - Blame information for rev 1773

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

Line No. Rev Author Line
1 104 markom
/* 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
}

powered by: WebSVN 2.1.0

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