OSDN Git Service

* id.po: Update.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 18ad119..6f88f62 100644 (file)
@@ -52,7 +52,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-pragma.h"
 #include "langhooks.h"
 #include "tree-mudflap.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
 #include "diagnostic.h"
 #include "tree-dump.h"
 #include "cgraph.h"
@@ -61,6 +62,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "except.h"
 #include "langhooks-def.h"
 #include "pointer-set.h"
+#include "gimple.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -248,7 +250,7 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
 
 union lang_tree_node
   GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) GENERIC_NEXT (&%h.generic))")))
+       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))")))
 {
   union tree_node GTY ((tag ("0"),
                        desc ("tree_node_structure (&%h)")))
@@ -445,7 +447,7 @@ c_print_identifier (FILE *file, tree node, int indent)
   print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
   print_node (file, "tag", I_TAG_DECL (node), indent + 4);
   print_node (file, "label", I_LABEL_DECL (node), indent + 4);
-  if (C_IS_RESERVED_WORD (node))
+  if (C_IS_RESERVED_WORD (node) && C_RID_CODE (node) != RID_CXX_COMPAT_WARN)
     {
       tree rid = ridpointers[C_RID_CODE (node)];
       indent_to (file, indent + 4);
@@ -786,7 +788,7 @@ pop_scope (void)
                   && TREE_PUBLIC (p)
                   && !DECL_INITIAL (p)
                   && !flag_gnu89_inline)
-           pedwarn ("inline function %q+D declared but never defined", p);
+           pedwarn (input_location, 0, "inline function %q+D declared but never defined", p);
 
          goto common_symbol;
 
@@ -1027,14 +1029,14 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl,
       if (TREE_CHAIN (t) == 0
          && TYPE_MAIN_VARIANT (type) != void_type_node)
        {
-         inform ("a parameter list with an ellipsis can%'t match "
+         inform (input_location, "a parameter list with an ellipsis can%'t match "
                  "an empty parameter name list declaration");
          break;
        }
 
       if (c_type_promotes_to (type) != type)
        {
-         inform ("an argument type that has a default promotion can%'t match "
+         inform (input_location, "an argument type that has a default promotion can%'t match "
                  "an empty parameter name list declaration");
          break;
        }
@@ -1113,16 +1115,16 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
    first in a pair of mismatched declarations, using the diagnostic
    function DIAG.  */
 static void
-locate_old_decl (tree decl, void (*diag)(const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2))
+locate_old_decl (tree decl)
 {
   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
     ;
   else if (DECL_INITIAL (decl))
-    diag (G_("previous definition of %q+D was here"), decl);
+    inform (input_location, "previous definition of %q+D was here", decl);
   else if (C_DECL_IMPLICIT (decl))
-    diag (G_("previous implicit declaration of %q+D was here"), decl);
+    inform (input_location, "previous implicit declaration of %q+D was here", decl);
   else
-    diag (G_("previous declaration of %q+D was here"), decl);
+    inform (input_location, "previous declaration of %q+D was here", decl);
 }
 
 /* Subroutine of duplicate_decls.  Compare NEWDECL to OLDDECL.
@@ -1163,7 +1165,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            && !C_DECL_DECLARED_BUILTIN (olddecl)))
        {
          error ("%q+D redeclared as different kind of symbol", newdecl);
-         locate_old_decl (olddecl, error);
+         locate_old_decl (olddecl);
        }
       else if (TREE_PUBLIC (newdecl))
        warning (0, "built-in function %q+D declared as non-function",
@@ -1179,7 +1181,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   if (TREE_CODE (olddecl) == CONST_DECL)
     {
       error ("redeclaration of enumerator %q+D", newdecl);
-      locate_old_decl (olddecl, error);
+      locate_old_decl (olddecl);
       return false;
     }
 
@@ -1223,11 +1225,11 @@ 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 ("conflicting types for %q+D", newdecl);
+         pedwarned = pedwarn (input_location, 0,
+                              "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;
-         pedwarned = true;
        }
       /* Permit void foo (...) to match an earlier call to foo (...) with
         no declared type (thus, implicitly int).  */
@@ -1236,10 +1238,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
               && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
               && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
        {
-         pedwarn ("conflicting types for %q+D", newdecl);
+         pedwarned = pedwarn (input_location, 0,
+                              "conflicting types for %q+D", newdecl);
          /* Make sure we keep void as the return type.  */
          TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
-         pedwarned = true;
        }
       else
        {
@@ -1248,7 +1250,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          else
            error ("conflicting types for %q+D", newdecl);
          diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
-         locate_old_decl (olddecl, error);
+         locate_old_decl (olddecl);
          return false;
        }
     }
@@ -1258,11 +1260,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
      header.  (Conflicting redeclarations were handled above.)  */
   if (TREE_CODE (newdecl) == TYPE_DECL)
     {
-      if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl))
+      if (DECL_IN_SYSTEM_HEADER (newdecl)
+         || DECL_IN_SYSTEM_HEADER (olddecl)
+         || TREE_NO_WARNING (newdecl)
+         || TREE_NO_WARNING (olddecl))
        return true;  /* Allow OLDDECL to continue in use.  */
 
       error ("redefinition of typedef %q+D", newdecl);
-      locate_old_decl (olddecl, error);
+      locate_old_decl (olddecl);
       return false;
     }
 
@@ -1313,7 +1318,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                  && same_translation_unit_p (newdecl, olddecl))
                {
                  error ("redefinition of %q+D", newdecl);
-                 locate_old_decl (olddecl, error);
+                 locate_old_decl (olddecl);
                  return false;
                }
            }
