X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fc-decl.c;h=cbd356f9cefd3d088607052c2d8fe3a506ec1d44;hp=8f50b17d1eddaa4bd1aeeba6e78fd84157ef1711;hb=2e3bc123c86bc34472ec6c28f12f1f7d532e1915;hpb=14bf94b5411c4f8db25a854be55be29d86858212 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 8f50b17d1ed..cbd356f9cef 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -16,8 +16,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ /* Process declarations and symbol lookup for C front end. Also constructs types; the standard scalar types at initialization, @@ -60,6 +60,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "libfuncs.h" #include "except.h" #include "langhooks-def.h" +#include "pointer-set.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -330,6 +331,10 @@ struct c_scope GTY((chain_next ("%h.outer"))) declarations. */ BOOL_BITFIELD parm_flag : 1; + /* True if we saw [*] in this scope. Used to give an error messages + if these appears in a function definition. */ + BOOL_BITFIELD had_vla_unspec : 1; + /* True if we already complained about forward parameter decls in this scope. This prevents double warnings on foo (int a; int b; ...) */ @@ -465,7 +470,7 @@ c_print_identifier (FILE *file, tree node, int indent) { tree rid = ridpointers[C_RID_CODE (node)]; indent_to (file, indent + 4); - fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"", + fprintf (file, "rid %p \"%s\"", (void *) rid, IDENTIFIER_POINTER (rid)); } } @@ -560,7 +565,7 @@ c_finish_incomplete_decl (tree decl) && !DECL_EXTERNAL (decl) && TYPE_DOMAIN (type) == 0) { - warning (0, "%Jarray %qD assumed to have one element", decl, decl); + warning (0, "array %q+D assumed to have one element", decl); complete_array_type (&TREE_TYPE (decl), NULL_TREE, true); @@ -751,22 +756,22 @@ pop_scope (void) /* Warnings for unused labels, errors for undefined labels. */ if (TREE_USED (p) && !DECL_INITIAL (p)) { - error ("%Jlabel %qD used but not defined", p, p); + error ("label %q+D used but not defined", p); DECL_INITIAL (p) = error_mark_node; } else if (!TREE_USED (p) && warn_unused_label) { if (DECL_INITIAL (p)) - warning (0, "%Jlabel %qD defined but not used", p, p); + warning (0, "label %q+D defined but not used", p); else - warning (0, "%Jlabel %qD declared but not defined", p, p); + warning (0, "label %q+D declared but not defined", p); } /* Labels go in BLOCK_VARS. */ TREE_CHAIN (p) = BLOCK_VARS (block); BLOCK_VARS (block) = p; gcc_assert (I_LABEL_BINDING (b->id) == b); - I_LABEL_BINDING (b->id) = b->shadowed; - break; + I_LABEL_BINDING (b->id) = b->shadowed; + break; case ENUMERAL_TYPE: case UNION_TYPE: @@ -780,7 +785,7 @@ pop_scope (void) gcc_assert (I_TAG_BINDING (b->id) == b); I_TAG_BINDING (b->id) = b->shadowed; } - break; + break; case FUNCTION_DECL: /* Propagate TREE_ADDRESSABLE from nested functions to their @@ -794,26 +799,26 @@ pop_scope (void) if (!DECL_EXTERNAL (p) && DECL_INITIAL (p) == 0) { - error ("%Jnested function %qD declared but never defined", p, p); + error ("nested function %q+D declared but never defined", p); undef_nested_function = true; } goto common_symbol; case VAR_DECL: /* Warnings for unused variables. */ - if (warn_unused_variable - && !TREE_USED (p) + if (!TREE_USED (p) + && !TREE_NO_WARNING (p) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) && scope != file_scope - && scope != external_scope) - warning (0, "%Junused variable %qD", p, p); + && scope != external_scope) + warning (OPT_Wunused_variable, "unused variable %q+D", p); if (b->inner_comp) { - error ("%Jtype of array %qD completed incompatibly with" - " implicit initialization", p, p); + error ("type of array %q+D completed incompatibly with" + " implicit initialization", p); } /* Fall through. */ @@ -1078,8 +1083,14 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) for (;;) { - tree oldargtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs)); - tree newargtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs)); + tree oldargtype = TREE_VALUE (oldargs); + tree newargtype = TREE_VALUE (newargs); + + if (oldargtype == error_mark_node || newargtype == error_mark_node) + return false; + + oldargtype = TYPE_MAIN_VARIANT (oldargtype); + newargtype = TYPE_MAIN_VARIANT (newargtype); if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype)) break; @@ -1088,14 +1099,14 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) agree on the number of arguments. */ if (END_OF_ARGLIST (oldargtype)) { - error ("%Jprototype for %qD declares more arguments " - "than previous old-style definition", newdecl, newdecl); + error ("prototype for %q+D declares more arguments " + "than previous old-style definition", newdecl); return false; } else if (END_OF_ARGLIST (newargtype)) { - error ("%Jprototype for %qD declares fewer arguments " - "than previous old-style definition", newdecl, newdecl); + error ("prototype for %q+D declares fewer arguments " + "than previous old-style definition", newdecl); return false; } @@ -1103,9 +1114,9 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) for the arg. */ else if (!comptypes (oldargtype, newargtype)) { - error ("%Jprototype for %qD declares argument %d" + error ("prototype for %q+D declares argument %d" " with incompatible type", - newdecl, newdecl, i); + newdecl, i); return false; } @@ -1116,8 +1127,8 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) /* If we get here, no errors were found, but do issue a warning for this poor-style construct. */ - warning (0, "%Jprototype for %qD follows non-prototype definition", - newdecl, newdecl); + warning (0, "prototype for %q+D follows non-prototype definition", + newdecl); return true; #undef END_OF_ARGLIST } @@ -1131,11 +1142,11 @@ locate_old_decl (tree decl, void (*diag)(const char *, ...) ATTRIBUTE_GCC_CDIAG( if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)) ; else if (DECL_INITIAL (decl)) - diag (G_("%Jprevious definition of %qD was here"), decl, decl); + diag (G_("previous definition of %q+D was here"), decl); else if (C_DECL_IMPLICIT (decl)) - diag (G_("%Jprevious implicit declaration of %qD was here"), decl, decl); + diag (G_("previous implicit declaration of %q+D was here"), decl); else - diag (G_("%Jprevious declaration of %qD was here"), decl, decl); + diag (G_("previous declaration of %q+D was here"), decl); } /* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL. @@ -1155,6 +1166,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, bool warned = false; bool retval = true; +#define DECL_EXTERN_INLINE(DECL) (DECL_DECLARED_INLINE_P (DECL) \ + && DECL_EXTERNAL (DECL)) + /* If we have error_mark_node for either decl or type, just discard the previous decl - we're in an error cascade already. */ if (olddecl == error_mark_node || newdecl == error_mark_node) @@ -1172,16 +1186,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))) { - error ("%J%qD redeclared as different kind of symbol", - newdecl, newdecl); + error ("%q+D redeclared as different kind of symbol", newdecl); locate_old_decl (olddecl, error); } else if (TREE_PUBLIC (newdecl)) - warning (0, "%Jbuilt-in function %qD declared as non-function", - newdecl, newdecl); + warning (0, "built-in function %q+D declared as non-function", + newdecl); else - warning (OPT_Wshadow, "%Jdeclaration of %qD shadows " - "a built-in function", newdecl, newdecl); + warning (OPT_Wshadow, "declaration of %q+D shadows " + "a built-in function", newdecl); return false; } @@ -1189,7 +1202,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, given scope. */ if (TREE_CODE (olddecl) == CONST_DECL) { - error ("%Jredeclaration of enumerator %qD", newdecl, newdecl); + error ("redeclaration of enumerator %q+D", newdecl); locate_old_decl (olddecl, error); return false; } @@ -1210,8 +1223,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* If types don't match for a built-in, throw away the built-in. No point in calling locate_old_decl here, it won't print anything. */ - warning (0, "%Jconflicting types for built-in function %qD", - newdecl, newdecl); + warning (0, "conflicting types for built-in function %q+D", + newdecl); return false; } } @@ -1234,7 +1247,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl)) { - pedwarn ("%Jconflicting types for %qD", newdecl, newdecl); + pedwarn ("conflicting types for %q+D", newdecl); /* Make sure we keep void as the return type. */ TREE_TYPE (newdecl) = *newtypep = newtype = oldtype; C_FUNCTION_IMPLICIT_INT (newdecl) = 0; @@ -1247,7 +1260,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl)) { - pedwarn ("%Jconflicting types for %qD", newdecl, newdecl); + pedwarn ("conflicting types for %q+D", newdecl); /* Make sure we keep void as the return type. */ TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype; pedwarned = true; @@ -1255,9 +1268,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, else { if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype)) - error ("%J conflicting type qualifiers for %qD", newdecl, newdecl); + error ("conflicting type qualifiers for %q+D", newdecl); else - error ("%Jconflicting types for %qD", newdecl, newdecl); + error ("conflicting types for %q+D", newdecl); diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype); locate_old_decl (olddecl, error); return false; @@ -1272,7 +1285,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl)) return true; /* Allow OLDDECL to continue in use. */ - error ("%Jredefinition of typedef %qD", newdecl, newdecl); + error ("redefinition of typedef %q+D", newdecl); locate_old_decl (olddecl, error); return false; } @@ -1283,6 +1296,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, Multiple definitions are not allowed (6.9p3,5) but GCC permits two definitions if one is 'extern inline' and one is not. The non- extern-inline definition supersedes the extern-inline definition. */ + else if (TREE_CODE (newdecl) == FUNCTION_DECL) { /* If you declare a built-in function name as static, or @@ -1295,8 +1309,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, || (DECL_INITIAL (newdecl) && !TYPE_ARG_TYPES (TREE_TYPE (newdecl))))) { - warning (OPT_Wshadow, "%Jdeclaration of %qD shadows " - "a built-in function", newdecl, newdecl); + warning (OPT_Wshadow, "declaration of %q+D shadows " + "a built-in function", newdecl); /* Discard the old built-in function. */ return false; } @@ -1305,45 +1319,25 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { if (DECL_INITIAL (olddecl)) { - /* If both decls have extern inline and are in the same TU, - reject the new decl. */ - if (DECL_DECLARED_INLINE_P (olddecl) - && DECL_EXTERNAL (olddecl) - && DECL_DECLARED_INLINE_P (newdecl) - && DECL_EXTERNAL (newdecl) + /* If both decls are in the same TU and the new declaration + isn't overriding an extern inline reject the new decl. + When we handle c99 style inline rules we'll want to reject + the following: + + DECL_EXTERN_INLINE (olddecl) + && !DECL_EXTERN_INLINE (newdecl) + + if they're in the same translation unit. Until we implement + the full semantics we accept the construct. */ + if (!(DECL_EXTERN_INLINE (olddecl) + && !DECL_EXTERN_INLINE (newdecl)) && same_translation_unit_p (newdecl, olddecl)) { - error ("%Jredefinition of %qD", newdecl, newdecl); + error ("redefinition of %q+D", newdecl); locate_old_decl (olddecl, error); return false; } - /* If both decls have not extern inline, reject the new decl. */ - if (!DECL_DECLARED_INLINE_P (olddecl) - && !DECL_EXTERNAL (olddecl) - && !DECL_DECLARED_INLINE_P (newdecl) - && !DECL_EXTERNAL (newdecl)) - { - error ("%Jredefinition of %qD", newdecl, newdecl); - locate_old_decl (olddecl, error); - return false; - } - /* If the new decl is declared as extern inline, error if they are - in the same TU, otherwise retain the old decl. */ - if (!DECL_DECLARED_INLINE_P (olddecl) - && !DECL_EXTERNAL (olddecl) - && DECL_DECLARED_INLINE_P (newdecl) - && DECL_EXTERNAL (newdecl)) - { - if (same_translation_unit_p (newdecl, olddecl)) - { - error ("%Jredefinition of %qD", newdecl, newdecl); - locate_old_decl (olddecl, error); - return false; - } - else - retval = false; - } - } + } } /* If we have a prototype after an old-style function definition, the argument types must be checked specially. */ @@ -1372,11 +1366,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, occur only in Objective C; see also above. (FIXME: Make Objective C use normal builtins.) */ if (!DECL_IS_BUILTIN (olddecl) - && !(DECL_EXTERNAL (olddecl) - && DECL_DECLARED_INLINE_P (olddecl))) + && !DECL_EXTERN_INLINE (olddecl)) { - error ("%Jstatic declaration of %qD follows " - "non-static declaration", newdecl, newdecl); + error ("static declaration of %q+D follows " + "non-static declaration", newdecl); locate_old_decl (olddecl, error); } return false; @@ -1385,15 +1378,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { if (DECL_CONTEXT (olddecl)) { - error ("%Jnon-static declaration of %qD follows " - "static declaration", newdecl, newdecl); + error ("non-static declaration of %q+D follows " + "static declaration", newdecl); locate_old_decl (olddecl, error); return false; } else if (warn_traditional) { - warning (0, "%Jnon-static declaration of %qD follows " - "static declaration", newdecl, newdecl); + warning (OPT_Wtraditional, "non-static declaration of %q+D " + "follows static declaration", newdecl); warned = true; } } @@ -1402,14 +1395,21 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { /* Only variables can be thread-local, and all declarations must agree on this property. */ - if (DECL_THREAD_LOCAL (newdecl) != DECL_THREAD_LOCAL (olddecl)) + if (C_DECL_THREADPRIVATE_P (olddecl) && !DECL_THREAD_LOCAL_P (newdecl)) + { + /* Nothing to check. Since OLDDECL is marked threadprivate + and NEWDECL does not have a thread-local attribute, we + will merge the threadprivate attribute into NEWDECL. */ + ; + } + else if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl)) { - if (DECL_THREAD_LOCAL (newdecl)) - error ("%Jthread-local declaration of %qD follows " - "non-thread-local declaration", newdecl, newdecl); + if (DECL_THREAD_LOCAL_P (newdecl)) + error ("thread-local declaration of %q+D follows " + "non-thread-local declaration", newdecl); else - error ("%Jnon-thread-local declaration of %qD follows " - "thread-local declaration", newdecl, newdecl); + error ("non-thread-local declaration of %q+D follows " + "thread-local declaration", newdecl); locate_old_decl (olddecl, error); return false; @@ -1418,7 +1418,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* Multiple initialized definitions are not allowed (6.9p3,5). */ if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl)) { - error ("%Jredefinition of %qD", newdecl, newdecl); + error ("redefinition of %q+D", newdecl); locate_old_decl (olddecl, error); return false; } @@ -1438,26 +1438,26 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { if (!DECL_FILE_SCOPE_P (olddecl)) { - error ("%Jextern declaration of %qD follows " - "declaration with no linkage", newdecl, newdecl); + error ("extern declaration of %q+D follows " + "declaration with no linkage", newdecl); locate_old_decl (olddecl, error); return false; } else if (warn_traditional) { - warning (0, "%Jnon-static declaration of %qD follows " - "static declaration", newdecl, newdecl); + warning (OPT_Wtraditional, "non-static declaration of %q+D " + "follows static declaration", newdecl); warned = true; } } else { if (TREE_PUBLIC (newdecl)) - error ("%Jnon-static declaration of %qD follows " - "static declaration", newdecl, newdecl); + error ("non-static declaration of %q+D follows " + "static declaration", newdecl); else - error ("%Jstatic declaration of %qD follows " - "non-static declaration", newdecl, newdecl); + error ("static declaration of %q+D follows " + "non-static declaration", newdecl); locate_old_decl (olddecl, error); return false; @@ -1474,14 +1474,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (DECL_EXTERNAL (olddecl)) { - error ("%Jdeclaration of %qD with no linkage follows " - "extern declaration", newdecl, newdecl); + error ("declaration of %q+D with no linkage follows " + "extern declaration", newdecl); locate_old_decl (olddecl, error); } else { - error ("%Jredeclaration of %qD with no linkage", - newdecl, newdecl); + error ("redeclaration of %q+D with no linkage", newdecl); locate_old_decl (olddecl, error); } @@ -1491,11 +1490,12 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* warnings */ /* All decls must agree on a visibility. */ - if (DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl) + if (CODE_CONTAINS_STRUCT (TREE_CODE (newdecl), TS_DECL_WITH_VIS) + && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl) && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) { - warning (0, "%Jredeclaration of %qD with different visibility " - "(old visibility preserved)", newdecl, newdecl); + warning (0, "redeclaration of %q+D with different visibility " + "(old visibility preserved)", newdecl); warned = true; } @@ -1505,15 +1505,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_DECLARED_INLINE_P (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warning (OPT_Wattributes, "%Jinline declaration of %qD follows " - "declaration with attribute noinline", newdecl, newdecl); + warning (OPT_Wattributes, "inline declaration of %qD follows " + "declaration with attribute noinline", newdecl); warned = true; } else if (DECL_DECLARED_INLINE_P (olddecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) { - warning (OPT_Wattributes, "%Jdeclaration of %qD with attribute " - "noinline follows inline declaration ", newdecl, newdecl); + warning (OPT_Wattributes, "declaration of %q+D with attribute " + "noinline follows inline declaration ", newdecl); warned = true; } @@ -1527,14 +1527,12 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { if (TREE_USED (olddecl)) { - warning (0, "%J%qD declared inline after being called", - olddecl, olddecl); + warning (0, "%q+D declared inline after being called", olddecl); warned = true; } else if (DECL_INITIAL (olddecl)) { - warning (0, "%J%qD declared inline after its definition", - olddecl, olddecl); + warning (0, "%q+D declared inline after its definition", olddecl); warned = true; } } @@ -1553,7 +1551,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (TREE_CODE (newdecl) == PARM_DECL && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl))) { - error ("%Jredefinition of parameter %qD", newdecl, newdecl); + error ("redefinition of parameter %q+D", newdecl); locate_old_decl (olddecl, error); return false; } @@ -1575,9 +1573,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl)) /* Don't warn about forward parameter decls. */ && !(TREE_CODE (newdecl) == PARM_DECL - && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))) + && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)) + /* Don't warn about a variable definition following a declaration. */ + && !(TREE_CODE (newdecl) == VAR_DECL + && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))) { - warning (0, "%Jredundant redeclaration of %qD", newdecl, newdecl); + warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D", + newdecl); warned = true; } @@ -1585,6 +1587,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (warned || pedwarned) locate_old_decl (olddecl, pedwarned ? pedwarn : warning0); +#undef DECL_EXTERN_INLINE + return retval; } @@ -1657,8 +1661,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) } } - /* Keep the old rtl since we can safely use it. */ - COPY_DECL_RTL (olddecl, newdecl); /* Merge the type qualifiers. */ if (TREE_READONLY (newdecl)) @@ -1683,62 +1685,73 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) && !C_DECL_BUILTIN_PROTOTYPE (olddecl))) DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl); - /* Merge the unused-warning information. */ - if (DECL_IN_SYSTEM_HEADER (olddecl)) - DECL_IN_SYSTEM_HEADER (newdecl) = 1; - else if (DECL_IN_SYSTEM_HEADER (newdecl)) - DECL_IN_SYSTEM_HEADER (olddecl) = 1; - /* Merge the initialization information. */ if (DECL_INITIAL (newdecl) == 0) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - /* Merge the section attribute. - We want to issue an error if the sections conflict but that must be - done later in decl_attributes since we are called before attributes - are assigned. */ - if (DECL_SECTION_NAME (newdecl) == NULL_TREE) - DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - - /* Copy the assembler name. - Currently, it can only be defined in the prototype. */ - COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); - - /* Use visibility of whichever declaration had it specified */ - if (DECL_VISIBILITY_SPECIFIED (olddecl)) + /* Merge the threadprivate attribute. */ + if (TREE_CODE (olddecl) == VAR_DECL && C_DECL_THREADPRIVATE_P (olddecl)) { - DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); - DECL_VISIBILITY_SPECIFIED (newdecl) = 1; + DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl); + C_DECL_THREADPRIVATE_P (newdecl) = 1; } - if (TREE_CODE (newdecl) == FUNCTION_DECL) + if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)) { - DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl); - DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); - DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); - DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) - |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); - TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); - DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); - DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); - DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); - } + /* Merge the unused-warning information. */ + if (DECL_IN_SYSTEM_HEADER (olddecl)) + DECL_IN_SYSTEM_HEADER (newdecl) = 1; + else if (DECL_IN_SYSTEM_HEADER (newdecl)) + DECL_IN_SYSTEM_HEADER (olddecl) = 1; - /* Merge the storage class information. */ - merge_weak (newdecl, olddecl); + /* Merge the section attribute. + We want to issue an error if the sections conflict but that + must be done later in decl_attributes since we are called + before attributes are assigned. */ + if (DECL_SECTION_NAME (newdecl) == NULL_TREE) + DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - /* For functions, static overrides non-static. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); - /* This is since we don't automatically - copy the attributes of NEWDECL into OLDDECL. */ - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - /* If this clears `static', clear it in the identifier too. */ - if (!TREE_PUBLIC (olddecl)) - TREE_PUBLIC (DECL_NAME (olddecl)) = 0; + /* Copy the assembler name. + Currently, it can only be defined in the prototype. */ + COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); + + /* Use visibility of whichever declaration had it specified */ + if (DECL_VISIBILITY_SPECIFIED (olddecl)) + { + DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); + DECL_VISIBILITY_SPECIFIED (newdecl) = 1; + } + + if (TREE_CODE (newdecl) == FUNCTION_DECL) + { + DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl); + DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); + DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) + |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); + TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); + TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); + DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); + DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); + DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); + } + + /* Merge the storage class information. */ + merge_weak (newdecl, olddecl); + + /* For functions, static overrides non-static. */ + if (TREE_CODE (newdecl) == FUNCTION_DECL) + { + TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); + /* This is since we don't automatically + copy the attributes of NEWDECL into OLDDECL. */ + TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); + /* If this clears `static', clear it in the identifier too. */ + if (!TREE_PUBLIC (olddecl)) + TREE_PUBLIC (DECL_NAME (olddecl)) = 0; + } } + if (DECL_EXTERNAL (newdecl)) { TREE_STATIC (newdecl) = TREE_STATIC (olddecl); @@ -1762,13 +1775,13 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) { /* If we're redefining a function previously defined as extern inline, make sure we emit debug info for the inline before we - throw it away, in case it was inlined into a function that hasn't - been written out yet. */ + throw it away, in case it was inlined into a function that + hasn't been written out yet. */ if (new_is_definition && DECL_INITIAL (olddecl)) { if (TREE_USED (olddecl) /* In unit-at-a-time mode we never inline re-defined extern - inline functions. */ + inline functions. */ && !flag_unit_at_a_time && cgraph_function_possibly_inlined_p (olddecl)) (*debug_hooks->outlining_inline_function) (olddecl); @@ -1779,8 +1792,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) } else { - /* If either decl says `inline', this fn is inline, - unless its definition was passed already. */ + /* If either decl says `inline', this fn is inline, unless + its definition was passed already. */ if (DECL_DECLARED_INLINE_P (newdecl) || DECL_DECLARED_INLINE_P (olddecl)) DECL_DECLARED_INLINE_P (newdecl) = 1; @@ -1839,7 +1852,28 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common)); + sizeof (struct tree_decl_common) - sizeof (struct tree_common)); + switch (TREE_CODE (olddecl)) + { + case FIELD_DECL: + case VAR_DECL: + case PARM_DECL: + case LABEL_DECL: + case RESULT_DECL: + case CONST_DECL: + case TYPE_DECL: + case FUNCTION_DECL: + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common)); + break; + + default: + + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common)); + } DECL_UID (olddecl) = olddecl_uid; DECL_CONTEXT (olddecl) = olddecl_context; } @@ -1867,7 +1901,11 @@ duplicate_decls (tree newdecl, tree olddecl) tree newtype = NULL, oldtype = NULL; if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype)) - return false; + { + /* Avoid `unused variable' and other warnings warnings for OLDDECL. */ + TREE_NO_WARNING (olddecl) = 1; + return false; + } merge_decls (newdecl, olddecl, newtype, oldtype); return true; @@ -1885,13 +1923,7 @@ warn_if_shadowing (tree new_decl) /* No shadow warnings for internally generated vars. */ || DECL_IS_BUILTIN (new_decl) /* No shadow warnings for vars made for inlining. */ - || DECL_FROM_INLINE (new_decl) - /* Don't warn about the parm names in function declarator - within a function declarator. It would be nice to avoid - warning in any function declarator in a declaration, as - opposed to a definition, but there is no way to tell - it's not a definition at this point. */ - || (TREE_CODE (new_decl) == PARM_DECL && current_scope->outer->parm_flag)) + || DECL_FROM_INLINE (new_decl)) return; /* Is anything being shadowed? Invisible decls do not count. */ @@ -1902,28 +1934,28 @@ warn_if_shadowing (tree new_decl) if (old_decl == error_mark_node) { - warning (0, "%Jdeclaration of %qD shadows previous non-variable", - new_decl, new_decl); + warning (OPT_Wshadow, "declaration of %q+D shadows previous " + "non-variable", new_decl); break; } else if (TREE_CODE (old_decl) == PARM_DECL) - warning (0, "%Jdeclaration of %qD shadows a parameter", - new_decl, new_decl); + warning (OPT_Wshadow, "declaration of %q+D shadows a parameter", + new_decl); else if (DECL_FILE_SCOPE_P (old_decl)) - warning (0, "%Jdeclaration of %qD shadows a global declaration", - new_decl, new_decl); + warning (OPT_Wshadow, "declaration of %q+D shadows a global " + "declaration", new_decl); else if (TREE_CODE (old_decl) == FUNCTION_DECL && DECL_BUILT_IN (old_decl)) { - warning (0, "%Jdeclaration of %qD shadows a built-in function", - new_decl, new_decl); + warning (OPT_Wshadow, "declaration of %q+D shadows " + "a built-in function", new_decl); break; } else - warning (0, "%Jdeclaration of %qD shadows a previous local", - new_decl, new_decl); + warning (OPT_Wshadow, "declaration of %q+D shadows a previous local", + new_decl); - warning (0, "%Jshadowed declaration is here", old_decl); + warning (OPT_Wshadow, "%Jshadowed declaration is here", old_decl); break; } @@ -1946,7 +1978,7 @@ warn_if_shadowing (tree new_decl) translation and get back the corresponding typedef name. For example, given: - typedef struct S MY_TYPE; + typedef struct S MY_TYPE; MY_TYPE object; Later parts of the compiler might only know that `object' was of @@ -2121,10 +2153,9 @@ pushdecl (tree x) visdecl = b->decl; vistype = TREE_TYPE (visdecl); } - if (warn_nested_externs - && scope != file_scope + if (scope != file_scope && !DECL_IN_SYSTEM_HEADER (x)) - warning (0, "nested extern declaration of %qD", x); + warning (OPT_Wnested_externs, "nested extern declaration of %qD", x); while (b && !B_IN_EXTERNAL_SCOPE (b)) { @@ -2216,7 +2247,8 @@ pushdecl (tree x) } } - warn_if_shadowing (x); + if (TREE_CODE (x) != PARM_DECL) + warn_if_shadowing (x); skip_external_and_shadow_checks: if (TREE_CODE (x) == TYPE_DECL) @@ -2430,7 +2462,7 @@ undeclared_variable (tree id, location_t loc) } /* If we are parsing old-style parameter decls, current_function_decl - will be nonnull but current_function_scope will be null. */ + will be nonnull but current_function_scope will be null. */ scope = current_function_scope ? current_function_scope : current_scope; } bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false); @@ -2569,7 +2601,7 @@ define_label (location_t location, tree name) if (!in_system_header && lookup_name (name)) warning (OPT_Wtraditional, "%Htraditional C lacks a separate namespace " - "for labels, identifier %qE conflicts", &location, name); + "for labels, identifier %qE conflicts", &location, name); nlist_se = XOBNEW (&parser_obstack, struct c_label_list); nlist_se->next = label_context_stack_se->labels_def; @@ -2644,7 +2676,7 @@ pending_xref_error (void) { if (pending_invalid_xref != 0) error ("%H%qE defined as wrong kind of tag", - &pending_invalid_xref_location, pending_invalid_xref); + &pending_invalid_xref_location, pending_invalid_xref); pending_invalid_xref = 0; } @@ -2985,14 +3017,14 @@ quals_from_declspecs (const struct c_declspecs *specs) return quals; } -/* Construct an array declarator. EXPR is the expression inside [], or - NULL_TREE. QUALS are the type qualifiers inside the [] (to be applied - to the pointer to which a parameter array is converted). STATIC_P is - true if "static" is inside the [], false otherwise. VLA_UNSPEC_P - is true if the array is [*], a VLA of unspecified length which is - nevertheless a complete type (not currently implemented by GCC), - false otherwise. The field for the contained declarator is left to be - filled in by set_array_declarator_inner. */ +/* Construct an array declarator. EXPR is the expression inside [], + or NULL_TREE. QUALS are the type qualifiers inside the [] (to be + applied to the pointer to which a parameter array is converted). + STATIC_P is true if "static" is inside the [], false otherwise. + VLA_UNSPEC_P is true if the array is [*], a VLA of unspecified + length which is nevertheless a complete type, false otherwise. The + field for the contained declarator is left to be filled in by + set_array_declarator_inner. */ struct c_declarator * build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p, @@ -3024,7 +3056,16 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p, pedwarn ("ISO C90 does not support %<[*]%> array declarators"); } if (vla_unspec_p) - warning (0, "GCC does not yet properly implement %<[*]%> array declarators"); + { + if (!current_scope->parm_flag) + { + /* C99 6.7.5.2p4 */ + error ("%<[*]%> not allowed in other than function prototype scope"); + declarator->u.array.vla_unspec_p = false; + return NULL; + } + current_scope->had_vla_unspec = true; + } return declarator; } @@ -3046,6 +3087,33 @@ set_array_declarator_inner (struct c_declarator *decl, error ("static or type qualifiers in abstract declarator"); return decl; } + +/* INIT is a constructor that forms DECL's initializer. If the final + element initializes a flexible array field, add the size of that + initializer to DECL's size. */ + +static void +add_flexible_array_elts_to_size (tree decl, tree init) +{ + tree elt, type; + + if (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init))) + return; + + elt = VEC_last (constructor_elt, CONSTRUCTOR_ELTS (init))->value; + type = TREE_TYPE (elt); + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_SIZE (type) == NULL_TREE + && TYPE_DOMAIN (type) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE) + { + complete_array_type (&type, elt, false); + DECL_SIZE (decl) + = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type)); + DECL_SIZE_UNIT (decl) + = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type)); + } +} /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ @@ -3102,7 +3170,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl))) - warning (0, "%J%qD is usually a function", decl, decl); + warning (OPT_Wmain, "%q+D is usually a function", decl); if (initialized) /* Is it valid for this decl to have an initializer at all? @@ -3192,7 +3260,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, if (TREE_CODE (decl) == VAR_DECL && !initialized && TREE_PUBLIC (decl) - && !DECL_THREAD_LOCAL (decl) + && !DECL_THREAD_LOCAL_P (decl) && !flag_no_common) DECL_COMMON (decl) = 1; @@ -3223,8 +3291,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) - warning (OPT_Wattributes, "%Jinline function %qD given attribute noinline", - decl, decl); + warning (OPT_Wattributes, "inline function %q+D given attribute noinline", + decl); /* Add this decl to the current scope. TEM may equal DECL or it may be a previous decl of the same name. */ @@ -3295,12 +3363,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree) switch (failure) { case 1: - error ("%Jinitializer fails to determine size of %qD", decl, decl); + error ("initializer fails to determine size of %q+D", decl); break; case 2: if (do_default) - error ("%Jarray size missing in %qD", decl, decl); + error ("array size missing in %q+D", decl); /* If a `static' var's size isn't known, make it extern as well as static, so it does not get allocated. @@ -3312,7 +3380,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) break; case 3: - error ("%Jzero or negative size array %qD", decl, decl); + error ("zero or negative size array %q+D", decl); break; case 0: @@ -3345,6 +3413,9 @@ finish_decl (tree decl, tree init, tree asmspec_tree) if (TREE_CODE (decl) == VAR_DECL) { + if (init && TREE_CODE (init) == CONSTRUCTOR) + add_flexible_array_elts_to_size (decl, init); + if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node && COMPLETE_TYPE_P (TREE_TYPE (decl))) layout_decl (decl, 0); @@ -3364,7 +3435,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) is an error. */ : !DECL_EXTERNAL (decl))) { - error ("%Jstorage size of %qD isn%'t known", decl, decl); + error ("storage size of %q+D isn%'t known", decl); TREE_TYPE (decl) = error_mark_node; } @@ -3374,7 +3445,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) constant_expression_warning (DECL_SIZE (decl)); else - error ("%Jstorage size of %qD isn%'t constant", decl, decl); + error ("storage size of %q+D isn%'t constant", decl); } if (TREE_USED (type)) @@ -3394,23 +3465,21 @@ finish_decl (tree decl, tree init, tree asmspec_tree) /* If #pragma weak was used, mark the decl weak now. */ maybe_apply_pragma_weak (decl); - /* If this is a variable definition, determine its ELF visibility. */ - if (TREE_CODE (decl) == VAR_DECL - && TREE_STATIC (decl) - && !DECL_EXTERNAL (decl)) - c_determine_visibility (decl); - /* Output the assembler code and/or RTL code for variables and functions, unless the type is an undefined structure or union. If not, it will get done when the type is completed. */ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL) { + /* Determine the ELF visibility. */ + if (TREE_PUBLIC (decl)) + c_determine_visibility (decl); + /* This is a no-op in c-lang.c or something real in objc-act.c. */ if (c_dialect_objc ()) objc_check_decl (decl); - if (asmspec) + if (asmspec) { /* If this is not a static variable, issue a warning. It doesn't make any sense to give an ASMSPEC for an @@ -3421,14 +3490,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree) && TREE_CODE (decl) == VAR_DECL && !C_DECL_REGISTER (decl) && !TREE_STATIC (decl)) - warning (0, "%Jignoring asm-specifier for non-static local " - "variable %qD", decl, decl); - else if (C_DECL_REGISTER (decl)) - change_decl_assembler_name (decl, get_identifier (asmspec)); + warning (0, "ignoring asm-specifier for non-static local " + "variable %q+D", decl); else set_user_assembler_name (decl, asmspec); } - + if (DECL_FILE_SCOPE_P (decl)) { if (DECL_INITIAL (decl) == NULL_TREE @@ -3474,7 +3541,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) add_stmt (build_stmt (DECL_EXPR, decl)); } } - + if (!DECL_FILE_SCOPE_P (decl)) { @@ -3493,7 +3560,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) } /* If this was marked 'used', be sure it will be output. */ - if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) mark_decl_referenced (decl); if (TREE_CODE (decl) == TYPE_DECL) @@ -3538,6 +3605,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gcc_personality_sj0" : "__gcc_personality_v0"); + default_init_unwind_resume_libfunc (); using_eh_for_cleanups (); } @@ -3594,8 +3662,6 @@ mark_forward_parm_decls (void) TREE_ASM_WRITTEN (b->decl) = 1; } -static GTY(()) int compound_literal_number; - /* Build a COMPOUND_LITERAL_EXPR. TYPE is the type given in the compound literal, which may be an incomplete array type completed by the initializer; INIT is a CONSTRUCTOR that initializes the compound @@ -3645,14 +3711,8 @@ build_compound_literal (tree type, tree init) if (TREE_STATIC (decl)) { - /* This decl needs a name for the assembler output. We also need - a unique suffix to be added to the name. */ - char *name; - - ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", - compound_literal_number); - compound_literal_number++; - DECL_NAME (decl) = get_identifier (name); + /* This decl needs a name for the assembler output. */ + set_compound_literal_name (decl); DECL_DEFER_OUTPUT (decl) = 1; DECL_COMDAT (decl) = 1; DECL_ARTIFICIAL (decl) = 1; @@ -3741,6 +3801,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) type_mv = TYPE_MAIN_VARIANT (*type); if (pedantic + && !in_system_header && type_mv != integer_type_node && type_mv != unsigned_type_node && type_mv != boolean_type_node) @@ -3764,11 +3825,12 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) { struct lang_type *lt = TYPE_LANG_SPECIFIC (*type); if (!lt - || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) + || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) warning (0, "%qs is narrower than values of its type", name); } } + /* Given declspecs and a declarator, determine the name and type of the object declared @@ -3813,20 +3875,21 @@ grokdeclarator (const struct c_declarator *declarator, int type_quals = TYPE_UNQUALIFIED; const char *name, *orig_name; tree typedef_type = 0; - int funcdef_flag = 0; + bool funcdef_flag = false; bool funcdef_syntax = false; int size_varies = 0; tree decl_attr = declspecs->decl_attr; int array_ptr_quals = TYPE_UNQUALIFIED; tree array_ptr_attrs = NULL_TREE; int array_parm_static = 0; + bool array_parm_vla_unspec_p = false; tree returned_attrs = NULL_TREE; bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; if (decl_context == FUNCDEF) - funcdef_flag = 1, decl_context = NORMAL; + funcdef_flag = true, decl_context = NORMAL; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ @@ -3877,6 +3940,14 @@ grokdeclarator (const struct c_declarator *declarator, if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS) warn_deprecated_use (declspecs->type); + if ((decl_context == NORMAL || decl_context == FIELD) + && current_scope == file_scope + && variably_modified_type_p (type, NULL_TREE)) + { + error ("variably modified %qs at file scope", name); + type = integer_type_node; + } + typedef_type = type; size_varies = C_TYPE_VARIABLE_SIZE (type); @@ -3983,8 +4054,13 @@ grokdeclarator (const struct c_declarator *declarator, && !funcdef_flag) { /* 'extern' with initialization is invalid if not at file scope. */ - if (current_scope == file_scope) - warning (0, "%qs initialized and declared %", name); + if (current_scope == file_scope) + { + /* It is fine to have 'extern const' when compiling at C + and C++ intersection. */ + if (!(warn_cxx_compat && constp)) + warning (0, "%qs initialized and declared %", name); + } else error ("%qs has both % and initializer", name); } @@ -4087,29 +4163,30 @@ grokdeclarator (const struct c_declarator *declarator, array_ptr_quals = declarator->u.array.quals; array_ptr_attrs = declarator->u.array.attrs; array_parm_static = declarator->u.array.static_p; - + array_parm_vla_unspec_p = declarator->u.array.vla_unspec_p; + declarator = declarator->declarator; /* Check for some types that there cannot be arrays of. */ - + if (VOID_TYPE_P (type)) { error ("declaration of %qs as array of voids", name); type = error_mark_node; } - + if (TREE_CODE (type) == FUNCTION_TYPE) { error ("declaration of %qs as array of functions", name); type = error_mark_node; } - + if (pedantic && !in_system_header && flexible_array_type_p (type)) pedwarn ("invalid use of structure with flexible array member"); - + if (size == error_mark_node) type = error_mark_node; - + if (type == error_mark_node) continue; @@ -4122,16 +4199,16 @@ grokdeclarator (const struct c_declarator *declarator, /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ STRIP_TYPE_NOPS (size); - + if (!INTEGRAL_TYPE_P (TREE_TYPE (size))) { error ("size of array %qs has non-integer type", name); size = integer_one_node; } - + if (pedantic && integer_zerop (size)) pedwarn ("ISO C forbids zero-size array %qs", name); - + if (TREE_CODE (size) == INTEGER_CST) { constant_expression_warning (size); @@ -4141,13 +4218,19 @@ grokdeclarator (const struct c_declarator *declarator, size = integer_one_node; } } + else if ((decl_context == NORMAL || decl_context == FIELD) + && current_scope == file_scope) + { + error ("variably modified %qs at file scope", name); + size = integer_one_node; + } else { /* Make sure the array size remains visibly nonconstant even if it is (eg) a const variable with known value. */ size_varies = 1; - + if (!flag_isoc99 && pedantic) { if (TREE_CONSTANT (size)) @@ -4162,10 +4245,10 @@ grokdeclarator (const struct c_declarator *declarator, if (integer_zerop (size)) { - /* A zero-length array cannot be represented with - an unsigned index type, which is what we'll - get with build_index_type. Create an - open-ended range instead. */ + /* A zero-length array cannot be represented with + an unsigned index type, which is what we'll + get with build_index_type. Create an + open-ended range instead. */ itype = build_range_type (sizetype, size, NULL_TREE); } else @@ -4180,25 +4263,26 @@ grokdeclarator (const struct c_declarator *declarator, - 1. Do the calculation in index_type, so that if it is a variable the computations will be done in the proper mode. */ - itype = fold (build2 (MINUS_EXPR, index_type, - convert (index_type, size), - convert (index_type, - size_one_node))); + itype = fold_build2 (MINUS_EXPR, index_type, + convert (index_type, size), + convert (index_type, + size_one_node)); - /* If that overflowed, the array is too big. ??? + /* If that overflowed, the array is too big. ??? While a size of INT_MAX+1 technically shouldn't cause an overflow (because we subtract 1), the overflow is recorded during the conversion to index_type, before the subtraction. Handling this case seems like an unnecessary complication. */ - if (TREE_OVERFLOW (itype)) + if (TREE_CODE (itype) == INTEGER_CST + && TREE_OVERFLOW (itype)) { error ("size of array %qs is too large", name); type = error_mark_node; continue; } - + itype = build_index_type (itype); } } @@ -4211,26 +4295,79 @@ grokdeclarator (const struct c_declarator *declarator, identical to GCC's zero-length array extension. */ itype = build_range_type (sizetype, size_zero_node, NULL_TREE); } + else if (decl_context == PARM) + { + if (array_parm_vla_unspec_p) + { + if (! orig_name) + { + /* C99 6.7.5.2p4 */ + error ("%<[*]%> not allowed in other than a declaration"); + } + + itype = build_range_type (sizetype, size_zero_node, NULL_TREE); + size_varies = 1; + } + } + else if (decl_context == TYPENAME) + { + if (array_parm_vla_unspec_p) + { + /* The error is printed elsewhere. We use this to + avoid messing up with incomplete array types of + the same type, that would otherwise be modified + below. */ + itype = build_range_type (sizetype, size_zero_node, + NULL_TREE); + } + } /* Complain about arrays of incomplete types. */ if (!COMPLETE_TYPE_P (type)) { error ("array type has incomplete element type"); - type = error_mark_node; + type = error_mark_node; } else + /* When itype is NULL, a shared incomplete array type is + returned for all array of a given type. Elsewhere we + make sure we don't complete that type before copying + it, but here we want to make sure we don't ever + modify the shared type, so we gcc_assert (itype) + below. */ type = build_array_type (type, itype); - if (size_varies) - C_TYPE_VARIABLE_SIZE (type) = 1; - - /* The GCC extension for zero-length arrays differs from - ISO flexible array members in that sizeof yields - zero. */ - if (size && integer_zerop (size)) + if (type != error_mark_node) { - TYPE_SIZE (type) = bitsize_zero_node; - TYPE_SIZE_UNIT (type) = size_zero_node; + if (size_varies) + { + /* It is ok to modify type here even if itype is + NULL: if size_varies, we're in a + multi-dimensional array and the inner type has + variable size, so the enclosing shared array type + must too. */ + if (size && TREE_CODE (size) == INTEGER_CST) + type + = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); + C_TYPE_VARIABLE_SIZE (type) = 1; + } + + /* The GCC extension for zero-length arrays differs from + ISO flexible array members in that sizeof yields + zero. */ + if (size && integer_zerop (size)) + { + gcc_assert (itype); + TYPE_SIZE (type) = bitsize_zero_node; + TYPE_SIZE_UNIT (type) = size_zero_node; + } + if (array_parm_vla_unspec_p) + { + gcc_assert (itype); + /* The type is complete. C99 6.7.5.2p4 */ + TYPE_SIZE (type) = bitsize_zero_node; + TYPE_SIZE_UNIT (type) = size_zero_node; + } } if (decl_context != PARM @@ -4264,7 +4401,7 @@ grokdeclarator (const struct c_declarator *declarator, type for the function to return. */ if (type == error_mark_node) continue; - + size_varies = 0; /* Warn about some types functions can't return. */ @@ -4283,12 +4420,14 @@ grokdeclarator (const struct c_declarator *declarator, inner layer of declarator. */ arg_info = declarator->u.arg_info; arg_types = grokparms (arg_info, really_funcdef); + if (really_funcdef) + put_pending_sizes (arg_info->pending_sizes); /* Type qualifiers before the return type of the function qualify the return type, not the function type. */ if (type_quals) { - /* Type qualifiers on a function return type are + /* Type qualifiers on a function return type are normally permitted by the standard but have no effect, so give a warning at -Wreturn-type. Qualifiers on a void return type are banned on @@ -4299,20 +4438,20 @@ grokdeclarator (const struct c_declarator *declarator, else warning (OPT_Wreturn_type, "type qualifiers ignored on function return type"); - + type = c_build_qualified_type (type, type_quals); } type_quals = TYPE_UNQUALIFIED; - + type = build_function_type (type, arg_types); declarator = declarator->declarator; - + /* Set the TYPE_CONTEXTs for each tagged type which is local to the formal parameter list of this FUNCTION_TYPE to point to the FUNCTION_TYPE node itself. */ { tree link; - + for (link = arg_info->tags; link; link = TREE_CHAIN (link)) @@ -4333,7 +4472,7 @@ grokdeclarator (const struct c_declarator *declarator, size_varies = 0; type = build_pointer_type (type); - + /* Process type qualifiers (such as const or volatile) that were given inside the `*'. */ type_quals = declarator->u.pointer_quals; @@ -4357,7 +4496,8 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (type) == ARRAY_TYPE && COMPLETE_TYPE_P (type) - && TREE_OVERFLOW (TYPE_SIZE (type))) + && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST + && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) { error ("size of array %qs is too large", name); /* If we proceed with the array type as it is, we'll eventually @@ -4380,25 +4520,10 @@ grokdeclarator (const struct c_declarator *declarator, C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; decl_attributes (&decl, returned_attrs, 0); if (declspecs->inline_p) - pedwarn ("%Jtypedef %qD declared %", decl, decl); + pedwarn ("typedef %q+D declared %", decl); return decl; } - /* Detect the case of an array type of unspecified size - which came, as such, direct from a typedef name. - We must copy the type, so that each identifier gets - a distinct type, so that each identifier's size can be - controlled separately by its own initializer. */ - - if (type != 0 && typedef_type != 0 - && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0 - && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type)) - { - type = build_array_type (TREE_TYPE (type), 0); - if (size_varies) - C_TYPE_VARIABLE_SIZE (type) = 1; - } - /* If this is a type name (such as, in a cast or sizeof), compute the type and return it now. */ @@ -4417,6 +4542,13 @@ grokdeclarator (const struct c_declarator *declarator, return type; } + if (pedantic && decl_context == FIELD + && variably_modified_type_p (type, NULL_TREE)) + { + /* C99 6.7.2.1p8 */ + pedwarn ("a member of a structure or union cannot have a variably modified type"); + } + /* Aside from typedefs and type names (handle above), `void' at top level (not within pointer) is allowed only in public variables. @@ -4493,9 +4625,8 @@ grokdeclarator (const struct c_declarator *declarator, promoted_type = c_type_promotes_to (type); DECL_ARG_TYPE (decl) = promoted_type; - DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written; if (declspecs->inline_p) - pedwarn ("%Jparameter %qD declared %", decl, decl); + pedwarn ("parameter %q+D declared %", decl); } else if (decl_context == FIELD) { @@ -4512,7 +4643,7 @@ grokdeclarator (const struct c_declarator *declarator, type = build_pointer_type (type); } else if (TREE_CODE (type) != ERROR_MARK - && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type)) + && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type)) { error ("field %qs has incomplete type", name); type = error_mark_node; @@ -4544,8 +4675,8 @@ grokdeclarator (const struct c_declarator *declarator, } else if (storage_class == csc_static) { - error ("invalid storage class for function %qs", name); - if (funcdef_flag) + error ("invalid storage class for function %qs", name); + if (funcdef_flag) storage_class = declspecs->storage_class = csc_none; else return 0; @@ -4649,7 +4780,7 @@ grokdeclarator (const struct c_declarator *declarator, C_DECL_VARIABLE_SIZE (decl) = 1; if (declspecs->inline_p) - pedwarn ("%Jvariable %qD declared %", decl, decl); + pedwarn ("variable %q+D declared %", decl); /* At file scope, an initialized extern declaration may follow a static declaration. In that case, DECL_EXTERNAL will be @@ -4659,11 +4790,10 @@ grokdeclarator (const struct c_declarator *declarator, /* At file scope, the presence of a `static' or `register' storage class specifier, or the absence of all storage class specifiers makes this declaration a definition (perhaps tentative). Also, - the absence of both `static' and `register' makes it public. */ + the absence of `static' makes it public. */ if (current_scope == file_scope) { - TREE_PUBLIC (decl) = !(storage_class == csc_static - || storage_class == csc_register); + TREE_PUBLIC (decl) = storage_class != csc_static; TREE_STATIC (decl) = !extern_ref; } /* Not at file scope, only `static' makes a static definition. */ @@ -4676,7 +4806,7 @@ grokdeclarator (const struct c_declarator *declarator, if (threadp) { if (targetm.have_tls) - DECL_THREAD_LOCAL (decl) = 1; + DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); else /* A mere warning is sure to result in improper semantics at runtime. Don't bother to allow this to compile. */ @@ -4684,6 +4814,13 @@ grokdeclarator (const struct c_declarator *declarator, } } + if (storage_class == csc_extern + && variably_modified_type_p (type, NULL_TREE)) + { + /* C99 6.7.5.2p2 */ + error ("object with variably modified type must have no linkage"); + } + /* Record `register' declaration for warnings on & and in case doing stupid register allocation. */ @@ -4698,8 +4835,11 @@ grokdeclarator (const struct c_declarator *declarator, /* If a type has volatile components, it should be stored in memory. Otherwise, the fact that those components are volatile - will be ignored, and would even crash the compiler. */ - if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))) + will be ignored, and would even crash the compiler. + Of course, this only makes sense on VAR,PARM, and RESULT decl's. */ + if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)) + && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL + || TREE_CODE (decl) == RESULT_DECL)) { /* It is not an error for a structure with volatile fields to be declared register, but reset DECL_REGISTER since it @@ -4722,7 +4862,7 @@ grokdeclarator (const struct c_declarator *declarator, } /* Decode the parameter-list info for a function type or function definition. - The argument is the value returned by `get_parm_info' (or made in parse.y + The argument is the value returned by `get_parm_info' (or made in c-parse.c if there is an identifier list instead of a parameter decl list). These two functions are separate because when a function returns or receives functions then each is called multiple times but the order @@ -4740,9 +4880,16 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) { tree arg_types = arg_info->types; - if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag - && !in_system_header) - warning (0, "function declaration isn%'t a prototype"); + if (funcdef_flag && arg_info->had_vla_unspec) + { + /* A function definition isn't function prototype scope C99 6.2.1p4. */ + /* C99 6.7.5.2p4 */ + error ("%<[*]%> not allowed in other than function prototype scope"); + } + + if (arg_types == 0 && !funcdef_flag && !in_system_header) + warning (OPT_Wstrict_prototypes, + "function declaration isn%'t a prototype"); if (arg_types == error_mark_node) return 0; /* don't set TYPE_ARG_TYPES in this case */ @@ -4783,8 +4930,8 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) if (funcdef_flag) { if (DECL_NAME (parm)) - error ("%Jparameter %u (%qD) has incomplete type", - parm, parmno, parm); + error ("parameter %u (%q+D) has incomplete type", + parmno, parm); else error ("%Jparameter %u has incomplete type", parm, parmno); @@ -4795,13 +4942,16 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) else if (VOID_TYPE_P (type)) { if (DECL_NAME (parm)) - warning (0, "%Jparameter %u (%qD) has void type", - parm, parmno, parm); + warning (0, "parameter %u (%q+D) has void type", + parmno, parm); else warning (0, "%Jparameter %u has void type", parm, parmno); } } + + if (DECL_NAME (parm) && TREE_USED (parm)) + warn_if_shadowing (parm); } return arg_types; } @@ -4833,6 +4983,8 @@ get_parm_info (bool ellipsis) arg_info->tags = 0; arg_info->types = 0; arg_info->others = 0; + arg_info->pending_sizes = 0; + arg_info->had_vla_unspec = current_scope->had_vla_unspec; /* The bindings in this scope must not get put into a block. We will take care of deleting the binding nodes. */ @@ -4847,7 +4999,7 @@ get_parm_info (bool ellipsis) (by 'const' or 'volatile'), or has a storage class specifier ('register'), then the behavior is undefined; issue an error. Typedefs for 'void' are OK (see DR#157). */ - if (b->prev == 0 /* one binding */ + if (b->prev == 0 /* one binding */ && TREE_CODE (b->decl) == PARM_DECL /* which is a parameter */ && !DECL_NAME (b->decl) /* anonymous */ && VOID_TYPE_P (TREE_TYPE (b->decl))) /* of void type */ @@ -4887,8 +5039,7 @@ get_parm_info (bool ellipsis) /* Check for forward decls that never got their actual decl. */ if (TREE_ASM_WRITTEN (decl)) - error ("%Jparameter %qD has just a forward declaration", - decl, decl); + error ("parameter %q+D has just a forward declaration", decl); /* Check for (..., void, ...) and issue an error. */ else if (VOID_TYPE_P (type) && !DECL_NAME (decl)) { @@ -4988,6 +5139,7 @@ get_parm_info (bool ellipsis) arg_info->tags = tags; arg_info->types = types; arg_info->others = others; + arg_info->pending_sizes = get_pending_sizes (); return arg_info; } @@ -5073,17 +5225,17 @@ start_struct (enum tree_code code, tree name) if (ref && TREE_CODE (ref) == code) { if (TYPE_SIZE (ref)) - { + { if (code == UNION_TYPE) error ("redefinition of %", name); - else + else error ("redefinition of %", name); } else if (C_TYPE_BEING_DEFINED (ref)) { if (code == UNION_TYPE) error ("nested redefinition of %", name); - else + else error ("nested redefinition of %", name); } } @@ -5202,7 +5354,7 @@ detect_field_duplicates (tree fieldlist) for (y = fieldlist; y != x; y = TREE_CHAIN (y)) if (DECL_NAME (y) == DECL_NAME (x)) { - error ("%Jduplicate member %qD", x, x); + error ("duplicate member %q+D", x); DECL_NAME (x) = NULL_TREE; } } @@ -5218,7 +5370,7 @@ detect_field_duplicates (tree fieldlist) slot = htab_find_slot (htab, y, INSERT); if (*slot) { - error ("%Jduplicate member %qD", x, x); + error ("duplicate member %q+D", x); DECL_NAME (x) = NULL_TREE; } *slot = y; @@ -5281,8 +5433,13 @@ finish_struct (tree t, tree fieldlist, tree attributes) saw_named_field = 0; for (x = fieldlist; x; x = TREE_CHAIN (x)) { + if (TREE_TYPE (x) == error_mark_node) + continue; + DECL_CONTEXT (x) = t; - DECL_PACKED (x) |= TYPE_PACKED (t); + + if (TYPE_PACKED (t) && TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) + DECL_PACKED (x) = 1; /* If any field is const, the structure type is pseudo-const. */ if (TREE_READONLY (x)) @@ -5368,7 +5525,7 @@ finish_struct (tree t, tree fieldlist, tree attributes) if (width != TYPE_PRECISION (type)) { TREE_TYPE (*fieldlistp) - = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type)); + = c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type)); DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp)); } DECL_INITIAL (*fieldlistp) = 0; @@ -5390,46 +5547,46 @@ finish_struct (tree t, tree fieldlist, tree attributes) for (x = fieldlist; x; x = TREE_CHAIN (x)) { - if (len > 15 || DECL_NAME (x) == NULL) - break; - len += 1; + if (len > 15 || DECL_NAME (x) == NULL) + break; + len += 1; } if (len > 15) { - tree *field_array; - struct lang_type *space; - struct sorted_fields_type *space2; + tree *field_array; + struct lang_type *space; + struct sorted_fields_type *space2; - len += list_length (x); + len += list_length (x); - /* Use the same allocation policy here that make_node uses, to - ensure that this lives as long as the rest of the struct decl. - All decls in an inline function need to be saved. */ + /* Use the same allocation policy here that make_node uses, to + ensure that this lives as long as the rest of the struct decl. + All decls in an inline function need to be saved. */ - space = GGC_CNEW (struct lang_type); - space2 = GGC_NEWVAR (struct sorted_fields_type, + space = GGC_CNEW (struct lang_type); + space2 = GGC_NEWVAR (struct sorted_fields_type, sizeof (struct sorted_fields_type) + len * sizeof (tree)); - len = 0; + len = 0; space->s = space2; field_array = &space2->elts[0]; - for (x = fieldlist; x; x = TREE_CHAIN (x)) - { - field_array[len++] = x; - - /* If there is anonymous struct or union, break out of the loop. */ - if (DECL_NAME (x) == NULL) - break; - } - /* Found no anonymous struct/union. Add the TYPE_LANG_SPECIFIC. */ - if (x == NULL) - { - TYPE_LANG_SPECIFIC (t) = space; - TYPE_LANG_SPECIFIC (t)->s->len = len; - field_array = TYPE_LANG_SPECIFIC (t)->s->elts; - qsort (field_array, len, sizeof (tree), field_decl_cmp); - } + for (x = fieldlist; x; x = TREE_CHAIN (x)) + { + field_array[len++] = x; + + /* If there is anonymous struct or union, break out of the loop. */ + if (DECL_NAME (x) == NULL) + break; + } + /* Found no anonymous struct/union. Add the TYPE_LANG_SPECIFIC. */ + if (x == NULL) + { + TYPE_LANG_SPECIFIC (t) = space; + TYPE_LANG_SPECIFIC (t)->s->len = len; + field_array = TYPE_LANG_SPECIFIC (t)->s->elts; + qsort (field_array, len, sizeof (tree), field_decl_cmp); + } } } @@ -5437,8 +5594,9 @@ finish_struct (tree t, tree fieldlist, tree attributes) { TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t); - TYPE_ALIGN (x) = TYPE_ALIGN (t); - TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t); + C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t); + C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t); + C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t); } /* If this was supposed to be a transparent union, but we can't @@ -5478,7 +5636,7 @@ finish_struct (tree t, tree fieldlist, tree attributes) /* If we're inside a function proper, i.e. not file-scope and not still parsing parameters, then arrange for the size of a variable sized type to be bound now. */ - if (cur_stmt_list && variably_modified_type_p (t, NULL)) + if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE)) add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t))); return t; @@ -5813,8 +5971,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, if (DECL_DECLARED_INLINE_P (decl1) && DECL_UNINLINABLE (decl1) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1))) - warning (OPT_Wattributes, "%Jinline function %qD given attribute noinline", - decl1, decl1); + warning (OPT_Wattributes, "inline function %q+D given attribute noinline", + decl1); announce_function (decl1); @@ -5837,6 +5995,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, /* If this definition isn't a prototype and we had a prototype declaration before, copy the arg type info from that prototype. */ old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope); + if (old_decl && TREE_CODE (old_decl) != FUNCTION_DECL) + old_decl = 0; current_function_prototype_locus = UNKNOWN_LOCATION; current_function_prototype_built_in = false; current_function_prototype_arg_types = NULL_TREE; @@ -5891,14 +6051,15 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, && old_decl != error_mark_node && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0 && C_DECL_ISNT_PROTOTYPE (old_decl)) - warning (0, "function declaration isn%'t a prototype"); + warning (OPT_Wstrict_prototypes, + "function declaration isn%'t a prototype"); /* Optionally warn of any global def with no previous prototype. */ else if (warn_missing_prototypes && old_decl != error_mark_node && TREE_PUBLIC (decl1) && !MAIN_NAME_P (DECL_NAME (decl1)) && C_DECL_ISNT_PROTOTYPE (old_decl)) - warning (0, "%Jno previous prototype for %qD", decl1, decl1); + warning (OPT_Wmissing_prototypes, "no previous prototype for %q+D", decl1); /* Optionally warn of any def with no previous prototype if the function has already been used. */ else if (warn_missing_prototypes @@ -5906,14 +6067,15 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, && old_decl != error_mark_node && TREE_USED (old_decl) && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0) - warning (0, "%J%qD was used with no prototype before its definition", - decl1, decl1); + warning (OPT_Wmissing_prototypes, + "%q+D was used with no prototype before its definition", decl1); /* Optionally warn of any global def with no previous declaration. */ else if (warn_missing_declarations && TREE_PUBLIC (decl1) && old_decl == 0 && !MAIN_NAME_P (DECL_NAME (decl1))) - warning (0, "%Jno previous declaration for %qD", decl1, decl1); + warning (OPT_Wmissing_declarations, "no previous declaration for %q+D", + decl1); /* Optionally warn of any def with no previous declaration if the function has already been used. */ else if (warn_missing_declarations @@ -5921,8 +6083,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, && old_decl != error_mark_node && TREE_USED (old_decl) && C_DECL_IMPLICIT (old_decl)) - warning (0, "%J%qD was used with no declaration before its definition", - decl1, decl1); + warning (OPT_Wmissing_declarations, + "%q+D was used with no declaration before its definition", decl1); /* This is a definition, not a reference. So normally clear DECL_EXTERNAL. @@ -5954,7 +6116,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1))) != integer_type_node) - pedwarn ("%Jreturn type of %qD is not %", decl1, decl1); + pedwarn ("return type of %q+D is not %", decl1); for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args; args = TREE_CHAIN (args)) @@ -5969,8 +6131,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, { case 1: if (TYPE_MAIN_VARIANT (type) != integer_type_node) - pedwarn ("%Jfirst argument of %qD should be %", - decl1, decl1); + pedwarn ("first argument of %q+D should be %", decl1); break; case 2: @@ -5978,8 +6139,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) != char_type_node)) - pedwarn ("%Jsecond argument of %qD should be %", - decl1, decl1); + pedwarn ("second argument of %q+D should be %", + decl1); break; case 3: @@ -5987,8 +6148,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) != char_type_node)) - pedwarn ("%Jthird argument of %qD should probably be " - "%", decl1, decl1); + pedwarn ("third argument of %q+D should probably be " + "%", decl1); break; } } @@ -5997,10 +6158,10 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, argument because it's only mentioned in an appendix of the standard. */ if (argct > 0 && (argct < 2 || argct > 3)) - pedwarn ("%J%qD takes only zero or two arguments", decl1, decl1); + pedwarn ("%q+D takes only zero or two arguments", decl1); if (!TREE_PUBLIC (decl1)) - pedwarn ("%J%qD is normally a non-static function", decl1, decl1); + pedwarn ("%q+D is normally a non-static function", decl1); } /* Record the decl so that the function name is defined. @@ -6057,9 +6218,10 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) warning if we got here because ARG_INFO_TYPES was error_mark_node (this happens when a function definition has just an ellipsis in its parameter list). */ - else if (warn_traditional && !in_system_header && !current_function_scope + else if (!in_system_header && !current_function_scope && arg_info->types != error_mark_node) - warning (0, "%Jtraditional C rejects ISO C style function definitions", + warning (OPT_Wtraditional, + "%Jtraditional C rejects ISO C style function definitions", fndecl); /* Now make all the parameter declarations visible in the function body. @@ -6068,8 +6230,12 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) { DECL_CONTEXT (decl) = current_function_decl; if (DECL_NAME (decl)) - bind (DECL_NAME (decl), decl, current_scope, - /*invisible=*/false, /*nested=*/false); + { + bind (DECL_NAME (decl), decl, current_scope, + /*invisible=*/false, /*nested=*/false); + if (!TREE_USED (decl)) + warn_if_shadowing (decl); + } else error ("%Jparameter name omitted", decl); } @@ -6102,13 +6268,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) struct c_binding *b; tree parm, decl, last; tree parmids = arg_info->parms; - - /* We use DECL_WEAK as a flag to show which parameters have been - seen already, since it is not used on PARM_DECL. */ -#ifdef ENABLE_CHECKING - for (b = current_scope->bindings; b; b = b->prev) - gcc_assert (TREE_CODE (b->decl) != PARM_DECL || !DECL_WEAK (b->decl)); -#endif + struct pointer_set_t *seen_args = pointer_set_create (); if (!in_system_header) warning (OPT_Wold_style_definition, "%Jold-style function definition", @@ -6131,12 +6291,12 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) decl = b->decl; /* If we got something other than a PARM_DECL it is an error. */ if (TREE_CODE (decl) != PARM_DECL) - error ("%J%qD declared as a non-parameter", decl, decl); + error ("%q+D declared as a non-parameter", decl); /* If the declaration is already marked, we have a duplicate name. Complain and ignore the duplicate. */ - else if (DECL_WEAK (decl)) + else if (pointer_set_contains (seen_args, decl)) { - error ("%Jmultiple parameters named %qD", decl, decl); + error ("multiple parameters named %q+D", decl); TREE_PURPOSE (parm) = 0; continue; } @@ -6144,11 +6304,12 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) an int. */ else if (VOID_TYPE_P (TREE_TYPE (decl))) { - error ("%Jparameter %qD declared with void type", decl, decl); + error ("parameter %q+D declared with void type", decl); TREE_TYPE (decl) = integer_type_node; DECL_ARG_TYPE (decl) = integer_type_node; layout_decl (decl, 0); } + warn_if_shadowing (decl); } /* If no declaration found, default to int. */ else @@ -6157,15 +6318,16 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) DECL_ARG_TYPE (decl) = TREE_TYPE (decl); DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (fndecl); pushdecl (decl); + warn_if_shadowing (decl); if (flag_isoc99) - pedwarn ("%Jtype of %qD defaults to %", decl, decl); + pedwarn ("type of %q+D defaults to %", decl); else if (extra_warnings) - warning (0, "%Jtype of %qD defaults to %", decl, decl); + warning (OPT_Wextra, "type of %q+D defaults to %", decl); } TREE_PURPOSE (parm) = decl; - DECL_WEAK (decl) = 1; + pointer_set_insert (seen_args, decl); } /* Now examine the parms chain for incomplete declarations @@ -6180,14 +6342,13 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) if (TREE_TYPE (parm) != error_mark_node && !COMPLETE_TYPE_P (TREE_TYPE (parm))) { - error ("%Jparameter %qD has incomplete type", parm, parm); + error ("parameter %q+D has incomplete type", parm); TREE_TYPE (parm) = error_mark_node; } - if (!DECL_WEAK (parm)) + if (!pointer_set_contains (seen_args, parm)) { - error ("%Jdeclaration for parameter %qD but no such parameter", - parm, parm); + error ("declaration for parameter %q+D but no such parameter", parm); /* Pretend the parameter was not missing. This gets us to a standard state and minimizes @@ -6208,18 +6369,18 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) { last = TREE_PURPOSE (parm); DECL_ARGUMENTS (fndecl) = last; - DECL_WEAK (last) = 0; for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm)) if (TREE_PURPOSE (parm)) { TREE_CHAIN (last) = TREE_PURPOSE (parm); last = TREE_PURPOSE (parm); - DECL_WEAK (last) = 0; } TREE_CHAIN (last) = 0; } + pointer_set_destroy (seen_args); + /* If there was a previous prototype, set the DECL_ARG_TYPE of each argument according to the type previously specified, and report any mismatches. */ @@ -6412,21 +6573,25 @@ store_parm_decls (void) cfun->x_dont_save_pending_sizes_p = 1; } -/* Handle attribute((warn_unused_result)) on FNDECL and all its nested - functions. */ +/* Emit diagnostics that require gimple input for detection. Operate on + FNDECL and all its nested functions. */ static void -c_warn_unused_result_recursively (tree fndecl) +c_gimple_diagnostics_recursively (tree fndecl) { struct cgraph_node *cgn; /* Handle attribute((warn_unused_result)). Relies on gimple input. */ c_warn_unused_result (&DECL_SAVED_TREE (fndecl)); + /* Notice when OpenMP structured block constraints are violated. */ + if (flag_openmp) + diagnose_omp_structured_block_errors (fndecl); + /* Finalize all nested functions now. */ cgn = cgraph_node (fndecl); for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) - c_warn_unused_result_recursively (cgn->decl); + c_gimple_diagnostics_recursively (cgn->decl); } /* Finish up a function declaration and compile that function @@ -6448,12 +6613,12 @@ finish_function (void) { tree args = DECL_ARGUMENTS (fndecl); for (; args; args = TREE_CHAIN (args)) - { - tree type = TREE_TYPE (args); - if (INTEGRAL_TYPE_P (type) - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (args) = integer_type_node; - } + { + tree type = TREE_TYPE (args); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + DECL_ARG_TYPE (args) = integer_type_node; + } } if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node) @@ -6472,7 +6637,7 @@ finish_function (void) /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned. If warn_main is -1 (-Wno-main) we don't want to be warned. */ if (!warn_main) - pedwarn ("%Jreturn type of %qD is not %", fndecl, fndecl); + pedwarn ("return type of %q+D is not %", fndecl); } else { @@ -6516,7 +6681,8 @@ finish_function (void) inline function, as we might never be compiled separately. */ && DECL_INLINE (fndecl)) { - warning (0, "no return statement in function returning non-void"); + warning (OPT_Wreturn_type, + "no return statement in function returning non-void"); TREE_NO_WARNING (fndecl) = 1; } @@ -6525,7 +6691,7 @@ finish_function (void) if (extra_warnings && current_function_returns_value && current_function_returns_null) - warning (0, "this function may return with or without a value"); + warning (OPT_Wextra, "this function may return with or without a value"); /* Store the end of the function, so that we get good line number info for the epilogue. */ @@ -6551,9 +6717,9 @@ finish_function (void) && !undef_nested_function) { if (!decl_function_context (fndecl)) - { - c_genericize (fndecl); - c_warn_unused_result_recursively (fndecl); + { + c_genericize (fndecl); + c_gimple_diagnostics_recursively (fndecl); /* ??? Objc emits functions after finalizing the compilation unit. This should be cleaned up later and this conditional removed. */ @@ -6564,14 +6730,14 @@ finish_function (void) } cgraph_finalize_function (fndecl, false); - } + } else - { - /* Register this function with cgraph just far enough to get it - added to our parent's nested function list. Handy, since the - C front end doesn't have such a list. */ - (void) cgraph_node (fndecl); - } + { + /* Register this function with cgraph just far enough to get it + added to our parent's nested function list. Handy, since the + C front end doesn't have such a list. */ + (void) cgraph_node (fndecl); + } } if (!decl_function_context (fndecl)) @@ -6599,19 +6765,23 @@ c_expand_body (tree fndecl) if (DECL_STATIC_CONSTRUCTOR (fndecl) && targetm.have_ctors_dtors) targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0), - DEFAULT_INIT_PRIORITY); + DEFAULT_INIT_PRIORITY); if (DECL_STATIC_DESTRUCTOR (fndecl) && targetm.have_ctors_dtors) targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0), - DEFAULT_INIT_PRIORITY); + DEFAULT_INIT_PRIORITY); } /* Check the declarations given in a for-loop for satisfying the C99 - constraints. */ -void + constraints. If exactly one such decl is found, return it. */ + +tree check_for_loop_decls (void) { struct c_binding *b; + tree one_decl = NULL_TREE; + int n_decls = 0; + if (!flag_isoc99) { @@ -6619,7 +6789,7 @@ check_for_loop_decls (void) the C99 for loop scope. This doesn't make much sense, so don't allow it. */ error ("% loop initial declaration used outside C99 mode"); - return; + return NULL_TREE; } /* C99 subclause 6.8.5 paragraph 3: @@ -6647,11 +6817,11 @@ check_for_loop_decls (void) { case VAR_DECL: if (TREE_STATIC (decl)) - error ("%Jdeclaration of static variable %qD in % loop " - "initial declaration", decl, decl); + error ("declaration of static variable %q+D in % loop " + "initial declaration", decl); else if (DECL_EXTERNAL (decl)) - error ("%Jdeclaration of % variable %qD in % loop " - "initial declaration", decl, decl); + error ("declaration of % variable %q+D in % loop " + "initial declaration", decl); break; case RECORD_TYPE: @@ -6667,10 +6837,15 @@ check_for_loop_decls (void) id); break; default: - error ("%Jdeclaration of non-variable %qD in % loop " - "initial declaration", decl, decl); + error ("declaration of non-variable %q+D in % loop " + "initial declaration", decl); } + + n_decls++; + one_decl = decl; } + + return n_decls == 1 ? one_decl : NULL_TREE; } /* Save and reinitialize the variables @@ -7018,6 +7193,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->typespec_word == cts_float) error ("both % and % in " "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat32) + error ("both % and %<_Decimal32%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat64) + error ("both % and %<_Decimal64%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat128) + error ("both % and %<_Decimal128%> in " + "declaration specifiers"); else specs->long_p = true; break; @@ -7041,6 +7225,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->typespec_word == cts_double) error ("both % and % in " "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat32) + error ("both % and %<_Decimal32%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat64) + error ("both % and %<_Decimal64%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat128) + error ("both % and %<_Decimal128%> in " + "declaration specifiers"); else specs->short_p = true; break; @@ -7061,6 +7254,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->typespec_word == cts_double) error ("both % and % in " "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat32) + error ("both % and %<_Decimal32%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat64) + error ("both % and %<_Decimal64%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat128) + error ("both % and %<_Decimal128%> in " + "declaration specifiers"); else specs->signed_p = true; break; @@ -7081,6 +7283,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->typespec_word == cts_double) error ("both % and % in " "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat32) + error ("both % and %<_Decimal32%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat64) + error ("both % and %<_Decimal64%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat128) + error ("both % and %<_Decimal128%> in " + "declaration specifiers"); else specs->unsigned_p = true; break; @@ -7094,6 +7305,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->typespec_word == cts_bool) error ("both % and %<_Bool%> in " "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat32) + error ("both % and %<_Decimal32%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat64) + error ("both % and %<_Decimal64%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat128) + error ("both % and %<_Decimal128%> in " + "declaration specifiers"); else specs->complex_p = true; break; @@ -7199,6 +7419,47 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else specs->typespec_word = cts_double; return specs; + case RID_DFLOAT32: + case RID_DFLOAT64: + case RID_DFLOAT128: + { + const char *str; + if (i == RID_DFLOAT32) + str = "_Decimal32"; + else if (i == RID_DFLOAT64) + str = "_Decimal64"; + else + str = "_Decimal128"; + if (specs->long_long_p) + error ("both % and %<%s%> in " + "declaration specifiers", str); + if (specs->long_p) + error ("both % and %<%s%> in " + "declaration specifiers", str); + else if (specs->short_p) + error ("both % and %<%s%> in " + "declaration specifiers", str); + else if (specs->signed_p) + error ("both % and %<%s%> in " + "declaration specifiers", str); + else if (specs->unsigned_p) + error ("both % and %<%s%> in " + "declaration specifiers", str); + else if (specs->complex_p) + error ("both % and %<%s%> in " + "declaration specifiers", str); + else if (i == RID_DFLOAT32) + specs->typespec_word = cts_dfloat32; + else if (i == RID_DFLOAT64) + specs->typespec_word = cts_dfloat64; + else + specs->typespec_word = cts_dfloat128; + } + if (!targetm.decimal_float_supported_p ()) + error ("decimal floating point not supported for this target"); + if (pedantic) + pedwarn ("ISO C does not support decimal floating point"); + return specs; default: /* ObjC reserved word "id", handled below. */ break; @@ -7263,7 +7524,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) && C_IS_RESERVED_WORD (scspec)); i = C_RID_CODE (scspec); if (extra_warnings && specs->non_sc_seen_p) - warning (0, "%qE is not at beginning of declaration", scspec); + warning (OPT_Wextra, "%qE is not at beginning of declaration", scspec); switch (i) { case RID_INLINE: @@ -7476,6 +7737,18 @@ finish_declspecs (struct c_declspecs *specs) : double_type_node); } break; + case cts_dfloat32: + case cts_dfloat64: + case cts_dfloat128: + gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p + && !specs->signed_p && !specs->unsigned_p && !specs->complex_p); + if (specs->typespec_word == cts_dfloat32) + specs->type = dfloat32_type_node; + else if (specs->typespec_word == cts_dfloat64) + specs->type = dfloat64_type_node; + else + specs->type = dfloat128_type_node; + break; default: gcc_unreachable (); } @@ -7501,20 +7774,19 @@ build_cdtor (int method_type, tree cdtors) cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY); } -/* Perform final processing on one file scope's declarations (or the - external scope's declarations), GLOBALS. */ +/* A subroutine of c_write_global_declarations. Perform final processing + on one file scope's declarations (or the external scope's declarations), + GLOBALS. */ + static void c_write_global_declarations_1 (tree globals) { - size_t len = list_length (globals); - tree *vec = XNEWVEC (tree, len); - size_t i; tree decl; + bool reconsider; /* Process the decls in the order they were written. */ - for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) + for (decl = globals; decl; decl = TREE_CHAIN (decl)) { - vec[i] = decl; /* Check for used but undefined static functions using the C standard's definition of "used", and set TREE_NO_WARNING so that check_global_declarations doesn't repeat the check. */ @@ -7524,21 +7796,44 @@ c_write_global_declarations_1 (tree globals) && !TREE_PUBLIC (decl) && C_DECL_USED (decl)) { - pedwarn ("%J%qF used but never defined", decl, decl); + pedwarn ("%q+F used but never defined", decl); TREE_NO_WARNING (decl) = 1; } + + wrapup_global_declaration_1 (decl); } - wrapup_global_declarations (vec, len); - check_global_declarations (vec, len); + do + { + reconsider = false; + for (decl = globals; decl; decl = TREE_CHAIN (decl)) + reconsider |= wrapup_global_declaration_2 (decl); + } + while (reconsider); - free (vec); + for (decl = globals; decl; decl = TREE_CHAIN (decl)) + check_global_declaration_1 (decl); } +/* A subroutine of c_write_global_declarations Emit debug information for each + of the declarations in GLOBALS. */ + +static void +c_write_global_declarations_2 (tree globals) +{ + tree decl; + + for (decl = globals; decl ; decl = TREE_CHAIN (decl)) + debug_hooks->global_decl (decl); +} + +/* Preserve the external declarations scope across a garbage collect. */ +static GTY(()) tree ext_block; + void c_write_global_declarations (void) { - tree ext_block, t; + tree t; /* We don't want to do this if generating a PCH. */ if (pch_file) @@ -7554,6 +7849,18 @@ c_write_global_declarations (void) external_scope = 0; gcc_assert (!current_scope); + if (ext_block) + { + tree tmp = BLOCK_VARS (ext_block); + int flags; + FILE * stream = dump_begin (TDI_tu, &flags); + if (stream && tmp) + { + dump_node (tmp, flags & ~TDF_SLIM, stream); + dump_end (TDI_tu, stream); + } + } + /* Process all file scopes in this compilation, and the external_scope, through wrapup_global_declarations and check_global_declarations. */ for (t = all_translation_units; t; t = TREE_CHAIN (t)) @@ -7569,6 +7876,19 @@ c_write_global_declarations (void) /* We're done parsing; proceed to optimize and emit assembly. FIXME: shouldn't be the front end's responsibility to call this. */ cgraph_optimize (); + + /* After cgraph has had a chance to emit everything that's going to + be emitted, output debug information for globals. */ + if (errorcount == 0 && sorrycount == 0) + { + timevar_push (TV_SYMOUT); + for (t = all_translation_units; t; t = TREE_CHAIN (t)) + c_write_global_declarations_2 (BLOCK_VARS (DECL_INITIAL (t))); + c_write_global_declarations_2 (BLOCK_VARS (ext_block)); + timevar_pop (TV_SYMOUT); + } + + ext_block = NULL; } #include "gt-c-decl.h"