aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/eval.c23
-rw-r--r--gdb/valarith.c79
-rw-r--r--gdb/value.h4
4 files changed, 85 insertions, 29 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dc34aa0..734b65d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
2008-09-11 Ulrich Weigand <uweigand@de.ibm.com>
+ * value.h (value_bitstring_subscript): New prototype.
+ * valarith.h (value_bitstring_subscript): New function.
+ (value_subscript): No longer handle TYPE_CODE_BITSTRING.
+ * eval.c (evaluate_subexp_standard): Call value_bitstring_subscript
+ instead of value_subscript to handle TYPE_CODE_BITSTRING.
+
+2008-09-11 Ulrich Weigand <uweigand@de.ibm.com>
+
* expression.h (struct expression): New member GDBARCH.
* parse.c (parse_exp_in_context): Initialize it.
* parser-def.h (parse_gdbarch, parse_language): New macros.
diff --git a/gdb/eval.c b/gdb/eval.c
index ca36762..9400ef4 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1666,7 +1666,28 @@ evaluate_subexp_standard (struct type *expect_type,
}
else
{
- arg1 = value_subscript (arg1, arg2);
+ arg1 = coerce_ref (arg1);
+ type = check_typedef (value_type (arg1));
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRING:
+ arg1 = value_subscript (arg1, arg2);
+ break;
+
+ case TYPE_CODE_BITSTRING:
+ arg1 = value_bitstring_subscript (LA_BOOL_TYPE, arg1, arg2);
+ break;
+
+ default:
+ if (TYPE_NAME (type))
+ error (_("cannot subscript something of type `%s'"),
+ TYPE_NAME (type));
+ else
+ error (_("cannot subscript requested type"));
+ }
}
}
return (arg1);
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 34bacaa..909c1a0 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -171,6 +171,11 @@ an integer nor a pointer of the same type."));
}
/* Return the value of ARRAY[IDX].
+
+ ARRAY may be of type TYPE_CODE_ARRAY or TYPE_CODE_STRING. If the
+ current language supports C-style arrays, it may also be TYPE_CODE_PTR.
+ To access TYPE_CODE_BITSTRING values, use value_bitstring_subscript.
+
See comments in value_coerce_array() for rationale for reason for
doing lower bounds adjustment here rather than there.
FIXME: Perhaps we should validate that the index is valid and if
@@ -218,34 +223,6 @@ value_subscript (struct value *array, struct value *idx)
array = value_coerce_array (array);
}
- if (TYPE_CODE (tarray) == TYPE_CODE_BITSTRING)
- {
- struct type *range_type = TYPE_INDEX_TYPE (tarray);
- LONGEST index = value_as_long (idx);
- struct value *v;
- int offset, byte, bit_index;
- LONGEST lowerbound, upperbound;
- get_discrete_bounds (range_type, &lowerbound, &upperbound);
- if (index < lowerbound || index > upperbound)
- error (_("bitstring index out of range"));
- index -= lowerbound;
- offset = index / TARGET_CHAR_BIT;
- byte = *((char *) value_contents (array) + offset);
- bit_index = index % TARGET_CHAR_BIT;
- byte >>= (gdbarch_bits_big_endian (current_gdbarch) ?
- TARGET_CHAR_BIT - 1 - bit_index : bit_index);
- v = value_from_longest (LA_BOOL_TYPE, byte & 1);
- set_value_bitpos (v, bit_index);
- set_value_bitsize (v, 1);
- VALUE_LVAL (v) = VALUE_LVAL (array);
- if (VALUE_LVAL (array) == lval_internalvar)
- VALUE_LVAL (v) = lval_internalvar_component;
- VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
- VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array);
- set_value_offset (v, offset + value_offset (array));
- return v;
- }
-
if (c_style)
return value_ind (value_add (array, idx));
else
@@ -286,6 +263,52 @@ value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound
set_value_offset (v, value_offset (array) + elt_offs);
return v;
}
+
+/* Return the value of BITSTRING[IDX] as (boolean) type TYPE. */
+
+struct value *
+value_bitstring_subscript (struct type *type,
+ struct value *bitstring, struct value *idx)
+{
+
+ struct type *bitstring_type, *range_type;
+ LONGEST index = value_as_long (idx);
+ struct value *v;
+ int offset, byte, bit_index;
+ LONGEST lowerbound, upperbound;
+
+ bitstring_type = check_typedef (value_type (bitstring));
+ gdb_assert (TYPE_CODE (bitstring_type) == TYPE_CODE_BITSTRING);
+
+ range_type = TYPE_INDEX_TYPE (bitstring_type);
+ get_discrete_bounds (range_type, &lowerbound, &upperbound);
+ if (index < lowerbound || index > upperbound)
+ error (_("bitstring index out of range"));
+
+ index -= lowerbound;
+ offset = index / TARGET_CHAR_BIT;
+ byte = *((char *) value_contents (bitstring) + offset);
+
+ bit_index = index % TARGET_CHAR_BIT;
+ byte >>= (gdbarch_bits_big_endian (current_gdbarch) ?
+ TARGET_CHAR_BIT - 1 - bit_index : bit_index);
+
+ v = value_from_longest (type, byte & 1);
+
+ set_value_bitpos (v, bit_index);
+ set_value_bitsize (v, 1);
+
+ VALUE_LVAL (v) = VALUE_LVAL (bitstring);
+ if (VALUE_LVAL (bitstring) == lval_internalvar)
+ VALUE_LVAL (v) = lval_internalvar_component;
+ VALUE_ADDRESS (v) = VALUE_ADDRESS (bitstring);
+ VALUE_FRAME_ID (v) = VALUE_FRAME_ID (bitstring);
+
+ set_value_offset (v, offset + value_offset (bitstring));
+
+ return v;
+}
+
/* Check to see if either argument is a structure, or a reference to
one. This is called so we know whether to go ahead with the normal
diff --git a/gdb/value.h b/gdb/value.h
index 2aac9b2d..77de981 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -405,6 +405,10 @@ extern struct value *value_repeat (struct value *arg1, int count);
extern struct value *value_subscript (struct value *array, struct value *idx);
+extern struct value *value_bitstring_subscript (struct type *type,
+ struct value *bitstring,
+ struct value *idx);
+
extern struct value *register_value_being_returned (struct type *valtype,
struct regcache *retbuf);