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