@@ -1325,7 +1330,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
               && TYPE_ACTUAL_ARG_TYPES (oldtype)
               && !validate_proto_after_old_defn (newdecl, newtype, oldtype))
        {
-         locate_old_decl (olddecl, error);
+         locate_old_decl (olddecl);
          return false;
        }
       /* A non-static declaration (even an "extern") followed by a
@@ -1349,7 +1354,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            {
              error ("static declaration of %q+D follows "
                     "non-static declaration", newdecl);
-             locate_old_decl (olddecl, error);
+             locate_old_decl (olddecl);
            }
          return false;
        }
@@ -1359,14 +1364,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            {
              error ("non-static declaration of %q+D follows "
                     "static declaration", newdecl);
-             locate_old_decl (olddecl, error);
+             locate_old_decl (olddecl);
              return false;
            }
          else if (warn_traditional)
            {
-             warning (OPT_Wtraditional, "non-static declaration of %q+D "
-                      "follows static declaration", newdecl);
-             warned = true;
+             warned |= warning (OPT_Wtraditional, 
+                                "non-static declaration of %q+D "
+                                "follows static declaration", newdecl);
            }
        }
 
@@ -1407,7 +1412,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            error ("non-thread-local declaration of %q+D follows "
                   "thread-local declaration", newdecl);
 
-         locate_old_decl (olddecl, error);
+         locate_old_decl (olddecl);
          return false;
        }
 
@@ -1415,7 +1420,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
        {
          error ("redefinition of %q+D", newdecl);
-         locate_old_decl (olddecl, error);
+         locate_old_decl (olddecl);
          return false;
        }
 
@@ -1436,14 +1441,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                {
                  error ("extern declaration of %q+D follows "
                         "declaration with no linkage", newdecl);
-                 locate_old_decl (olddecl, error);
+                 locate_old_decl (olddecl);
                  return false;
                }
              else if (warn_traditional)
                {
-                 warning (OPT_Wtraditional, "non-static declaration of %q+D "
-                          "follows static declaration", newdecl);
-                 warned = true;
+                 warned |= warning (OPT_Wtraditional, 
+                                    "non-static declaration of %q+D "
+                                    "follows static declaration", newdecl);
                }
            }
          else
@@ -1455,7 +1460,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                error ("static declaration of %q+D follows "
                       "non-static declaration", newdecl);
 
-             locate_old_decl (olddecl, error);
+             locate_old_decl (olddecl);
              return false;
            }
        }
@@ -1472,12 +1477,12 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            {
              error ("declaration of %q+D with no linkage follows "
                     "extern declaration", newdecl);
-             locate_old_decl (olddecl, error);
+             locate_old_decl (olddecl);
            }
          else
            {
              error ("redeclaration of %q+D with no linkage", newdecl);
-             locate_old_decl (olddecl, error);
+             locate_old_decl (olddecl);
            }
 
          return false;
@@ -1490,9 +1495,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
-      warning (0, "redeclaration of %q+D with different visibility "
-              "(old visibility preserved)", newdecl);
-      warned = true;
+      warned |= warning (0, "redeclaration of %q+D with different visibility "
+                        "(old visibility preserved)", newdecl);
     }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -1501,40 +1505,16 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       if (DECL_DECLARED_INLINE_P (newdecl)
          && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warning (OPT_Wattributes, "inline declaration of %qD follows "
-                  "declaration with attribute noinline", newdecl);
-         warned = true;
+         warned |= warning (OPT_Wattributes, 
+                            "inline declaration of %qD follows "
+                            "declaration with attribute noinline", newdecl);
        }
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
        {
-         warning (OPT_Wattributes, "declaration of %q+D with attribute "
-                  "noinline follows inline declaration ", newdecl);
-         warned = true;
-       }
-
-      /* Inline declaration after use or definition.
-        ??? Should we still warn about this now we have unit-at-a-time
-        mode and can get it right?
-        Definitely don't complain if the decls are in different translation
-        units.
-        C99 permits this, so don't warn in that case.  (The function
-        may not be inlined everywhere in function-at-a-time mode, but
-        we still shouldn't warn.)  */
-      if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
-         && same_translation_unit_p (olddecl, newdecl)
-         && flag_gnu89_inline)
-       {
-         if (TREE_USED (olddecl))
-           {
-             warning (0, "%q+D declared inline after being called", olddecl);
-             warned = true;
-           }
-         else if (DECL_INITIAL (olddecl))
-           {
-             warning (0, "%q+D declared inline after its definition", olddecl);
-             warned = true;
-           }
+         warned |= warning (OPT_Wattributes, 
+                            "declaration of %q+D with attribute "
+                            "noinline follows inline declaration ", newdecl);
        }
     }
   else /* PARM_DECL, VAR_DECL */
@@ -1552,7 +1532,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
        {
          error ("redefinition of parameter %q+D", newdecl);
-         locate_old_decl (olddecl, error);
+         locate_old_decl (olddecl);
          return false;
        }
     }
@@ -1578,14 +1558,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       && !(TREE_CODE (newdecl) == VAR_DECL
           && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)))
     {
-      warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D",
-              newdecl);
-      warned = true;
+      warned = warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D",
+                       newdecl);
     }
 
-  /* Report location of previous decl/defn in a consistent manner.  */
+  /* Report location of previous decl/defn.  */
   if (warned || pedwarned)
-    locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
+    locate_old_decl (olddecl);
 
 #undef DECL_EXTERN_INLINE
 
@@ -1676,12 +1655,21 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
   if (TREE_DEPRECATED (newdecl))
     TREE_DEPRECATED (olddecl) = 1;
 
-  /* Keep source location of definition rather than declaration and of
-     prototype rather than non-prototype unless that prototype is
-     built-in.  */
-  if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
-      || (old_is_prototype && !new_is_prototype
-         && !C_DECL_BUILTIN_PROTOTYPE (olddecl)))
+  /* If a decl is in a system header and the other isn't, keep the one on the
+     system header. Otherwise, keep source location of definition rather than
+     declaration and of prototype rather than non-prototype unless that
+     prototype is built-in.  */
+  if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)
+      && DECL_IN_SYSTEM_HEADER (olddecl)
+      && !DECL_IN_SYSTEM_HEADER (newdecl) )
+    DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
+  else if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)
+          && DECL_IN_SYSTEM_HEADER (newdecl)
+          && !DECL_IN_SYSTEM_HEADER (olddecl))
+    DECL_SOURCE_LOCATION (olddecl) = DECL_SOURCE_LOCATION (newdecl);
+  else if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
+          || (old_is_prototype && !new_is_prototype
+              && !C_DECL_BUILTIN_PROTOTYPE (olddecl)))
     DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
 
   /* Merge the initialization information.  */
