gdb:
authorKen Werner <ken.werner@de.ibm.com>
Wed, 3 Nov 2010 14:21:58 +0000 (14:21 +0000)
committerKen Werner <ken.werner@de.ibm.com>
Wed, 3 Nov 2010 14:21:58 +0000 (14:21 +0000)
* dwarf2read.c (read_array_type): Read the DW_AT_byte_size from the
DIE and set the length of the type.
* gdbtypes.h (get_array_bounds): Move here from valprint.h.
* gdbtypes.c (get_array_bounds): Move here from valprint.c and
return 0 if the corresponding bounds of the type are undefined.
* valprint.h (get_array_bounds): Move declaration to gdbtypes.h.
* valprint.c (get_array_bounds): Move implementation to gdbtypes.c.
(val_print_array_elements): Use get_array_bounds to compute the number
of array elements instead of dividing the length of the array by the
length of the element types.
* valarith.c (vector_binop): Likewise.
* valops.c (value_cast): Likewise.
* c-valprint.c (c_val_print): Likewise.
* c-typeprint.c (c_type_print_varspec_suffix): Likewise.

gdb/testsuite:
* gdb.base/gnu_vector.exp: Adjust expect messages.

12 files changed:
gdb/ChangeLog
gdb/c-typeprint.c
gdb/c-valprint.c
gdb/dwarf2read.c
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/gnu_vector.exp
gdb/valarith.c
gdb/valops.c
gdb/valprint.c
gdb/valprint.h

index 93817eccee3d6e5b3b56d3d4f2a6d602931ce19f..719582bfb58c5e1ea6588c301f92aff1c6b23950 100644 (file)
@@ -1,3 +1,20 @@
+2010-11-03  Ken Werner  <ken.werner@de.ibm.com>
+
+       * dwarf2read.c (read_array_type): Read the DW_AT_byte_size from the
+       DIE and set the length of the type.
+       * gdbtypes.h (get_array_bounds): Move here from valprint.h.
+       * gdbtypes.c (get_array_bounds): Move here from valprint.c and
+       return 0 if the corresponding bounds of the type are undefined.
+       * valprint.h (get_array_bounds): Move declaration to gdbtypes.h.
+       * valprint.c (get_array_bounds): Move implementation to gdbtypes.c.
+       (val_print_array_elements): Use get_array_bounds to compute the number
+       of array elements instead of dividing the length of the array by the
+       length of the element types.
+       * valarith.c (vector_binop): Likewise.
+       * valops.c (value_cast): Likewise.
+       * c-valprint.c (c_val_print): Likewise.
+       * c-typeprint.c (c_type_print_varspec_suffix): Likewise.
+
 2010-11-03  Ken Werner  <ken.werner@de.ibm.com>
 
        * valarith.c (value_pos, value_neg, value_complement): Handle
index 87f7b0d3b6795fac2e8ddf1a0709ad5059a48130..04f8127f2a8cea8f69a327a04611d6c9b31e4fe2 100644 (file)
@@ -572,19 +572,20 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_ARRAY:
-      if (passed_a_ptr)
-       fprintf_filtered (stream, ")");
+      {
+       LONGEST low_bound, high_bound;
 
-      fprintf_filtered (stream, "[");
-      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
-       && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
-       fprintf_filtered (stream, "%d",
-                         (TYPE_LENGTH (type)
-                          / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
-      fprintf_filtered (stream, "]");
+       if (passed_a_ptr)
+         fprintf_filtered (stream, ")");
 
-      c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
-                                  0, 0);
+       fprintf_filtered (stream, "[");
+       if (get_array_bounds (type, &low_bound, &high_bound))
+         fprintf_filtered (stream, "%d", (int) (high_bound - low_bound + 1));
+       fprintf_filtered (stream, "]");
+
+       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
+                                    0, 0);
+      }
       break;
 
     case TYPE_CODE_MEMBERPTR:
index bc524bd86cc43a2de5c19877bb3efe268028eb13..20ac6336cd20f2a5a9fb9761f06b00bb8c700ec9 100644 (file)
@@ -171,8 +171,13 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
       elttype = check_typedef (unresolved_elttype);
       if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0)
        {
+          LONGEST low_bound, high_bound;
+
+          if (!get_array_bounds (type, &low_bound, &high_bound))
+            error (_("Could not determine the array high bound"));
+
          eltlen = TYPE_LENGTH (elttype);
-         len = TYPE_LENGTH (type) / eltlen;
+         len = high_bound - low_bound + 1;
          if (options->prettyprint_arrays)
            {
              print_spaces_filtered (2 + 2 * recurse, stream);
index e613d90c4dd08d35014c9bc23390f99fe6922b54..a91f14a4c9373b5f1c0e3ad0b1e957711c38a184 100644 (file)
@@ -7194,6 +7194,19 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   if (attr)
     make_vector_type (type);
 
+  /* The DIE may have DW_AT_byte_size set.  For example an OpenCL
+     implementation may choose to implement triple vectors using this
+     attribute.  */
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+  if (attr)
+    {
+      if (DW_UNSND (attr) >= TYPE_LENGTH (type))
+       TYPE_LENGTH (type) = DW_UNSND (attr);
+      else
+       complaint (&symfile_complaints, _("\
+DW_AT_byte_size for array type smaller than the total size of elements"));
+    }
+
   name = dwarf2_name (die, cu);
   if (name)
     TYPE_NAME (type) = name;
index d08dbfe396c1e034aaa5946118fd9167ff3733ad..3306e23f47d056bf653b168b2515218209496e4f 100644 (file)
@@ -802,6 +802,50 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
     }
 }
 
