From 256f17be375910358b134f2fbf40b529f5a0fb34 Mon Sep 17 00:00:00 2001 From: Aidan Skinner Date: Tue, 4 Jun 2002 15:28:49 +0000 Subject: Add base ada language files --- gdb/ada-typeprint.c | 896 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 896 insertions(+) create mode 100644 gdb/ada-typeprint.c (limited to 'gdb/ada-typeprint.c') diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c new file mode 100644 index 00000000000..677356186b2 --- /dev/null +++ b/gdb/ada-typeprint.c @@ -0,0 +1,896 @@ +/* Support for printing Ada types for GDB, the GNU debugger. + Copyright 1986, 1988, 1989, 1991, 1997 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "obstack.h" +#include "bfd.h" /* Binary File Description */ +#include "symtab.h" +#include "gdbtypes.h" +#include "expression.h" +#include "value.h" +#include "gdbcore.h" +#include "target.h" +#include "command.h" +#include "gdbcmd.h" +#include "language.h" +#include "demangle.h" +#include "c-lang.h" +#include "typeprint.h" +#include "ada-lang.h" + +#include +#include +#include + +static int print_record_field_types (struct type *, struct type *, + struct ui_file *, int, int); + +static void print_array_type (struct type*, struct ui_file*, int, int); + +static void print_choices (struct type*, int, struct ui_file*, struct type*); + +static void print_range (struct type*, struct ui_file*); + +static void print_range_bound (struct type*, char*, int*, struct ui_file*); + +static void +print_dynamic_range_bound (struct type*, const char*, int, + const char*, struct ui_file*); + +static void print_range_type_named (char*, struct ui_file*); + + + +static char* name_buffer; +static int name_buffer_len; + +/* The (demangled) Ada name of TYPE. This value persists until the + next call. */ + +static char* +demangled_type_name (type) + struct type *type; +{ + if (ada_type_name (type) == NULL) + return NULL; + else + { + char* raw_name = ada_type_name (type); + char *s, *q; + + if (name_buffer == NULL || name_buffer_len <= strlen (raw_name)) + { + name_buffer_len = 16 + 2 * strlen (raw_name); + name_buffer = xrealloc (name_buffer, name_buffer_len); + } + strcpy (name_buffer, raw_name); + + s = (char*) strstr (name_buffer, "___"); + if (s != NULL) + *s = '\0'; + + s = name_buffer + strlen (name_buffer) - 1; + while (s > name_buffer && (s[0] != '_' || s[-1] != '_')) + s -= 1; + + if (s == name_buffer) + return name_buffer; + + if (! islower (s[1])) + return NULL; + + for (s = q = name_buffer; *s != '\0'; q += 1) + { + if (s[0] == '_' && s[1] == '_') + { + *q = '.'; s += 2; + } + else + { + *q = *s; s += 1; + } + } + *q = '\0'; + return name_buffer; + } +} + + +/* Print a description of a type in the format of a + typedef for the current language. + NEW is the new name for a type TYPE. */ + +void +ada_typedef_print (type, new, stream) + struct type *type; + struct symbol *new; + struct ui_file *stream; +{ + fprintf_filtered (stream, "type %.*s is ", + ada_name_prefix_len (SYMBOL_SOURCE_NAME(new)), + SYMBOL_SOURCE_NAME(new)); + type_print (type, "", stream, 1); +} + +/* Print range type TYPE on STREAM. */ + +static void +print_range (type, stream) + struct type* type; + struct ui_file* stream; +{ + struct type* target_type; + target_type = TYPE_TARGET_TYPE (type); + if (target_type == NULL) + target_type = type; + + switch (TYPE_CODE (target_type)) + { + case TYPE_CODE_RANGE: + case TYPE_CODE_INT: + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: + case TYPE_CODE_ENUM: + break; + default: + target_type = builtin_type_ada_int; + break; + } + + if (TYPE_NFIELDS (type) < 2) + { + /* A range needs at least 2 bounds to be printed. If there are less + than 2, just print the type name instead of the range itself. + This check handles cases such as characters, for example. + + Note that if the name is not defined, then we don't print anything. + */ + fprintf_filtered (stream, "%.*s", + ada_name_prefix_len (TYPE_NAME (type)), + TYPE_NAME (type)); + } + else + { + /* We extract the range type bounds respectively from the first element + and the last element of the type->fields array */ + const LONGEST lower_bound = (LONGEST) TYPE_LOW_BOUND (type); + const LONGEST upper_bound = + (LONGEST) TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) -1); + + ada_print_scalar (target_type, lower_bound, stream); + fprintf_filtered (stream, " .. "); + ada_print_scalar (target_type, upper_bound, stream); + } +} + +/* Print the number or discriminant bound at BOUNDS+*N on STREAM, and + set *N past the bound and its delimiter, if any. */ + +static void +print_range_bound (type, bounds, n, stream) + struct type* type; + char* bounds; + int* n; + struct ui_file* stream; +{ + LONGEST B; + if (ada_scan_number (bounds, *n, &B, n)) + { + ada_print_scalar (type, B, stream); + if (bounds[*n] == '_') + *n += 2; + } + else + { + int bound_len; + char* bound = bounds + *n; + char* pend; + + pend = strstr (bound, "__"); + if (pend == NULL) + *n += bound_len = strlen (bound); + else + { + bound_len = pend - bound; + *n += bound_len + 2; + } + fprintf_filtered (stream, "%.*s", bound_len, bound); + } +} + +/* Assuming NAME[0 .. NAME_LEN-1] is the name of a range type, print + the value (if found) of the bound indicated by SUFFIX ("___L" or + "___U") according to the ___XD conventions. */ + +static void +print_dynamic_range_bound (type, name, name_len, suffix, stream) + struct type* type; + const char* name; + int name_len; + const char* suffix; + struct ui_file* stream; +{ + static char *name_buf = NULL; + static size_t name_buf_len = 0; + LONGEST B; + int OK; + + GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1); + strncpy (name_buf, name, name_len); + strcpy (name_buf + name_len, suffix); + + B = get_int_var_value (name_buf, 0, &OK); + if (OK) + ada_print_scalar (type, B, stream); + else + fprintf_filtered (stream, "?"); +} + +/* Print the range type named NAME. */ + +static void +print_range_type_named (name, stream) + char* name; + struct ui_file* stream; +{ + struct type *raw_type = ada_find_any_type (name); + struct type *base_type; + LONGEST low, high; + char* subtype_info; + + if (raw_type == NULL) + base_type = builtin_type_int; + else if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE) + base_type = TYPE_TARGET_TYPE (raw_type); + else + base_type = raw_type; + + subtype_info = strstr (name, "___XD"); + if (subtype_info == NULL && raw_type == NULL) + fprintf_filtered (stream, "? .. ?"); + else if (subtype_info == NULL) + print_range (raw_type, stream); + else + { + int prefix_len = subtype_info - name; + char *bounds_str; + int n; + + subtype_info += 5; + bounds_str = strchr (subtype_info, '_'); + n = 1; + + if (*subtype_info == 'L') + { + print_range_bound (raw_type, bounds_str, &n, stream); + subtype_info += 1; + } + else + print_dynamic_range_bound (raw_type, name, prefix_len, "___L", stream); + + fprintf_filtered (stream, " .. "); + + if (*subtype_info == 'U') + print_range_bound (raw_type, bounds_str, &n, stream); + else + print_dynamic_range_bound (raw_type, name, prefix_len, "___U", stream); + } +} + +/* Print enumerated type TYPE on STREAM. */ + +static void +print_enum_type (type, stream) + struct type *type; + struct ui_file *stream; +{ + int len = TYPE_NFIELDS (type); + int i, lastval; + + fprintf_filtered (stream, "("); + wrap_here (" "); + + lastval = 0; + for (i = 0; i < len; i++) + { + QUIT; + if (i) fprintf_filtered (stream, ", "); + wrap_here (" "); + fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream); + if (lastval != TYPE_FIELD_BITPOS (type, i)) + { + fprintf_filtered (stream, " => %d", TYPE_FIELD_BITPOS (type, i)); + lastval = TYPE_FIELD_BITPOS (type, i); + } + lastval += 1; + } + fprintf_filtered (stream, ")"); +} + +/* Print representation of Ada fixed-point type TYPE on STREAM. */ + +static void +print_fixed_point_type (type, stream) + struct type *type; + struct ui_file *stream; +{ + DOUBLEST delta = ada_delta (type); + DOUBLEST small = ada_fixed_to_float (type, 1.0); + + if (delta < 0.0) + fprintf_filtered (stream, "delta ??"); + else + { + fprintf_filtered (stream, "delta %g", (double) delta); + if (delta != small) + fprintf_filtered (stream, " <'small = %g>", (double) small); + } +} + +/* Print representation of special VAX floating-point type TYPE on STREAM. */ + +static void +print_vax_floating_point_type (type, stream) + struct type *type; + struct ui_file *stream; +{ + fprintf_filtered (stream, "", + ada_vax_float_type_suffix (type)); +} + +/* Print simple (constrained) array type TYPE on STREAM. LEVEL is the + recursion (indentation) level, in case the element type itself has + nested structure, and SHOW is the number of levels of internal + structure to show (see ada_print_type). */ + +static void +print_array_type (type, stream, show, level) + struct type *type; + struct ui_file *stream; + int show; + int level; +{ + int bitsize; + int n_indices; + + bitsize = 0; + fprintf_filtered (stream, "array ("); + + n_indices = -1; + if (show < 0) + fprintf_filtered (stream, "..."); + else + { + if (ada_is_packed_array_type (type)) + type = ada_coerce_to_simple_array_type (type); + if (ada_is_simple_array (type)) + { + struct type* range_desc_type = + ada_find_parallel_type (type, "___XA"); + struct type* arr_type; + + bitsize = 0; + if (range_desc_type == NULL) + { + for (arr_type = type; TYPE_CODE (arr_type) == TYPE_CODE_ARRAY; + arr_type = TYPE_TARGET_TYPE (arr_type)) + { + if (arr_type != type) + fprintf_filtered (stream, ", "); + print_range (TYPE_INDEX_TYPE (arr_type), stream); + if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0) + bitsize = TYPE_FIELD_BITSIZE (arr_type, 0); + } + } + else + { + int k; + n_indices = TYPE_NFIELDS (range_desc_type); + for (k = 0, arr_type = type; + k < n_indices; + k += 1, arr_type = TYPE_TARGET_TYPE (arr_type)) + { + if (k > 0) + fprintf_filtered (stream, ", "); + print_range_type_named (TYPE_FIELD_NAME (range_desc_type, k), + stream); + if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0) + bitsize = TYPE_FIELD_BITSIZE (arr_type, 0); + } + } + } + else + { + int i, i0; + for (i = i0 = ada_array_arity (type); i > 0; i -= 1) + fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", "); + } + } + + fprintf_filtered (stream, ") of "); + wrap_here (""); + ada_print_type (ada_array_element_type (type, n_indices), "", stream, + show == 0 ? 0 : show-1, level+1); + if (bitsize > 0) + fprintf_filtered (stream, " ", bitsize); +} + +/* Print the choices encoded by field FIELD_NUM of variant-part TYPE on + STREAM, assuming the VAL_TYPE is the type of the values. */ + +static void +print_choices (type, field_num, stream, val_type) + struct type *type; + int field_num; + struct ui_file *stream; + struct type *val_type; +{ + int have_output; + int p; + const char* name = TYPE_FIELD_NAME (type, field_num); + + have_output = 0; + + /* Skip over leading 'V': NOTE soon to be obsolete. */ + if (name[0] == 'V') + { + if (! ada_scan_number (name, 1, NULL, &p)) + goto Huh; + } + else + p = 0; + + while (1) + { + switch (name[p]) + { + default: + return; + case 'S': + case 'R': + case 'O': + if (have_output) + fprintf_filtered (stream, " | "); + have_output = 1; + break; + } + + switch (name[p]) + { + case 'S': + { + LONGEST W; + if (! ada_scan_number (name, p + 1, &W, &p)) + goto Huh; + ada_print_scalar (val_type, W, stream); + break; + } + case 'R': + { + LONGEST L, U; + if (! ada_scan_number (name, p + 1, &L, &p) + || name[p] != 'T' + || ! ada_scan_number (name, p + 1, &U, &p)) + goto Huh; + ada_print_scalar (val_type, L, stream); + fprintf_filtered (stream, " .. "); + ada_print_scalar (val_type, U, stream); + break; + } + case 'O': + fprintf_filtered (stream, "others"); + p += 1; + break; + } + } + +Huh: + fprintf_filtered (stream, "??"); + +} + +/* Assuming that field FIELD_NUM of TYPE is a VARIANTS field whose + discriminant is contained in OUTER_TYPE, print its variants on STREAM. + LEVEL is the recursion + (indentation) level, in case any of the fields themselves have + nested structure, and SHOW is the number of levels of internal structure + to show (see ada_print_type). For this purpose, fields nested in a + variant part are taken to be at the same level as the fields + immediately outside the variant part. */ + +static void +print_variant_clauses (type, field_num, outer_type, stream, show, level) + struct type *type; + int field_num; + struct type *outer_type; + struct ui_file *stream; + int show; + int level; +{ + int i; + struct type *var_type; + struct type *discr_type; + + var_type = TYPE_FIELD_TYPE (type, field_num); + discr_type = ada_variant_discrim_type (var_type, outer_type); + + if (TYPE_CODE (var_type) == TYPE_CODE_PTR) + { + var_type = TYPE_TARGET_TYPE (var_type); + if (TYPE_FLAGS (var_type) & TYPE_FLAG_STUB) + { + var_type = ada_find_parallel_type (var_type, "___XVU"); + if (var_type == NULL) + return; + } + } + + for (i = 0; i < TYPE_NFIELDS (var_type); i += 1) + { + fprintf_filtered (stream, "\n%*swhen ", level + 4, ""); + print_choices (var_type, i, stream, discr_type); + fprintf_filtered (stream, " =>"); + if (print_record_field_types (TYPE_FIELD_TYPE (var_type, i), + outer_type, stream, show, level+4) <= 0) + fprintf_filtered (stream, " null;"); + } +} + +/* Assuming that field FIELD_NUM of TYPE is a variant part whose + discriminants are contained in OUTER_TYPE, print a description of it + on STREAM. LEVEL is the recursion (indentation) level, in case any of + the fields themselves have nested structure, and SHOW is the number of + levels of internal structure to show (see ada_print_type). For this + purpose, fields nested in a variant part are taken to be at the same + level as the fields immediately outside the variant part. */ + +static void +print_variant_part (type, field_num, outer_type, stream, show, level) + struct type *type; + int field_num; + struct type *outer_type; + struct ui_file *stream; + int show; + int level; +{ + fprintf_filtered (stream, "\n%*scase %s is", level + 4, "", + ada_variant_discrim_name + (TYPE_FIELD_TYPE (type, field_num))); + print_variant_clauses (type, field_num, outer_type, stream, show, level + 4); + fprintf_filtered (stream, "\n%*send case;", level + 4, ""); +} + +/* Print a description on STREAM of the fields in record type TYPE, whose + discriminants are in OUTER_TYPE. LEVEL is the recursion (indentation) + level, in case any of the fields themselves have nested structure, + and SHOW is the number of levels of internal structure to show + (see ada_print_type). Does not print parent type information of TYPE. + Returns 0 if no fields printed, -1 for an incomplete type, else > 0. + Prints each field beginning on a new line, but does not put a new line at + end. */ + +static int +print_record_field_types (type, outer_type, stream, show, level) + struct type *type; + struct type *outer_type; + struct ui_file *stream; + int show; + int level; +{ + int len, i, flds; + + flds = 0; + len = TYPE_NFIELDS (type); + + if (len == 0 && (TYPE_FLAGS (type) & TYPE_FLAG_STUB) != 0) + return -1; + + for (i = 0; i < len; i += 1) + { + QUIT; + + if (ada_is_parent_field (type, i) + || ada_is_ignored_field (type, i)) + ; + else if (ada_is_wrapper_field (type, i)) + flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type, + stream, show, level); + else if (ada_is_variant_part (type, i)) + { + print_variant_part (type, i, outer_type, stream, show, level); + flds = 1; + } + else + { + flds += 1; + fprintf_filtered (stream, "\n%*s", level + 4, ""); + ada_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 4); + fprintf_filtered (stream, ";"); + } + } + + return flds; +} + +/* Print record type TYPE on STREAM. LEVEL is the recursion (indentation) + level, in case the element type itself has nested structure, and SHOW is + the number of levels of internal structure to show (see ada_print_type). */ + +static void +print_record_type (type0, stream, show, level) + struct type* type0; + struct ui_file* stream; + int show; + int level; +{ + struct type* parent_type; + struct type* type; + + type = type0; + if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) + { + struct type* type1 = ada_find_parallel_type (type, "___XVE"); + if (type1 != NULL) + type = type1; + } + + parent_type = ada_parent_type (type); + if (ada_type_name (parent_type) != NULL) + fprintf_filtered (stream, "new %s with ", + demangled_type_name (parent_type)); + else if (parent_type == NULL && ada_is_tagged_type (type)) + fprintf_filtered (stream, "tagged "); + + fprintf_filtered (stream, "record"); + + if (show < 0) + fprintf_filtered (stream, " ... end record"); + else + { + int flds; + + flds = 0; + if (parent_type != NULL && ada_type_name (parent_type) == NULL) + flds += print_record_field_types (parent_type, parent_type, + stream, show, level); + flds += print_record_field_types (type, type, stream, show, level); + + if (flds > 0) + fprintf_filtered (stream, "\n%*send record", level, ""); + else if (flds < 0) + fprintf_filtered (stream, " end record"); + else + fprintf_filtered (stream, " null; end record"); + } +} + +/* Print the unchecked union type TYPE in something resembling Ada + format on STREAM. LEVEL is the recursion (indentation) level + in case the element type itself has nested structure, and SHOW is the + number of levels of internal structure to show (see ada_print_type). */ +static void +print_unchecked_union_type (struct type* type, struct ui_file* stream, + int show, int level) +{ + fprintf_filtered (stream, "record (?) is"); + + if (show < 0) + fprintf_filtered (stream, " ... end record"); + else if (TYPE_NFIELDS (type) == 0) + fprintf_filtered (stream, " null; end record"); + else + { + int i; + + fprintf_filtered (stream, "\n%*scase ? is", + level+4, ""); + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + { + fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level+8, "", + level+12, ""); + ada_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 12); + fprintf_filtered (stream, ";"); + } + + fprintf_filtered (stream, "\n%*send case;\n%*send record", + level+4, "", level, ""); + } +} + + + +/* Print function or procedure type TYPE on STREAM. Make it a header + for function or procedure NAME if NAME is not null. */ + +static void +print_func_type (type, stream, name) + struct type *type; + struct ui_file *stream; + char* name; +{ + int i, len = TYPE_NFIELDS (type); + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID) + fprintf_filtered (stream, "procedure"); + else + fprintf_filtered (stream, "function"); + + if (name != NULL && name[0] != '\0') + fprintf_filtered (stream, " %s", name); + + if (len > 0) + { + fprintf_filtered (stream, " ("); + for (i = 0; i < len; i += 1) + { + if (i > 0) + { + fputs_filtered ("; ", stream); + wrap_here (" "); + } + fprintf_filtered (stream, "a%d: ", i+1); + ada_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); + } + fprintf_filtered (stream, ")"); + } + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) + { + fprintf_filtered (stream, " return "); + ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0); + } +} + + +/* Print a description of a type TYPE0. + Output goes to STREAM (via stdio). + If VARSTRING is a non-empty string, print as an Ada variable/field + declaration. + SHOW+1 is the maximum number of levels of internal type structure + to show (this applies to record types, enumerated types, and + array types). + SHOW is the number of levels of internal type structure to show + when there is a type name for the SHOWth deepest level (0th is + outer level). + When SHOW<0, no inner structure is shown. + LEVEL indicates level of recursion (for nested definitions). */ + +void +ada_print_type (type0, varstring, stream, show, level) + struct type* type0; + char* varstring; + struct ui_file* stream; + int show; + int level; +{ + enum type_code code; + int demangled_args; + struct type* type = ada_completed_type (ada_get_base_type (type0)); + char* type_name = demangled_type_name (type); + int is_var_decl = (varstring != NULL && varstring[0] != '\0'); + + if (type == NULL) + { + if (is_var_decl) + fprintf_filtered (stream, "%.*s: ", + ada_name_prefix_len(varstring), + varstring); + fprintf_filtered (stream, ""); + return; + } + + if (show > 0) + CHECK_TYPEDEF (type); + + if (is_var_decl && TYPE_CODE (type) != TYPE_CODE_FUNC) + fprintf_filtered (stream, "%.*s: ", + ada_name_prefix_len (varstring), varstring); + + if (type_name != NULL && show <= 0) + { + fprintf_filtered (stream, "%.*s", + ada_name_prefix_len (type_name), type_name); + return; + } + + if (ada_is_aligner_type (type)) + ada_print_type (ada_aligned_type (type), "", stream, show, level); + else if (ada_is_packed_array_type (type)) + print_array_type (type, stream, show, level); + else + switch (TYPE_CODE (type)) + { + default: + fprintf_filtered (stream, "<"); + c_print_type (type, "", stream, show, level); + fprintf_filtered (stream, ">"); + break; + case TYPE_CODE_PTR: + fprintf_filtered (stream, "access "); + ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, + level); + break; + case TYPE_CODE_REF: + fprintf_filtered (stream, " "); + ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, + level); + break; + case TYPE_CODE_ARRAY: + print_array_type (type, stream, show, level); + break; + case TYPE_CODE_INT: + if (ada_is_fixed_point_type (type)) + print_fixed_point_type (type, stream); + else if (ada_is_vax_floating_type (type)) + print_vax_floating_point_type (type, stream); + else + { + char* name = ada_type_name (type); + if (! ada_is_range_type_name (name)) + fprintf_filtered (stream, "<%d-byte integer>", TYPE_LENGTH (type)); + else + { + fprintf_filtered (stream, "range "); + print_range_type_named (name, stream); + } + } + break; + case TYPE_CODE_RANGE: + if (ada_is_fixed_point_type (type)) + print_fixed_point_type (type, stream); + else if (ada_is_vax_floating_type (type)) + print_vax_floating_point_type (type, stream); + else if (ada_is_modular_type (type)) + fprintf_filtered (stream, "mod %ld", (long) ada_modulus (type)); + else + { + fprintf_filtered (stream, "range "); + print_range (type, stream); + } + break; + case TYPE_CODE_FLT: + fprintf_filtered (stream, "<%d-byte float>", TYPE_LENGTH (type)); + break; + case TYPE_CODE_ENUM: + if (show < 0) + fprintf_filtered (stream, "(...)"); + else + print_enum_type (type, stream); + break; + case TYPE_CODE_STRUCT: + if (ada_is_array_descriptor (type)) + print_array_type (type, stream, show, level); + else if (ada_is_bogus_array_descriptor (type)) + fprintf_filtered (stream, "array (?) of ? ()"); + else + print_record_type (type, stream, show, level); + break; + case TYPE_CODE_UNION: + print_unchecked_union_type (type, stream, show, level); + break; + case TYPE_CODE_FUNC: + print_func_type (type, stream, varstring); + break; + } +} -- cgit v1.2.1