diff options
-rw-r--r-- | gdb/ChangeLog | 18 | ||||
-rw-r--r-- | gdb/ada-valprint.c | 153 | ||||
-rw-r--r-- | gdb/valprint.c | 68 | ||||
-rw-r--r-- | gdb/valprint.h | 3 |
4 files changed, 152 insertions, 90 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0010275..ee7cb56 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2008-05-23 Joel Brobecker <brobecker@adacore.com> + + * valprint.h (get_array_bounds): Renames get_array_low_bound. + * valprint.c (get_array_bounds): Renames get_array_low_bound. + Return the proper bound value if the array index type is an + enumerated type. Compute the high bound if requested. + (val_print_array_elements): Handle the case when the array + element has a null size. + * ada-valprint.c (print_optional_low_bound): Add handling + for empty arrays or arrays of zero-size elements. + (ada_val_print_array): New function, extracted out from + ada_val_print_1 case TYPE_CODE_ARRAY, and enhanced to + handle empty arrays and arrays of zero-size elements. + (ada_val_print_1)[case TYPE_CODE_ARRAY]: Replace extracted-out + code by call to ada_val_print_array. + (ada_value_print): Remove handling of null array. The handling + was incomplete and is now better handled by ada_val_print_array. + 2008-05-23 Markus Deuling <deuling@de.ibm.com> * annotate.c (annotate_source, annotate_frame_begin): Replace diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c index a94bcd1..f09df20 100644 --- a/gdb/ada-valprint.c +++ b/gdb/ada-valprint.c @@ -74,21 +74,28 @@ adjust_type_signedness (struct type *type) TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; } -/* Assuming TYPE is a simple, non-empty array type, prints its lower bound - on STREAM, if non-standard (i.e., other than 1 for numbers, other - than lower bound of index type for enumerated type). Returns 1 - if something printed, otherwise 0. */ +/* Assuming TYPE is a simple array type, prints its lower bound on STREAM, + if non-standard (i.e., other than 1 for numbers, other than lower bound + of index type for enumerated type). Returns 1 if something printed, + otherwise 0. */ static int print_optional_low_bound (struct ui_file *stream, struct type *type) { struct type *index_type; long low_bound; + long high_bound; if (print_array_indexes_p ()) return 0; - if (!get_array_low_bound (type, &low_bound)) + if (!get_array_bounds (type, &low_bound, &high_bound)) + return 0; + + /* If this is an empty array, then don't print the lower bound. + That would be confusing, because we would print the lower bound, + followed by... nothing! */ + if (low_bound > high_bound) return 0; index_type = TYPE_INDEX_TYPE (type); @@ -586,8 +593,73 @@ ada_val_print_stub (void *args0) argsp->recurse, argsp->pretty); } +/* Assuming TYPE is a simple array, print the value of this array located + at VALADDR. See ada_val_print for a description of the various + parameters of this function; they are identical. The semantics + of the return value is also identical to ada_val_print. */ + +static int +ada_val_print_array (struct type *type, const gdb_byte *valaddr, + CORE_ADDR address, struct ui_file *stream, int format, + int deref_ref, int recurse, enum val_prettyprint pretty) +{ + struct type *elttype = TYPE_TARGET_TYPE (type); + unsigned int eltlen; + unsigned int len; + int result = 0; + + if (elttype == NULL) + eltlen = 0; + else + eltlen = TYPE_LENGTH (elttype); + if (eltlen == 0) + len = 0; + else + len = TYPE_LENGTH (type) / eltlen; + + /* For an array of chars, print with string syntax. */ + if (ada_is_string_type (type) && (format == 0 || format == 's')) + { + if (prettyprint_arrays) + print_spaces_filtered (2 + 2 * recurse, stream); + + /* If requested, look for the first null char and only print + elements up to it. */ + if (stop_print_at_null) + { + int temp_len; + + /* Look for a NULL char. */ + for (temp_len = 0; + (temp_len < len + && temp_len < print_max + && char_at (valaddr, temp_len, eltlen) != 0); + temp_len += 1); + len = temp_len; + } + + printstr (stream, valaddr, len, 0, eltlen); + result = len; + } + else + { + fprintf_filtered (stream, "("); + print_optional_low_bound (stream, type); + if (TYPE_FIELD_BITSIZE (type, 0) > 0) + val_print_packed_array_elements (type, valaddr, 0, stream, + format, recurse, pretty); + else + val_print_array_elements (type, valaddr, address, stream, + format, deref_ref, recurse, + pretty, 0); + fprintf_filtered (stream, ")"); + } + + return result; +} + /* See the comment on ada_val_print. This function differs in that it - * does not catch evaluation errors (leaving that to ada_val_print). */ + does not catch evaluation errors (leaving that to ada_val_print). */ static int ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, @@ -802,57 +874,8 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, } case TYPE_CODE_ARRAY: - elttype = TYPE_TARGET_TYPE (type); - if (elttype == NULL) - eltlen = 0; - else - eltlen = TYPE_LENGTH (elttype); - /* FIXME: This doesn't deal with non-empty arrays of - 0-length items (not a typical case!) */ - if (eltlen == 0) - len = 0; - else - len = TYPE_LENGTH (type) / eltlen; - - /* For an array of chars, print with string syntax. */ - if (ada_is_string_type (type) && (format == 0 || format == 's')) - { - if (prettyprint_arrays) - { - print_spaces_filtered (2 + 2 * recurse, stream); - } - /* If requested, look for the first null char and only print - elements up to it. */ - if (stop_print_at_null) - { - int temp_len; - - /* Look for a NULL char. */ - for (temp_len = 0; - temp_len < len && temp_len < print_max - && char_at (valaddr, temp_len, eltlen) != 0; - temp_len += 1); - len = temp_len; - } - - printstr (stream, valaddr, len, 0, eltlen); - } - else - { - len = 0; - fprintf_filtered (stream, "("); - print_optional_low_bound (stream, type); - if (TYPE_FIELD_BITSIZE (type, 0) > 0) - val_print_packed_array_elements (type, valaddr, 0, stream, - format, recurse, pretty); - else - val_print_array_elements (type, valaddr, address, stream, - format, deref_ref, recurse, - pretty, 0); - fprintf_filtered (stream, ")"); - } - gdb_flush (stream); - return len; + return ada_val_print_array (type, valaddr, address, stream, format, + deref_ref, recurse, pretty); case TYPE_CODE_REF: /* For references, the debugger is expected to print the value as @@ -949,22 +972,6 @@ ada_value_print (struct value *val0, struct ui_file *stream, int format, return 0; } - if (TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == 0 - && TYPE_CODE (TYPE_INDEX_TYPE (type)) == TYPE_CODE_RANGE) - { - /* This is an array of zero-length elements, that is an array - of null records. This array needs to be printed by hand, - as the standard routine to print arrays relies on the size of - the array elements to be nonzero. This is because it computes - the number of elements in the array by dividing the array size - by the array element size. */ - fprintf_filtered (stream, "(%d .. %d => ())", - TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)), - TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (type))); - return 0; - } - return (val_print (type, value_contents (val), 0, address, stream, format, 1, 0, pretty, current_language)); } diff --git a/gdb/valprint.c b/gdb/valprint.c index 5b00b30..99c376f 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -937,43 +937,61 @@ print_array_indexes_p (void) return print_array_indexes; } -/* Assuming TYPE is a simple, non-empty array type, compute its lower bound. - Save it into LOW_BOUND if not NULL. +/* Assuming TYPE is a simple, non-empty array type, compute its upper + and lower bound. Save the low bound into LOW_BOUND if not NULL. + Save the high bound into HIGH_BOUND if not NULL. Return 1 if the operation was successful. Return zero otherwise, - in which case the value of LOW_BOUND is unmodified. + in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified. - Computing the array lower bound is pretty easy, but this function - does some additional verifications before returning the low bound. + Computing the array upper and lower bounds is pretty easy, but this + function does some additional verifications before returning them. If something incorrect is detected, it is better to return a status rather than throwing an error, making it easier for the caller to implement an error-recovery plan. For instance, it may decide to - warn the user that the bound was not found and then use a default - value instead. */ + warn the user that the bounds were not found and then use some + default values instead. */ int -get_array_low_bound (struct type *type, long *low_bound) +get_array_bounds (struct type *type, long *low_bound, long *high_bound) { struct type *index = TYPE_INDEX_TYPE (type); long low = 0; + long high = 0; if (index == NULL) return 0; - if (TYPE_CODE (index) != TYPE_CODE_RANGE - && TYPE_CODE (index) != TYPE_CODE_ENUM) + if (TYPE_CODE (index) == TYPE_CODE_RANGE) + { + low = TYPE_LOW_BOUND (index); + high = TYPE_HIGH_BOUND (index); + } + else if (TYPE_CODE (index) == TYPE_CODE_ENUM) + { + const int n_enums = TYPE_NFIELDS (index); + + low = TYPE_FIELD_BITPOS (index, 0); + high = TYPE_FIELD_BITPOS (index, n_enums - 1); + } + else return 0; - low = TYPE_LOW_BOUND (index); - if (low > TYPE_HIGH_BOUND (index)) + /* Abort if the lower bound is greater than the higher bound, except + when low = high + 1. This is a very common idiom used in Ada when + defining empty ranges (for instance "range 1 .. 0"). */ + if (low > high + 1) return 0; if (low_bound) *low_bound = low; + if (high_bound) + *high_bound = high; + return 1; } - + /* Print on STREAM using the given FORMAT the index for the element at INDEX of an array whose index type is INDEX_TYPE. */ @@ -1021,14 +1039,32 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, elttype = TYPE_TARGET_TYPE (type); eltlen = TYPE_LENGTH (check_typedef (elttype)); - len = TYPE_LENGTH (type) / eltlen; index_type = TYPE_INDEX_TYPE (type); + /* Compute the number of elements in the array. On most arrays, + the size of its elements is not zero, and so the number of elements + is simply the size of the array divided by the size of the elements. + But for arrays of elements whose size is zero, we need to look at + the bounds. */ + if (eltlen != 0) + len = TYPE_LENGTH (type) / eltlen; + else + { + long low, hi; + if (get_array_bounds (type, &low, &hi)) + len = hi - low + 1; + else + { + warning (_("unable to get bounds of array, assuming null array")); + len = 0; + } + } + /* Get the array low bound. This only makes sense if the array has one or more element in it. */ - if (len > 0 && !get_array_low_bound (type, &low_bound_index)) + if (len > 0 && !get_array_bounds (type, &low_bound_index, NULL)) { - warning ("unable to get low bound of array, using zero as default"); + warning (_("unable to get low bound of array, using zero as default")); low_bound_index = 0; } diff --git a/gdb/valprint.h b/gdb/valprint.h index 669f59d..3b20516 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -50,7 +50,8 @@ extern int stop_print_at_null; /* Stop printing at null char? */ extern int print_array_indexes_p (void); -extern int get_array_low_bound (struct type *type, long *low_bound); +extern int get_array_bounds (struct type *type, long *low_bound, + long *high_bound); extern void maybe_print_array_index (struct type *index_type, LONGEST index, struct ui_file *stream, int format, |