mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
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
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 *);
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)),
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user