+/* 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 values of LOW_BOUND and HIGH_BOUNDS are unmodified.
+
+   We now simply use get_discrete_bounds call to get the values
+   of the low and high bounds.
+   get_discrete_bounds can return three values:
+   1, meaning that index is a range,
+   0, meaning that index is a discrete type,
+   or -1 for failure.  */
+
+int
+get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
+{
+  struct type *index = TYPE_INDEX_TYPE (type);
+  LONGEST low = 0;
+  LONGEST high = 0;
+  int res;
+
+  if (index == NULL)
+    return 0;
+
+  res = get_discrete_bounds (index, &low, &high);
+  if (res == -1)
+    return 0;
+
+  /* Check if the array bounds are undefined.  */
+  if (res == 1
+      && ((low_bound && TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type))
+         || (high_bound && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))))
+    return 0;
+
+  if (low_bound)
+    *low_bound = low;
+
+  if (high_bound)
+    *high_bound = high;
+
+  return 1;
+}
+
 /* Create an array type using either a blank type supplied in
    RESULT_TYPE, or creating a new type, inheriting the objfile from
    RANGE_TYPE.
index 5617a1d2265586f63c75cc434db2fde9759c1de6..e66f5385b2c247696899ab47b0176c38cf886420 100644 (file)
@@ -1383,6 +1383,9 @@ extern int get_vptr_fieldno (struct type *, struct type **);
 
 extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *);
 
+extern int get_array_bounds (struct type *type, LONGEST *low_bound,
+                            LONGEST *high_bound);
+
 extern int class_types_same_p (const struct type *, const struct type *);
 
 extern int is_ancestor (struct type *, struct type *);
index c062b020e82c5cec8be736efba2bd92462f1eb63..cc60e462090a17e8a5041ee09a182d4d6f881b68 100644 (file)
@@ -1,3 +1,7 @@
+2010-11-03  Ken Werner  <ken.werner@de.ibm.com>
+
+       * gdb.base/gnu_vector.exp: Adjust expect messages.
+
 2010-11-03  Ken Werner  <ken.werner@de.ibm.com>
 
        * gdb.base/gnu_vector.exp: Add unary operator tests.
index 870b563dce8d0409ad9f7f46e42bb390cead8aa8..dbae9bbcc5e1035b32d82e9ae5d7ee49968b11b2 100644 (file)
@@ -129,8 +129,8 @@ gdb_test "print f4a + d2" "Cannot perform operation on vectors with different ty
 gdb_test "print d2 + f4a" "Cannot perform operation on vectors with different types"
 gdb_test "print ui4 + i4a" "Cannot perform operation on vectors with different types"
 gdb_test "print i4a + ui4" "Cannot perform operation on vectors with different types"
-gdb_test "print i4a + i2" "Cannot perform operation on vectors with different sizes"
-gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different sizes"
-gdb_test "print f4a + f2" "Cannot perform operation on vectors with different sizes"
-gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different sizes"
+gdb_test "print i4a + i2" "Cannot perform operation on vectors with different types"
+gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different types"
+gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
+gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
 
index f6e3a0572429ee819b3421fd7473d8b802fa6452..7c553d1ca4a2db618b5932dafa6ad6ac43a9ac2a 100644 (file)
@@ -1394,7 +1394,8 @@ vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
 {
   struct value *val, *tmp, *mark;
   struct type *type1, *type2, *eltype1, *eltype2, *result_type;
-  int t1_is_vec, t2_is_vec, elsize, n, i;
+  int t1_is_vec, t2_is_vec, elsize, i;
+  LONGEST low_bound1, high_bound1, low_bound2, high_bound2;
 
   type1 = check_typedef (value_type (val1));
   type2 = check_typedef (value_type (val2));
@@ -1407,23 +1408,23 @@ vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
   if (!t1_is_vec || !t2_is_vec)
     error (_("Vector operations are only supported among vectors"));
 
+  if (!get_array_bounds (type1, &low_bound1, &high_bound1)
+      || !get_array_bounds (type2, &low_bound2, &high_bound2))
+    error (_("Could not determine the vector bounds"));
+
   eltype1 = check_typedef (TYPE_TARGET_TYPE (type1));
   eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
+  elsize = TYPE_LENGTH (eltype1);
 
   if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
-      || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
-      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2))
+      || elsize != TYPE_LENGTH (eltype2)
+      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
+      || low_bound1 != low_bound2 || high_bound1 != high_bound2)
     error (_("Cannot perform operation on vectors with different types"));
 
-  elsize = TYPE_LENGTH (eltype1);
-  n = TYPE_LENGTH (type1) / elsize;
-
-  if (n != TYPE_LENGTH (type2) / TYPE_LENGTH (eltype2))
-    error (_("Cannot perform operation on vectors with different sizes"));
-
   val = allocate_value (type1);
   mark = value_mark ();
-  for (i = 0; i < n; i++)
+  for (i = 0; i < high_bound1 - low_bound1 + 1; i++)
     {
       tmp = value_binop (value_subscript (val1, i),
                         value_subscript (val2, i), op);
index 22ba54a0075cb6fd8704ab2105d8b6938f365b35..e98f7c14139460ed3e3ea94cd431bc6d1ee2354d 100644 (file)
@@ -544,14 +544,17 @@ value_cast (struct type *type, struct value *arg2)
       /* Widen the scalar to a vector.  */
       struct type *eltype;
       struct value *val;
