* 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.
This commit is contained in:
Ken Werner 2010-11-03 14:21:58 +00:00
parent 27dee630aa
commit dbc98a8b6e
12 changed files with 127 additions and 96 deletions

View 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> 2010-11-03 Ken Werner <ken.werner@de.ibm.com>
* valarith.c (value_pos, value_neg, value_complement): Handle * valarith.c (value_pos, value_neg, value_complement): Handle

View file

@ -572,19 +572,20 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
if (passed_a_ptr) {
fprintf_filtered (stream, ")"); LONGEST low_bound, high_bound;
fprintf_filtered (stream, "["); if (passed_a_ptr)
if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 fprintf_filtered (stream, ")");
&& !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
fprintf_filtered (stream, "%d",
(TYPE_LENGTH (type)
/ TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
fprintf_filtered (stream, "]");
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, fprintf_filtered (stream, "[");
0, 0); 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; break;
case TYPE_CODE_MEMBERPTR: case TYPE_CODE_MEMBERPTR:

View file

@ -171,8 +171,13 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
elttype = check_typedef (unresolved_elttype); elttype = check_typedef (unresolved_elttype);
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) 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); eltlen = TYPE_LENGTH (elttype);
len = TYPE_LENGTH (type) / eltlen; len = high_bound - low_bound + 1;
if (options->prettyprint_arrays) if (options->prettyprint_arrays)
{ {
print_spaces_filtered (2 + 2 * recurse, stream); print_spaces_filtered (2 + 2 * recurse, stream);

View file

@ -7194,6 +7194,19 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
if (attr) if (attr)
make_vector_type (type); 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); name = dwarf2_name (die, cu);
if (name) if (name)
TYPE_NAME (type) = name; TYPE_NAME (type) = name;

View 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 /* Create an array type using either a blank type supplied in
RESULT_TYPE, or creating a new type, inheriting the objfile from RESULT_TYPE, or creating a new type, inheriting the objfile from
RANGE_TYPE. RANGE_TYPE.

View 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_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 class_types_same_p (const struct type *, const struct type *);
extern int is_ancestor (struct type *, struct type *); extern int is_ancestor (struct type *, struct type *);

View 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> 2010-11-03 Ken Werner <ken.werner@de.ibm.com>
* gdb.base/gnu_vector.exp: Add unary operator tests. * gdb.base/gnu_vector.exp: Add unary operator tests.

View 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 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 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 + 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 i4a + i2" "Cannot perform operation on vectors with different types"
gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different sizes" 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 sizes" 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 sizes" gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"

View file

@ -1394,7 +1394,8 @@ vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
{ {
struct value *val, *tmp, *mark; struct value *val, *tmp, *mark;
struct type *type1, *type2, *eltype1, *eltype2, *result_type; 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)); type1 = check_typedef (value_type (val1));
type2 = check_typedef (value_type (val2)); 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) if (!t1_is_vec || !t2_is_vec)
error (_("Vector operations are only supported among vectors")); 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)); eltype1 = check_typedef (TYPE_TARGET_TYPE (type1));
eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)); eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
elsize = TYPE_LENGTH (eltype1);
if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2) if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
|| TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) || elsize != TYPE_LENGTH (eltype2)
|| TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)) || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
|| low_bound1 != low_bound2 || high_bound1 != high_bound2)
error (_("Cannot perform operation on vectors with different types")); 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); val = allocate_value (type1);
mark = value_mark (); 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), tmp = value_binop (value_subscript (val1, i),
value_subscript (val2, i), op); value_subscript (val2, i), op);

View file

@ -544,14 +544,17 @@ value_cast (struct type *type, struct value *arg2)
/* Widen the scalar to a vector. */ /* Widen the scalar to a vector. */
struct type *eltype; struct type *eltype;
struct value *val; 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)); eltype = check_typedef (TYPE_TARGET_TYPE (type));
arg2 = value_cast (eltype, arg2); arg2 = value_cast (eltype, arg2);
val = allocate_value (type); 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. */ /* Duplicate the contents of arg2 into the destination vector. */
memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)), memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),

View 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 /* Print on STREAM using the given OPTIONS the index for the element
at INDEX of an array whose index type is INDEX_TYPE. */ 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; unsigned int rep1;
/* Number of repetitions we have detected so far. */ /* Number of repetitions we have detected so far. */
unsigned int reps; unsigned int reps;
LONGEST low_bound_index = 0; LONGEST low_bound, high_bound;
elttype = TYPE_TARGET_TYPE (type); elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (check_typedef (elttype)); eltlen = TYPE_LENGTH (check_typedef (elttype));
index_type = TYPE_INDEX_TYPE (type); index_type = TYPE_INDEX_TYPE (type);
/* Compute the number of elements in the array. On most arrays, if (get_array_bounds (type, &low_bound, &high_bound))
the size of its elements is not zero, and so the number of elements len = high_bound - low_bound + 1;
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 else
{ {
LONGEST low, hi; warning (_("unable to get bounds of array, assuming null array"));
low_bound = 0;
if (get_array_bounds (type, &low, &hi)) len = 0;
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;
} }
annotate_array_section_begin (i, elttype); 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)); 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); stream, options);
rep1 = i + 1; rep1 = i + 1;

View 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, extern void get_formatted_print_options (struct value_print_options *opts,
char format); 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, extern void maybe_print_array_index (struct type *index_type, LONGEST index,
struct ui_file *stream, struct ui_file *stream,
const struct value_print_options *options); const struct value_print_options *options);