OSDN Git Service

PR c/21342
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 5ef46b0..0ca4500 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -29,6 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "input.h"
 #include "tm.h"
 #include "intl.h"
 #include "tree.h"
@@ -97,6 +98,14 @@ static int enum_overflow;
 
 static location_t current_function_prototype_locus;
 
+/* Whether this prototype was built-in.  */
+
+static bool current_function_prototype_built_in;
+
+/* The argument type information of this prototype.  */
+
+static tree current_function_prototype_arg_types;
+
 /* The argument information structure for the function currently being
    defined.  */
 
@@ -148,6 +157,11 @@ static int warn_about_return_type;
 
 static int current_extern_inline;
 
+/* Nonzero when the current toplevel function contains a declaration
+   of a nested function which is never defined.  */
+
+static bool undef_nested_function;
+
 /* True means global_bindings_p should return false even if the scope stack
    says we are in file scope.  */
 bool c_override_global_bindings_to_false;
@@ -205,17 +219,17 @@ struct c_binding GTY((chain_next ("%h.prev")))
 #define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
 
 #define I_SYMBOL_BINDING(node) \
-  (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->symbol_binding)
+  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->symbol_binding)
 #define I_SYMBOL_DECL(node) \
  (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
 
 #define I_TAG_BINDING(node) \
-  (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->tag_binding)
+  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->tag_binding)
 #define I_TAG_DECL(node) \
  (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
 
 #define I_LABEL_BINDING(node) \
-  (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->label_binding)
+  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->label_binding)
 #define I_LABEL_DECL(node) \
  (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
 
@@ -239,7 +253,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 *)TREE_CHAIN (&%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)")))
@@ -518,12 +532,12 @@ c_finish_incomplete_decl (tree decl)
       tree type = TREE_TYPE (decl);
       if (type != error_mark_node
          && TREE_CODE (type) == ARRAY_TYPE
-         && ! DECL_EXTERNAL (decl)
+         && !DECL_EXTERNAL (decl)
          && TYPE_DOMAIN (type) == 0)
        {
-         warning ("%Jarray %qD assumed to have one element", decl, decl);
+         warning (0, "%Jarray %qD assumed to have one element", decl, decl);
 
-         complete_array_type (type, NULL_TREE, 1);
+         complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
 
          layout_decl (decl, 0);
        }
@@ -634,7 +648,7 @@ push_scope (void)
       if (current_scope && scope->depth == 0)
        {
          scope->depth--;
-         sorry ("GCC supports only %u nested scopes\n", scope->depth);
+         sorry ("GCC supports only %u nested scopes", scope->depth);
        }
 
       current_scope        = scope;
@@ -667,6 +681,8 @@ pop_scope (void)
   bool functionbody = scope->function_body;
   bool keep = functionbody || scope->keep || scope->bindings;
 
+  c_end_vm_scope (scope->depth);
+
   /* If appropriate, create a BLOCK to record the decls for the life
      of this function.  */
   block = 0;
@@ -724,9 +740,9 @@ pop_scope (void)
          else if (!TREE_USED (p) && warn_unused_label)
            {
              if (DECL_INITIAL (p))
-               warning ("%Jlabel %qD defined but not used", p, p);
+               warning (0, "%Jlabel %qD defined but not used", p, p);
              else
-               warning ("%Jlabel %qD declared but not defined", p, p);
+               warning (0, "%Jlabel %qD declared but not defined", p, p);
            }
          /* Labels go in BLOCK_VARS.  */
          TREE_CHAIN (p) = BLOCK_VARS (block);
@@ -752,12 +768,18 @@ pop_scope (void)
        case FUNCTION_DECL:
          /* Propagate TREE_ADDRESSABLE from nested functions to their
             containing functions.  */
-         if (! TREE_ASM_WRITTEN (p)
+         if (!TREE_ASM_WRITTEN (p)
              && DECL_INITIAL (p) != 0
              && TREE_ADDRESSABLE (p)
              && DECL_ABSTRACT_ORIGIN (p) != 0
              && DECL_ABSTRACT_ORIGIN (p) != p)
            TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
+         if (!DECL_EXTERNAL (p)
+             && DECL_INITIAL (p) == 0)
+           {
+             error ("%Jnested function %qD declared but never defined", p, p);
+             undef_nested_function = true;
+           }
          goto common_symbol;
 
        case VAR_DECL:
@@ -767,11 +789,9 @@ pop_scope (void)
              && !DECL_IN_SYSTEM_HEADER (p)
              && DECL_NAME (p)
              && !DECL_ARTIFICIAL (p)
-             && (scope != file_scope
-                 || (TREE_STATIC (p) && !TREE_PUBLIC (p)
-                     && !TREE_THIS_VOLATILE (p)))
-             && scope != external_scope)
-           warning ("%Junused variable %qD", p, p);
+             && scope != file_scope
+             && scope != external_scope) 
+           warning (0, "%Junused variable %qD", p, p);
 
          if (b->inner_comp)
            {
@@ -898,6 +918,8 @@ pop_file_scope (void)
   /* Pop off the file scope and close this translation unit.  */
   pop_scope ();
   file_scope = 0;
+
+  maybe_apply_pending_pragma_weaks ();
   cgraph_finalize_compilation_unit ();
 }
 
@@ -965,10 +987,10 @@ match_builtin_function_types (tree newtype, tree oldtype)
 
   while (oldargs || newargs)
     {
-      if (! oldargs
-         || ! newargs
-         || ! TREE_VALUE (oldargs)
-         || ! TREE_VALUE (newargs)
+      if (!oldargs
+         || !newargs
+         || !TREE_VALUE (oldargs)
+         || !TREE_VALUE (newargs)
          || TYPE_MODE (TREE_VALUE (oldargs))
             != TYPE_MODE (TREE_VALUE (newargs)))
        return 0;
@@ -1007,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 ("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 ("an argument type that has a default promotion can%'t match "
                  "an empty parameter name list declaration");
          break;
        }
@@ -1031,8 +1053,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
   tree newargs, oldargs;
   int i;
 
-  /* ??? Elsewhere TYPE_MAIN_VARIANT is not used in this context.  */
-#define END_OF_ARGLIST(t) (TYPE_MAIN_VARIANT (t) == void_type_node)
+#define END_OF_ARGLIST(t) ((t) == void_type_node)
 
   oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype);
   newargs = TYPE_ARG_TYPES (newtype);
@@ -1040,8 +1061,8 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
 
   for (;;)
     {
-      tree oldargtype = TREE_VALUE (oldargs);
-      tree newargtype = TREE_VALUE (newargs);
+      tree oldargtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs));
+      tree newargtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs));
 
       if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype))
        break;
@@ -1063,9 +1084,10 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
 
       /* Type for passing arg must be consistent with that declared
         for the arg.  */
-      else if (! comptypes (oldargtype, newargtype))
+      else if (!comptypes (oldargtype, newargtype))
        {
-         error ("%Jprototype for %qD declares arg %d with incompatible type",
+         error ("%Jprototype for %qD declares argument %d"
+                " with incompatible type",
                 newdecl, newdecl, i);
          return false;
        }
@@ -1077,7 +1099,7 @@ 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 ("%Jprototype for %qD follows non-prototype definition",
+  warning (0, "%Jprototype for %qD follows non-prototype definition",
           newdecl, newdecl);
   return true;
 #undef END_OF_ARGLIST
@@ -1114,6 +1136,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   tree newtype, oldtype;
   bool pedwarned = false;
   bool warned = false;
+  bool retval = true;
 
   /* If we have error_mark_node for either decl or type, just discard
      the previous decl - we're in an error cascade already.  */
@@ -1137,10 +1160,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          locate_old_decl (olddecl, error);
        }
       else if (TREE_PUBLIC (newdecl))
-       warning ("%Jbuilt-in function %qD declared as non-function",
+       warning (0, "%Jbuilt-in function %qD declared as non-function",
                 newdecl, newdecl);
       else if (warn_shadow)
-       warning ("%Jdeclaration of %qD shadows a built-in function",
+       warning (0, "%Jdeclaration of %qD shadows a built-in function",
                 newdecl, newdecl);
       return false;
     }
@@ -1170,7 +1193,7 @@ 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 ("%Jconflicting types for built-in function %qD",
+             warning (0, "%Jconflicting types for built-in function %qD",
                       newdecl, newdecl);
              return false;
            }
@@ -1192,7 +1215,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl)
               && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node
               && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
-              && C_FUNCTION_IMPLICIT_INT (newdecl))
+              && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
        {
          pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
          /* Make sure we keep void as the return type.  */
@@ -1200,6 +1223,18 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          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).  */
+      else if (TREE_CODE (newdecl) == FUNCTION_DECL
+              && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node
+              && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
+              && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
+       {
+         pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
+         /* Make sure we keep void as the return type.  */
+         TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
+         pedwarned = true;
+       }
       else
        {
          if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype))
@@ -1244,7 +1279,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                  && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
        {
          if (warn_shadow)
-           warning ("%Jdeclaration of %qD shadows a built-in function",
+           warning (0, "%Jdeclaration of %qD shadows a built-in function",
                     newdecl, newdecl);
          /* Discard the old built-in function.  */
          return false;
@@ -1252,17 +1287,47 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 
       if (DECL_INITIAL (newdecl))
        {
-         if (DECL_INITIAL (olddecl)
-             && !(DECL_DECLARED_INLINE_P (olddecl)
-                  && DECL_EXTERNAL (olddecl)
-                  && !(DECL_DECLARED_INLINE_P (newdecl)
-                       && DECL_EXTERNAL (newdecl)
-                       && same_translation_unit_p (olddecl, newdecl))))
+         if (DECL_INITIAL (olddecl))
            {
-             error ("%Jredefinition of %qD", newdecl, newdecl);
-             locate_old_decl (olddecl, error);
-             return false;
-           }
+             /* 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)
+                 && same_translation_unit_p (newdecl, olddecl))
+               {
+                 error ("%Jredefinition of %qD", newdecl, 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.  */
@@ -1311,7 +1376,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            }
          else if (warn_traditional)
            {
-             warning ("%Jnon-static declaration of %qD follows "
+             warning (0, "%Jnon-static declaration of %qD follows "
                       "static declaration", newdecl, newdecl);
              warned = true;
            }
@@ -1364,7 +1429,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                }
              else if (warn_traditional)
                {
-                 warning ("%Jnon-static declaration of %qD follows "
+                 warning (0, "%Jnon-static declaration of %qD follows "
                           "static declaration", newdecl, newdecl);
                  warned = true;
                }
@@ -1413,7 +1478,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   if (DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
-      warning ("%Jredeclaration of %qD with different visibility "
+      warning (0, "%Jredeclaration of %qD with different visibility "
               "(old visibility preserved)", newdecl, newdecl);
       warned = true;
     }
@@ -1424,14 +1489,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       if (DECL_DECLARED_INLINE_P (newdecl)
          && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warning ("%Jinline declaration of %qD follows "
+         warning (0, "%Jinline declaration of %qD follows "
                   "declaration with attribute noinline", newdecl, newdecl);
          warned = true;
        }
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
        {
-         warning ("%Jdeclaration of %qD with attribute noinline follows "
+         warning (0, "%Jdeclaration of %qD with attribute noinline follows "
                   "inline declaration ", newdecl, newdecl);
          warned = true;
        }
@@ -1446,13 +1511,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
        {
          if (TREE_USED (olddecl))
            {
-             warning ("%J%qD declared inline after being called",
+             warning (0, "%J%qD declared inline after being called",
                       olddecl, olddecl);
              warned = true;
            }
          else if (DECL_INITIAL (olddecl))
            {
-             warning ("%J%qD declared inline after its definition",
+             warning (0, "%J%qD declared inline after its definition",
                       olddecl, olddecl);
              warned = true;
            }
@@ -1496,15 +1561,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       && !(TREE_CODE (newdecl) == PARM_DECL
           && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)))
     {
-      warning ("%Jredundant redeclaration of %qD", newdecl, newdecl);
+      warning (0, "%Jredundant redeclaration of %qD", newdecl, newdecl);
       warned = true;
     }
 
   /* Report location of previous decl/defn in a consistent manner.  */
   if (warned || pedwarned)
-    locate_old_decl (olddecl, pedwarned ? pedwarn : warning);
+    locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
 
-  return true;
+  return retval;
 }
 
 /* Subroutine of duplicate_decls.  NEWDECL has been found to be
@@ -1517,12 +1582,16 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 {
   int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
                           && DECL_INITIAL (newdecl) != 0);
+  int new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL
+                         && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0);
+  int old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
+                         && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0);
 
   /* For real parm decl following a forward decl, rechain the old decl
      in its new location and clear TREE_ASM_WRITTEN (it's not a
      forward decl anymore).  */
   if (TREE_CODE (newdecl) == PARM_DECL
-      && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
+      && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
     {
       struct c_binding *b, **here;
 
@@ -1590,8 +1659,12 @@ 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.  */
-  if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
+  /* 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)))
     DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
 
   /* Merge the unused-warning information.  */
@@ -1633,6 +1706,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
       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.  */
@@ -1646,7 +1720,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
         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))
+      if (!TREE_PUBLIC (olddecl))
        TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
     }
   if (DECL_EXTERNAL (newdecl))
@@ -1656,7 +1730,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 
       /* An extern decl does not override previous storage class.  */
       TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
-      if (! DECL_EXTERNAL (newdecl))
+      if (!DECL_EXTERNAL (newdecl))
        {
          DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
          DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
@@ -1706,10 +1780,15 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
          DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
          C_DECL_DECLARED_BUILTIN (newdecl) = 1;
+         if (new_is_prototype)
+           C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
+         else
+           C_DECL_BUILTIN_PROTOTYPE (newdecl)
+             = C_DECL_BUILTIN_PROTOTYPE (olddecl);
        }
 
       /* Also preserve various other info from the definition.  */
-      if (! new_is_definition)
+      if (!new_is_definition)
        {
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
          DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
@@ -1719,7 +1798,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 
          /* Set DECL_INLINE on the declaration if we've got a body
             from which to instantiate.  */
-         if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl))
+         if (DECL_INLINE (olddecl) && !DECL_UNINLINABLE (newdecl))
            {
              DECL_INLINE (newdecl) = 1;
              DECL_ABSTRACT_ORIGIN (newdecl)
@@ -1731,7 +1810,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          /* If a previous declaration said inline, mark the
             definition as inlinable.  */
          if (DECL_DECLARED_INLINE_P (newdecl)
-             && ! DECL_UNINLINABLE (newdecl))
+             && !DECL_UNINLINABLE (newdecl))
            DECL_INLINE (newdecl) = 1;
        }
     }
@@ -1805,23 +1884,30 @@ warn_if_shadowing (tree new_decl)
       {
        tree old_decl = b->decl;
 
-       if (TREE_CODE (old_decl) == PARM_DECL)
-         warning ("%Jdeclaration of %qD shadows a parameter",
+       if (old_decl == error_mark_node)
+         {
+           warning (0, "%Jdeclaration of %qD shadows previous non-variable",
+                    new_decl, new_decl);
+           break;
+         }
+       else if (TREE_CODE (old_decl) == PARM_DECL)
+         warning (0, "%Jdeclaration of %qD shadows a parameter",
                   new_decl, new_decl);
        else if (DECL_FILE_SCOPE_P (old_decl))
-         warning ("%Jdeclaration of %qD shadows a global declaration",
+         warning (0, "%Jdeclaration of %qD shadows a global declaration",
                   new_decl, new_decl);
        else if (TREE_CODE (old_decl) == FUNCTION_DECL
                 && DECL_BUILT_IN (old_decl))
-         warning ("%Jdeclaration of %qD shadows a built-in function",
-                  new_decl, new_decl);
+         {
+           warning (0, "%Jdeclaration of %qD shadows a built-in function",
+                    new_decl, new_decl);
+           break;
+         }
        else
-         warning ("%Jdeclaration of %qD shadows a previous local",
+         warning (0, "%Jdeclaration of %qD shadows a previous local",
                   new_decl, new_decl);
 
-       if (TREE_CODE (old_decl) != FUNCTION_DECL
-           || ! DECL_BUILT_IN (old_decl))
-         warning ("%Jshadowed declaration is here", old_decl);
+       warning (0, "%Jshadowed declaration is here", old_decl);
 
        break;
       }
@@ -1909,7 +1995,7 @@ pushdecl (tree x)
   bool nested = false;
 
   /* Functions need the lang_decl data.  */
-  if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
+  if (TREE_CODE (x) == FUNCTION_DECL && !DECL_LANG_SPECIFIC (x))
     DECL_LANG_SPECIFIC (x) = GGC_CNEW (struct lang_decl);
 
   /* Must set DECL_CONTEXT for everything not at file scope or
@@ -1920,6 +2006,12 @@ pushdecl (tree x)
          || DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
     DECL_CONTEXT (x) = current_function_decl;
 
+  /* If this is of variably modified type, prevent jumping into its
+     scope.  */
+  if ((TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == TYPE_DECL)
+      && variably_modified_type_p (TREE_TYPE (x), NULL_TREE))
+    c_begin_vm_scope (scope->depth);
+
   /* Anonymous decls are just inserted in the scope.  */
   if (!name)
     {
@@ -1937,11 +2029,52 @@ pushdecl (tree x)
   b = I_SYMBOL_BINDING (name);
   if (b && B_IN_SCOPE (b, scope))
     {
+      struct c_binding *b_ext, *b_use;
+      tree type = TREE_TYPE (x);
+      tree visdecl = b->decl;
+      tree vistype = TREE_TYPE (visdecl);
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
          && COMPLETE_TYPE_P (TREE_TYPE (x)))
        b->inner_comp = false;
-      if (duplicate_decls (x, b->decl))
-       return b->decl;
+      b_use = b;
+      b_ext = b;
+      /* If this is an external linkage declaration, we should check
+        for compatibility with the type in the external scope before
+        setting the type at this scope based on the visible
+        information only.  */
+      if (TREE_PUBLIC (x) && TREE_PUBLIC (visdecl))
+       {
+         while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
+           b_ext = b_ext->shadowed;
+         if (b_ext)
+           {
+             b_use = b_ext;
+             if (b_use->type)
+               TREE_TYPE (b_use->decl) = b_use->type;
+           }
+       }
+      if (duplicate_decls (x, b_use->decl))
+       {
+         if (b_use != b)
+           {
+             /* Save the updated type in the external scope and
+                restore the proper type for this scope.  */
+             tree thistype;
+             if (comptypes (vistype, type))
+               thistype = composite_type (vistype, type);
+             else
+               thistype = TREE_TYPE (b_use->decl);
+             b_use->type = TREE_TYPE (b_use->decl);
+             if (TREE_CODE (b_use->decl) == FUNCTION_DECL
+                 && DECL_BUILT_IN (b_use->decl))
+               thistype
+                 = build_type_attribute_variant (thistype,
+                                                 TYPE_ATTRIBUTES
+                                                 (b_use->type));
+             TREE_TYPE (b_use->decl) = thistype;
+           }
+         return b_use->decl;
+       }
       else
        goto skip_external_and_shadow_checks;
     }
@@ -1975,7 +2108,7 @@ pushdecl (tree x)
       if (warn_nested_externs
          && scope != file_scope
          && !DECL_IN_SYSTEM_HEADER (x))
-       warning ("nested extern declaration of %qD", x);
+       warning (0, "nested extern declaration of %qD", x);
 
       while (b && !B_IN_EXTERNAL_SCOPE (b))
        {
@@ -1987,7 +2120,7 @@ pushdecl (tree x)
             its type saved; the others will already have had their
             proper types saved and the types will not have changed as
             their scopes will not have been re-entered.  */
-         if (DECL_FILE_SCOPE_P (b->decl) && !type_saved)
+         if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved)
            {
              b->type = TREE_TYPE (b->decl);
              type_saved = true;
@@ -2028,7 +2161,15 @@ pushdecl (tree x)
          && duplicate_decls (x, b->decl))
        {
          tree thistype;
-         thistype = (vistype ? composite_type (vistype, type) : type);
+         if (vistype)
+           {
+             if (comptypes (vistype, type))
+               thistype = composite_type (vistype, type);
+             else
+               thistype = TREE_TYPE (b->decl);
+           }
+         else
+           thistype = type;
          b->type = TREE_TYPE (b->decl);
          if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
            thistype
@@ -2048,6 +2189,7 @@ pushdecl (tree x)
                 just need to fall through to make the declaration in
                 this scope.  */
              nested = true;
+             x = visdecl;
            }
          else
            {
@@ -2057,30 +2199,6 @@ pushdecl (tree x)
            }
        }
     }
-  /* Similarly, a declaration of a function with static linkage at
-     block scope must be checked against any existing declaration
-     of that function at file scope.  */
-  else if (TREE_CODE (x) == FUNCTION_DECL && scope != file_scope
-          && !TREE_PUBLIC (x) && !DECL_INITIAL (x))
-    {
-      if (warn_nested_externs && !DECL_IN_SYSTEM_HEADER (x))
-       warning ("nested static declaration of %qD", x);
-
-      while (b && !B_IN_FILE_SCOPE (b))
-       b = b->shadowed;
-
-      if (b && same_translation_unit_p (x, b->decl)
-         && duplicate_decls (x, b->decl))
-       {
-         bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
-         return b->decl;
-       }
-      else
-       {
-         bind (name, x, file_scope, /*invisible=*/true, /*nested=*/false);
-         nested = true;
-       }
-    }
 
   warn_if_shadowing (x);
 
@@ -2129,12 +2247,11 @@ pushdecl_top_level (tree x)
 {
   tree name;
   bool nested = false;
-
-  gcc_assert (TREE_CODE (x) == VAR_DECL);
+  gcc_assert (TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == CONST_DECL);
 
   name = DECL_NAME (x);
 
 gcc_assert (!I_SYMBOL_BINDING (name));
gcc_assert (TREE_CODE (x) == CONST_DECL || !I_SYMBOL_BINDING (name));
 
   if (TREE_PUBLIC (x))
     {
@@ -2154,7 +2271,7 @@ implicit_decl_warning (tree id, tree olddecl)
   switch (mesg_implicit_function_declaration)
     {
     case 0: return;
-    case 1: diag = warning; break;
+    case 1: diag = warning0; break;
     case 2: diag = error;   break;
     default: gcc_unreachable ();
     }
@@ -2185,6 +2302,9 @@ implicitly_declare (tree functionid)
 
   if (decl)
     {
+      if (decl == error_mark_node)
+       return decl;
+
       /* FIXME: Objective-C has weird not-really-builtin functions
         which are supposed to be visible automatically.  They wind up
         in the external scope because they're pushed before the file
@@ -2217,7 +2337,7 @@ implicitly_declare (tree functionid)
                                                      (TREE_TYPE (decl)));
              if (!comptypes (newtype, TREE_TYPE (decl)))
                {
-                 warning ("incompatible implicit declaration of built-in"
+                 warning (0, "incompatible implicit declaration of built-in"
                           " function %qD", decl);
                  newtype = TREE_TYPE (decl);
                }
@@ -2270,26 +2390,26 @@ implicitly_declare (tree functionid)
    ID, including a reference to a builtin outside of function-call
    context.  Establish a binding of the identifier to error_mark_node
    in an appropriate scope, which will suppress further errors for the
-   same identifier.  */
+   same identifier.  The error message should be given location LOC.  */
 void
-undeclared_variable (tree id)
+undeclared_variable (tree id, location_t loc)
 {
   static bool already = false;
   struct c_scope *scope;
 
   if (current_function_decl == 0)
     {
-      error ("%qE undeclared here (not in a function)", id);
+      error ("%H%qE undeclared here (not in a function)", &loc, id);
       scope = current_scope;
     }
   else
     {
-      error ("%qE undeclared (first use in this function)", id);
+      error ("%H%qE undeclared (first use in this function)", &loc, id);
 
-      if (! already)
+      if (!already)
        {
-         error ("(Each undeclared identifier is reported only once");
-         error ("for each function it appears in.)");
+         error ("%H(Each undeclared identifier is reported only once", &loc);
+         error ("%Hfor each function it appears in.)", &loc);
          already = true;
        }
 
@@ -2327,8 +2447,7 @@ lookup_label (tree name)
 
   if (current_function_decl == 0)
     {
-      error ("label %qs referenced outside of any function",
-            IDENTIFIER_POINTER (name));
+      error ("label %qE referenced outside of any function", name);
       return 0;
     }
 
@@ -2370,7 +2489,7 @@ declare_label (tree name)
      at this scope */
   if (b && B_IN_CURRENT_SCOPE (b))
     {
-      error ("duplicate label declaration %qs", IDENTIFIER_POINTER (name));
+      error ("duplicate label declaration %qE", name);
       locate_old_decl (b->decl, error);
 
       /* Just use the previous declaration.  */
@@ -2398,6 +2517,7 @@ define_label (location_t location, tree name)
      if there is a containing function with a declared label with
      the same name.  */
   tree label = I_LABEL_DECL (name);
+  struct c_label_list *nlist_se, *nlist_vm;
 
   if (label
       && ((DECL_CONTEXT (label) == current_function_decl
@@ -2414,6 +2534,11 @@ define_label (location_t location, tree name)
       /* The label has been used or declared already in this function,
         but not defined.  Update its location to point to this
         definition.  */
+      if (C_DECL_UNDEFINABLE_STMT_EXPR (label))
+       error ("%Jjump into statement expression", label);
+      if (C_DECL_UNDEFINABLE_VM (label))
+       error ("%Jjump into scope of identifier with variably modified type",
+              label);
       DECL_SOURCE_LOCATION (label) = location;
     }
   else
@@ -2427,9 +2552,18 @@ define_label (location_t location, tree name)
     }
 
   if (warn_traditional && !in_system_header && lookup_name (name))
-    warning ("%Htraditional C lacks a separate namespace for labels, "
-             "identifier %qs conflicts", &location,
-            IDENTIFIER_POINTER (name));
+    warning (0, "%Htraditional C lacks a separate namespace 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;
+  nlist_se->label = label;
+  label_context_stack_se->labels_def = nlist_se;
+
+  nlist_vm = XOBNEW (&parser_obstack, struct c_label_list);
+  nlist_vm->next = label_context_stack_vm->labels_def;
+  nlist_vm->label = label;
+  label_context_stack_vm->labels_def = nlist_vm;
 
   /* Mark label as having been defined.  */
   DECL_INITIAL (label) = error_mark_node;
@@ -2493,9 +2627,8 @@ void
 pending_xref_error (void)
 {
   if (pending_invalid_xref != 0)
-    error ("%H%qs defined as wrong kind of tag",
-           &pending_invalid_xref_location,
-           IDENTIFIER_POINTER (pending_invalid_xref));
+    error ("%H%qE defined as wrong kind of tag",
+           &pending_invalid_xref_location, pending_invalid_xref);
   pending_invalid_xref = 0;
 }
 
@@ -2535,11 +2668,9 @@ lookup_name_in_scope (tree name, struct c_scope *scope)
 void
 c_init_decl_processing (void)
 {
-  tree endlink;
-  tree ptr_ftype_void, ptr_ftype_ptr;
   location_t save_loc = input_location;
 
-  /* Adds some ggc roots, and reserved words for c-parse.in.  */
+  /* Initialize reserved words for parser.  */
   c_parse_init ();
 
   current_function_decl = 0;
@@ -2573,12 +2704,6 @@ c_init_decl_processing (void)
   pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
                        boolean_type_node));
 
-  endlink = void_list_node;
-  ptr_ftype_void = build_function_type (ptr_type_node, endlink);
-  ptr_ftype_ptr
-    = build_function_type (ptr_type_node,
-                          tree_cons (NULL_TREE, ptr_type_node, endlink));
-
   input_location = save_loc;
 
   pedantic_lvalues = true;
@@ -2601,9 +2726,9 @@ c_make_fname_decl (tree id, int type_dep)
   tree decl, type, init;
   size_t length = strlen (name);
 
-  type =  build_array_type
-          (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
-          build_index_type (size_int (length)));
+  type = build_array_type (char_type_node,
+                          build_index_type (size_int (length)));
+  type = c_build_qualified_type (type, TYPE_QUAL_CONST);
 
   decl = build_decl (VAR_DECL, id, type);
 
@@ -2651,6 +2776,7 @@ builtin_function (const char *name, tree type, int function_code,
   DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
   DECL_BUILT_IN_CLASS (decl) = cl;
   DECL_FUNCTION_CODE (decl) = function_code;
+  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
   if (library_name)
     SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
 
@@ -2697,8 +2823,6 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
 {
   bool found_tag = false;
 
-  pending_invalid_xref = 0;
-
   if (declspecs->type && !declspecs->default_int_p && !declspecs->typedef_p)
     {
       tree value = declspecs->type;
@@ -2722,8 +2846,29 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
                  warned = 1;
                }
            }
+         else if (!declspecs->tag_defined_p
+                  && declspecs->storage_class != csc_none)
+           {
+             if (warned != 1)
+               pedwarn ("empty declaration with storage class specifier "
+                        "does not redeclare tag");
+             warned = 1;
+             pending_xref_error ();
+           }
+         else if (!declspecs->tag_defined_p
+                  && (declspecs->const_p
+                      || declspecs->volatile_p
+                      || declspecs->restrict_p))
+           {
+             if (warned != 1)
+               pedwarn ("empty declaration with type qualifier "
+                        "does not redeclare tag");
+             warned = 1;
+             pending_xref_error ();
+           }
          else
            {
+             pending_invalid_xref = 0;
              t = lookup_tag (code, name, 1);
 
              if (t == 0)
@@ -2748,6 +2893,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
       warned = 1;
     }
 
+  pending_invalid_xref = 0;
+
   if (declspecs->inline_p)
     {
       error ("%<inline%> in empty declaration");
@@ -2768,13 +2915,13 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
 
   if (!warned && !in_system_header && declspecs->storage_class != csc_none)
     {
-      warning ("useless storage class specifier in empty declaration");
+      warning (0, "useless storage class specifier in empty declaration");
       warned = 2;
     }
 
   if (!warned && !in_system_header && declspecs->thread_p)
     {
-      warning ("useless %<__thread%> in empty declaration");
+      warning (0, "useless %<__thread%> in empty declaration");
       warned = 2;
     }
 
@@ -2782,7 +2929,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
                                       || declspecs->volatile_p
                                       || declspecs->restrict_p))
     {
-      warning ("useless type qualifier in empty declaration");
+      warning (0, "useless type qualifier in empty declaration");
       warned = 2;
     }
 
@@ -2861,7 +3008,7 @@ 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 ("GCC does not yet properly implement %<[*]%> array declarators");
+    warning (0, "GCC does not yet properly implement %<[*]%> array declarators");
   return declarator;
 }
 
@@ -2932,12 +3079,14 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
 
   decl = grokdeclarator (declarator, declspecs,
                         NORMAL, initialized, NULL);
+  if (!decl)
+    return 0;
 
   deprecated_state = DEPRECATED_NORMAL;
 
   if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
       && MAIN_NAME_P (DECL_NAME (decl)))
-    warning ("%J%qD is usually a function", decl, decl);
+    warning (0, "%J%qD is usually a function", decl, decl);
 
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
@@ -2985,11 +3134,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
            error ("variable %qD has initializer but incomplete type", decl);
            initialized = 0;
          }
-       else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
-         {
-           error ("elements of array %qD have incomplete type", decl);
-           initialized = 0;
-         }
        else if (C_DECL_VARIABLE_SIZE (decl))
          {
            /* Although C99 is unclear about whether incomplete arrays
@@ -3063,7 +3207,7 @@ 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 ("%Jinline function %qD given attribute noinline", decl, decl);
+    warning (0, "%Jinline function %qD given attribute noinline", decl, decl);
 
   /* Add this decl to the current scope.
      TEM may equal DECL or it may be a previous decl of the same name.  */
@@ -3118,14 +3262,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
       && TYPE_DOMAIN (type) == 0
       && TREE_CODE (decl) != TYPE_DECL)
     {
-      int do_default
+      bool do_default
        = (TREE_STATIC (decl)
           /* Even if pedantic, an external linkage array
              may have incomplete type at first.  */
           ? pedantic && !TREE_PUBLIC (decl)
           : !DECL_EXTERNAL (decl));
       int failure
-       = complete_array_type (type, DECL_INITIAL (decl), do_default);
+       = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl),
+                              do_default);
 
       /* Get the completed type made by complete_array_type.  */
       type = TREE_TYPE (decl);
@@ -3143,17 +3288,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
             If it is not `static', then do not mark extern;
             finish_incomplete_decl will give it a default size
             and it will get allocated.  */
-         else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl))
+         else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
            DECL_EXTERNAL (decl) = 1;
        }
-
-      /* TYPE_MAX_VALUE is always one less than the number of elements
-        in the array, because we start counting at zero.  Therefore,
-        warn only if the value is less than zero.  */
-      else if (pedantic && TYPE_DOMAIN (type) != 0
-              && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+      else if (failure == 3)
        error ("%Jzero or negative size array %qD", decl, decl);
 
+      if (DECL_INITIAL (decl))
+       TREE_TYPE (DECL_INITIAL (decl)) = type;
+
       layout_decl (decl, 0);
     }
 
@@ -3201,20 +3344,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
   if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
     {
       if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
-       {
-         tree builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
-         set_user_assembler_name (builtin, asmspec);
-          if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
-            init_block_move_fn (asmspec);
-          else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
-            init_block_clear_fn (asmspec);
-        }
+       set_builtin_user_assembler_name (decl, asmspec);
       set_user_assembler_name (decl, asmspec);
     }
 
   /* If #pragma weak was used, mark the decl weak now.  */
-  if (current_scope == file_scope)
-    maybe_apply_pragma_weak (decl);
+  maybe_apply_pragma_weak (decl);
 
   /* If this is a variable definition, determine its ELF visibility.  */
   if (TREE_CODE (decl) == VAR_DECL 
@@ -3239,11 +3374,11 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
             ordinary, non-register local variable.  Historically,
             GCC has accepted -- but ignored -- the ASMSPEC in
             this case.  */
-         if (! DECL_FILE_SCOPE_P (decl)
+         if (!DECL_FILE_SCOPE_P (decl)
              && TREE_CODE (decl) == VAR_DECL
              && !C_DECL_REGISTER (decl)
              && !TREE_STATIC (decl))
-           warning ("%Jignoring asm-specifier for non-static local "
+           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));
@@ -3303,7 +3438,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
          /* Recompute the RTL of a local array now
             if it used to be an incomplete type.  */
          if (was_incomplete
-             && ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
+             && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
            {
              /* If we used it already as memory, it must stay in memory.  */
              TREE_ADDRESSABLE (decl) = TREE_USED (decl);
@@ -3448,17 +3583,19 @@ build_compound_literal (tree type, tree init)
 
   if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
     {
-      int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
-      
+      int failure = complete_array_type (&TREE_TYPE (decl),
+                                        DECL_INITIAL (decl), true);
       gcc_assert (!failure);
+
+      type = TREE_TYPE (decl);
+      TREE_TYPE (DECL_INITIAL (decl)) = type;
     }
 
-  type = TREE_TYPE (decl);
   if (type == error_mark_node || !COMPLETE_TYPE_P (type))
     return error_mark_node;
 
   stmt = build_stmt (DECL_EXPR, decl);
-  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+  complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
   TREE_SIDE_EFFECTS (complit) = 1;
 
   layout_decl (decl, 0);
@@ -3476,6 +3613,7 @@ build_compound_literal (tree type, tree init)
       DECL_DEFER_OUTPUT (decl) = 1;
       DECL_COMDAT (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
+      DECL_IGNORED_P (decl) = 1;
       pushdecl (decl);
       rest_of_decl_compilation (decl, 1, 0);
     }
@@ -3483,73 +3621,6 @@ build_compound_literal (tree type, tree init)
   return complit;
 }
 \f
-/* Make TYPE a complete type based on INITIAL_VALUE.
-   Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
-   2 if there was no information (in which case assume 1 if DO_DEFAULT).  */
-
-int
-complete_array_type (tree type, tree initial_value, int do_default)
-{
-  tree maxindex = NULL_TREE;
-  int value = 0;
-
-  if (initial_value)
-    {
-      /* Note MAXINDEX  is really the maximum index,
-        one less than the size.  */
-      if (TREE_CODE (initial_value) == STRING_CST)
-       {
-         int eltsize
-           = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
-         maxindex = build_int_cst (NULL_TREE,
-                                   (TREE_STRING_LENGTH (initial_value)
-                                    / eltsize) - 1);
-       }
-      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
-       {
-         tree elts = CONSTRUCTOR_ELTS (initial_value);
-         maxindex = build_int_cst (NULL_TREE, -1);
-         for (; elts; elts = TREE_CHAIN (elts))
-           {
-             if (TREE_PURPOSE (elts))
-               maxindex = TREE_PURPOSE (elts);
-             else
-               maxindex = fold (build2 (PLUS_EXPR, integer_type_node,
-                                        maxindex, integer_one_node));
-           }
-       }
-      else
-       {
-         /* Make an error message unless that happened already.  */
-         if (initial_value != error_mark_node)
-           value = 1;
-
-         /* Prevent further error messages.  */
-         maxindex = build_int_cst (NULL_TREE, 0);
-       }
-    }
-
-  if (!maxindex)
-    {
-      if (do_default)
-       maxindex = build_int_cst (NULL_TREE, 0);
-      value = 2;
-    }
-
-  if (maxindex)
-    {
-      TYPE_DOMAIN (type) = build_index_type (maxindex);
-      
-      gcc_assert (TREE_TYPE (maxindex));
-    }
-
-  /* Lay out the type now that we can get the real answer.  */
-
-  layout_type (type);
-
-  return value;
-}
-\f
 /* Determine whether TYPE is a structure with a flexible array member,
    or a union containing such a structure (possibly recursively).  */
 
@@ -3593,12 +3664,10 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
   unsigned HOST_WIDE_INT w;
   const char *name = orig_name ? orig_name: _("<anonymous>");
 
-  /* Necessary?  */
-  STRIP_NOPS (*width);
-
   /* Detect and ignore out of range field width and process valid
      field widths.  */
-  if (TREE_CODE (*width) != INTEGER_CST)
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (*width))
+      || TREE_CODE (*width) != INTEGER_CST)
     {
       error ("bit-field %qs width not an integer constant", name);
       *width = integer_one_node;
@@ -3654,7 +3723,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
       if (!lt
           || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
          || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
-       warning ("%qs is narrower than values of its type", name);
+       warning (0, "%qs is narrower than values of its type", name);
     }
 }
 \f
@@ -3789,10 +3858,6 @@ grokdeclarator (const struct c_declarator *declarator,
       && TREE_CODE (type) == INTEGER_TYPE)
     type = c_common_unsigned_type (type);
 
-  /* Check the type and width of a bit-field.  */
-  if (bitfield)
-    check_bitfield_type_and_width (&type, width, orig_name);
-
   /* Figure out the type qualifiers for the declaration.  There are
      two ways a declaration can become qualified.  One is something
      like `const int i' where the `const' is explicit.  Another is
@@ -3817,7 +3882,7 @@ grokdeclarator (const struct c_declarator *declarator,
       if (volatilep > 1)
        pedwarn ("duplicate %<volatile%>");
     }
-  if (! flag_gen_aux_info && (TYPE_QUALS (type)))
+  if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
     type = TYPE_MAIN_VARIANT (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
                | (restrictp ? TYPE_QUAL_RESTRICT : 0)
@@ -3876,7 +3941,7 @@ grokdeclarator (const struct c_declarator *declarator,
     {
       /* 'extern' with initialization is invalid if not at file scope.  */
       if (current_scope == file_scope)
-       warning ("%qs initialized and declared %<extern%>", name);
+       warning (0, "%qs initialized and declared %<extern%>", name);
       else
        error ("%qs has both %<extern%> and initializer", name);
     }
@@ -3902,7 +3967,13 @@ grokdeclarator (const struct c_declarator *declarator,
 
   /* Now figure out the structure of the declarator proper.
      Descend through it, creating more complex types, until we reach
-     the declared identifier (or NULL_TREE, in an absolute declarator).  */
+     the declared identifier (or NULL_TREE, in an absolute declarator).
+     At each stage we maintain an unqualified version of the type
+     together with any qualifiers that should be applied to it with
+     c_build_qualified_type; this way, array types including
+     multidimensional array types are first built up in unqualified
+     form and then the qualified form is created with
+     TYPE_MAIN_VARIANT pointing to the unqualified form.  */
 
   while (declarator && declarator->kind != cdk_id)
     {
@@ -4009,7 +4080,7 @@ grokdeclarator (const struct c_declarator *declarator,
                   lvalue.  */
                STRIP_TYPE_NOPS (size);
                
-               if (! INTEGRAL_TYPE_P (TREE_TYPE (size)))
+               if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
                  {
                    error ("size of array %qs has non-integer type", name);
                    size = integer_one_node;
@@ -4056,6 +4127,12 @@ grokdeclarator (const struct c_declarator *declarator,
                  }
                else
                  {
+                   /* Arrange for the SAVE_EXPR on the inside of the
+                      MINUS_EXPR, which allows the -1 to get folded
+                      with the +1 that happens when building TYPE_SIZE.  */
+                   if (size_varies)
+                     size = variable_size (size);
+
                    /* Compute the maximum valid index, that is, size
                       - 1.  Do the calculation in index_type, so that
                       if it is a variable the computations will be
@@ -4079,8 +4156,6 @@ grokdeclarator (const struct c_declarator *declarator,
                        continue;
                      }
                    
-                   if (size_varies)
-                     itype = variable_size (itype);
                    itype = build_index_type (itype);
                  }
              }
@@ -4094,17 +4169,14 @@ grokdeclarator (const struct c_declarator *declarator,
                itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
              }
 
-           /* If pedantic, complain about arrays of incomplete types.  */
-           if (pedantic && !COMPLETE_TYPE_P (type))
-             pedwarn ("array type has incomplete element type");
-
-           /* Build the array type itself, then merge any constancy
-              or volatility into the target type.  We must do it in
-              this order to ensure that the TYPE_MAIN_VARIANT field
-              of the array type is set correctly.  */
-           type = build_array_type (type, itype);
-           if (type_quals)
-             type = c_build_qualified_type (type, type_quals);
+            /* Complain about arrays of incomplete types.  */
+           if (!COMPLETE_TYPE_P (type))
+             {
+               error ("array type has incomplete element type");
+               type = error_mark_node;
+             }
+           else
+             type = build_array_type (type, itype);
 
            if (size_varies)
              C_TYPE_VARIABLE_SIZE (type) = 1;
@@ -4114,14 +4186,9 @@ grokdeclarator (const struct c_declarator *declarator,
               zero.  */
            if (size && integer_zerop (size))
              {
-               layout_type (type);
                TYPE_SIZE (type) = bitsize_zero_node;
                TYPE_SIZE_UNIT (type) = size_zero_node;
              }
-           else if (declarator->kind == cdk_pointer)
-             /* We can never complete an array type which is the
-                target of a pointer, so go ahead and lay it out.  */
-             layout_type (type);
 
            if (decl_context != PARM
                && (array_ptr_quals != TYPE_UNQUALIFIED
@@ -4187,7 +4254,7 @@ grokdeclarator (const struct c_declarator *declarator,
                if (VOID_TYPE_P (type) && really_funcdef)
                  pedwarn ("function definition has qualified void return type");
                else if (warn_return_type)
-                 warning ("type qualifiers ignored on function return type");
+                 warning (0, "type qualifiers ignored on function return type");
                
                type = c_build_qualified_type (type, type_quals);
              }
@@ -4235,7 +4302,12 @@ grokdeclarator (const struct c_declarator *declarator,
        }
     }
 
-  /* Now TYPE has the actual type.  */
+  /* Now TYPE has the actual type, apart from any qualifiers in
+     TYPE_QUALS.  */
+
+  /* Check the type and width of a bit-field.  */
+  if (bitfield)
+    check_bitfield_type_and_width (&type, width, orig_name);
 
   /* Did array size calculations overflow?  */
 
@@ -4308,7 +4380,7 @@ grokdeclarator (const struct c_declarator *declarator,
      a better error message can be made later.  */
 
   if (VOID_TYPE_P (type) && decl_context != PARM
-      && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
+      && !((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
            && (storage_class == csc_extern
                || (current_scope == file_scope
                    && !(storage_class == csc_static
@@ -4343,7 +4415,7 @@ grokdeclarator (const struct c_declarator *declarator,
 
            /* We don't yet implement attributes in this context.  */
            if (array_ptr_attrs != NULL_TREE)
-             warning ("attributes in parameter array declarator ignored");
+             warning (0, "attributes in parameter array declarator ignored");
 
            size_varies = 0;
          }
@@ -4400,11 +4472,7 @@ grokdeclarator (const struct c_declarator *declarator,
            error ("field %qs has incomplete type", name);
            type = error_mark_node;
          }
-       /* Move type qualifiers down to element of an array.  */
-       if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
-         type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
-                                                          type_quals),
-                                  TYPE_DOMAIN (type));
+       type = c_build_qualified_type (type, type_quals);
        decl = build_decl (FIELD_DECL, declarator->u.id, type);
        DECL_NONADDRESSABLE_P (decl) = bitfield;
 
@@ -4414,7 +4482,9 @@ grokdeclarator (const struct c_declarator *declarator,
     else if (TREE_CODE (type) == FUNCTION_TYPE)
       {
        if (storage_class == csc_register || threadp)
-         error ("invalid storage class for function %qs", name);
+         {
+           error ("invalid storage class for function %qs", name);
+          }
        else if (current_scope != file_scope)
          {
            /* Function declaration not at file scope.  Storage
@@ -4427,8 +4497,14 @@ grokdeclarator (const struct c_declarator *declarator,
                if (pedantic)
                  pedwarn ("invalid storage class for function %qs", name);
              }
-           if (storage_class == csc_static)
-             error ("invalid storage class for function %qs", name);
+           else if (storage_class == csc_static)
+             {
+               error ("invalid storage class for function %qs", name);
+               if (funcdef_flag)
+                 storage_class = declspecs->storage_class = csc_none;
+               else
+                 return 0;
+             }
          }
 
        decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
@@ -4436,14 +4512,14 @@ grokdeclarator (const struct c_declarator *declarator,
 
        DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
 
-       if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
+       if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
          pedwarn ("ISO C forbids qualified function types");
 
        /* GNU C interprets a volatile-qualified function type to indicate
           that the function does not return.  */
        if ((type_quals & TYPE_QUAL_VOLATILE)
            && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
-         warning ("%<noreturn%> function returns non-void value");
+         warning (0, "%<noreturn%> function returns non-void value");
 
        /* Every function declaration is an external reference
           (DECL_EXTERNAL) except for those which are not at file
@@ -4501,17 +4577,7 @@ grokdeclarator (const struct c_declarator *declarator,
        /* An uninitialized decl with `extern' is a reference.  */
        int extern_ref = !initialized && storage_class == csc_extern;
 
-       /* Move type qualifiers down to element of an array.  */
-       if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
-         {
-           int saved_align = TYPE_ALIGN(type);
-           type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
-                                                            type_quals),
-                                    TYPE_DOMAIN (type));
-           TYPE_ALIGN (type) = saved_align;
-         }
-       else if (type_quals)
-         type = c_build_qualified_type (type, type_quals);
+       type = c_build_qualified_type (type, type_quals);
 
        /* C99 6.2.2p7: It is invalid (compile-time undefined
           behavior) to create an 'extern' declaration for a
@@ -4533,6 +4599,7 @@ grokdeclarator (const struct c_declarator *declarator,
          }
 
        decl = build_decl (VAR_DECL, declarator->u.id, type);
+       DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
        if (size_varies)
          C_DECL_VARIABLE_SIZE (decl) = 1;
 
@@ -4630,14 +4697,14 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
 
   if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag
       && !in_system_header)
-    warning ("function declaration isn%'t a prototype");
+    warning (0, "function declaration isn%'t a prototype");
 
   if (arg_types == error_mark_node)
     return 0;  /* don't set TYPE_ARG_TYPES in this case */
 
   else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
     {
-      if (! funcdef_flag)
+      if (!funcdef_flag)
        pedwarn ("parameter names (without types) in function declaration");
 
       arg_info->parms = arg_info->types;
@@ -4649,10 +4716,14 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
       tree parm, type, typelt;
       unsigned int parmno;
 
-      /* If the arg types are incomplete in a declaration, they must
-        include undefined tags.  These tags can never be defined in
-        the scope of the declaration, so the types can never be
-        completed, and no call can be compiled successfully.  */
+      /* If there is a parameter of incomplete type in a definition,
+        this is an error.  In a declaration this is valid, and a
+        struct or union type may be completed later, before any calls
+        or definition of the function.  In the case where the tag was
+        first declared within the parameter list, a warning has
+        already been given.  If a parameter has void type, then
+        however the function cannot be defined or called, so
+        warn.  */
 
       for (parm = arg_info->parms, typelt = arg_types, parmno = 1;
           parm;
@@ -4676,13 +4747,13 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
                  TREE_VALUE (typelt) = error_mark_node;
                  TREE_TYPE (parm) = error_mark_node;
                }
-             else
+             else if (VOID_TYPE_P (type))
                {
                  if (DECL_NAME (parm))
-                   warning ("%Jparameter %u (%qD) has incomplete type",
+                   warning (0, "%Jparameter %u (%qD) has void type",
                             parm, parmno, parm);
                  else
-                   warning ("%Jparameter %u has incomplete type",
+                   warning (0, "%Jparameter %u has void type",
                             parm, parmno);
                }
            }
@@ -4817,16 +4888,16 @@ get_parm_info (bool ellipsis)
            {
              if (b->id)
                /* The %s will be one of 'struct', 'union', or 'enum'.  */
-               warning ("%<%s %E%> declared inside parameter list",
+               warning (0, "%<%s %E%> declared inside parameter list",
                         keyword, b->id);
              else
                /* The %s will be one of 'struct', 'union', or 'enum'.  */
-               warning ("anonymous %s declared inside parameter list",
+               warning (0, "anonymous %s declared inside parameter list",
                         keyword);
 
-             if (! explained_incomplete_types)
+             if (!explained_incomplete_types)
                {
-                 warning ("its scope is only this definition or declaration,"
+                 warning (0, "its scope is only this definition or declaration,"
                           " which is probably not what you want");
                  explained_incomplete_types = true;
                }
@@ -4837,10 +4908,13 @@ get_parm_info (bool ellipsis)
 
        case CONST_DECL:
        case TYPE_DECL:
+       case FUNCTION_DECL:
          /* CONST_DECLs appear here when we have an embedded enum,
             and TYPE_DECLs appear here when we have an embedded struct
             or union.  No warnings for this - we already warned about the
-            type itself.  */
+            type itself.  FUNCTION_DECLs appear when there is an implicit
+            function declaration in the parameter list.  */
+
          TREE_CHAIN (decl) = others;
          others = decl;
          /* fall through */
@@ -4857,7 +4931,6 @@ get_parm_info (bool ellipsis)
 
          /* Other things that might be encountered.  */
        case LABEL_DECL:
-       case FUNCTION_DECL:
        case VAR_DECL:
        default:
          gcc_unreachable ();
@@ -4874,11 +4947,13 @@ get_parm_info (bool ellipsis)
 }
 \f
 /* Get the struct, enum or union (CODE says which) with tag NAME.
-   Define the tag as a forward-reference if it is not defined.  */
+   Define the tag as a forward-reference if it is not defined.
+   Return a c_typespec structure for the type specifier.  */
 
-tree
-xref_tag (enum tree_code code, tree name)
+struct c_typespec
+parser_xref_tag (enum tree_code code, tree name)
 {
+  struct c_typespec ret;
   /* If a cross reference is requested, look up the type
      already defined for this tag and return it.  */
 
@@ -4894,8 +4969,12 @@ xref_tag (enum tree_code code, tree name)
      this would not work properly if we return the reference found.
      (For example, with "struct foo" in an outer scope, "union foo;"
      must shadow that tag with a new one of union type.)  */
+  ret.kind = (ref ? ctsk_tagref : ctsk_tagfirstref);
   if (ref && TREE_CODE (ref) == code)
-    return ref;
+    {
+      ret.spec = ref;
+      return ret;
+    }
 
   /* If no such tag is yet defined, create a forward-reference node
      and record it as the "definition".
@@ -4918,7 +4997,18 @@ xref_tag (enum tree_code code, tree name)
 
   pushtag (name, ref);
 
-  return ref;
+  ret.spec = ref;
+  return ret;
+}
+
+/* Get the struct, enum or union (CODE says which) with tag NAME.
+   Define the tag as a forward-reference if it is not defined.
+   Return a tree for the type.  */
+
+tree
+xref_tag (enum tree_code code, tree name)
+{
+  return parser_xref_tag (code, name).spec;
 }
 \f
 /* Make sure that the tag NAME is defined *in the current scope*
@@ -4940,18 +5030,16 @@ start_struct (enum tree_code code, tree name)
       if (TYPE_SIZE (ref))
         {
          if (code == UNION_TYPE)
-           error ("redefinition of %<union %s%>", IDENTIFIER_POINTER (name));
+           error ("redefinition of %<union %E%>", name);
           else
-           error ("redefinition of %<struct %s%>", IDENTIFIER_POINTER (name));
+           error ("redefinition of %<struct %E%>", name);
        }
       else if (C_TYPE_BEING_DEFINED (ref))
        {
          if (code == UNION_TYPE)
-           error ("nested redefinition of %<union %s%>",
-                  IDENTIFIER_POINTER (name));
+           error ("nested redefinition of %<union %E%>", name);
           else
-           error ("nested redefinition of %<struct %s%>",
-                  IDENTIFIER_POINTER (name));
+           error ("nested redefinition of %<struct %E%>", name);
        }
     }
   else
@@ -5004,27 +5092,29 @@ grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs,
         that took root before someone noticed the bug...  */
 
       tree type = declspecs->type;
+      bool type_ok = (TREE_CODE (type) == RECORD_TYPE
+                     || TREE_CODE (type) == UNION_TYPE);
+      bool ok = false;
 
-      if (type
-         && (TREE_CODE (type) == RECORD_TYPE
-             || TREE_CODE (type) == UNION_TYPE)
+      if (type_ok
          && (flag_ms_extensions || !declspecs->typedef_p))
        {
          if (flag_ms_extensions)
-           ; /* ok */
+           ok = true;
          else if (flag_iso)
-           goto warn_unnamed_field;
+           ok = false;
          else if (TYPE_NAME (type) == NULL)
-           ; /* ok */
+           ok = true;
          else
-           goto warn_unnamed_field;
+           ok = false;
        }
-      else
+      if (!ok)
        {
-       warn_unnamed_field:
-         warning ("declaration does not declare anything");
+         pedwarn ("declaration does not declare anything");
          return NULL_TREE;
        }
+      if (pedantic)
+       pedwarn ("ISO C doesn%'t support unnamed structs/unions");
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -5118,9 +5208,22 @@ finish_struct (tree t, tree fieldlist, tree attributes)
          break;
 
       if (x == 0)
-       pedwarn ("%s has no %s",
-                TREE_CODE (t) == UNION_TYPE ? _("union") : _("struct"),
-                fieldlist ? _("named members") : _("members"));
+       {
+         if (TREE_CODE (t) == UNION_TYPE)
+           {
+             if (fieldlist)
+               pedwarn ("union has no named members");
+             else
+               pedwarn ("union has no members");
+           }
+         else
+           {
+             if (fieldlist)
+               pedwarn ("struct has no named members");
+             else
+               pedwarn ("struct has no members");
+           }
+       }
     }
 
   /* Install struct as DECL_CONTEXT of each field decl.
@@ -5183,7 +5286,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
              error ("%Jflexible array member not at end of struct", x);
              TREE_TYPE (x) = error_mark_node;
            }
-         else if (! saw_named_field)
+         else if (!saw_named_field)
            {
              error ("%Jflexible array member in otherwise empty struct", x);
              TREE_TYPE (x) = error_mark_node;
@@ -5218,8 +5321,11 @@ finish_struct (tree t, tree fieldlist, tree attributes)
            = tree_low_cst (DECL_INITIAL (*fieldlistp), 1);
          tree type = TREE_TYPE (*fieldlistp);
          if (width != TYPE_PRECISION (type))
-           TREE_TYPE (*fieldlistp)
-             = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+           {
+             TREE_TYPE (*fieldlistp)
+               = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+             DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
+           }
          DECL_INITIAL (*fieldlistp) = 0;
        }
       else
@@ -5294,10 +5400,10 @@ finish_struct (tree t, tree fieldlist, tree attributes)
      make it one, warn and turn off the flag.  */
   if (TREE_CODE (t) == UNION_TYPE
       && TYPE_TRANSPARENT_UNION (t)
-      && TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))
+      && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))))
     {
       TYPE_TRANSPARENT_UNION (t) = 0;
-      warning ("union cannot be made transparent");
+      warning (0, "union cannot be made transparent");
     }
 
   /* If this structure or union completes the type of any previous
@@ -5315,7 +5421,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
          if (c_dialect_objc ())
            objc_check_decl (decl);
          rest_of_decl_compilation (decl, toplevel, 0);
-         if (! toplevel)
+         if (!toplevel)
            expand_decl (decl);
        }
     }
@@ -5324,6 +5430,12 @@ finish_struct (tree t, tree fieldlist, tree attributes)
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (t, toplevel);
 
+  /* 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))
+    add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t)));
+
   return t;
 }
 
@@ -5362,14 +5474,14 @@ start_enum (tree name)
     }
 
   if (C_TYPE_BEING_DEFINED (enumtype))
-    error ("nested redefinition of %<enum %s%>", IDENTIFIER_POINTER (name));
+    error ("nested redefinition of %<enum %E%>", name);
 
   C_TYPE_BEING_DEFINED (enumtype) = 1;
 
   if (TYPE_VALUES (enumtype) != 0)
     {
       /* This enum is a named one that has been declared already.  */
-      error ("redeclaration of %<enum %s%>", IDENTIFIER_POINTER (name));
+      error ("redeclaration of %<enum %E%>", name);
 
       /* Completely replace its old definition.
         The old enumerators remain defined, however.  */
@@ -5432,7 +5544,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
       tem = c_common_type_for_size (precision, unsign);
       if (tem == NULL)
        {
-         warning ("enumeration values exceed range of largest integer");
+         warning (0, "enumeration values exceed range of largest integer");
          tem = long_long_integer_type_node;
        }
     }
@@ -5536,17 +5648,14 @@ build_enumerator (tree name, tree value)
 
   /* Validate and default VALUE.  */
 
-  /* Remove no-op casts from the value.  */
-  if (value)
-    STRIP_TYPE_NOPS (value);
-
   if (value != 0)
     {
       /* Don't issue more errors for error_mark_node (i.e. an
         undeclared identifier) - just ignore the value expression.  */
       if (value == error_mark_node)
        value = 0;
-      else if (TREE_CODE (value) != INTEGER_CST)
+      else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))
+              || TREE_CODE (value) != INTEGER_CST)
        {
          error ("enumerator value for %qE is not an integer constant", name);
          value = 0;
@@ -5568,7 +5677,7 @@ build_enumerator (tree name, tree value)
        error ("overflow in enumeration values");
     }
 
-  if (pedantic && ! int_fits_type_p (value, integer_type_node))
+  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.
@@ -5615,6 +5724,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
 {
   tree decl1, old_decl;
   tree restype, resdecl;
+  struct c_label_context_se *nstack_se;
+  struct c_label_context_vm *nstack_vm;
 
   current_function_returns_value = 0;  /* Assume, until we see it does.  */
   current_function_returns_null = 0;
@@ -5623,6 +5734,19 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   current_extern_inline = 0;
   c_switch_stack = NULL;
 
+  nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
+  nstack_se->labels_def = NULL;
+  nstack_se->labels_used = NULL;
+  nstack_se->next = label_context_stack_se;
+  label_context_stack_se = nstack_se;
+
+  nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
+  nstack_vm->labels_def = NULL;
+  nstack_vm->labels_used = NULL;
+  nstack_vm->scope = 0;
+  nstack_vm->next = label_context_stack_vm;
+  label_context_stack_vm = nstack_vm;
+
   /* Indicate no valid break/continue context by setting these variables
      to some non-null, non-label value.  We'll notice and emit the proper
      error message in c_finish_bc_stmt.  */
@@ -5640,7 +5764,7 @@ 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 ("%Jinline function %qD given attribute noinline", decl1, decl1);
+    warning (0, "%Jinline function %qD given attribute noinline", decl1, decl1);
 
   announce_function (decl1);
 
@@ -5661,50 +5785,93 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   DECL_INITIAL (decl1) = error_mark_node;
 
   /* If this definition isn't a prototype and we had a prototype declaration
-     before, copy the arg type info from that prototype.
-     But not if what we had before was a builtin function.  */
+     before, copy the arg type info from that prototype.  */
   old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
-  if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
-      && !DECL_BUILT_IN (old_decl)
-      && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
-                   TREE_TYPE (TREE_TYPE (old_decl)))
-      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
-    {
-      TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl),
-                                         TREE_TYPE (decl1));
-      current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
+  current_function_prototype_locus = UNKNOWN_LOCATION;
+  current_function_prototype_built_in = false;
+  current_function_prototype_arg_types = NULL_TREE;
+  if (TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
+    {
+      if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
+         && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
+                       TREE_TYPE (TREE_TYPE (old_decl))))
+       {
+         TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl),
+                                             TREE_TYPE (decl1));
+         current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
+         current_function_prototype_built_in
+           = C_DECL_BUILTIN_PROTOTYPE (old_decl);
+         current_function_prototype_arg_types
+           = TYPE_ARG_TYPES (TREE_TYPE (decl1));
+       }
+      if (TREE_PUBLIC (decl1))
+       {
+         /* If there is an external prototype declaration of this
+            function, record its location but do not copy information
+            to this decl.  This may be an invisible declaration
+            (built-in or in a scope which has finished) or simply
+            have more refined argument types than any declaration
+            found above.  */
+         struct c_binding *b;
+         for (b = I_SYMBOL_BINDING (DECL_NAME (decl1)); b; b = b->shadowed)
+           if (B_IN_SCOPE (b, external_scope))
+             break;
+         if (b)
+           {
+             tree ext_decl, ext_type;
+             ext_decl = b->decl;
+             ext_type = b->type ? b->type : TREE_TYPE (ext_decl);
+             if (TREE_CODE (ext_type) == FUNCTION_TYPE
+                 && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
+                               TREE_TYPE (ext_type)))
+               {
+                 current_function_prototype_locus
+                   = DECL_SOURCE_LOCATION (ext_decl);
+                 current_function_prototype_built_in
+                   = C_DECL_BUILTIN_PROTOTYPE (ext_decl);
+                 current_function_prototype_arg_types
+                   = TYPE_ARG_TYPES (ext_type);
+               }
+           }
+       }
     }
 
   /* Optionally warn of old-fashioned def with no previous prototype.  */
   if (warn_strict_prototypes
+      && old_decl != error_mark_node
       && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
       && C_DECL_ISNT_PROTOTYPE (old_decl))
-    warning ("function declaration isn%'t a prototype");
+    warning (0, "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))
+          && !MAIN_NAME_P (DECL_NAME (decl1))
           && C_DECL_ISNT_PROTOTYPE (old_decl))
-    warning ("%Jno previous prototype for %qD", decl1, decl1);
+    warning (0, "%Jno previous prototype for %qD", decl1, decl1);
   /* Optionally warn of any def with no previous prototype
      if the function has already been used.  */
   else if (warn_missing_prototypes
-          && old_decl != 0 && TREE_USED (old_decl)
+          && old_decl != 0
+          && old_decl != error_mark_node
+          && TREE_USED (old_decl)
           && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
-    warning ("%J%qD was used with no prototype before its definition",
+    warning (0, "%J%qD was used with no prototype before its definition",
             decl1, 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 ("%Jno previous declaration for %qD", decl1, decl1);
+          && !MAIN_NAME_P (DECL_NAME (decl1)))
+    warning (0, "%Jno previous declaration for %qD", decl1, decl1);
   /* Optionally warn of any def with no previous declaration
      if the function has already been used.  */
   else if (warn_missing_declarations
-          && old_decl != 0 && TREE_USED (old_decl)
+          && old_decl != 0
+          && old_decl != error_mark_node
+          && TREE_USED (old_decl)
           && C_DECL_IMPLICIT (old_decl))
-    warning ("%J%qD was used with no declaration before its definition",
+    warning (0, "%J%qD was used with no declaration before its definition",
             decl1, decl1);
 
   /* This is a definition, not a reference.
@@ -5782,7 +5949,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
       if (argct > 0 && (argct < 2 || argct > 3))
        pedwarn ("%J%qD takes only zero or two arguments", decl1, decl1);
 
-      if (! TREE_PUBLIC (decl1))
+      if (!TREE_PUBLIC (decl1))
        pedwarn ("%J%qD is normally a non-static function", decl1, decl1);
     }
 
@@ -5842,7 +6009,7 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
      its parameter list).  */
   else if (warn_traditional && !in_system_header && !current_function_scope
           && arg_info->types != error_mark_node)
-    warning ("%Jtraditional C rejects ISO C style function definitions",
+    warning (0, "%Jtraditional C rejects ISO C style function definitions",
             fndecl);
 
   /* Now make all the parameter declarations visible in the function body.
@@ -5893,8 +6060,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
     gcc_assert (TREE_CODE (b->decl) != PARM_DECL || !DECL_WEAK (b->decl));
 #endif
 
-  if (warn_old_style_definition && !in_system_header)
-    warning ("%Jold-style function definition", fndecl);
+  if (!in_system_header)
+    warning (OPT_Wold_style_definition, "%Jold-style function definition", fndecl);
 
   /* Match each formal parameter name with its declaration.  Save each
      decl in the appropriate TREE_PURPOSE slot of the parmids chain.  */
@@ -5943,7 +6110,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
          if (flag_isoc99)
            pedwarn ("%Jtype of %qD defaults to %<int%>", decl, decl);
          else if (extra_warnings)
-           warning ("%Jtype of %qD defaults to %<int%>", decl, decl);
+           warning (0, "%Jtype of %qD defaults to %<int%>", decl, decl);
        }
 
       TREE_PURPOSE (parm) = decl;
@@ -5959,13 +6126,14 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
       if (TREE_CODE (parm) != PARM_DECL)
        continue;
 
-      if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
+      if (TREE_TYPE (parm) != error_mark_node
+         && !COMPLETE_TYPE_P (TREE_TYPE (parm)))
        {
          error ("%Jparameter %qD has incomplete type", parm, parm);
          TREE_TYPE (parm) = error_mark_node;
        }
 
-      if (! DECL_WEAK (parm))
+      if (!DECL_WEAK (parm))
        {
          error ("%Jdeclaration for parameter %qD but no such parameter",
                 parm, parm);
@@ -6005,11 +6173,11 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
      set the DECL_ARG_TYPE of each argument according to
      the type previously specified, and report any mismatches.  */
 
-  if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+  if (current_function_prototype_arg_types)
     {
       tree type;
       for (parm = DECL_ARGUMENTS (fndecl),
-            type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+            type = current_function_prototype_arg_types;
           parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type))
                             != void_type_node));
           parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
@@ -6017,16 +6185,22 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
          if (parm == 0 || type == 0
              || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
            {
-             error ("number of arguments doesn%'t match prototype");
-             error ("%Hprototype declaration",
-                    &current_function_prototype_locus);
+             if (current_function_prototype_built_in)
+               warning (0, "number of arguments doesn%'t match "
+                        "built-in prototype");
+             else
+               {
+                 error ("number of arguments doesn%'t match prototype");
+                 error ("%Hprototype declaration",
+                        &current_function_prototype_locus);
+               }
              break;
            }
          /* Type for passing arg must be consistent with that
             declared for the arg.  ISO C says we take the unqualified
             type for parameters declared with qualified type.  */
-         if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
-                          TYPE_MAIN_VARIANT (TREE_VALUE (type))))
+         if (!comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
+                         TYPE_MAIN_VARIANT (TREE_VALUE (type))))
            {
              if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
                  == TYPE_MAIN_VARIANT (TREE_VALUE (type)))
@@ -6046,17 +6220,33 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
 
                  if (pedantic)
                    {
-                     pedwarn ("promoted argument %qD "
-                              "doesn%'t match prototype", parm);
-                     pedwarn ("%Hprototype declaration",
-                              &current_function_prototype_locus);
+                     /* ??? 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);
+                       }
                    }
                }
              else
                {
-                 error ("argument %qD doesn%'t match prototype", parm);
-                 error ("%Hprototype declaration",
-                        &current_function_prototype_locus);
+                 if (current_function_prototype_built_in)
+                   warning (0, "argument %qD doesn%'t match "
+                            "built-in prototype", parm);
+                 else
+                   {
+                     error ("argument %qD doesn%'t match prototype", parm);
+                     error ("%Hprototype declaration",
+                            &current_function_prototype_locus);
+                   }
                }
            }
        }
@@ -6153,8 +6343,11 @@ store_parm_decls (void)
   DECL_SAVED_TREE (fndecl) = push_stmt_list ();
 
   /* ??? Insert the contents of the pending sizes list into the function
-     to be evaluated.  This just changes mis-behavior until assign_parms
-     phase ordering problems are resolved.  */
+     to be evaluated.  The only reason left to have this is
+       void foo(int n, int array[n++])
+     because we throw away the array type in favor of a pointer type, and
+     thus won't naturally see the SAVE_EXPR containing the increment.  All
+     other pending sizes would be handled by gimplify_parameters.  */
   {
     tree t;
     for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t))
@@ -6196,6 +6389,9 @@ finish_function (void)
 {
   tree fndecl = current_function_decl;
 
+  label_context_stack_se = label_context_stack_se->next;
+  label_context_stack_vm = label_context_stack_vm->next;
+
   if (TREE_CODE (fndecl) == FUNCTION_DECL
       && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
     {
@@ -6230,7 +6426,23 @@ finish_function (void)
       else
        {
          if (flag_isoc99)
-           c_finish_return (integer_zero_node);
+           {
+             tree stmt = c_finish_return (integer_zero_node);
+#ifdef USE_MAPPED_LOCATION
+             /* 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);
+#else
+             /* Hack.  We don't want the middle-end to warn that this
+                return is unreachable, so put the statement on the
+                special line 0.  */
+             annotate_with_file_line (stmt, input_filename, 0);
+#endif
+           }
        }
     }
 
@@ -6243,7 +6455,7 @@ finish_function (void)
   if (warn_return_type
       && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
       && !current_function_returns_value && !current_function_returns_null
-      /* Don't complain if we abort.  */
+      /* Don't complain if we are no-return.  */
       && !current_function_returns_abnormally
       /* Don't warn for main().  */
       && !MAIN_NAME_P (DECL_NAME (fndecl))
@@ -6252,14 +6464,14 @@ finish_function (void)
       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
         inline function, as we might never be compiled separately.  */
       && DECL_INLINE (fndecl))
-    warning ("no return statement in function returning non-void");
+    warning (0, "no return statement in function returning non-void");
 
   /* With just -Wextra, complain only if function returns both with
      and without a value.  */
   if (extra_warnings
       && current_function_returns_value
       && current_function_returns_null)
-    warning ("this function may return with or without a value");
+    warning (0, "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.  */
@@ -6281,7 +6493,8 @@ finish_function (void)
      until their parent function is genericized.  Since finalizing
      requires GENERIC, delay that as well.  */
 
-  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
+  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node
+      && !undef_nested_function)
     {
       if (!decl_function_context (fndecl))
         {
@@ -6307,6 +6520,9 @@ finish_function (void)
         }
     }
 
+  if (!decl_function_context (fndecl))
+    undef_nested_function = false;
+
   /* We're leaving the context of this function, so zap cfun.
      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
      tree_rest_of_compilation.  */
@@ -6324,7 +6540,7 @@ c_expand_body (tree fndecl)
       || DECL_INITIAL (fndecl) == error_mark_node)
     return;
 
-  tree_rest_of_compilation (fndecl, false);
+  tree_rest_of_compilation (fndecl);
 
   if (DECL_STATIC_CONSTRUCTOR (fndecl)
       && targetm.have_ctors_dtors)
@@ -6595,6 +6811,8 @@ build_id_declarator (tree ident)
   ret->kind = cdk_id;
   ret->declarator = 0;
   ret->u.id = ident;
+  /* Default value - may get reset to a more precise location. */
+  ret->id_loc = input_location;
   return ret;
 }
 
@@ -6636,8 +6854,11 @@ build_null_declspecs (void)
   ret->attrs = 0;
   ret->typespec_word = cts_none;
   ret->storage_class = csc_none;
+  ret->declspecs_seen_p = false;
+  ret->type_seen_p = false;
   ret->non_sc_seen_p = false;
   ret->typedef_p = false;
+  ret->tag_defined_p = false;
   ret->explicit_signed_p = false;
   ret->deprecated_p = false;
   ret->default_int_p = false;
@@ -6664,6 +6885,7 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
   enum rid i;
   bool dupe = false;
   specs->non_sc_seen_p = true;
+  specs->declspecs_seen_p = true;
   gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
              && C_IS_RESERVED_WORD (qual));
   i = C_RID_CODE (qual);
@@ -6685,7 +6907,7 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
       gcc_unreachable ();
     }
   if (dupe && pedantic && !flag_isoc99)
-    pedwarn ("duplicate %qs", IDENTIFIER_POINTER (qual));
+    pedwarn ("duplicate %qE", qual);
   return specs;
 }
 
@@ -6693,9 +6915,12 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
    returning SPECS.  */
 
 struct c_declspecs *
-declspecs_add_type (struct c_declspecs *specs, tree type)
+declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
 {
+  tree type = spec.spec;
   specs->non_sc_seen_p = true;
+  specs->declspecs_seen_p = true;
+  specs->type_seen_p = true;
   if (TREE_DEPRECATED (type))
     specs->deprecated_p = true;
 
@@ -6817,7 +7042,7 @@ declspecs_add_type (struct c_declspecs *specs, tree type)
              break;
            case RID_COMPLEX:
              dupe = specs->complex_p;
-             if (pedantic && !flag_isoc99)
+             if (pedantic && !flag_isoc99 && !in_system_header)
                pedwarn ("ISO C90 does not support complex types");
              if (specs->typespec_word == cts_void)
                error ("both %<complex%> and %<void%> in "
@@ -6833,7 +7058,7 @@ declspecs_add_type (struct c_declspecs *specs, tree type)
            }
 
          if (dupe)
-           error ("duplicate %qs", IDENTIFIER_POINTER (type));
+           error ("duplicate %qE", type);
 
          return specs;
        }
@@ -6962,15 +7187,20 @@ declspecs_add_type (struct c_declspecs *specs, tree type)
     {
       tree t = lookup_name (type);
       if (!t || TREE_CODE (t) != TYPE_DECL)
-       error ("%qs fails to be a typedef or built in type",
-              IDENTIFIER_POINTER (type));
+       error ("%qE fails to be a typedef or built in type", type);
       else if (TREE_TYPE (t) == error_mark_node)
        ;
       else
        specs->type = TREE_TYPE (t);
     }
   else if (TREE_CODE (type) != ERROR_MARK)
-    specs->type = type;
+    {
+      if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref)
+       specs->tag_defined_p = true;
+      if (spec.kind == ctsk_typeof)
+       specs->typedef_p = true;
+      specs->type = type;
+    }
 
   return specs;
 }
@@ -6984,12 +7214,12 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
   enum rid i;
   enum c_storage_class n = csc_none;
   bool dupe = false;
+  specs->declspecs_seen_p = true;
   gcc_assert (TREE_CODE (scspec) == IDENTIFIER_NODE
              && C_IS_RESERVED_WORD (scspec));
   i = C_RID_CODE (scspec);
   if (extra_warnings && specs->non_sc_seen_p)
-    warning ("%qs is not at beginning of declaration",
-            IDENTIFIER_POINTER (scspec));
+    warning (0, "%qE is not at beginning of declaration", scspec);
   switch (i)
     {
     case RID_INLINE:
@@ -7038,7 +7268,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
   if (n != csc_none && n == specs->storage_class)
     dupe = true;
   if (dupe)
-    error ("duplicate %qs", IDENTIFIER_POINTER (scspec));
+    error ("duplicate %qE", scspec);
   if (n != csc_none)
     {
       if (specs->storage_class != csc_none && n != specs->storage_class)
@@ -7050,8 +7280,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
          specs->storage_class = n;
          if (n != csc_extern && n != csc_static && specs->thread_p)
            {
-             error ("%<__thread%> used with %qs",
-                    IDENTIFIER_POINTER (scspec));
+             error ("%<__thread%> used with %qE", scspec);
              specs->thread_p = false;
            }
        }
@@ -7066,6 +7295,7 @@ struct c_declspecs *
 declspecs_add_attrs (struct c_declspecs *specs, tree attrs)
 {
   specs->attrs = chainon (attrs, specs->attrs);
+  specs->declspecs_seen_p = true;
   return specs;
 }
 
@@ -7295,11 +7525,6 @@ 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 ();
-
-  /* Presently this has to happen after cgraph_optimize.
-     FIXME: shouldn't be the front end's responsibility to call this.  */
-  if (flag_mudflap)
-    mudflap_finish_file ();
 }
 
 #include "gt-c-decl.h"