diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/valops.c | 42 |
2 files changed, 44 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index fa4b413..fe104ce 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +Wed Sep 27 10:14:36 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * eval.c (evaluate_struct_tuple): New function. Used to evaluate + structure tuples. Now also handles Chill variant records. + (get_label): New function, used by evaluate_struct_tuple. + (evaluate_subexp_standard case OP_ARRAY): Use evaluate_struct_tuple. + (evaluate_labeled_field_init): Removed. + + * valops.c (search_struct_field): Generalize to work with Chill + variant records. + Sat Sep 23 01:22:23 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) * mdebugread.c (parse_partial_symbols): Reset includes_used diff --git a/gdb/valops.c b/gdb/valops.c index 323f296..46a22a2 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1535,16 +1535,40 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) error("there is no field named %s", name); return v; } - if (t_field_name && t_field_name[0] == '\0' - && TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION) + + if (t_field_name && t_field_name[0] == '\0') { - /* Look for a match through the fields of an anonymous union. */ - value_ptr v; - v = search_struct_field (name, arg1, offset, - TYPE_FIELD_TYPE (type, i), - looking_for_baseclass); - if (v) - return v; + struct type *field_type = TYPE_FIELD_TYPE (type, i); + if (TYPE_CODE (field_type) == TYPE_CODE_UNION + || TYPE_CODE (field_type) == TYPE_CODE_STRUCT) + { + /* Look for a match through the fields of an anonymous union, + or anonymous struct. C++ provides anonymous unions. + + In the GNU Chill implementation of variant record types, + each <alternative field> has an (anonymous) union type, + each member of the union represents a <variant alternative>. + Each <variant alternative> is represented as a struct, + with a member for each <variant field>. */ + + value_ptr v; + int new_offset = offset; + + /* This is pretty gross. In G++, the offset in an anonymous + union is relative to the beginning of the enclosing struct. + In the GNU Chill implementation of variant records, + the bitpos is zero in an anonymous union field, so we + have to add the offset of the union here. */ + if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT + || (TYPE_NFIELDS (field_type) > 0 + && TYPE_FIELD_BITPOS (field_type, 0) == 0)) + new_offset += TYPE_FIELD_BITPOS (type, i) / 8; + + v = search_struct_field (name, arg1, new_offset, field_type, + looking_for_baseclass); + if (v) + return v; + } } } |