xref: /dflybsd-src/contrib/gdb-7/gdb/ada-typeprint.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Support for printing Ada 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 "target.h"
285796c8dcSSimon Schubert #include "command.h"
295796c8dcSSimon Schubert #include "gdbcmd.h"
305796c8dcSSimon Schubert #include "language.h"
315796c8dcSSimon Schubert #include "demangle.h"
325796c8dcSSimon Schubert #include "c-lang.h"
335796c8dcSSimon Schubert #include "typeprint.h"
345796c8dcSSimon Schubert #include "ada-lang.h"
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert #include <ctype.h>
375796c8dcSSimon Schubert #include "gdb_string.h"
385796c8dcSSimon Schubert #include <errno.h>
395796c8dcSSimon Schubert 
40c50c785cSJohn Marino static int print_selected_record_field_types (struct type *, struct type *,
41c50c785cSJohn Marino 					      int, int,
42*ef5ccd6cSJohn Marino 					      struct ui_file *, int, int,
43*ef5ccd6cSJohn Marino 					      const struct type_print_options *);
44c50c785cSJohn Marino 
455796c8dcSSimon Schubert static int print_record_field_types (struct type *, struct type *,
46*ef5ccd6cSJohn Marino 				     struct ui_file *, int, int,
47*ef5ccd6cSJohn Marino 				     const struct type_print_options *);
485796c8dcSSimon Schubert 
49*ef5ccd6cSJohn Marino static void print_array_type (struct type *, struct ui_file *, int, int,
50*ef5ccd6cSJohn Marino 			      const struct type_print_options *);
515796c8dcSSimon Schubert 
52c50c785cSJohn Marino static int print_choices (struct type *, int, struct ui_file *,
535796c8dcSSimon Schubert 			  struct type *);
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert static void print_range (struct type *, struct ui_file *);
565796c8dcSSimon Schubert 
575796c8dcSSimon Schubert static void print_range_bound (struct type *, char *, int *,
585796c8dcSSimon Schubert 			       struct ui_file *);
595796c8dcSSimon Schubert 
605796c8dcSSimon Schubert static void
615796c8dcSSimon Schubert print_dynamic_range_bound (struct type *, const char *, int,
625796c8dcSSimon Schubert 			   const char *, struct ui_file *);
635796c8dcSSimon Schubert 
64cf7f2e2dSJohn Marino static void print_range_type (struct type *, struct ui_file *);
655796c8dcSSimon Schubert 
665796c8dcSSimon Schubert 
675796c8dcSSimon Schubert 
685796c8dcSSimon Schubert static char *name_buffer;
695796c8dcSSimon Schubert static int name_buffer_len;
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert /* The (decoded) Ada name of TYPE.  This value persists until the
725796c8dcSSimon Schubert    next call.  */
735796c8dcSSimon Schubert 
745796c8dcSSimon Schubert static char *
decoded_type_name(struct type * type)755796c8dcSSimon Schubert decoded_type_name (struct type *type)
765796c8dcSSimon Schubert {
775796c8dcSSimon Schubert   if (ada_type_name (type) == NULL)
785796c8dcSSimon Schubert     return NULL;
795796c8dcSSimon Schubert   else
805796c8dcSSimon Schubert     {
81*ef5ccd6cSJohn Marino       const char *raw_name = ada_type_name (type);
825796c8dcSSimon Schubert       char *s, *q;
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert       if (name_buffer == NULL || name_buffer_len <= strlen (raw_name))
855796c8dcSSimon Schubert 	{
865796c8dcSSimon Schubert 	  name_buffer_len = 16 + 2 * strlen (raw_name);
875796c8dcSSimon Schubert 	  name_buffer = xrealloc (name_buffer, name_buffer_len);
885796c8dcSSimon Schubert 	}
895796c8dcSSimon Schubert       strcpy (name_buffer, raw_name);
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert       s = (char *) strstr (name_buffer, "___");
925796c8dcSSimon Schubert       if (s != NULL)
935796c8dcSSimon Schubert 	*s = '\0';
945796c8dcSSimon Schubert 
955796c8dcSSimon Schubert       s = name_buffer + strlen (name_buffer) - 1;
965796c8dcSSimon Schubert       while (s > name_buffer && (s[0] != '_' || s[-1] != '_'))
975796c8dcSSimon Schubert 	s -= 1;
985796c8dcSSimon Schubert 
995796c8dcSSimon Schubert       if (s == name_buffer)
1005796c8dcSSimon Schubert 	return name_buffer;
1015796c8dcSSimon Schubert 
1025796c8dcSSimon Schubert       if (!islower (s[1]))
1035796c8dcSSimon Schubert 	return NULL;
1045796c8dcSSimon Schubert 
1055796c8dcSSimon Schubert       for (s = q = name_buffer; *s != '\0'; q += 1)
1065796c8dcSSimon Schubert 	{
1075796c8dcSSimon Schubert 	  if (s[0] == '_' && s[1] == '_')
1085796c8dcSSimon Schubert 	    {
1095796c8dcSSimon Schubert 	      *q = '.';
1105796c8dcSSimon Schubert 	      s += 2;
1115796c8dcSSimon Schubert 	    }
1125796c8dcSSimon Schubert 	  else
1135796c8dcSSimon Schubert 	    {
1145796c8dcSSimon Schubert 	      *q = *s;
1155796c8dcSSimon Schubert 	      s += 1;
1165796c8dcSSimon Schubert 	    }
1175796c8dcSSimon Schubert 	}
1185796c8dcSSimon Schubert       *q = '\0';
1195796c8dcSSimon Schubert       return name_buffer;
1205796c8dcSSimon Schubert     }
1215796c8dcSSimon Schubert }
1225796c8dcSSimon Schubert 
123cf7f2e2dSJohn Marino /* Print TYPE on STREAM, preferably as a range.  */
1245796c8dcSSimon Schubert 
1255796c8dcSSimon Schubert static void
print_range(struct type * type,struct ui_file * stream)1265796c8dcSSimon Schubert print_range (struct type *type, struct ui_file *stream)
1275796c8dcSSimon Schubert {
128cf7f2e2dSJohn Marino   switch (TYPE_CODE (type))
129cf7f2e2dSJohn Marino     {
130cf7f2e2dSJohn Marino     case TYPE_CODE_RANGE:
131cf7f2e2dSJohn Marino     case TYPE_CODE_ENUM:
132cf7f2e2dSJohn Marino       {
1335796c8dcSSimon Schubert 	struct type *target_type;
1345796c8dcSSimon Schubert 	target_type = TYPE_TARGET_TYPE (type);
1355796c8dcSSimon Schubert 	if (target_type == NULL)
1365796c8dcSSimon Schubert 	  target_type = type;
137cf7f2e2dSJohn Marino 	ada_print_scalar (target_type, ada_discrete_type_low_bound (type),
138cf7f2e2dSJohn Marino 			  stream);
139cf7f2e2dSJohn Marino 	fprintf_filtered (stream, " .. ");
140cf7f2e2dSJohn Marino 	ada_print_scalar (target_type, ada_discrete_type_high_bound (type),
141cf7f2e2dSJohn Marino 			  stream);
142cf7f2e2dSJohn Marino       }
1435796c8dcSSimon Schubert       break;
1445796c8dcSSimon Schubert     default:
1455796c8dcSSimon Schubert       fprintf_filtered (stream, "%.*s",
1465796c8dcSSimon Schubert 			ada_name_prefix_len (TYPE_NAME (type)),
1475796c8dcSSimon Schubert 			TYPE_NAME (type));
148cf7f2e2dSJohn Marino       break;
1495796c8dcSSimon Schubert     }
1505796c8dcSSimon Schubert }
1515796c8dcSSimon Schubert 
1525796c8dcSSimon Schubert /* Print the number or discriminant bound at BOUNDS+*N on STREAM, and
1535796c8dcSSimon Schubert    set *N past the bound and its delimiter, if any.  */
1545796c8dcSSimon Schubert 
1555796c8dcSSimon Schubert static void
print_range_bound(struct type * type,char * bounds,int * n,struct ui_file * stream)1565796c8dcSSimon Schubert print_range_bound (struct type *type, char *bounds, int *n,
1575796c8dcSSimon Schubert 		   struct ui_file *stream)
1585796c8dcSSimon Schubert {
1595796c8dcSSimon Schubert   LONGEST B;
160cf7f2e2dSJohn Marino 
1615796c8dcSSimon Schubert   if (ada_scan_number (bounds, *n, &B, n))
1625796c8dcSSimon Schubert     {
1635796c8dcSSimon Schubert       /* STABS decodes all range types which bounds are 0 .. -1 as
1645796c8dcSSimon Schubert          unsigned integers (ie. the type code is TYPE_CODE_INT, not
1655796c8dcSSimon Schubert          TYPE_CODE_RANGE).  Unfortunately, ada_print_scalar() relies
1665796c8dcSSimon Schubert          on the unsigned flag to determine whether the bound should
1675796c8dcSSimon Schubert          be printed as a signed or an unsigned value.  This causes
1685796c8dcSSimon Schubert          the upper bound of the 0 .. -1 range types to be printed as
1695796c8dcSSimon Schubert          a very large unsigned number instead of -1.
1705796c8dcSSimon Schubert          To workaround this stabs deficiency, we replace the TYPE by NULL
1715796c8dcSSimon Schubert          to indicate default output when we detect that the bound is negative,
1725796c8dcSSimon Schubert          and the type is a TYPE_CODE_INT.  The bound is negative when
1735796c8dcSSimon Schubert          'm' is the last character of the number scanned in BOUNDS.  */
1745796c8dcSSimon Schubert       if (bounds[*n - 1] == 'm' && TYPE_CODE (type) == TYPE_CODE_INT)
1755796c8dcSSimon Schubert 	type = NULL;
1765796c8dcSSimon Schubert       ada_print_scalar (type, B, stream);
1775796c8dcSSimon Schubert       if (bounds[*n] == '_')
1785796c8dcSSimon Schubert 	*n += 2;
1795796c8dcSSimon Schubert     }
1805796c8dcSSimon Schubert   else
1815796c8dcSSimon Schubert     {
1825796c8dcSSimon Schubert       int bound_len;
1835796c8dcSSimon Schubert       char *bound = bounds + *n;
1845796c8dcSSimon Schubert       char *pend;
1855796c8dcSSimon Schubert 
1865796c8dcSSimon Schubert       pend = strstr (bound, "__");
1875796c8dcSSimon Schubert       if (pend == NULL)
1885796c8dcSSimon Schubert 	*n += bound_len = strlen (bound);
1895796c8dcSSimon Schubert       else
1905796c8dcSSimon Schubert 	{
1915796c8dcSSimon Schubert 	  bound_len = pend - bound;
1925796c8dcSSimon Schubert 	  *n += bound_len + 2;
1935796c8dcSSimon Schubert 	}
1945796c8dcSSimon Schubert       fprintf_filtered (stream, "%.*s", bound_len, bound);
1955796c8dcSSimon Schubert     }
1965796c8dcSSimon Schubert }
1975796c8dcSSimon Schubert 
1985796c8dcSSimon Schubert /* Assuming NAME[0 .. NAME_LEN-1] is the name of a range type, print
1995796c8dcSSimon Schubert    the value (if found) of the bound indicated by SUFFIX ("___L" or
2005796c8dcSSimon Schubert    "___U") according to the ___XD conventions.  */
2015796c8dcSSimon Schubert 
2025796c8dcSSimon Schubert static void
print_dynamic_range_bound(struct type * type,const char * name,int name_len,const char * suffix,struct ui_file * stream)2035796c8dcSSimon Schubert print_dynamic_range_bound (struct type *type, const char *name, int name_len,
2045796c8dcSSimon Schubert 			   const char *suffix, struct ui_file *stream)
2055796c8dcSSimon Schubert {
2065796c8dcSSimon Schubert   static char *name_buf = NULL;
2075796c8dcSSimon Schubert   static size_t name_buf_len = 0;
2085796c8dcSSimon Schubert   LONGEST B;
2095796c8dcSSimon Schubert   int OK;
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert   GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1);
2125796c8dcSSimon Schubert   strncpy (name_buf, name, name_len);
2135796c8dcSSimon Schubert   strcpy (name_buf + name_len, suffix);
2145796c8dcSSimon Schubert 
2155796c8dcSSimon Schubert   B = get_int_var_value (name_buf, &OK);
2165796c8dcSSimon Schubert   if (OK)
2175796c8dcSSimon Schubert     ada_print_scalar (type, B, stream);
2185796c8dcSSimon Schubert   else
2195796c8dcSSimon Schubert     fprintf_filtered (stream, "?");
2205796c8dcSSimon Schubert }
2215796c8dcSSimon Schubert 
222cf7f2e2dSJohn Marino /* Print RAW_TYPE as a range type, using any bound information
223cf7f2e2dSJohn Marino    following the GNAT encoding (if available).  */
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert static void
print_range_type(struct type * raw_type,struct ui_file * stream)226cf7f2e2dSJohn Marino print_range_type (struct type *raw_type, struct ui_file *stream)
2275796c8dcSSimon Schubert {
228*ef5ccd6cSJohn Marino   const char *name;
2295796c8dcSSimon Schubert   struct type *base_type;
230*ef5ccd6cSJohn Marino   const char *subtype_info;
2315796c8dcSSimon Schubert 
232cf7f2e2dSJohn Marino   gdb_assert (raw_type != NULL);
233cf7f2e2dSJohn Marino   name = TYPE_NAME (raw_type);
234cf7f2e2dSJohn Marino   gdb_assert (name != NULL);
2355796c8dcSSimon Schubert 
2365796c8dcSSimon Schubert   if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE)
2375796c8dcSSimon Schubert     base_type = TYPE_TARGET_TYPE (raw_type);
2385796c8dcSSimon Schubert   else
2395796c8dcSSimon Schubert     base_type = raw_type;
2405796c8dcSSimon Schubert 
2415796c8dcSSimon Schubert   subtype_info = strstr (name, "___XD");
2425796c8dcSSimon Schubert   if (subtype_info == NULL)
2435796c8dcSSimon Schubert     print_range (raw_type, stream);
2445796c8dcSSimon Schubert   else
2455796c8dcSSimon Schubert     {
2465796c8dcSSimon Schubert       int prefix_len = subtype_info - name;
2475796c8dcSSimon Schubert       char *bounds_str;
2485796c8dcSSimon Schubert       int n;
2495796c8dcSSimon Schubert 
2505796c8dcSSimon Schubert       subtype_info += 5;
2515796c8dcSSimon Schubert       bounds_str = strchr (subtype_info, '_');
2525796c8dcSSimon Schubert       n = 1;
2535796c8dcSSimon Schubert 
2545796c8dcSSimon Schubert       if (*subtype_info == 'L')
2555796c8dcSSimon Schubert 	{
2565796c8dcSSimon Schubert 	  print_range_bound (base_type, bounds_str, &n, stream);
2575796c8dcSSimon Schubert 	  subtype_info += 1;
2585796c8dcSSimon Schubert 	}
2595796c8dcSSimon Schubert       else
2605796c8dcSSimon Schubert 	print_dynamic_range_bound (base_type, name, prefix_len, "___L",
2615796c8dcSSimon Schubert 				   stream);
2625796c8dcSSimon Schubert 
2635796c8dcSSimon Schubert       fprintf_filtered (stream, " .. ");
2645796c8dcSSimon Schubert 
2655796c8dcSSimon Schubert       if (*subtype_info == 'U')
2665796c8dcSSimon Schubert 	print_range_bound (base_type, bounds_str, &n, stream);
2675796c8dcSSimon Schubert       else
2685796c8dcSSimon Schubert 	print_dynamic_range_bound (base_type, name, prefix_len, "___U",
2695796c8dcSSimon Schubert 				   stream);
2705796c8dcSSimon Schubert     }
2715796c8dcSSimon Schubert }
2725796c8dcSSimon Schubert 
2735796c8dcSSimon Schubert /* Print enumerated type TYPE on STREAM.  */
2745796c8dcSSimon Schubert 
2755796c8dcSSimon Schubert static void
print_enum_type(struct type * type,struct ui_file * stream)2765796c8dcSSimon Schubert print_enum_type (struct type *type, struct ui_file *stream)
2775796c8dcSSimon Schubert {
2785796c8dcSSimon Schubert   int len = TYPE_NFIELDS (type);
279*ef5ccd6cSJohn Marino   int i;
280*ef5ccd6cSJohn Marino   LONGEST lastval;
2815796c8dcSSimon Schubert 
2825796c8dcSSimon Schubert   fprintf_filtered (stream, "(");
2835796c8dcSSimon Schubert   wrap_here (" ");
2845796c8dcSSimon Schubert 
2855796c8dcSSimon Schubert   lastval = 0;
2865796c8dcSSimon Schubert   for (i = 0; i < len; i++)
2875796c8dcSSimon Schubert     {
2885796c8dcSSimon Schubert       QUIT;
2895796c8dcSSimon Schubert       if (i)
2905796c8dcSSimon Schubert 	fprintf_filtered (stream, ", ");
2915796c8dcSSimon Schubert       wrap_here ("    ");
2925796c8dcSSimon Schubert       fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
293*ef5ccd6cSJohn Marino       if (lastval != TYPE_FIELD_ENUMVAL (type, i))
2945796c8dcSSimon Schubert 	{
295*ef5ccd6cSJohn Marino 	  fprintf_filtered (stream, " => %s",
296*ef5ccd6cSJohn Marino 			    plongest (TYPE_FIELD_ENUMVAL (type, i)));
297*ef5ccd6cSJohn Marino 	  lastval = TYPE_FIELD_ENUMVAL (type, i);
2985796c8dcSSimon Schubert 	}
2995796c8dcSSimon Schubert       lastval += 1;
3005796c8dcSSimon Schubert     }
3015796c8dcSSimon Schubert   fprintf_filtered (stream, ")");
3025796c8dcSSimon Schubert }
3035796c8dcSSimon Schubert 
3045796c8dcSSimon Schubert /* Print representation of Ada fixed-point type TYPE on STREAM.  */
3055796c8dcSSimon Schubert 
3065796c8dcSSimon Schubert static void
print_fixed_point_type(struct type * type,struct ui_file * stream)3075796c8dcSSimon Schubert print_fixed_point_type (struct type *type, struct ui_file *stream)
3085796c8dcSSimon Schubert {
3095796c8dcSSimon Schubert   DOUBLEST delta = ada_delta (type);
3105796c8dcSSimon Schubert   DOUBLEST small = ada_fixed_to_float (type, 1.0);
3115796c8dcSSimon Schubert 
3125796c8dcSSimon Schubert   if (delta < 0.0)
3135796c8dcSSimon Schubert     fprintf_filtered (stream, "delta ??");
3145796c8dcSSimon Schubert   else
3155796c8dcSSimon Schubert     {
3165796c8dcSSimon Schubert       fprintf_filtered (stream, "delta %g", (double) delta);
3175796c8dcSSimon Schubert       if (delta != small)
3185796c8dcSSimon Schubert 	fprintf_filtered (stream, " <'small = %g>", (double) small);
3195796c8dcSSimon Schubert     }
3205796c8dcSSimon Schubert }
3215796c8dcSSimon Schubert 
3225796c8dcSSimon Schubert /* Print simple (constrained) array type TYPE on STREAM.  LEVEL is the
3235796c8dcSSimon Schubert    recursion (indentation) level, in case the element type itself has
3245796c8dcSSimon Schubert    nested structure, and SHOW is the number of levels of internal
3255796c8dcSSimon Schubert    structure to show (see ada_print_type).  */
3265796c8dcSSimon Schubert 
3275796c8dcSSimon Schubert static void
print_array_type(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)3285796c8dcSSimon Schubert print_array_type (struct type *type, struct ui_file *stream, int show,
329*ef5ccd6cSJohn Marino 		  int level, const struct type_print_options *flags)
3305796c8dcSSimon Schubert {
3315796c8dcSSimon Schubert   int bitsize;
3325796c8dcSSimon Schubert   int n_indices;
3335796c8dcSSimon Schubert 
334cf7f2e2dSJohn Marino   if (ada_is_constrained_packed_array_type (type))
3355796c8dcSSimon Schubert     type = ada_coerce_to_simple_array_type (type);
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert   bitsize = 0;
3385796c8dcSSimon Schubert   fprintf_filtered (stream, "array (");
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert   if (type == NULL)
3415796c8dcSSimon Schubert     {
3425796c8dcSSimon Schubert       fprintf_filtered (stream, _("<undecipherable array type>"));
3435796c8dcSSimon Schubert       return;
3445796c8dcSSimon Schubert     }
3455796c8dcSSimon Schubert 
3465796c8dcSSimon Schubert   n_indices = -1;
3475796c8dcSSimon Schubert   if (ada_is_simple_array_type (type))
3485796c8dcSSimon Schubert     {
349cf7f2e2dSJohn Marino       struct type *range_desc_type;
3505796c8dcSSimon Schubert       struct type *arr_type;
3515796c8dcSSimon Schubert 
352cf7f2e2dSJohn Marino       range_desc_type = ada_find_parallel_type (type, "___XA");
353cf7f2e2dSJohn Marino       ada_fixup_array_indexes_type (range_desc_type);
354cf7f2e2dSJohn Marino 
3555796c8dcSSimon Schubert       bitsize = 0;
3565796c8dcSSimon Schubert       if (range_desc_type == NULL)
3575796c8dcSSimon Schubert 	{
3585796c8dcSSimon Schubert 	  for (arr_type = type; TYPE_CODE (arr_type) == TYPE_CODE_ARRAY;
3595796c8dcSSimon Schubert 	       arr_type = TYPE_TARGET_TYPE (arr_type))
3605796c8dcSSimon Schubert 	    {
3615796c8dcSSimon Schubert 	      if (arr_type != type)
3625796c8dcSSimon Schubert 		fprintf_filtered (stream, ", ");
3635796c8dcSSimon Schubert 	      print_range (TYPE_INDEX_TYPE (arr_type), stream);
3645796c8dcSSimon Schubert 	      if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
3655796c8dcSSimon Schubert 		bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
3665796c8dcSSimon Schubert 	    }
3675796c8dcSSimon Schubert 	}
3685796c8dcSSimon Schubert       else
3695796c8dcSSimon Schubert 	{
3705796c8dcSSimon Schubert 	  int k;
371cf7f2e2dSJohn Marino 
3725796c8dcSSimon Schubert 	  n_indices = TYPE_NFIELDS (range_desc_type);
3735796c8dcSSimon Schubert 	  for (k = 0, arr_type = type;
3745796c8dcSSimon Schubert 	       k < n_indices;
3755796c8dcSSimon Schubert 	       k += 1, arr_type = TYPE_TARGET_TYPE (arr_type))
3765796c8dcSSimon Schubert 	    {
3775796c8dcSSimon Schubert 	      if (k > 0)
3785796c8dcSSimon Schubert 		fprintf_filtered (stream, ", ");
379cf7f2e2dSJohn Marino 	      print_range_type (TYPE_FIELD_TYPE (range_desc_type, k),
380cf7f2e2dSJohn Marino 				stream);
3815796c8dcSSimon Schubert 	      if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
3825796c8dcSSimon Schubert 		bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
3835796c8dcSSimon Schubert 	    }
3845796c8dcSSimon Schubert 	}
3855796c8dcSSimon Schubert     }
3865796c8dcSSimon Schubert   else
3875796c8dcSSimon Schubert     {
3885796c8dcSSimon Schubert       int i, i0;
389cf7f2e2dSJohn Marino 
3905796c8dcSSimon Schubert       for (i = i0 = ada_array_arity (type); i > 0; i -= 1)
3915796c8dcSSimon Schubert 	fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", ");
3925796c8dcSSimon Schubert     }
3935796c8dcSSimon Schubert 
3945796c8dcSSimon Schubert   fprintf_filtered (stream, ") of ");
3955796c8dcSSimon Schubert   wrap_here ("");
3965796c8dcSSimon Schubert   ada_print_type (ada_array_element_type (type, n_indices), "", stream,
397*ef5ccd6cSJohn Marino 		  show == 0 ? 0 : show - 1, level + 1, flags);
3985796c8dcSSimon Schubert   if (bitsize > 0)
3995796c8dcSSimon Schubert     fprintf_filtered (stream, " <packed: %d-bit elements>", bitsize);
4005796c8dcSSimon Schubert }
4015796c8dcSSimon Schubert 
4025796c8dcSSimon Schubert /* Print the choices encoded by field FIELD_NUM of variant-part TYPE on
403c50c785cSJohn Marino    STREAM, assuming that VAL_TYPE (if non-NULL) is the type of the
404c50c785cSJohn Marino    values.  Return non-zero if the field is an encoding of
405c50c785cSJohn Marino    discriminant values, as in a standard variant record, and 0 if the
406c50c785cSJohn Marino    field is not so encoded (as happens with single-component variants
407c50c785cSJohn Marino    in types annotated with pragma Unchecked_Variant).  */
4085796c8dcSSimon Schubert 
409c50c785cSJohn Marino static int
print_choices(struct type * type,int field_num,struct ui_file * stream,struct type * val_type)4105796c8dcSSimon Schubert print_choices (struct type *type, int field_num, struct ui_file *stream,
4115796c8dcSSimon Schubert 	       struct type *val_type)
4125796c8dcSSimon Schubert {
4135796c8dcSSimon Schubert   int have_output;
4145796c8dcSSimon Schubert   int p;
4155796c8dcSSimon Schubert   const char *name = TYPE_FIELD_NAME (type, field_num);
4165796c8dcSSimon Schubert 
4175796c8dcSSimon Schubert   have_output = 0;
4185796c8dcSSimon Schubert 
4195796c8dcSSimon Schubert   /* Skip over leading 'V': NOTE soon to be obsolete.  */
4205796c8dcSSimon Schubert   if (name[0] == 'V')
4215796c8dcSSimon Schubert     {
4225796c8dcSSimon Schubert       if (!ada_scan_number (name, 1, NULL, &p))
4235796c8dcSSimon Schubert 	goto Huh;
4245796c8dcSSimon Schubert     }
4255796c8dcSSimon Schubert   else
4265796c8dcSSimon Schubert     p = 0;
4275796c8dcSSimon Schubert 
4285796c8dcSSimon Schubert   while (1)
4295796c8dcSSimon Schubert     {
4305796c8dcSSimon Schubert       switch (name[p])
4315796c8dcSSimon Schubert 	{
4325796c8dcSSimon Schubert 	default:
433c50c785cSJohn Marino 	  goto Huh;
434c50c785cSJohn Marino 	case '_':
435c50c785cSJohn Marino 	case '\0':
436c50c785cSJohn Marino 	  fprintf_filtered (stream, " =>");
437c50c785cSJohn Marino 	  return 1;
4385796c8dcSSimon Schubert 	case 'S':
4395796c8dcSSimon Schubert 	case 'R':
4405796c8dcSSimon Schubert 	case 'O':
4415796c8dcSSimon Schubert 	  if (have_output)
4425796c8dcSSimon Schubert 	    fprintf_filtered (stream, " | ");
4435796c8dcSSimon Schubert 	  have_output = 1;
4445796c8dcSSimon Schubert 	  break;
4455796c8dcSSimon Schubert 	}
4465796c8dcSSimon Schubert 
4475796c8dcSSimon Schubert       switch (name[p])
4485796c8dcSSimon Schubert 	{
4495796c8dcSSimon Schubert 	case 'S':
4505796c8dcSSimon Schubert 	  {
4515796c8dcSSimon Schubert 	    LONGEST W;
452cf7f2e2dSJohn Marino 
4535796c8dcSSimon Schubert 	    if (!ada_scan_number (name, p + 1, &W, &p))
4545796c8dcSSimon Schubert 	      goto Huh;
4555796c8dcSSimon Schubert 	    ada_print_scalar (val_type, W, stream);
4565796c8dcSSimon Schubert 	    break;
4575796c8dcSSimon Schubert 	  }
4585796c8dcSSimon Schubert 	case 'R':
4595796c8dcSSimon Schubert 	  {
4605796c8dcSSimon Schubert 	    LONGEST L, U;
461cf7f2e2dSJohn Marino 
4625796c8dcSSimon Schubert 	    if (!ada_scan_number (name, p + 1, &L, &p)
4635796c8dcSSimon Schubert 		|| name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p))
4645796c8dcSSimon Schubert 	      goto Huh;
4655796c8dcSSimon Schubert 	    ada_print_scalar (val_type, L, stream);
4665796c8dcSSimon Schubert 	    fprintf_filtered (stream, " .. ");
4675796c8dcSSimon Schubert 	    ada_print_scalar (val_type, U, stream);
4685796c8dcSSimon Schubert 	    break;
4695796c8dcSSimon Schubert 	  }
4705796c8dcSSimon Schubert 	case 'O':
4715796c8dcSSimon Schubert 	  fprintf_filtered (stream, "others");
4725796c8dcSSimon Schubert 	  p += 1;
4735796c8dcSSimon Schubert 	  break;
4745796c8dcSSimon Schubert 	}
4755796c8dcSSimon Schubert     }
4765796c8dcSSimon Schubert 
4775796c8dcSSimon Schubert Huh:
478c50c785cSJohn Marino   fprintf_filtered (stream, "?? =>");
479c50c785cSJohn Marino   return 0;
4805796c8dcSSimon Schubert }
4815796c8dcSSimon Schubert 
482c50c785cSJohn Marino /* Assuming that field FIELD_NUM of TYPE represents variants whose
483c50c785cSJohn Marino    discriminant is contained in OUTER_TYPE, print its components on STREAM.
484c50c785cSJohn Marino    LEVEL is the recursion (indentation) level, in case any of the fields
485c50c785cSJohn Marino    themselves have nested structure, and SHOW is the number of levels of
486c50c785cSJohn Marino    internal structure to show (see ada_print_type).  For this purpose,
487c50c785cSJohn Marino    fields nested in a variant part are taken to be at the same level as
488c50c785cSJohn Marino    the fields immediately outside the variant part.  */
4895796c8dcSSimon Schubert 
4905796c8dcSSimon Schubert static void
print_variant_clauses(struct type * type,int field_num,struct type * outer_type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)4915796c8dcSSimon Schubert print_variant_clauses (struct type *type, int field_num,
4925796c8dcSSimon Schubert 		       struct type *outer_type, struct ui_file *stream,
493*ef5ccd6cSJohn Marino 		       int show, int level,
494*ef5ccd6cSJohn Marino 		       const struct type_print_options *flags)
4955796c8dcSSimon Schubert {
4965796c8dcSSimon Schubert   int i;
4975796c8dcSSimon Schubert   struct type *var_type, *par_type;
4985796c8dcSSimon Schubert   struct type *discr_type;
4995796c8dcSSimon Schubert 
5005796c8dcSSimon Schubert   var_type = TYPE_FIELD_TYPE (type, field_num);
5015796c8dcSSimon Schubert   discr_type = ada_variant_discrim_type (var_type, outer_type);
5025796c8dcSSimon Schubert 
5035796c8dcSSimon Schubert   if (TYPE_CODE (var_type) == TYPE_CODE_PTR)
5045796c8dcSSimon Schubert     {
5055796c8dcSSimon Schubert       var_type = TYPE_TARGET_TYPE (var_type);
5065796c8dcSSimon Schubert       if (var_type == NULL || TYPE_CODE (var_type) != TYPE_CODE_UNION)
5075796c8dcSSimon Schubert 	return;
5085796c8dcSSimon Schubert     }
5095796c8dcSSimon Schubert 
5105796c8dcSSimon Schubert   par_type = ada_find_parallel_type (var_type, "___XVU");
5115796c8dcSSimon Schubert   if (par_type != NULL)
5125796c8dcSSimon Schubert     var_type = par_type;
5135796c8dcSSimon Schubert 
5145796c8dcSSimon Schubert   for (i = 0; i < TYPE_NFIELDS (var_type); i += 1)
5155796c8dcSSimon Schubert     {
5165796c8dcSSimon Schubert       fprintf_filtered (stream, "\n%*swhen ", level + 4, "");
517c50c785cSJohn Marino       if (print_choices (var_type, i, stream, discr_type))
518c50c785cSJohn Marino 	{
5195796c8dcSSimon Schubert 	  if (print_record_field_types (TYPE_FIELD_TYPE (var_type, i),
520*ef5ccd6cSJohn Marino 					outer_type, stream, show, level + 4,
521*ef5ccd6cSJohn Marino 					flags)
522c50c785cSJohn Marino 	      <= 0)
5235796c8dcSSimon Schubert 	    fprintf_filtered (stream, " null;");
5245796c8dcSSimon Schubert 	}
525c50c785cSJohn Marino       else
526c50c785cSJohn Marino 	print_selected_record_field_types (var_type, outer_type, i, i,
527*ef5ccd6cSJohn Marino 					   stream, show, level + 4, flags);
528c50c785cSJohn Marino     }
5295796c8dcSSimon Schubert }
5305796c8dcSSimon Schubert 
5315796c8dcSSimon Schubert /* Assuming that field FIELD_NUM of TYPE is a variant part whose
5325796c8dcSSimon Schubert    discriminants are contained in OUTER_TYPE, print a description of it
5335796c8dcSSimon Schubert    on STREAM.  LEVEL is the recursion (indentation) level, in case any of
5345796c8dcSSimon Schubert    the fields themselves have nested structure, and SHOW is the number of
5355796c8dcSSimon Schubert    levels of internal structure to show (see ada_print_type).  For this
5365796c8dcSSimon Schubert    purpose, fields nested in a variant part are taken to be at the same
5375796c8dcSSimon Schubert    level as the fields immediately outside the variant part.  */
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert static void
print_variant_part(struct type * type,int field_num,struct type * outer_type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)5405796c8dcSSimon Schubert print_variant_part (struct type *type, int field_num, struct type *outer_type,
541*ef5ccd6cSJohn Marino 		    struct ui_file *stream, int show, int level,
542*ef5ccd6cSJohn Marino 		    const struct type_print_options *flags)
5435796c8dcSSimon Schubert {
5445796c8dcSSimon Schubert   fprintf_filtered (stream, "\n%*scase %s is", level + 4, "",
5455796c8dcSSimon Schubert 		    ada_variant_discrim_name
5465796c8dcSSimon Schubert 		    (TYPE_FIELD_TYPE (type, field_num)));
5475796c8dcSSimon Schubert   print_variant_clauses (type, field_num, outer_type, stream, show,
548*ef5ccd6cSJohn Marino 			 level + 4, flags);
5495796c8dcSSimon Schubert   fprintf_filtered (stream, "\n%*send case;", level + 4, "");
5505796c8dcSSimon Schubert }
5515796c8dcSSimon Schubert 
552c50c785cSJohn Marino /* Print a description on STREAM of the fields FLD0 through FLD1 in
553c50c785cSJohn Marino    record or union type TYPE, whose discriminants are in OUTER_TYPE.
554c50c785cSJohn Marino    LEVEL is the recursion (indentation) level, in case any of the
555c50c785cSJohn Marino    fields themselves have nested structure, and SHOW is the number of
556c50c785cSJohn Marino    levels of internal structure to show (see ada_print_type).  Does
557c50c785cSJohn Marino    not print parent type information of TYPE.  Returns 0 if no fields
558c50c785cSJohn Marino    printed, -1 for an incomplete type, else > 0.  Prints each field
559c50c785cSJohn Marino    beginning on a new line, but does not put a new line at end.  */
5605796c8dcSSimon Schubert 
5615796c8dcSSimon Schubert static int
print_selected_record_field_types(struct type * type,struct type * outer_type,int fld0,int fld1,struct ui_file * stream,int show,int level,const struct type_print_options * flags)562c50c785cSJohn Marino print_selected_record_field_types (struct type *type, struct type *outer_type,
563c50c785cSJohn Marino 				   int fld0, int fld1,
564*ef5ccd6cSJohn Marino 				   struct ui_file *stream, int show, int level,
565*ef5ccd6cSJohn Marino 				   const struct type_print_options *flags)
5665796c8dcSSimon Schubert {
567c50c785cSJohn Marino   int i, flds;
5685796c8dcSSimon Schubert 
5695796c8dcSSimon Schubert   flds = 0;
5705796c8dcSSimon Schubert 
571c50c785cSJohn Marino   if (fld0 > fld1 && TYPE_STUB (type))
5725796c8dcSSimon Schubert     return -1;
5735796c8dcSSimon Schubert 
574c50c785cSJohn Marino   for (i = fld0; i <= fld1; i += 1)
5755796c8dcSSimon Schubert     {
5765796c8dcSSimon Schubert       QUIT;
5775796c8dcSSimon Schubert 
5785796c8dcSSimon Schubert       if (ada_is_parent_field (type, i) || ada_is_ignored_field (type, i))
5795796c8dcSSimon Schubert 	;
5805796c8dcSSimon Schubert       else if (ada_is_wrapper_field (type, i))
5815796c8dcSSimon Schubert 	flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type,
582*ef5ccd6cSJohn Marino 					  stream, show, level, flags);
5835796c8dcSSimon Schubert       else if (ada_is_variant_part (type, i))
5845796c8dcSSimon Schubert 	{
585*ef5ccd6cSJohn Marino 	  print_variant_part (type, i, outer_type, stream, show, level, flags);
5865796c8dcSSimon Schubert 	  flds = 1;
5875796c8dcSSimon Schubert 	}
5885796c8dcSSimon Schubert       else
5895796c8dcSSimon Schubert 	{
5905796c8dcSSimon Schubert 	  flds += 1;
5915796c8dcSSimon Schubert 	  fprintf_filtered (stream, "\n%*s", level + 4, "");
5925796c8dcSSimon Schubert 	  ada_print_type (TYPE_FIELD_TYPE (type, i),
5935796c8dcSSimon Schubert 			  TYPE_FIELD_NAME (type, i),
594*ef5ccd6cSJohn Marino 			  stream, show - 1, level + 4, flags);
5955796c8dcSSimon Schubert 	  fprintf_filtered (stream, ";");
5965796c8dcSSimon Schubert 	}
5975796c8dcSSimon Schubert     }
5985796c8dcSSimon Schubert 
5995796c8dcSSimon Schubert   return flds;
6005796c8dcSSimon Schubert }
6015796c8dcSSimon Schubert 
602c50c785cSJohn Marino /* Print a description on STREAM of all fields of record or union type
603c50c785cSJohn Marino    TYPE, as for print_selected_record_field_types, above.  */
604c50c785cSJohn Marino 
605c50c785cSJohn Marino static int
print_record_field_types(struct type * type,struct type * outer_type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)606c50c785cSJohn Marino print_record_field_types (struct type *type, struct type *outer_type,
607*ef5ccd6cSJohn Marino 			  struct ui_file *stream, int show, int level,
608*ef5ccd6cSJohn Marino 			  const struct type_print_options *flags)
609c50c785cSJohn Marino {
610c50c785cSJohn Marino   return print_selected_record_field_types (type, outer_type,
611c50c785cSJohn Marino 					    0, TYPE_NFIELDS (type) - 1,
612*ef5ccd6cSJohn Marino 					    stream, show, level, flags);
613c50c785cSJohn Marino }
614c50c785cSJohn Marino 
615c50c785cSJohn Marino 
6165796c8dcSSimon Schubert /* Print record type TYPE on STREAM.  LEVEL is the recursion (indentation)
6175796c8dcSSimon Schubert    level, in case the element type itself has nested structure, and SHOW is
6185796c8dcSSimon Schubert    the number of levels of internal structure to show (see ada_print_type).  */
6195796c8dcSSimon Schubert 
6205796c8dcSSimon Schubert static void
print_record_type(struct type * type0,struct ui_file * stream,int show,int level,const struct type_print_options * flags)6215796c8dcSSimon Schubert print_record_type (struct type *type0, struct ui_file *stream, int show,
622*ef5ccd6cSJohn Marino 		   int level, const struct type_print_options *flags)
6235796c8dcSSimon Schubert {
6245796c8dcSSimon Schubert   struct type *parent_type;
6255796c8dcSSimon Schubert   struct type *type;
6265796c8dcSSimon Schubert 
6275796c8dcSSimon Schubert   type = ada_find_parallel_type (type0, "___XVE");
6285796c8dcSSimon Schubert   if (type == NULL)
6295796c8dcSSimon Schubert     type = type0;
6305796c8dcSSimon Schubert 
6315796c8dcSSimon Schubert   parent_type = ada_parent_type (type);
6325796c8dcSSimon Schubert   if (ada_type_name (parent_type) != NULL)
633a45ae5f8SJohn Marino     {
634a45ae5f8SJohn Marino       const char *parent_name = decoded_type_name (parent_type);
635a45ae5f8SJohn Marino 
636a45ae5f8SJohn Marino       /* If we fail to decode the parent type name, then use the parent
637a45ae5f8SJohn Marino 	 type name as is.  Not pretty, but should never happen except
638a45ae5f8SJohn Marino 	 when the debugging info is incomplete or incorrect.  This
639a45ae5f8SJohn Marino 	 prevents a crash trying to print a NULL pointer.  */
640a45ae5f8SJohn Marino       if (parent_name == NULL)
641a45ae5f8SJohn Marino 	parent_name = ada_type_name (parent_type);
642a45ae5f8SJohn Marino       fprintf_filtered (stream, "new %s with record", parent_name);
643a45ae5f8SJohn Marino     }
6445796c8dcSSimon Schubert   else if (parent_type == NULL && ada_is_tagged_type (type, 0))
6455796c8dcSSimon Schubert     fprintf_filtered (stream, "tagged record");
6465796c8dcSSimon Schubert   else
6475796c8dcSSimon Schubert     fprintf_filtered (stream, "record");
6485796c8dcSSimon Schubert 
6495796c8dcSSimon Schubert   if (show < 0)
6505796c8dcSSimon Schubert     fprintf_filtered (stream, " ... end record");
6515796c8dcSSimon Schubert   else
6525796c8dcSSimon Schubert     {
6535796c8dcSSimon Schubert       int flds;
6545796c8dcSSimon Schubert 
6555796c8dcSSimon Schubert       flds = 0;
6565796c8dcSSimon Schubert       if (parent_type != NULL && ada_type_name (parent_type) == NULL)
6575796c8dcSSimon Schubert 	flds += print_record_field_types (parent_type, parent_type,
658*ef5ccd6cSJohn Marino 					  stream, show, level, flags);
659*ef5ccd6cSJohn Marino       flds += print_record_field_types (type, type, stream, show, level,
660*ef5ccd6cSJohn Marino 					flags);
6615796c8dcSSimon Schubert 
6625796c8dcSSimon Schubert       if (flds > 0)
6635796c8dcSSimon Schubert 	fprintf_filtered (stream, "\n%*send record", level, "");
6645796c8dcSSimon Schubert       else if (flds < 0)
6655796c8dcSSimon Schubert 	fprintf_filtered (stream, _(" <incomplete type> end record"));
6665796c8dcSSimon Schubert       else
6675796c8dcSSimon Schubert 	fprintf_filtered (stream, " null; end record");
6685796c8dcSSimon Schubert     }
6695796c8dcSSimon Schubert }
6705796c8dcSSimon Schubert 
6715796c8dcSSimon Schubert /* Print the unchecked union type TYPE in something resembling Ada
6725796c8dcSSimon Schubert    format on STREAM.  LEVEL is the recursion (indentation) level
6735796c8dcSSimon Schubert    in case the element type itself has nested structure, and SHOW is the
6745796c8dcSSimon Schubert    number of levels of internal structure to show (see ada_print_type).  */
6755796c8dcSSimon Schubert static void
print_unchecked_union_type(struct type * type,struct ui_file * stream,int show,int level,const struct type_print_options * flags)6765796c8dcSSimon Schubert print_unchecked_union_type (struct type *type, struct ui_file *stream,
677*ef5ccd6cSJohn Marino 			    int show, int level,
678*ef5ccd6cSJohn Marino 			    const struct type_print_options *flags)
6795796c8dcSSimon Schubert {
6805796c8dcSSimon Schubert   if (show < 0)
6815796c8dcSSimon Schubert     fprintf_filtered (stream, "record (?) is ... end record");
6825796c8dcSSimon Schubert   else if (TYPE_NFIELDS (type) == 0)
6835796c8dcSSimon Schubert     fprintf_filtered (stream, "record (?) is null; end record");
6845796c8dcSSimon Schubert   else
6855796c8dcSSimon Schubert     {
6865796c8dcSSimon Schubert       int i;
6875796c8dcSSimon Schubert 
6885796c8dcSSimon Schubert       fprintf_filtered (stream, "record (?) is\n%*scase ? is", level + 4, "");
6895796c8dcSSimon Schubert 
6905796c8dcSSimon Schubert       for (i = 0; i < TYPE_NFIELDS (type); i += 1)
6915796c8dcSSimon Schubert 	{
6925796c8dcSSimon Schubert 	  fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level + 8, "",
6935796c8dcSSimon Schubert 			    level + 12, "");
6945796c8dcSSimon Schubert 	  ada_print_type (TYPE_FIELD_TYPE (type, i),
6955796c8dcSSimon Schubert 			  TYPE_FIELD_NAME (type, i),
696*ef5ccd6cSJohn Marino 			  stream, show - 1, level + 12, flags);
6975796c8dcSSimon Schubert 	  fprintf_filtered (stream, ";");
6985796c8dcSSimon Schubert 	}
6995796c8dcSSimon Schubert 
7005796c8dcSSimon Schubert       fprintf_filtered (stream, "\n%*send case;\n%*send record",
7015796c8dcSSimon Schubert 			level + 4, "", level, "");
7025796c8dcSSimon Schubert     }
7035796c8dcSSimon Schubert }
7045796c8dcSSimon Schubert 
7055796c8dcSSimon Schubert 
7065796c8dcSSimon Schubert 
7075796c8dcSSimon Schubert /* Print function or procedure type TYPE on STREAM.  Make it a header
7085796c8dcSSimon Schubert    for function or procedure NAME if NAME is not null.  */
7095796c8dcSSimon Schubert 
7105796c8dcSSimon Schubert static void
print_func_type(struct type * type,struct ui_file * stream,const char * name,const struct type_print_options * flags)711*ef5ccd6cSJohn Marino print_func_type (struct type *type, struct ui_file *stream, const char *name,
712*ef5ccd6cSJohn Marino 		 const struct type_print_options *flags)
7135796c8dcSSimon Schubert {
7145796c8dcSSimon Schubert   int i, len = TYPE_NFIELDS (type);
7155796c8dcSSimon Schubert 
7165796c8dcSSimon Schubert   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
7175796c8dcSSimon Schubert     fprintf_filtered (stream, "procedure");
7185796c8dcSSimon Schubert   else
7195796c8dcSSimon Schubert     fprintf_filtered (stream, "function");
7205796c8dcSSimon Schubert 
7215796c8dcSSimon Schubert   if (name != NULL && name[0] != '\0')
7225796c8dcSSimon Schubert     fprintf_filtered (stream, " %s", name);
7235796c8dcSSimon Schubert 
7245796c8dcSSimon Schubert   if (len > 0)
7255796c8dcSSimon Schubert     {
7265796c8dcSSimon Schubert       fprintf_filtered (stream, " (");
7275796c8dcSSimon Schubert       for (i = 0; i < len; i += 1)
7285796c8dcSSimon Schubert 	{
7295796c8dcSSimon Schubert 	  if (i > 0)
7305796c8dcSSimon Schubert 	    {
7315796c8dcSSimon Schubert 	      fputs_filtered ("; ", stream);
7325796c8dcSSimon Schubert 	      wrap_here ("    ");
7335796c8dcSSimon Schubert 	    }
7345796c8dcSSimon Schubert 	  fprintf_filtered (stream, "a%d: ", i + 1);
735*ef5ccd6cSJohn Marino 	  ada_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0,
736*ef5ccd6cSJohn Marino 			  flags);
7375796c8dcSSimon Schubert 	}
7385796c8dcSSimon Schubert       fprintf_filtered (stream, ")");
7395796c8dcSSimon Schubert     }
7405796c8dcSSimon Schubert 
7415796c8dcSSimon Schubert   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
7425796c8dcSSimon Schubert     {
7435796c8dcSSimon Schubert       fprintf_filtered (stream, " return ");
744*ef5ccd6cSJohn Marino       ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
7455796c8dcSSimon Schubert     }
7465796c8dcSSimon Schubert }
7475796c8dcSSimon Schubert 
7485796c8dcSSimon Schubert 
7495796c8dcSSimon Schubert /* Print a description of a type TYPE0.
7505796c8dcSSimon Schubert    Output goes to STREAM (via stdio).
7515796c8dcSSimon Schubert    If VARSTRING is a non-empty string, print as an Ada variable/field
7525796c8dcSSimon Schubert        declaration.
7535796c8dcSSimon Schubert    SHOW+1 is the maximum number of levels of internal type structure
7545796c8dcSSimon Schubert       to show (this applies to record types, enumerated types, and
7555796c8dcSSimon Schubert       array types).
7565796c8dcSSimon Schubert    SHOW is the number of levels of internal type structure to show
7575796c8dcSSimon Schubert       when there is a type name for the SHOWth deepest level (0th is
7585796c8dcSSimon Schubert       outer level).
7595796c8dcSSimon Schubert    When SHOW<0, no inner structure is shown.
7605796c8dcSSimon Schubert    LEVEL indicates level of recursion (for nested definitions).  */
7615796c8dcSSimon Schubert 
7625796c8dcSSimon Schubert void
ada_print_type(struct type * type0,const char * varstring,struct ui_file * stream,int show,int level,const struct type_print_options * flags)763cf7f2e2dSJohn Marino ada_print_type (struct type *type0, const char *varstring,
764*ef5ccd6cSJohn Marino 		struct ui_file *stream, int show, int level,
765*ef5ccd6cSJohn Marino 		const struct type_print_options *flags)
7665796c8dcSSimon Schubert {
7675796c8dcSSimon Schubert   struct type *type = ada_check_typedef (ada_get_base_type (type0));
7685796c8dcSSimon Schubert   char *type_name = decoded_type_name (type0);
7695796c8dcSSimon Schubert   int is_var_decl = (varstring != NULL && varstring[0] != '\0');
7705796c8dcSSimon Schubert 
7715796c8dcSSimon Schubert   if (type == NULL)
7725796c8dcSSimon Schubert     {
7735796c8dcSSimon Schubert       if (is_var_decl)
7745796c8dcSSimon Schubert 	fprintf_filtered (stream, "%.*s: ",
7755796c8dcSSimon Schubert 			  ada_name_prefix_len (varstring), varstring);
7765796c8dcSSimon Schubert       fprintf_filtered (stream, "<null type?>");
7775796c8dcSSimon Schubert       return;
7785796c8dcSSimon Schubert     }
7795796c8dcSSimon Schubert 
7805796c8dcSSimon Schubert   if (show > 0)
7815796c8dcSSimon Schubert     type = ada_check_typedef (type);
7825796c8dcSSimon Schubert 
7835796c8dcSSimon Schubert   if (is_var_decl && TYPE_CODE (type) != TYPE_CODE_FUNC)
7845796c8dcSSimon Schubert     fprintf_filtered (stream, "%.*s: ",
7855796c8dcSSimon Schubert 		      ada_name_prefix_len (varstring), varstring);
7865796c8dcSSimon Schubert 
787a45ae5f8SJohn Marino   if (type_name != NULL && show <= 0 && !ada_is_aligner_type (type))
7885796c8dcSSimon Schubert     {
7895796c8dcSSimon Schubert       fprintf_filtered (stream, "%.*s",
7905796c8dcSSimon Schubert 			ada_name_prefix_len (type_name), type_name);
7915796c8dcSSimon Schubert       return;
7925796c8dcSSimon Schubert     }
7935796c8dcSSimon Schubert 
7945796c8dcSSimon Schubert   if (ada_is_aligner_type (type))
795*ef5ccd6cSJohn Marino     ada_print_type (ada_aligned_type (type), "", stream, show, level, flags);
796a45ae5f8SJohn Marino   else if (ada_is_constrained_packed_array_type (type)
797a45ae5f8SJohn Marino 	   && TYPE_CODE (type) != TYPE_CODE_PTR)
798*ef5ccd6cSJohn Marino     print_array_type (type, stream, show, level, flags);
7995796c8dcSSimon Schubert   else
8005796c8dcSSimon Schubert     switch (TYPE_CODE (type))
8015796c8dcSSimon Schubert       {
8025796c8dcSSimon Schubert       default:
8035796c8dcSSimon Schubert 	fprintf_filtered (stream, "<");
804*ef5ccd6cSJohn Marino 	c_print_type (type, "", stream, show, level, flags);
8055796c8dcSSimon Schubert 	fprintf_filtered (stream, ">");
8065796c8dcSSimon Schubert 	break;
8075796c8dcSSimon Schubert       case TYPE_CODE_PTR:
808c50c785cSJohn Marino       case TYPE_CODE_TYPEDEF:
8095796c8dcSSimon Schubert 	fprintf_filtered (stream, "access ");
810*ef5ccd6cSJohn Marino 	ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level,
811*ef5ccd6cSJohn Marino 			flags);
8125796c8dcSSimon Schubert 	break;
8135796c8dcSSimon Schubert       case TYPE_CODE_REF:
8145796c8dcSSimon Schubert 	fprintf_filtered (stream, "<ref> ");
815*ef5ccd6cSJohn Marino 	ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level,
816*ef5ccd6cSJohn Marino 			flags);
8175796c8dcSSimon Schubert 	break;
8185796c8dcSSimon Schubert       case TYPE_CODE_ARRAY:
819*ef5ccd6cSJohn Marino 	print_array_type (type, stream, show, level, flags);
8205796c8dcSSimon Schubert 	break;
8215796c8dcSSimon Schubert       case TYPE_CODE_BOOL:
8225796c8dcSSimon Schubert 	fprintf_filtered (stream, "(false, true)");
8235796c8dcSSimon Schubert 	break;
8245796c8dcSSimon Schubert       case TYPE_CODE_INT:
8255796c8dcSSimon Schubert 	if (ada_is_fixed_point_type (type))
8265796c8dcSSimon Schubert 	  print_fixed_point_type (type, stream);
8275796c8dcSSimon Schubert 	else
8285796c8dcSSimon Schubert 	  {
829*ef5ccd6cSJohn Marino 	    const char *name = ada_type_name (type);
830cf7f2e2dSJohn Marino 
8315796c8dcSSimon Schubert 	    if (!ada_is_range_type_name (name))
8325796c8dcSSimon Schubert 	      fprintf_filtered (stream, _("<%d-byte integer>"),
8335796c8dcSSimon Schubert 				TYPE_LENGTH (type));
8345796c8dcSSimon Schubert 	    else
8355796c8dcSSimon Schubert 	      {
8365796c8dcSSimon Schubert 		fprintf_filtered (stream, "range ");
837cf7f2e2dSJohn Marino 		print_range_type (type, stream);
8385796c8dcSSimon Schubert 	      }
8395796c8dcSSimon Schubert 	  }
8405796c8dcSSimon Schubert 	break;
8415796c8dcSSimon Schubert       case TYPE_CODE_RANGE:
8425796c8dcSSimon Schubert 	if (ada_is_fixed_point_type (type))
8435796c8dcSSimon Schubert 	  print_fixed_point_type (type, stream);
8445796c8dcSSimon Schubert 	else if (ada_is_modular_type (type))
8455796c8dcSSimon Schubert 	  fprintf_filtered (stream, "mod %s",
8465796c8dcSSimon Schubert 			    int_string (ada_modulus (type), 10, 0, 0, 1));
8475796c8dcSSimon Schubert 	else
8485796c8dcSSimon Schubert 	  {
8495796c8dcSSimon Schubert 	    fprintf_filtered (stream, "range ");
8505796c8dcSSimon Schubert 	    print_range (type, stream);
8515796c8dcSSimon Schubert 	  }
8525796c8dcSSimon Schubert 	break;
8535796c8dcSSimon Schubert       case TYPE_CODE_FLT:
8545796c8dcSSimon Schubert 	fprintf_filtered (stream, _("<%d-byte float>"), TYPE_LENGTH (type));
8555796c8dcSSimon Schubert 	break;
8565796c8dcSSimon Schubert       case TYPE_CODE_ENUM:
8575796c8dcSSimon Schubert 	if (show < 0)
8585796c8dcSSimon Schubert 	  fprintf_filtered (stream, "(...)");
8595796c8dcSSimon Schubert 	else
8605796c8dcSSimon Schubert 	  print_enum_type (type, stream);
8615796c8dcSSimon Schubert 	break;
8625796c8dcSSimon Schubert       case TYPE_CODE_STRUCT:
8635796c8dcSSimon Schubert 	if (ada_is_array_descriptor_type (type))
864*ef5ccd6cSJohn Marino 	  print_array_type (type, stream, show, level, flags);
8655796c8dcSSimon Schubert 	else if (ada_is_bogus_array_descriptor (type))
8665796c8dcSSimon Schubert 	  fprintf_filtered (stream,
8675796c8dcSSimon Schubert 			    _("array (?) of ? (<mal-formed descriptor>)"));
8685796c8dcSSimon Schubert 	else
869*ef5ccd6cSJohn Marino 	  print_record_type (type, stream, show, level, flags);
8705796c8dcSSimon Schubert 	break;
8715796c8dcSSimon Schubert       case TYPE_CODE_UNION:
872*ef5ccd6cSJohn Marino 	print_unchecked_union_type (type, stream, show, level, flags);
8735796c8dcSSimon Schubert 	break;
8745796c8dcSSimon Schubert       case TYPE_CODE_FUNC:
875*ef5ccd6cSJohn Marino 	print_func_type (type, stream, varstring, flags);
8765796c8dcSSimon Schubert 	break;
8775796c8dcSSimon Schubert       }
8785796c8dcSSimon Schubert }
879cf7f2e2dSJohn Marino 
880cf7f2e2dSJohn Marino /* Implement the la_print_typedef language method for Ada.  */
881cf7f2e2dSJohn Marino 
882cf7f2e2dSJohn Marino void
ada_print_typedef(struct type * type,struct symbol * new_symbol,struct ui_file * stream)883cf7f2e2dSJohn Marino ada_print_typedef (struct type *type, struct symbol *new_symbol,
884cf7f2e2dSJohn Marino                    struct ui_file *stream)
885cf7f2e2dSJohn Marino {
886cf7f2e2dSJohn Marino   type = ada_check_typedef (type);
887*ef5ccd6cSJohn Marino   ada_print_type (type, "", stream, 0, 0, &type_print_raw_options);
888cf7f2e2dSJohn Marino   fprintf_filtered (stream, "\n");
889cf7f2e2dSJohn Marino }
890