gdb:
* 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:
parent
27dee630aa
commit
dbc98a8b6e
12 changed files with 127 additions and 96 deletions
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue