* value.h (value_add, value_sub): Remove.

(value_ptradd, value_ptrsub, value_ptrdiff): Add prototypes.
	* valarith.c (value_add, value_sub): Remove.
	(value_ptradd, value_ptrsub, value_ptrdiff): New functions.
	(find_size_for_pointer_math): Add assertion.  Update comment.
	(value_binop): Update comment.

	* eval.c (ptrmath_type_p): New function.
	(evaluate_subexp_standard): Replace value_add and value_sub
	by value_ptradd, value_ptrsub, value_ptrdiff or value_binop.
	Use builtin_type_uint8 instead of builtin_type_char to hold
	the increment for BINOP_{PRE,POST}{IN,DE}CREMENT operations.
	* valarith.c (value_subscript): Replace value_add by
	value_ptradd.  Replace value_sub by value_binop.
	* ada-lang.c (ada_value_ptr_subscript): Likewise.
	(ada_tag_name_2): Replace value_add by value_ptradd.
	(ada_evaluate_subexp): Replace value_add and value_sub by
	value_binop.
	* m2-lang.c (evaluate_subexp_modula2): Replace value_add
	by value_ptradd.
	* gnu-v2-abi.c (gnuv2_virtual_fn_field): Likewise.
	* gnu-v3-abi.c (gnuv3_method_ptr_to_value): Likewise.
This commit is contained in:
Ulrich Weigand 2008-09-11 14:13:46 +00:00
parent 98b90dd888
commit 89eef11460
8 changed files with 158 additions and 92 deletions

View file

@ -1,3 +1,28 @@
2008-09-11 Ulrich Weigand <uweigand@de.ibm.com>
* value.h (value_add, value_sub): Remove.
(value_ptradd, value_ptrsub, value_ptrdiff): Add prototypes.
* valarith.c (value_add, value_sub): Remove.
(value_ptradd, value_ptrsub, value_ptrdiff): New functions.
(find_size_for_pointer_math): Add assertion. Update comment.
(value_binop): Update comment.
* eval.c (ptrmath_type_p): New function.
(evaluate_subexp_standard): Replace value_add and value_sub
by value_ptradd, value_ptrsub, value_ptrdiff or value_binop.
Use builtin_type_uint8 instead of builtin_type_char to hold
the increment for BINOP_{PRE,POST}{IN,DE}CREMENT operations.
* valarith.c (value_subscript): Replace value_add by
value_ptradd. Replace value_sub by value_binop.
* ada-lang.c (ada_value_ptr_subscript): Likewise.
(ada_tag_name_2): Replace value_add by value_ptradd.
(ada_evaluate_subexp): Replace value_add and value_sub by
value_binop.
* m2-lang.c (evaluate_subexp_modula2): Replace value_add
by value_ptradd.
* gnu-v2-abi.c (gnuv2_virtual_fn_field): Likewise.
* gnu-v3-abi.c (gnuv3_method_ptr_to_value): Likewise.
2008-09-11 Ulrich Weigand <uweigand@de.ibm.com> 2008-09-11 Ulrich Weigand <uweigand@de.ibm.com>
* eval.c (evaluate_subexp_for_sizeof): Use builtin_int type of * eval.c (evaluate_subexp_for_sizeof): Use builtin_int type of

View file