@@ -1697,12 +1685,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 
   if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
     {
-      /* 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 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
@@ -1793,18 +1775,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
         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.  */
-             && !flag_unit_at_a_time
-             && cgraph_function_possibly_inlined_p (olddecl))
-           (*debug_hooks->outlining_inline_function) (olddecl);
-
-         /* The new defn must not be inline.  */
-         DECL_INLINE (newdecl) = 0;
-         DECL_UNINLINABLE (newdecl) = 1;
-       }
+       /* The new defn must not be inline.  */
+       DECL_UNINLINABLE (newdecl) = 1;
       else
        {
          /* If either decl says `inline', this fn is inline, unless
@@ -1836,6 +1808,17 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
              = C_DECL_BUILTIN_PROTOTYPE (olddecl);
        }
 
+      /* Preserve function specific target and optimization options */
+      if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
+         && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
+       DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
+         = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
+
+      if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
+         && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
+       DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
+         = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
+
       /* Also preserve various other info from the definition.  */
       if (!new_is_definition)
        {
@@ -1843,29 +1826,24 @@ 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) = DECL_ARGUMENTS (olddecl);
 
-         /* Set DECL_INLINE on the declaration if we've got a body
-            from which to instantiate.  */
-         if (DECL_INLINE (olddecl) && !DECL_UNINLINABLE (newdecl))
-           {
-             DECL_INLINE (newdecl) = 1;
-             DECL_ABSTRACT_ORIGIN (newdecl)
-               = DECL_ABSTRACT_ORIGIN (olddecl);
-           }
-       }
-      else
-       {
-         /* If a previous declaration said inline, mark the
-            definition as inlinable.  */
-         if (DECL_DECLARED_INLINE_P (newdecl)
-             && !DECL_UNINLINABLE (newdecl))
-           DECL_INLINE (newdecl) = 1;
+         /* See if we've got a function to instantiate from.  */
+         if (DECL_SAVED_TREE (olddecl))
+           DECL_ABSTRACT_ORIGIN (newdecl)
+             = DECL_ABSTRACT_ORIGIN (olddecl);
        }
     }
 
    extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
 
+   /* Merge the USED information.  */
+   if (TREE_USED (olddecl))
+     TREE_USED (newdecl) = 1;
+   else if (TREE_USED (newdecl))
+     TREE_USED (olddecl) = 1;
+
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
      But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
   {
@@ -1877,6 +1855,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
            sizeof (struct tree_decl_common) - sizeof (struct tree_common));
     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:
@@ -1884,7 +1866,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
       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));
@@ -2338,13 +2319,16 @@ implicit_decl_warning (tree id, tree olddecl)
 {
   if (warn_implicit_function_declaration)
     {
+      bool warned;
+
       if (flag_isoc99)
-       pedwarn (G_("implicit declaration of function %qE"), id);
+       warned = pedwarn (input_location, OPT_Wimplicit_function_declaration,
+                         "implicit declaration of function %qE", id);
       else 
-       warning (OPT_Wimplicit_function_declaration, 
-                G_("implicit declaration of function %qE"), id);
-      if (olddecl)
-       locate_old_decl (olddecl, inform);
+       warned = warning (OPT_Wimplicit_function_declaration, 
+                         G_("implicit declaration of function %qE"), id);
+      if (olddecl && warned)
+       locate_old_decl (olddecl);
     }
 }
 
@@ -2415,7 +2399,7 @@ implicitly_declare (tree functionid)
                {
                  error ("incompatible implicit declaration of function %qD",
                         decl);
-                 locate_old_decl (decl, error);
+                 locate_old_decl (decl);
                }
            }
          b->type = TREE_TYPE (decl);
@@ -2557,7 +2541,7 @@ declare_label (tree name)
   if (b && B_IN_CURRENT_SCOPE (b))
     {
       error ("duplicate label declaration %qE", name);
-      locate_old_decl (b->decl, error);
+      locate_old_decl (b->decl);
 
       /* Just use the previous declaration.  */
       return b->decl;
@@ -2593,7 +2577,7 @@ define_label (location_t location, tree name)
              && C_DECLARED_LABEL_FLAG (label))))
     {
       error ("%Hduplicate label %qD", &location, label);
-      locate_old_decl (label, error);
+      locate_old_decl (label);
       return 0;
     }
   else if (label && DECL_CONTEXT (label) == current_function_decl)
@@ -2850,6 +2834,31 @@ c_builtin_function (tree decl)
 
   return decl;
 }
+
+tree
+c_builtin_function_ext_scope (tree decl)
+{
+  tree type = TREE_TYPE (decl);
+  tree   id = DECL_NAME (decl);
+
+  const char *name = IDENTIFIER_POINTER (id);
+  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
+
+  /* Should never be called on a symbol with a preexisting meaning.  */
+  gcc_assert (!I_SYMBOL_BINDING (id));
+
+  bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false);
+
+  /* Builtins in the implementation namespace are made visible without
+     needing to be explicitly declared.  See push_file_scope.  */
+  if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
+    {
+      TREE_CHAIN (decl) = visible_builtins;
+      visible_builtins = decl;
+    }
+
+  return decl;
+}
 \f
 /* Called when a declaration is seen that contains no names to declare.
    If its type is a reference to a structure, union or enum inherited
@@ -2891,7 +2900,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
              if (warned != 1 && code != ENUMERAL_TYPE)
                /* Empty unnamed enum OK */
                {
-                 pedwarn ("unnamed struct/union that defines no instances");
+                 pedwarn (input_location, 0,
+                          "unnamed struct/union that defines no instances");
                  warned = 1;
                }
            }
@@ -2899,7 +2909,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
                   && declspecs->storage_class != csc_none)
            {
              if (warned != 1)
-               pedwarn ("empty declaration with storage class specifier "
+               pedwarn (input_location, 0,
+                        "empty declaration with storage class specifier "
                         "does not redeclare tag");
              warned = 1;
              pending_xref_error ();
@@ -2910,8 +2921,9 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
                       || declspecs->restrict_p))
            {
              if (warned != 1)
-               pedwarn ("empty declaration with type qualifier "
-                        "does not redeclare tag");
+               pedwarn (input_location, 0,
+                        "empty declaration with type qualifier "
+                         "does not redeclare tag");
              warned = 1;
              pending_xref_error ();
            }
