X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fada-typeprint.c;h=b78654d100f8677f5dd18732e161768c1c9257c7;hb=22ad8107d35d833db000e5a5050c0f53af7af51f;hp=7d548bdd8764e2bdcadae4fd8447ca3bf290bc03;hpb=aba02109701c9824499b42f1cf044a995fc603e1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c index 7d548bdd87..b78654d100 100644 --- a/gdb/ada-typeprint.c +++ b/gdb/ada-typeprint.c @@ -1,5 +1,5 @@ /* Support for printing Ada types for GDB, the GNU debugger. - Copyright (C) 1986-2014 Free Software Foundation, Inc. + Copyright (C) 1986-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -31,11 +31,9 @@ #include "demangle.h" #include "c-lang.h" #include "typeprint.h" +#include "target-float.h" #include "ada-lang.h" - #include -#include -#include static int print_selected_record_field_types (struct type *, struct type *, int, int, @@ -67,7 +65,7 @@ decoded_type_name (struct type *type) if (name_buffer == NULL || name_buffer_len <= strlen (raw_name)) { name_buffer_len = 16 + 2 * strlen (raw_name); - name_buffer = xrealloc (name_buffer, name_buffer_len); + name_buffer = (char *) xrealloc (name_buffer, name_buffer_len); } strcpy (name_buffer, raw_name); @@ -103,26 +101,90 @@ decoded_type_name (struct type *type) } } -/* Print TYPE on STREAM, preferably as a range. */ +/* Return nonzero if TYPE is a subrange type, and its bounds + are identical to the bounds of its subtype. */ + +static int +type_is_full_subrange_of_target_type (struct type *type) +{ + struct type *subtype; + + if (TYPE_CODE (type) != TYPE_CODE_RANGE) + return 0; + + subtype = TYPE_TARGET_TYPE (type); + if (subtype == NULL) + return 0; + + if (is_dynamic_type (type)) + return 0; + + if (ada_discrete_type_low_bound (type) + != ada_discrete_type_low_bound (subtype)) + return 0; + + if (ada_discrete_type_high_bound (type) + != ada_discrete_type_high_bound (subtype)) + return 0; + + return 1; +} + +/* Print TYPE on STREAM, preferably as a range if BOUNDS_PREFERED_P + is nonzero. */ static void -print_range (struct type *type, struct ui_file *stream) +print_range (struct type *type, struct ui_file *stream, + int bounds_prefered_p) { + if (!bounds_prefered_p) + { + /* Try stripping all TYPE_CODE_RANGE layers whose bounds + are identical to the bounds of their subtype. When + the bounds of both types match, it can allow us to + print a range using the name of its base type, which + is easier to read. For instance, we would print... + + array (character) of ... + + ... instead of... + + array ('["00"]' .. '["ff"]') of ... */ + while (type_is_full_subrange_of_target_type (type)) + type = TYPE_TARGET_TYPE (type); + } + switch (TYPE_CODE (type)) { case TYPE_CODE_RANGE: case TYPE_CODE_ENUM: { - struct type *target_type; - - target_type = TYPE_TARGET_TYPE (type); - if (target_type == NULL) - target_type = type; - ada_print_scalar (target_type, ada_discrete_type_low_bound (type), - stream); - fprintf_filtered (stream, " .. "); - ada_print_scalar (target_type, ada_discrete_type_high_bound (type), - stream); + LONGEST lo = 0, hi = 0; /* init for gcc -Wall */ + int got_error = 0; + + TRY + { + lo = ada_discrete_type_low_bound (type); + hi = ada_discrete_type_high_bound (type); + } + CATCH (e, RETURN_MASK_ERROR) + { + /* This can happen when the range is dynamic. Sometimes, + resolving dynamic property values requires us to have + access to an actual object, which is not available + when the user is using the "ptype" command on a type. + Print the range as an unbounded range. */ + fprintf_filtered (stream, "<>"); + got_error = 1; + } + END_CATCH + + if (!got_error) + { + ada_print_scalar (type, lo, stream); + fprintf_filtered (stream, " .. "); + ada_print_scalar (type, hi, stream); + } } break; default: @@ -137,7 +199,7 @@ print_range (struct type *type, struct ui_file *stream) set *N past the bound and its delimiter, if any. */ static void -print_range_bound (struct type *type, char *bounds, int *n, +print_range_bound (struct type *type, const char *bounds, int *n, struct ui_file *stream) { LONGEST B; @@ -164,8 +226,8 @@ print_range_bound (struct type *type, char *bounds, int *n, else { int bound_len; - char *bound = bounds + *n; - char *pend; + const char *bound = bounds + *n; + const char *pend; pend = strstr (bound, "__"); if (pend == NULL) @@ -187,27 +249,27 @@ static void print_dynamic_range_bound (struct type *type, const char *name, int name_len, const char *suffix, struct ui_file *stream) { - static char *name_buf = NULL; - static size_t name_buf_len = 0; LONGEST B; - int OK; - - GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1); - strncpy (name_buf, name, name_len); - strcpy (name_buf + name_len, suffix); + std::string name_buf (name, name_len); + name_buf += suffix; - B = get_int_var_value (name_buf, &OK); - if (OK) + if (get_int_var_value (name_buf.c_str (), B)) ada_print_scalar (type, B, stream); else fprintf_filtered (stream, "?"); } /* Print RAW_TYPE as a range type, using any bound information - following the GNAT encoding (if available). */ + following the GNAT encoding (if available). + + If BOUNDS_PREFERED_P is nonzero, force the printing of the range + using its bounds. Otherwise, try printing the range without + printing the value of the bounds, if possible (this is only + considered a hint, not a guaranty). */ static void -print_range_type (struct type *raw_type, struct ui_file *stream) +print_range_type (struct type *raw_type, struct ui_file *stream, + int bounds_prefered_p) { const char *name; struct type *base_type; @@ -224,11 +286,11 @@ print_range_type (struct type *raw_type, struct ui_file *stream) subtype_info = strstr (name, "___XD"); if (subtype_info == NULL) - print_range (raw_type, stream); + print_range (raw_type, stream, bounds_prefered_p); else { int prefix_len = subtype_info - name; - char *bounds_str; + const char *bounds_str; int n; subtype_info += 5; @@ -290,16 +352,23 @@ print_enum_type (struct type *type, struct ui_file *stream) static void print_fixed_point_type (struct type *type, struct ui_file *stream) { - DOUBLEST delta = ada_delta (type); - DOUBLEST small = ada_fixed_to_float (type, 1.0); + struct value *delta = ada_delta (type); + struct value *small = ada_scaling_factor (type); - if (delta < 0.0) + if (delta == nullptr) fprintf_filtered (stream, "delta ??"); else { - fprintf_filtered (stream, "delta %g", (double) delta); - if (delta != small) - fprintf_filtered (stream, " <'small = %g>", (double) small); + std::string str; + str = target_float_to_string (value_contents (delta), + value_type (delta), "%g"); + fprintf_filtered (stream, "delta %s", str.c_str()); + if (!value_equal (delta, small)) + { + str = target_float_to_string (value_contents (small), + value_type (small), "%g"); + fprintf_filtered (stream, " <'small = %s>", str.c_str()); + } } } @@ -314,6 +383,7 @@ print_array_type (struct type *type, struct ui_file *stream, int show, { int bitsize; int n_indices; + struct type *elt_type = NULL; if (ada_is_constrained_packed_array_type (type)) type = ada_coerce_to_simple_array_type (type); @@ -344,7 +414,8 @@ print_array_type (struct type *type, struct ui_file *stream, int show, { if (arr_type != type) fprintf_filtered (stream, ", "); - print_range (TYPE_INDEX_TYPE (arr_type), stream); + print_range (TYPE_INDEX_TYPE (arr_type), stream, + 0 /* bounds_prefered_p */); if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0) bitsize = TYPE_FIELD_BITSIZE (arr_type, 0); } @@ -361,7 +432,7 @@ print_array_type (struct type *type, struct ui_file *stream, int show, if (k > 0) fprintf_filtered (stream, ", "); print_range_type (TYPE_FIELD_TYPE (range_desc_type, k), - stream); + stream, 0 /* bounds_prefered_p */); if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0) bitsize = TYPE_FIELD_BITSIZE (arr_type, 0); } @@ -375,11 +446,15 @@ print_array_type (struct type *type, struct ui_file *stream, int show, fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", "); } + elt_type = ada_array_element_type (type, n_indices); fprintf_filtered (stream, ") of "); wrap_here (""); - ada_print_type (ada_array_element_type (type, n_indices), "", stream, - show == 0 ? 0 : show - 1, level + 1, flags); - if (bitsize > 0) + ada_print_type (elt_type, "", stream, show == 0 ? 0 : show - 1, level + 1, + flags); + /* Arrays with variable-length elements are never bit-packed in practice but + compilers have to describe their stride so that we can properly fetch + individual elements. Do not say the array is packed in this case. */ + if (bitsize > 0 && !is_dynamic_type (elt_type)) fprintf_filtered (stream, " ", bitsize); } @@ -697,7 +772,8 @@ print_func_type (struct type *type, struct ui_file *stream, const char *name, { int i, len = TYPE_NFIELDS (type); - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID) + if (TYPE_TARGET_TYPE (type) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID) fprintf_filtered (stream, "procedure"); else fprintf_filtered (stream, "function"); @@ -722,7 +798,9 @@ print_func_type (struct type *type, struct ui_file *stream, const char *name, fprintf_filtered (stream, ")"); } - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) + if (TYPE_TARGET_TYPE (type) == NULL) + fprintf_filtered (stream, " return "); + else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) { fprintf_filtered (stream, " return "); ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags); @@ -818,7 +896,7 @@ ada_print_type (struct type *type0, const char *varstring, else { fprintf_filtered (stream, "range "); - print_range_type (type, stream); + print_range_type (type, stream, 1 /* bounds_prefered_p */); } } break; @@ -831,7 +909,7 @@ ada_print_type (struct type *type0, const char *varstring, else { fprintf_filtered (stream, "range "); - print_range (type, stream); + print_range (type, stream, 1 /* bounds_prefered_p */); } break; case TYPE_CODE_FLT: