diff options
author | Richard Stallman <rms@gnu.org> | 1993-09-22 18:26:01 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-09-22 18:26:01 +0000 |
commit | 635b1dad854b47d35904cbed864193e6345b91ea (patch) | |
tree | a7c4017a6c649fef79ef4c0c162159ad5157ed12 | |
parent | 214a36e8508ab10a3ef23f682a0469a2e5255bd3 (diff) | |
download | gcc-635b1dad854b47d35904cbed864193e6345b91ea.zip gcc-635b1dad854b47d35904cbed864193e6345b91ea.tar.gz gcc-635b1dad854b47d35904cbed864193e6345b91ea.tar.bz2 |
(build_component_ref): For a field in an anonymous union,
make two nested COMPONENT_REFs.
(lookup_field): Additional arg INDIRECT.
From-SVN: r5400
-rw-r--r-- | gcc/c-typeck.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index a298c57..9ce2929 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1033,11 +1033,16 @@ default_conversion (exp) return exp; } -/* Look up component name in the structure type definition. */ +/* Look up component name in the structure type definition. + + If this component name is found indirectly within an anonymous union, + store in *INDIRECT the component which directly contains + that anonymous union. Otherwise, set *INDIRECT to 0. */ static tree -lookup_field (type, component) +lookup_field (type, component, indirect) tree type, component; + tree *indirect; { tree field; @@ -1066,11 +1071,15 @@ lookup_field (type, component) /* Step through all anon unions in linear fashion. */ while (DECL_NAME (field_array[bot]) == NULL_TREE) { - tree anon; + tree anon, junk; + field = field_array[bot++]; - anon = lookup_field (TREE_TYPE (field), component); + anon = lookup_field (TREE_TYPE (field), component, &junk); if (anon != NULL_TREE) - return anon; + { + *indirect = field; + return anon; + } } /* Entire record is only anon unions. */ @@ -1101,9 +1110,13 @@ lookup_field (type, component) { if (DECL_NAME (field) == NULL_TREE) { - tree anon = lookup_field (TREE_TYPE (field), component); + tree junk; + tree anon = lookup_field (TREE_TYPE (field), component, &junk); if (anon != NULL_TREE) - return anon; + { + *indirect = field; + return anon; + } } if (DECL_NAME (field) == component) @@ -1111,6 +1124,7 @@ lookup_field (type, component) } } + *indirect = NULL_TREE; return field; } @@ -1147,13 +1161,15 @@ build_component_ref (datum, component) if (code == RECORD_TYPE || code == UNION_TYPE) { + tree indirect = 0; + if (TYPE_SIZE (type) == 0) { incomplete_type_error (NULL_TREE, type); return error_mark_node; } - field = lookup_field (type, component); + field = lookup_field (type, component, &indirect); if (!field) { @@ -1166,6 +1182,19 @@ build_component_ref (datum, component) if (TREE_TYPE (field) == error_mark_node) return error_mark_node; + /* If FIELD was found buried within an anonymous union, + make one COMPONENT_REF to get that anonymous union, + then fall thru to make a second COMPONENT_REF to get FIELD. */ + if (indirect != 0) + { + ref = build (COMPONENT_REF, TREE_TYPE (indirect), datum, indirect); + if (TREE_READONLY (datum) || TREE_READONLY (indirect)) + TREE_READONLY (ref) = 1; + if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (indirect)) + TREE_THIS_VOLATILE (ref) = 1; + datum = ref; + } + ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field); if (TREE_READONLY (datum) || TREE_READONLY (field)) |