@@ -2931,14 +2943,15 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
        {
          if (warned != 1 && !in_system_header)
            {
-             pedwarn ("useless type name in empty declaration");
+             pedwarn (input_location, 0,
+                      "useless type name in empty declaration");
              warned = 1;
            }
        }
     }
   else if (warned != 1 && !in_system_header && declspecs->typedef_p)
     {
-      pedwarn ("useless type name in empty declaration");
+      pedwarn (input_location, 0, "useless type name in empty declaration");
       warned = 1;
     }
 
@@ -2985,7 +2998,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
   if (warned != 1)
     {
       if (!found_tag)
-       pedwarn ("empty declaration");
+       pedwarn (input_location, 0, "empty declaration");
     }
 }
 \f
@@ -3048,13 +3061,15 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
     }
   declarator->u.array.static_p = static_p;
   declarator->u.array.vla_unspec_p = vla_unspec_p;
-  if (pedantic && !flag_isoc99)
+  if (!flag_isoc99)
     {
       if (static_p || quals != NULL)
-       pedwarn ("ISO C90 does not support %<static%> or type "
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C90 does not support %<static%> or type "
                 "qualifiers in parameter array declarators");
       if (vla_unspec_p)
-       pedwarn ("ISO C90 does not support %<[*]%> array declarators");
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C90 does not support %<[*]%> array declarators");
     }
   if (vla_unspec_p)
     {
@@ -3162,8 +3177,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   if (!decl)
     return 0;
 
-  if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
-      && MAIN_NAME_P (DECL_NAME (decl)))
+  if (TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl)))
     warning (OPT_Wmain, "%q+D is usually a function", decl);
 
   if (initialized)
@@ -3310,7 +3324,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
       && !TREE_READONLY (decl)
       && DECL_DECLARED_INLINE_P (current_function_decl)
       && DECL_EXTERNAL (current_function_decl))
-    pedwarn ("%q+D is static but declared in inline function %qD "
+    pedwarn (input_location, 0,
+            "%q+D is static but declared in inline function %qD "
             "which is not static", decl, current_function_decl);
 
   /* Add this decl to the current scope.
@@ -3600,10 +3615,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
        }
     }
 
-  /* If this was marked 'used', be sure it will be output.  */
-  if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
-    mark_decl_referenced (decl);
-
   if (TREE_CODE (decl) == TYPE_DECL)
     {
       if (!DECL_FILE_SCOPE_P (decl)
@@ -3630,7 +3641,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
          tree cleanup;
 
          /* Build "cleanup(&decl)" for the destructor.  */
-         cleanup = build_unary_op (ADDR_EXPR, decl, 0);
+         cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
          cleanup = build_tree_list (NULL_TREE, cleanup);
          cleanup = build_function_call (cleanup_decl, cleanup);
 
@@ -3688,7 +3699,8 @@ mark_forward_parm_decls (void)
 
   if (pedantic && !current_scope->warned_forward_parm_decls)
     {
-      pedwarn ("ISO C forbids forward parameter declarations");
+      pedwarn (input_location, OPT_pedantic,
+              "ISO C forbids forward parameter declarations");
       current_scope->warned_forward_parm_decls = true;
     }
 
@@ -3835,12 +3847,12 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
     }
 
   type_mv = TYPE_MAIN_VARIANT (*type);
-  if (pedantic
-      && !in_system_header
+  if (!in_system_header
       && type_mv != integer_type_node
       && type_mv != unsigned_type_node
       && type_mv != boolean_type_node)
-    pedwarn ("type of bit-field %qs is a GCC extension", name);
+    pedwarn (input_location, OPT_pedantic,
+            "type of bit-field %qs is a GCC extension", name);
 
   max_width = TYPE_PRECISION (*type);
 
@@ -3857,8 +3869,8 @@ 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_max, TYPE_UNSIGNED (*type)))
+         || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
+         || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
        warning (0, "%qs is narrower than values of its type", name);
     }
 }
@@ -3870,28 +3882,27 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
 static void
 warn_variable_length_array (const char *name, tree size)
 {
-  int ped = !flag_isoc99 && pedantic && warn_vla != 0;
   int const_size = TREE_CONSTANT (size);
 
-  if (ped)
+  if (!flag_isoc99 && pedantic && warn_vla != 0)
     {
       if (const_size)
        {
          if (name)
-           pedwarn ("ISO C90 forbids array %qs whose size "
+           pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array %qs whose size "
                     "can%'t be evaluated",
                     name);
          else
-           pedwarn ("ISO C90 forbids array whose size "
+           pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array whose size "
                     "can%'t be evaluated");
        }
       else
        {
          if (name) 
-           pedwarn ("ISO C90 forbids variable length array %qs",
+           pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array %qs",
                     name);
          else
-           pedwarn ("ISO C90 forbids variable length array");
+           pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array");
        }
     }
   else if (warn_vla > 0)
@@ -4052,8 +4063,9 @@ grokdeclarator (const struct c_declarator *declarator,
       if ((warn_implicit_int || warn_return_type || flag_isoc99)
          && funcdef_flag)
        warn_about_return_type = 1;
-      else if (warn_implicit_int || flag_isoc99)
-       pedwarn_c99 ("type defaults to %<int%> in declaration of %qs", name);
+      else 
+       pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, 
+                    "type defaults to %<int%> in declaration of %qs", name);
     }
 
   /* Adjust the type if a bit-field is being declared,
@@ -4061,7 +4073,7 @@ grokdeclarator (const struct c_declarator *declarator,
      "signed".  */
   if (bitfield && !flag_signed_bitfields && !declspecs->explicit_signed_p
       && TREE_CODE (type) == INTEGER_TYPE)
