Commit 535335bf by Jason Merrill Committed by Jason Merrill

init.c (sort_mem_initializers): Rename "field_type" to "ctx".

	* init.c (sort_mem_initializers): Rename "field_type" to "ctx".
	(build_field_list): Cache field type.

From-SVN: r162188
parent 57ece258
2010-07-14 Jason Merrill <jason@redhat.com> 2010-07-14 Jason Merrill <jason@redhat.com>
* init.c (sort_mem_initializers): Rename "field_type" to "ctx".
(build_field_list): Cache field type.
Implement C++0x unrestricted unions (N2544) Implement C++0x unrestricted unions (N2544)
* class.c (check_field_decl): Loosen union handling in C++0x. * class.c (check_field_decl): Loosen union handling in C++0x.
* method.c (walk_field_subobs): Split out from... * method.c (walk_field_subobs): Split out from...
......
...@@ -564,25 +564,27 @@ build_field_list (tree t, tree list, int *uses_unions_p) ...@@ -564,25 +564,27 @@ build_field_list (tree t, tree list, int *uses_unions_p)
for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields))
{ {
tree fieldtype;
/* Skip CONST_DECLs for enumeration constants and so forth. */ /* Skip CONST_DECLs for enumeration constants and so forth. */
if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields)) if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
continue; continue;
fieldtype = TREE_TYPE (fields);
/* Keep track of whether or not any fields are unions. */ /* Keep track of whether or not any fields are unions. */
if (TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE) if (TREE_CODE (fieldtype) == UNION_TYPE)
*uses_unions_p = 1; *uses_unions_p = 1;
/* For an anonymous struct or union, we must recursively /* For an anonymous struct or union, we must recursively
consider the fields of the anonymous type. They can be consider the fields of the anonymous type. They can be
directly initialized from the constructor. */ directly initialized from the constructor. */
if (ANON_AGGR_TYPE_P (TREE_TYPE (fields))) if (ANON_AGGR_TYPE_P (fieldtype))
{ {
/* Add this field itself. Synthesized copy constructors /* Add this field itself. Synthesized copy constructors
initialize the entire aggregate. */ initialize the entire aggregate. */
list = tree_cons (fields, NULL_TREE, list); list = tree_cons (fields, NULL_TREE, list);
/* And now add the fields in the anonymous aggregate. */ /* And now add the fields in the anonymous aggregate. */
list = build_field_list (TREE_TYPE (fields), list, list = build_field_list (fieldtype, list, uses_unions_p);
uses_unions_p);
} }
/* Add this field. */ /* Add this field. */
else if (DECL_NAME (fields)) else if (DECL_NAME (fields))
...@@ -718,7 +720,7 @@ sort_mem_initializers (tree t, tree mem_inits) ...@@ -718,7 +720,7 @@ sort_mem_initializers (tree t, tree mem_inits)
for (p = &sorted_inits; *p; ) for (p = &sorted_inits; *p; )
{ {
tree field; tree field;
tree field_type; tree ctx;
int done; int done;
init = *p; init = *p;
...@@ -736,13 +738,13 @@ sort_mem_initializers (tree t, tree mem_inits) ...@@ -736,13 +738,13 @@ sort_mem_initializers (tree t, tree mem_inits)
/* See if this field is a member of a union, or a member of a /* See if this field is a member of a union, or a member of a
structure contained in a union, etc. */ structure contained in a union, etc. */
for (field_type = DECL_CONTEXT (field); for (ctx = DECL_CONTEXT (field);
!same_type_p (field_type, t); !same_type_p (ctx, t);
field_type = TYPE_CONTEXT (field_type)) ctx = TYPE_CONTEXT (ctx))
if (TREE_CODE (field_type) == UNION_TYPE) if (TREE_CODE (ctx) == UNION_TYPE)
break; break;
/* If this field is not a member of a union, skip it. */ /* If this field is not a member of a union, skip it. */
if (TREE_CODE (field_type) != UNION_TYPE) if (TREE_CODE (ctx) != UNION_TYPE)
goto next; goto next;
/* If this union member has no explicit initializer, splice /* If this union member has no explicit initializer, splice
...@@ -766,37 +768,37 @@ sort_mem_initializers (tree t, tree mem_inits) ...@@ -766,37 +768,37 @@ sort_mem_initializers (tree t, tree mem_inits)
union { struct { int i; int j; }; }; union { struct { int i; int j; }; };
initializing both `i' and `j' makes sense. */ initializing both `i' and `j' makes sense. */
field_type = DECL_CONTEXT (field); ctx = DECL_CONTEXT (field);
done = 0; done = 0;
do do
{ {
tree last_field_type; tree last_ctx;
last_field_type = DECL_CONTEXT (last_field); last_ctx = DECL_CONTEXT (last_field);
while (1) while (1)
{ {
if (same_type_p (last_field_type, field_type)) if (same_type_p (last_ctx, ctx))
{ {
if (TREE_CODE (field_type) == UNION_TYPE) if (TREE_CODE (ctx) == UNION_TYPE)
error_at (DECL_SOURCE_LOCATION (current_function_decl), error_at (DECL_SOURCE_LOCATION (current_function_decl),
"initializations for multiple members of %qT", "initializations for multiple members of %qT",
last_field_type); last_ctx);
done = 1; done = 1;
break; break;
} }
if (same_type_p (last_field_type, t)) if (same_type_p (last_ctx, t))
break; break;
last_field_type = TYPE_CONTEXT (last_field_type); last_ctx = TYPE_CONTEXT (last_ctx);
} }
/* If we've reached the outermost class, then we're /* If we've reached the outermost class, then we're
done. */ done. */
if (same_type_p (field_type, t)) if (same_type_p (ctx, t))
break; break;
field_type = TYPE_CONTEXT (field_type); ctx = TYPE_CONTEXT (ctx);
} }
while (!done); while (!done);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment