aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/ch-valprint.c18
-rw-r--r--gdb/gdbtypes.c63
-rw-r--r--gdb/gdbtypes.h2
4 files changed, 73 insertions, 19 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bb8b927..c9965a8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,12 @@
+Wed Oct 4 17:23:03 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdbtypes.c (get_discrete_bounds): New function.
+ (force_to_range_type): Use get_discrete_bounds.
+ * gdbtypes.h (get_discrete_bounds): Add declaration.
+ * valarith.c (value_bit_index): Generalize to use get_discrete_bounds.
+ * ch-valprint.c (chill_val_print): Make (power)sets and bitstring
+ support use get_discrete_bounds and generally be more robust.
+
Tue Oct 3 16:54:56 1995 Stan Shebs <shebs@andros.cygnus.com>
* remote-nrom.c (nrom_ops): Add value for to_thread_alive,
diff --git a/gdb/ch-valprint.c b/gdb/ch-valprint.c
index 795aca6..120d8ad 100644
--- a/gdb/ch-valprint.c
+++ b/gdb/ch-valprint.c
@@ -347,8 +347,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
{
struct type *range = elttype;
- int low_bound = TYPE_LOW_BOUND (range);
- int high_bound = TYPE_HIGH_BOUND (range);
+ LONGEST low_bound, high_bound;
int i;
int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
int need_comma = 0;
@@ -357,9 +356,23 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
fputs_filtered ("B'", stream);
else
fputs_filtered ("[", stream);
+
+ i = get_discrete_bounds (range, &low_bound, &high_bound);
+ maybe_bad_bstring:
+ if (i < 0)
+ {
+ fputs_filtered ("<error value>", stream);
+ goto done;
+ }
+
for (i = low_bound; i <= high_bound; i++)
{
int element = value_bit_index (type, valaddr, i);
+ if (element < 0)
+ {
+ i = element;
+ goto maybe_bad_bstring;
+ }
if (is_bitstring)
fprintf_filtered (stream, "%d", element);
else if (element)
@@ -381,6 +394,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
}
}
+ done:
if (is_bitstring)
fputs_filtered ("'", stream);
else
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ca27e4c..2a17764 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -336,6 +336,48 @@ create_range_type (result_type, index_type, low_bound, high_bound)
return (result_type);
}
+/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type TYPE.
+ Return 1 of type is a range type, 0 if it is discrete (and bounds
+ will fit in LONGEST), or -1 otherwise. */
+
+int
+get_discrete_bounds (type, lowp, highp)
+ struct type *type;
+ LONGEST *lowp, *highp;
+{
+ switch (TYPE_CODE (type))
+ {
+ TYPE_CODE_RANGE:
+ *lowp = TYPE_LOW_BOUND (type);
+ *highp = TYPE_HIGH_BOUND (type);
+ return 1;
+ case TYPE_CODE_ENUM:
+ *lowp = TYPE_FIELD_BITPOS (type, 0);
+ *highp = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
+ return 0;
+ case TYPE_CODE_BOOL:
+ *lowp = 0;
+ *highp = 1;
+ return 0;
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (type) >= sizeof (LONGEST)) /* Too big */
+ return -1;
+ if (!TYPE_UNSIGNED (type))
+ {
+ *lowp = - (1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
+ *highp = -*lowp - 1;
+ return 0;
+ }
+ /* ... fall through for unsigned ints ... */
+ case TYPE_CODE_CHAR:
+ *lowp = 0;
+ *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT) - 1;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
/* A lot of code assumes that the "index type" of an array/string/
set/bitstring is specifically a range type, though in some languages
it can be any discrete type. */
@@ -350,26 +392,13 @@ force_to_range_type (type)
return type;
case TYPE_CODE_ENUM:
- {
- int low_bound = TYPE_FIELD_BITPOS (type, 0);
- int high_bound = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
- struct type *range_type =
- create_range_type (NULL, type, low_bound, high_bound);
- TYPE_NAME (range_type) = TYPE_NAME (range_type);
- TYPE_DUMMY_RANGE (range_type) = 1;
- return range_type;
- }
case TYPE_CODE_BOOL:
- {
- struct type *range_type = create_range_type (NULL, type, 0, 1);
- TYPE_NAME (range_type) = TYPE_NAME (range_type);
- TYPE_DUMMY_RANGE (range_type) = 1;
- return range_type;
- }
case TYPE_CODE_CHAR:
{
- int char_max = 1 << (TYPE_LENGTH (type) * HOST_CHAR_BIT) - 1;
- struct type *range_type = create_range_type (NULL, type, 0, char_max);
+ LONGEST low_bound, high_bound;
+ struct type *range_type;
+ get_discrete_bounds (type, &low_bound, &high_bound);
+ range_type = create_range_type (NULL, type, low_bound, high_bound);
TYPE_NAME (range_type) = TYPE_NAME (range_type);
TYPE_DUMMY_RANGE (range_type) = 1;
return range_type;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 50185ba..29d8601 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -761,6 +761,8 @@ lookup_fundamental_type PARAMS ((struct objfile *, int));
extern void
fill_in_vptr_fieldno PARAMS ((struct type *));
+extern int get_discrete_bounds PARAMS ((struct type*, LONGEST*, LONGEST*));
+
#if MAINTENANCE_CMDS
extern void recursive_dump_type PARAMS ((struct type *, int));
#endif