-    type = c_common_unsigned_type (type);
+    type = unsigned_type_for (type);
 
   /* Figure out the type qualifiers for the declaration.  There are
      two ways a declaration can become qualified.  One is something
@@ -4081,11 +4093,11 @@ grokdeclarator (const struct c_declarator *declarator,
   if (pedantic && !flag_isoc99)
     {
       if (constp > 1)
-       pedwarn ("duplicate %<const%>");
+       pedwarn (input_location, OPT_pedantic, "duplicate %<const%>");
       if (restrictp > 1)
-       pedwarn ("duplicate %<restrict%>");
+       pedwarn (input_location, OPT_pedantic, "duplicate %<restrict%>");
       if (volatilep > 1)
-       pedwarn ("duplicate %<volatile%>");
+       pedwarn (input_location, OPT_pedantic, "duplicate %<volatile%>");
     }
   if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
     type = TYPE_MAIN_VARIANT (type);
@@ -4102,9 +4114,10 @@ grokdeclarator (const struct c_declarator *declarator,
          || storage_class == csc_register
          || storage_class == csc_typedef))
     {
-      if (storage_class == csc_auto
-         && (pedantic || current_scope == file_scope))
-       pedwarn ("function definition declared %<auto%>");
+      if (storage_class == csc_auto)
+       pedwarn (input_location, 
+                (current_scope == file_scope) ? 0 : OPT_pedantic, 
+                "function definition declared %<auto%>");
       if (storage_class == csc_register)
        error ("function definition declared %<register%>");
       if (storage_class == csc_typedef)
@@ -4160,7 +4173,8 @@ grokdeclarator (const struct c_declarator *declarator,
       if (storage_class == csc_auto)
        error ("file-scope declaration of %qs specifies %<auto%>", name);
       if (pedantic && storage_class == csc_register)
-       pedwarn ("file-scope declaration of %qs specifies %<register%>", name);
+       pedwarn (input_location, OPT_pedantic,
+                "file-scope declaration of %qs specifies %<register%>", name);
     }
   else
     {
@@ -4273,7 +4287,8 @@ grokdeclarator (const struct c_declarator *declarator,
              }
 
            if (pedantic && !in_system_header && flexible_array_type_p (type))
-             pedwarn ("invalid use of structure with flexible array member");
+             pedwarn (input_location, OPT_pedantic,
+                      "invalid use of structure with flexible array member");
 
            if (size == error_mark_node)
              type = error_mark_node;
@@ -4298,7 +4313,8 @@ grokdeclarator (const struct c_declarator *declarator,
                  }
 
                if (pedantic && integer_zerop (size))
-                 pedwarn ("ISO C forbids zero-size array %qs", name);
+                 pedwarn (input_location, OPT_pedantic,
+                          "ISO C forbids zero-size array %qs", name);
 
                if (TREE_CODE (size) == INTEGER_CST)
                  {
@@ -4370,7 +4386,8 @@ grokdeclarator (const struct c_declarator *declarator,
            else if (decl_context == FIELD)
              {
                if (pedantic && !flag_isoc99 && !in_system_header)
-                 pedwarn ("ISO C90 does not support flexible array members");
+                 pedwarn (input_location, OPT_pedantic,
+                          "ISO C90 does not support flexible array members");
 
                /* ISO C99 Flexible array members are effectively
                   identical to GCC's zero-length array extension.  */
