ChangeLog: 2010-10-19 Ken Werner * 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. testsuite/ChangeLog: 2010-10-19 Ken Werner * gdb.base/gnu_vector.exp: Adjust expect messages. Index: gdb/c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.74 diff -p -u -r1.74 c-valprint.c --- gdb/c-valprint.c 15 Oct 2010 18:54:12 -0000 1.74 +++ gdb/c-valprint.c 19 Oct 2010 12:15:30 -0000 @@ -171,8 +171,13 @@ c_val_print (struct type *type, const gd 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: gdb/dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.472 diff -p -u -r1.472 dwarf2read.c --- gdb/dwarf2read.c 17 Oct 2010 18:49:46 -0000 1.472 +++ gdb/dwarf2read.c 19 Oct 2010 12:15:31 -0000 @@ -7194,6 +7194,19 @@ read_array_type (struct die_info *die, s 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: gdb/gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.203 diff -p -u -r1.203 gdbtypes.c --- gdb/gdbtypes.c 15 Oct 2010 17:48:47 -0000 1.203 +++ gdb/gdbtypes.c 19 Oct 2010 12:15:31 -0000 @@ -802,6 +802,50 @@ get_discrete_bounds (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; + + /* 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: gdb/gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.137 diff -p -u -r1.137 gdbtypes.h --- gdb/gdbtypes.h 15 Oct 2010 17:48:47 -0000 1.137 +++ gdb/gdbtypes.h 19 Oct 2010 12:15:31 -0000 @@ -1383,6 +1383,9 @@ extern int get_vptr_fieldno (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: gdb/valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.87 diff -p -u -r1.87 valarith.c --- gdb/valarith.c 8 Oct 2010 16:50:53 -0000 1.87 +++ gdb/valarith.c 19 Oct 2010 12:15:31 -0000 @@ -1388,7 +1388,8 @@ vector_binop (struct value *val1, struct { 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)); @@ -1401,23 +1402,23 @@ vector_binop (struct value *val1, struct 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: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.252 diff -p -u -r1.252 valops.c --- gdb/valops.c 8 Oct 2010 16:50:53 -0000 1.252 +++ gdb/valops.c 19 Oct 2010 12:15:32 -0000 @@ -543,14 +543,17 @@ value_cast (struct type *type, struct va /* 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: gdb/valprint.c =================================================================== RCS file: /cvs/src/src/gdb/valprint.c,v retrieving revision 1.97 diff -p -u -r1.97 valprint.c --- gdb/valprint.c 18 Oct 2010 19:14:02 -0000 1.97 +++ gdb/valprint.c 19 Oct 2010 12:15:32 -0000 @@ -1067,44 +1067,6 @@ print_char_chars (struct ui_file *stream } } -/* 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 *t 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 *t } } 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: gdb/valprint.h =================================================================== RCS file: /cvs/src/src/gdb/valprint.h,v retrieving revision 1.27 diff -p -u -r1.27 valprint.h --- gdb/valprint.h 11 Jun 2010 15:36:05 -0000 1.27 +++ gdb/valprint.h 19 Oct 2010 12:15:32 -0000 @@ -109,9 +109,6 @@ extern void get_raw_print_options (struc 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); Index: gdb/testsuite/gdb.base/gnu_vector.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v retrieving revision 1.3 diff -p -u -r1.3 gnu_vector.exp --- gdb/testsuite/gdb.base/gnu_vector.exp 8 Oct 2010 16:50:55 -0000 1.3 +++ gdb/testsuite/gdb.base/gnu_vector.exp 19 Oct 2010 12:15:32 -0000 @@ -119,8 +119,8 @@ gdb_test "print f4a + d2" "Cannot perfor 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: gdb/c-typeprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-typeprint.c,v retrieving revision 1.63 diff -p -u -r1.63 c-typeprint.c --- gdb/c-typeprint.c 19 Oct 2010 04:22:20 -0000 1.63 +++ gdb/c-typeprint.c 19 Oct 2010 17:52:38 -0000 @@ -572,19 +572,20 @@ c_type_print_varspec_suffix (struct type 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: