/* Support for printing Ada values for GDB, the GNU debugger.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include <ctype.h>
-#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
-#include "demangle.h"
#include "valprint.h"
#include "language.h"
#include "annotate.h"
#include "ada-lang.h"
-#include "c-lang.h"
-#include "infcall.h"
-#include "objfiles.h"
#include "target-float.h"
#include "cli/cli-style.h"
+#include "gdbarch.h"
static int print_field_values (struct type *, const gdb_byte *,
int,
}
if (i < len)
{
- fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
+ fputs_styled (ada_enum_name (TYPE_FIELD_NAME (type, i)),
+ variable_name_style.style (), stream);
}
else
{
unsigned int length, int force_ellipses, int type_len,
const struct value_print_options *options)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype));
+ enum bfd_endian byte_order = type_byte_order (elttype);
unsigned int i;
unsigned int things_printed = 0;
int in_quotes = 0;
struct value *original_value,
const struct value_print_options *options)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
struct type *elttype = TYPE_TARGET_TYPE (type);
unsigned int eltlen;
unsigned int len;
thin pointers, etc). */
static void
-ada_val_print_gnat_array (struct type *type, const gdb_byte *valaddr,
- int offset, CORE_ADDR address,
+ada_val_print_gnat_array (struct value *val,
struct ui_file *stream, int recurse,
- struct value *original_value,
const struct value_print_options *options)
{
- struct value *mark = value_mark ();
- struct value *val;
+ scoped_value_mark free_values;
+
+ struct type *type = ada_check_typedef (value_type (val));
- val = value_from_contents_and_address (type, valaddr + offset, address);
/* 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. */
fprintf_filtered (stream, "0x0");
}
else
- val_print (value_type (val),
- value_embedded_offset (val), value_address (val),
- stream, recurse, val, options,
- language_def (language_ada));
- value_free_to_mark (mark);
+ common_val_print (val, stream, recurse, options,
+ language_def (language_ada));
}
/* Implement Ada val_print'ing for the case where TYPE is
}
}
+/* 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)
+{
+ common_val_print (val, stream, recurse, options, language_def (language_c));
+
+ struct type *type = ada_check_typedef (value_type (val));
+ if (ada_is_tag_type (type))
+ {
+ const char *name = ada_tag_name (val);
+
+ if (name != NULL)
+ fprintf_filtered (stream, " (%s)", name);
+ }
+}
+
/* Implement Ada val_print'ing for the case where TYPE is
a TYPE_CODE_INT or TYPE_CODE_RANGE. */
}
}
+/* 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 (value_type (val));
+ const gdb_byte *valaddr = value_contents_for_printing (val);
+
+ if (ada_is_fixed_point_type (type))
+ {
+ struct value *scale = ada_scaling_factor (type);
+ val = value_cast (value_type (scale), val);
+ val = value_binop (val, scale, BINOP_MUL);
+
+ const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g";
+ std::string str
+ = target_float_to_string (value_contents (val), value_type (val), fmt);
+ fputs_filtered (str.c_str (), stream);
+ return;
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_RANGE
+ && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ENUM
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_BOOL
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == 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 recuse for those as well. */
+ struct type *target_type = TYPE_TARGET_TYPE (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 = get_type_arch (type);
+ struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+ CORE_ADDR addr = extract_typed_address (valaddr, ptr_type);
+
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") ");
+ fputs_filtered (paddress (gdbarch, addr), stream);
+ }
+ else
+ {
+ value_print_scalar_formatted (val, options, 0, stream);
+ if (ada_is_character_type (type))
+ {
+ LONGEST c;
+
+ fputs_filtered (" ", 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. */
const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i));
if (name[0] == '\'')
- fprintf_filtered (stream, "%ld %s", (long) val, name);
+ fprintf_filtered (stream, "%ld %ps", (long) val,
+ styled_string (variable_name_style.style (),
+ name));
else
- fputs_filtered (name, stream);
+ fputs_styled (name, variable_name_style.style (), stream);
}
else
print_longest (stream, 'd', 0, val);
|| (ada_is_constrained_packed_array_type (type)
&& TYPE_CODE (type) != TYPE_CODE_PTR))
{
- ada_val_print_gnat_array (type, valaddr, offset, address,
- stream, recurse, original_value,
- options);
+ struct value *val = value_from_contents_and_address (type,
+ valaddr + offset,
+ address);
+ ada_val_print_gnat_array (val, stream, recurse, options);
return;
}
}
}
+/* See the comment on ada_value_print. This function differs in that
+ it does not catch evaluation errors (leaving that to
+ ada_value_print). */
+
+static void
+ada_value_print_1 (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options)
+{
+ struct type *type = ada_check_typedef (value_type (val));
+
+ if (ada_is_array_descriptor_type (type)
+ || (ada_is_constrained_packed_array_type (type)
+ && TYPE_CODE (type) != TYPE_CODE_PTR))
+ {
+ ada_val_print_gnat_array (val, stream, recurse, options);
+ return;
+ }
+
+ val = ada_to_fixed_value (val);
+ type = value_type (val);
+ struct type *saved_type = type;
+
+ const gdb_byte *valaddr = value_contents_for_printing (val);
+ CORE_ADDR address = value_address (val);
+ type = ada_check_typedef (resolve_dynamic_type (type, valaddr, address));
+ if (type != saved_type)
+ {
+ val = value_copy (val);
+ deprecated_set_value_type (val, type);
+ }
+
+ switch (TYPE_CODE (type))
+ {
+ 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 (type, valaddr, 0, 0,
+ address, stream, recurse, val,
+ 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 (type, valaddr, 0, 0,
+ address, stream, recurse,
+ val, options);
+ break;
+
+ case TYPE_CODE_ARRAY:
+ ada_val_print_array (type, valaddr, 0, 0,
+ address, stream, recurse, val,
+ options);
+ return;
+
+ case TYPE_CODE_REF:
+ ada_val_print_ref (type, valaddr, 0, 0,
+ address, stream, recurse, val,
+ options);
+ break;
+ }
+}
+
+/* See ada-lang.h. */
+
+void
+ada_value_print_inner (struct value *val, struct ui_file *stream,
+ int recurse,
+ const struct value_print_options *options)
+{
+ try
+ {
+ ada_value_print_1 (val, stream, recurse, options);
+ }
+ catch (const gdb_exception_error &except)
+ {
+ fprintf_styled (stream, metadata_style.style (),
+ _("<error reading variable: %s>"),
+ except.what ());
+ }
+}
+
void
ada_value_print (struct value *val0, struct ui_file *stream,
const struct value_print_options *options)