home *** CD-ROM | disk | FTP | other *** search
- 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.
-
- Index: gcc-2.95.2/gcc/cp/class.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/class.c,v
- retrieving revision 1.2
- diff -u -3 -p -r1.2 class.c
- --- gcc-2.95.2/gcc/cp/class.c 1999/11/05 06:11:44 1.2
- +++ gcc-2.95.2/gcc/cp/class.c 1999/11/05 06:12:00
- @@ -1336,7 +1336,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))
- @@ -1349,7 +1349,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)));
- @@ -2949,7 +2949,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))
- @@ -3130,9 +3130,6 @@ finish_struct_1 (t, warn_anon)
- int empty = 1;
- 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))
- {
- Index: gcc-2.95.2/gcc/cp/cp-tree.h
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/cp-tree.h,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 cp-tree.h
- --- gcc-2.95.2/gcc/cp/cp-tree.h 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/cp-tree.h 1999/11/05 06:12:00
- @@ -700,7 +700,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;
- @@ -1772,16 +1772,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
-
- @@ -2890,7 +2888,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));
- Index: gcc-2.95.2/gcc/cp/decl.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/decl.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 decl.c
- --- gcc-2.95.2/gcc/cp/decl.c 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/decl.c 1999/11/05 06:12:01
- @@ -4343,7 +4343,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;
-
- @@ -7017,7 +7017,7 @@ define_function (name, type, function_co
- union type.) */
-
- void
- -fixup_anonymous_union (t)
- +fixup_anonymous_aggr (t)
- tree t;
- {
- tree *q;
- @@ -7104,12 +7104,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)
- @@ -7155,9 +7158,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))
- {
- @@ -10087,7 +10090,7 @@ grokdeclarator (declarator, declspecs, d
- /* 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'
- Index: gcc-2.95.2/gcc/cp/decl2.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/decl2.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 decl2.c
- --- gcc-2.95.2/gcc/cp/decl2.c 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/decl2.c 1999/11/05 06:12:01
- @@ -893,10 +893,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));
- @@ -2158,6 +2158,11 @@ build_anon_union_vars (anon_decl, elems,
- 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))
- @@ -2179,7 +2184,7 @@ build_anon_union_vars (anon_decl, elems,
- 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)
- @@ -2211,7 +2216,7 @@ build_anon_union_vars (anon_decl, elems,
- 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;
- Index: gcc-2.95.2/gcc/cp/init.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/init.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 init.c
- --- gcc-2.95.2/gcc/cp/init.c 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/init.c 1999/11/05 06:12:01
- @@ -154,16 +154,25 @@ perform_member_init (member, name, init,
-
- 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,
- /* 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,
- 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)
- @@ -612,15 +616,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
- {
- @@ -649,9 +646,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)
- @@ -865,7 +864,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;
- }
- Index: gcc-2.95.2/gcc/cp/method.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/method.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 method.c
- --- gcc-2.95.2/gcc/cp/method.c 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/method.c 1999/11/05 06:12:01
- @@ -2267,18 +2267,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;
-
- @@ -2286,7 +2278,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);
- @@ -2375,19 +2367,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;
-
- Index: gcc-2.95.2/gcc/cp/pt.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/pt.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 pt.c
- --- gcc-2.95.2/gcc/cp/pt.c 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/pt.c 1999/11/05 06:12:01
- @@ -4886,8 +4886,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
- Index: gcc-2.95.2/gcc/cp/search.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/search.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 search.c
- --- gcc-2.95.2/gcc/cp/search.c 1999/11/05 01:09:46 1.1.1.1
- +++ gcc-2.95.2/gcc/cp/search.c 1999/11/05 06:12:01
- @@ -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;
- @@ -2939,7 +2939,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)
- @@ -3013,7 +3013,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));
- }
-
- Index: gcc-2.95.2/gcc/cp/typeck.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/typeck.c,v
- retrieving revision 1.2
- diff -u -3 -p -r1.2 typeck.c
- --- gcc-2.95.2/gcc/cp/typeck.c 1999/11/05 06:11:44 1.2
- +++ gcc-2.95.2/gcc/cp/typeck.c 1999/11/05 06:12:01
- @@ -2011,7 +2011,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)
- @@ -2221,7 +2221,7 @@ build_component_ref (datum, component, b
- 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);
- }
- @@ -2251,7 +2251,7 @@ build_component_ref (datum, component, b
- 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,
-