2002-04-04 Jim Ingham <jingham@apple.com>

* valarith.c (find_size_for_pointer_math): New function, either returns
       the size for a pointer's target, returns 1 for void *, or errors for
       incomplete types.
       (value_add, value_sub): use find_size_for_pointer_math.
This commit is contained in:
Jim Ingham 2002-04-10 00:11:51 +00:00
parent 0e994e6610
commit ca439ad26a
2 changed files with 52 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2002-04-04 Jim Ingham <jingham@apple.com>
* valarith.c (find_size_for_pointer_math): New function, either returns
the size for a pointer's target, returns 1 for void *, or errors for
incomplete types.
(value_add, value_sub): use find_size_for_pointer_math.
2002-04-09 Daniel Jacobowitz <drow@mvista.com> 2002-04-09 Daniel Jacobowitz <drow@mvista.com>
* linux-low.c (linux_look_up_symbols): New hook. * linux-low.c (linux_look_up_symbols): New hook.

View File

@ -43,12 +43,50 @@ static struct value *value_subscripted_rvalue (struct value *, struct value *, i
void _initialize_valarith (void); void _initialize_valarith (void);
/* Given a pointer, return the size of its target.
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.
*/
static LONGEST
find_size_for_pointer_math (struct type *ptr_type)
{
LONGEST sz = -1;
struct type *ptr_target;
ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type));
sz = TYPE_LENGTH (ptr_target);
if (sz == 0)
{
if (TYPE_CODE (ptr_type) == TYPE_CODE_VOID)
sz = 1;
else
{
char *name;
name = TYPE_NAME (ptr_target);
if (name == NULL)
name = TYPE_TAG_NAME (ptr_target);
if (name == NULL)
error ("Cannot perform pointer math on incomplete types, "
"try casting to a known type, or void *.");
else
error ("Cannot perform pointer math on incomplete type \"%s\", "
"try casting to a known type, or void *.", name);
}
}
return sz;
}
struct value * struct value *
value_add (struct value *arg1, struct value *arg2) value_add (struct value *arg1, struct value *arg2)
{ {
struct value *valint; struct value *valint;
struct value *valptr; struct value *valptr;
register int len; LONGEST sz;
struct type *type1, *type2, *valptrtype; struct type *type1, *type2, *valptrtype;
COERCE_NUMBER (arg1); COERCE_NUMBER (arg1);
@ -77,12 +115,12 @@ value_add (struct value *arg1, struct value *arg2)
valint = arg1; valint = arg1;
valptrtype = type2; valptrtype = type2;
} }
len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype)));
if (len == 0) sz = find_size_for_pointer_math (valptrtype);
len = 1; /* For (void *) */
retval = value_from_pointer (valptrtype, retval = value_from_pointer (valptrtype,
value_as_address (valptr) value_as_address (valptr)
+ (len * value_as_long (valint))); + (sz * value_as_long (valint)));
VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr); VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
return retval; return retval;
} }
@ -104,7 +142,8 @@ value_sub (struct value *arg1, struct value *arg2)
if (TYPE_CODE (type2) == TYPE_CODE_INT) if (TYPE_CODE (type2) == TYPE_CODE_INT)
{ {
/* pointer - integer. */ /* pointer - integer. */
LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); LONGEST sz = find_size_for_pointer_math (type1);
return value_from_pointer (type1, return value_from_pointer (type1,
(value_as_address (arg1) (value_as_address (arg1)
- (sz * value_as_long (arg2)))); - (sz * value_as_long (arg2))));