2006-05-13 Gaius Mulley <gaius@glam.ac.uk>
[external/binutils.git] / gdb / m2-typeprint.c
1 /* Support for printing Modula 2 types for GDB, the GNU debugger.
2    Copyright (C) 1986, 1988, 1989, 1991, 1992, 1995, 2000, 2001,
3                  2002, 2003, 2004, 2005, 2006
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., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 #include "defs.h"
24 #include "gdb_obstack.h"
25 #include "bfd.h"                /* Binary File Description */
26 #include "symtab.h"
27 #include "gdbtypes.h"
28 #include "expression.h"
29 #include "value.h"
30 #include "gdbcore.h"
31 #include "m2-lang.h"
32 #include "target.h"
33 #include "language.h"
34 #include "demangle.h"
35 #include "c-lang.h"
36 #include "typeprint.h"
37 #include "cp-abi.h"
38
39 #include "gdb_string.h"
40 #include <errno.h>
41
42 static void m2_print_bounds (struct type *type,
43                              struct ui_file *stream, int show, int level,
44                              int print_high);
45
46 static void m2_typedef (struct type *, struct ui_file *, int, int);
47 static void m2_array (struct type *, struct ui_file *, int, int);
48 static void m2_pointer (struct type *, struct ui_file *, int, int);
49 static void m2_ref (struct type *, struct ui_file *, int, int);
50 static void m2_procedure (struct type *, struct ui_file *, int, int);
51 static void m2_union (struct type *, struct ui_file *);
52 static void m2_enum (struct type *, struct ui_file *, int, int);
53 static void m2_range (struct type *, struct ui_file *, int, int);
54 static void m2_type_name (struct type *type, struct ui_file *stream);
55 static void m2_short_set (struct type *type, struct ui_file *stream,
56                           int show, int level);
57 static int m2_long_set (struct type *type, struct ui_file *stream,
58                         int show, int level);
59 static void m2_record_fields (struct type *type, struct ui_file *stream,
60                               int show, int level);
61 static void m2_unknown (const char *s, struct type *type,
62                         struct ui_file *stream, int show, int level);
63
64 int m2_is_long_set (struct type *type);
65 int m2_is_long_set_of_type (struct type *type, struct type **of_type);
66
67
68 void
69 m2_print_type (struct type *type, char *varstring, struct ui_file *stream,
70                int show, int level)
71 {
72   enum type_code code;
73   int demangled_args;
74
75   CHECK_TYPEDEF (type);
76   code = TYPE_CODE (type);
77
78   QUIT;
79
80   wrap_here ("    ");
81   if (type == NULL)
82     {
83       fputs_filtered (_("<type unknown>"), stream);
84       return;
85     }
86
87   switch (TYPE_CODE (type))
88     {
89     case TYPE_CODE_SET:
90       m2_short_set(type, stream, show, level);
91       break;
92
93     case TYPE_CODE_STRUCT:
94       if (m2_long_set (type, stream, show, level))
95         break;
96       m2_record_fields (type, stream, show, level);
97       break;
98
99     case TYPE_CODE_TYPEDEF:
100       m2_typedef (type, stream, show, level);
101       break;
102
103     case TYPE_CODE_ARRAY:
104       m2_array (type, stream, show, level);
105       break;
106
107     case TYPE_CODE_PTR:
108       m2_pointer (type, stream, show, level);
109       break;
110
111     case TYPE_CODE_REF:
112       m2_ref (type, stream, show, level);
113       break;
114
115     case TYPE_CODE_MEMBER:
116       m2_unknown (_("member"), type, stream, show, level);
117       break;
118
119     case TYPE_CODE_METHOD:
120       m2_unknown (_("method"), type, stream, show, level);
121       break;
122
123     case TYPE_CODE_FUNC:
124       m2_procedure (type, stream, show, level);
125       break;
126
127     case TYPE_CODE_UNION:
128       m2_union (type, stream);
129       break;
130
131     case TYPE_CODE_ENUM:
132       m2_enum (type, stream, show, level);
133       break;
134
135     case TYPE_CODE_VOID:
136       break;
137
138     case TYPE_CODE_UNDEF:
139       /* i18n: Do not translate the "struct" part! */
140       m2_unknown (_("undef"), type, stream, show, level);
141       break;
142
143     case TYPE_CODE_ERROR:
144       m2_unknown (_("error"), type, stream, show, level);
145       break;
146
147     case TYPE_CODE_RANGE:
148       m2_range (type, stream, show, level);
149       break;
150
151     case TYPE_CODE_TEMPLATE:
152       break;
153
154     default:
155       m2_type_name (type, stream);
156       break;
157     }
158 }
159
160 /*
161  *  m2_type_name - if a, type, has a name then print it.
162  */
163
164 void
165 m2_type_name (struct type *type, struct ui_file *stream)
166 {
167   if (TYPE_NAME (type) != NULL)
168     fputs_filtered (TYPE_NAME (type), stream);
169 }
170
171 /*
172  *  m2_range - displays a Modula-2 subrange type.
173  */
174
175 void
176 m2_range (struct type *type, struct ui_file *stream, int show,
177           int level)
178 {
179   if (TYPE_HIGH_BOUND (type) == TYPE_LOW_BOUND (type))
180     m2_print_type (TYPE_DOMAIN_TYPE (type), "", stream, show, level);
181   else
182     {
183       struct type *target = TYPE_TARGET_TYPE (type);
184
185       fprintf_filtered (stream, "[");
186       print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
187       fprintf_filtered (stream, "..");
188       print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
189       fprintf_filtered (stream, "]");
190     }
191 }
192
193 static void
194 m2_typedef (struct type *type, struct ui_file *stream, int show,
195             int level)
196 {
197   if (TYPE_NAME (type) != NULL)
198     {
199       fputs_filtered (TYPE_NAME (type), stream);
200       fputs_filtered (" = ", stream);
201     }
202   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
203 }
204
205 /*
206  *  m2_array - prints out a Modula-2 ARRAY ... OF type
207  */
208
209 static void m2_array (struct type *type, struct ui_file *stream,
210                       int show, int level)
211 {
212   fprintf_filtered (stream, "ARRAY [");
213   if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
214       && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED)
215     {
216       if (TYPE_INDEX_TYPE (type) != 0)
217         {
218           m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 0);
219           fprintf_filtered (stream, "..");
220           m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 1);
221         }
222       else
223         fprintf_filtered (stream, "%d",
224                           (TYPE_LENGTH (type)
225                            / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
226     }
227   fprintf_filtered (stream, "] OF ");
228   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
229 }
230
231 static void
232 m2_pointer (struct type *type, struct ui_file *stream, int show,
233             int level)
234 {
235   if (TYPE_CONST (type))
236     fprintf_filtered (stream, "[...] : ");
237   else
238     fprintf_filtered (stream, "POINTER TO ");
239
240   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
241 }
242
243 static void
244 m2_ref (struct type *type, struct ui_file *stream, int show,
245         int level)
246 {
247   fprintf_filtered (stream, "VAR");
248   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
249 }
250
251 static void
252 m2_unknown (const char *s, struct type *type, struct ui_file *stream,
253             int show, int level)
254 {
255   fprintf_filtered (stream, "%s %s", s, _("is unknown"));
256 }
257
258 static void m2_union (struct type *type, struct ui_file *stream)
259 {
260   fprintf_filtered (stream, "union");
261 }
262
263 static void
264 m2_procedure (struct type *type, struct ui_file *stream,
265               int show, int level)
266 {
267   fprintf_filtered (stream, "PROCEDURE ");
268   m2_type_name (type, stream);
269   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
270     {
271       int i, len = TYPE_NFIELDS (type);
272
273       fprintf_filtered (stream, " (");
274       for (i = 0; i < len; i++)
275         {
276           if (i > 0)
277             {
278               fputs_filtered (", ", stream);
279               wrap_here ("    ");
280             }
281           m2_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
282         }
283       if (TYPE_TARGET_TYPE (type) != NULL)
284         {
285           fprintf_filtered (stream, " : ");
286           m2_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0);
287         }
288     }
289 }
290
291 static void
292 m2_print_bounds (struct type *type,
293                  struct ui_file *stream, int show, int level,
294                  int print_high)
295 {
296   struct type *target = TYPE_TARGET_TYPE (type);
297
298   if (target == NULL)
299     target = builtin_type_int;
300
301   if (TYPE_NFIELDS(type) == 0)
302     return;
303
304   if (print_high)
305     print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
306   else
307     print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
308 }
309
310 static void
311 m2_short_set (struct type *type, struct ui_file *stream, int show, int level)
312 {
313   fprintf_filtered(stream, "SET [");
314   m2_print_bounds (TYPE_INDEX_TYPE (type), stream,
315                    show - 1, level, 0);
316
317   fprintf_filtered(stream, "..");
318   m2_print_bounds (TYPE_INDEX_TYPE (type), stream,
319                    show - 1, level, 1);
320   fprintf_filtered(stream, "]");
321 }
322
323 int
324 m2_is_long_set (struct type *type)
325 {
326   LONGEST previous_high = 0;  /* unnecessary initialization
327                                  keeps gcc -Wall happy */
328   int len, i;
329   struct type *range;
330
331   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
332     {
333
334       /*
335        *  check if all fields of the RECORD are consecutive sets
336        */
337       len = TYPE_NFIELDS (type);
338       for (i = TYPE_N_BASECLASSES (type); i < len; i++)
339         {
340           if (TYPE_FIELD_TYPE (type, i) == NULL)
341             return 0;
342           if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) != TYPE_CODE_SET)
343             return 0;
344           if (TYPE_FIELD_NAME (type, i) != NULL
345               && (strcmp (TYPE_FIELD_NAME (type, i), "") != 0))
346             return 0;
347           range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i));
348           if ((i > TYPE_N_BASECLASSES (type))
349               && previous_high + 1 != TYPE_LOW_BOUND (range))
350             return 0;
351           previous_high = TYPE_HIGH_BOUND (range);
352         }
353       return len>0;
354     }
355   return 0;
356 }
357
358 /*
359  *  m2_get_discrete_bounds - a wrapper for get_discrete_bounds which
360  *                           understands that CHARs might be signed.
361  *                           This should be integrated into gdbtypes.c
362  *                           inside get_discrete_bounds.
363  */
364
365 int
366 m2_get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
367 {
368   CHECK_TYPEDEF (type);
369   switch (TYPE_CODE (type))
370     {
371     case TYPE_CODE_CHAR:
372       if (TYPE_LENGTH (type) < sizeof (LONGEST))
373         {
374           if (!TYPE_UNSIGNED (type))
375             {
376               *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
377               *highp = -*lowp - 1;
378               return 0;
379             }
380         }
381       /* fall through */
382     default:
383       return get_discrete_bounds (type, lowp, highp);
384     }
385 }
386
387 /*
388  *  m2_is_long_set_of_type - returns TRUE if the long set was declared as
389  *                           SET OF <oftype> of_type is assigned to the
390  *                           subtype.
391  */
392
393 int
394 m2_is_long_set_of_type (struct type *type, struct type **of_type)
395 {
396   int len, i;
397   struct type *range;
398   struct type *target;
399   LONGEST l1, l2;
400   LONGEST h1, h2;
401
402   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
403     {
404       len = TYPE_NFIELDS (type);
405       i = TYPE_N_BASECLASSES (type);
406       if (len == 0)
407         return 0;
408       range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i));
409       target = TYPE_TARGET_TYPE (range);
410       if (target == NULL)
411         target = builtin_type_int;
412
413       l1 = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)));
414       h1 = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)));
415       *of_type = target;
416       if (m2_get_discrete_bounds (target, &l2, &h2) >= 0)
417         return (l1 == l2 && h1 == h2);
418       error (_("long_set failed to find discrete bounds for its subtype"));
419       return 0;
420     }
421   error (_("expecting long_set"));
422   return 0;
423 }
424
425 static int
426 m2_long_set (struct type *type, struct ui_file *stream, int show, int level)
427 {
428   struct type *index_type;
429   struct type *range_type;
430   struct type *of_type;
431   int i;
432   int len = TYPE_NFIELDS (type);
433   LONGEST low;
434   LONGEST high;
435
436   if (m2_is_long_set (type))
437     {
438       if (TYPE_TAG_NAME (type) != NULL)
439         {
440           fputs_filtered (TYPE_TAG_NAME (type), stream);
441           if (show == 0)
442             return 1;
443         }
444       else if (TYPE_NAME (type) != NULL)
445         {
446           fputs_filtered (TYPE_NAME (type), stream);
447           if (show == 0)
448             return 1;
449         }
450
451       if (TYPE_TAG_NAME (type) != NULL || TYPE_NAME (type) != NULL)
452         fputs_filtered (" = ", stream);
453
454       if (get_long_set_bounds (type, &low, &high))
455         {
456           fprintf_filtered(stream, "SET OF ");
457           i = TYPE_N_BASECLASSES (type);
458           if (m2_is_long_set_of_type (type, &of_type))
459             m2_print_type (of_type, "", stream, show - 1, level);
460           else
461             {
462               fprintf_filtered(stream, "[");
463               m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)),
464                                stream, show - 1, level, 0);
465
466               fprintf_filtered(stream, "..");
467
468               m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)),
469                                stream, show - 1, level, 1);
470               fprintf_filtered(stream, "]");
471             }
472         }
473       else
474         /* i18n: Do not translate the "SET OF" part! */
475         fprintf_filtered(stream, _("SET OF <unknown>"));
476
477       return 1;
478     }
479   return 0;
480 }
481
482 void
483 m2_record_fields (struct type *type, struct ui_file *stream, int show,
484                   int level)
485 {
486   /* Print the tag if it exists. 
487    */
488   if (TYPE_TAG_NAME (type) != NULL)
489     {
490       if (strncmp (TYPE_TAG_NAME (type), "$$", 2) != 0)
491         {
492           fputs_filtered (TYPE_TAG_NAME (type), stream);
493           if (show > 0)
494             fprintf_filtered (stream, " = ");
495         }
496     }
497   wrap_here ("    ");
498   if (show < 0)
499     {
500       if (TYPE_CODE (type) == DECLARED_TYPE_STRUCT)
501         fprintf_filtered (stream, "RECORD ... END ");
502       else if (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION)
503         fprintf_filtered (stream, "CASE ... END ");
504     }
505   else if (show > 0)
506     {
507       if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
508         fprintf_filtered (stream, "RECORD\n");
509       else if (TYPE_CODE (type) == TYPE_CODE_UNION)
510         /* i18n: Do not translate "CASE" and "OF" */
511         fprintf_filtered (stream, _("CASE <variant> OF\n"));
512       int i;
513       int len = TYPE_NFIELDS (type);
514
515       for (i = TYPE_N_BASECLASSES (type); i < len; i++)
516         {
517           QUIT;
518
519           print_spaces_filtered (level + 4, stream);
520           fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
521           fputs_filtered (" : ", stream);
522           m2_print_type (TYPE_FIELD_TYPE (type, i),
523                          "",
524                          stream, 0, level + 4);
525           if (TYPE_FIELD_PACKED (type, i))
526             {
527               /* It is a bitfield.  This code does not attempt
528                  to look at the bitpos and reconstruct filler,
529                  unnamed fields.  This would lead to misleading
530                  results if the compiler does not put out fields
531                  for such things (I don't know what it does).  */
532               fprintf_filtered (stream, " : %d",
533                                 TYPE_FIELD_BITSIZE (type, i));
534             }
535           fprintf_filtered (stream, ";\n");
536         }
537       
538       fprintfi_filtered (level, stream, "END ");
539     }
540 }
541
542 void
543 m2_enum (struct type *type, struct ui_file *stream, int show, int level)
544 {
545   int lastval, i, len;
546
547   if (show < 0)
548     {
549       /* If we just printed a tag name, no need to print anything else.  */
550       if (TYPE_TAG_NAME (type) == NULL)
551         fprintf_filtered (stream, "(...)");
552     }
553   else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
554     {
555       fprintf_filtered (stream, "(");
556       len = TYPE_NFIELDS (type);
557       lastval = 0;
558       for (i = 0; i < len; i++)
559         {
560           QUIT;
561           if (i > 0)
562             fprintf_filtered (stream, ", ");
563           wrap_here ("    ");
564           fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
565           if (lastval != TYPE_FIELD_BITPOS (type, i))
566             {
567               fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
568               lastval = TYPE_FIELD_BITPOS (type, i);
569             }
570           lastval++;
571         }
572       fprintf_filtered (stream, ")");
573     }
574 }