diff options
author | Per Bothner <per@bothner.com> | 1995-09-27 17:24:45 +0000 |
---|---|---|
committer | Per Bothner <per@bothner.com> | 1995-09-27 17:24:45 +0000 |
commit | 37d190e0057b8654a308d39ca709eb0583d9137f (patch) | |
tree | bbb633ac513806fa4fe4f46fa88ab86df3fef100 /gdb/valops.c | |
parent | 4cbbec3182422f6a4633947ad7e346f3115f8b71 (diff) | |
download | ppe42-binutils-37d190e0057b8654a308d39ca709eb0583d9137f.tar.gz ppe42-binutils-37d190e0057b8654a308d39ca709eb0583d9137f.zip |
* 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.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r-- | gdb/valops.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/gdb/valops.c b/gdb/valops.c index 323f296540..46a22a246e 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; + } } } |