aboutsummaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
authorPer Bothner <per@bothner.com>1995-12-01 08:06:45 +0000
committerPer Bothner <per@bothner.com>1995-12-01 08:06:45 +0000
commit5f3e7bfcbfcd9a744d69e5ed2a2a56af38bf2e35 (patch)
tree94186163ae85f4a226b03c77a04fb35573bcb02a /gdb/valops.c
parentc8b2ba5d4801584559e674774b640b1da8c74738 (diff)
downloadgdb-5f3e7bfcbfcd9a744d69e5ed2a2a56af38bf2e35.zip
gdb-5f3e7bfcbfcd9a744d69e5ed2a2a56af38bf2e35.tar.gz
gdb-5f3e7bfcbfcd9a744d69e5ed2a2a56af38bf2e35.tar.bz2
* valops.c (value_slice): Implement (value) bitstring slices.
* valprint.c (val_print): If TYPE_LENGTH is zero, don't automatically print "<incomplete type>" - Chill has zero-length (string) types.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index b30f4b0..6e6eae0 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2155,35 +2155,60 @@ value_slice (array, lowbound, length)
value_ptr array;
int lowbound, length;
{
+ struct type *slice_range_type, *slice_type, *range_type;
+ LONGEST lowerbound, upperbound, offset;
+ value_ptr slice;
struct type *array_type;
array_type = check_typedef (VALUE_TYPE (array));
COERCE_VARYING_ARRAY (array, array_type);
- if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
- error ("not implemented - bitstring slice");
if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
- && TYPE_CODE (array_type) != TYPE_CODE_STRING)
+ && TYPE_CODE (array_type) != TYPE_CODE_STRING
+ && TYPE_CODE (array_type) != TYPE_CODE_BITSTRING)
error ("cannot take slice of non-array");
+ range_type = TYPE_INDEX_TYPE (array_type);
+ if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
+ error ("slice from bad array or bitstring");
+ if (lowbound < lowerbound || length < 0
+ || lowbound + length - 1 > upperbound
+ /* Chill allows zero-length strings but not arrays. */
+ || (current_language->la_language == language_chill
+ && length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY))
+ error ("slice out of range");
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ slice_range_type = create_range_type ((struct type*) NULL,
+ TYPE_TARGET_TYPE (range_type),
+ lowerbound, lowerbound + length - 1);
+ if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
+ {
+ int i;
+ slice_type = create_set_type ((struct type*) NULL, slice_range_type);
+ TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING;
+ slice = value_zero (slice_type, not_lval);
+ for (i = 0; i < length; i++)
+ {
+ int element = value_bit_index (array_type,
+ VALUE_CONTENTS (array),
+ lowbound + i);
+ if (element < 0)
+ error ("internal error accessing bitstring");
+ else if (element > 0)
+ {
+ int j = i % TARGET_CHAR_BIT;
+ if (BITS_BIG_ENDIAN)
+ j = TARGET_CHAR_BIT - 1 - j;
+ VALUE_CONTENTS_RAW (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
+ }
+ }
+ /* We should set the address, bitssize, and bitspos, so the clice
+ can be used on the LHS, but that may require extensions to
+ value_assign. For now, just leave as a non_lval. FIXME. */
+ }
else
{
- struct type *slice_range_type, *slice_type;
- value_ptr slice;
- struct type *range_type = TYPE_FIELD_TYPE (array_type,0);
struct type *element_type = TYPE_TARGET_TYPE (array_type);
- LONGEST lowerbound, upperbound, offset;
-
- if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
- error ("slice from bad array");
offset
= (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
- if (lowbound < lowerbound || length < 0
- || lowbound + length - 1 > upperbound)
- error ("slice out of range");
- /* FIXME-type-allocation: need a way to free this type when we are
- done with it. */
- slice_range_type = create_range_type ((struct type*) NULL,
- TYPE_TARGET_TYPE (range_type),
- lowerbound,
- lowerbound + length - 1);
slice_type = create_array_type ((struct type*) NULL, element_type,
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
@@ -2199,8 +2224,8 @@ value_slice (array, lowbound, length)
VALUE_LVAL (slice) = VALUE_LVAL (array);
VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset;
- return slice;
}
+ return slice;
}
/* Assuming chill_varying_type (VARRAY) is true, return an equivalent