X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalprint.c;h=3104e0b45e10955a8d503ad89581b25c6ebb9aab;hb=9a897d43f034544cd09292d0fb6fded7eb64ae8d;hp=fbecd512d76297c402725b332f8859fb5dc6594c;hpb=fe43fede4726122efbee9d52b9e68b47be97757f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valprint.c b/gdb/valprint.c index fbecd512d7..3104e0b45e 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1,6 +1,6 @@ /* Print values for GDB, the GNU debugger. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -27,14 +27,15 @@ #include "language.h" #include "annotate.h" #include "valprint.h" -#include "floatformat.h" -#include "doublest.h" -#include "dfp.h" +#include "target-float.h" #include "extension.h" #include "ada-lang.h" #include "gdb_obstack.h" #include "charset.h" +#include "typeprint.h" #include +#include +#include "common/byte-vector.h" /* Maximum number of wchars returned from wchar_iterate. */ #define MAX_WCHARS 4 @@ -69,9 +70,6 @@ struct converted_character int repeat_count; }; -typedef struct converted_character converted_character_d; -DEF_VEC_O (converted_character_d); - /* Command lists for set/show print raw. */ struct cmd_list_element *setprintrawlist; struct cmd_list_element *showprintrawlist; @@ -81,23 +79,13 @@ struct cmd_list_element *showprintrawlist; static int partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int *errptr); -static void show_print (char *, int); - -static void set_print (char *, int); - -static void set_radix (char *, int); - -static void show_radix (char *, int); - -static void set_input_radix (char *, int, struct cmd_list_element *); - static void set_input_radix_1 (int, unsigned); -static void set_output_radix (char *, int, struct cmd_list_element *); - static void set_output_radix_1 (int, unsigned); -void _initialize_valprint (void); +static void val_print_type_code_flags (struct type *type, + const gdb_byte *valaddr, + struct ui_file *stream); #define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */ @@ -275,7 +263,7 @@ int val_print_scalar_type_p (struct type *type) { type = check_typedef (type); - while (TYPE_CODE (type) == TYPE_CODE_REF) + while (TYPE_IS_REFERENCE (type)) { type = TYPE_TARGET_TYPE (type); type = check_typedef (type); @@ -298,11 +286,23 @@ val_print_scalar_type_p (struct type *type) int valprint_check_validity (struct ui_file *stream, struct type *type, - int embedded_offset, + LONGEST embedded_offset, const struct value *val) { type = check_typedef (type); + if (type_not_associated (type)) + { + val_print_not_associated (stream); + return 0; + } + + if (type_not_allocated (type)) + { + val_print_not_allocated (stream); + return 0; + } + if (TYPE_CODE (type) != TYPE_CODE_UNION && TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_ARRAY) @@ -318,8 +318,22 @@ valprint_check_validity (struct ui_file *stream, if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset, TARGET_CHAR_BIT * TYPE_LENGTH (type))) { - fputs_filtered (_(""), stream); - return 0; + const int is_ref = TYPE_CODE (type) == TYPE_CODE_REF; + int ref_is_addressable = 0; + + if (is_ref) + { + const struct value *deref_val = coerce_ref_if_computed (val); + + if (deref_val != NULL) + ref_is_addressable = value_lval_const (deref_val) == lval_memory; + } + + if (!is_ref || !ref_is_addressable) + fputs_filtered (_(""), stream); + + /* C++ references should be valid even if they're synthetic. */ + return is_ref; } if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) @@ -389,11 +403,13 @@ print_unpacked_pointer (struct type *type, struct type *elttype, /* generic_val_print helper for TYPE_CODE_ARRAY. */ static void -generic_val_print_array (struct type *type, const gdb_byte *valaddr, - int embedded_offset, CORE_ADDR address, - struct ui_file *stream, int recurse, - const struct value *original_value, - const struct value_print_options *options) +generic_val_print_array (struct type *type, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int recurse, + struct value *original_value, + const struct value_print_options *options, + const struct + generic_val_print_decorations *decorations) { struct type *unresolved_elttype = TYPE_TARGET_TYPE (type); struct type *elttype = check_typedef (unresolved_elttype); @@ -410,11 +426,11 @@ generic_val_print_array (struct type *type, const gdb_byte *valaddr, print_spaces_filtered (2 + 2 * recurse, stream); } - fprintf_filtered (stream, "{"); - val_print_array_elements (type, valaddr, embedded_offset, + fputs_filtered (decorations->array_start, stream); + val_print_array_elements (type, embedded_offset, address, stream, recurse, original_value, options, 0); - fprintf_filtered (stream, "}"); + fputs_filtered (decorations->array_end, stream); } else { @@ -428,21 +444,26 @@ generic_val_print_array (struct type *type, const gdb_byte *valaddr, /* generic_val_print helper for TYPE_CODE_PTR. */ static void -generic_val_print_ptr (struct type *type, const gdb_byte *valaddr, +generic_val_print_ptr (struct type *type, int embedded_offset, struct ui_file *stream, - const struct value *original_value, + struct value *original_value, const struct value_print_options *options) { + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + if (options->format && options->format != 's') { - val_print_scalar_formatted (type, valaddr, embedded_offset, + val_print_scalar_formatted (type, embedded_offset, original_value, options, 0, stream); } else { struct type *unresolved_elttype = TYPE_TARGET_TYPE(type); struct type *elttype = check_typedef (unresolved_elttype); - CORE_ADDR addr = unpack_pointer (type, valaddr + embedded_offset); + const gdb_byte *valaddr = value_contents_for_printing (original_value); + CORE_ADDR addr = unpack_pointer (type, + valaddr + embedded_offset * unit_size); print_unpacked_pointer (type, elttype, addr, stream, options); } @@ -452,63 +473,399 @@ generic_val_print_ptr (struct type *type, const gdb_byte *valaddr, /* generic_val_print helper for TYPE_CODE_MEMBERPTR. */ static void -generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr, +generic_val_print_memberptr (struct type *type, int embedded_offset, struct ui_file *stream, - const struct value *original_value, + struct value *original_value, const struct value_print_options *options) { - val_print_scalar_formatted (type, valaddr, embedded_offset, + val_print_scalar_formatted (type, embedded_offset, original_value, options, 0, stream); } -/* generic_val_print helper for TYPE_CODE_REF. */ +/* Print '@' followed by the address contained in ADDRESS_BUFFER. */ static void -generic_val_print_ref (struct type *type, const gdb_byte *valaddr, +print_ref_address (struct type *type, const gdb_byte *address_buffer, + int embedded_offset, struct ui_file *stream) +{ + struct gdbarch *gdbarch = get_type_arch (type); + + if (address_buffer != NULL) + { + CORE_ADDR address + = extract_typed_address (address_buffer + embedded_offset, type); + + fprintf_filtered (stream, "@"); + fputs_filtered (paddress (gdbarch, address), stream); + } + /* Else: we have a non-addressable value, such as a DW_AT_const_value. */ +} + +/* If VAL is addressable, return the value contents buffer of a value that + represents a pointer to VAL. Otherwise return NULL. */ + +static const gdb_byte * +get_value_addr_contents (struct value *deref_val) +{ + gdb_assert (deref_val != NULL); + + if (value_lval_const (deref_val) == lval_memory) + return value_contents_for_printing_const (value_addr (deref_val)); + else + { + /* We have a non-addressable value, such as a DW_AT_const_value. */ + return NULL; + } +} + +/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF. */ + +static void +generic_val_print_ref (struct type *type, int embedded_offset, struct ui_file *stream, int recurse, - const struct value *original_value, + struct value *original_value, const struct value_print_options *options) { - struct gdbarch *gdbarch = get_type_arch (type); struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type)); + struct value *deref_val = NULL; + const int value_is_synthetic + = value_bits_synthetic_pointer (original_value, + TARGET_CHAR_BIT * embedded_offset, + TARGET_CHAR_BIT * TYPE_LENGTH (type)); + const int must_coerce_ref = ((options->addressprint && value_is_synthetic) + || options->deref_ref); + const int type_is_defined = TYPE_CODE (elttype) != TYPE_CODE_UNDEF; + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + if (must_coerce_ref && type_is_defined) + { + deref_val = coerce_ref_if_computed (original_value); + + if (deref_val != NULL) + { + /* More complicated computed references are not supported. */ + gdb_assert (embedded_offset == 0); + } + else + deref_val = value_at (TYPE_TARGET_TYPE (type), + unpack_pointer (type, valaddr + embedded_offset)); + } + /* Else, original_value isn't a synthetic reference or we don't have to print + the reference's contents. + + Notice that for references to TYPE_CODE_STRUCT, 'set print object on' will + cause original_value to be a not_lval instead of an lval_computed, + which will make value_bits_synthetic_pointer return false. + This happens because if options->objectprint is true, c_value_print will + overwrite original_value's contents with the result of coercing + the reference through value_addr, and then set its type back to + TYPE_CODE_REF. In that case we don't have to coerce the reference again; + we can simply treat it as non-synthetic and move on. */ if (options->addressprint) { - CORE_ADDR addr - = extract_typed_address (valaddr + embedded_offset, type); + const gdb_byte *address = (value_is_synthetic && type_is_defined + ? get_value_addr_contents (deref_val) + : valaddr); + + print_ref_address (type, address, embedded_offset, stream); - fprintf_filtered (stream, "@"); - fputs_filtered (paddress (gdbarch, addr), stream); if (options->deref_ref) fputs_filtered (": ", stream); } - /* De-reference the reference. */ + if (options->deref_ref) { - if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) + if (type_is_defined) + common_val_print (deref_val, stream, recurse, options, + current_language); + else + fputs_filtered ("???", stream); + } +} + +/* Helper function for generic_val_print_enum. + This is also used to print enums in TYPE_CODE_FLAGS values. */ + +static void +generic_val_print_enum_1 (struct type *type, LONGEST val, + struct ui_file *stream) +{ + unsigned int i; + unsigned int len; + + len = TYPE_NFIELDS (type); + for (i = 0; i < len; i++) + { + QUIT; + if (val == TYPE_FIELD_ENUMVAL (type, i)) { - struct value *deref_val; + break; + } + } + if (i < len) + { + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + } + else if (TYPE_FLAG_ENUM (type)) + { + int first = 1; + + /* We have a "flag" enum, so we try to decompose it into + pieces as appropriate. A flag enum has disjoint + constants by definition. */ + fputs_filtered ("(", stream); + for (i = 0; i < len; ++i) + { + QUIT; - deref_val = coerce_ref_if_computed (original_value); - if (deref_val != NULL) + if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0) { - /* More complicated computed references are not supported. */ - gdb_assert (embedded_offset == 0); + if (!first) + fputs_filtered (" | ", stream); + first = 0; + + val &= ~TYPE_FIELD_ENUMVAL (type, i); + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); } - else - deref_val = value_at (TYPE_TARGET_TYPE (type), - unpack_pointer (type, - (valaddr - + embedded_offset))); + } - common_val_print (deref_val, stream, recurse, options, - current_language); + if (first || val != 0) + { + if (!first) + fputs_filtered (" | ", stream); + fputs_filtered ("unknown: ", stream); + print_longest (stream, 'd', 0, val); } + + fputs_filtered (")", stream); + } + else + print_longest (stream, 'd', 0, val); +} + +/* generic_val_print helper for TYPE_CODE_ENUM. */ + +static void +generic_val_print_enum (struct type *type, + int embedded_offset, struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options) +{ + LONGEST val; + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format) + { + val_print_scalar_formatted (type, embedded_offset, + original_value, options, 0, stream); + } + else + { + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + val = unpack_long (type, valaddr + embedded_offset * unit_size); + + generic_val_print_enum_1 (type, val, stream); + } +} + +/* generic_val_print helper for TYPE_CODE_FLAGS. */ + +static void +generic_val_print_flags (struct type *type, + int embedded_offset, struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options) + +{ + if (options->format) + val_print_scalar_formatted (type, embedded_offset, original_value, + options, 0, stream); + else + { + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + val_print_type_code_flags (type, valaddr + embedded_offset, stream); + } +} + +/* generic_val_print helper for TYPE_CODE_FUNC and TYPE_CODE_METHOD. */ + +static void +generic_val_print_func (struct type *type, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + + if (options->format) + { + val_print_scalar_formatted (type, embedded_offset, + original_value, options, 0, stream); + } + else + { + /* FIXME, we should consider, at least for ANSI C language, + eliminating the distinction made between FUNCs and POINTERs + to FUNCs. */ + fprintf_filtered (stream, "{"); + type_print (type, "", stream, -1); + fprintf_filtered (stream, "} "); + /* Try to print what function it points to, and its address. */ + print_address_demangle (options, gdbarch, address, stream, demangle); + } +} + +/* generic_val_print helper for TYPE_CODE_BOOL. */ + +static void +generic_val_print_bool (struct type *type, + int embedded_offset, struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options, + const struct generic_val_print_decorations *decorations) +{ + LONGEST val; + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, embedded_offset, + original_value, &opts, 0, stream); + } + else + { + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + val = unpack_long (type, valaddr + embedded_offset * unit_size); + if (val == 0) + fputs_filtered (decorations->false_name, stream); + else if (val == 1) + fputs_filtered (decorations->true_name, stream); else - fputs_filtered ("???", stream); + print_longest (stream, 'd', 0, val); } } +/* generic_val_print helper for TYPE_CODE_INT. */ + +static void +generic_val_print_int (struct type *type, + int embedded_offset, struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options) +{ + struct value_print_options opts = *options; + + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, embedded_offset, + original_value, &opts, 0, stream); +} + +/* generic_val_print helper for TYPE_CODE_CHAR. */ + +static void +generic_val_print_char (struct type *type, struct type *unresolved_type, + int embedded_offset, + struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options) +{ + LONGEST val; + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, embedded_offset, + original_value, &opts, 0, stream); + } + else + { + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + val = unpack_long (type, valaddr + embedded_offset * unit_size); + if (TYPE_UNSIGNED (type)) + fprintf_filtered (stream, "%u", (unsigned int) val); + else + fprintf_filtered (stream, "%d", (int) val); + fputs_filtered (" ", stream); + LA_PRINT_CHAR (val, unresolved_type, stream); + } +} + +/* generic_val_print helper for TYPE_CODE_FLT and TYPE_CODE_DECFLOAT. */ + +static void +generic_val_print_float (struct type *type, + int embedded_offset, struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + + if (options->format) + { + val_print_scalar_formatted (type, embedded_offset, + original_value, options, 0, stream); + } + else + { + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + print_floating (valaddr + embedded_offset * unit_size, type, stream); + } +} + +/* generic_val_print helper for TYPE_CODE_COMPLEX. */ + +static void +generic_val_print_complex (struct type *type, + int embedded_offset, struct ui_file *stream, + struct value *original_value, + const struct value_print_options *options, + const struct generic_val_print_decorations + *decorations) +{ + struct gdbarch *gdbarch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (gdbarch); + const gdb_byte *valaddr = value_contents_for_printing (original_value); + + fprintf_filtered (stream, "%s", decorations->complex_prefix); + if (options->format) + val_print_scalar_formatted (TYPE_TARGET_TYPE (type), + embedded_offset, original_value, options, 0, + stream); + else + print_floating (valaddr + embedded_offset * unit_size, + TYPE_TARGET_TYPE (type), stream); + fprintf_filtered (stream, "%s", decorations->complex_infix); + if (options->format) + val_print_scalar_formatted (TYPE_TARGET_TYPE (type), + embedded_offset + + type_length_units (TYPE_TARGET_TYPE (type)), + original_value, options, 0, stream); + else + print_floating (valaddr + embedded_offset * unit_size + + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), + TYPE_TARGET_TYPE (type), stream); + fprintf_filtered (stream, "%s", decorations->complex_suffix); +} + /* A generic val_print that is suitable for use by language implementations of the la_val_print method. This function can handle most type codes, though not all, notably exception @@ -521,146 +878,58 @@ generic_val_print_ref (struct type *type, const gdb_byte *valaddr, output in some small, language-specific ways. */ void -generic_val_print (struct type *type, const gdb_byte *valaddr, +generic_val_print (struct type *type, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, - const struct value *original_value, + struct value *original_value, const struct value_print_options *options, const struct generic_val_print_decorations *decorations) { - struct gdbarch *gdbarch = get_type_arch (type); - unsigned int i = 0; /* Number of characters printed. */ - unsigned len; struct type *unresolved_type = type; - LONGEST val; type = check_typedef (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: - generic_val_print_array (type, valaddr, embedded_offset, address, stream, - recurse, original_value, options); + generic_val_print_array (type, embedded_offset, address, stream, + recurse, original_value, options, decorations); break; case TYPE_CODE_MEMBERPTR: - generic_val_print_memberptr (type, valaddr, embedded_offset, stream, + generic_val_print_memberptr (type, embedded_offset, stream, original_value, options); break; case TYPE_CODE_PTR: - generic_val_print_ptr (type, valaddr, embedded_offset, stream, + generic_val_print_ptr (type, embedded_offset, stream, original_value, options); break; case TYPE_CODE_REF: - generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse, + case TYPE_CODE_RVALUE_REF: + generic_val_print_ref (type, embedded_offset, stream, recurse, original_value, options); break; case TYPE_CODE_ENUM: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr + embedded_offset); - for (i = 0; i < len; i++) - { - QUIT; - if (val == TYPE_FIELD_ENUMVAL (type, i)) - { - break; - } - } - if (i < len) - { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - else if (TYPE_FLAG_ENUM (type)) - { - int first = 1; - - /* We have a "flag" enum, so we try to decompose it into - pieces as appropriate. A flag enum has disjoint - constants by definition. */ - fputs_filtered ("(", stream); - for (i = 0; i < len; ++i) - { - QUIT; - - if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0) - { - if (!first) - fputs_filtered (" | ", stream); - first = 0; - - val &= ~TYPE_FIELD_ENUMVAL (type, i); - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - } - - if (first || val != 0) - { - if (!first) - fputs_filtered (" | ", stream); - fputs_filtered ("unknown: ", stream); - print_longest (stream, 'd', 0, val); - } - - fputs_filtered (")", stream); - } - else - print_longest (stream, 'd', 0, val); + generic_val_print_enum (type, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_FLAGS: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - val_print_type_code_flags (type, valaddr + embedded_offset, - stream); + generic_val_print_flags (type, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - /* FIXME, we should consider, at least for ANSI C language, - eliminating the distinction made between FUNCs and POINTERs - to FUNCs. */ - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - /* Try to print what function it points to, and its address. */ - print_address_demangle (options, gdbarch, address, stream, demangle); + generic_val_print_func (type, embedded_offset, address, stream, + original_value, options); break; case TYPE_CODE_BOOL: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (val == 0) - fputs_filtered (decorations->false_name, stream); - else if (val == 1) - fputs_filtered (decorations->true_name, stream); - else - print_longest (stream, 'd', 0, val); - } + generic_val_print_bool (type, embedded_offset, stream, + original_value, options, decorations); break; case TYPE_CODE_RANGE: @@ -675,60 +944,19 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, /* FALLTHROUGH */ case TYPE_CODE_INT: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - val_print_type_code_int (type, valaddr + embedded_offset, stream); + generic_val_print_int (type, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_CHAR: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (TYPE_UNSIGNED (type)) - fprintf_filtered (stream, "%u", (unsigned int) val); - else - fprintf_filtered (stream, "%d", (int) val); - fputs_filtered (" ", stream); - LA_PRINT_CHAR (val, unresolved_type, stream); - } + generic_val_print_char (type, unresolved_type, embedded_offset, + stream, original_value, options); break; case TYPE_CODE_FLT: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - } - else - { - print_floating (valaddr + embedded_offset, type, stream); - } - break; - case TYPE_CODE_DECFLOAT: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_decimal_floating (valaddr + embedded_offset, - type, stream); + generic_val_print_float (type, embedded_offset, stream, + original_value, options); break; case TYPE_CODE_VOID: @@ -740,37 +968,15 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, break; case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which - don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a - "struct foo *bar" and no complete type for struct foo in that - file. */ + /* This happens (without TYPE_STUB set) on systems which don't use + dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" + and no complete type for struct foo in that file. */ fprintf_filtered (stream, _("")); break; case TYPE_CODE_COMPLEX: - fprintf_filtered (stream, "%s", decorations->complex_prefix); - if (options->format) - val_print_scalar_formatted (TYPE_TARGET_TYPE (type), - valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_floating (valaddr + embedded_offset, - TYPE_TARGET_TYPE (type), - stream); - fprintf_filtered (stream, "%s", decorations->complex_infix); - if (options->format) - val_print_scalar_formatted (TYPE_TARGET_TYPE (type), - valaddr, - embedded_offset - + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), - original_value, - options, 0, stream); - else - print_floating (valaddr + embedded_offset - + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), - TYPE_TARGET_TYPE (type), - stream); - fprintf_filtered (stream, "%s", decorations->complex_suffix); + generic_val_print_complex (type, embedded_offset, stream, + original_value, options, decorations); break; case TYPE_CODE_UNION: @@ -784,15 +990,14 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, } /* Print using the given LANGUAGE the data of type TYPE located at - VALADDR + EMBEDDED_OFFSET (within GDB), which came from the - inferior at address ADDRESS + EMBEDDED_OFFSET, onto stdio stream - STREAM according to OPTIONS. VAL is the whole object that came - from ADDRESS. VALADDR must point to the head of VAL's contents - buffer. + VAL's contents buffer + EMBEDDED_OFFSET (within GDB), which came + from the inferior at address ADDRESS + EMBEDDED_OFFSET, onto + stdio stream STREAM according to OPTIONS. VAL is the whole object + that came from ADDRESS. The language printers will pass down an adjusted EMBEDDED_OFFSET to further helper subroutines as subfields of TYPE are printed. In - such cases, VALADDR is passed down unadjusted, as well as VAL, so + such cases, VAL is passed down unadjusted, so that VAL can be queried for metadata about the contents data being printed, using EMBEDDED_OFFSET as an offset into VAL's contents buffer. For example: "has this field been optimized out", or "I'm @@ -804,9 +1009,9 @@ generic_val_print (struct type *type, const gdb_byte *valaddr, RECURSE. */ void -val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, +val_print (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, - const struct value *val, + struct value *val, const struct value_print_options *options, const struct language_defn *language) { @@ -836,7 +1041,7 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, if (!options->raw) { - ret = apply_ext_lang_val_pretty_printer (type, valaddr, embedded_offset, + ret = apply_ext_lang_val_pretty_printer (type, embedded_offset, address, stream, recurse, val, options, language); if (ret) @@ -853,7 +1058,7 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, TRY { - language->la_val_print (type, valaddr, embedded_offset, address, + language->la_val_print (type, embedded_offset, address, stream, recurse, val, &local_opts); } @@ -903,6 +1108,18 @@ value_check_printable (struct value *val, struct ui_file *stream, return 0; } + if (type_not_associated (value_type (val))) + { + val_print_not_associated (stream); + return 0; + } + + if (type_not_allocated (value_type (val))) + { + val_print_not_allocated (stream); + return 0; + } + return 1; } @@ -927,7 +1144,10 @@ common_val_print (struct value *val, struct ui_file *stream, int recurse, get a fixed representation of our value. */ val = ada_to_fixed_value (val); - val_print (value_type (val), value_contents_for_printing (val), + if (value_lazy (val)) + value_fetch_lazy (val); + + val_print (value_type (val), value_embedded_offset (val), value_address (val), stream, recurse, val, options, language); @@ -947,7 +1167,6 @@ value_print (struct value *val, struct ui_file *stream, { int r = apply_ext_lang_val_pretty_printer (value_type (val), - value_contents_for_printing (val), value_embedded_offset (val), value_address (val), stream, 0, @@ -960,63 +1179,51 @@ value_print (struct value *val, struct ui_file *stream, LA_VALUE_PRINT (val, stream, options); } -/* Called by various _val_print routines to print - TYPE_CODE_INT's. TYPE is the type. VALADDR is the address of the - value. STREAM is where to print the value. */ - -void -val_print_type_code_int (struct type *type, const gdb_byte *valaddr, - struct ui_file *stream) -{ - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - - if (TYPE_LENGTH (type) > sizeof (LONGEST)) - { - LONGEST val; - - if (TYPE_UNSIGNED (type) - && extract_long_unsigned_integer (valaddr, TYPE_LENGTH (type), - byte_order, &val)) - { - print_longest (stream, 'u', 0, val); - } - else - { - /* Signed, or we couldn't turn an unsigned value into a - LONGEST. For signed values, one could assume two's - complement (a reasonable assumption, I think) and do - better than this. */ - print_hex_chars (stream, (unsigned char *) valaddr, - TYPE_LENGTH (type), byte_order); - } - } - else - { - print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, - unpack_long (type, valaddr)); - } -} - -void +static void val_print_type_code_flags (struct type *type, const gdb_byte *valaddr, struct ui_file *stream) { ULONGEST val = unpack_long (type, valaddr); - int bitpos, nfields = TYPE_NFIELDS (type); + int field, nfields = TYPE_NFIELDS (type); + struct gdbarch *gdbarch = get_type_arch (type); + struct type *bool_type = builtin_type (gdbarch)->builtin_bool; - fputs_filtered ("[ ", stream); - for (bitpos = 0; bitpos < nfields; bitpos++) + fputs_filtered ("[", stream); + for (field = 0; field < nfields; field++) { - if (TYPE_FIELD_BITPOS (type, bitpos) != -1 - && (val & ((ULONGEST)1 << bitpos))) + if (TYPE_FIELD_NAME (type, field)[0] != '\0') { - if (TYPE_FIELD_NAME (type, bitpos)) - fprintf_filtered (stream, "%s ", TYPE_FIELD_NAME (type, bitpos)); + struct type *field_type = TYPE_FIELD_TYPE (type, field); + + if (field_type == bool_type + /* We require boolean types here to be one bit wide. This is a + problematic place to notify the user of an internal error + though. Instead just fall through and print the field as an + int. */ + && TYPE_FIELD_BITSIZE (type, field) == 1) + { + if (val & ((ULONGEST)1 << TYPE_FIELD_BITPOS (type, field))) + fprintf_filtered (stream, " %s", + TYPE_FIELD_NAME (type, field)); + } else - fprintf_filtered (stream, "#%d ", bitpos); + { + unsigned field_len = TYPE_FIELD_BITSIZE (type, field); + ULONGEST field_val + = val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1); + + if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT) + field_val &= ((ULONGEST) 1 << field_len) - 1; + fprintf_filtered (stream, " %s=", + TYPE_FIELD_NAME (type, field)); + if (TYPE_CODE (field_type) == TYPE_CODE_ENUM) + generic_val_print_enum_1 (field_type, field_val, stream); + else + print_longest (stream, 'd', 0, field_val); + } } } - fputs_filtered ("]", stream); + fputs_filtered (" ]", stream); } /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR, @@ -1028,14 +1235,16 @@ val_print_type_code_flags (struct type *type, const gdb_byte *valaddr, void val_print_scalar_formatted (struct type *type, - const gdb_byte *valaddr, int embedded_offset, - const struct value *val, + LONGEST embedded_offset, + struct value *val, const struct value_print_options *options, int size, struct ui_file *stream) { + struct gdbarch *arch = get_type_arch (type); + int unit_size = gdbarch_addressable_memory_unit_size (arch); + gdb_assert (val != NULL); - gdb_assert (valaddr == value_contents_for_printing_const (val)); /* If we get here with a string format, try again without it. Go all the way back to the language printers, which may call us @@ -1045,11 +1254,16 @@ val_print_scalar_formatted (struct type *type, struct value_print_options opts = *options; opts.format = 0; opts.deref_ref = 0; - val_print (type, valaddr, embedded_offset, 0, stream, 0, val, &opts, + val_print (type, embedded_offset, 0, stream, 0, val, &opts, current_language); return; } + /* value_contents_for_printing fetches all VAL's contents. They are + needed to check whether VAL is optimized-out or unavailable + below. */ + const gdb_byte *valaddr = value_contents_for_printing (val); + /* A scalar object that does not have all bits available can't be printed, because all bits contribute to its representation. */ if (value_bits_any_optimized_out (val, @@ -1059,7 +1273,7 @@ val_print_scalar_formatted (struct type *type, else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) val_print_unavailable (stream); else - print_scalar_formatted (valaddr + embedded_offset, type, + print_scalar_formatted (valaddr + embedded_offset * unit_size, type, options, size, stream); } @@ -1137,113 +1351,31 @@ longest_to_int (LONGEST arg) return (rtnval); } -/* Print a floating point value of type TYPE (not always a - TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. */ +/* Print a floating point value of floating-point type TYPE, + pointed to in GDB by VALADDR, on STREAM. */ void print_floating (const gdb_byte *valaddr, struct type *type, struct ui_file *stream) { - DOUBLEST doub; - int inv; - const struct floatformat *fmt = NULL; - unsigned len = TYPE_LENGTH (type); - enum float_kind kind; - - /* If it is a floating-point, check for obvious problems. */ - if (TYPE_CODE (type) == TYPE_CODE_FLT) - fmt = floatformat_from_type (type); - if (fmt != NULL) - { - kind = floatformat_classify (fmt, valaddr); - if (kind == float_nan) - { - if (floatformat_is_negative (fmt, valaddr)) - fprintf_filtered (stream, "-"); - fprintf_filtered (stream, "nan("); - fputs_filtered ("0x", stream); - fputs_filtered (floatformat_mantissa (fmt, valaddr), stream); - fprintf_filtered (stream, ")"); - return; - } - else if (kind == float_infinite) - { - if (floatformat_is_negative (fmt, valaddr)) - fputs_filtered ("-", stream); - fputs_filtered ("inf", stream); - return; - } - } - - /* NOTE: cagney/2002-01-15: The TYPE passed into print_floating() - isn't necessarily a TYPE_CODE_FLT. Consequently, unpack_double - needs to be used as that takes care of any necessary type - conversions. Such conversions are of course direct to DOUBLEST - and disregard any possible target floating point limitations. - For instance, a u64 would be converted and displayed exactly on a - host with 80 bit DOUBLEST but with loss of information on a host - with 64 bit DOUBLEST. */ - - doub = unpack_double (type, valaddr, &inv); - if (inv) - { - fprintf_filtered (stream, ""); - return; - } - - /* FIXME: kettenis/2001-01-20: The following code makes too much - assumptions about the host and target floating point format. */ - - /* NOTE: cagney/2002-02-03: Since the TYPE of what was passed in may - not necessarily be a TYPE_CODE_FLT, the below ignores that and - instead uses the type's length to determine the precision of the - floating-point value being printed. */ - - if (len < sizeof (double)) - fprintf_filtered (stream, "%.9g", (double) doub); - else if (len == sizeof (double)) - fprintf_filtered (stream, "%.17g", (double) doub); - else -#ifdef PRINTF_HAS_LONG_DOUBLE - fprintf_filtered (stream, "%.35Lg", doub); -#else - /* This at least wins with values that are representable as - doubles. */ - fprintf_filtered (stream, "%.17g", (double) doub); -#endif -} - -void -print_decimal_floating (const gdb_byte *valaddr, struct type *type, - struct ui_file *stream) -{ - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - char decstr[MAX_DECIMAL_STRING]; - unsigned len = TYPE_LENGTH (type); - - decimal_to_string (valaddr, len, byte_order, decstr); - fputs_filtered (decstr, stream); - return; + std::string str = target_float_to_string (valaddr, type); + fputs_filtered (str.c_str (), stream); } void print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order) + unsigned len, enum bfd_endian byte_order, bool zero_pad) { - -#define BITS_IN_BYTES 8 - const gdb_byte *p; unsigned int i; int b; + bool seen_a_one = false; /* Declared "int" so it will be signed. This ensures that right shift will shift in zeros. */ const int mask = 0x080; - /* FIXME: We should be not printing leading zeroes in most cases. */ - if (byte_order == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -1253,14 +1385,17 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, /* Every byte has 8 binary characters; peel off and print from the MSB end. */ - for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++) + for (i = 0; i < (HOST_CHAR_BIT * sizeof (*p)); i++) { if (*p & (mask >> i)) - b = 1; + b = '1'; else - b = 0; + b = '0'; - fprintf_filtered (stream, "%1d", b); + if (zero_pad || seen_a_one || b == '1') + fputc_filtered (b, stream); + if (b == '1') + seen_a_one = true; } } } @@ -1270,17 +1405,37 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, p >= valaddr; p--) { - for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++) + for (i = 0; i < (HOST_CHAR_BIT * sizeof (*p)); i++) { if (*p & (mask >> i)) - b = 1; + b = '1'; else - b = 0; + b = '0'; - fprintf_filtered (stream, "%1d", b); + if (zero_pad || seen_a_one || b == '1') + fputc_filtered (b, stream); + if (b == '1') + seen_a_one = true; } } } + + /* When not zero-padding, ensure that something is printed when the + input is 0. */ + if (!zero_pad && !seen_a_one) + fputc_filtered ('0', stream); +} + +/* A helper for print_octal_chars that emits a single octal digit, + optionally suppressing it if is zero and updating SEEN_A_ONE. */ + +static void +emit_octal_digit (struct ui_file *stream, bool *seen_a_one, int digit) +{ + if (*seen_a_one || digit != 0) + fprintf_filtered (stream, "%o", digit); + if (digit != 0) + *seen_a_one = true; } /* VALADDR points to an integer of LEN bytes. @@ -1294,9 +1449,6 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, unsigned char octa1, octa2, octa3, carry; int cycle; - /* FIXME: We should be not printing leading zeroes in most cases. */ - - /* Octal is 3 bits, which doesn't fit. Yuk. So we have to track * the extra bits, which cycle every three bytes: * @@ -1314,23 +1466,30 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, */ #define BITS_IN_OCTAL 3 #define HIGH_ZERO 0340 -#define LOW_ZERO 0016 +#define LOW_ZERO 0034 #define CARRY_ZERO 0003 + static_assert (HIGH_ZERO + LOW_ZERO + CARRY_ZERO == 0xff, + "cycle zero constants are wrong"); #define HIGH_ONE 0200 #define MID_ONE 0160 #define LOW_ONE 0016 #define CARRY_ONE 0001 + static_assert (HIGH_ONE + MID_ONE + LOW_ONE + CARRY_ONE == 0xff, + "cycle one constants are wrong"); #define HIGH_TWO 0300 #define MID_TWO 0070 #define LOW_TWO 0007 + static_assert (HIGH_TWO + MID_TWO + LOW_TWO == 0xff, + "cycle two constants are wrong"); /* For 32 we start in cycle 2, with two bits and one bit carry; for 64 in cycle in cycle 1, with one bit and a two bit carry. */ - cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL; + cycle = (len * HOST_CHAR_BIT) % BITS_IN_OCTAL; carry = 0; fputs_filtered ("0", stream); + bool seen_a_one = false; if (byte_order == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -1345,8 +1504,8 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa1 = (HIGH_ZERO & *p) >> 5; octa2 = (LOW_ZERO & *p) >> 2; carry = (CARRY_ZERO & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); break; case 1: @@ -1356,9 +1515,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_ONE & *p) >> 4; octa3 = (LOW_ONE & *p) >> 1; carry = (CARRY_ONE & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; case 2: @@ -1368,9 +1527,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_TWO & *p) >> 3; octa3 = (LOW_TWO & *p); carry = 0; - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; default: @@ -1395,8 +1554,8 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa1 = (HIGH_ZERO & *p) >> 5; octa2 = (LOW_ZERO & *p) >> 2; carry = (CARRY_ZERO & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); break; case 1: @@ -1406,9 +1565,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_ONE & *p) >> 4; octa3 = (LOW_ONE & *p) >> 1; carry = (CARRY_ONE & *p); - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; case 2: @@ -1418,9 +1577,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, octa2 = (MID_TWO & *p) >> 3; octa3 = (LOW_TWO & *p); carry = 0; - fprintf_filtered (stream, "%o", octa1); - fprintf_filtered (stream, "%o", octa2); - fprintf_filtered (stream, "%o", octa3); + emit_octal_digit (stream, &seen_a_one, octa1); + emit_octal_digit (stream, &seen_a_one, octa2); + emit_octal_digit (stream, &seen_a_one, octa3); break; default: @@ -1434,12 +1593,58 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, } +/* Possibly negate the integer represented by BYTES. It contains LEN + bytes in the specified byte order. If the integer is negative, + copy it into OUT_VEC, negate it, and return true. Otherwise, do + nothing and return false. */ + +static bool +maybe_negate_by_bytes (const gdb_byte *bytes, unsigned len, + enum bfd_endian byte_order, + gdb::byte_vector *out_vec) +{ + gdb_byte sign_byte; + if (byte_order == BFD_ENDIAN_BIG) + sign_byte = bytes[0]; + else + sign_byte = bytes[len - 1]; + if ((sign_byte & 0x80) == 0) + return false; + + out_vec->resize (len); + + /* Compute -x == 1 + ~x. */ + if (byte_order == BFD_ENDIAN_LITTLE) + { + unsigned carry = 1; + for (unsigned i = 0; i < len; ++i) + { + unsigned tem = (0xff & ~bytes[i]) + carry; + (*out_vec)[i] = tem & 0xff; + carry = tem / 256; + } + } + else + { + unsigned carry = 1; + for (unsigned i = len; i > 0; --i) + { + unsigned tem = (0xff & ~bytes[i - 1]) + carry; + (*out_vec)[i - 1] = tem & 0xff; + carry = tem / 256; + } + } + + return true; +} + /* VALADDR points to an integer of LEN bytes. Print it in decimal on stream or format it in buf. */ void print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order) + unsigned len, bool is_signed, + enum bfd_endian byte_order) { #define TEN 10 #define CARRY_OUT( x ) ((x) / TEN) /* extend char to int */ @@ -1449,23 +1654,25 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, #define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4) const gdb_byte *p; - unsigned char *digits; int carry; int decimal_len; int i, j, decimal_digits; int dummy; int flip; + gdb::byte_vector negated_bytes; + if (is_signed + && maybe_negate_by_bytes (valaddr, len, byte_order, &negated_bytes)) + { + fputs_filtered ("-", stream); + valaddr = negated_bytes.data (); + } + /* Base-ten number is less than twice as many digits as the base 16 number, which is 2 digits per byte. */ decimal_len = len * 2 * 2; - digits = xmalloc (decimal_len); - - for (i = 0; i < decimal_len; i++) - { - digits[i] = 0; - } + std::vector digits (decimal_len, 0); /* Ok, we have an unknown number of bytes of data to be printed in * decimal. @@ -1559,40 +1766,73 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, /* Ok, now "digits" is the decimal representation, with the "decimal_digits" actual digits. Print! */ - for (i = decimal_digits - 1; i >= 0; i--) + for (i = decimal_digits - 1; i > 0 && digits[i] == 0; --i) + ; + + for (; i >= 0; i--) { fprintf_filtered (stream, "%1d", digits[i]); } - xfree (digits); } /* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */ void print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order) + unsigned len, enum bfd_endian byte_order, + bool zero_pad) { const gdb_byte *p; - /* FIXME: We should be not printing leading zeroes in most cases. */ - fputs_filtered ("0x", stream); if (byte_order == BFD_ENDIAN_BIG) { - for (p = valaddr; + p = valaddr; + + if (!zero_pad) + { + /* Strip leading 0 bytes, but be sure to leave at least a + single byte at the end. */ + for (; p < valaddr + len - 1 && !*p; ++p) + ; + } + + const gdb_byte *first = p; + for (; p < valaddr + len; p++) { - fprintf_filtered (stream, "%02x", *p); + /* When not zero-padding, use a different format for the + very first byte printed. */ + if (!zero_pad && p == first) + fprintf_filtered (stream, "%x", *p); + else + fprintf_filtered (stream, "%02x", *p); } } else { - for (p = valaddr + len - 1; + p = valaddr + len - 1; + + if (!zero_pad) + { + /* Strip leading 0 bytes, but be sure to leave at least a + single byte at the end. */ + for (; p >= valaddr + 1 && !*p; --p) + ; + } + + const gdb_byte *first = p; + for (; p >= valaddr; p--) { - fprintf_filtered (stream, "%02x", *p); + /* When not zero-padding, use a different format for the + very first byte printed. */ + if (!zero_pad && p == first) + fprintf_filtered (stream, "%x", *p); + else + fprintf_filtered (stream, "%02x", *p); } } } @@ -1687,10 +1927,10 @@ maybe_print_array_index (struct type *index_type, LONGEST index, void val_print_array_elements (struct type *type, - const gdb_byte *valaddr, int embedded_offset, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, - const struct value *val, + struct value *val, const struct value_print_options *options, unsigned int i) { @@ -1707,7 +1947,7 @@ val_print_array_elements (struct type *type, LONGEST low_pos, high_pos; elttype = TYPE_TARGET_TYPE (type); - eltlen = TYPE_LENGTH (check_typedef (elttype)); + eltlen = type_length_units (check_typedef (elttype)); index_type = TYPE_INDEX_TYPE (type); if (get_array_bounds (type, &low_bound, &high_bound)) @@ -1788,7 +2028,7 @@ val_print_array_elements (struct type *type, if (reps > options->repeat_count_threshold) { - val_print (elttype, valaddr, embedded_offset + i * eltlen, + val_print (elttype, embedded_offset + i * eltlen, address, stream, recurse + 1, val, options, current_language); annotate_elt_rep (reps); @@ -1800,7 +2040,7 @@ val_print_array_elements (struct type *type, } else { - val_print (elttype, valaddr, embedded_offset + i * eltlen, + val_print (elttype, embedded_offset + i * eltlen, address, stream, recurse + 1, val, options, current_language); annotate_elt (); @@ -1901,7 +2141,7 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, { /* We want fetchlimit chars, so we might as well read them all in one operation. */ - unsigned int fetchlen = min (len, fetchlimit); + unsigned int fetchlen = std::min ((unsigned) len, fetchlimit); *buffer = (gdb_byte *) xmalloc (fetchlen * width); bufptr = *buffer; @@ -1925,12 +2165,12 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, So we choose the minimum of 8 and fetchlimit. We used to use 200 instead of 8 but 200 is way too big for remote debugging over a serial line. */ - chunksize = min (8, fetchlimit); + chunksize = std::min (8u, fetchlimit); do { QUIT; - nfetch = min (chunksize, fetchlimit - bufsize); + nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize); if (*buffer == NULL) *buffer = (gdb_byte *) xmalloc (nfetch * width); @@ -1976,7 +2216,7 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, else { /* Length of string is really 0! */ /* We always allocate *buffer. */ - *buffer = bufptr = xmalloc (1); + *buffer = bufptr = (gdb_byte *) xmalloc (1); errcode = 0; } @@ -2123,22 +2363,16 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - struct obstack wchar_buf, output; - struct cleanup *cleanups; gdb_byte *buf; - struct wchar_iterator *iter; int need_escape = 0; - buf = alloca (TYPE_LENGTH (type)); + buf = (gdb_byte *) alloca (TYPE_LENGTH (type)); pack_long (buf, type, c); - iter = make_wchar_iterator (buf, TYPE_LENGTH (type), - encoding, TYPE_LENGTH (type)); - cleanups = make_cleanup_wchar_iterator (iter); + wchar_iterator iter (buf, TYPE_LENGTH (type), encoding, TYPE_LENGTH (type)); /* This holds the printable form of the wchar_t data. */ - obstack_init (&wchar_buf); - make_cleanup_obstack_free (&wchar_buf); + auto_obstack wchar_buf; while (1) { @@ -2149,7 +2383,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, int print_escape = 1; enum wchar_iterate_result result; - num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); + num_chars = iter.iterate (&result, &chars, &buf, &buflen); if (num_chars < 0) break; if (num_chars > 0) @@ -2185,8 +2419,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, } /* The output in the host encoding. */ - obstack_init (&output); - make_cleanup_obstack_free (&output); + auto_obstack output; convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (), (gdb_byte *) obstack_base (&wchar_buf), @@ -2194,36 +2427,34 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, sizeof (gdb_wchar_t), &output, translit_char); obstack_1grow (&output, '\0'); - fputs_filtered (obstack_base (&output), stream); - - do_cleanups (cleanups); + fputs_filtered ((const char *) obstack_base (&output), stream); } /* Return the repeat count of the next character/byte in ITER, storing the result in VEC. */ static int -count_next_character (struct wchar_iterator *iter, - VEC (converted_character_d) **vec) +count_next_character (wchar_iterator *iter, + std::vector *vec) { struct converted_character *current; - if (VEC_empty (converted_character_d, *vec)) + if (vec->empty ()) { struct converted_character tmp; gdb_wchar_t *chars; tmp.num_chars - = wchar_iterate (iter, &tmp.result, &chars, &tmp.buf, &tmp.buflen); + = iter->iterate (&tmp.result, &chars, &tmp.buf, &tmp.buflen); if (tmp.num_chars > 0) { gdb_assert (tmp.num_chars < MAX_WCHARS); memcpy (tmp.chars, chars, tmp.num_chars * sizeof (gdb_wchar_t)); } - VEC_safe_push (converted_character_d, *vec, &tmp); + vec->push_back (tmp); } - current = VEC_last (converted_character_d, *vec); + current = &vec->back (); /* Count repeated characters or bytes. */ current->repeat_count = 1; @@ -2243,8 +2474,7 @@ count_next_character (struct wchar_iterator *iter, while (1) { /* Get the next character. */ - d.num_chars - = wchar_iterate (iter, &d.result, &chars, &d.buf, &d.buflen); + d.num_chars = iter->iterate (&d.result, &chars, &d.buf, &d.buflen); /* If a character was successfully converted, save the character into the converted character. */ @@ -2278,7 +2508,7 @@ count_next_character (struct wchar_iterator *iter, /* Push this next converted character onto the result vector. */ repeat = current->repeat_count; - VEC_safe_push (converted_character_d, *vec, &d); + vec->push_back (d); return repeat; } } @@ -2290,13 +2520,13 @@ count_next_character (struct wchar_iterator *iter, static void print_converted_chars_to_obstack (struct obstack *obstack, - VEC (converted_character_d) *chars, + const std::vector &chars, int quote_char, int width, enum bfd_endian byte_order, const struct value_print_options *options) { unsigned int idx; - struct converted_character *elem; + const converted_character *elem; enum {START, SINGLE, REPEAT, INCOMPLETE, FINISH} state, last; gdb_wchar_t wide_quote_char = gdb_btowc (quote_char); int need_escape = 0; @@ -2413,7 +2643,7 @@ print_converted_chars_to_obstack (struct obstack *obstack, last = state; if (state != FINISH) { - elem = VEC_index (converted_character_d, chars, idx++); + elem = &chars[idx++]; switch (elem->result) { case wchar_iterate_ok: @@ -2456,12 +2686,8 @@ generic_printstr (struct ui_file *stream, struct type *type, enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); unsigned int i; int width = TYPE_LENGTH (type); - struct obstack wchar_buf, output; - struct cleanup *cleanup; - struct wchar_iterator *iter; int finished = 0; struct converted_character *last; - VEC (converted_character_d) *converted_chars; if (length == -1) { @@ -2493,10 +2719,8 @@ generic_printstr (struct ui_file *stream, struct type *type, } /* Arrange to iterate over the characters, in wchar_t form. */ - iter = make_wchar_iterator (string, length * width, encoding, width); - cleanup = make_cleanup_wchar_iterator (iter); - converted_chars = NULL; - make_cleanup (VEC_cleanup (converted_character_d), &converted_chars); + wchar_iterator iter (string, length * width, encoding, width); + std::vector converted_chars; /* Convert characters until the string is over or the maximum number of printed characters has been reached. */ @@ -2508,7 +2732,7 @@ generic_printstr (struct ui_file *stream, struct type *type, QUIT; /* Grab the next character and repeat count. */ - r = count_next_character (iter, &converted_chars); + r = count_next_character (&iter, &converted_chars); /* If less than zero, the end of the input string was reached. */ if (r < 0) @@ -2521,7 +2745,7 @@ generic_printstr (struct ui_file *stream, struct type *type, /* Get the last element and determine if the entire string was processed. */ - last = VEC_last (converted_character_d, converted_chars); + last = &converted_chars.back (); finished = (last->result == wchar_iterate_eof); /* Ensure that CONVERTED_CHARS is terminated. */ @@ -2529,8 +2753,7 @@ generic_printstr (struct ui_file *stream, struct type *type, /* WCHAR_BUF is the obstack we use to represent the string in wchar_t form. */ - obstack_init (&wchar_buf); - make_cleanup_obstack_free (&wchar_buf); + auto_obstack wchar_buf; /* Print the output string to the obstack. */ print_converted_chars_to_obstack (&wchar_buf, converted_chars, quote_char, @@ -2540,8 +2763,7 @@ generic_printstr (struct ui_file *stream, struct type *type, obstack_grow_wstr (&wchar_buf, LCST ("...")); /* OUTPUT is where we collect `char's for printing. */ - obstack_init (&output); - make_cleanup_obstack_free (&output); + auto_obstack output; convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (), (gdb_byte *) obstack_base (&wchar_buf), @@ -2549,9 +2771,7 @@ generic_printstr (struct ui_file *stream, struct type *type, sizeof (gdb_wchar_t), &output, translit_char); obstack_1grow (&output, '\0'); - fputs_filtered (obstack_base (&output), stream); - - do_cleanups (cleanup); + fputs_filtered ((const char *) obstack_base (&output), stream); } /* Print a string from the inferior, starting at ADDR and printing up to LEN @@ -2569,7 +2789,7 @@ val_print_string (struct type *elttype, const char *encoding, const struct value_print_options *options) { int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero. */ - int errcode; /* Errno returned from bad reads. */ + int err; /* Non-zero if we got a bad read. */ int found_nul; /* Non-zero if we found the nul char. */ unsigned int fetchlimit; /* Maximum number of chars to print. */ int bytes_read; @@ -2587,11 +2807,11 @@ val_print_string (struct type *elttype, const char *encoding, because finding the null byte (or available memory) is what actually limits the fetch. */ - fetchlimit = (len == -1 ? options->print_max : min (len, - options->print_max)); + fetchlimit = (len == -1 ? options->print_max : std::min ((unsigned) len, + options->print_max)); - errcode = read_string (addr, len, width, fetchlimit, byte_order, - &buffer, &bytes_read); + err = read_string (addr, len, width, fetchlimit, byte_order, + &buffer, &bytes_read); old_chain = make_cleanup (xfree, buffer); addr += bytes_read; @@ -2619,7 +2839,7 @@ val_print_string (struct type *elttype, const char *encoding, && extract_unsigned_integer (peekbuf, width, byte_order) != 0) force_ellipsis = 1; } - else if ((len >= 0 && errcode != 0) || (len > bytes_read / width)) + else if ((len >= 0 && err != 0) || (len > bytes_read / width)) { /* Getting an error when we have a requested length, or fetching less than the number of characters actually requested, always make us @@ -2630,21 +2850,18 @@ val_print_string (struct type *elttype, const char *encoding, /* If we get an error before fetching anything, don't print a string. But if we fetch something and then get an error, print the string and then the error message. */ - if (errcode == 0 || bytes_read > 0) + if (err == 0 || bytes_read > 0) { LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width, encoding, force_ellipsis, options); } - if (errcode != 0) + if (err != 0) { - char *str; - - str = memory_error_message (errcode, gdbarch, addr); - make_cleanup (xfree, str); + std::string str = memory_error_message (TARGET_XFER_E_IO, gdbarch, addr); fprintf_filtered (stream, ""); } @@ -2666,7 +2883,7 @@ static unsigned input_radix_1 = 10; setting the input radix to "10" never changes it! */ static void -set_input_radix (char *args, int from_tty, struct cmd_list_element *c) +set_input_radix (const char *args, int from_tty, struct cmd_list_element *c) { set_input_radix_1 (from_tty, input_radix_1); } @@ -2703,7 +2920,7 @@ set_input_radix_1 (int from_tty, unsigned radix) static unsigned output_radix_1 = 10; static void -set_output_radix (char *args, int from_tty, struct cmd_list_element *c) +set_output_radix (const char *args, int from_tty, struct cmd_list_element *c) { set_output_radix_1 (from_tty, output_radix_1); } @@ -2748,7 +2965,7 @@ set_output_radix_1 (int from_tty, unsigned radix) the 'set input-radix' command. */ static void -set_radix (char *arg, int from_tty) +set_radix (const char *arg, int from_tty) { unsigned radix; @@ -2766,7 +2983,7 @@ set_radix (char *arg, int from_tty) /* Show both the input and output radices. */ static void -show_radix (char *arg, int from_tty) +show_radix (const char *arg, int from_tty) { if (from_tty) { @@ -2790,7 +3007,7 @@ show_radix (char *arg, int from_tty) static void -set_print (char *arg, int from_tty) +set_print (const char *arg, int from_tty) { printf_unfiltered ( "\"set print\" must be followed by the name of a print subcommand.\n"); @@ -2798,13 +3015,13 @@ set_print (char *arg, int from_tty) } static void -show_print (char *args, int from_tty) +show_print (const char *args, int from_tty) { cmd_show_list (showprintlist, from_tty, ""); } static void -set_print_raw (char *arg, int from_tty) +set_print_raw (const char *arg, int from_tty) { printf_unfiltered ( "\"set print raw\" must be followed by the name of a \"print raw\" subcommand.\n"); @@ -2812,7 +3029,7 @@ set_print_raw (char *arg, int from_tty) } static void -show_print_raw (char *args, int from_tty) +show_print_raw (const char *args, int from_tty) { cmd_show_list (showprintrawlist, from_tty, ""); }