X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fada-typeprint.c;h=83972fe125dc24103c8df54212d8c444931232c4;hb=d656f129ebc7b96db96244d0206fc7fb9af85a65;hp=0d1f9dc117c07bbafb2cbb5df1dcea80887d45af;hpb=3ec5942fbf8501db10784b0dff7d24222a113728;p=binutils-gdb.git diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c index 0d1f9dc117c..83972fe125d 100644 --- a/gdb/ada-typeprint.c +++ b/gdb/ada-typeprint.c @@ -1,5 +1,5 @@ /* Support for printing Ada types for GDB, the GNU debugger. - Copyright (C) 1986-2017 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -17,20 +17,13 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_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 "cli/cli-style.h" #include "typeprint.h" +#include "target-float.h" #include "ada-lang.h" #include @@ -158,20 +151,15 @@ print_range (struct type *type, struct ui_file *stream, case TYPE_CODE_RANGE: case TYPE_CODE_ENUM: { - struct type *target_type; LONGEST lo = 0, hi = 0; /* init for gcc -Wall */ int got_error = 0; - target_type = TYPE_TARGET_TYPE (type); - if (target_type == NULL) - target_type = type; - - TRY + try { lo = ada_discrete_type_low_bound (type); hi = ada_discrete_type_high_bound (type); } - CATCH (e, RETURN_MASK_ERROR) + catch (const gdb_exception_error &e) { /* This can happen when the range is dynamic. Sometimes, resolving dynamic property values requires us to have @@ -181,13 +169,12 @@ print_range (struct type *type, struct ui_file *stream, fprintf_filtered (stream, "<>"); got_error = 1; } - END_CATCH if (!got_error) { - ada_print_scalar (target_type, lo, stream); + ada_print_scalar (type, lo, stream); fprintf_filtered (stream, " .. "); - ada_print_scalar (target_type, hi, stream); + ada_print_scalar (type, hi, stream); } } break; @@ -339,7 +326,8 @@ print_enum_type (struct type *type, struct ui_file *stream) if (i) fprintf_filtered (stream, ", "); wrap_here (" "); - fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream); + fputs_styled (ada_enum_name (TYPE_FIELD_NAME (type, i)), + variable_name_style.style (), stream); if (lastval != TYPE_FIELD_ENUMVAL (type, i)) { fprintf_filtered (stream, " => %s", @@ -356,16 +344,23 @@ print_enum_type (struct type *type, struct ui_file *stream) static void print_fixed_point_type (struct type *type, struct ui_file *stream) { - DOUBLEST delta = ada_delta (type); - DOUBLEST small = ada_fixed_to_float (type, 1); + struct value *delta = ada_delta (type); + struct value *small = ada_scaling_factor (type); - if (delta < 0.0) + if (delta == nullptr) fprintf_filtered (stream, "delta ??"); else { - fprintf_filtered (stream, "delta %g", (double) delta); - if (delta != small) - fprintf_filtered (stream, " <'small = %g>", (double) small); + 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()); + } } } @@ -390,7 +385,8 @@ print_array_type (struct type *type, struct ui_file *stream, int show, if (type == NULL) { - fprintf_filtered (stream, _("")); + fprintf_styled (stream, metadata_style.style (), + _("")); return; } @@ -460,7 +456,7 @@ print_array_type (struct type *type, struct ui_file *stream, int show, values. Return non-zero if the field is an encoding of discriminant values, as in a standard variant record, and 0 if the field is not so encoded (as happens with single-component variants - in types annotated with pragma Unchecked_Variant). */ + in types annotated with pragma Unchecked_Union). */ static int print_choices (struct type *type, int field_num, struct ui_file *stream, @@ -531,7 +527,7 @@ print_choices (struct type *type, int field_num, struct ui_file *stream, } Huh: - fprintf_filtered (stream, "?? =>"); + fprintf_filtered (stream, "? =>"); return 0; } @@ -597,9 +593,12 @@ 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) { - fprintf_filtered (stream, "\n%*scase %s is", level + 4, "", - ada_variant_discrim_name - (TYPE_FIELD_TYPE (type, field_num))); + const char *variant + = ada_variant_discrim_name (TYPE_FIELD_TYPE (type, field_num)); + if (*variant == '\0') + variant = "?"; + + fprintf_filtered (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, ""); @@ -655,6 +654,120 @@ print_selected_record_field_types (struct type *type, struct type *outer_type, return flds; } +static void print_record_field_types_dynamic + (const gdb::array_view &parts, + int from, int to, struct type *type, struct ui_file *stream, + int show, int level, const struct type_print_options *flags); + +/* Print the choices encoded by VARIANT on STREAM. LEVEL is the + indentation level. The type of the discriminant for VARIANT is + given by DISR_TYPE. */ + +static void +print_choices (struct type *discr_type, const variant &variant, + struct ui_file *stream, int level) +{ + fprintf_filtered (stream, "\n%*swhen ", level, ""); + if (variant.is_default ()) + fprintf_filtered (stream, "others"); + else + { + bool first = true; + for (const discriminant_range &range : variant.discriminants) + { + if (!first) + fprintf_filtered (stream, " | "); + first = false; + + ada_print_scalar (discr_type, range.low, stream); + if (range.low != range.high) + ada_print_scalar (discr_type, range.high, stream); + } + } + + fprintf_filtered (stream, " =>"); +} + +/* Print a single variant part, PART, on STREAM. TYPE is the + enclosing type. SHOW, LEVEL, and FLAGS are the usual type-printing + settings. This prints information about PART and the fields it + controls. It returns the index of the next field that should be + shown -- that is, one after the last field printed by this + call. */ + +static int +print_variant_part (const variant_part &part, + struct type *type, struct ui_file *stream, + int show, int level, + const struct type_print_options *flags) +{ + struct type *discr_type = nullptr; + const char *name; + if (part.discriminant_index == -1) + name = "?"; + else + { + name = TYPE_FIELD_NAME (type, part.discriminant_index); + discr_type = TYPE_FIELD_TYPE (type, part.discriminant_index); + } + + fprintf_filtered (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;"); + else + { + print_record_field_types_dynamic (variant.parts, + variant.first_field, + variant.last_field, type, stream, + show, level + 8, flags); + last_field = variant.last_field; + } + } + + fprintf_filtered (stream, "\n%*send case;", level + 4, ""); + + return last_field; +} + +/* Print some fields of TYPE to STREAM. SHOW, LEVEL, and FLAGS are + the usual type-printing settings. PARTS is the array of variant + parts that correspond to the range of fields to be printed. FROM + and TO are the range of fields to print. */ + +static void +print_record_field_types_dynamic (const gdb::array_view &parts, + int from, int to, + struct type *type, struct ui_file *stream, + int show, int level, + const struct type_print_options *flags) +{ + int field = from; + + for (const variant_part &part : parts) + { + if (part.variants.empty ()) + continue; + + /* Print any non-varying fields. */ + int first_varying = part.variants[0].first_field; + print_selected_record_field_types (type, type, field, + first_varying - 1, stream, + show, level, flags); + + field = print_variant_part (part, type, stream, show, level, flags); + } + + /* Print any trailing fields that we were asked to print. */ + print_selected_record_field_types (type, type, field, to - 1, stream, show, + level, flags); +} + /* Print a description on STREAM of all fields of record or union type TYPE, as for print_selected_record_field_types, above. */ @@ -663,6 +776,21 @@ 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) { + struct dynamic_prop *prop = get_dyn_prop (DYN_PROP_VARIANT_PARTS, type); + if (prop != nullptr) + { + if (prop->kind == PROP_TYPE) + { + type = prop->data.original_type; + prop = get_dyn_prop (DYN_PROP_VARIANT_PARTS, type); + } + gdb_assert (prop->kind == PROP_VARIANT_PARTS); + print_record_field_types_dynamic (*prop->data.variant_parts, + 0, TYPE_NFIELDS (type), + type, stream, show, level, flags); + return TYPE_NFIELDS (type); + } + return print_selected_record_field_types (type, outer_type, 0, TYPE_NFIELDS (type) - 1, stream, show, level, flags); @@ -776,7 +904,10 @@ print_func_type (struct type *type, struct ui_file *stream, const char *name, fprintf_filtered (stream, "function"); if (name != NULL && name[0] != '\0') - fprintf_filtered (stream, " %s", name); + { + fputs_filtered (" ", stream); + fputs_styled (name, function_name_style.style (), stream); + } if (len > 0) { @@ -832,7 +963,7 @@ ada_print_type (struct type *type0, const char *varstring, if (is_var_decl) fprintf_filtered (stream, "%.*s: ", ada_name_prefix_len (varstring), varstring); - fprintf_filtered (stream, ""); + fprintf_styled (stream, metadata_style.style (), ""); return; } @@ -888,8 +1019,9 @@ ada_print_type (struct type *type0, const char *varstring, const char *name = ada_type_name (type); if (!ada_is_range_type_name (name)) - fprintf_filtered (stream, _("<%d-byte integer>"), - TYPE_LENGTH (type)); + fprintf_styled (stream, metadata_style.style (), + _("<%s-byte integer>"), + pulongest (TYPE_LENGTH (type))); else { fprintf_filtered (stream, "range "); @@ -910,7 +1042,9 @@ ada_print_type (struct type *type0, const char *varstring, } break; case TYPE_CODE_FLT: - fprintf_filtered (stream, _("<%d-byte float>"), TYPE_LENGTH (type)); + fprintf_styled (stream, metadata_style.style (), + _("<%s-byte float>"), + pulongest (TYPE_LENGTH (type))); break; case TYPE_CODE_ENUM: if (show < 0) @@ -944,5 +1078,4 @@ ada_print_typedef (struct type *type, struct symbol *new_symbol, { type = ada_check_typedef (type); ada_print_type (type, "", stream, 0, 0, &type_print_raw_options); - fprintf_filtered (stream, "\n"); }