Implement anonymous structs.
* cp-tree.h (ANON_AGGR_TYPE_P): Rename from ANON_UNION_TYPE_P. * class.c, decl.c, decl2.c, init.c, pt.c, search.c, typeck.c: Adjust. * class.c (finish_struct_1): Remove redundant check for anon struct. * decl.c (fixup_anonymous_aggr): Renamed from fixup_anonymous_union. (check_tag_decl): Check for anonymous struct here. * decl2.c (build_anon_union_vars): Catch anon struct at file scope. * init.c (sort_member_init, emit_base_init): Handle getting fields as well as names in current_member_init_list. (perform_member_init): Handle getting an anon aggr. * method.c (do_build_assign_ref): Don't descend into anon aggrs. (do_build_copy_constructor): Likewise. From-SVN: r27027
This commit is contained in:
parent
cb6c8ebb73
commit
6bdb8141ec
|
@ -1,3 +1,18 @@
|
|||
1999-05-19 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
Implement anonymous structs.
|
||||
* cp-tree.h (ANON_AGGR_TYPE_P): Rename from ANON_UNION_TYPE_P.
|
||||
* class.c, decl.c, decl2.c, init.c, pt.c, search.c, typeck.c: Adjust.
|
||||
* class.c (finish_struct_1): Remove redundant check for anon struct.
|
||||
* decl.c (fixup_anonymous_aggr): Renamed from fixup_anonymous_union.
|
||||
(check_tag_decl): Check for anonymous struct here.
|
||||
* decl2.c (build_anon_union_vars): Catch anon struct at file scope.
|
||||
* init.c (sort_member_init, emit_base_init): Handle getting fields
|
||||
as well as names in current_member_init_list.
|
||||
(perform_member_init): Handle getting an anon aggr.
|
||||
* method.c (do_build_assign_ref): Don't descend into anon aggrs.
|
||||
(do_build_copy_constructor): Likewise.
|
||||
|
||||
1999-05-19 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* tree.c (cp_build_qualified_type): Don't allow qualified function
|
||||
|
|
|
@ -1337,7 +1337,7 @@ delete_duplicate_fields_1 (field, fields)
|
|||
tree prev = 0;
|
||||
if (DECL_NAME (field) == 0)
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)
|
||||
if (! ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
return fields;
|
||||
|
||||
for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
|
||||
|
@ -1350,7 +1350,7 @@ delete_duplicate_fields_1 (field, fields)
|
|||
{
|
||||
if (DECL_NAME (x) == 0)
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)
|
||||
if (! ANON_AGGR_TYPE_P (TREE_TYPE (x)))
|
||||
continue;
|
||||
TYPE_FIELDS (TREE_TYPE (x))
|
||||
= delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
|
||||
|
@ -2953,7 +2953,7 @@ finish_struct_anon (t)
|
|||
continue;
|
||||
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
{
|
||||
tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
|
||||
for (; *uelt; uelt = &TREE_CHAIN (*uelt))
|
||||
|
@ -3135,9 +3135,6 @@ finish_struct_1 (t, warn_anon)
|
|||
int has_pointers = 0;
|
||||
tree inline_friends;
|
||||
|
||||
if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
|
||||
pedwarn ("anonymous class type not used to declare any objects");
|
||||
|
||||
if (TYPE_SIZE (t))
|
||||
{
|
||||
if (IS_AGGR_TYPE (t))
|
||||
|
|
|
@ -696,7 +696,7 @@ struct lang_type
|
|||
unsigned const_needs_init : 1;
|
||||
unsigned ref_needs_init : 1;
|
||||
unsigned has_const_assign_ref : 1;
|
||||
unsigned anon_union : 1;
|
||||
unsigned anon_aggr : 1;
|
||||
|
||||
unsigned has_nonpublic_ctor : 2;
|
||||
unsigned has_nonpublic_assign_ref : 2;
|
||||
|
@ -1764,16 +1764,14 @@ extern int flag_new_for_scope;
|
|||
Just used to communicate formatting information to dbxout.c. */
|
||||
#define DECL_OPERATOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.operator_attr)
|
||||
|
||||
#define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0)
|
||||
|
||||
/* Nonzero if TYPE is an anonymous union type. We have to use a flag for
|
||||
this because "A union for which objects or pointers are declared is not
|
||||
an anonymous union" [class.union]. */
|
||||
#define ANON_UNION_TYPE_P(NODE) \
|
||||
/* Nonzero if TYPE is an anonymous union or struct type. We have to use a
|
||||
flag for this because "A union for which objects or pointers are
|
||||
declared is not an anonymous union" [class.union]. */
|
||||
#define ANON_AGGR_TYPE_P(NODE) \
|
||||
(TYPE_LANG_SPECIFIC (NODE) \
|
||||
&& TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union)
|
||||
#define SET_ANON_UNION_TYPE_P(NODE) \
|
||||
(TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union = 1)
|
||||
&& TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_aggr)
|
||||
#define SET_ANON_AGGR_TYPE_P(NODE) \
|
||||
(TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_aggr = 1)
|
||||
|
||||
#define UNKNOWN_TYPE LANG_TYPE
|
||||
|
||||
|
@ -2879,7 +2877,7 @@ extern int in_function_p PROTO((void));
|
|||
extern void replace_defarg PROTO((tree, tree));
|
||||
extern void print_other_binding_stack PROTO((struct binding_level *));
|
||||
extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
|
||||
extern void fixup_anonymous_union PROTO((tree));
|
||||
extern void fixup_anonymous_aggr PROTO((tree));
|
||||
extern int check_static_variable_definition PROTO((tree, tree));
|
||||
extern void push_local_binding PROTO((tree, tree, int));
|
||||
extern int push_class_binding PROTO((tree, tree));
|
||||
|
|
|
@ -4338,7 +4338,7 @@ pushdecl_class_level (x)
|
|||
if (TREE_CODE (x) == TYPE_DECL)
|
||||
set_identifier_type_value (name, TREE_TYPE (x));
|
||||
}
|
||||
else if (ANON_UNION_TYPE_P (TREE_TYPE (x)))
|
||||
else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
|
||||
{
|
||||
tree f;
|
||||
|
||||
|
@ -7011,7 +7011,7 @@ define_function (name, type, function_code, pfn, library_name)
|
|||
union type.) */
|
||||
|
||||
void
|
||||
fixup_anonymous_union (t)
|
||||
fixup_anonymous_aggr (t)
|
||||
tree t;
|
||||
{
|
||||
tree *q;
|
||||
|
@ -7098,12 +7098,15 @@ check_tag_decl (declspecs)
|
|||
/* Check for an anonymous union. We're careful
|
||||
accessing TYPE_IDENTIFIER because some built-in types, like
|
||||
pointer-to-member types, do not have TYPE_NAME. */
|
||||
else if (t && TREE_CODE (t) == UNION_TYPE
|
||||
else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t))
|
||||
&& TYPE_NAME (t)
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
|
||||
{
|
||||
/* Anonymous unions are objects, so they can have specifiers. */;
|
||||
SET_ANON_UNION_TYPE_P (t);
|
||||
SET_ANON_AGGR_TYPE_P (t);
|
||||
|
||||
if (TREE_CODE (t) != UNION_TYPE && pedantic && ! in_system_header)
|
||||
pedwarn ("ISO C++ prohibits anonymous structs");
|
||||
}
|
||||
|
||||
else if (ob_modifier)
|
||||
|
@ -7149,9 +7152,9 @@ shadow_tag (declspecs)
|
|||
union { ... } ;
|
||||
because there is no declarator after the union, the parser
|
||||
sends that declaration here. */
|
||||
if (t && ANON_UNION_TYPE_P (t))
|
||||
if (t && ANON_AGGR_TYPE_P (t))
|
||||
{
|
||||
fixup_anonymous_union (t);
|
||||
fixup_anonymous_aggr (t);
|
||||
|
||||
if (TYPE_FIELDS (t))
|
||||
{
|
||||
|
@ -10053,7 +10056,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
/* Static anonymous unions are dealt with here. */
|
||||
if (staticp && decl_context == TYPENAME
|
||||
&& TREE_CODE (declspecs) == TREE_LIST
|
||||
&& ANON_UNION_TYPE_P (TREE_VALUE (declspecs)))
|
||||
&& ANON_AGGR_TYPE_P (TREE_VALUE (declspecs)))
|
||||
decl_context = FIELD;
|
||||
|
||||
/* Give error if `const,' `volatile,' `inline,' `friend,' or `virtual'
|
||||
|
|
|
@ -887,10 +887,10 @@ grok_x_components (specs)
|
|||
|
||||
/* The only case where we need to do anything additional here is an
|
||||
anonymous union field, e.g.: `struct S { union { int i; }; };'. */
|
||||
if (t == NULL_TREE || !ANON_UNION_TYPE_P (t))
|
||||
if (t == NULL_TREE || !ANON_AGGR_TYPE_P (t))
|
||||
return;
|
||||
|
||||
fixup_anonymous_union (t);
|
||||
fixup_anonymous_aggr (t);
|
||||
finish_member_declaration (build_lang_field_decl (FIELD_DECL,
|
||||
NULL_TREE,
|
||||
t));
|
||||
|
@ -2152,6 +2152,11 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
|
|||
tree main_decl = NULL_TREE;
|
||||
tree field;
|
||||
|
||||
/* Rather than write the code to handle the non-union case,
|
||||
just give an error. */
|
||||
if (TREE_CODE (type) != UNION_TYPE)
|
||||
error ("anonymous struct not inside named type");
|
||||
|
||||
for (field = TYPE_FIELDS (type);
|
||||
field != NULL_TREE;
|
||||
field = TREE_CHAIN (field))
|
||||
|
@ -2173,7 +2178,7 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
|
|||
cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
|
||||
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
{
|
||||
decl = build_anon_union_vars (field, elems, static_p, external_p);
|
||||
if (!decl)
|
||||
|
@ -2205,7 +2210,7 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
|
|||
TREE_ASM_WRITTEN (decl) = 1;
|
||||
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
/* The remainder of the processing was already done in the
|
||||
recursive call. */
|
||||
continue;
|
||||
|
|
|
@ -154,16 +154,25 @@ perform_member_init (member, name, init, explicit)
|
|||
|
||||
expand_start_target_temps ();
|
||||
|
||||
if (TYPE_NEEDS_CONSTRUCTING (type)
|
||||
|| (init && TYPE_HAS_CONSTRUCTOR (type)))
|
||||
decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
|
||||
|
||||
/* Deal with this here, as we will get confused if we try to call the
|
||||
assignment op for an anonymous union. This can happen in a
|
||||
synthesized copy constructor. */
|
||||
if (ANON_AGGR_TYPE_P (type))
|
||||
{
|
||||
init = build (INIT_EXPR, type, decl, TREE_VALUE (init));
|
||||
TREE_SIDE_EFFECTS (init) = 1;
|
||||
expand_expr_stmt (init);
|
||||
}
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (type)
|
||||
|| (init && TYPE_HAS_CONSTRUCTOR (type)))
|
||||
{
|
||||
/* Since `init' is already a TREE_LIST on the current_member_init_list,
|
||||
only build it into one if we aren't already a list. */
|
||||
if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST)
|
||||
init = build_expr_list (NULL_TREE, init);
|
||||
|
||||
decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
|
||||
|
||||
if (explicit
|
||||
&& TREE_CODE (type) == ARRAY_TYPE
|
||||
&& init != NULL_TREE
|
||||
|
@ -186,7 +195,7 @@ perform_member_init (member, name, init, explicit)
|
|||
/* default-initialization. */
|
||||
if (AGGREGATE_TYPE_P (type))
|
||||
init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
cp_error ("default-initialization of `%#D', which has reference type",
|
||||
member);
|
||||
|
@ -216,8 +225,6 @@ perform_member_init (member, name, init, explicit)
|
|||
current_member_init_list. */
|
||||
if (init || explicit)
|
||||
{
|
||||
decl = build_component_ref (current_class_ref, name, NULL_TREE,
|
||||
explicit);
|
||||
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
|
||||
}
|
||||
}
|
||||
|
@ -275,16 +282,13 @@ sort_member_init (t)
|
|||
continue;
|
||||
name = TREE_PURPOSE (x);
|
||||
|
||||
#if 0
|
||||
/* This happens in templates, since the IDENTIFIER is replaced
|
||||
with the COMPONENT_REF in tsubst_expr. */
|
||||
field = (TREE_CODE (name) == COMPONENT_REF
|
||||
? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name));
|
||||
#else
|
||||
/* Let's find out when this happens. */
|
||||
my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348);
|
||||
field = IDENTIFIER_CLASS_VALUE (name);
|
||||
#endif
|
||||
if (TREE_CODE (name) == IDENTIFIER_NODE)
|
||||
field = IDENTIFIER_CLASS_VALUE (name);
|
||||
else
|
||||
{
|
||||
my_friendly_assert (TREE_CODE (name) == FIELD_DECL, 348);
|
||||
field = name;
|
||||
}
|
||||
|
||||
/* If one member shadows another, get the outermost one. */
|
||||
if (TREE_CODE (field) == TREE_LIST)
|
||||
|
@ -635,15 +639,8 @@ emit_base_init (t, immediately)
|
|||
init = TREE_VALUE (mem_init_list);
|
||||
from_init_list = 1;
|
||||
|
||||
#if 0
|
||||
if (TREE_CODE (name) == COMPONENT_REF)
|
||||
name = DECL_NAME (TREE_OPERAND (name, 1));
|
||||
#else
|
||||
/* Also see if it's ever a COMPONENT_REF here. If it is, we
|
||||
need to do `expand_assignment (name, init, 0, 0);' and
|
||||
a continue. */
|
||||
my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349);
|
||||
#endif
|
||||
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE
|
||||
|| TREE_CODE (name) == FIELD_DECL, 349);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -672,9 +669,11 @@ emit_base_init (t, immediately)
|
|||
{
|
||||
name = TREE_PURPOSE (mem_init_list);
|
||||
init = TREE_VALUE (mem_init_list);
|
||||
/* XXX: this may need the COMPONENT_REF operand 0 check if
|
||||
it turns out we actually get them. */
|
||||
field = IDENTIFIER_CLASS_VALUE (name);
|
||||
|
||||
if (TREE_CODE (name) == IDENTIFIER_NODE)
|
||||
field = IDENTIFIER_CLASS_VALUE (name);
|
||||
else
|
||||
field = name;
|
||||
|
||||
/* If one member shadows another, get the outermost one. */
|
||||
if (TREE_CODE (field) == TREE_LIST)
|
||||
|
@ -831,7 +830,7 @@ initializing_context (field)
|
|||
|
||||
/* Anonymous union members can be initialized in the first enclosing
|
||||
non-anonymous union context. */
|
||||
while (t && ANON_UNION_TYPE_P (t))
|
||||
while (t && ANON_AGGR_TYPE_P (t))
|
||||
t = TYPE_CONTEXT (t);
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -2282,18 +2282,10 @@ do_build_copy_constructor (fndecl)
|
|||
continue;
|
||||
}
|
||||
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& ANON_UNION_TYPE_P (t)
|
||||
&& ANON_AGGR_TYPE_P (t)
|
||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||
{
|
||||
do
|
||||
{
|
||||
init = build (COMPONENT_REF, t, init, field);
|
||||
field = largest_union_member (t);
|
||||
}
|
||||
while ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& ANON_UNION_TYPE_P (t)
|
||||
&& TYPE_FIELDS (t) != NULL_TREE);
|
||||
}
|
||||
/* Just use the field; anonymous types can't have
|
||||
nontrivial copy ctors or assignment ops. */;
|
||||
else
|
||||
continue;
|
||||
|
||||
|
@ -2301,7 +2293,7 @@ do_build_copy_constructor (fndecl)
|
|||
init = build_tree_list (NULL_TREE, init);
|
||||
|
||||
current_member_init_list
|
||||
= tree_cons (DECL_NAME (field), init, current_member_init_list);
|
||||
= tree_cons (field, init, current_member_init_list);
|
||||
}
|
||||
current_member_init_list = nreverse (current_member_init_list);
|
||||
current_base_init_list = nreverse (current_base_init_list);
|
||||
|
@ -2390,19 +2382,10 @@ do_build_assign_ref (fndecl)
|
|||
continue;
|
||||
}
|
||||
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& ANON_UNION_TYPE_P (t)
|
||||
&& ANON_AGGR_TYPE_P (t)
|
||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||
{
|
||||
do
|
||||
{
|
||||
comp = build (COMPONENT_REF, t, comp, field);
|
||||
init = build (COMPONENT_REF, t, init, field);
|
||||
field = largest_union_member (t);
|
||||
}
|
||||
while ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& ANON_UNION_TYPE_P (t)
|
||||
&& TYPE_FIELDS (t) != NULL_TREE);
|
||||
}
|
||||
/* Just use the field; anonymous types can't have
|
||||
nontrivial copy ctors or assignment ops. */;
|
||||
else
|
||||
continue;
|
||||
|
||||
|
|
|
@ -4884,8 +4884,8 @@ instantiate_class_template (type)
|
|||
TYPE_PACKED (type) = TYPE_PACKED (pattern);
|
||||
TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
|
||||
TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
|
||||
if (ANON_UNION_TYPE_P (pattern))
|
||||
SET_ANON_UNION_TYPE_P (type);
|
||||
if (ANON_AGGR_TYPE_P (pattern))
|
||||
SET_ANON_AGGR_TYPE_P (type);
|
||||
|
||||
/* We must copy the arguments to the permanent obstack since
|
||||
during the tsubst'ing below they may wind up in the
|
||||
|
|
|
@ -534,7 +534,7 @@ lookup_field_1 (type, name)
|
|||
#endif /* GATHER_STATISTICS */
|
||||
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (field)) == 'd', 0);
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
{
|
||||
tree temp = lookup_field_1 (TREE_TYPE (field), name);
|
||||
if (temp)
|
||||
|
@ -610,7 +610,7 @@ context_for_name_lookup (decl)
|
|||
declared. */
|
||||
tree context = DECL_REAL_CONTEXT (decl);
|
||||
|
||||
while (TYPE_P (context) && ANON_UNION_TYPE_P (context))
|
||||
while (TYPE_P (context) && ANON_AGGR_TYPE_P (context))
|
||||
context = TYPE_CONTEXT (context);
|
||||
if (!context)
|
||||
context = global_namespace;
|
||||
|
@ -2927,7 +2927,7 @@ dfs_push_decls (binfo, data)
|
|||
&& TREE_CODE (fields) != USING_DECL)
|
||||
setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0);
|
||||
else if (TREE_CODE (fields) == FIELD_DECL
|
||||
&& ANON_UNION_TYPE_P (TREE_TYPE (fields)))
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
|
||||
dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data);
|
||||
|
||||
method_vec = (CLASS_TYPE_P (type)
|
||||
|
@ -3001,7 +3001,7 @@ dfs_unuse_fields (binfo, data)
|
|||
|
||||
TREE_USED (fields) = 0;
|
||||
if (DECL_NAME (fields) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
|
||||
unuse_fields (TREE_TYPE (fields));
|
||||
}
|
||||
|
||||
|
|
|
@ -2006,7 +2006,7 @@ lookup_anon_field (t, type)
|
|||
|
||||
/* Otherwise, it could be nested, search harder. */
|
||||
if (DECL_NAME (field) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
{
|
||||
tree subfield = lookup_anon_field (TREE_TYPE (field), type);
|
||||
if (subfield)
|
||||
|
@ -2216,7 +2216,7 @@ build_component_ref (datum, component, basetype_path, protect)
|
|||
tree context = DECL_FIELD_CONTEXT (field);
|
||||
tree base = context;
|
||||
while (!same_type_p (base, basetype) && TYPE_NAME (base)
|
||||
&& ANON_UNION_TYPE_P (base))
|
||||
&& ANON_AGGR_TYPE_P (base))
|
||||
{
|
||||
base = TYPE_CONTEXT (base);
|
||||
}
|
||||
|
@ -2246,7 +2246,7 @@ build_component_ref (datum, component, basetype_path, protect)
|
|||
basetype = base;
|
||||
|
||||
/* Handle things from anon unions here... */
|
||||
if (TYPE_NAME (context) && ANON_UNION_TYPE_P (context))
|
||||
if (TYPE_NAME (context) && ANON_AGGR_TYPE_P (context))
|
||||
{
|
||||
tree subfield = lookup_anon_field (basetype, context);
|
||||
tree subdatum = build_component_ref (datum, subfield,
|
||||
|
|
Loading…
Reference in New Issue