aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog18
-rw-r--r--gdb/ada-valprint.c153
-rw-r--r--gdb/valprint.c68
-rw-r--r--gdb/valprint.h3
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,