diff options
author | Zack Weinberg <zack@gcc.gnu.org> | 2003-08-30 21:21:40 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2003-08-30 21:21:40 +0000 |
commit | bf7a697f0ad4399b6ef6abc542520c9be858356e (patch) | |
tree | cdce6115b5f67f736d2426ccd24c4fa2c238f753 /gcc/c-decl.c | |
parent | 496b84c8edb6289c1e9e24c8c69ae2f63d1bcd13 (diff) | |
download | gcc-bf7a697f0ad4399b6ef6abc542520c9be858356e.zip gcc-bf7a697f0ad4399b6ef6abc542520c9be858356e.tar.gz gcc-bf7a697f0ad4399b6ef6abc542520c9be858356e.tar.bz2 |
c-tree.h (C_TYPE_INCOMPLETE_VARS): New macro.
* c-tree.h (C_TYPE_INCOMPLETE_VARS): New macro.
* c-decl.c (struct c_scope): Remove "incomplete" field.
(pushdecl): Attach variables with incomplete types to
the TYPE_MAIN_VARIANT of the incomplete type in question.
(finish_struct): Look at C_TYPE_INCOMPLETE_VARS for variables
to complete, not at current_scope->incomplete. All such
variables do need completion.
From-SVN: r70952
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 94 |
1 files changed, 28 insertions, 66 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index eef6e6d..a346516 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -185,7 +185,7 @@ static int current_extern_inline; the end of the list on each insertion, or reverse the lists later, we maintain a pointer to the last list entry for each of the lists. - The order of the tags, shadowed, shadowed_tags, and incomplete + The order of the tags, shadowed, and shadowed_tags lists does not matter, so we just prepend to these lists. */ struct c_scope GTY(()) @@ -225,9 +225,6 @@ struct c_scope GTY(()) tree blocks; tree blocks_last; - /* Variable declarations with incomplete type in this scope. */ - tree incomplete; - /* True if we are currently filling this scope with parameter declarations. */ bool parm_flag : 1; @@ -1745,14 +1742,15 @@ pushdecl (tree x) IDENTIFIER_SYMBOL_VALUE (name) = x; C_DECL_INVISIBLE (x) = 0; - /* Keep list of variables in this scope with incomplete type. + /* If x's type is incomplete because it's based on a + structure or union which has not yet been fully declared, + attach it to that structure or union type, so we can go + back and complete the variable declaration later, if the + structure or union gets fully declared. + If the input is erroneous, we can have error_mark in the type slot (e.g. "f(void a, ...)") - that doesn't count as an - incomplete type. - - FIXME: Chain these off the TYPE_DECL for the incomplete type, - then we don't have to do (potentially quite costly) searches - in finish_struct. */ + incomplete type. */ if (TREE_TYPE (x) != error_mark_node && !COMPLETE_TYPE_P (TREE_TYPE (x))) { @@ -1760,11 +1758,14 @@ pushdecl (tree x) while (TREE_CODE (element) == ARRAY_TYPE) element = TREE_TYPE (element); + element = TYPE_MAIN_VARIANT (element); + if ((TREE_CODE (element) == RECORD_TYPE || TREE_CODE (element) == UNION_TYPE) && (TREE_CODE (x) != TYPE_DECL || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)) - scope->incomplete = tree_cons (NULL_TREE, x, scope->incomplete); + C_TYPE_INCOMPLETE_VARS (element) + = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element)); } } @@ -5143,63 +5144,24 @@ finish_struct (tree t, tree fieldlist, tree attributes) /* If this structure or union completes the type of any previous variable declaration, lay it out and output its rtl. */ - - if (current_scope->incomplete != NULL_TREE) - { - tree prev = NULL_TREE; - - for (x = current_scope->incomplete; x; x = TREE_CHAIN (x)) - { - tree decl = TREE_VALUE (x); - - if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t) - && TREE_CODE (decl) != TYPE_DECL) - { - layout_decl (decl, 0); - /* This is a no-op in c-lang.c or something real in - objc-act.c. */ - if (c_dialect_objc ()) - objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL, toplevel, 0); - if (! toplevel) - expand_decl (decl); - /* Unlink X from the incomplete list. */ - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (x); - else - current_scope->incomplete = TREE_CHAIN (x); - } - else if (!COMPLETE_TYPE_P (TREE_TYPE (decl)) - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - { - tree element = TREE_TYPE (decl); - while (TREE_CODE (element) == ARRAY_TYPE) - element = TREE_TYPE (element); - if (element == t) - { - layout_array_type (TREE_TYPE (decl)); - if (TREE_CODE (decl) != TYPE_DECL) - { - layout_decl (decl, 0); - if (c_dialect_objc ()) - objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL, toplevel, 0); - if (! toplevel) - expand_decl (decl); - } - /* Unlink X from the incomplete list. */ - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (x); - else - current_scope->incomplete = TREE_CHAIN (x); - } - else - prev = x; - } - else - prev = x; + for (x = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)); + x; + x = TREE_CHAIN (x)) + { + tree decl = TREE_VALUE (x); + if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + layout_array_type (TREE_TYPE (decl)); + if (TREE_CODE (decl) != TYPE_DECL) + { + layout_decl (decl, 0); + if (c_dialect_objc ()) + objc_check_decl (decl); + rest_of_decl_compilation (decl, NULL, toplevel, 0); + if (! toplevel) + expand_decl (decl); } } + C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0; /* Finish debugging output for this type. */ rest_of_type_compilation (t, toplevel); |