@ -2362,8 +2362,10 @@ ada_value_ptr_subscript (struct value *arr, struct type *type, int arity,
get_discrete_bounds (TYPE_INDEX_TYPE (type), &lwb, &upb); get_discrete_bounds (TYPE_INDEX_TYPE (type), &lwb, &upb);
idx = value_pos_atr (ind[k]); idx = value_pos_atr (ind[k]);
if (lwb != 0) if (lwb != 0)
idx = value_sub (idx, value_from_longest (builtin_type_int, lwb)); idx = value_binop (idx, value_from_longest (value_type (idx), lwb),
arr = value_add (arr, idx); BINOP_SUB);
arr = value_ptradd (arr, idx);
type = TYPE_TARGET_TYPE (type); type = TYPE_TARGET_TYPE (type);
} }
@ -5726,7 +5728,8 @@ ada_tag_name_2 (struct tag_args *args)
valp = value_cast (info_type, args->tag); valp = value_cast (info_type, args->tag);
if (valp == NULL) if (valp == NULL)
return 0; return 0;
val = value_ind (value_add (valp, value_from_longest (builtin_type_int, -1))); val = value_ind (value_ptradd (valp,
value_from_longest (builtin_type_int8, -1)));
if (val == NULL) if (val == NULL)
return 0; return 0;
val = ada_value_struct_elt (val, "expanded_name", 1); val = ada_value_struct_elt (val, "expanded_name", 1);
@ -8460,7 +8463,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
type = value_type (arg1); type = value_type (arg1);
while (TYPE_CODE (type) == TYPE_CODE_REF) while (TYPE_CODE (type) == TYPE_CODE_REF)
type = TYPE_TARGET_TYPE (type); type = TYPE_TARGET_TYPE (type);
return value_cast (type, value_add (arg1, arg2)); return value_cast (type, value_binop (arg1, arg2, BINOP_ADD));
case BINOP_SUB: case BINOP_SUB:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
@ -8481,7 +8484,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
type = value_type (arg1); type = value_type (arg1);
while (TYPE_CODE (type) == TYPE_CODE_REF) while (TYPE_CODE (type) == TYPE_CODE_REF)
type = TYPE_TARGET_TYPE (type); type = TYPE_TARGET_TYPE (type);
return value_cast (type, value_sub (arg1, arg2)); return value_cast (type, value_binop (arg1, arg2, BINOP_SUB));
case BINOP_MUL: case BINOP_MUL:
case BINOP_DIV: case BINOP_DIV:

View file

