diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/ch-valprint.c | 18 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 63 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 2 |
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 |