-      int i, n;
+      LONGEST low_bound, high_bound;
+      int i;
+
+      if (!get_array_bounds (type, &low_bound, &high_bound))
+       error (_("Could not determine the vector bounds"));
 
       eltype = check_typedef (TYPE_TARGET_TYPE (type));
       arg2 = value_cast (eltype, arg2);
       val = allocate_value (type);
-      n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
 
-      for (i = 0; i < n; i++)
+      for (i = 0; i < high_bound - low_bound + 1; i++)
        {
          /* Duplicate the contents of arg2 into the destination vector.  */
          memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
index 09da426b76b9f81528eb25253197c3eb68e285d8..dba528bdf66ab739f4662a02e771adb194c081ee 100644 (file)
@@ -1067,44 +1067,6 @@ print_char_chars (struct ui_file *stream, struct type *type,
     }
 }
 
-/* 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 values of LOW_BOUND and HIGH_BOUNDS are unmodified.
-  
-   We now simply use get_discrete_bounds call to get the values
-   of the low and high bounds. 
-   get_discrete_bounds can return three values:
-   1, meaning that index is a range,
-   0, meaning that index is a discrete type,
-   or -1 for failure.  */
-
-int
-get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
-{
-  struct type *index = TYPE_INDEX_TYPE (type);
-  LONGEST low = 0;
-  LONGEST high = 0;
-  int res;
-                                
-  if (index == NULL)
-    return 0;
-
-  res = get_discrete_bounds (index, &low, &high);
-  if (res == -1)
-    return 0;
-
-  if (low_bound)
-    *low_bound = low;
-
-  if (high_bound)
-    *high_bound = high;
-
-  return 1;
-}
-
 /* Print on STREAM using the given OPTIONS the index for the element
    at INDEX of an array whose index type is INDEX_TYPE.  */
     
@@ -1149,38 +1111,19 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
   unsigned int rep1;
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
-  LONGEST low_bound_index = 0;
+  LONGEST low_bound, high_bound;
 
   elttype = TYPE_TARGET_TYPE (type);
   eltlen = TYPE_LENGTH (check_typedef (elttype));
   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;
+  if (get_array_bounds (type, &low_bound, &high_bound))
+    len = high_bound - low_bound + 1;
   else
     {
-      LONGEST 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_bounds (type, &low_bound_index, NULL))
-    {
-      warning (_("unable to get low bound of array, using zero as default"));
-      low_bound_index = 0;
+      warning (_("unable to get bounds of array, assuming null array"));
+      low_bound = 0;
+      len = 0;
     }
 
   annotate_array_section_begin (i, elttype);
@@ -1200,7 +1143,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
            }
        }
       wrap_here (n_spaces (2 + 2 * recurse));
-      maybe_print_array_index (index_type, i + low_bound_index,
+      maybe_print_array_index (index_type, i + low_bound,
                                stream, options);
 
       rep1 = i + 1;
index 6e339d11c5fa9af36f4c2a30b4b90d919ec2ce24..ffb823acf5648c0def5c90a3123eaa3bb924d6b4 100644 (file)
@@ -109,9 +109,6 @@ extern void get_raw_print_options (struct value_print_options *opts);
 extern void get_formatted_print_options (struct value_print_options *opts,
                                         char format);
 
-extern int get_array_bounds (struct type *type, LONGEST *low_bound,
-                            LONGEST *high_bound);
-
 extern void maybe_print_array_index (struct type *index_type, LONGEST index,
                                      struct ui_file *stream,
                                     const struct value_print_options *options);