@ -439,6 +439,27 @@ value_f90_subarray (struct value *array,
return value_slice (array, low_bound, high_bound - low_bound + 1); return value_slice (array, low_bound, high_bound - low_bound + 1);
} }
static int
ptrmath_type_p (struct type *type)
{
type = check_typedef (type);
if (TYPE_CODE (type) == TYPE_CODE_REF)
type = TYPE_TARGET_TYPE (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
return 1;
case TYPE_CODE_ARRAY:
return current_language->c_style_arrays;
default:
return 0;
}
}
struct value * struct value *
evaluate_subexp_standard (struct type *expect_type, evaluate_subexp_standard (struct type *expect_type,
struct expression *exp, int *pos, struct expression *exp, int *pos,
@ -1506,10 +1527,10 @@ evaluate_subexp_standard (struct type *expect_type,
op = exp->elts[pc + 1].opcode; op = exp->elts[pc + 1].opcode;
if (binop_user_defined_p (op, arg1, arg2)) if (binop_user_defined_p (op, arg1, arg2))
return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside); return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside);
else if (op == BINOP_ADD) else if (op == BINOP_ADD && ptrmath_type_p (value_type (arg1)))
arg2 = value_add (arg1, arg2); arg2 = value_ptradd (arg1, arg2);
else if (op == BINOP_SUB) else if (op == BINOP_SUB && ptrmath_type_p (value_type (arg1)))
arg2 = value_sub (arg1, arg2); arg2 = value_ptrsub (arg1, arg2);
else else
arg2 = value_binop (arg1, arg2, op); arg2 = value_binop (arg1, arg2, op);
return value_assign (arg1, arg2); return value_assign (arg1, arg2);
@ -1521,8 +1542,12 @@ evaluate_subexp_standard (struct type *expect_type,
goto nosideret; goto nosideret;
if (binop_user_defined_p (op, arg1, arg2)) if (binop_user_defined_p (op, arg1, arg2))
return value_x_binop (arg1, arg2, op, OP_NULL, noside); return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else if (ptrmath_type_p (value_type (arg1)))
return value_ptradd (arg1, arg2);
else if (ptrmath_type_p (value_type (arg2)))
return value_ptradd (arg2, arg1);
else else
return value_add (arg1, arg2); return value_binop (arg1, arg2, BINOP_ADD);
case BINOP_SUB: case BINOP_SUB:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
@ -1531,8 +1556,19 @@ evaluate_subexp_standard (struct type *expect_type,
goto nosideret; goto nosideret;
if (binop_user_defined_p (op, arg1, arg2)) if (binop_user_defined_p (op, arg1, arg2))
return value_x_binop (arg1, arg2, op, OP_NULL, noside); return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else if (ptrmath_type_p (value_type (arg1)))
{
if (ptrmath_type_p (value_type (arg2)))
{
/* FIXME -- should be ptrdiff_t */
type = builtin_type (exp->gdbarch)->builtin_long;
return value_from_longest (type, value_ptrdiff (arg1, arg2));
}
else
return value_ptrsub (arg1, arg2);
}
else else
return value_sub (arg1, arg2); return value_binop (arg1, arg2, BINOP_SUB);
case BINOP_EXP: case BINOP_EXP:
case BINOP_MUL: case BINOP_MUL:
@ -2091,8 +2127,12 @@ evaluate_subexp_standard (struct type *expect_type,
} }
else else
{ {
arg2 = value_add (arg1, value_from_longest (builtin_type_char, arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1);
(LONGEST) 1)); if (ptrmath_type_p (value_type (arg1)))
arg2 = value_ptradd (arg1, arg2);
else
arg2 = value_binop (arg1, arg2, BINOP_ADD);
return value_assign (arg1, arg2); return value_assign (arg1, arg2);
} }
@ -2106,8 +2146,12 @@ evaluate_subexp_standard (struct type *expect_type,
} }
else else
{ {
arg2 = value_sub (arg1, value_from_longest (builtin_type_char, arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1);
(LONGEST) 1)); if (ptrmath_type_p (value_type (arg1)))
arg2 = value_ptrsub (arg1, arg2);
else
arg2 = value_binop (arg1, arg2, BINOP_SUB);
return value_assign (arg1, arg2); return value_assign (arg1, arg2);
} }
@ -2121,8 +2165,12 @@ evaluate_subexp_standard (struct type *expect_type,
} }
else else
{ {
arg2 = value_add (arg1, value_from_longest (builtin_type_char, arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1);
(LONGEST) 1)); if (ptrmath_type_p (value_type (arg1)))
arg2 = value_ptradd (arg1, arg2);
else
arg2 = value_binop (arg1, arg2, BINOP_ADD);
value_assign (arg1, arg2); value_assign (arg1, arg2);
return arg1; return arg1;
} }
@ -2137,8 +2185,12 @@ evaluate_subexp_standard (struct type *expect_type,
} }
else else
{ {
arg2 = value_sub (arg1, value_from_longest (builtin_type_char, arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1);
(LONGEST) 1)); if (ptrmath_type_p (value_type (arg1)))
arg2 = value_ptrsub (arg1, arg2);
else
arg2 = value_binop (arg1, arg2, BINOP_SUB);
value_assign (arg1, arg2); value_assign (arg1, arg2);
return arg1; return arg1;
} }

View file

@ -151,7 +151,7 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
else else
{ {
/* Handle the case where the vtbl field points directly to a structure. */ /* Handle the case where the vtbl field points directly to a structure. */
vtbl = value_add (vtbl, vi); vtbl = value_ptradd (vtbl, vi);
entry = value_ind (vtbl); entry = value_ind (vtbl);
} }

View file

@ -675,7 +675,7 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
instance. */ instance. */
*this_p = value_cast (builtin_type_void_data_ptr, *this_p); *this_p = value_cast (builtin_type_void_data_ptr, *this_p);
adjval = value_from_longest (builtin_type_long, adjustment); adjval = value_from_longest (builtin_type_long, adjustment);
*this_p = value_add (*this_p, adjval); *this_p = value_ptradd (*this_p, adjval);
*this_p = value_cast (final_type, *this_p); *this_p = value_cast (final_type, *this_p);
if (vbit) if (vbit)

