/* Perform arithmetic and other operations on values, for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
|| tarray->code () == TYPE_CODE_STRING)
{
struct type *range_type = tarray->index_type ();
- LONGEST lowerbound, upperbound;
+ gdb::optional<LONGEST> lowerbound = get_discrete_low_bound (range_type);
+ if (!lowerbound.has_value ())
+ lowerbound = 0;
- get_discrete_bounds (range_type, &lowerbound, &upperbound);
if (VALUE_LVAL (array) != lval_memory)
- return value_subscripted_rvalue (array, index, lowerbound);
+ return value_subscripted_rvalue (array, index, *lowerbound);
if (!c_style)
{
- if (index >= lowerbound && index <= upperbound)
- return value_subscripted_rvalue (array, index, lowerbound);
+ gdb::optional<LONGEST> upperbound
+ = get_discrete_high_bound (range_type);
+
+ if (!upperbound.has_value ())
+ upperbound = 0;
+
+ if (index >= *lowerbound && index <= *upperbound)
+ return value_subscripted_rvalue (array, index, *lowerbound);
+
/* Emit warning unless we have an array of unknown size.
An array of unknown size has lowerbound 0 and upperbound -1. */
- if (upperbound > -1)
+ if (*upperbound > -1)
warning (_("array or string index out of range"));
/* fall doing C stuff */
c_style = true;
}
- index -= lowerbound;
+ index -= *lowerbound;
array = value_coerce_array (array);
}
LONGEST stride = array_type->bit_stride ();
if (stride != 0)
{
- struct gdbarch *arch = get_type_arch (elt_type);
+ struct gdbarch *arch = elt_type->arch ();
int unit_size = gdbarch_addressable_memory_unit_size (arch);
elt_size = stride / (unit_size * 8);
}
noside);
}
else
- result = value_struct_elt (argp, args.data (), name, static_memfuncp,
+ result = value_struct_elt (argp, args, name, static_memfuncp,
"structure");
return result;
struct value *
value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
{
- struct gdbarch *gdbarch = get_type_arch (value_type (arg1));
+ struct gdbarch *gdbarch = value_type (arg1)->arch ();
char *ptr;
char tstr[13], mangle_tstr[13];
int static_memfuncp, nargs;
char_type = type2;
inchar = (char) unpack_long (type2,
- value_contents (inval2));
+ value_contents (inval2).data ());
for (idx = 0; idx < count; idx++)
{
ptr[idx] = inchar;
char_type = TYPE_TARGET_TYPE (type2);
for (idx = 0; idx < count; idx++)
- {
- memcpy (&ptr[idx * inval2len], value_contents (inval2),
- inval2len);
- }
+ memcpy (&ptr[idx * inval2len], value_contents (inval2).data (),
+ inval2len);
}
outval = value_string (ptr.data (), count * inval2len, char_type);
}
{
char_type = type1;
- ptr[0] = (char) unpack_long (type1, value_contents (inval1));
+ ptr[0] = (char) unpack_long (type1, value_contents (inval1).data ());
}
else
{
char_type = TYPE_TARGET_TYPE (type1);
- memcpy (ptr.data (), value_contents (inval1), inval1len);
+ memcpy (ptr.data (), value_contents (inval1).data (), inval1len);
}
if (type2->code () == TYPE_CODE_CHAR)
{
ptr[inval1len] =
- (char) unpack_long (type2, value_contents (inval2));
+ (char) unpack_long (type2, value_contents (inval2).data ());
}
else
{
- memcpy (&ptr[inval1len], value_contents (inval2), inval2len);
+ memcpy (&ptr[inval1len], value_contents (inval2).data (), inval2len);
}
outval = value_string (ptr.data (), inval1len + inval2len, char_type);
}
if (is_floating_type (type1))
{
*eff_type_x = type1;
- memcpy (x, value_contents (arg1), TYPE_LENGTH (type1));
+ memcpy (x, value_contents (arg1).data (), TYPE_LENGTH (type1));
}
else if (is_integral_type (type1))
{
if (is_floating_type (type2))
{
*eff_type_y = type2;
- memcpy (y, value_contents (arg2), TYPE_LENGTH (type2));
+ memcpy (y, value_contents (arg2).data (), TYPE_LENGTH (type2));
}
else if (is_integral_type (type2))
{
struct type *type2 = check_typedef (value_type (arg2));
const struct language_defn *language = current_language;
- struct gdbarch *gdbarch = get_type_arch (type1);
+ struct gdbarch *gdbarch = type1->arch ();
struct value *val;
+ gdb_mpq v1, v2, res;
+
gdb_assert (is_fixed_point_type (type1) || is_fixed_point_type (type2));
- if (!is_fixed_point_type (type1))
+ if (op == BINOP_MUL || op == BINOP_DIV)
{
- arg1 = value_cast (type2, arg1);
- type1 = type2;
+ v1 = value_to_gdb_mpq (arg1);
+ v2 = value_to_gdb_mpq (arg2);
+
+ /* The code below uses TYPE1 for the result type, so make sure
+ it is set properly. */
+ if (!is_fixed_point_type (type1))
+ type1 = type2;
}
- if (!is_fixed_point_type (type2))
+ else
{
- arg2 = value_cast (type1, arg2);
- type2 = type1;
+ if (!is_fixed_point_type (type1))
+ {
+ arg1 = value_cast (type2, arg1);
+ type1 = type2;
+ }
+ if (!is_fixed_point_type (type2))
+ {
+ arg2 = value_cast (type1, arg2);
+ type2 = type1;
+ }
+
+ v1.read_fixed_point (gdb::make_array_view (value_contents (arg1).data (),
+ TYPE_LENGTH (type1)),
+ type_byte_order (type1), type1->is_unsigned (),
+ type1->fixed_point_scaling_factor ());
+ v2.read_fixed_point (gdb::make_array_view (value_contents (arg2).data (),
+ TYPE_LENGTH (type2)),
+ type_byte_order (type2), type2->is_unsigned (),
+ type2->fixed_point_scaling_factor ());
}
- gdb_mpq v1, v2, res;
- v1.read_fixed_point (value_contents (arg1), TYPE_LENGTH (type1),
- type_byte_order (type1), type1->is_unsigned (),
- fixed_point_scaling_factor (type1));
- v2.read_fixed_point (value_contents (arg2), TYPE_LENGTH (type2),
- type_byte_order (type2), type2->is_unsigned (),
- fixed_point_scaling_factor (type2));
-
-#define INIT_VAL_WITH_FIXED_POINT_VAL(RESULT) \
- do { \
- val = allocate_value (type1); \
- (RESULT).write_fixed_point \
- (value_contents_raw (val), TYPE_LENGTH (type1), \
- type_byte_order (type1), type1->is_unsigned (), \
- fixed_point_scaling_factor (type1)); \
- } while (0)
+ auto fixed_point_to_value = [type1] (const gdb_mpq &fp)
+ {
+ value *fp_val = allocate_value (type1);
+
+ fp.write_fixed_point
+ (gdb::make_array_view (value_contents_raw (fp_val).data (),
+ TYPE_LENGTH (type1)),
+ type_byte_order (type1),
+ type1->is_unsigned (),
+ type1->fixed_point_scaling_factor ());
+
+ return fp_val;
+ };
switch (op)
{
case BINOP_ADD:
mpq_add (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_SUB:
mpq_sub (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_MIN:
- INIT_VAL_WITH_FIXED_POINT_VAL (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
+ val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
break;
case BINOP_MAX:
- INIT_VAL_WITH_FIXED_POINT_VAL (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
+ val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
break;
case BINOP_MUL:
mpq_mul (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_DIV:
+ if (mpq_sgn (v2.val) == 0)
+ error (_("Division by zero"));
mpq_div (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_EQUAL:
struct type *comp_type = promotion_type (value_type (arg1_real),
value_type (arg2_real));
+ if (!can_create_complex_type (comp_type))
+ error (_("Argument to complex arithmetic operation not supported."));
+
arg1_real = value_cast (comp_type, arg1_real);
arg1_imag = value_cast (comp_type, arg1_imag);
arg2_real = value_cast (comp_type, arg2_real);
v2.data (), &eff_type_v2);
target_float_binop (op, v1.data (), eff_type_v1,
v2.data (), eff_type_v2,
- value_contents_raw (val), result_type);
+ value_contents_raw (val).data (), result_type);
}
else if (type1->code () == TYPE_CODE_BOOL
|| type2->code () == TYPE_CODE_BOOL)
result_type = type1;
val = allocate_value (result_type);
- store_signed_integer (value_contents_raw (val),
+ store_signed_integer (value_contents_raw (val).data (),
TYPE_LENGTH (result_type),
type_byte_order (result_type),
v);
}
val = allocate_value (result_type);
- store_unsigned_integer (value_contents_raw (val),
+ store_unsigned_integer (value_contents_raw (val).data (),
TYPE_LENGTH (value_type (val)),
type_byte_order (result_type),
v);
}
val = allocate_value (result_type);
- store_signed_integer (value_contents_raw (val),
+ store_signed_integer (value_contents_raw (val).data (),
TYPE_LENGTH (value_type (val)),
type_byte_order (result_type),
v);
val = allocate_value (vector_type);
for (i = 0; i < high_bound - low_bound + 1; i++)
/* Duplicate the contents of elval into the destination vector. */
- memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
- value_contents_all (elval), TYPE_LENGTH (eltype));
+ memcpy (value_contents_writeable (val).data () + (i * TYPE_LENGTH (eltype)),
+ value_contents_all (elval).data (), TYPE_LENGTH (eltype));
return val;
}
{
tmp = value_binop (value_subscript (val1, i),
value_subscript (val2, i), op);
- memcpy (value_contents_writeable (val) + i * elsize,
- value_contents_all (tmp),
+ memcpy (value_contents_writeable (val).data () + i * elsize,
+ value_contents_all (tmp).data (),
elsize);
}
value_free_to_mark (mark);
return val;
}
\f
-/* Simulate the C operator ! -- return 1 if ARG1 contains zero. */
+/* See value.h. */
-int
+bool
value_logical_not (struct value *arg1)
{
int len;
type1 = check_typedef (value_type (arg1));
if (is_floating_value (arg1))
- return target_float_is_zero (value_contents (arg1), type1);
+ return target_float_is_zero (value_contents (arg1).data (), type1);
len = TYPE_LENGTH (type1);
- p = value_contents (arg1);
+ p = value_contents (arg1).data ();
while (--len >= 0)
{
{
int len1 = TYPE_LENGTH (value_type (arg1));
int len2 = TYPE_LENGTH (value_type (arg2));
- const gdb_byte *s1 = value_contents (arg1);
- const gdb_byte *s2 = value_contents (arg2);
+ const gdb_byte *s1 = value_contents (arg1).data ();
+ const gdb_byte *s2 = value_contents (arg2).data ();
int i, len = len1 < len2 ? len1 : len2;
for (i = 0; i < len; i++)
&& ((len = (int) TYPE_LENGTH (type1))
== (int) TYPE_LENGTH (type2)))
{
- p1 = value_contents (arg1);
- p2 = value_contents (arg2);
+ p1 = value_contents (arg1).data ();
+ p2 = value_contents (arg2).data ();
while (--len >= 0)
{
if (*p1++ != *p2++)
return (type1->code () == type2->code ()
&& TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
- && memcmp (value_contents (arg1), value_contents (arg2),
+ && memcmp (value_contents (arg1).data (),
+ value_contents (arg2).data (),
TYPE_LENGTH (type1)) == 0);
}
if (is_integral_type (type) || is_floating_value (arg1)
|| (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
|| type->code () == TYPE_CODE_COMPLEX)
- return value_from_contents (type, value_contents (arg1));
+ return value_from_contents (type, value_contents (arg1).data ());
else
error (_("Argument to positive operation not a number."));
}
for (i = 0; i < high_bound - low_bound + 1; i++)
{
tmp = value_neg (value_subscript (arg1, i));
- memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
- value_contents_all (tmp), TYPE_LENGTH (eltype));
+ memcpy ((value_contents_writeable (val).data ()
+ + i * TYPE_LENGTH (eltype)),
+ value_contents_all (tmp).data (), TYPE_LENGTH (eltype));
}
return val;
}
for (i = 0; i < high_bound - low_bound + 1; i++)
{
tmp = value_complement (value_subscript (arg1, i));
- memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
- value_contents_all (tmp), TYPE_LENGTH (eltype));
+ memcpy ((value_contents_writeable (val).data ()
+ + i * TYPE_LENGTH (eltype)),
+ value_contents_all (tmp).data (), TYPE_LENGTH (eltype));
}
}
else if (type->code () == TYPE_CODE_COMPLEX)
int
value_bit_index (struct type *type, const gdb_byte *valaddr, int index)
{
- struct gdbarch *gdbarch = get_type_arch (type);
+ struct gdbarch *gdbarch = type->arch ();
LONGEST low_bound, high_bound;
LONGEST word;
unsigned rel_index;
struct type *range = type->index_type ();
- if (get_discrete_bounds (range, &low_bound, &high_bound) < 0)
+ if (!get_discrete_bounds (range, &low_bound, &high_bound))
return -2;
if (index < low_bound || index > high_bound)
return -1;
&& eltype->code () != TYPE_CODE_ENUM
&& eltype->code () != TYPE_CODE_BOOL)
error (_("First argument of 'IN' has wrong type"));
- member = value_bit_index (settype, value_contents (set),
+ member = value_bit_index (settype, value_contents (set).data (),
value_as_long (element));
if (member < 0)
error (_("First argument of 'IN' not in range"));