/* Support for printing Ada types for GDB, the GNU debugger.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 Free Software Foundation, Inc.
This file is part of GDB.
access to an actual object, which is not available
when the user is using the "ptype" command on a type.
Print the range as an unbounded range. */
- fprintf_filtered (stream, "<>");
+ gdb_printf (stream, "<>");
got_error = 1;
}
if (!got_error)
{
ada_print_scalar (type, lo, stream);
- fprintf_filtered (stream, " .. ");
+ gdb_printf (stream, " .. ");
ada_print_scalar (type, hi, stream);
}
}
break;
default:
- fprintf_filtered (stream, "%.*s",
- ada_name_prefix_len (type->name ()),
- type->name ());
+ gdb_printf (stream, "%.*s",
+ ada_name_prefix_len (type->name ()),
+ type->name ());
break;
}
}
if (ada_scan_number (bounds, *n, &B, n))
{
/* STABS decodes all range types which bounds are 0 .. -1 as
- unsigned integers (ie. the type code is TYPE_CODE_INT, not
- TYPE_CODE_RANGE). Unfortunately, ada_print_scalar() relies
- on the unsigned flag to determine whether the bound should
- be printed as a signed or an unsigned value. This causes
- the upper bound of the 0 .. -1 range types to be printed as
- a very large unsigned number instead of -1.
- To workaround this stabs deficiency, we replace the TYPE by NULL
- to indicate default output when we detect that the bound is negative,
- and the type is a TYPE_CODE_INT. The bound is negative when
- 'm' is the last character of the number scanned in BOUNDS. */
+ unsigned integers (ie. the type code is TYPE_CODE_INT, not
+ TYPE_CODE_RANGE). Unfortunately, ada_print_scalar() relies
+ on the unsigned flag to determine whether the bound should
+ be printed as a signed or an unsigned value. This causes
+ the upper bound of the 0 .. -1 range types to be printed as
+ a very large unsigned number instead of -1.
+ To workaround this stabs deficiency, we replace the TYPE by NULL
+ to indicate default output when we detect that the bound is negative,
+ and the type is a TYPE_CODE_INT. The bound is negative when
+ 'm' is the last character of the number scanned in BOUNDS. */
if (bounds[*n - 1] == 'm' && type->code () == TYPE_CODE_INT)
type = NULL;
ada_print_scalar (type, B, stream);
bound_len = pend - bound;
*n += bound_len + 2;
}
- fprintf_filtered (stream, "%.*s", bound_len, bound);
+ gdb_printf (stream, "%.*s", bound_len, bound);
}
}
if (get_int_var_value (name_buf.c_str (), B))
ada_print_scalar (type, B, stream);
else
- fprintf_filtered (stream, "?");
+ gdb_printf (stream, "?");
}
/* Print RAW_TYPE as a range type, using any bound information
print_dynamic_range_bound (base_type, name, prefix_len, "___L",
stream);
- fprintf_filtered (stream, " .. ");
+ gdb_printf (stream, " .. ");
if (*subtype_info == 'U')
print_range_bound (base_type, bounds_str, &n, stream);
int i;
LONGEST lastval;
- fprintf_filtered (stream, "(");
- wrap_here (" ");
+ gdb_printf (stream, "(");
+ stream->wrap_here (1);
lastval = 0;
for (i = 0; i < len; i++)
{
QUIT;
if (i)
- fprintf_filtered (stream, ", ");
- wrap_here (" ");
- fputs_styled (ada_enum_name (TYPE_FIELD_NAME (type, i)),
+ gdb_printf (stream, ", ");
+ stream->wrap_here (4);
+ fputs_styled (ada_enum_name (type->field (i).name ()),
variable_name_style.style (), stream);
- if (lastval != TYPE_FIELD_ENUMVAL (type, i))
+ if (lastval != type->field (i).loc_enumval ())
{
- fprintf_filtered (stream, " => %s",
- plongest (TYPE_FIELD_ENUMVAL (type, i)));
- lastval = TYPE_FIELD_ENUMVAL (type, i);
+ gdb_printf (stream, " => %s",
+ plongest (type->field (i).loc_enumval ()));
+ lastval = type->field (i).loc_enumval ();
}
lastval += 1;
}
- fprintf_filtered (stream, ")");
-}
-
-/* Print representation of Ada fixed-point type TYPE on STREAM. */
-
-static void
-print_gnat_encoded_fixed_point_type (struct type *type, struct ui_file *stream)
-{
- struct value *delta = gnat_encoded_fixed_point_delta (type);
- struct value *small = gnat_encoded_fixed_point_scaling_factor (type);
-
- if (delta == nullptr)
- fprintf_filtered (stream, "delta ??");
- else
- {
- std::string str;
- str = target_float_to_string (value_contents (delta),
- value_type (delta), "%g");
- fprintf_filtered (stream, "delta %s", str.c_str());
- if (!value_equal (delta, small))
- {
- str = target_float_to_string (value_contents (small),
- value_type (small), "%g");
- fprintf_filtered (stream, " <'small = %s>", str.c_str());
- }
- }
+ gdb_printf (stream, ")");
}
/* Print simple (constrained) array type TYPE on STREAM. LEVEL is the
type = ada_coerce_to_simple_array_type (type);
bitsize = 0;
- fprintf_filtered (stream, "array (");
+ gdb_printf (stream, "array (");
if (type == NULL)
{
arr_type = TYPE_TARGET_TYPE (arr_type))
{
if (arr_type != type)
- fprintf_filtered (stream, ", ");
+ gdb_printf (stream, ", ");
print_range (arr_type->index_type (), stream,
0 /* bounds_prefered_p */);
if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
k += 1, arr_type = TYPE_TARGET_TYPE (arr_type))
{
if (k > 0)
- fprintf_filtered (stream, ", ");
+ gdb_printf (stream, ", ");
print_range_type (range_desc_type->field (k).type (),
stream, 0 /* bounds_prefered_p */);
if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
int i, i0;
for (i = i0 = ada_array_arity (type); i > 0; i -= 1)
- fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", ");
+ gdb_printf (stream, "%s<>", i == i0 ? "" : ", ");
}
elt_type = ada_array_element_type (type, n_indices);
- fprintf_filtered (stream, ") of ");
- wrap_here ("");
+ gdb_printf (stream, ") of ");
+ stream->wrap_here (0);
ada_print_type (elt_type, "", stream, show == 0 ? 0 : show - 1, level + 1,
flags);
/* Arrays with variable-length elements are never bit-packed in practice but
compilers have to describe their stride so that we can properly fetch
individual elements. Do not say the array is packed in this case. */
if (bitsize > 0 && !is_dynamic_type (elt_type))
- fprintf_filtered (stream, " <packed: %d-bit elements>", bitsize);
+ gdb_printf (stream, " <packed: %d-bit elements>", bitsize);
}
/* Print the choices encoded by field FIELD_NUM of variant-part TYPE on
{
int have_output;
int p;
- const char *name = TYPE_FIELD_NAME (type, field_num);
+ const char *name = type->field (field_num).name ();
have_output = 0;
goto Huh;
case '_':
case '\0':
- fprintf_filtered (stream, " =>");
+ gdb_printf (stream, " =>");
return 1;
case 'S':
case 'R':
case 'O':
if (have_output)
- fprintf_filtered (stream, " | ");
+ gdb_printf (stream, " | ");
have_output = 1;
break;
}
|| name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p))
goto Huh;
ada_print_scalar (val_type, L, stream);
- fprintf_filtered (stream, " .. ");
+ gdb_printf (stream, " .. ");
ada_print_scalar (val_type, U, stream);
break;
}
case 'O':
- fprintf_filtered (stream, "others");
+ gdb_printf (stream, "others");
p += 1;
break;
}
}
Huh:
- fprintf_filtered (stream, "? =>");
+ gdb_printf (stream, "? =>");
return 0;
}
+/* A helper for print_variant_clauses that prints the members of
+ VAR_TYPE. DISCR_TYPE is the type of the discriminant (or nullptr
+ if not available). The discriminant is contained in OUTER_TYPE.
+ STREAM, LEVEL, SHOW, and FLAGS are the same as for
+ ada_print_type. */
+
+static void
+print_variant_clauses (struct type *var_type, struct type *discr_type,
+ struct type *outer_type, struct ui_file *stream,
+ int show, int level,
+ const struct type_print_options *flags)
+{
+ for (int i = 0; i < var_type->num_fields (); i += 1)
+ {
+ gdb_printf (stream, "\n%*swhen ", level, "");
+ if (print_choices (var_type, i, stream, discr_type))
+ {
+ if (print_record_field_types (var_type->field (i).type (),
+ outer_type, stream, show, level,
+ flags)
+ <= 0)
+ gdb_printf (stream, " null;");
+ }
+ else
+ print_selected_record_field_types (var_type, outer_type, i, i,
+ stream, show, level, flags);
+ }
+}
+
/* Assuming that field FIELD_NUM of TYPE represents variants whose
discriminant is contained in OUTER_TYPE, print its components on STREAM.
LEVEL is the recursion (indentation) level, in case any of the fields
int show, int level,
const struct type_print_options *flags)
{
- int i;
struct type *var_type, *par_type;
struct type *discr_type;
if (par_type != NULL)
var_type = par_type;
- for (i = 0; i < var_type->num_fields (); i += 1)
- {
- fprintf_filtered (stream, "\n%*swhen ", level + 4, "");
- if (print_choices (var_type, i, stream, discr_type))
- {
- if (print_record_field_types (var_type->field (i).type (),
- outer_type, stream, show, level + 4,
- flags)
- <= 0)
- fprintf_filtered (stream, " null;");
- }
- else
- print_selected_record_field_types (var_type, outer_type, i, i,
- stream, show, level + 4, flags);
- }
+ print_variant_clauses (var_type, discr_type, outer_type, stream, show,
+ level + 4, flags);
}
/* Assuming that field FIELD_NUM of TYPE is a variant part whose
if (*variant == '\0')
variant = "?";
- fprintf_filtered (stream, "\n%*scase %s is", level + 4, "", variant);
+ gdb_printf (stream, "\n%*scase %s is", level + 4, "", variant);
print_variant_clauses (type, field_num, outer_type, stream, show,
level + 4, flags);
- fprintf_filtered (stream, "\n%*send case;", level + 4, "");
+ gdb_printf (stream, "\n%*send case;", level + 4, "");
}
/* Print a description on STREAM of the fields FLD0 through FLD1 in
else
{
flds += 1;
- fprintf_filtered (stream, "\n%*s", level + 4, "");
+ gdb_printf (stream, "\n%*s", level + 4, "");
ada_print_type (type->field (i).type (),
- TYPE_FIELD_NAME (type, i),
+ type->field (i).name (),
stream, show - 1, level + 4, flags);
- fprintf_filtered (stream, ";");
+ gdb_printf (stream, ";");
}
}
print_choices (struct type *discr_type, const variant &variant,
struct ui_file *stream, int level)
{
- fprintf_filtered (stream, "\n%*swhen ", level, "");
+ gdb_printf (stream, "\n%*swhen ", level, "");
if (variant.is_default ())
- fprintf_filtered (stream, "others");
+ gdb_printf (stream, "others");
else
{
bool first = true;
for (const discriminant_range &range : variant.discriminants)
{
if (!first)
- fprintf_filtered (stream, " | ");
+ gdb_printf (stream, " | ");
first = false;
ada_print_scalar (discr_type, range.low, stream);
}
}
- fprintf_filtered (stream, " =>");
+ gdb_printf (stream, " =>");
}
/* Print a single variant part, PART, on STREAM. TYPE is the
name = "?";
else
{
- name = TYPE_FIELD_NAME (type, part.discriminant_index);
+ name = type->field (part.discriminant_index).name ();;
discr_type = type->field (part.discriminant_index).type ();
}
- fprintf_filtered (stream, "\n%*scase %s is", level + 4, "", name);
+ gdb_printf (stream, "\n%*scase %s is", level + 4, "", name);
int last_field = -1;
for (const variant &variant : part.variants)
print_choices (discr_type, variant, stream, level + 8);
if (variant.first_field == variant.last_field)
- fprintf_filtered (stream, " null;");
+ gdb_printf (stream, " null;");
else
{
print_record_field_types_dynamic (variant.parts,
}
}
- fprintf_filtered (stream, "\n%*send case;", level + 4, "");
+ gdb_printf (stream, "\n%*send case;", level + 4, "");
return last_field;
}
prevents a crash trying to print a NULL pointer. */
if (parent_name == NULL)
parent_name = ada_type_name (parent_type);
- fprintf_filtered (stream, "new %s with record", parent_name);
+ gdb_printf (stream, "new %s with record", parent_name);
}
else if (parent_type == NULL && ada_is_tagged_type (type, 0))
- fprintf_filtered (stream, "tagged record");
+ gdb_printf (stream, "tagged record");
else
- fprintf_filtered (stream, "record");
+ gdb_printf (stream, "record");
if (show < 0)
- fprintf_filtered (stream, " ... end record");
+ gdb_printf (stream, " ... end record");
else
{
int flds;
flags);
if (flds > 0)
- fprintf_filtered (stream, "\n%*send record", level, "");
+ gdb_printf (stream, "\n%*send record", level, "");
else if (flds < 0)
- fprintf_filtered (stream, _(" <incomplete type> end record"));
+ gdb_printf (stream, _(" <incomplete type> end record"));
else
- fprintf_filtered (stream, " null; end record");
+ gdb_printf (stream, " null; end record");
}
}
const struct type_print_options *flags)
{
if (show < 0)
- fprintf_filtered (stream, "record (?) is ... end record");
+ gdb_printf (stream, "record (?) is ... end record");
else if (type->num_fields () == 0)
- fprintf_filtered (stream, "record (?) is null; end record");
+ gdb_printf (stream, "record (?) is null; end record");
else
{
- int i;
-
- fprintf_filtered (stream, "record (?) is\n%*scase ? is", level + 4, "");
+ gdb_printf (stream, "record (?) is\n%*scase ? is", level + 4, "");
- for (i = 0; i < type->num_fields (); i += 1)
- {
- fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level + 8, "",
- level + 12, "");
- ada_print_type (type->field (i).type (),
- TYPE_FIELD_NAME (type, i),
- stream, show - 1, level + 12, flags);
- fprintf_filtered (stream, ";");
- }
+ print_variant_clauses (type, nullptr, type, stream, show, level + 8, flags);
- fprintf_filtered (stream, "\n%*send case;\n%*send record",
- level + 4, "", level, "");
+ gdb_printf (stream, "\n%*send case;\n%*send record",
+ level + 4, "", level, "");
}
}
if (TYPE_TARGET_TYPE (type) != NULL
&& TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_VOID)
- fprintf_filtered (stream, "procedure");
+ gdb_printf (stream, "procedure");
else
- fprintf_filtered (stream, "function");
+ gdb_printf (stream, "function");
if (name != NULL && name[0] != '\0')
{
- fputs_filtered (" ", stream);
+ gdb_puts (" ", stream);
fputs_styled (name, function_name_style.style (), stream);
}
if (len > 0)
{
- fprintf_filtered (stream, " (");
+ gdb_printf (stream, " (");
for (i = 0; i < len; i += 1)
{
if (i > 0)
{
- fputs_filtered ("; ", stream);
- wrap_here (" ");
+ gdb_puts ("; ", stream);
+ stream->wrap_here (4);
}
- fprintf_filtered (stream, "a%d: ", i + 1);
+ gdb_printf (stream, "a%d: ", i + 1);
ada_print_type (type->field (i).type (), "", stream, -1, 0,
flags);
}
- fprintf_filtered (stream, ")");
+ gdb_printf (stream, ")");
}
if (TYPE_TARGET_TYPE (type) == NULL)
- fprintf_filtered (stream, " return <unknown return type>");
+ gdb_printf (stream, " return <unknown return type>");
else if (TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_VOID)
{
- fprintf_filtered (stream, " return ");
+ gdb_printf (stream, " return ");
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
}
}
const struct type_print_options *flags)
{
struct type *type = ada_check_typedef (ada_get_base_type (type0));
- char *type_name = decoded_type_name (type0);
+ /* If we can decode the original type name, use it. However, there
+ are cases where the original type is an internally-generated type
+ with a name that can't be decoded (and whose encoded name might
+ not actually bear any relation to the type actually declared in
+ the sources). In that case, try using the name of the base type
+ in its place.
+
+ Note that we looked at the possibility of always using the name
+ of the base type. This does not always work, unfortunately, as
+ there are situations where it's the base type which has an
+ internally-generated name. */
+ const char *type_name = decoded_type_name (type0);
+ if (type_name == nullptr)
+ type_name = decoded_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);
+ gdb_printf (stream, "%.*s: ",
+ ada_name_prefix_len (varstring), varstring);
fprintf_styled (stream, metadata_style.style (), "<null type?>");
return;
}
if (is_var_decl && type->code () != TYPE_CODE_FUNC)
- fprintf_filtered (stream, "%.*s: ",
- ada_name_prefix_len (varstring), varstring);
+ gdb_printf (stream, "%.*s: ",
+ ada_name_prefix_len (varstring), varstring);
if (type_name != NULL && show <= 0 && !ada_is_aligner_type (type))
{
- fprintf_filtered (stream, "%.*s",
- ada_name_prefix_len (type_name), type_name);
+ gdb_printf (stream, "%.*s",
+ ada_name_prefix_len (type_name), type_name);
return;
}
switch (type->code ())
{
default:
- fprintf_filtered (stream, "<");
+ gdb_printf (stream, "<");
c_print_type (type, "", stream, show, level, flags);
- fprintf_filtered (stream, ">");
+ gdb_printf (stream, ">");
break;
case TYPE_CODE_PTR:
case TYPE_CODE_TYPEDEF:
- fprintf_filtered (stream, "access ");
+ /* An __XVL field is not truly a pointer, so don't print
+ "access" in this case. */
+ if (type->code () != TYPE_CODE_PTR
+ || strstr (varstring, "___XVL") == nullptr)
+ gdb_printf (stream, "access ");
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level,
flags);
break;
case TYPE_CODE_REF:
- fprintf_filtered (stream, "<ref> ");
+ gdb_printf (stream, "<ref> ");
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level,
flags);
break;
print_array_type (type, stream, show, level, flags);
break;
case TYPE_CODE_BOOL:
- fprintf_filtered (stream, "(false, true)");
+ gdb_printf (stream, "(false, true)");
break;
case TYPE_CODE_INT:
- if (ada_is_gnat_encoded_fixed_point_type (type))
- print_gnat_encoded_fixed_point_type (type, stream);
- else
- {
- const char *name = ada_type_name (type);
-
- if (!ada_is_range_type_name (name))
- fprintf_styled (stream, metadata_style.style (),
- _("<%s-byte integer>"),
- pulongest (TYPE_LENGTH (type)));
- else
- {
- fprintf_filtered (stream, "range ");
- print_range_type (type, stream, 1 /* bounds_prefered_p */);
- }
- }
+ {
+ const char *name = ada_type_name (type);
+
+ if (!ada_is_range_type_name (name))
+ fprintf_styled (stream, metadata_style.style (),
+ _("<%s-byte integer>"),
+ pulongest (TYPE_LENGTH (type)));
+ else
+ {
+ gdb_printf (stream, "range ");
+ print_range_type (type, stream, 1 /* bounds_prefered_p */);
+ }
+ }
break;
case TYPE_CODE_RANGE:
- if (ada_is_gnat_encoded_fixed_point_type (type))
- print_gnat_encoded_fixed_point_type (type, stream);
+ if (is_fixed_point_type (type))
+ {
+ gdb_printf (stream, "<");
+ print_type_fixed_point (type, stream);
+ gdb_printf (stream, ">");
+ }
else if (ada_is_modular_type (type))
- fprintf_filtered (stream, "mod %s",
- int_string (ada_modulus (type), 10, 0, 0, 1));
+ gdb_printf (stream, "mod %s",
+ int_string (ada_modulus (type), 10, 0, 0, 1));
else
{
- fprintf_filtered (stream, "range ");
+ gdb_printf (stream, "range ");
print_range (type, stream, 1 /* bounds_prefered_p */);
}
break;
break;
case TYPE_CODE_ENUM:
if (show < 0)
- fprintf_filtered (stream, "(...)");
+ gdb_printf (stream, "(...)");
else
print_enum_type (type, stream);
break;
if (ada_is_array_descriptor_type (type))
print_array_type (type, stream, show, level, flags);
else if (ada_is_bogus_array_descriptor (type))
- fprintf_filtered (stream,
- _("array (?) of ? (<mal-formed descriptor>)"));
+ gdb_printf (stream,
+ _("array (?) of ? (<mal-formed descriptor>)"));
else
print_record_type (type, stream, show, level, flags);
break;
void
ada_print_typedef (struct type *type, struct symbol *new_symbol,
- struct ui_file *stream)
+ struct ui_file *stream)
{
type = ada_check_typedef (type);
ada_print_type (type, "", stream, 0, 0, &type_print_raw_options);