* 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>
* 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))
{
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:

View 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);

View 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;

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
RESULT_TYPE, or creating a new type, inheriting the objfile from
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_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 *);

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>
* 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 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"

View 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);

View 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)),

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
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;

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,
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);