@@ -4515,7 +4532,8 @@ grokdeclarator (const struct c_declarator *declarator,
                   function definitions in ISO C; GCC used to used
                   them for noreturn functions.  */
                if (VOID_TYPE_P (type) && really_funcdef)
-                 pedwarn ("function definition has qualified void return type");
+                 pedwarn (input_location, 0,
+                          "function definition has qualified void return type");
                else
                  warning (OPT_Wignored_qualifiers,
                           "type qualifiers ignored on function return type");
@@ -4547,7 +4565,8 @@ grokdeclarator (const struct c_declarator *declarator,
 
            if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
                && type_quals)
-             pedwarn ("ISO C forbids qualified function types");
+             pedwarn (input_location, OPT_pedantic,
+                      "ISO C forbids qualified function types");
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
            size_varies = 0;
@@ -4628,7 +4647,8 @@ grokdeclarator (const struct c_declarator *declarator,
       tree decl;
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
-       pedwarn ("ISO C forbids qualified function types");
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C forbids qualified function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       decl = build_decl (TYPE_DECL, declarator->u.id, type);
@@ -4636,7 +4656,7 @@ grokdeclarator (const struct c_declarator *declarator,
       if (declspecs->explicit_signed_p)
        C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
       if (declspecs->inline_p)
-       pedwarn ("typedef %q+D declared %<inline%>", decl);
+       pedwarn (input_location, 0,"typedef %q+D declared %<inline%>", decl);
       return decl;
     }
 
@@ -4651,7 +4671,8 @@ grokdeclarator (const struct c_declarator *declarator,
                  && !declspecs->inline_p);
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
-       pedwarn ("ISO C forbids const or volatile function types");
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C forbids const or volatile function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       return type;
@@ -4661,7 +4682,8 @@ grokdeclarator (const struct c_declarator *declarator,
       && 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");
+      pedwarn (input_location, OPT_pedantic, 
+              "a member of a structure or union cannot have a variably modified type");
     }
 
   /* Aside from typedefs and type names (handle above),
@@ -4714,8 +4736,9 @@ grokdeclarator (const struct c_declarator *declarator,
          }
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
-           if (pedantic && type_quals)
-             pedwarn ("ISO C forbids qualified function types");
+           if (type_quals)
+             pedwarn (input_location, OPT_pedantic,
+                      "ISO C forbids qualified function types");
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
            type = build_pointer_type (type);
@@ -4741,7 +4764,7 @@ grokdeclarator (const struct c_declarator *declarator,
 
        DECL_ARG_TYPE (decl) = promoted_type;
        if (declspecs->inline_p)
-         pedwarn ("parameter %q+D declared %<inline%>", decl);
+         pedwarn (input_location, 0, "parameter %q+D declared %<inline%>", decl);
       }
     else if (decl_context == FIELD)
       {
@@ -4787,10 +4810,7 @@ grokdeclarator (const struct c_declarator *declarator,
               GCC allows 'auto', perhaps with 'inline', to support
               nested functions.  */
            if (storage_class == csc_auto)
-             {
-               if (pedantic)
-                 pedwarn ("invalid storage class for function %qs", name);
-             }
+               pedwarn (input_location, OPT_pedantic, "invalid storage class for function %qs", name);
            else if (storage_class == csc_static)
              {
                error ("invalid storage class for function %qs", name);
@@ -4806,7 +4826,8 @@ grokdeclarator (const struct c_declarator *declarator,
        decl = build_decl_attribute_variant (decl, decl_attr);
 
        if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
-         pedwarn ("ISO C forbids qualified function types");
+         pedwarn (input_location, OPT_pedantic,
+                  "ISO C forbids qualified function types");
 
        /* GNU C interprets a volatile-qualified function type to indicate
           that the function does not return.  */
@@ -4848,25 +4869,11 @@ grokdeclarator (const struct c_declarator *declarator,
        if (flag_hosted && MAIN_NAME_P (declarator->u.id))
          {
            if (declspecs->inline_p)
-             pedwarn ("cannot inline function %<main%>");
+             pedwarn (input_location, 0, "cannot inline function %<main%>");
          }
        else if (declspecs->inline_p)
-         {
-           /* Record that the function is declared `inline'.  */
-           DECL_DECLARED_INLINE_P (decl) = 1;
-
-           /* Do not mark bare declarations as DECL_INLINE.  Doing so
-              in the presence of multiple declarations can result in
-              the abstract origin pointing between the declarations,
-              which will confuse dwarf2out.  */
-           if (initialized)
-             DECL_INLINE (decl) = 1;
-         }
-       /* If -finline-functions, assume it can be inlined.  This does
-          two things: let the function be deferred until it is actually
-          needed, and let dwarf2 know that the function is inlinable.  */
-       else if (flag_inline_trees == 2 && initialized)
-         DECL_INLINE (decl) = 1;
+         /* Record that the function is declared `inline'.  */
+         DECL_DECLARED_INLINE_P (decl) = 1;
       }
     else
       {
@@ -4901,7 +4908,7 @@ grokdeclarator (const struct c_declarator *declarator,
          C_DECL_VARIABLE_SIZE (decl) = 1;
 
        if (declspecs->inline_p)
-         pedwarn ("variable %q+D declared %<inline%>", decl);
+         pedwarn (input_location, 0, "variable %q+D declared %<inline%>", decl);
 
        /* At file scope, an initialized extern declaration may follow
           a static declaration.  In that case, DECL_EXTERNAL will be
@@ -5009,7 +5016,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
   else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
     {
       if (!funcdef_flag)
-       pedwarn ("parameter names (without types) in function declaration");
+       pedwarn (input_location, 0, "parameter names (without types) in function declaration");
 
       arg_info->parms = arg_info->types;
       arg_info->types = 0;
@@ -5372,12 +5379,15 @@ start_struct (enum tree_code code, tree name)
    WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
    DECL_ATTRS is as for grokdeclarator.
 
+   LOC is the location of the structure component.
+
    This is done during the parsing of the struct declaration.
    The FIELD_DECL nodes are chained together and the lot of them
    are ultimately passed to `build_struct' to make the RECORD_TYPE node.  */
 
 tree
-grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs,
+grokfield (location_t loc,
+          struct c_declarator *declarator, struct c_declspecs *declspecs,
           tree width, tree *decl_attrs)
 {
   tree value;
@@ -5423,11 +5433,10 @@ grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs,
        }
       if (!ok)
        {
-         pedwarn ("declaration does not declare anything");
+         pedwarn (loc, 0, "declaration does not declare anything");
          return NULL_TREE;
        }
-      if (pedantic)
-       pedwarn ("ISO C doesn%'t support unnamed structs/unions");
+      pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions");
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -5526,16 +5535,16 @@ finish_struct (tree t, tree fieldlist, tree attributes)
          if (TREE_CODE (t) == UNION_TYPE)
            {
              if (fieldlist)
-               pedwarn ("union has no named members");
+               pedwarn (input_location, OPT_pedantic, "union has no named members");
              else
-               pedwarn ("union has no members");
+               pedwarn (input_location, OPT_pedantic, "union has no members");
            }
          else
            {
              if (fieldlist)
-               pedwarn ("struct has no named members");
+               pedwarn (input_location, OPT_pedantic, "struct has no named members");
              else
-               pedwarn ("struct has no members");
+               pedwarn (input_location, OPT_pedantic, "struct has no members");
            }
        }
     }
@@ -5614,7 +5623,8 @@ finish_struct (tree t, tree fieldlist, tree attributes)
 
       if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
          && flexible_array_type_p (TREE_TYPE (x)))
-       pedwarn ("%Jinvalid use of structure with flexible array member", x);
+       pedwarn (input_location, OPT_pedantic, 
+                "%Jinvalid use of structure with flexible array member", x);
 
       if (DECL_NAME (x))
        saw_named_field = 1;
@@ -5856,8 +5866,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
      that normally we only go as narrow as int - and signed iff any of
      the values are negative.  */
   unsign = (tree_int_cst_sgn (minnode) >= 0);
-  precision = MAX (min_precision (minnode, unsign),
-                  min_precision (maxnode, unsign));
+  precision = MAX (tree_int_cst_min_precision (minnode, unsign),
+                  tree_int_cst_min_precision (maxnode, unsign));
 
   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
@@ -5906,16 +5916,16 @@ finish_enum (tree enumtype, tree values, tree attributes)
 
          /* The ISO C Standard mandates enumerators to have type int,
             even though the underlying type of an enum type is
-            unspecified.  Here we convert any enumerators that fit in
-            an int to type int, to avoid promotions to unsigned types
-            when comparing integers with enumerators that fit in the
-            int range.  When -pedantic is given, build_enumerator()
-            would have already taken care of those that don't fit.  */
-         if (int_fits_type_p (ini, integer_type_node))
-           tem = integer_type_node;
-         else
-           tem = enumtype;
-         ini = convert (tem, ini);
+            unspecified.  However, GCC allows enumerators of any
+            integer type as an extensions.  build_enumerator()
+            converts any enumerators that fit in an int to type int,
+            to avoid promotions to unsigned types when comparing
+            integers with enumerators that fit in the int range.
+            When -pedantic is given, build_enumerator() would have
+            already warned about those that don't fit. Here we
+            convert the rest to the enumerator type. */
+         if (TREE_TYPE (ini) != integer_type_node)
+           ini = convert (enumtype, ini);
 
          DECL_INITIAL (enu) = ini;
          TREE_PURPOSE (pair) = DECL_NAME (enu);
@@ -5962,7 +5972,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
    Assignment of sequential values by default is handled here.  */
 
 tree
-build_enumerator (struct c_enum_contents *the_enum, tree name, tree value)
+build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
+                 location_t value_loc)
 {
   tree decl, type;
 
@@ -5996,18 +6007,31 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value)
       if (the_enum->enum_overflow)
        error ("overflow in enumeration values");
     }
-
-  if (pedantic && !int_fits_type_p (value, integer_type_node))
-    {
-      pedwarn ("ISO C restricts enumerator values to range of %<int%>");
-      /* XXX This causes -pedantic to change the meaning of the program.
-        Remove?  -zw 2004-03-15  */
-      value = convert (integer_type_node, value);
-    }
+  /* Even though the underlying type of an enum is unspecified, the
+     type of enumeration constants is explicitly defined as int
+     (6.4.4.3/2 in the C99 Standard).  GCC allows any integer type as
+     an extension.  */
+  else if (!int_fits_type_p (value, integer_type_node))
+    pedwarn (value_loc, OPT_pedantic, 
+            "ISO C restricts enumerator values to range of %<int%>");
+
+  /* The ISO C Standard mandates enumerators to have type int, even
+     though the underlying type of an enum type is unspecified.
+     However, GCC allows enumerators of any integer type as an
+     extensions.  Here we convert any enumerators that fit in an int
+     to type int, to avoid promotions to unsigned types when comparing
+     integers with enumerators that fit in the int range.  When
+     -pedantic is given, we would have already warned about those that
+     don't fit. We have to do this here rather than in finish_enum
+     because this value may be used to define more enumerators.  */
+  if (int_fits_type_p (value, integer_type_node))
+    value = convert (integer_type_node, value);
 
   /* Set basis for default for next value.  */
-  the_enum->enum_next_value = build_binary_op (PLUS_EXPR, value,
-                                              integer_one_node, 0);
+  the_enum->enum_next_value
+    = build_binary_op
+         (EXPR_HAS_LOCATION (value) ? EXPR_LOCATION (value) : input_location,
+        PLUS_EXPR, value, integer_one_node, 0);
   the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value);
 
   /* Now create a declaration for the enum value name.  */
