/* Print values for GDB, the GNU debugger.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbarch.h"
#include "cli/cli-style.h"
#include "count-one-bits.h"
+#include "c-lang.h"
+#include "cp-abi.h"
+#include "inferior.h"
/* Maximum number of wchars returned from wchar_iterate. */
#define MAX_WCHARS 4
10, /* repeat_count_threshold */
0, /* output_format */
0, /* format */
+ 1, /* memory_tag_violations */
0, /* stop_print_at_null */
0, /* print_array_indexes */
0, /* deref_ref */
static void
show_print_array_indexes (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
+ struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
}
value);
}
+/* If nonzero, prints memory tag violations for pointers. */
+
+static void
+show_memory_tag_violations (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file,
+ _("Printing of memory tag violations is %s.\n"),
+ value);
+}
+
/* If nonzero, stops printing of char arrays at first null. */
static void
type = TYPE_TARGET_TYPE (type);
type = check_typedef (type);
}
- switch (TYPE_CODE (type))
+ switch (type->code ())
{
case TYPE_CODE_ARRAY:
case TYPE_CODE_STRUCT:
const struct language_defn *language)
{
return (val_print_scalar_type_p (type)
- || language->la_is_string_type_p (type));
+ || language->is_string_type_p (type));
}
-/* See its definition in value.h. */
+/* See valprint.h. */
int
valprint_check_validity (struct ui_file *stream,
return 0;
}
- if (TYPE_CODE (type) != TYPE_CODE_UNION
- && TYPE_CODE (type) != TYPE_CODE_STRUCT
- && TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ if (type->code () != TYPE_CODE_UNION
+ && type->code () != TYPE_CODE_STRUCT
+ && type->code () != TYPE_CODE_ARRAY)
{
if (value_bits_any_optimized_out (val,
TARGET_CHAR_BIT * embedded_offset,
if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset,
TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{
- const int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+ const int is_ref = type->code () == TYPE_CODE_REF;
int ref_is_addressable = 0;
if (is_ref)
CORE_ADDR address, struct ui_file *stream,
const struct value_print_options *options)
{
- struct gdbarch *gdbarch = get_type_arch (type);
+ struct gdbarch *gdbarch = type->arch ();
- if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+ if (elttype->code () == TYPE_CODE_FUNC)
{
/* Try to print what function it points to. */
print_function_pointer_address (options, gdbarch, address, stream);
if (!get_array_bounds (type, &low_bound, &high_bound))
error (_("Could not determine the array high bound"));
- if (options->prettyformat_arrays)
- {
- print_spaces_filtered (2 + 2 * recurse, stream);
- }
-
fputs_filtered (decorations->array_start, stream);
value_print_array_elements (val, stream, recurse, options, 0);
fputs_filtered (decorations->array_end, stream);
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);
+ struct gdbarch *gdbarch = type->arch ();
if (address_buffer != NULL)
{
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 int type_is_defined = elttype->code () != TYPE_CODE_UNDEF;
const gdb_byte *valaddr = value_contents_for_printing (original_value);
if (must_coerce_ref && type_is_defined)
unsigned int i;
unsigned int len;
- len = TYPE_NFIELDS (type);
+ len = type->num_fields ();
for (i = 0; i < len; i++)
{
QUIT;
fputs_styled (TYPE_FIELD_NAME (type, i), variable_name_style.style (),
stream);
}
- else if (TYPE_FLAG_ENUM (type))
+ else if (type->is_flag_enum ())
{
int first = 1;
const struct value_print_options *options)
{
LONGEST val;
- struct gdbarch *gdbarch = get_type_arch (type);
+ struct gdbarch *gdbarch = type->arch ();
int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
gdb_assert (!options->format);
struct value *original_value,
const struct value_print_options *options)
{
- struct gdbarch *gdbarch = get_type_arch (type);
+ struct gdbarch *gdbarch = type->arch ();
gdb_assert (!options->format);
const gdb_byte *valaddr = value_contents_for_printing (value);
LONGEST val = unpack_long (type, valaddr);
- if (TYPE_UNSIGNED (type))
+ if (type->is_unsigned ())
fprintf_filtered (stream, "%u", (unsigned int) val);
else
fprintf_filtered (stream, "%d", (int) val);
/* 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,
+generic_val_print_float (struct type *type, 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);
-
gdb_assert (!options->format);
const gdb_byte *valaddr = value_contents_for_printing (original_value);
- print_floating (valaddr + embedded_offset * unit_size, type, stream);
+ print_floating (valaddr, type, stream);
+}
+
+/* generic_val_print helper for TYPE_CODE_FIXED_POINT. */
+
+static void
+generic_val_print_fixed_point (struct value *val, struct ui_file *stream,
+ const struct value_print_options *options)
+{
+ if (options->format)
+ value_print_scalar_formatted (val, options, 0, stream);
+ else
+ {
+ struct type *type = value_type (val);
+
+ const gdb_byte *valaddr = value_contents_for_printing (val);
+ gdb_mpf f;
+
+ f.read_fixed_point (gdb::make_array_view (valaddr, TYPE_LENGTH (type)),
+ type_byte_order (type), type->is_unsigned (),
+ type->fixed_point_scaling_factor ());
+
+ const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11Fg" : "%.17Fg";
+ std::string str = gmp_string_printf (fmt, f.val);
+ fprintf_filtered (stream, "%s", str.c_str ());
+ }
}
/* generic_value_print helper for TYPE_CODE_COMPLEX. */
{
fprintf_filtered (stream, "%s", decorations->complex_prefix);
- struct type *type = check_typedef (value_type (val));
- struct value *real_part
- = value_from_component (val, TYPE_TARGET_TYPE (type), 0);
+ struct value *real_part = value_real_part (val);
value_print_scalar_formatted (real_part, options, 0, stream);
fprintf_filtered (stream, "%s", decorations->complex_infix);
- struct value *imag_part
- = value_from_component (val, TYPE_TARGET_TYPE (type),
- TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
-
+ struct value *imag_part = value_imaginary_part (val);
value_print_scalar_formatted (imag_part, options, 0, stream);
fprintf_filtered (stream, "%s", decorations->complex_suffix);
}
+/* generic_value_print helper for TYPE_CODE_MEMBERPTR. */
+
+static void
+generic_value_print_memberptr
+ (struct value *val, struct ui_file *stream,
+ int recurse,
+ const struct value_print_options *options,
+ const struct generic_val_print_decorations *decorations)
+{
+ if (!options->format)
+ {
+ /* Member pointers are essentially specific to C++, and so if we
+ encounter one, we should print it according to C++ rules. */
+ struct type *type = check_typedef (value_type (val));
+ const gdb_byte *valaddr = value_contents_for_printing (val);
+ cp_print_class_member (valaddr, type, stream, "&");
+ }
+ else
+ generic_value_print (val, stream, recurse, options, decorations);
+}
+
/* See valprint.h. */
void
struct type *type = value_type (val);
type = check_typedef (type);
- switch (TYPE_CODE (type))
+
+ if (is_fixed_point_type (type))
+ type = type->fixed_point_type_base_type ();
+
+ switch (type->code ())
{
case TYPE_CODE_ARRAY:
generic_val_print_array (val, stream, recurse, options, decorations);
break;
case TYPE_CODE_MEMBERPTR:
- value_print_scalar_formatted (val, options, 0, stream);
+ generic_value_print_memberptr (val, stream, recurse, options,
+ decorations);
break;
case TYPE_CODE_PTR:
break;
case TYPE_CODE_RANGE:
- /* FIXME: create_static_range_type does not set the unsigned bit in a
- range type (I think it probably should copy it from the
- target type), so we won't print values which are too large to
- fit in a signed integer correctly. */
- /* FIXME: Doesn't handle ranges of enums correctly. (Can't just
- print with the target type, though, because the size of our
- type and the target type might differ). */
-
- /* FALLTHROUGH */
-
case TYPE_CODE_INT:
generic_value_print_int (val, stream, options);
break;
if (options->format)
value_print_scalar_formatted (val, options, 0, stream);
else
- generic_val_print_float (type, 0, stream,
- val, options);
+ generic_val_print_float (type, stream, val, options);
+ break;
+
+ case TYPE_CODE_FIXED_POINT:
+ generic_val_print_fixed_point (val, stream, options);
break;
case TYPE_CODE_VOID:
case TYPE_CODE_UNDEF:
/* 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. */
+ 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_styled (stream, metadata_style.style (), _("<incomplete type>"));
break;
generic_value_print_complex (val, stream, options, decorations);
break;
+ case TYPE_CODE_METHODPTR:
+ cplus_print_method_ptr (value_contents_for_printing (val), type,
+ stream);
+ break;
+
case TYPE_CODE_UNION:
case TYPE_CODE_STRUCT:
- case TYPE_CODE_METHODPTR:
default:
error (_("Unhandled type code %d in symbol table."),
- TYPE_CODE (type));
+ type->code ());
}
}
only a stub and we can't find and substitute its complete type, then
print appropriate string and return. */
- if (TYPE_STUB (real_type))
+ if (real_type->is_stub ())
{
fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
return;
try
{
- language->la_value_print_inner (value, stream, recurse, &local_opts);
+ language->value_print_inner (value, stream, recurse, &local_opts);
}
catch (const gdb_exception_error &except)
{
{
if (options->max_depth > -1 && recurse >= options->max_depth)
{
- gdb_assert (language->la_struct_too_deep_ellipsis != NULL);
- fputs_filtered (language->la_struct_too_deep_ellipsis, stream);
+ gdb_assert (language->struct_too_deep_ellipsis () != NULL);
+ fputs_filtered (language->struct_too_deep_ellipsis (), stream);
return true;
}
return 0;
}
- if (TYPE_CODE (value_type (val)) == TYPE_CODE_INTERNAL_FUNCTION)
+ if (value_type (val)->code () == TYPE_CODE_INTERNAL_FUNCTION)
{
fprintf_styled (stream, metadata_style.style (),
_("<internal function %s>"),
return;
}
- LA_VALUE_PRINT (val, stream, options);
+ current_language->value_print (val, stream, options);
}
static void
const gdb_byte *valaddr = (value_contents_for_printing (original_value)
+ embedded_offset);
ULONGEST val = unpack_long (type, valaddr);
- int field, nfields = TYPE_NFIELDS (type);
- struct gdbarch *gdbarch = get_type_arch (type);
+ int field, nfields = type->num_fields ();
+ struct gdbarch *gdbarch = type->arch ();
struct type *bool_type = builtin_type (gdbarch)->builtin_bool;
fputs_filtered ("[", stream);
{
if (TYPE_FIELD_NAME (type, field)[0] != '\0')
{
- struct type *field_type = TYPE_FIELD_TYPE (type, field);
+ struct type *field_type = type->field (field).type ();
if (field_type == bool_type
/* We require boolean types here to be one bit wide. This is a
fprintf_filtered (stream, " %ps=",
styled_string (variable_name_style.style (),
TYPE_FIELD_NAME (type, field)));
- if (TYPE_CODE (field_type) == TYPE_CODE_ENUM)
+ if (field_type->code () == TYPE_CODE_ENUM)
generic_val_print_enum_1 (field_type, field_val, stream);
else
print_longest (stream, 'd', 0, field_val);
/* Take low nibble and bump our pointer "p". */
digits[0] += LOW_NIBBLE (*p);
- if (byte_order == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
p++;
else
p--;
}
}
-/* VALADDR points to a char integer of LEN bytes.
- Print it out in appropriate language form on stream.
- Omit any leading zero chars. */
-
-void
-print_char_chars (struct ui_file *stream, struct type *type,
- const gdb_byte *valaddr,
- unsigned len, enum bfd_endian byte_order)
-{
- const gdb_byte *p;
-
- if (byte_order == BFD_ENDIAN_BIG)
- {
- p = valaddr;
- while (p < valaddr + len - 1 && *p == 0)
- ++p;
-
- while (p < valaddr + len)
- {
- LA_EMIT_CHAR (*p, type, stream, '\'');
- ++p;
- }
- }
- else
- {
- p = valaddr + len - 1;
- while (p > valaddr && *p == 0)
- --p;
-
- while (p >= valaddr)
- {
- LA_EMIT_CHAR (*p, type, stream, '\'');
- --p;
- }
- }
-}
-
/* Print function pointer with inferior address ADDRESS onto stdio
stream STREAM. */
CORE_ADDR address,
struct ui_file *stream)
{
- CORE_ADDR func_addr
- = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
- current_top_target ());
+ CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr
+ (gdbarch, address, current_inferior ()->top_target ());
/* If the function pointer is represented by a description, print
the address of the description. */
void
maybe_print_array_index (struct type *index_type, LONGEST index,
- struct ui_file *stream,
+ struct ui_file *stream,
const struct value_print_options *options)
{
- struct value *index_value;
-
if (!options->print_array_indexes)
return;
-
- index_value = value_from_longest (index_type, index);
- LA_PRINT_ARRAY_INDEX (index_value, stream, options);
+ current_language->print_array_index (index_type, index, stream, options);
}
/* See valprint.h. */
{
unsigned int things_printed = 0;
unsigned len;
- struct type *elttype, *index_type, *base_index_type;
+ struct type *elttype, *index_type;
unsigned eltlen;
/* Position of the array element we are examining to see
whether it is repeated. */
/* Number of repetitions we have detected so far. */
unsigned int reps;
LONGEST low_bound, high_bound;
- LONGEST low_pos, high_pos;
struct type *type = check_typedef (value_type (val));
elttype = TYPE_TARGET_TYPE (type);
eltlen = type_length_units (check_typedef (elttype));
- index_type = TYPE_INDEX_TYPE (type);
+ index_type = type->index_type ();
+ if (index_type->code () == TYPE_CODE_RANGE)
+ index_type = TYPE_TARGET_TYPE (index_type);
if (get_array_bounds (type, &low_bound, &high_bound))
{
- if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
- base_index_type = TYPE_TARGET_TYPE (index_type);
- else
- base_index_type = index_type;
-
- /* Non-contiguous enumerations types can by used as index types
- in some languages (e.g. Ada). In this case, the array length
- shall be computed from the positions of the first and last
- literal in the enumeration type, and not from the values
- of these literals. */
- if (!discrete_position (base_index_type, low_bound, &low_pos)
- || !discrete_position (base_index_type, high_bound, &high_pos))
- {
- warning (_("unable to get positions in array, use bounds instead"));
- low_pos = low_bound;
- high_pos = high_bound;
- }
-
- /* The array length should normally be HIGH_POS - LOW_POS + 1.
- But we have to be a little extra careful, because some languages
- such as Ada allow LOW_POS to be greater than HIGH_POS for
- empty arrays. In that situation, the array length is just zero,
- not negative! */
- if (low_pos > high_pos)
+ /* The array length should normally be HIGH_BOUND - LOW_BOUND +
+ 1. But we have to be a little extra careful, because some
+ languages such as Ada allow LOW_BOUND to be greater than
+ HIGH_BOUND for empty arrays. In that situation, the array
+ length is just zero, not negative! */
+ if (low_bound > high_bound)
len = 0;
else
- len = high_pos - low_pos + 1;
+ len = high_bound - low_bound + 1;
}
else
{
else
fprintf_filtered (stream, ", ");
}
+ else if (options->prettyformat_arrays)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
wrap_here (n_spaces (2 + 2 * recurse));
maybe_print_array_index (index_type, i + low_bound,
- stream, options);
+ stream, options);
rep1 = i + 1;
reps = 1;
annotate_array_section_end ();
if (i < len)
fprintf_filtered (stream, "...");
+ if (options->prettyformat_arrays)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
}
/* Read LEN bytes of target memory at address MEMADDR, placing the
Unless an exception is thrown, BUFFER will always be allocated, even on
failure. In this case, some characters might have been read before the
- failure happened. Check BYTES_READ to recognize this situation.
-
- Note: There was a FIXME asking to make this code use target_read_string,
- but this function is more general (can read past null characters, up to
- given LEN). Besides, it is used much more often than target_read_string
- so it is more tested. Perhaps callers of target_read_string should use
- this function instead? */
+ failure happened. Check BYTES_READ to recognize this situation. */
int
read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
unsigned int fetchlimit; /* Maximum number of chars to print. */
int bytes_read;
gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */
- struct gdbarch *gdbarch = get_type_arch (elttype);
+ struct gdbarch *gdbarch = elttype->arch ();
enum bfd_endian byte_order = type_byte_order (elttype);
int width = TYPE_LENGTH (elttype);
gdb_byte *peekbuf;
/* We didn't find a NUL terminator we were looking for. Attempt
- to peek at the next character. If not successful, or it is not
- a null byte, then force ellipsis to be printed. */
+ to peek at the next character. If not successful, or it is not
+ a null byte, then force ellipsis to be printed. */
peekbuf = (gdb_byte *) alloca (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
- print ellipsis. */
+ than the number of characters actually requested, always make us
+ print ellipsis. */
force_ellipsis = 1;
}
}
\f
-static void
-set_print (const char *arg, int from_tty)
-{
- printf_unfiltered (
- "\"set print\" must be followed by the name of a print subcommand.\n");
- help_list (setprintlist, "set print ", all_commands, gdb_stdout);
-}
-
-static void
-show_print (const char *args, int from_tty)
-{
- cmd_show_list (showprintlist, from_tty, "");
-}
-
-static void
-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");
- help_list (setprintrawlist, "set print raw ", all_commands, gdb_stdout);
-}
-
-static void
-show_print_raw (const char *args, int from_tty)
-{
- cmd_show_list (showprintrawlist, from_tty, "");
-}
-
/* Controls printing of vtbl's. */
static void
show_vtblprint (struct ui_file *file, int from_tty,
Use \"unlimited\" to print the complete structure.")
},
+ boolean_option_def {
+ "memory-tag-violations",
+ [] (value_print_options *opt) { return &opt->memory_tag_violations; },
+ show_memory_tag_violations, /* show_cmd_cb */
+ N_("Set printing of memory tag violations for pointers."),
+ N_("Show printing of memory tag violations for pointers."),
+ N_("Issue a warning when the printed value is a pointer\n\
+whose logical tag doesn't match the allocation tag of the memory\n\
+location it points to."),
+ },
+
boolean_option_def {
"null-stop",
[] (value_print_options *opt) { return &opt->stop_print_at_null; },
{
cmd_list_element *cmd;
- add_prefix_cmd ("print", no_class, set_print,
- _("Generic command for setting how things print."),
- &setprintlist, "set print ", 0, &setlist);
- add_alias_cmd ("p", "print", no_class, 1, &setlist);
+ cmd_list_element *set_print_cmd
+ = add_basic_prefix_cmd ("print", no_class,
+ _("Generic command for setting how things print."),
+ &setprintlist, 0, &setlist);
+ add_alias_cmd ("p", set_print_cmd, no_class, 1, &setlist);
/* Prefer set print to set prompt. */
- add_alias_cmd ("pr", "print", no_class, 1, &setlist);
+ add_alias_cmd ("pr", set_print_cmd, no_class, 1, &setlist);
- add_prefix_cmd ("print", no_class, show_print,
- _("Generic command for showing print settings."),
- &showprintlist, "show print ", 0, &showlist);
- add_alias_cmd ("p", "print", no_class, 1, &showlist);
- add_alias_cmd ("pr", "print", no_class, 1, &showlist);
+ cmd_list_element *show_print_cmd
+ = add_show_prefix_cmd ("print", no_class,
+ _("Generic command for showing print settings."),
+ &showprintlist, 0, &showlist);
+ add_alias_cmd ("p", show_print_cmd, no_class, 1, &showlist);
+ add_alias_cmd ("pr", show_print_cmd, no_class, 1, &showlist);
- cmd = add_prefix_cmd ("raw", no_class, set_print_raw,
- _("\
+ cmd = add_basic_prefix_cmd ("raw", no_class,
+ _("\
Generic command for setting what things to print in \"raw\" mode."),
- &setprintrawlist, "set print raw ", 0,
- &setprintlist);
+ &setprintrawlist, 0, &setprintlist);
deprecate_cmd (cmd, nullptr);
- cmd = add_prefix_cmd ("raw", no_class, show_print_raw,
- _("Generic command for showing \"print raw\" settings."),
- &showprintrawlist, "show print raw ", 0,
- &showprintlist);
+ cmd = add_show_prefix_cmd ("raw", no_class,
+ _("Generic command for showing \"print raw\" settings."),
+ &showprintrawlist, 0, &showprintlist);
deprecate_cmd (cmd, nullptr);
gdb::option::add_setshow_cmds_for_options