X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fc-decl.c;h=af038e1783aaa4b129b21efeb733d60b753ef03e;hp=bf8555715b072ec92f91be31ccc444491f7e434d;hb=becaf513f11a73ca428070e42ef9970aba4eda3e;hpb=15f854771f342ac87910102576494172705ae081 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index bf8555715b0..af038e1783a 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -38,10 +38,8 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "function.h" #include "output.h" -#include "expr.h" #include "c-tree.h" #include "toplev.h" -#include "ggc.h" #include "tm_p.h" #include "cpplib.h" #include "target.h" @@ -53,17 +51,13 @@ along with GCC; see the file COPYING3. If not see #include "c-lang.h" #include "langhooks.h" #include "tree-mudflap.h" -#include "gimple.h" #include "tree-iterator.h" #include "diagnostic.h" #include "tree-dump.h" #include "cgraph.h" #include "hashtab.h" -#include "libfuncs.h" -#include "except.h" #include "langhooks-def.h" #include "pointer-set.h" -#include "gimple.h" #include "plugin.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ @@ -2375,7 +2369,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); - gimple_set_body (newdecl, gimple_body (olddecl)); DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl)); for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t)) DECL_CONTEXT (t) = newdecl; @@ -2417,9 +2410,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) switch (TREE_CODE (olddecl)) { case FUNCTION_DECL: - gimple_set_body (olddecl, gimple_body (newdecl)); - /* fall through */ - case FIELD_DECL: case VAR_DECL: case PARM_DECL: @@ -3454,7 +3444,7 @@ c_init_decl_processing (void) using preprocessed headers. */ input_location = BUILTINS_LOCATION; - build_common_tree_nodes (flag_signed_char, false); + build_common_tree_nodes (flag_signed_char); c_common_nodes_and_builtins (); @@ -6567,6 +6557,8 @@ grokfield (location_t loc, Otherwise this is a forward declaration of a structure tag. If this is something of the form "foo;" and foo is a TYPE_DECL, then + If foo names a structure or union without a tag, then this + is an anonymous struct (this is permitted by C1X). If MS extensions are enabled and foo names a structure, then again this is an anonymous struct. Otherwise this is an error. @@ -6580,14 +6572,11 @@ grokfield (location_t loc, || TREE_CODE (type) == UNION_TYPE); bool ok = false; - if (type_ok - && (flag_ms_extensions || !declspecs->typedef_p)) + if (type_ok) { if (flag_ms_extensions) ok = true; - else if (flag_iso) - ok = false; - else if (TYPE_NAME (type) == NULL) + else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL) ok = true; else ok = false; @@ -6597,7 +6586,15 @@ grokfield (location_t loc, pedwarn (loc, 0, "declaration does not declare anything"); return NULL_TREE; } - pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions"); + if (!flag_isoc1x) + { + if (flag_isoc99) + pedwarn (loc, OPT_pedantic, + "ISO C99 doesn%'t support unnamed structs/unions"); + else + pedwarn (loc, OPT_pedantic, + "ISO C90 doesn%'t support unnamed structs/unions"); + } } value = grokdeclarator (declarator, declspecs, FIELD, false, @@ -6629,6 +6626,31 @@ grokfield (location_t loc, return value; } +/* Subroutine of detect_field_duplicates: add the fields of FIELDLIST + to HTAB, giving errors for any duplicates. */ + +static void +detect_field_duplicates_hash (tree fieldlist, htab_t htab) +{ + tree x, y; + void **slot; + + for (x = fieldlist; x ; x = TREE_CHAIN (x)) + if ((y = DECL_NAME (x)) != 0) + { + slot = htab_find_slot (htab, y, INSERT); + if (*slot) + { + error ("duplicate member %q+D", x); + DECL_NAME (x) = NULL_TREE; + } + *slot = y; + } + else if (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE) + detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab); +} + /* Generate an error for any duplicate field names in FIELDLIST. Munge the list such that this does not present a problem later. */ @@ -6647,11 +6669,16 @@ detect_field_duplicates (tree fieldlist) return; do { timeout--; + if (DECL_NAME (x) == NULL_TREE + && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)) + timeout = 0; x = TREE_CHAIN (x); } while (timeout > 0 && x); - /* If there were "few" fields, avoid the overhead of allocating - a hash table. Instead just do the nested traversal thing. */ + /* If there were "few" fields and no anonymous structures or unions, + avoid the overhead of allocating a hash table. Instead just do + the nested traversal thing. */ if (timeout > 0) { for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x)) @@ -6668,20 +6695,8 @@ detect_field_duplicates (tree fieldlist) else { htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL); - void **slot; - - for (x = fieldlist; x ; x = TREE_CHAIN (x)) - if ((y = DECL_NAME (x)) != 0) - { - slot = htab_find_slot (htab, y, INSERT); - if (*slot) - { - error ("duplicate member %q+D", x); - DECL_NAME (x) = NULL_TREE; - } - *slot = y; - } + detect_field_duplicates_hash (fieldlist, htab); htab_delete (htab); } } @@ -6771,8 +6786,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, if (pedantic) { for (x = fieldlist; x; x = TREE_CHAIN (x)) - if (DECL_NAME (x) != 0) - break; + { + if (DECL_NAME (x) != 0) + break; + if (flag_isoc1x + && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)) + break; + } if (x == 0) { @@ -6875,7 +6896,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic, "invalid use of structure with flexible array member"); - if (DECL_NAME (x)) + if (DECL_NAME (x) + || TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE) saw_named_field = 1; } @@ -7990,9 +8013,12 @@ store_parm_decls (void) thus won't naturally see the SAVE_EXPR containing the increment. All other pending sizes would be handled by gimplify_parameters. */ { + VEC(tree,gc) *pending_sizes = get_pending_sizes (); tree t; - for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t)) - add_stmt (TREE_VALUE (t)); + int i; + + for (i = 0; VEC_iterate (tree, pending_sizes, i, t); i++) + add_stmt (t); } /* Even though we're inside a function body, we still don't want to