@@ -6115,7 +6139,9 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
     }
 
   if (warn_about_return_type)
-    pedwarn_c99 ("return type defaults to %<int%>");
+    pedwarn_c99 (input_location, flag_isoc99 ? 0 
+                : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
+                "return type defaults to %<int%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
@@ -6232,16 +6258,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
     maybe_apply_pragma_weak (decl1);
 
   /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
-  if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
+  if (warn_main && MAIN_NAME_P (DECL_NAME (decl1)))
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
          != integer_type_node)
-       pedwarn ("return type of %q+D is not %<int%>", decl1);
+       pedwarn (input_location, OPT_Wmain, "return type of %q+D is not %<int%>", decl1);
 
-      check_main_parameter_types(decl1);
+      check_main_parameter_types (decl1);
 
       if (!TREE_PUBLIC (decl1))
-       pedwarn ("%q+D is normally a non-static function", decl1);
+       pedwarn (input_location, OPT_Wmain, "%q+D is normally a non-static function", decl1);
     }
 
   /* Record the decl so that the function name is defined.
@@ -6389,7 +6415,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
          warn_if_shadowing (decl);
 
          if (flag_isoc99)
-           pedwarn ("type of %q+D defaults to %<int%>", decl);
+           pedwarn (input_location, 0, "type of %q+D defaults to %<int%>", decl);
          else 
            warning (OPT_Wmissing_parameter_type, "type of %q+D defaults to %<int%>", decl);
        }
@@ -6500,22 +6526,19 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
                      < TYPE_PRECISION (integer_type_node))
                    DECL_ARG_TYPE (parm) = integer_type_node;
 
-                 if (pedantic)
+                 /* ??? Is it possible to get here with a
+                    built-in prototype or will it always have
+                    been diagnosed as conflicting with an
+                    old-style definition and discarded?  */
+                 if (current_function_prototype_built_in)
+                   warning (OPT_pedantic, "promoted argument %qD "
+                            "doesn%'t match built-in prototype", parm);
+                 else
                    {
-                     /* ??? Is it possible to get here with a
-                        built-in prototype or will it always have
-                        been diagnosed as conflicting with an
-                        old-style definition and discarded?  */
-                     if (current_function_prototype_built_in)
-                       warning (0, "promoted argument %qD "
-                                "doesn%'t match built-in prototype", parm);
-                     else
-                       {
-                         pedwarn ("promoted argument %qD "
-                                  "doesn%'t match prototype", parm);
-                         pedwarn ("%Hprototype declaration",
-                                  &current_function_prototype_locus);
-                       }
+                     pedwarn (input_location, OPT_pedantic, "promoted argument %qD "
+                              "doesn%'t match prototype", parm);
+                     pedwarn (current_function_prototype_locus, OPT_pedantic,
+                              "prototype declaration");
                    }
                }
              else
@@ -6650,9 +6673,10 @@ static void
 c_gimple_diagnostics_recursively (tree fndecl)
 {
   struct cgraph_node *cgn;
+  gimple_seq body = gimple_body (fndecl);
 
   /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-  c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+  c_warn_unused_result (body);
 
   /* Notice when OpenMP structured block constraints are violated.  */
   if (flag_openmp)
@@ -6699,30 +6723,18 @@ finish_function (void)
   if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
     DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
 
-  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
+  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted
+      && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
+      == integer_type_node && flag_isoc99)
     {
-      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
-         != integer_type_node)
-       {
-         /* 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 ("return type of %q+D is not %<int%>", fndecl);
-       }
-      else
-       {
-         if (flag_isoc99)
-           {
-             tree stmt = c_finish_return (integer_zero_node);
-             /* Hack.  We don't want the middle-end to warn that this return
-                is unreachable, so we mark its location as special.  Using
-                UNKNOWN_LOCATION has the problem that it gets clobbered in
-                annotate_one_with_locus.  A cleaner solution might be to
-                ensure ! should_carry_locus_p (stmt), but that needs a flag.
-             */
-             SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
-           }
-       }
+      tree stmt = c_finish_return (integer_zero_node);
+      /* Hack.  We don't want the middle-end to warn that this return
+        is unreachable, so we mark its location as special.  Using
+        UNKNOWN_LOCATION has the problem that it gets clobbered in
+        annotate_one_with_locus.  A cleaner solution might be to
+        ensure ! should_carry_locus_p (stmt), but that needs a flag.
+      */
+      SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
     }
 
   /* Tie off the statement tree for this function.  */
