diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 93817eccee3..719582bfb58 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2010-11-03 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. + 2010-11-03 Ken Werner * valarith.c (value_pos, value_neg, value_complement): Handle diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 87f7b0d3b67..04f8127f2a8 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -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: diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index bc524bd86cc..20ac6336cd2 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -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); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index e613d90c4dd..a91f14a4c93 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -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; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index d08dbfe396c..3306e23f47d 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -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. diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 5617a1d2265..e66f5385b2c 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -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 *); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c062b020e82..cc60e462090 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-11-03 Ken Werner + + * gdb.base/gnu_vector.exp: Adjust expect messages. + 2010-11-03 Ken Werner * gdb.base/gnu_vector.exp: Add unary operator tests. diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp index 870b563dce8..dbae9bbcc5e 100644 --- a/gdb/testsuite/gdb.base/gnu_vector.exp +++ b/gdb/testsuite/gdb.base/gnu_vector.exp @@ -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" diff --git a/gdb/valarith.c b/gdb/valarith.c index f6e3a057242..7c553d1ca4a 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -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); diff --git a/gdb/valops.c b/gdb/valops.c index 22ba54a0075..e98f7c14139 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -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)), diff --git a/gdb/valprint.c b/gdb/valprint.c index 09da426b76b..dba528bdf66 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -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; diff --git a/gdb/valprint.h b/gdb/valprint.h index 6e339d11c5f..ffb823acf56 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -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);