* 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.
This commit is contained in:
Joel Brobecker 2008-05-23 18:13:35 +00:00
parent 133d72e995
commit e936309cee
4 changed files with 152 additions and 90 deletions

View File

@ -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

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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,