diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2008-09-11 14:13:46 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2008-09-11 14:13:46 +0000 |
commit | 89eef114606ca0510db54cec2fc60946a91990e8 (patch) | |
tree | ce97504e52ddf8d7505920f03559f2428b431940 /gdb/valarith.c | |
parent | 98b90dd8884cb6526f17524e800a315860904ec0 (diff) | |
download | gdb-89eef114606ca0510db54cec2fc60946a91990e8.zip gdb-89eef114606ca0510db54cec2fc60946a91990e8.tar.gz gdb-89eef114606ca0510db54cec2fc60946a91990e8.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/valarith.c')
-rw-r--r-- | gdb/valarith.c | 116 |
1 files changed, 50 insertions, 66 deletions
diff --git a/gdb/valarith.c b/gdb/valarith.c index c13c393..b9daedf 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -50,7 +50,7 @@ void _initialize_valarith (void); If the pointer type is void *, then return 1. If the target type is incomplete, then error out. This isn't a general purpose function, but just a - helper for value_sub & value_add. + helper for value_ptrsub & value_ptradd. */ static LONGEST @@ -59,6 +59,7 @@ find_size_for_pointer_math (struct type *ptr_type) LONGEST sz = -1; struct type *ptr_target; + gdb_assert (TYPE_CODE (ptr_type) == TYPE_CODE_PTR); ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type)); sz = TYPE_LENGTH (ptr_target); @@ -84,90 +85,73 @@ find_size_for_pointer_math (struct type *ptr_type) return sz; } +/* Given a pointer ARG1 and an integral value ARG2, return the + result of C-style pointer arithmetic ARG1 + ARG2. */ + struct value * -value_add (struct value *arg1, struct value *arg2) +value_ptradd (struct value *arg1, struct value *arg2) { - struct value *valint; - struct value *valptr; + struct type *valptrtype; LONGEST sz; - struct type *type1, *type2, *valptrtype; arg1 = coerce_array (arg1); - arg2 = coerce_array (arg2); - type1 = check_typedef (value_type (arg1)); - type2 = check_typedef (value_type (arg2)); + valptrtype = check_typedef (value_type (arg1)); + sz = find_size_for_pointer_math (valptrtype); - if ((TYPE_CODE (type1) == TYPE_CODE_PTR - || TYPE_CODE (type2) == TYPE_CODE_PTR) - && - (is_integral_type (type1) || is_integral_type (type2))) - /* Exactly one argument is a pointer, and one is an integer. */ - { - struct value *retval; + if (!is_integral_type (value_type (arg2))) + error (_("Argument to arithmetic operation not a number or boolean.")); - if (TYPE_CODE (type1) == TYPE_CODE_PTR) - { - valptr = arg1; - valint = arg2; - valptrtype = type1; - } - else - { - valptr = arg2; - valint = arg1; - valptrtype = type2; - } + return value_from_pointer (valptrtype, + value_as_address (arg1) + + (sz * value_as_long (arg2))); +} - sz = find_size_for_pointer_math (valptrtype); +/* Given a pointer ARG1 and an integral value ARG2, return the + result of C-style pointer arithmetic ARG1 - ARG2. */ - retval = value_from_pointer (valptrtype, - value_as_address (valptr) - + (sz * value_as_long (valint))); - return retval; - } +struct value * +value_ptrsub (struct value *arg1, struct value *arg2) +{ + struct type *valptrtype; + LONGEST sz; - return value_binop (arg1, arg2, BINOP_ADD); + 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))); } -struct value * -value_sub (struct value *arg1, struct value *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; + LONGEST sz; + arg1 = coerce_array (arg1); arg2 = coerce_array (arg2); type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); - if (TYPE_CODE (type1) == TYPE_CODE_PTR) - { - if (is_integral_type (type2)) - { - /* pointer - integer. */ - LONGEST sz = find_size_for_pointer_math (type1); + gdb_assert (TYPE_CODE (type1) == TYPE_CODE_PTR); + gdb_assert (TYPE_CODE (type2) == TYPE_CODE_PTR); - return value_from_pointer (type1, - (value_as_address (arg1) - - (sz * value_as_long (arg2)))); - } - 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 (_("\ + if (TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))) + != TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2)))) + error (_("\ First argument of `-' is a pointer and second argument is neither\n\ 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]. @@ -216,15 +200,15 @@ value_subscript (struct value *array, struct value *idx) if (lowerbound != 0) { - bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound); - idx = value_sub (idx, bound); + bound = value_from_longest (value_type (idx), (LONGEST) lowerbound); + idx = value_binop (idx, bound, BINOP_SUB); } array = value_coerce_array (array); } if (c_style) - return value_ind (value_add (array, idx)); + return value_ind (value_ptradd (array, idx)); else 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, characters, integers, or floats. 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 * value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) |