bfd:
[deliverable/binutils-gdb.git] / gdb / valprint.c
index 3bab21edd9d6044ab6eb70a780894dec691e7dcf..99c376f47b9807127492ce199a29c5c5beaae3c6 100644 (file)
@@ -313,6 +313,8 @@ void
 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;
@@ -330,7 +332,7 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
             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
@@ -525,7 +527,7 @@ print_decimal_floating (const gdb_byte *valaddr, struct type *type,
 
 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
@@ -541,7 +543,7 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
 
   /* 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;
@@ -585,7 +587,7 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
  */
 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;
@@ -628,7 +630,7 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
   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;
@@ -733,19 +735,12 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
  */
 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)
 
@@ -782,9 +777,9 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
    * 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.
@@ -814,7 +809,10 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
          /* 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;
        }
 
@@ -868,14 +866,14 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 
 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;
@@ -900,11 +898,11 @@ print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
 
 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)
@@ -939,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.  */
     
@@ -1023,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;
     }
 
This page took 0.027484 seconds and 4 git commands to generate.