bfd:
[deliverable/binutils-gdb.git] / gdb / valprint.c
index eb3ad35be5d01b2e25ba428ad0c38203933ed60c..99c376f47b9807127492ce199a29c5c5beaae3c6 100644 (file)
@@ -180,9 +180,10 @@ show_addressprint (struct ui_file *file, int from_tty,
 }
 \f
 
-/* Print data of type TYPE located at VALADDR (within GDB), which came from
-   the inferior at address ADDRESS, onto stdio stream STREAM according to
-   FORMAT (a letter, or 0 for natural format using TYPE).
+/* Print using the given LANGUAGE the data of type TYPE located at VALADDR
+   (within GDB), which came from the inferior at address ADDRESS, onto
+   stdio stream STREAM according to FORMAT (a letter, or 0 for natural
+   format using TYPE).
 
    If DEREF_REF is nonzero, then dereference references, otherwise just print
    them like pointers.
@@ -203,7 +204,8 @@ show_addressprint (struct ui_file *file, int from_tty,
 int
 val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
           CORE_ADDR address, struct ui_file *stream, int format,
-          int deref_ref, int recurse, enum val_prettyprint pretty)
+          int deref_ref, int recurse, enum val_prettyprint pretty,
+          const struct language_defn *language)
 {
   volatile struct gdb_exception except;
   volatile enum val_prettyprint real_pretty = pretty;
@@ -228,8 +230,9 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
 
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
-      ret = LA_VAL_PRINT (type, valaddr, embedded_offset, address,
-                         stream, format, deref_ref, recurse, real_pretty);
+      ret = language->la_val_print (type, valaddr, embedded_offset, address,
+                                   stream, format, deref_ref, recurse,
+                                   real_pretty);
     }
   if (except.reason < 0)
     fprintf_filtered (stream, _("<error reading variable>"));
@@ -259,8 +262,8 @@ value_check_printable (struct value *val, struct ui_file *stream)
   return 1;
 }
 
-/* Print the value VAL onto stream STREAM according to FORMAT (a
-   letter, or 0 for natural format using TYPE).
+/* Print using the given LANGUAGE the value VAL onto stream STREAM according
+   to FORMAT (a letter, or 0 for natural format using TYPE).
 
    If DEREF_REF is nonzero, then dereference references, otherwise just print
    them like pointers.
@@ -275,14 +278,16 @@ value_check_printable (struct value *val, struct ui_file *stream)
 
 int
 common_val_print (struct value *val, struct ui_file *stream, int format,
-                 int deref_ref, int recurse, enum val_prettyprint pretty)
+                 int deref_ref, int recurse, enum val_prettyprint pretty,
+                 const struct language_defn *language)
 {
   if (!value_check_printable (val, stream))
     return 0;
 
   return val_print (value_type (val), value_contents_all (val),
                    value_embedded_offset (val), VALUE_ADDRESS (val),
-                   stream, format, deref_ref, recurse, pretty);
+                   stream, format, deref_ref, recurse, pretty,
+                   language);
 }
 
 /* Print the value VAL in C-ish syntax on stream STREAM.
@@ -308,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;
@@ -325,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
@@ -520,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
@@ -536,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;
@@ -580,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;
@@ -623,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;
@@ -728,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)
 
@@ -777,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.
@@ -809,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;
        }
 
@@ -863,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;
@@ -895,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)
@@ -934,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.  */
     
@@ -1018,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;
     }
 
@@ -1061,7 +1100,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
       if (reps > repeat_count_threshold)
        {
          val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
-                    deref_ref, recurse + 1, pretty);
+                    deref_ref, recurse + 1, pretty, current_language);
          annotate_elt_rep (reps);
          fprintf_filtered (stream, " <repeats %u times>", reps);
          annotate_elt_rep_end ();
@@ -1072,7 +1111,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
       else
        {
          val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
-                    deref_ref, recurse + 1, pretty);
+                    deref_ref, recurse + 1, pretty, current_language);
          annotate_elt ();
          things_printed++;
        }
This page took 0.031767 seconds and 4 git commands to generate.