aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/c-typeprint.c23
-rw-r--r--gdb/c-valprint.c7
-rw-r--r--gdb/dwarf2read.c13
-rw-r--r--gdb/gdbtypes.c44
-rw-r--r--gdb/gdbtypes.h3
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.base/gnu_vector.exp8
-rw-r--r--gdb/valarith.c21
-rw-r--r--gdb/valops.c9
-rw-r--r--gdb/valprint.c71
-rw-r--r--gdb/valprint.h3
12 files changed, 127 insertions, 96 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 93817ec..719582b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,22 @@
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
vector types.
* valops.c (value_one): Likewise.
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 87f7b0d..04f8127 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 bc524bd..20ac633 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 e613d90..a91f14a 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 d08dbfe..3306e23 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 5617a1d..e66f538 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 c062b02..cc60e46 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
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.
2010-11-03 Ken Werner <ken.werner@de.ibm.com>
diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp
index 870b563..dbae9bb 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 f6e3a05..7c553d1 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 22ba54a..e98f7c1 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 09da426..dba528b 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 6e339d1..ffb823a 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);