val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
struct ui_file *stream)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (current_gdbarch);
+
if (TYPE_LENGTH (type) > sizeof (LONGEST))
{
LONGEST val;
complement (a reasonable assumption, I think) and do
better than this. */
print_hex_chars (stream, (unsigned char *) valaddr,
- TYPE_LENGTH (type));
+ TYPE_LENGTH (type), byte_order);
}
}
else
void
print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
- unsigned len)
+ unsigned len, enum bfd_endian byte_order)
{
#define BITS_IN_BYTES 8
/* FIXME: We should be not printing leading zeroes in most cases. */
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = valaddr;
p < valaddr + len;
*/
void
print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
- unsigned len)
+ unsigned len, enum bfd_endian byte_order)
{
const gdb_byte *p;
unsigned char octa1, octa2, octa3, carry;
carry = 0;
fputs_filtered ("0", stream);
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = valaddr;
p < valaddr + len;
*/
void
print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
- unsigned len)
+ unsigned len, enum bfd_endian byte_order)
{
#define TEN 10
-#define TWO_TO_FOURTH 16
#define CARRY_OUT( x ) ((x) / TEN) /* extend char to int */
#define CARRY_LEFT( x ) ((x) % TEN)
#define SHIFT( x ) ((x) << 4)
-#define START_P \
- ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ? valaddr : valaddr + len - 1)
-#define NOT_END_P \
- ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ? (p < valaddr + len) : (p >= valaddr))
-#define NEXT_P \
- ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ? p++ : p-- )
#define LOW_NIBBLE( x ) ( (x) & 0x00F)
#define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4)
* LSD end.
*/
decimal_digits = 0; /* Number of decimal digits so far */
- p = START_P;
+ p = (byte_order == BFD_ENDIAN_BIG) ? valaddr : valaddr + len - 1;
flip = 0;
- while (NOT_END_P)
+ while ((byte_order == BFD_ENDIAN_BIG) ? (p < valaddr + len) : (p >= valaddr))
{
/*
* Multiply current base-ten number by 16 in place.
/* Take low nibble and bump our pointer "p".
*/
digits[0] += LOW_NIBBLE (*p);
- NEXT_P;
+ if (byte_order == BFD_ENDIAN_BIG)
+ p++;
+ else
+ p--;
flip = 0;
}
void
print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
- unsigned len)
+ unsigned len, enum bfd_endian byte_order)
{
const gdb_byte *p;
/* FIXME: We should be not printing leading zeroes in most cases. */
fputs_filtered ("0x", stream);
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = valaddr;
p < valaddr + len;
void
print_char_chars (struct ui_file *stream, const gdb_byte *valaddr,
- unsigned len)
+ unsigned len, enum bfd_endian byte_order)
{
const gdb_byte *p;
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
p = valaddr;
while (p < valaddr + len - 1 && *p == 0)
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. */
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;
}