@@ -6740,9 +6752,9 @@ finish_function (void)
       && !MAIN_NAME_P (DECL_NAME (fndecl))
       /* Or if they didn't actually specify a return type.  */
       && !C_FUNCTION_IMPLICIT_INT (fndecl)
-      /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
-        inline function, as we might never be compiled separately.  */
-      && DECL_INLINE (fndecl))
+      /* Normally, with -Wreturn-type, flow will complain, but we might
+         optimize out static functions.  */
+      && !TREE_PUBLIC (fndecl))
     {
       warning (OPT_Wreturn_type,
               "no return statement in function returning non-void");
@@ -6812,13 +6824,19 @@ check_for_loop_decls (void)
   tree one_decl = NULL_TREE;
   int n_decls = 0;
 
-
   if (!flag_isoc99)
     {
+      static bool hint = true;
       /* If we get here, declarations have been used in a for loop without
         the C99 for loop scope.  This doesn't make much sense, so don't
         allow it.  */
-      error ("%<for%> loop initial declaration used outside C99 mode");
+      error ("%<for%> loop initial declarations are only allowed in C99 mode");
+      if (hint)
+       {
+         inform (input_location, 
+                 "use option -std=c99 or -std=gnu99 to compile your code");
+         hint = false;
+       }
       return NULL_TREE;
     }
   /* C99 subclause 6.8.5 paragraph 3:
@@ -6963,15 +6981,6 @@ current_stmt_tree (void)
   return &c_stmt_tree;
 }
 
-/* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
-   C.  */
-
-int
-anon_aggr_type_p (const_tree ARG_UNUSED (node))
-{
-  return 0;
-}
-
 /* Return the global value of T as a symbol.  */
 
 tree
@@ -7158,8 +7167,8 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
     default:
       gcc_unreachable ();
     }
-  if (dupe && pedantic && !flag_isoc99)
-    pedwarn ("duplicate %qE", qual);
+  if (dupe && !flag_isoc99)
+    pedwarn (input_location, OPT_pedantic, "duplicate %qE", qual);
   return specs;
 }
 
@@ -7177,7 +7186,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
     specs->deprecated_p = true;
 
   /* Handle type specifier keywords.  */
-  if (TREE_CODE (type) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (type))
+  if (TREE_CODE (type) == IDENTIFIER_NODE
+      && C_IS_RESERVED_WORD (type)
+      && C_RID_CODE (type) != RID_CXX_COMPAT_WARN)
     {
       enum rid i = C_RID_CODE (type);
       if (specs->type)
@@ -7205,9 +7216,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
                             "declaration specifiers");
                      break;
                    }
-                 if (pedantic && !flag_isoc99 && !in_system_header
-                     && warn_long_long)
-                   pedwarn ("ISO C90 does not support %<long long%>");
+                 if (pedantic && !flag_isoc99 && !in_system_header)
+                   pedwarn (input_location, OPT_Wlong_long, "ISO C90 does not support %<long long%>");
                  specs->long_long_p = 1;
                  break;
                }
@@ -7330,8 +7340,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              break;
            case RID_COMPLEX:
              dupe = specs->complex_p;
-             if (pedantic && !flag_isoc99 && !in_system_header)
-               pedwarn ("ISO C90 does not support complex types");
+             if (!flag_isoc99 && !in_system_header)
+               pedwarn (input_location, OPT_pedantic, "ISO C90 does not support complex types");
              if (specs->typespec_word == cts_void)
                error ("both %<complex%> and %<void%> in "
                       "declaration specifiers");
@@ -7361,8 +7371,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              break;
            case RID_SAT:
              dupe = specs->saturating_p;
-             if (pedantic)
-               pedwarn ("ISO C does not support saturating types");
+             pedwarn (input_location, OPT_pedantic, "ISO C does not support saturating types");
              if (specs->typespec_word == cts_void)
                error ("both %<_Sat%> and %<void%> in "
                       "declaration specifiers");
@@ -7559,8 +7568,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              }
              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");
+             pedwarn (input_location, OPT_pedantic, 
+                      "ISO C does not support decimal floating point");
              return specs;
            case RID_FRACT:
            case RID_ACCUM:
@@ -7580,8 +7589,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              }
              if (!targetm.fixed_point_supported_p ())
                error ("fixed-point types not supported for this target");
-             if (pedantic)
-               pedwarn ("ISO C does not support fixed-point types");
+             pedwarn (input_location, OPT_pedantic, 
+                      "ISO C does not support fixed-point types");
              return specs;
            default:
              /* ObjC reserved word "id", handled below.  */
@@ -7767,9 +7776,9 @@ finish_declspecs (struct c_declspecs *specs)
       else if (specs->complex_p)
        {
          specs->typespec_word = cts_double;
-         if (pedantic)
-           pedwarn ("ISO C does not support plain %<complex%> meaning "
-                    "%<double complex%>");
+         pedwarn (input_location, OPT_pedantic, 
+                  "ISO C does not support plain %<complex%> meaning "
+                  "%<double complex%>");
        }
       else
        {
@@ -7812,8 +7821,8 @@ finish_declspecs (struct c_declspecs *specs)
        specs->type = char_type_node;
       if (specs->complex_p)
        {
-         if (pedantic)
-           pedwarn ("ISO C does not support complex integer types");
+         pedwarn (input_location, OPT_pedantic, 
+                  "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
       break;
@@ -7838,8 +7847,8 @@ finish_declspecs (struct c_declspecs *specs)
                       : integer_type_node);
       if (specs->complex_p)
        {
-         if (pedantic)
-           pedwarn ("ISO C does not support complex integer types");
+         pedwarn (input_location, OPT_pedantic, 
+                  "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
       break;
@@ -7989,7 +7998,7 @@ c_write_global_declarations_1 (tree globals)
          && !TREE_PUBLIC (decl)
          && C_DECL_USED (decl))
        {
-         pedwarn ("%q+F used but never defined", decl);
+         pedwarn (input_location, 0, "%q+F used but never defined", decl);
          TREE_NO_WARNING (decl) = 1;
        }