mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-28 22:40:24 +00:00
* 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:
parent
133d72e995
commit
e936309cee
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user