Merge from vendor branch AWK:
[dragonfly.git] / contrib / gdb / gdb / jv-valprint.c
1 /* Support for printing Java values for GDB, the GNU debugger.
2    Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "gdbtypes.h"
23 #include "expression.h"
24 #include "value.h"
25 #include "demangle.h"
26 #include "valprint.h"
27 #include "language.h"
28 #include "jv-lang.h"
29 #include "c-lang.h"
30
31 int
32 java_value_print (val, stream, format, pretty)
33      value_ptr val;
34      GDB_FILE *stream;
35      int format;
36      enum val_prettyprint pretty;
37 {
38   struct type *type;
39   CORE_ADDR address;
40   int i;
41   char *name;
42
43   type = VALUE_TYPE (val);
44   address = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
45
46   if (is_object_type (type))
47     {
48       CORE_ADDR obj_addr;
49
50       /* Get the run-time type, and cast the object into that */
51
52       obj_addr = unpack_pointer (type, VALUE_CONTENTS (val));
53
54       if (obj_addr != 0)
55         {
56           type = type_from_class (java_class_from_object (val));
57           type = lookup_pointer_type (type);
58
59           val = value_at (type, address, NULL);
60         }
61     }
62
63   if (TYPE_CODE (type) == TYPE_CODE_PTR && ! value_logical_not (val))
64     type_print (TYPE_TARGET_TYPE (type), "", stream, -1);
65
66   name = TYPE_TAG_NAME (type);
67   if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL
68       && (i = strlen (name), name[i-1] == ']'))
69     {
70       char buf4[4];
71       long length;
72       unsigned int things_printed = 0;
73       int reps; 
74       struct type *el_type = java_primitive_type_from_name (name, i - 2);
75
76       i = 0;
77       read_memory (address + JAVA_OBJECT_SIZE, buf4, 4);
78
79       length = (long) extract_signed_integer (buf4, 4);
80       fprintf_filtered (stream, "{length: %ld", length);
81
82       if (el_type == NULL)
83         {
84           CORE_ADDR element, next_element;
85
86           address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */
87
88           while (i < length && things_printed < print_max)
89             {
90               char buf[TARGET_PTR_BIT / HOST_CHAR_BIT];
91
92               fputs_filtered (", ", stream);
93               wrap_here (n_spaces (2));
94
95               if (i > 0)
96                 element = next_element;
97               else
98                 {
99                   read_memory (address, buf, sizeof(buf));
100                   address += TARGET_PTR_BIT / HOST_CHAR_BIT;
101                   element = extract_address (buf, sizeof(buf));
102                 }
103
104               for (reps = 1;  i + reps < length;  reps++)
105                 {
106                   read_memory (address, buf, sizeof(buf));
107                   address += TARGET_PTR_BIT / HOST_CHAR_BIT;
108                   next_element = extract_address (buf, sizeof(buf));
109                   if (next_element != element)
110                     break;
111                 }
112
113               if (reps == 1)
114                 fprintf_filtered (stream, "%d: ", i);
115               else
116                 fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
117
118               if (element == 0)
119                 fprintf_filtered (stream, "null");
120               else
121                 fprintf_filtered (stream, "@%x", element);
122
123               things_printed++;
124               i += reps;
125             }
126         }
127       else
128         {
129           value_ptr v = allocate_value (el_type);
130           value_ptr next_v = allocate_value (el_type);
131
132           VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4;
133           VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v);
134
135           while (i < length && things_printed < print_max)
136             {
137               fputs_filtered (", ", stream);
138               wrap_here (n_spaces (2));
139
140               if (i > 0)
141                 {
142                   value_ptr tmp;
143
144                   tmp = next_v;
145                   next_v = v;
146                   v = tmp;
147                 }
148               else
149                 {
150                   VALUE_LAZY (v) = 1;
151                   VALUE_OFFSET (v) = 0;
152                 }
153
154               VALUE_OFFSET (next_v) = VALUE_OFFSET (v);
155
156               for (reps = 1;  i + reps < length;  reps++)
157                 {
158                   VALUE_LAZY (next_v) = 1;
159                   VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type);
160                   if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v),
161                               TYPE_LENGTH (el_type)) != 0)
162                     break;
163                 }
164
165               if (reps == 1)
166                 fprintf_filtered (stream, "%d: ", i);
167               else
168                 fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
169
170               val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
171                          stream, format, 2, 1, pretty);
172
173               things_printed++;
174               i += reps;
175             }
176         }
177
178       if (i < length)
179         fprintf_filtered (stream, "...");
180
181       fprintf_filtered (stream, "}");
182
183       return 0;
184     }
185
186   /* If it's type String, print it */
187
188   if (TYPE_CODE (type) == TYPE_CODE_PTR
189       && TYPE_TARGET_TYPE (type)
190       && TYPE_NAME (TYPE_TARGET_TYPE (type))
191       && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0
192       && (format == 0 || format == 's')
193       && address != 0)
194     {
195       value_ptr data_val;
196       CORE_ADDR data;
197       value_ptr boffset_val;
198       unsigned long boffset;
199       value_ptr count_val;
200       unsigned long count;
201       value_ptr mark;
202
203       mark = value_mark ();     /* Remember start of new values */
204
205       data_val = value_struct_elt (&val, NULL, "data", NULL, NULL);
206       data = value_as_pointer (data_val);
207
208       boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL);
209       boffset = value_as_pointer (boffset_val);
210
211       count_val = value_struct_elt (&val, NULL, "count", NULL, NULL);
212       count = value_as_pointer (count_val);
213
214       value_free_to_mark (mark); /* Release unnecessary values */
215
216       val_print_string (data + boffset, count, 2, stream);
217
218       return 0;
219     }
220
221   return (val_print (type, VALUE_CONTENTS (val), 0, address,
222                      stream, format, 1, 0, pretty));
223 }
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    DONT_PRINT is an array of baseclass types that we
229    should not print, or zero if called from top level.  */
230
231 void
232 java_print_value_fields (type, valaddr, address, stream,
233                          format, recurse, pretty)
234      struct type *type;
235      char *valaddr;
236      CORE_ADDR address;
237      GDB_FILE *stream;
238      int format;
239      int recurse;
240      enum val_prettyprint pretty;
241 {
242   int i, len, n_baseclasses;
243
244   CHECK_TYPEDEF (type);
245
246   fprintf_filtered (stream, "{");
247   len = TYPE_NFIELDS (type);
248   n_baseclasses = TYPE_N_BASECLASSES (type);
249
250   if (n_baseclasses > 0)
251     {
252       int i, n_baseclasses = TYPE_N_BASECLASSES (type);
253
254       for (i = 0; i < n_baseclasses; i++)
255         {
256           int boffset;
257           struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
258           char *basename = TYPE_NAME (baseclass);
259           char *base_valaddr;
260           
261           if (BASETYPE_VIA_VIRTUAL (type, i))
262             continue;
263
264           if (basename != NULL && strcmp (basename, "java.lang.Object") == 0)
265             continue;
266
267           boffset = 0;
268
269           if (pretty)
270             {
271               fprintf_filtered (stream, "\n");
272               print_spaces_filtered (2 * (recurse+1), stream);
273             }
274           fputs_filtered ("<", stream);
275           /* Not sure what the best notation is in the case where there is no
276              baseclass name.  */
277           fputs_filtered (basename ? basename : "", stream);
278           fputs_filtered ("> = ", stream);
279
280           base_valaddr = valaddr;
281
282           java_print_value_fields (baseclass, base_valaddr, address + boffset,
283                                    stream, format, recurse+1, pretty);
284           fputs_filtered (", ", stream);
285           
286         flush_it:
287           ;
288         }
289
290     }
291
292   if (!len && n_baseclasses == 1)
293     fprintf_filtered (stream, "<No data fields>");
294   else
295     {
296       extern int inspect_it;
297       int fields_seen = 0;
298
299       for (i = n_baseclasses; i < len; i++)
300         {
301           /* If requested, skip printing of static fields.  */
302           if (TYPE_FIELD_STATIC (type, i))
303             {
304               char *name = TYPE_FIELD_NAME (type, i);
305               if (!static_field_print)
306                 continue;
307               if (name != NULL && strcmp (name, "class") == 0)
308                 continue;
309             }
310           if (fields_seen)
311             fprintf_filtered (stream, ", ");
312           else if (n_baseclasses > 0)
313             {
314               if (pretty)
315                 {
316                   fprintf_filtered (stream, "\n");
317                   print_spaces_filtered (2 + 2 * recurse, stream);
318                   fputs_filtered ("members of ", stream);
319                   fputs_filtered (type_name_no_tag (type), stream);
320                   fputs_filtered (": ", stream);
321                 }
322             }
323           fields_seen = 1;
324
325           if (pretty)
326             {
327               fprintf_filtered (stream, "\n");
328               print_spaces_filtered (2 + 2 * recurse, stream);
329             }
330           else 
331             {
332               wrap_here (n_spaces (2 + 2 * recurse));
333             }
334           if (inspect_it)
335             {
336               if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
337                 fputs_filtered ("\"( ptr \"", stream);
338               else
339                 fputs_filtered ("\"( nodef \"", stream);
340               if (TYPE_FIELD_STATIC (type, i))
341                 fputs_filtered ("static ", stream);
342               fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
343                                        language_cplus,
344                                        DMGL_PARAMS | DMGL_ANSI);
345               fputs_filtered ("\" \"", stream);
346               fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
347                                        language_cplus,
348                                        DMGL_PARAMS | DMGL_ANSI);
349               fputs_filtered ("\") \"", stream);
350             }
351           else
352             {
353               annotate_field_begin (TYPE_FIELD_TYPE (type, i));
354
355               if (TYPE_FIELD_STATIC (type, i))
356                 fputs_filtered ("static ", stream);
357               fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
358                                        language_cplus,
359                                        DMGL_PARAMS | DMGL_ANSI);
360               annotate_field_name_end ();
361               fputs_filtered (": ", stream);
362               annotate_field_value ();
363             }
364
365           if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
366             {
367               value_ptr v;
368
369               /* Bitfields require special handling, especially due to byte
370                  order problems.  */
371               if (TYPE_FIELD_IGNORE (type, i))
372                 {
373                    fputs_filtered ("<optimized out or zero length>", stream);
374                 }
375               else
376                 {
377                    v = value_from_longest (TYPE_FIELD_TYPE (type, i),
378                                    unpack_field_as_long (type, valaddr, i));
379
380                    val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
381                               0, stream, format, 0, recurse + 1, pretty);
382                 }
383             }
384           else
385             {
386               if (TYPE_FIELD_IGNORE (type, i))
387                 {
388                    fputs_filtered ("<optimized out or zero length>", stream);
389                 }
390               else if (TYPE_FIELD_STATIC (type, i))
391                 {
392                   value_ptr v = value_static_field (type, i);
393                   if (v == NULL)
394                     fputs_filtered ("<optimized out>", stream);
395                   else
396                     {
397                       struct type *t = check_typedef (VALUE_TYPE (v));
398                       if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
399                         v = value_addr (v);
400                       val_print (VALUE_TYPE (v),
401                                  VALUE_CONTENTS (v), 0, VALUE_ADDRESS (v),
402                                  stream, format, 0, recurse+1, pretty);
403                     }
404                 }
405               else
406                 {
407                    val_print (TYPE_FIELD_TYPE (type, i), 
408                               valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
409                               address + TYPE_FIELD_BITPOS (type, i) / 8,
410                               stream, format, 0, recurse + 1, pretty);
411                 }
412             }
413           annotate_field_end ();
414         }
415
416       if (pretty)
417         {
418           fprintf_filtered (stream, "\n");
419           print_spaces_filtered (2 * recurse, stream);
420         }
421     }
422   fprintf_filtered (stream, "}");
423 }
424
425 /* Print data of type TYPE located at VALADDR (within GDB), which came from
426    the inferior at address ADDRESS, onto stdio stream STREAM according to
427    FORMAT (a letter or 0 for natural format).  The data at VALADDR is in
428    target byte order.
429
430    If the data are a string pointer, returns the number of string characters
431    printed.
432
433    If DEREF_REF is nonzero, then dereference references, otherwise just print
434    them like pointers.
435
436    The PRETTY parameter controls prettyprinting.  */
437
438 int
439 java_val_print (type, valaddr, embedded_offset, address, stream, format,
440                 deref_ref, recurse, pretty)
441      struct type *type;
442      char *valaddr;
443      CORE_ADDR address;
444      GDB_FILE *stream;
445      int format;
446      int deref_ref;
447      int recurse;
448      enum val_prettyprint pretty;
449 {
450   register unsigned int i = 0;          /* Number of characters printed */
451   struct type *target_type;
452   CORE_ADDR addr;
453
454   CHECK_TYPEDEF (type);
455   switch (TYPE_CODE (type))
456     {
457     case TYPE_CODE_PTR:
458       if (format && format != 's')
459         {
460           print_scalar_formatted (valaddr, type, format, 0, stream);
461           break;
462         }
463 #if 0
464       if (vtblprint && cp_is_vtbl_ptr_type(type))
465         {
466           /* Print the unmangled name if desired.  */
467           /* Print vtable entry - we only get here if we ARE using
468              -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.) */
469           print_address_demangle(extract_address (valaddr, TYPE_LENGTH (type)),
470                                  stream, demangle);
471           break;
472         }
473 #endif
474       addr = unpack_pointer (type, valaddr);
475       if (addr == 0)
476         {
477           fputs_filtered ("null", stream);
478           return i;
479         }
480       target_type = check_typedef (TYPE_TARGET_TYPE (type));
481
482       if (TYPE_CODE (target_type) == TYPE_CODE_FUNC)
483         {
484           /* Try to print what function it points to.  */
485           print_address_demangle (addr, stream, demangle);
486           /* Return value is irrelevant except for string pointers.  */
487           return (0);
488         }
489
490       if (addressprint && format != 's')
491         {
492           fputs_filtered ("@", stream);
493           print_longest (stream, 'x', 0, (ULONGEST) addr);
494         }
495
496       return i;
497
498     case TYPE_CODE_CHAR:
499       format = format ? format : output_format;
500       if (format)
501         print_scalar_formatted (valaddr, type, format, 0, stream);
502       else
503         LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream);
504       break;
505
506     case TYPE_CODE_INT:
507       /* Can't just call c_val_print because that print bytes as C chars. */
508       format = format ? format : output_format;
509       if (format)
510         print_scalar_formatted (valaddr, type, format, 0, stream);
511       else
512         val_print_type_code_int (type, valaddr, stream);
513       break;
514
515     case TYPE_CODE_STRUCT:
516       java_print_value_fields (type, valaddr, address, stream, format,
517                                recurse, pretty);
518       break;
519
520     default:
521       return c_val_print (type, valaddr, embedded_offset, address, stream,
522                           format, deref_ref, recurse, pretty);
523     }
524
525   return 0;
526 }