xref: /dragonfly/contrib/gdb-7/gdb/m2-typeprint.c (revision ef5ccd6c)
15796c8dcSSimon Schubert /* Support for printing Modula 2 types for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert 
45796c8dcSSimon Schubert    This file is part of GDB.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
75796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
85796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
95796c8dcSSimon Schubert    (at your option) any later version.
105796c8dcSSimon Schubert 
115796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
125796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
135796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145796c8dcSSimon Schubert    GNU General Public License for more details.
155796c8dcSSimon Schubert 
165796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
175796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert #include "defs.h"
205796c8dcSSimon Schubert #include "gdb_obstack.h"
215796c8dcSSimon Schubert #include "bfd.h"		/* Binary File Description */
225796c8dcSSimon Schubert #include "symtab.h"
235796c8dcSSimon Schubert #include "gdbtypes.h"
245796c8dcSSimon Schubert #include "expression.h"
255796c8dcSSimon Schubert #include "value.h"
265796c8dcSSimon Schubert #include "gdbcore.h"
275796c8dcSSimon Schubert #include "m2-lang.h"
285796c8dcSSimon Schubert #include "target.h"
295796c8dcSSimon Schubert #include "language.h"
305796c8dcSSimon Schubert #include "demangle.h"
315796c8dcSSimon Schubert #include "c-lang.h"
325796c8dcSSimon Schubert #include "typeprint.h"
335796c8dcSSimon Schubert #include "cp-abi.h"
345796c8dcSSimon Schubert 
355796c8dcSSimon Schubert #include "gdb_string.h"
365796c8dcSSimon Schubert #include <errno.h>
375796c8dcSSimon Schubert 
385796c8dcSSimon Schubert static void m2_print_bounds (struct type *type,
395796c8dcSSimon Schubert 			     struct ui_file *stream, int show, int level,
405796c8dcSSimon Schubert 			     int print_high);
415796c8dcSSimon Schubert 
42*ef5ccd6cSJohn Marino static void m2_typedef (struct type *, struct ui_file *, int, int,
43*ef5ccd6cSJohn Marino 			const struct type_print_options *);
44*ef5ccd6cSJohn Marino static void m2_array (struct type *, struct ui_file *, int, int,
45*ef5ccd6cSJohn Marino 		      const struct type_print_options *);
46*ef5ccd6cSJohn Marino static void m2_pointer (struct type *, struct ui_file *, int, int,
47*ef5ccd6cSJohn Marino 			const struct type_print_options *);
48*ef5ccd6cSJohn Marino static void m2_ref (struct type *, struct ui_file *, int, int,
49*ef5ccd6cSJohn Marino 		    const struct type_print_options *);
50*ef5ccd6cSJohn Marino static void m2_procedure (struct type *, struct ui_file *, int, int,
51*ef5ccd6cSJohn Marino 			  const struct type_print_options *);
525796c8dcSSimon Schubert static void m2_union (struct type *, struct ui_file *);
535796c8dcSSimon Schubert static void m2_enum (struct type *, struct ui_file *, int, int);
54*ef5ccd6cSJohn Marino static void m2_range (struct type *, struct ui_file *, int, int,
55*ef5ccd6cSJohn Marino 		      const struct type_print_options *);
565796c8dcSSimon Schubert static void m2_type_name (struct type *type, struct ui_file *stream);
575796c8dcSSimon Schubert static void m2_short_set (struct type *type, struct ui_file *stream,
585796c8dcSSimon Schubert 			  int show, int level);
595796c8dcSSimon Schubert static int m2_long_set (struct type *type, struct ui_file *stream,
60*ef5ccd6cSJohn Marino 			int show, int level, const struct type_print_options *flags);
615796c8dcSSimon Schubert static int m2_unbounded_array (struct type *type, struct ui_file *stream,
62*ef5ccd6cSJohn Marino 			       int show, int level,
63*ef5ccd6cSJohn Marino 			       const struct type_print_options *flags);
645796c8dcSSimon Schubert static void m2_record_fields (struct type *type, struct ui_file *stream,
65*ef5ccd6cSJohn Marino 			      int show, int level, const struct type_print_options *flags);
665796c8dcSSimon Schubert static void m2_unknown (const char *s, struct type *type,
675796c8dcSSimon Schubert 			struct ui_file *stream, int show, int level);
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert int m2_is_long_set (struct type *type);
705796c8dcSSimon Schubert int m2_is_long_set_of_type (struct type *type, struct type **of_type);
715796c8dcSSimon Schubert int m2_is_unbounded_array (struct type *type);
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert 
745796c8dcSSimon Schubert void
m2_print_type(struct type * type,const char * varstring,struct ui_file * stream,int show,int level,const struct type_print_options * flags)75c50c785cSJohn Marino m2_print_type (struct type *type, const char *varstring,
76c50c785cSJohn Marino 	       struct ui_file *stream,
77*ef5ccd6cSJohn Marino 	       int show, int level,
78*ef5ccd6cSJohn Marino 	       const struct type_print_options *flags)
795796c8dcSSimon Schubert {
805796c8dcSSimon Schubert   CHECK_TYPEDEF (type);
815796c8dcSSimon Schubert 
825796c8dcSSimon Schubert   QUIT;
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert   wrap_here ("    ");
855796c8dcSSimon Schubert   if (type == NULL)
865796c8dcSSimon Schubert     {
875796c8dcSSimon Schubert       fputs_filtered (_("<type unknown>"), stream);
885796c8dcSSimon Schubert       return;
895796c8dcSSimon Schubert     }
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert   switch (TYPE_CODE (type))
925796c8dcSSimon Schubert     {
935796c8dcSSimon Schubert     case TYPE_CODE_SET:
945796c8dcSSimon Schubert       m2_short_set(type, stream, show, level);
955796c8dcSSimon Schubert       break;
965796c8dcSSimon Schubert 
975796c8dcSSimon Schubert     case TYPE_CODE_STRUCT:
98*ef5ccd6cSJohn Marino       if (m2_long_set (type, stream, show, level, flags)
99*ef5ccd6cSJohn Marino 	  || m2_unbounded_array (type, stream, show, level, flags))
1005796c8dcSSimon Schubert 	break;
101*ef5ccd6cSJohn Marino       m2_record_fields (type, stream, show, level, flags);
1025796c8dcSSimon Schubert       break;
1035796c8dcSSimon Schubert 
1045796c8dcSSimon Schubert     case TYPE_CODE_TYPEDEF:
105*ef5ccd6cSJohn Marino       m2_typedef (type, stream, show, level, flags);
1065796c8dcSSimon Schubert       break;
1075796c8dcSSimon Schubert 
1085796c8dcSSimon Schubert     case TYPE_CODE_ARRAY:
109*ef5ccd6cSJohn Marino       m2_array (type, stream, show, level, flags);
1105796c8dcSSimon Schubert       break;
1115796c8dcSSimon Schubert 
1125796c8dcSSimon Schubert     case TYPE_CODE_PTR:
113*ef5ccd6cSJohn Marino       m2_pointer (type, stream, show, level, flags);
1145796c8dcSSimon Schubert       break;
1155796c8dcSSimon Schubert 
1165796c8dcSSimon Schubert     case TYPE_CODE_REF:
117*ef5ccd6cSJohn Marino       m2_ref (type, stream, show, level, flags);
1185796c8dcSSimon Schubert       break;
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert     case TYPE_CODE_METHOD:
1215796c8dcSSimon Schubert       m2_unknown (_("method"), type, stream, show, level);
1225796c8dcSSimon Schubert       break;
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert     case TYPE_CODE_FUNC:
125*ef5ccd6cSJohn Marino       m2_procedure (type, stream, show, level, flags);
1265796c8dcSSimon Schubert       break;
1275796c8dcSSimon Schubert 
1285796c8dcSSimon Schubert     case TYPE_CODE_UNION:
1295796c8dcSSimon Schubert       m2_union (type, stream);
1305796c8dcSSimon Schubert       break;
1315796c8dcSSimon Schubert 
1325796c8dcSSimon Schubert     case TYPE_CODE_ENUM:
1335796c8dcSSimon Schubert       m2_enum (type, stream, show, level);
1345796c8dcSSimon Schubert       break;
1355796c8dcSSimon Schubert 
1365796c8dcSSimon Schubert     case TYPE_CODE_VOID:
1375796c8dcSSimon Schubert       break;
1385796c8dcSSimon Schubert 
1395796c8dcSSimon Schubert     case TYPE_CODE_UNDEF:
1405796c8dcSSimon Schubert       /* i18n: Do not translate the "struct" part!  */
1415796c8dcSSimon Schubert       m2_unknown (_("undef"), type, stream, show, level);
1425796c8dcSSimon Schubert       break;
1435796c8dcSSimon Schubert 
1445796c8dcSSimon Schubert     case TYPE_CODE_ERROR:
1455796c8dcSSimon Schubert       m2_unknown (_("error"), type, stream, show, level);
1465796c8dcSSimon Schubert       break;
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert     case TYPE_CODE_RANGE:
149*ef5ccd6cSJohn Marino       m2_range (type, stream, show, level, flags);
1505796c8dcSSimon Schubert       break;
1515796c8dcSSimon Schubert 
1525796c8dcSSimon Schubert     default:
1535796c8dcSSimon Schubert       m2_type_name (type, stream);
1545796c8dcSSimon Schubert       break;
1555796c8dcSSimon Schubert     }
1565796c8dcSSimon Schubert }
1575796c8dcSSimon Schubert 
1585796c8dcSSimon Schubert /* Print a typedef using M2 syntax.  TYPE is the underlying type.
1595796c8dcSSimon Schubert    NEW_SYMBOL is the symbol naming the type.  STREAM is the stream on
1605796c8dcSSimon Schubert    which to print.  */
1615796c8dcSSimon Schubert 
1625796c8dcSSimon Schubert void
m2_print_typedef(struct type * type,struct symbol * new_symbol,struct ui_file * stream)1635796c8dcSSimon Schubert m2_print_typedef (struct type *type, struct symbol *new_symbol,
1645796c8dcSSimon Schubert 		  struct ui_file *stream)
1655796c8dcSSimon Schubert {
1665796c8dcSSimon Schubert   CHECK_TYPEDEF (type);
1675796c8dcSSimon Schubert   fprintf_filtered (stream, "TYPE ");
1685796c8dcSSimon Schubert   if (!TYPE_NAME (SYMBOL_TYPE (new_symbol))
1695796c8dcSSimon Schubert       || strcmp (TYPE_NAME ((SYMBOL_TYPE (new_symbol))),
1705796c8dcSSimon Schubert 		 SYMBOL_LINKAGE_NAME (new_symbol)) != 0)
1715796c8dcSSimon Schubert     fprintf_filtered (stream, "%s = ", SYMBOL_PRINT_NAME (new_symbol));
1725796c8dcSSimon Schubert   else
1735796c8dcSSimon Schubert     fprintf_filtered (stream, "<builtin> = ");
1745796c8dcSSimon Schubert   type_print (type, "", stream, 0);
1755796c8dcSSimon Schubert   fprintf_filtered (stream, ";\n");
1765796c8dcSSimon Schubert }
1775796c8dcSSimon Schubert 
1785796c8dcSSimon Schubert /* m2_type_name - if a, type, has a name then print it.  */
1795796c8dcSSimon Schubert 
1805796c8dcSSimon Schubert void
m2_type_name(struct type * type,struct ui_file * stream)1815796c8dcSSimon Schubert m2_type_name (struct type *type, struct ui_file *stream)
1825796c8dcSSimon Schubert {
1835796c8dcSSimon Schubert   if (TYPE_NAME (type) != NULL)
1845796c8dcSSimon Schubert     fputs_filtered (TYPE_NAME (type), stream);
1855796c8dcSSimon Schubert }
1865796c8dcSSimon Schubert 
1875796c8dcSSimon Schubert /* m2_range - displays a Modula-2 subrange type.  */
1885796c8dcSSimon Schubert 
1895796c8dcSSimon Schubert void
m2_range(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)1905796c8dcSSimon Schubert m2_range (struct type *type, struct ui_file *stream, int show,
191*ef5ccd6cSJohn Marino 	  int level, const struct type_print_options *flags)
1925796c8dcSSimon Schubert {
1935796c8dcSSimon Schubert   if (TYPE_HIGH_BOUND (type) == TYPE_LOW_BOUND (type))
194*ef5ccd6cSJohn Marino     m2_print_type (TYPE_DOMAIN_TYPE (type), "", stream, show, level,
195*ef5ccd6cSJohn Marino 		   flags);
1965796c8dcSSimon Schubert   else
1975796c8dcSSimon Schubert     {
1985796c8dcSSimon Schubert       struct type *target = TYPE_TARGET_TYPE (type);
1995796c8dcSSimon Schubert 
2005796c8dcSSimon Schubert       fprintf_filtered (stream, "[");
2015796c8dcSSimon Schubert       print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
2025796c8dcSSimon Schubert       fprintf_filtered (stream, "..");
2035796c8dcSSimon Schubert       print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
2045796c8dcSSimon Schubert       fprintf_filtered (stream, "]");
2055796c8dcSSimon Schubert     }
2065796c8dcSSimon Schubert }
2075796c8dcSSimon Schubert 
2085796c8dcSSimon Schubert static void
m2_typedef(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)2095796c8dcSSimon Schubert m2_typedef (struct type *type, struct ui_file *stream, int show,
210*ef5ccd6cSJohn Marino 	    int level, const struct type_print_options *flags)
2115796c8dcSSimon Schubert {
2125796c8dcSSimon Schubert   if (TYPE_NAME (type) != NULL)
2135796c8dcSSimon Schubert     {
2145796c8dcSSimon Schubert       fputs_filtered (TYPE_NAME (type), stream);
2155796c8dcSSimon Schubert       fputs_filtered (" = ", stream);
2165796c8dcSSimon Schubert     }
217*ef5ccd6cSJohn Marino   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level, flags);
2185796c8dcSSimon Schubert }
2195796c8dcSSimon Schubert 
2205796c8dcSSimon Schubert /* m2_array - prints out a Modula-2 ARRAY ... OF type.  */
2215796c8dcSSimon Schubert 
m2_array(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)2225796c8dcSSimon Schubert static void m2_array (struct type *type, struct ui_file *stream,
223*ef5ccd6cSJohn Marino 		      int show, int level, const struct type_print_options *flags)
2245796c8dcSSimon Schubert {
2255796c8dcSSimon Schubert   fprintf_filtered (stream, "ARRAY [");
2265796c8dcSSimon Schubert   if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
2275796c8dcSSimon Schubert       && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
2285796c8dcSSimon Schubert     {
2295796c8dcSSimon Schubert       if (TYPE_INDEX_TYPE (type) != 0)
2305796c8dcSSimon Schubert 	{
2315796c8dcSSimon Schubert 	  m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 0);
2325796c8dcSSimon Schubert 	  fprintf_filtered (stream, "..");
2335796c8dcSSimon Schubert 	  m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 1);
2345796c8dcSSimon Schubert 	}
2355796c8dcSSimon Schubert       else
2365796c8dcSSimon Schubert 	fprintf_filtered (stream, "%d",
2375796c8dcSSimon Schubert 			  (TYPE_LENGTH (type)
2385796c8dcSSimon Schubert 			   / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
2395796c8dcSSimon Schubert     }
2405796c8dcSSimon Schubert   fprintf_filtered (stream, "] OF ");
241*ef5ccd6cSJohn Marino   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level, flags);
2425796c8dcSSimon Schubert }
2435796c8dcSSimon Schubert 
2445796c8dcSSimon Schubert static void
m2_pointer(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)2455796c8dcSSimon Schubert m2_pointer (struct type *type, struct ui_file *stream, int show,
246*ef5ccd6cSJohn Marino 	    int level, const struct type_print_options *flags)
2475796c8dcSSimon Schubert {
2485796c8dcSSimon Schubert   if (TYPE_CONST (type))
2495796c8dcSSimon Schubert     fprintf_filtered (stream, "[...] : ");
2505796c8dcSSimon Schubert   else
2515796c8dcSSimon Schubert     fprintf_filtered (stream, "POINTER TO ");
2525796c8dcSSimon Schubert 
253*ef5ccd6cSJohn Marino   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level, flags);
2545796c8dcSSimon Schubert }
2555796c8dcSSimon Schubert 
2565796c8dcSSimon Schubert static void
m2_ref(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)2575796c8dcSSimon Schubert m2_ref (struct type *type, struct ui_file *stream, int show,
258*ef5ccd6cSJohn Marino 	int level, const struct type_print_options *flags)
2595796c8dcSSimon Schubert {
2605796c8dcSSimon Schubert   fprintf_filtered (stream, "VAR");
261*ef5ccd6cSJohn Marino   m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level, flags);
2625796c8dcSSimon Schubert }
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert static void
m2_unknown(const char * s,struct type * type,struct ui_file * stream,int show,int level)2655796c8dcSSimon Schubert m2_unknown (const char *s, struct type *type, struct ui_file *stream,
2665796c8dcSSimon Schubert 	    int show, int level)
2675796c8dcSSimon Schubert {
2685796c8dcSSimon Schubert   fprintf_filtered (stream, "%s %s", s, _("is unknown"));
2695796c8dcSSimon Schubert }
2705796c8dcSSimon Schubert 
m2_union(struct type * type,struct ui_file * stream)2715796c8dcSSimon Schubert static void m2_union (struct type *type, struct ui_file *stream)
2725796c8dcSSimon Schubert {
2735796c8dcSSimon Schubert   fprintf_filtered (stream, "union");
2745796c8dcSSimon Schubert }
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert static void
m2_procedure(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)2775796c8dcSSimon Schubert m2_procedure (struct type *type, struct ui_file *stream,
278*ef5ccd6cSJohn Marino 	      int show, int level, const struct type_print_options *flags)
2795796c8dcSSimon Schubert {
2805796c8dcSSimon Schubert   fprintf_filtered (stream, "PROCEDURE ");
2815796c8dcSSimon Schubert   m2_type_name (type, stream);
2825796c8dcSSimon Schubert   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
2835796c8dcSSimon Schubert     {
2845796c8dcSSimon Schubert       int i, len = TYPE_NFIELDS (type);
2855796c8dcSSimon Schubert 
2865796c8dcSSimon Schubert       fprintf_filtered (stream, " (");
2875796c8dcSSimon Schubert       for (i = 0; i < len; i++)
2885796c8dcSSimon Schubert 	{
2895796c8dcSSimon Schubert 	  if (i > 0)
2905796c8dcSSimon Schubert 	    {
2915796c8dcSSimon Schubert 	      fputs_filtered (", ", stream);
2925796c8dcSSimon Schubert 	      wrap_here ("    ");
2935796c8dcSSimon Schubert 	    }
294*ef5ccd6cSJohn Marino 	  m2_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0, flags);
2955796c8dcSSimon Schubert 	}
2965796c8dcSSimon Schubert       if (TYPE_TARGET_TYPE (type) != NULL)
2975796c8dcSSimon Schubert 	{
2985796c8dcSSimon Schubert 	  fprintf_filtered (stream, " : ");
299*ef5ccd6cSJohn Marino 	  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
3005796c8dcSSimon Schubert 	}
3015796c8dcSSimon Schubert     }
3025796c8dcSSimon Schubert }
3035796c8dcSSimon Schubert 
3045796c8dcSSimon Schubert static void
m2_print_bounds(struct type * type,struct ui_file * stream,int show,int level,int print_high)3055796c8dcSSimon Schubert m2_print_bounds (struct type *type,
3065796c8dcSSimon Schubert 		 struct ui_file *stream, int show, int level,
3075796c8dcSSimon Schubert 		 int print_high)
3085796c8dcSSimon Schubert {
3095796c8dcSSimon Schubert   struct type *target = TYPE_TARGET_TYPE (type);
3105796c8dcSSimon Schubert 
3115796c8dcSSimon Schubert   if (TYPE_NFIELDS(type) == 0)
3125796c8dcSSimon Schubert     return;
3135796c8dcSSimon Schubert 
3145796c8dcSSimon Schubert   if (print_high)
3155796c8dcSSimon Schubert     print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
3165796c8dcSSimon Schubert   else
3175796c8dcSSimon Schubert     print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
3185796c8dcSSimon Schubert }
3195796c8dcSSimon Schubert 
3205796c8dcSSimon Schubert static void
m2_short_set(struct type * type,struct ui_file * stream,int show,int level)3215796c8dcSSimon Schubert m2_short_set (struct type *type, struct ui_file *stream, int show, int level)
3225796c8dcSSimon Schubert {
3235796c8dcSSimon Schubert   fprintf_filtered(stream, "SET [");
3245796c8dcSSimon Schubert   m2_print_bounds (TYPE_INDEX_TYPE (type), stream,
3255796c8dcSSimon Schubert 		   show - 1, level, 0);
3265796c8dcSSimon Schubert 
3275796c8dcSSimon Schubert   fprintf_filtered(stream, "..");
3285796c8dcSSimon Schubert   m2_print_bounds (TYPE_INDEX_TYPE (type), stream,
3295796c8dcSSimon Schubert 		   show - 1, level, 1);
3305796c8dcSSimon Schubert   fprintf_filtered(stream, "]");
3315796c8dcSSimon Schubert }
3325796c8dcSSimon Schubert 
3335796c8dcSSimon Schubert int
m2_is_long_set(struct type * type)3345796c8dcSSimon Schubert m2_is_long_set (struct type *type)
3355796c8dcSSimon Schubert {
336c50c785cSJohn Marino   LONGEST previous_high = 0;  /* Unnecessary initialization
337c50c785cSJohn Marino 				 keeps gcc -Wall happy.  */
3385796c8dcSSimon Schubert   int len, i;
3395796c8dcSSimon Schubert   struct type *range;
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
3425796c8dcSSimon Schubert     {
3435796c8dcSSimon Schubert 
3445796c8dcSSimon Schubert       /* check if all fields of the RECORD are consecutive sets.  */
3455796c8dcSSimon Schubert 
3465796c8dcSSimon Schubert       len = TYPE_NFIELDS (type);
3475796c8dcSSimon Schubert       for (i = TYPE_N_BASECLASSES (type); i < len; i++)
3485796c8dcSSimon Schubert 	{
3495796c8dcSSimon Schubert 	  if (TYPE_FIELD_TYPE (type, i) == NULL)
3505796c8dcSSimon Schubert 	    return 0;
3515796c8dcSSimon Schubert 	  if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) != TYPE_CODE_SET)
3525796c8dcSSimon Schubert 	    return 0;
3535796c8dcSSimon Schubert 	  if (TYPE_FIELD_NAME (type, i) != NULL
3545796c8dcSSimon Schubert 	      && (strcmp (TYPE_FIELD_NAME (type, i), "") != 0))
3555796c8dcSSimon Schubert 	    return 0;
3565796c8dcSSimon Schubert 	  range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i));
3575796c8dcSSimon Schubert 	  if ((i > TYPE_N_BASECLASSES (type))
3585796c8dcSSimon Schubert 	      && previous_high + 1 != TYPE_LOW_BOUND (range))
3595796c8dcSSimon Schubert 	    return 0;
3605796c8dcSSimon Schubert 	  previous_high = TYPE_HIGH_BOUND (range);
3615796c8dcSSimon Schubert 	}
3625796c8dcSSimon Schubert       return len>0;
3635796c8dcSSimon Schubert     }
3645796c8dcSSimon Schubert   return 0;
3655796c8dcSSimon Schubert }
3665796c8dcSSimon Schubert 
3675796c8dcSSimon Schubert /* m2_get_discrete_bounds - a wrapper for get_discrete_bounds which
3685796c8dcSSimon Schubert                             understands that CHARs might be signed.
3695796c8dcSSimon Schubert                             This should be integrated into gdbtypes.c
3705796c8dcSSimon Schubert                             inside get_discrete_bounds.  */
3715796c8dcSSimon Schubert 
3725796c8dcSSimon Schubert static int
m2_get_discrete_bounds(struct type * type,LONGEST * lowp,LONGEST * highp)3735796c8dcSSimon Schubert m2_get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
3745796c8dcSSimon Schubert {
3755796c8dcSSimon Schubert   CHECK_TYPEDEF (type);
3765796c8dcSSimon Schubert   switch (TYPE_CODE (type))
3775796c8dcSSimon Schubert     {
3785796c8dcSSimon Schubert     case TYPE_CODE_CHAR:
3795796c8dcSSimon Schubert       if (TYPE_LENGTH (type) < sizeof (LONGEST))
3805796c8dcSSimon Schubert 	{
3815796c8dcSSimon Schubert 	  if (!TYPE_UNSIGNED (type))
3825796c8dcSSimon Schubert 	    {
3835796c8dcSSimon Schubert 	      *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
3845796c8dcSSimon Schubert 	      *highp = -*lowp - 1;
3855796c8dcSSimon Schubert 	      return 0;
3865796c8dcSSimon Schubert 	    }
3875796c8dcSSimon Schubert 	}
3885796c8dcSSimon Schubert       /* fall through */
3895796c8dcSSimon Schubert     default:
3905796c8dcSSimon Schubert       return get_discrete_bounds (type, lowp, highp);
3915796c8dcSSimon Schubert     }
3925796c8dcSSimon Schubert }
3935796c8dcSSimon Schubert 
3945796c8dcSSimon Schubert /* m2_is_long_set_of_type - returns TRUE if the long set was declared as
3955796c8dcSSimon Schubert                             SET OF <oftype> of_type is assigned to the
3965796c8dcSSimon Schubert                             subtype.  */
3975796c8dcSSimon Schubert 
3985796c8dcSSimon Schubert int
m2_is_long_set_of_type(struct type * type,struct type ** of_type)3995796c8dcSSimon Schubert m2_is_long_set_of_type (struct type *type, struct type **of_type)
4005796c8dcSSimon Schubert {
4015796c8dcSSimon Schubert   int len, i;
4025796c8dcSSimon Schubert   struct type *range;
4035796c8dcSSimon Schubert   struct type *target;
4045796c8dcSSimon Schubert   LONGEST l1, l2;
4055796c8dcSSimon Schubert   LONGEST h1, h2;
4065796c8dcSSimon Schubert 
4075796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
4085796c8dcSSimon Schubert     {
4095796c8dcSSimon Schubert       len = TYPE_NFIELDS (type);
4105796c8dcSSimon Schubert       i = TYPE_N_BASECLASSES (type);
4115796c8dcSSimon Schubert       if (len == 0)
4125796c8dcSSimon Schubert 	return 0;
4135796c8dcSSimon Schubert       range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i));
4145796c8dcSSimon Schubert       target = TYPE_TARGET_TYPE (range);
4155796c8dcSSimon Schubert 
4165796c8dcSSimon Schubert       l1 = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)));
4175796c8dcSSimon Schubert       h1 = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)));
4185796c8dcSSimon Schubert       *of_type = target;
4195796c8dcSSimon Schubert       if (m2_get_discrete_bounds (target, &l2, &h2) >= 0)
4205796c8dcSSimon Schubert 	return (l1 == l2 && h1 == h2);
4215796c8dcSSimon Schubert       error (_("long_set failed to find discrete bounds for its subtype"));
4225796c8dcSSimon Schubert       return 0;
4235796c8dcSSimon Schubert     }
4245796c8dcSSimon Schubert   error (_("expecting long_set"));
4255796c8dcSSimon Schubert   return 0;
4265796c8dcSSimon Schubert }
4275796c8dcSSimon Schubert 
4285796c8dcSSimon Schubert static int
m2_long_set(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)429*ef5ccd6cSJohn Marino m2_long_set (struct type *type, struct ui_file *stream, int show, int level,
430*ef5ccd6cSJohn Marino 	     const struct type_print_options *flags)
4315796c8dcSSimon Schubert {
4325796c8dcSSimon Schubert   struct type *of_type;
4335796c8dcSSimon Schubert   int i;
4345796c8dcSSimon Schubert   int len = TYPE_NFIELDS (type);
4355796c8dcSSimon Schubert   LONGEST low;
4365796c8dcSSimon Schubert   LONGEST high;
4375796c8dcSSimon Schubert 
4385796c8dcSSimon Schubert   if (m2_is_long_set (type))
4395796c8dcSSimon Schubert     {
4405796c8dcSSimon Schubert       if (TYPE_TAG_NAME (type) != NULL)
4415796c8dcSSimon Schubert 	{
4425796c8dcSSimon Schubert 	  fputs_filtered (TYPE_TAG_NAME (type), stream);
4435796c8dcSSimon Schubert 	  if (show == 0)
4445796c8dcSSimon Schubert 	    return 1;
4455796c8dcSSimon Schubert 	}
4465796c8dcSSimon Schubert       else if (TYPE_NAME (type) != NULL)
4475796c8dcSSimon Schubert 	{
4485796c8dcSSimon Schubert 	  fputs_filtered (TYPE_NAME (type), stream);
4495796c8dcSSimon Schubert 	  if (show == 0)
4505796c8dcSSimon Schubert 	    return 1;
4515796c8dcSSimon Schubert 	}
4525796c8dcSSimon Schubert 
4535796c8dcSSimon Schubert       if (TYPE_TAG_NAME (type) != NULL || TYPE_NAME (type) != NULL)
4545796c8dcSSimon Schubert 	fputs_filtered (" = ", stream);
4555796c8dcSSimon Schubert 
4565796c8dcSSimon Schubert       if (get_long_set_bounds (type, &low, &high))
4575796c8dcSSimon Schubert 	{
4585796c8dcSSimon Schubert 	  fprintf_filtered(stream, "SET OF ");
4595796c8dcSSimon Schubert 	  i = TYPE_N_BASECLASSES (type);
4605796c8dcSSimon Schubert 	  if (m2_is_long_set_of_type (type, &of_type))
461*ef5ccd6cSJohn Marino 	    m2_print_type (of_type, "", stream, show - 1, level, flags);
4625796c8dcSSimon Schubert 	  else
4635796c8dcSSimon Schubert 	    {
4645796c8dcSSimon Schubert 	      fprintf_filtered(stream, "[");
4655796c8dcSSimon Schubert 	      m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)),
4665796c8dcSSimon Schubert 			       stream, show - 1, level, 0);
4675796c8dcSSimon Schubert 
4685796c8dcSSimon Schubert 	      fprintf_filtered(stream, "..");
4695796c8dcSSimon Schubert 
4705796c8dcSSimon Schubert 	      m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)),
4715796c8dcSSimon Schubert 			       stream, show - 1, level, 1);
4725796c8dcSSimon Schubert 	      fprintf_filtered(stream, "]");
4735796c8dcSSimon Schubert 	    }
4745796c8dcSSimon Schubert 	}
4755796c8dcSSimon Schubert       else
4765796c8dcSSimon Schubert 	/* i18n: Do not translate the "SET OF" part!  */
4775796c8dcSSimon Schubert 	fprintf_filtered(stream, _("SET OF <unknown>"));
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert       return 1;
4805796c8dcSSimon Schubert     }
4815796c8dcSSimon Schubert   return 0;
4825796c8dcSSimon Schubert }
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert /* m2_is_unbounded_array - returns TRUE if, type, should be regarded
4855796c8dcSSimon Schubert                            as a Modula-2 unbounded ARRAY type.  */
4865796c8dcSSimon Schubert 
4875796c8dcSSimon Schubert int
m2_is_unbounded_array(struct type * type)4885796c8dcSSimon Schubert m2_is_unbounded_array (struct type *type)
4895796c8dcSSimon Schubert {
4905796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
4915796c8dcSSimon Schubert     {
4925796c8dcSSimon Schubert       /*
4935796c8dcSSimon Schubert        *  check if we have a structure with exactly two fields named
4945796c8dcSSimon Schubert        *  _m2_contents and _m2_high.  It also checks to see if the
4955796c8dcSSimon Schubert        *  type of _m2_contents is a pointer.  The TYPE_TARGET_TYPE
4965796c8dcSSimon Schubert        *  of the pointer determines the unbounded ARRAY OF type.
4975796c8dcSSimon Schubert        */
4985796c8dcSSimon Schubert       if (TYPE_NFIELDS (type) != 2)
4995796c8dcSSimon Schubert 	return 0;
5005796c8dcSSimon Schubert       if (strcmp (TYPE_FIELD_NAME (type, 0), "_m2_contents") != 0)
5015796c8dcSSimon Schubert 	return 0;
5025796c8dcSSimon Schubert       if (strcmp (TYPE_FIELD_NAME (type, 1), "_m2_high") != 0)
5035796c8dcSSimon Schubert 	return 0;
5045796c8dcSSimon Schubert       if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) != TYPE_CODE_PTR)
5055796c8dcSSimon Schubert 	return 0;
5065796c8dcSSimon Schubert       return 1;
5075796c8dcSSimon Schubert     }
5085796c8dcSSimon Schubert   return 0;
5095796c8dcSSimon Schubert }
5105796c8dcSSimon Schubert 
5115796c8dcSSimon Schubert /* m2_unbounded_array - if the struct type matches a Modula-2 unbounded
5125796c8dcSSimon Schubert                         parameter type then display the type as an
5135796c8dcSSimon Schubert                         ARRAY OF type.  Returns TRUE if an unbounded
5145796c8dcSSimon Schubert                         array type was detected.  */
5155796c8dcSSimon Schubert 
5165796c8dcSSimon Schubert static int
m2_unbounded_array(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)5175796c8dcSSimon Schubert m2_unbounded_array (struct type *type, struct ui_file *stream, int show,
518*ef5ccd6cSJohn Marino 		    int level, const struct type_print_options *flags)
5195796c8dcSSimon Schubert {
5205796c8dcSSimon Schubert   if (m2_is_unbounded_array (type))
5215796c8dcSSimon Schubert     {
5225796c8dcSSimon Schubert       if (show > 0)
5235796c8dcSSimon Schubert 	{
5245796c8dcSSimon Schubert 	  fputs_filtered ("ARRAY OF ", stream);
5255796c8dcSSimon Schubert 	  m2_print_type (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)),
526*ef5ccd6cSJohn Marino 			 "", stream, 0, level, flags);
5275796c8dcSSimon Schubert 	}
5285796c8dcSSimon Schubert       return 1;
5295796c8dcSSimon Schubert     }
5305796c8dcSSimon Schubert   return 0;
5315796c8dcSSimon Schubert }
5325796c8dcSSimon Schubert 
5335796c8dcSSimon Schubert void
m2_record_fields(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)5345796c8dcSSimon Schubert m2_record_fields (struct type *type, struct ui_file *stream, int show,
535*ef5ccd6cSJohn Marino 		  int level, const struct type_print_options *flags)
5365796c8dcSSimon Schubert {
5375796c8dcSSimon Schubert   /* Print the tag if it exists.  */
5385796c8dcSSimon Schubert   if (TYPE_TAG_NAME (type) != NULL)
5395796c8dcSSimon Schubert     {
5405796c8dcSSimon Schubert       if (strncmp (TYPE_TAG_NAME (type), "$$", 2) != 0)
5415796c8dcSSimon Schubert 	{
5425796c8dcSSimon Schubert 	  fputs_filtered (TYPE_TAG_NAME (type), stream);
5435796c8dcSSimon Schubert 	  if (show > 0)
5445796c8dcSSimon Schubert 	    fprintf_filtered (stream, " = ");
5455796c8dcSSimon Schubert 	}
5465796c8dcSSimon Schubert     }
5475796c8dcSSimon Schubert   wrap_here ("    ");
5485796c8dcSSimon Schubert   if (show < 0)
5495796c8dcSSimon Schubert     {
550cf7f2e2dSJohn Marino       if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
5515796c8dcSSimon Schubert 	fprintf_filtered (stream, "RECORD ... END ");
552cf7f2e2dSJohn Marino       else if (TYPE_CODE (type) == TYPE_CODE_UNION)
5535796c8dcSSimon Schubert 	fprintf_filtered (stream, "CASE ... END ");
5545796c8dcSSimon Schubert     }
5555796c8dcSSimon Schubert   else if (show > 0)
5565796c8dcSSimon Schubert     {
5575796c8dcSSimon Schubert       int i;
5585796c8dcSSimon Schubert       int len = TYPE_NFIELDS (type);
5595796c8dcSSimon Schubert 
5605796c8dcSSimon Schubert       if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
5615796c8dcSSimon Schubert 	fprintf_filtered (stream, "RECORD\n");
5625796c8dcSSimon Schubert       else if (TYPE_CODE (type) == TYPE_CODE_UNION)
563c50c785cSJohn Marino 	/* i18n: Do not translate "CASE" and "OF".  */
5645796c8dcSSimon Schubert 	fprintf_filtered (stream, _("CASE <variant> OF\n"));
5655796c8dcSSimon Schubert 
5665796c8dcSSimon Schubert       for (i = TYPE_N_BASECLASSES (type); i < len; i++)
5675796c8dcSSimon Schubert 	{
5685796c8dcSSimon Schubert 	  QUIT;
5695796c8dcSSimon Schubert 
5705796c8dcSSimon Schubert 	  print_spaces_filtered (level + 4, stream);
5715796c8dcSSimon Schubert 	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
5725796c8dcSSimon Schubert 	  fputs_filtered (" : ", stream);
5735796c8dcSSimon Schubert 	  m2_print_type (TYPE_FIELD_TYPE (type, i),
5745796c8dcSSimon Schubert 			 "",
575*ef5ccd6cSJohn Marino 			 stream, 0, level + 4, flags);
5765796c8dcSSimon Schubert 	  if (TYPE_FIELD_PACKED (type, i))
5775796c8dcSSimon Schubert 	    {
5785796c8dcSSimon Schubert 	      /* It is a bitfield.  This code does not attempt
5795796c8dcSSimon Schubert 		 to look at the bitpos and reconstruct filler,
5805796c8dcSSimon Schubert 		 unnamed fields.  This would lead to misleading
5815796c8dcSSimon Schubert 		 results if the compiler does not put out fields
5825796c8dcSSimon Schubert 		 for such things (I don't know what it does).  */
5835796c8dcSSimon Schubert 	      fprintf_filtered (stream, " : %d",
5845796c8dcSSimon Schubert 				TYPE_FIELD_BITSIZE (type, i));
5855796c8dcSSimon Schubert 	    }
5865796c8dcSSimon Schubert 	  fprintf_filtered (stream, ";\n");
5875796c8dcSSimon Schubert 	}
5885796c8dcSSimon Schubert 
5895796c8dcSSimon Schubert       fprintfi_filtered (level, stream, "END ");
5905796c8dcSSimon Schubert     }
5915796c8dcSSimon Schubert }
5925796c8dcSSimon Schubert 
5935796c8dcSSimon Schubert void
m2_enum(struct type * type,struct ui_file * stream,int show,int level)5945796c8dcSSimon Schubert m2_enum (struct type *type, struct ui_file *stream, int show, int level)
5955796c8dcSSimon Schubert {
596*ef5ccd6cSJohn Marino   LONGEST lastval;
597*ef5ccd6cSJohn Marino   int i, len;
5985796c8dcSSimon Schubert 
5995796c8dcSSimon Schubert   if (show < 0)
6005796c8dcSSimon Schubert     {
6015796c8dcSSimon Schubert       /* If we just printed a tag name, no need to print anything else.  */
6025796c8dcSSimon Schubert       if (TYPE_TAG_NAME (type) == NULL)
6035796c8dcSSimon Schubert 	fprintf_filtered (stream, "(...)");
6045796c8dcSSimon Schubert     }
6055796c8dcSSimon Schubert   else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
6065796c8dcSSimon Schubert     {
6075796c8dcSSimon Schubert       fprintf_filtered (stream, "(");
6085796c8dcSSimon Schubert       len = TYPE_NFIELDS (type);
6095796c8dcSSimon Schubert       lastval = 0;
6105796c8dcSSimon Schubert       for (i = 0; i < len; i++)
6115796c8dcSSimon Schubert 	{
6125796c8dcSSimon Schubert 	  QUIT;
6135796c8dcSSimon Schubert 	  if (i > 0)
6145796c8dcSSimon Schubert 	    fprintf_filtered (stream, ", ");
6155796c8dcSSimon Schubert 	  wrap_here ("    ");
6165796c8dcSSimon Schubert 	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
617*ef5ccd6cSJohn Marino 	  if (lastval != TYPE_FIELD_ENUMVAL (type, i))
6185796c8dcSSimon Schubert 	    {
619*ef5ccd6cSJohn Marino 	      fprintf_filtered (stream, " = %s",
620*ef5ccd6cSJohn Marino 				plongest (TYPE_FIELD_ENUMVAL (type, i)));
621*ef5ccd6cSJohn Marino 	      lastval = TYPE_FIELD_ENUMVAL (type, i);
6225796c8dcSSimon Schubert 	    }
6235796c8dcSSimon Schubert 	  lastval++;
6245796c8dcSSimon Schubert 	}
6255796c8dcSSimon Schubert       fprintf_filtered (stream, ")");
6265796c8dcSSimon Schubert     }
6275796c8dcSSimon Schubert }
628