|  | /* Support for printing Ada values for GDB, the GNU debugger. | 
|  |  | 
|  | Copyright (C) 1986-2023 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 3 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, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #include "defs.h" | 
|  | #include <ctype.h> | 
|  | #include "gdbtypes.h" | 
|  | #include "expression.h" | 
|  | #include "value.h" | 
|  | #include "valprint.h" | 
|  | #include "language.h" | 
|  | #include "annotate.h" | 
|  | #include "ada-lang.h" | 
|  | #include "target-float.h" | 
|  | #include "cli/cli-style.h" | 
|  | #include "gdbarch.h" | 
|  |  | 
|  | static int print_field_values (struct value *, struct value *, | 
|  | struct ui_file *, int, | 
|  | const struct value_print_options *, | 
|  | int, const struct language_defn *); | 
|  |  | 
|  |  | 
|  |  | 
|  | /* Assuming TYPE is a simple array type, prints its lower bound on STREAM, | 
|  | if non-standard (i.e., other than 1 for numbers, other than lower bound | 
|  | of index type for enumerated type).  Returns 1 if something printed, | 
|  | otherwise 0.  */ | 
|  |  | 
|  | static int | 
|  | print_optional_low_bound (struct ui_file *stream, struct type *type, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | struct type *index_type; | 
|  | LONGEST low_bound; | 
|  | LONGEST high_bound; | 
|  |  | 
|  | if (options->print_array_indexes) | 
|  | return 0; | 
|  |  | 
|  | if (!get_array_bounds (type, &low_bound, &high_bound)) | 
|  | return 0; | 
|  |  | 
|  | /* If this is an empty array, then don't print the lower bound. | 
|  | That would be confusing, because we would print the lower bound, | 
|  | followed by... nothing!  */ | 
|  | if (low_bound > high_bound) | 
|  | return 0; | 
|  |  | 
|  | index_type = type->index_type (); | 
|  |  | 
|  | while (index_type->code () == TYPE_CODE_RANGE) | 
|  | { | 
|  | /* We need to know what the base type is, in order to do the | 
|  | appropriate check below.  Otherwise, if this is a subrange | 
|  | of an enumerated type, where the underlying value of the | 
|  | first element is typically 0, we might test the low bound | 
|  | against the wrong value.  */ | 
|  | index_type = index_type->target_type (); | 
|  | } | 
|  |  | 
|  | /* Don't print the lower bound if it's the default one.  */ | 
|  | switch (index_type->code ()) | 
|  | { | 
|  | case TYPE_CODE_BOOL: | 
|  | case TYPE_CODE_CHAR: | 
|  | if (low_bound == 0) | 
|  | return 0; | 
|  | break; | 
|  | case TYPE_CODE_ENUM: | 
|  | if (low_bound == 0) | 
|  | return 0; | 
|  | low_bound = index_type->field (low_bound).loc_enumval (); | 
|  | break; | 
|  | case TYPE_CODE_UNDEF: | 
|  | index_type = NULL; | 
|  | /* FALL THROUGH */ | 
|  | default: | 
|  | if (low_bound == 1) | 
|  | return 0; | 
|  | break; | 
|  | } | 
|  |  | 
|  | ada_print_scalar (index_type, low_bound, stream); | 
|  | gdb_printf (stream, " => "); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | /*  Version of val_print_array_elements for GNAT-style packed arrays. | 
|  | Prints elements of packed array of type TYPE from VALADDR on | 
|  | STREAM.  Formats according to OPTIONS and separates with commas. | 
|  | RECURSE is the recursion (nesting) level.  TYPE must have been | 
|  | decoded (as by ada_coerce_to_simple_array).  */ | 
|  |  | 
|  | static void | 
|  | val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr, | 
|  | int offset, struct ui_file *stream, | 
|  | int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | unsigned int i; | 
|  | unsigned int things_printed = 0; | 
|  | unsigned len; | 
|  | struct type *elttype, *index_type; | 
|  | unsigned long bitsize = type->field (0).bitsize (); | 
|  | LONGEST low = 0; | 
|  |  | 
|  | scoped_value_mark mark; | 
|  |  | 
|  | elttype = type->target_type (); | 
|  | index_type = type->index_type (); | 
|  |  | 
|  | { | 
|  | LONGEST high; | 
|  |  | 
|  | if (!get_discrete_bounds (index_type, &low, &high)) | 
|  | len = 1; | 
|  | else if (low > high) | 
|  | { | 
|  | /* The array length should normally be HIGH_POS - LOW_POS + 1. | 
|  | But in Ada we allow LOW_POS to be greater than HIGH_POS for | 
|  | empty arrays.  In that situation, the array length is just zero, | 
|  | not negative!  */ | 
|  | len = 0; | 
|  | } | 
|  | else | 
|  | len = high - low + 1; | 
|  | } | 
|  |  | 
|  | if (index_type->code () == TYPE_CODE_RANGE) | 
|  | index_type = index_type->target_type (); | 
|  |  | 
|  | i = 0; | 
|  | annotate_array_section_begin (i, elttype); | 
|  |  | 
|  | while (i < len && things_printed < options->print_max) | 
|  | { | 
|  | /* Both this outer loop and the inner loop that checks for | 
|  | duplicates may allocate many values.  To avoid using too much | 
|  | memory, both spots release values as they work.  */ | 
|  | scoped_value_mark outer_free_values; | 
|  |  | 
|  | struct value *v0, *v1; | 
|  | int i0; | 
|  |  | 
|  | if (i != 0) | 
|  | { | 
|  | if (options->prettyformat_arrays) | 
|  | { | 
|  | gdb_printf (stream, ",\n"); | 
|  | print_spaces (2 + 2 * recurse, stream); | 
|  | } | 
|  | else | 
|  | { | 
|  | gdb_printf (stream, ", "); | 
|  | } | 
|  | } | 
|  | else if (options->prettyformat_arrays) | 
|  | { | 
|  | gdb_printf (stream, "\n"); | 
|  | print_spaces (2 + 2 * recurse, stream); | 
|  | } | 
|  | stream->wrap_here (2 + 2 * recurse); | 
|  | maybe_print_array_index (index_type, i + low, stream, options); | 
|  |  | 
|  | i0 = i; | 
|  | v0 = ada_value_primitive_packed_val (NULL, valaddr + offset, | 
|  | (i0 * bitsize) / HOST_CHAR_BIT, | 
|  | (i0 * bitsize) % HOST_CHAR_BIT, | 
|  | bitsize, elttype); | 
|  | while (1) | 
|  | { | 
|  | /* Make sure to free any values in the inner loop.  */ | 
|  | scoped_value_mark free_values; | 
|  |  | 
|  | i += 1; | 
|  | if (i >= len) | 
|  | break; | 
|  | v1 = ada_value_primitive_packed_val (NULL, valaddr + offset, | 
|  | (i * bitsize) / HOST_CHAR_BIT, | 
|  | (i * bitsize) % HOST_CHAR_BIT, | 
|  | bitsize, elttype); | 
|  | if (check_typedef (v0->type ())->length () | 
|  | != check_typedef (v1->type ())->length ()) | 
|  | break; | 
|  | if (!v0->contents_eq (v0->embedded_offset (), | 
|  | v1, v1->embedded_offset (), | 
|  | check_typedef (v0->type ())->length ())) | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (i - i0 > options->repeat_count_threshold) | 
|  | { | 
|  | struct value_print_options opts = *options; | 
|  |  | 
|  | opts.deref_ref = false; | 
|  | common_val_print (v0, stream, recurse + 1, &opts, current_language); | 
|  | annotate_elt_rep (i - i0); | 
|  | gdb_printf (stream, _(" %p[<repeats %u times>%p]"), | 
|  | metadata_style.style ().ptr (), i - i0, nullptr); | 
|  | annotate_elt_rep_end (); | 
|  |  | 
|  | } | 
|  | else | 
|  | { | 
|  | int j; | 
|  | struct value_print_options opts = *options; | 
|  |  | 
|  | opts.deref_ref = false; | 
|  | for (j = i0; j < i; j += 1) | 
|  | { | 
|  | if (j > i0) | 
|  | { | 
|  | if (options->prettyformat_arrays) | 
|  | { | 
|  | gdb_printf (stream, ",\n"); | 
|  | print_spaces (2 + 2 * recurse, stream); | 
|  | } | 
|  | else | 
|  | { | 
|  | gdb_printf (stream, ", "); | 
|  | } | 
|  | stream->wrap_here (2 + 2 * recurse); | 
|  | maybe_print_array_index (index_type, j + low, | 
|  | stream, options); | 
|  | } | 
|  | common_val_print (v0, stream, recurse + 1, &opts, | 
|  | current_language); | 
|  | annotate_elt (); | 
|  | } | 
|  | } | 
|  | things_printed += i - i0; | 
|  | } | 
|  | annotate_array_section_end (); | 
|  | if (i < len) | 
|  | { | 
|  | gdb_printf (stream, "..."); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Print the character C on STREAM as part of the contents of a literal | 
|  | string whose delimiter is QUOTER.  TYPE_LEN is the length in bytes | 
|  | of the character.  */ | 
|  |  | 
|  | void | 
|  | ada_emit_char (int c, struct type *type, struct ui_file *stream, | 
|  | int quoter, int type_len) | 
|  | { | 
|  | /* If this character fits in the normal ASCII range, and is | 
|  | a printable character, then print the character as if it was | 
|  | an ASCII character, even if this is a wide character. | 
|  | The UCHAR_MAX check is necessary because the isascii function | 
|  | requires that its argument have a value of an unsigned char, | 
|  | or EOF (EOF is obviously not printable).  */ | 
|  | if (c <= UCHAR_MAX && isascii (c) && isprint (c)) | 
|  | { | 
|  | if (c == quoter && c == '"') | 
|  | gdb_printf (stream, "\"\""); | 
|  | else | 
|  | gdb_printf (stream, "%c", c); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Follow GNAT's lead here and only use 6 digits for | 
|  | wide_wide_character.  */ | 
|  | gdb_printf (stream, "[\"%0*x\"]", std::min (6, type_len * 2), c); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Character #I of STRING, given that TYPE_LEN is the size in bytes | 
|  | of a character.  */ | 
|  |  | 
|  | static int | 
|  | char_at (const gdb_byte *string, int i, int type_len, | 
|  | enum bfd_endian byte_order) | 
|  | { | 
|  | if (type_len == 1) | 
|  | return string[i]; | 
|  | else | 
|  | return (int) extract_unsigned_integer (string + type_len * i, | 
|  | type_len, byte_order); | 
|  | } | 
|  |  | 
|  | /* Print a floating-point value of type TYPE, pointed to in GDB by | 
|  | VALADDR, on STREAM.  Use Ada formatting conventions: there must be | 
|  | a decimal point, and at least one digit before and after the | 
|  | point.  We use the GNAT format for NaNs and infinities.  */ | 
|  |  | 
|  | static void | 
|  | ada_print_floating (const gdb_byte *valaddr, struct type *type, | 
|  | struct ui_file *stream) | 
|  | { | 
|  | string_file tmp_stream; | 
|  |  | 
|  | print_floating (valaddr, type, &tmp_stream); | 
|  |  | 
|  | std::string s = tmp_stream.release (); | 
|  | size_t skip_count = 0; | 
|  |  | 
|  | /* Don't try to modify a result representing an error.  */ | 
|  | if (s[0] == '<') | 
|  | { | 
|  | gdb_puts (s.c_str (), stream); | 
|  | return; | 
|  | } | 
|  |  | 
|  | /* Modify for Ada rules.  */ | 
|  |  | 
|  | size_t pos = s.find ("inf"); | 
|  | if (pos == std::string::npos) | 
|  | pos = s.find ("Inf"); | 
|  | if (pos == std::string::npos) | 
|  | pos = s.find ("INF"); | 
|  | if (pos != std::string::npos) | 
|  | s.replace (pos, 3, "Inf"); | 
|  |  | 
|  | if (pos == std::string::npos) | 
|  | { | 
|  | pos = s.find ("nan"); | 
|  | if (pos == std::string::npos) | 
|  | pos = s.find ("NaN"); | 
|  | if (pos == std::string::npos) | 
|  | pos = s.find ("Nan"); | 
|  | if (pos != std::string::npos) | 
|  | { | 
|  | s[pos] = s[pos + 2] = 'N'; | 
|  | if (s[0] == '-') | 
|  | skip_count = 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (pos == std::string::npos | 
|  | && s.find ('.') == std::string::npos) | 
|  | { | 
|  | pos = s.find ('e'); | 
|  | if (pos == std::string::npos) | 
|  | gdb_printf (stream, "%s.0", s.c_str ()); | 
|  | else | 
|  | gdb_printf (stream, "%.*s.0%s", (int) pos, s.c_str (), &s[pos]); | 
|  | } | 
|  | else | 
|  | gdb_printf (stream, "%s", &s[skip_count]); | 
|  | } | 
|  |  | 
|  | void | 
|  | ada_printchar (int c, struct type *type, struct ui_file *stream) | 
|  | { | 
|  | gdb_puts ("'", stream); | 
|  | ada_emit_char (c, type, stream, '\'', type->length ()); | 
|  | gdb_puts ("'", stream); | 
|  | } | 
|  |  | 
|  | /* [From print_type_scalar in typeprint.c].   Print VAL on STREAM in a | 
|  | form appropriate for TYPE, if non-NULL.  If TYPE is NULL, print VAL | 
|  | like a default signed integer.  */ | 
|  |  | 
|  | void | 
|  | ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream) | 
|  | { | 
|  | if (!type) | 
|  | { | 
|  | print_longest (stream, 'd', 0, val); | 
|  | return; | 
|  | } | 
|  |  | 
|  | type = ada_check_typedef (type); | 
|  |  | 
|  | switch (type->code ()) | 
|  | { | 
|  |  | 
|  | case TYPE_CODE_ENUM: | 
|  | { | 
|  | gdb::optional<LONGEST> posn = discrete_position (type, val); | 
|  | if (posn.has_value ()) | 
|  | fputs_styled (ada_enum_name (type->field (*posn).name ()), | 
|  | variable_name_style.style (), stream); | 
|  | else | 
|  | print_longest (stream, 'd', 0, val); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_INT: | 
|  | print_longest (stream, type->is_unsigned () ? 'u' : 'd', 0, val); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_CHAR: | 
|  | current_language->printchar (val, type, stream); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_BOOL: | 
|  | gdb_printf (stream, val ? "true" : "false"); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_RANGE: | 
|  | ada_print_scalar (type->target_type (), val, stream); | 
|  | return; | 
|  |  | 
|  | case TYPE_CODE_UNDEF: | 
|  | case TYPE_CODE_PTR: | 
|  | case TYPE_CODE_ARRAY: | 
|  | case TYPE_CODE_STRUCT: | 
|  | case TYPE_CODE_UNION: | 
|  | case TYPE_CODE_FUNC: | 
|  | case TYPE_CODE_FLT: | 
|  | case TYPE_CODE_VOID: | 
|  | case TYPE_CODE_SET: | 
|  | case TYPE_CODE_STRING: | 
|  | case TYPE_CODE_ERROR: | 
|  | case TYPE_CODE_MEMBERPTR: | 
|  | case TYPE_CODE_METHODPTR: | 
|  | case TYPE_CODE_METHOD: | 
|  | case TYPE_CODE_REF: | 
|  | warning (_("internal error: unhandled type in ada_print_scalar")); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | error (_("Invalid type code in symbol table.")); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Print the character string STRING, printing at most LENGTH characters. | 
|  | Printing stops early if the number hits print_max; repeat counts | 
|  | are printed as appropriate.  Print ellipses at the end if we | 
|  | had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. | 
|  | TYPE_LEN is the length (1 or 2) of the character type.  */ | 
|  |  | 
|  | static void | 
|  | printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, | 
|  | unsigned int length, int force_ellipses, int type_len, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | enum bfd_endian byte_order = type_byte_order (elttype); | 
|  | unsigned int i; | 
|  | unsigned int things_printed = 0; | 
|  | int in_quotes = 0; | 
|  | int need_comma = 0; | 
|  |  | 
|  | if (length == 0) | 
|  | { | 
|  | gdb_puts ("\"\"", stream); | 
|  | return; | 
|  | } | 
|  |  | 
|  | unsigned int print_max_chars = get_print_max_chars (options); | 
|  | for (i = 0; i < length && things_printed < print_max_chars; i += 1) | 
|  | { | 
|  | /* Position of the character we are examining | 
|  | to see whether it is repeated.  */ | 
|  | unsigned int rep1; | 
|  | /* Number of repetitions we have detected so far.  */ | 
|  | unsigned int reps; | 
|  |  | 
|  | QUIT; | 
|  |  | 
|  | if (need_comma) | 
|  | { | 
|  | gdb_puts (", ", stream); | 
|  | need_comma = 0; | 
|  | } | 
|  |  | 
|  | rep1 = i + 1; | 
|  | reps = 1; | 
|  | while (rep1 < length | 
|  | && char_at (string, rep1, type_len, byte_order) | 
|  | == char_at (string, i, type_len, byte_order)) | 
|  | { | 
|  | rep1 += 1; | 
|  | reps += 1; | 
|  | } | 
|  |  | 
|  | if (reps > options->repeat_count_threshold) | 
|  | { | 
|  | if (in_quotes) | 
|  | { | 
|  | gdb_puts ("\", ", stream); | 
|  | in_quotes = 0; | 
|  | } | 
|  | gdb_puts ("'", stream); | 
|  | ada_emit_char (char_at (string, i, type_len, byte_order), | 
|  | elttype, stream, '\'', type_len); | 
|  | gdb_puts ("'", stream); | 
|  | gdb_printf (stream, _(" %p[<repeats %u times>%p]"), | 
|  | metadata_style.style ().ptr (), reps, nullptr); | 
|  | i = rep1 - 1; | 
|  | things_printed += options->repeat_count_threshold; | 
|  | need_comma = 1; | 
|  | } | 
|  | else | 
|  | { | 
|  | if (!in_quotes) | 
|  | { | 
|  | gdb_puts ("\"", stream); | 
|  | in_quotes = 1; | 
|  | } | 
|  | ada_emit_char (char_at (string, i, type_len, byte_order), | 
|  | elttype, stream, '"', type_len); | 
|  | things_printed += 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Terminate the quotes if necessary.  */ | 
|  | if (in_quotes) | 
|  | gdb_puts ("\"", stream); | 
|  |  | 
|  | if (force_ellipses || i < length) | 
|  | gdb_puts ("...", stream); | 
|  | } | 
|  |  | 
|  | void | 
|  | ada_printstr (struct ui_file *stream, struct type *type, | 
|  | const gdb_byte *string, unsigned int length, | 
|  | const char *encoding, int force_ellipses, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | printstr (stream, type, string, length, force_ellipses, type->length (), | 
|  | options); | 
|  | } | 
|  |  | 
|  | static int | 
|  | print_variant_part (struct value *value, int field_num, | 
|  | struct value *outer_value, | 
|  | struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options, | 
|  | int comma_needed, | 
|  | const struct language_defn *language) | 
|  | { | 
|  | struct type *type = value->type (); | 
|  | struct type *var_type = type->field (field_num).type (); | 
|  | int which = ada_which_variant_applies (var_type, outer_value); | 
|  |  | 
|  | if (which < 0) | 
|  | return 0; | 
|  |  | 
|  | struct value *variant_field = value_field (value, field_num); | 
|  | struct value *active_component = value_field (variant_field, which); | 
|  | return print_field_values (active_component, outer_value, stream, recurse, | 
|  | options, comma_needed, language); | 
|  | } | 
|  |  | 
|  | /* Print out fields of VALUE. | 
|  |  | 
|  | STREAM, RECURSE, and OPTIONS have the same meanings as in | 
|  | ada_print_value and ada_value_print. | 
|  |  | 
|  | OUTER_VALUE gives the enclosing record (used to get discriminant | 
|  | values when printing variant parts). | 
|  |  | 
|  | COMMA_NEEDED is 1 if fields have been printed at the current recursion | 
|  | level, so that a comma is needed before any field printed by this | 
|  | call. | 
|  |  | 
|  | Returns 1 if COMMA_NEEDED or any fields were printed.  */ | 
|  |  | 
|  | static int | 
|  | print_field_values (struct value *value, struct value *outer_value, | 
|  | struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options, | 
|  | int comma_needed, | 
|  | const struct language_defn *language) | 
|  | { | 
|  | int i, len; | 
|  |  | 
|  | struct type *type = value->type (); | 
|  | len = type->num_fields (); | 
|  |  | 
|  | for (i = 0; i < len; i += 1) | 
|  | { | 
|  | if (ada_is_ignored_field (type, i)) | 
|  | continue; | 
|  |  | 
|  | if (ada_is_wrapper_field (type, i)) | 
|  | { | 
|  | struct value *field_val = ada_value_primitive_field (value, 0, | 
|  | i, type); | 
|  | comma_needed = | 
|  | print_field_values (field_val, field_val, | 
|  | stream, recurse, options, | 
|  | comma_needed, language); | 
|  | continue; | 
|  | } | 
|  | else if (ada_is_variant_part (type, i)) | 
|  | { | 
|  | comma_needed = | 
|  | print_variant_part (value, i, outer_value, stream, recurse, | 
|  | options, comma_needed, language); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (comma_needed) | 
|  | gdb_printf (stream, ", "); | 
|  | comma_needed = 1; | 
|  |  | 
|  | if (options->prettyformat) | 
|  | { | 
|  | gdb_printf (stream, "\n"); | 
|  | print_spaces (2 + 2 * recurse, stream); | 
|  | } | 
|  | else | 
|  | { | 
|  | stream->wrap_here (2 + 2 * recurse); | 
|  | } | 
|  |  | 
|  | annotate_field_begin (type->field (i).type ()); | 
|  | gdb_printf (stream, "%.*s", | 
|  | ada_name_prefix_len (type->field (i).name ()), | 
|  | type->field (i).name ()); | 
|  | annotate_field_name_end (); | 
|  | gdb_puts (" => ", stream); | 
|  | annotate_field_value (); | 
|  |  | 
|  | if (type->field (i).is_packed ()) | 
|  | { | 
|  | /* Bitfields require special handling, especially due to byte | 
|  | order problems.  */ | 
|  | if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i)) | 
|  | { | 
|  | fputs_styled (_("<optimized out or zero length>"), | 
|  | metadata_style.style (), stream); | 
|  | } | 
|  | else | 
|  | { | 
|  | struct value *v; | 
|  | int bit_pos = type->field (i).loc_bitpos (); | 
|  | int bit_size = type->field (i).bitsize (); | 
|  | struct value_print_options opts; | 
|  |  | 
|  | v = ada_value_primitive_packed_val | 
|  | (value, nullptr, | 
|  | bit_pos / HOST_CHAR_BIT, | 
|  | bit_pos % HOST_CHAR_BIT, | 
|  | bit_size, type->field (i).type ()); | 
|  | opts = *options; | 
|  | opts.deref_ref = false; | 
|  | common_val_print (v, stream, recurse + 1, &opts, language); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | struct value_print_options opts = *options; | 
|  |  | 
|  | opts.deref_ref = false; | 
|  |  | 
|  | struct value *v = value_field (value, i); | 
|  | common_val_print (v, stream, recurse + 1, &opts, language); | 
|  | } | 
|  | annotate_field_end (); | 
|  | } | 
|  |  | 
|  | return comma_needed; | 
|  | } | 
|  |  | 
|  | /* Implement Ada val_print'ing for the case where TYPE is | 
|  | a TYPE_CODE_ARRAY of characters.  */ | 
|  |  | 
|  | static void | 
|  | ada_val_print_string (struct type *type, const gdb_byte *valaddr, | 
|  | int offset_aligned, | 
|  | struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | enum bfd_endian byte_order = type_byte_order (type); | 
|  | struct type *elttype = type->target_type (); | 
|  | unsigned int eltlen; | 
|  | unsigned int len; | 
|  |  | 
|  | /* We know that ELTTYPE cannot possibly be null, because we assume | 
|  | that we're called only when TYPE is a string-like type. | 
|  | Similarly, the size of ELTTYPE should also be non-null, since | 
|  | it's a character-like type.  */ | 
|  | gdb_assert (elttype != NULL); | 
|  | gdb_assert (elttype->length () != 0); | 
|  |  | 
|  | eltlen = elttype->length (); | 
|  | len = type->length () / eltlen; | 
|  |  | 
|  | /* If requested, look for the first null char and only print | 
|  | elements up to it.  */ | 
|  | if (options->stop_print_at_null) | 
|  | { | 
|  | unsigned int print_max_chars = get_print_max_chars (options); | 
|  | int temp_len; | 
|  |  | 
|  | /* Look for a NULL char.  */ | 
|  | for (temp_len = 0; | 
|  | (temp_len < len | 
|  | && temp_len < print_max_chars | 
|  | && char_at (valaddr + offset_aligned, | 
|  | temp_len, eltlen, byte_order) != 0); | 
|  | temp_len += 1); | 
|  | len = temp_len; | 
|  | } | 
|  |  | 
|  | printstr (stream, elttype, valaddr + offset_aligned, len, 0, | 
|  | eltlen, options); | 
|  | } | 
|  |  | 
|  | /* Implement Ada value_print'ing for the case where TYPE is a | 
|  | TYPE_CODE_PTR.  */ | 
|  |  | 
|  | static void | 
|  | ada_value_print_ptr (struct value *val, | 
|  | struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | if (!options->format | 
|  | && val->type ()->target_type ()->code () == TYPE_CODE_INT | 
|  | && val->type ()->target_type ()->length () == 0) | 
|  | { | 
|  | gdb_puts ("null", stream); | 
|  | return; | 
|  | } | 
|  |  | 
|  | common_val_print (val, stream, recurse, options, language_def (language_c)); | 
|  |  | 
|  | struct type *type = ada_check_typedef (val->type ()); | 
|  | if (ada_is_tag_type (type)) | 
|  | { | 
|  | gdb::unique_xmalloc_ptr<char> name = ada_tag_name (val); | 
|  |  | 
|  | if (name != NULL) | 
|  | gdb_printf (stream, " (%s)", name.get ()); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Implement Ada val_print'ing for the case where TYPE is | 
|  | a TYPE_CODE_INT or TYPE_CODE_RANGE.  */ | 
|  |  | 
|  | static void | 
|  | ada_value_print_num (struct value *val, struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | struct type *type = ada_check_typedef (val->type ()); | 
|  | const gdb_byte *valaddr = val->contents_for_printing ().data (); | 
|  |  | 
|  | if (type->code () == TYPE_CODE_RANGE | 
|  | && (type->target_type ()->code () == TYPE_CODE_ENUM | 
|  | || type->target_type ()->code () == TYPE_CODE_BOOL | 
|  | || type->target_type ()->code () == TYPE_CODE_CHAR)) | 
|  | { | 
|  | /* For enum-valued ranges, we want to recurse, because we'll end | 
|  | up printing the constant's name rather than its numeric | 
|  | value.  Character and fixed-point types are also printed | 
|  | differently, so recurse for those as well.  */ | 
|  | struct type *target_type = type->target_type (); | 
|  | val = value_cast (target_type, val); | 
|  | common_val_print (val, stream, recurse + 1, options, | 
|  | language_def (language_ada)); | 
|  | return; | 
|  | } | 
|  | else | 
|  | { | 
|  | int format = (options->format ? options->format | 
|  | : options->output_format); | 
|  |  | 
|  | if (format) | 
|  | { | 
|  | struct value_print_options opts = *options; | 
|  |  | 
|  | opts.format = format; | 
|  | value_print_scalar_formatted (val, &opts, 0, stream); | 
|  | } | 
|  | else if (ada_is_system_address_type (type)) | 
|  | { | 
|  | /* FIXME: We want to print System.Address variables using | 
|  | the same format as for any access type.  But for some | 
|  | reason GNAT encodes the System.Address type as an int, | 
|  | so we have to work-around this deficiency by handling | 
|  | System.Address values as a special case.  */ | 
|  |  | 
|  | struct gdbarch *gdbarch = type->arch (); | 
|  | struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; | 
|  | CORE_ADDR addr = extract_typed_address (valaddr, ptr_type); | 
|  |  | 
|  | gdb_printf (stream, "("); | 
|  | type_print (type, "", stream, -1); | 
|  | gdb_printf (stream, ") "); | 
|  | gdb_puts (paddress (gdbarch, addr), stream); | 
|  | } | 
|  | else | 
|  | { | 
|  | value_print_scalar_formatted (val, options, 0, stream); | 
|  | if (ada_is_character_type (type)) | 
|  | { | 
|  | LONGEST c; | 
|  |  | 
|  | gdb_puts (" ", stream); | 
|  | c = unpack_long (type, valaddr); | 
|  | ada_printchar (c, type, stream); | 
|  | } | 
|  | } | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Implement Ada val_print'ing for the case where TYPE is | 
|  | a TYPE_CODE_ENUM.  */ | 
|  |  | 
|  | static void | 
|  | ada_val_print_enum (struct value *value, struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | LONGEST val; | 
|  |  | 
|  | if (options->format) | 
|  | { | 
|  | value_print_scalar_formatted (value, options, 0, stream); | 
|  | return; | 
|  | } | 
|  |  | 
|  | struct type *type = ada_check_typedef (value->type ()); | 
|  | const gdb_byte *valaddr = value->contents_for_printing ().data (); | 
|  | int offset_aligned = ada_aligned_value_addr (type, valaddr) - valaddr; | 
|  |  | 
|  | val = unpack_long (type, valaddr + offset_aligned); | 
|  | gdb::optional<LONGEST> posn = discrete_position (type, val); | 
|  | if (posn.has_value ()) | 
|  | { | 
|  | const char *name = ada_enum_name (type->field (*posn).name ()); | 
|  |  | 
|  | if (name[0] == '\'') | 
|  | gdb_printf (stream, "%ld %ps", (long) val, | 
|  | styled_string (variable_name_style.style (), | 
|  | name)); | 
|  | else | 
|  | fputs_styled (name, variable_name_style.style (), stream); | 
|  | } | 
|  | else | 
|  | print_longest (stream, 'd', 0, val); | 
|  | } | 
|  |  | 
|  | /* Implement Ada val_print'ing for the case where the type is | 
|  | TYPE_CODE_STRUCT or TYPE_CODE_UNION.  */ | 
|  |  | 
|  | static void | 
|  | ada_val_print_struct_union (struct value *value, | 
|  | struct ui_file *stream, | 
|  | int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | gdb_printf (stream, "("); | 
|  |  | 
|  | if (print_field_values (value, value, stream, recurse, options, | 
|  | 0, language_def (language_ada)) != 0 | 
|  | && options->prettyformat) | 
|  | { | 
|  | gdb_printf (stream, "\n"); | 
|  | print_spaces (2 * recurse, stream); | 
|  | } | 
|  |  | 
|  | gdb_printf (stream, ")"); | 
|  | } | 
|  |  | 
|  | /* Implement Ada value_print'ing for the case where TYPE is a | 
|  | TYPE_CODE_ARRAY.  */ | 
|  |  | 
|  | static void | 
|  | ada_value_print_array (struct value *val, struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | struct type *type = ada_check_typedef (val->type ()); | 
|  |  | 
|  | /* For an array of characters, print with string syntax.  */ | 
|  | if (ada_is_string_type (type) | 
|  | && (options->format == 0 || options->format == 's')) | 
|  | { | 
|  | const gdb_byte *valaddr = val->contents_for_printing ().data (); | 
|  | int offset_aligned = ada_aligned_value_addr (type, valaddr) - valaddr; | 
|  |  | 
|  | ada_val_print_string (type, valaddr, offset_aligned, stream, recurse, | 
|  | options); | 
|  | return; | 
|  | } | 
|  |  | 
|  | gdb_printf (stream, "("); | 
|  | print_optional_low_bound (stream, type, options); | 
|  |  | 
|  | if (val->entirely_optimized_out ()) | 
|  | val_print_optimized_out (val, stream); | 
|  | else if (type->field (0).bitsize () > 0) | 
|  | { | 
|  | const gdb_byte *valaddr = val->contents_for_printing ().data (); | 
|  | int offset_aligned = ada_aligned_value_addr (type, valaddr) - valaddr; | 
|  | val_print_packed_array_elements (type, valaddr, offset_aligned, | 
|  | stream, recurse, options); | 
|  | } | 
|  | else | 
|  | value_print_array_elements (val, stream, recurse, options, 0); | 
|  | gdb_printf (stream, ")"); | 
|  | } | 
|  |  | 
|  | /* Implement Ada val_print'ing for the case where TYPE is | 
|  | a TYPE_CODE_REF.  */ | 
|  |  | 
|  | static void | 
|  | ada_val_print_ref (struct type *type, const gdb_byte *valaddr, | 
|  | int offset, int offset_aligned, CORE_ADDR address, | 
|  | struct ui_file *stream, int recurse, | 
|  | struct value *original_value, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | /* For references, the debugger is expected to print the value as | 
|  | an address if DEREF_REF is null.  But printing an address in place | 
|  | of the object value would be confusing to an Ada programmer. | 
|  | So, for Ada values, we print the actual dereferenced value | 
|  | regardless.  */ | 
|  | struct type *elttype = check_typedef (type->target_type ()); | 
|  | struct value *deref_val; | 
|  | CORE_ADDR deref_val_int; | 
|  |  | 
|  | if (elttype->code () == TYPE_CODE_UNDEF) | 
|  | { | 
|  | fputs_styled ("<ref to undefined type>", metadata_style.style (), | 
|  | stream); | 
|  | return; | 
|  | } | 
|  |  | 
|  | deref_val = coerce_ref_if_computed (original_value); | 
|  | if (deref_val) | 
|  | { | 
|  | if (ada_is_tagged_type (deref_val->type (), 1)) | 
|  | deref_val = ada_tag_value_at_base_address (deref_val); | 
|  |  | 
|  | common_val_print (deref_val, stream, recurse + 1, options, | 
|  | language_def (language_ada)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | deref_val_int = unpack_pointer (type, valaddr + offset_aligned); | 
|  | if (deref_val_int == 0) | 
|  | { | 
|  | gdb_puts ("(null)", stream); | 
|  | return; | 
|  | } | 
|  |  | 
|  | deref_val | 
|  | = ada_value_ind (value_from_pointer (lookup_pointer_type (elttype), | 
|  | deref_val_int)); | 
|  | if (ada_is_tagged_type (deref_val->type (), 1)) | 
|  | deref_val = ada_tag_value_at_base_address (deref_val); | 
|  |  | 
|  | if (deref_val->lazy ()) | 
|  | deref_val->fetch_lazy (); | 
|  |  | 
|  | common_val_print (deref_val, stream, recurse + 1, | 
|  | options, language_def (language_ada)); | 
|  | } | 
|  |  | 
|  | /* See the comment on ada_value_print.  This function differs in that | 
|  | it does not catch evaluation errors (leaving that to its | 
|  | caller).  */ | 
|  |  | 
|  | void | 
|  | ada_value_print_inner (struct value *val, struct ui_file *stream, int recurse, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | struct type *type = ada_check_typedef (val->type ()); | 
|  |  | 
|  | if (ada_is_array_descriptor_type (type) | 
|  | || (ada_is_constrained_packed_array_type (type) | 
|  | && type->code () != TYPE_CODE_PTR)) | 
|  | { | 
|  | /* If this is a reference, coerce it now.  This helps taking | 
|  | care of the case where ADDRESS is meaningless because | 
|  | original_value was not an lval.  */ | 
|  | val = coerce_ref (val); | 
|  | val = ada_get_decoded_value (val); | 
|  | if (val == nullptr) | 
|  | { | 
|  | gdb_assert (type->code () == TYPE_CODE_TYPEDEF); | 
|  | gdb_printf (stream, "0x0"); | 
|  | return; | 
|  | } | 
|  | } | 
|  | else | 
|  | val = ada_to_fixed_value (val); | 
|  |  | 
|  | type = val->type (); | 
|  | struct type *saved_type = type; | 
|  |  | 
|  | const gdb_byte *valaddr = val->contents_for_printing ().data (); | 
|  | CORE_ADDR address = val->address (); | 
|  | gdb::array_view<const gdb_byte> view | 
|  | = gdb::make_array_view (valaddr, type->length ()); | 
|  | type = ada_check_typedef (resolve_dynamic_type (type, view, address)); | 
|  | if (type != saved_type) | 
|  | { | 
|  | val = val->copy (); | 
|  | val->deprecated_set_type (type); | 
|  | } | 
|  |  | 
|  | if (is_fixed_point_type (type)) | 
|  | type = type->fixed_point_type_base_type (); | 
|  |  | 
|  | switch (type->code ()) | 
|  | { | 
|  | default: | 
|  | common_val_print (val, stream, recurse, options, | 
|  | language_def (language_c)); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_PTR: | 
|  | ada_value_print_ptr (val, stream, recurse, options); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_INT: | 
|  | case TYPE_CODE_RANGE: | 
|  | ada_value_print_num (val, stream, recurse, options); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_ENUM: | 
|  | ada_val_print_enum (val, stream, recurse, options); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_FLT: | 
|  | if (options->format) | 
|  | { | 
|  | common_val_print (val, stream, recurse, options, | 
|  | language_def (language_c)); | 
|  | break; | 
|  | } | 
|  |  | 
|  | ada_print_floating (valaddr, type, stream); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_UNION: | 
|  | case TYPE_CODE_STRUCT: | 
|  | ada_val_print_struct_union (val, stream, recurse, options); | 
|  | break; | 
|  |  | 
|  | case TYPE_CODE_ARRAY: | 
|  | ada_value_print_array (val, stream, recurse, options); | 
|  | return; | 
|  |  | 
|  | case TYPE_CODE_REF: | 
|  | ada_val_print_ref (type, valaddr, 0, 0, | 
|  | address, stream, recurse, val, | 
|  | options); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | ada_value_print (struct value *val0, struct ui_file *stream, | 
|  | const struct value_print_options *options) | 
|  | { | 
|  | struct value *val = ada_to_fixed_value (val0); | 
|  | struct type *type = ada_check_typedef (val->type ()); | 
|  | struct value_print_options opts; | 
|  |  | 
|  | /* If it is a pointer, indicate what it points to; but not for | 
|  | "void *" pointers.  */ | 
|  | if (type->code () == TYPE_CODE_PTR | 
|  | && !(type->target_type ()->code () == TYPE_CODE_INT | 
|  | && type->target_type ()->length () == 0)) | 
|  | { | 
|  | /* Hack:  don't print (char *) for char strings.  Their | 
|  | type is indicated by the quoted string anyway.  */ | 
|  | if (type->target_type ()->length () != sizeof (char) | 
|  | || type->target_type ()->code () != TYPE_CODE_INT | 
|  | || type->target_type ()->is_unsigned ()) | 
|  | { | 
|  | gdb_printf (stream, "("); | 
|  | type_print (type, "", stream, -1); | 
|  | gdb_printf (stream, ") "); | 
|  | } | 
|  | } | 
|  | else if (ada_is_array_descriptor_type (type)) | 
|  | { | 
|  | /* We do not print the type description unless TYPE is an array | 
|  | access type (this is encoded by the compiler as a typedef to | 
|  | a fat pointer - hence the check against TYPE_CODE_TYPEDEF).  */ | 
|  | if (type->code () == TYPE_CODE_TYPEDEF) | 
|  | { | 
|  | gdb_printf (stream, "("); | 
|  | type_print (type, "", stream, -1); | 
|  | gdb_printf (stream, ") "); | 
|  | } | 
|  | } | 
|  |  | 
|  | opts = *options; | 
|  | opts.deref_ref = true; | 
|  | common_val_print (val, stream, 0, &opts, current_language); | 
|  | } |