diff options
author | Jim Ingham <jingham@apple.com> | 2002-04-10 00:11:51 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2002-04-10 00:11:51 +0000 |
commit | e09ebdec76618e33e27b7f91a00cf6b0af3bd74e (patch) | |
tree | 5cae5ccc8d52791298187556ee3864aed235a82d /gdb/valarith.c | |
parent | 20f84719db89e17c380ca3409c9f00fe5cafa951 (diff) | |
download | gdb-e09ebdec76618e33e27b7f91a00cf6b0af3bd74e.tar.gz |
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.
Diffstat (limited to 'gdb/valarith.c')
-rw-r--r-- | gdb/valarith.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/gdb/valarith.c b/gdb/valarith.c index c3d537a1923..cc067cb4b51 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -43,12 +43,50 @@ static struct value *value_subscripted_rvalue (struct value *, struct value *, i 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 * value_add (struct value *arg1, struct value *arg2) { struct value *valint; struct value *valptr; - register int len; + LONGEST sz; struct type *type1, *type2, *valptrtype; COERCE_NUMBER (arg1); @@ -77,12 +115,12 @@ value_add (struct value *arg1, struct value *arg2) valint = arg1; valptrtype = type2; } - len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype))); - if (len == 0) - len = 1; /* For (void *) */ + + sz = find_size_for_pointer_math (valptrtype); + retval = value_from_pointer (valptrtype, value_as_address (valptr) - + (len * value_as_long (valint))); + + (sz * value_as_long (valint))); VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr); return retval; } @@ -104,7 +142,8 @@ value_sub (struct value *arg1, struct value *arg2) if (TYPE_CODE (type2) == TYPE_CODE_INT) { /* 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, (value_as_address (arg1) - (sz * value_as_long (arg2)))); |