View file

@ -251,7 +251,7 @@ evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
arg1 = value_cast (type, arg1); arg1 = value_cast (type, arg1);
type = check_typedef (value_type (arg1)); type = check_typedef (value_type (arg1));
return value_ind (value_add (arg1, arg2)); return value_ind (value_ptradd (arg1, arg2));
} }
else else
if (TYPE_CODE (type) != TYPE_CODE_ARRAY) if (TYPE_CODE (type) != TYPE_CODE_ARRAY)

View file

@ -50,7 +50,7 @@ void _initialize_valarith (void);
If the pointer type is void *, then return 1. If the pointer type is void *, then return 1.
If the target type is incomplete, then error out. If the target type is incomplete, then error out.
This isn't a general purpose function, but just a This isn't a general purpose function, but just a
helper for value_sub & value_add. helper for value_ptrsub & value_ptradd.
*/ */
static LONGEST static LONGEST
@ -59,6 +59,7 @@ find_size_for_pointer_math (struct type *ptr_type)
LONGEST sz = -1; LONGEST sz = -1;
struct type *ptr_target; struct type *ptr_target;
gdb_assert (TYPE_CODE (ptr_type) == TYPE_CODE_PTR);
ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type)); ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type));
sz = TYPE_LENGTH (ptr_target); sz = TYPE_LENGTH (ptr_target);
@ -84,90 +85,73 @@ find_size_for_pointer_math (struct type *ptr_type)
return sz; return sz;
} }
/* Given a pointer ARG1 and an integral value ARG2, return the
result of C-style pointer arithmetic ARG1 + ARG2. */
struct value * struct value *
value_add (struct value *arg1, struct value *arg2) value_ptradd (struct value *arg1, struct value *arg2)
{ {
struct value *valint; struct type *valptrtype;
struct value *valptr;
LONGEST sz; LONGEST sz;
struct type *type1, *type2, *valptrtype;
arg1 = coerce_array (arg1); arg1 = coerce_array (arg1);
arg2 = coerce_array (arg2); valptrtype = check_typedef (value_type (arg1));
type1 = check_typedef (value_type (arg1)); sz = find_size_for_pointer_math (valptrtype);
type2 = check_typedef (value_type (arg2));
if ((TYPE_CODE (type1) == TYPE_CODE_PTR if (!is_integral_type (value_type (arg2)))
|| TYPE_CODE (type2) == TYPE_CODE_PTR) error (_("Argument to arithmetic operation not a number or boolean."));
&&
(is_integral_type (type1) || is_integral_type (type2)))
/* Exactly one argument is a pointer, and one is an integer. */
{
struct value *retval;
if (TYPE_CODE (type1) == TYPE_CODE_PTR) return value_from_pointer (valptrtype,
{ value_as_address (arg1)
valptr = arg1; + (sz * value_as_long (arg2)));
valint = arg2;
valptrtype = type1;
}
else
{
valptr = arg2;
valint = arg1;
valptrtype = type2;
}
sz = find_size_for_pointer_math (valptrtype);
retval = value_from_pointer (valptrtype,
value_as_address (valptr)
+ (sz * value_as_long (valint)));
return retval;
}
return value_binop (arg1, arg2, BINOP_ADD);
} }
/* Given a pointer ARG1 and an integral value ARG2, return the
result of C-style pointer arithmetic ARG1 - ARG2. */
struct value * struct value *
value_sub (struct value *arg1, struct value *arg2) value_ptrsub (struct value *arg1, struct value *arg2)
{
struct type *valptrtype;
LONGEST sz;
arg1 = coerce_array (arg1);
valptrtype = check_typedef (value_type (arg1));
sz = find_size_for_pointer_math (valptrtype);
if (!is_integral_type (value_type (arg2)))
error (_("Argument to arithmetic operation not a number or boolean."));
return value_from_pointer (valptrtype,
value_as_address (arg1)
- (sz * value_as_long (arg2)));
}
/* Given two compatible pointer values ARG1 and ARG2, return the
result of C-style pointer arithmetic ARG1 - ARG2. */
LONGEST
value_ptrdiff (struct value *arg1, struct value *arg2)
{ {
struct type *type1, *type2; struct type *type1, *type2;
LONGEST sz;
arg1 = coerce_array (arg1); arg1 = coerce_array (arg1);
arg2 = coerce_array (arg2); arg2 = coerce_array (arg2);
type1 = check_typedef (value_type (arg1)); type1 = check_typedef (value_type (arg1));
type2 = check_typedef (value_type (arg2)); type2 = check_typedef (value_type (arg2));
if (TYPE_CODE (type1) == TYPE_CODE_PTR) gdb_assert (TYPE_CODE (type1) == TYPE_CODE_PTR);
{ gdb_assert (TYPE_CODE (type2) == TYPE_CODE_PTR);
if (is_integral_type (type2))
{
/* pointer - integer. */
LONGEST sz = find_size_for_pointer_math (type1);
return value_from_pointer (type1, if (TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)))
(value_as_address (arg1) != TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2))))
- (sz * value_as_long (arg2)))); error (_("\
}
else if (TYPE_CODE (type2) == TYPE_CODE_PTR
&& TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)))
== TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2))))
{
/* pointer to <type x> - pointer to <type x>. */
LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)));
return value_from_longest
(builtin_type_long, /* FIXME -- should be ptrdiff_t */
(value_as_long (arg1) - value_as_long (arg2)) / sz);
}
else
{
error (_("\
First argument of `-' is a pointer and second argument is neither\n\ First argument of `-' is a pointer and second argument is neither\n\
an integer nor a pointer of the same type.")); an integer nor a pointer of the same type."));
}
}
return value_binop (arg1, arg2, BINOP_SUB); sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)));
return (value_as_long (arg1) - value_as_long (arg2)) / sz;
} }
/* Return the value of ARRAY[IDX]. /* Return the value of ARRAY[IDX].
@ -216,15 +200,15 @@ value_subscript (struct value *array, struct value *idx)
if (lowerbound != 0) if (lowerbound != 0)
{ {
bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound); bound = value_from_longest (value_type (idx), (LONGEST) lowerbound);
idx = value_sub (idx, bound); idx = value_binop (idx, bound, BINOP_SUB);
} }
array = value_coerce_array (array); array = value_coerce_array (array);
} }
if (c_style) if (c_style)
return value_ind (value_add (array, idx)); return value_ind (value_ptradd (array, idx));
else else
error (_("not an array or string")); error (_("not an array or string"));
} }
@ -1176,7 +1160,7 @@ value_args_as_decimal (struct value *arg1, struct value *arg2,
representations as integers or floats. This includes booleans, representations as integers or floats. This includes booleans,
characters, integers, or floats. characters, integers, or floats.
Does not support addition and subtraction on pointers; Does not support addition and subtraction on pointers;
use value_add or value_sub if you want to handle those possibilities. */ use value_ptradd, value_ptrsub or value_ptrdiff for those operations. */
struct value * struct value *
value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)

View file

@ -331,9 +331,11 @@ extern struct value *value_concat (struct value *arg1, struct value *arg2);
extern struct value *value_binop (struct value *arg1, struct value *arg2, extern struct value *value_binop (struct value *arg1, struct value *arg2,
enum exp_opcode op); enum exp_opcode op);
extern struct value *value_add (struct value *arg1, struct value *arg2); extern struct value *value_ptradd (struct value *arg1, struct value *arg2);
extern struct value *value_sub (struct value *arg1, struct value *arg2); extern struct value *value_ptrsub (struct value *arg1, struct value *arg2);
extern LONGEST value_ptrdiff (struct value *arg1, struct value *arg2);
extern int value_must_coerce_to_target (struct value *arg1); extern int value_must_coerce_to_target (struct value *arg1);