OSDN Git Service

* c-decl.c (c_decode_option): Don't handle -lang-objc.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index d80e3d4..98aae30 100644 (file)
@@ -19,7 +19,6 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-
 /* Process declarations and symbol lookup for C front end.
    Also constructs types; the standard scalar types at initialization,
    and structure, union, array and enum types when they are declared.  */
 /* Process declarations and symbol lookup for C front end.
    Also constructs types; the standard scalar types at initialization,
    and structure, union, array and enum types when they are declared.  */
@@ -42,11 +41,7 @@ Boston, MA 02111-1307, USA.  */
 #include "defaults.h"
 #include "ggc.h"
 #include "tm_p.h"
 #include "defaults.h"
 #include "ggc.h"
 #include "tm_p.h"
-
-#if USE_CPPLIB
 #include "cpplib.h"
 #include "cpplib.h"
-extern cpp_reader parse_in;
-#endif
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -74,10 +69,27 @@ enum decl_context
 #ifndef WCHAR_TYPE
 #define WCHAR_TYPE "int"
 #endif
 #ifndef WCHAR_TYPE
 #define WCHAR_TYPE "int"
 #endif
-\f
-/* Do GC.  */
-int ggc_p = 1;
 
 
+#ifndef WINT_TYPE
+#define WINT_TYPE "unsigned int"
+#endif
+
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
+                    ? "int"                                    \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long int"                            \
+                       : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
+                    ? "unsigned int"                           \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long unsigned int"                   \
+                       : "long long unsigned int"))
+#endif
+\f
 /* Nonzero if we have seen an invalid cross reference
    to a struct, union, or enum, but not yet printed the message.  */
 
 /* Nonzero if we have seen an invalid cross reference
    to a struct, union, or enum, but not yet printed the message.  */
 
@@ -122,6 +134,19 @@ static tree current_function_parm_tags;
 static const char *current_function_prototype_file;
 static int current_function_prototype_line;
 
 static const char *current_function_prototype_file;
 static int current_function_prototype_line;
 
+/* The current statement tree.  */
+
+static struct stmt_tree_s c_stmt_tree;
+
+/* The current scope statement stack.  */
+
+static tree c_scope_stmt_stack;
+
+/* Nonzero if __FUNCTION__ and its ilk have been declared in this
+   function.  */
+
+static int c_function_name_declared_p;
+
 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
    that have names.  Here so we can clear out their names' definitions
    at the end of the function.  */
 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
    that have names.  Here so we can clear out their names' definitions
    at the end of the function.  */
@@ -223,7 +248,7 @@ struct binding_level
     /* Nonzero means make a BLOCK if this level has any subblocks.  */
     char keep_if_subblocks;
 
     /* Nonzero means make a BLOCK if this level has any subblocks.  */
     char keep_if_subblocks;
 
-    /* Number of decls in `names' that have incomplete 
+    /* Number of decls in `names' that have incomplete
        structure or union types.  */
     int n_incomplete;
 
        structure or union types.  */
     int n_incomplete;
 
@@ -234,7 +259,7 @@ struct binding_level
   };
 
 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
   };
 
 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
-  
+
 /* The binding level currently in effect.  */
 
 static struct binding_level *current_binding_level;
 /* The binding level currently in effect.  */
 
 static struct binding_level *current_binding_level;
@@ -263,7 +288,7 @@ static int keep_next_level_flag;
    if it has subblocks.  */
 
 static int keep_next_if_subblocks;
    if it has subblocks.  */
 
 static int keep_next_if_subblocks;
-  
+
 /* The chain of outer levels of label scopes.
    This uses the same data structure used for binding levels,
    but it works differently: each link in the chain records
 /* The chain of outer levels of label scopes.
    This uses the same data structure used for binding levels,
    but it works differently: each link in the chain records
@@ -293,6 +318,7 @@ static tree grokdeclarator          PARAMS ((tree, tree, enum decl_context,
 static tree grokparms                  PARAMS ((tree, int));
 static void layout_array_type          PARAMS ((tree));
 static tree c_make_fname_decl           PARAMS ((tree, const char *, int));
 static tree grokparms                  PARAMS ((tree, int));
 static void layout_array_type          PARAMS ((tree));
 static tree c_make_fname_decl           PARAMS ((tree, const char *, int));
+static void c_expand_body               PARAMS ((tree, int));
 \f
 /* C-specific option variables.  */
 
 \f
 /* C-specific option variables.  */
 
@@ -313,31 +339,27 @@ int flag_short_wchar;
 
 int flag_no_asm;
 
 
 int flag_no_asm;
 
-/* Nonzero means don't recognize any builtin functions.  */
-
-int flag_no_builtin;
-
-/* Nonzero means don't recognize the non-ANSI builtin functions.
-   -ansi sets this.  */
-
-int flag_no_nonansi_builtin;
-
 /* Nonzero means do some things the same way PCC does.  */
 
 int flag_traditional;
 
 /* Nonzero means do some things the same way PCC does.  */
 
 int flag_traditional;
 
-/* Nonzero means use the ISO C99 dialect of C.  */
+/* Nonzero means enable C89 Amendment 1 features.  */
 
 
-int flag_isoc99 = 0;
+int flag_isoc94 = 0;
 
 
-/* Nonzero means accept digraphs.  */
+/* Nonzero means use the ISO C99 dialect of C.  */
 
 
-int flag_digraphs = 1;
+int flag_isoc99 = 0;
 
 /* Nonzero means that we have builtin functions, and main is an int */
 
 int flag_hosted = 1;
 
 
 /* Nonzero means that we have builtin functions, and main is an int */
 
 int flag_hosted = 1;
 
+/* Nonzero means add default format_arg attributes for functions not
+   in ISO C.  */
+
+int flag_noniso_default_format_attributes = 1;
+
 /* Nonzero means to allow single precision math even if we're generally
    being traditional.  */
 int flag_allow_single_precision = 0;
 /* Nonzero means to allow single precision math even if we're generally
    being traditional.  */
 int flag_allow_single_precision = 0;
@@ -347,7 +369,7 @@ int flag_allow_single_precision = 0;
 int flag_signed_bitfields = 1;
 int explicit_flag_signed_bitfields = 0;
 
 int flag_signed_bitfields = 1;
 int explicit_flag_signed_bitfields = 0;
 
-/* Nonzero means warn about use of implicit int. */
+/* Nonzero means warn about use of implicit int.  */
 
 int warn_implicit_int;
 
 
 int warn_implicit_int;
 
@@ -356,9 +378,9 @@ int warn_implicit_int;
 int warn_long_long = 1;
 
 /* Nonzero means message about use of implicit function declarations;
 int warn_long_long = 1;
 
 /* Nonzero means message about use of implicit function declarations;
- 1 means warning; 2 means error. */
+ 1 means warning; 2 means error.  */
 
 
-int mesg_implicit_function_declaration;
+int mesg_implicit_function_declaration = -1;
 
 /* Nonzero means give string constants the type `const char *'
    to get extra warnings from them.  These warnings will be too numerous
 
 /* Nonzero means give string constants the type `const char *'
    to get extra warnings from them.  These warnings will be too numerous
@@ -377,9 +399,9 @@ int warn_cast_qual;
 
 int warn_bad_function_cast;
 
 
 int warn_bad_function_cast;
 
-/* Warn about functions which might be candidates for attribute noreturn. */
+/* Warn about functions which might be candidates for format attributes.  */
 
 
-int warn_missing_noreturn;
+int warn_missing_format_attribute;
 
 /* Warn about traditional constructs whose meanings changed in ANSI C.  */
 
 
 /* Warn about traditional constructs whose meanings changed in ANSI C.  */
 
@@ -444,14 +466,14 @@ int warn_main;
 
 /* Warn about #pragma directives that are not recognised.  */
 
 
 /* Warn about #pragma directives that are not recognised.  */
 
-int warn_unknown_pragmas = 0; /* Tri state variable.  */  
+int warn_unknown_pragmas = 0; /* Tri state variable.  */
 
 /* Warn about comparison of signed and unsigned values.
    If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified.  */
 
 int warn_sign_compare = -1;
 
 
 /* Warn about comparison of signed and unsigned values.
    If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified.  */
 
 int warn_sign_compare = -1;
 
-/* Warn about testing equality of floating point numbers. */
+/* Warn about testing equality of floating point numbers.  */
 
 int warn_float_equal = 0;
 
 
 int warn_float_equal = 0;
 
@@ -459,10 +481,6 @@ int warn_float_equal = 0;
 
 int warn_multichar = 1;
 
 
 int warn_multichar = 1;
 
-/* Wrapper since C and C++ expand_expr_stmt are different. */
-
-expand_expr_stmt_fn lang_expand_expr_stmt = c_expand_expr_stmt;
-
 /* The variant of the C language being processed.  */
 
 c_language_kind c_language = clk_c;
 /* The variant of the C language being processed.  */
 
 c_language_kind c_language = clk_c;
@@ -477,25 +495,22 @@ int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
 /* Decode the string P as a language-specific option for C.
    Return the number of strings consumed.  Should not complain
    if it does not recognise the option.  */
 /* Decode the string P as a language-specific option for C.
    Return the number of strings consumed.  Should not complain
    if it does not recognise the option.  */
-   
+
 int
 c_decode_option (argc, argv)
      int argc ATTRIBUTE_UNUSED;
      char **argv;
 {
   int strings_processed;
 int
 c_decode_option (argc, argv)
      int argc ATTRIBUTE_UNUSED;
      char **argv;
 {
   int strings_processed;
+  const char *option_value = NULL;
   char *p = argv[0];
   char *p = argv[0];
-#if USE_CPPLIB
-  strings_processed = cpp_handle_option (&parse_in, argc, argv);
-#else
-  strings_processed = 0;
-#endif /* ! USE_CPPLIB */
+
+  strings_processed = cpp_handle_option (parse_in, argc, argv);
 
   if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
     {
       flag_traditional = 1;
       flag_writable_strings = 1;
 
   if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
     {
       flag_traditional = 1;
       flag_writable_strings = 1;
-      flag_digraphs = 0;
     }
   else if (!strcmp (p, "-fallow-single-precision"))
     flag_allow_single_precision = 1;
     }
   else if (!strcmp (p, "-fallow-single-precision"))
     flag_allow_single_precision = 1;
@@ -516,7 +531,6 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
-      flag_digraphs = 1;
     }
   else if (!strncmp (p, "-std=", 5))
     {
     }
   else if (!strncmp (p, "-std=", 5))
     {
@@ -536,19 +550,19 @@ c_decode_option (argc, argv)
          || !strcmp (argstart, "c89"))
        {
        iso_1990:
          || !strcmp (argstart, "c89"))
        {
        iso_1990:
-         flag_digraphs = 0;
-       iso_1990_digraphs:
+         flag_isoc94 = 0;
+       iso_1994:
          flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
          flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
+         flag_noniso_default_format_attributes = 0;
          flag_isoc99 = 0;
        }
       else if (!strcmp (argstart, "iso9899:199409"))
        {
          flag_isoc99 = 0;
        }
       else if (!strcmp (argstart, "iso9899:199409"))
        {
-         flag_digraphs = 1;
-         /* ??? The other changes since ISO C 1990 are not supported.  */
-         goto iso_1990_digraphs;
+         flag_isoc94 = 1;
+         goto iso_1994;
        }
       else if (!strcmp (argstart, "iso9899:199x")
               || !strcmp (argstart, "iso9899:1999")
        }
       else if (!strcmp (argstart, "iso9899:199x")
               || !strcmp (argstart, "iso9899:1999")
@@ -559,8 +573,9 @@ c_decode_option (argc, argv)
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
+         flag_noniso_default_format_attributes = 0;
          flag_isoc99 = 1;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
+         flag_isoc94 = 1;
        }
       else if (!strcmp (argstart, "gnu89"))
        {
        }
       else if (!strcmp (argstart, "gnu89"))
        {
@@ -568,8 +583,9 @@ c_decode_option (argc, argv)
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
+         flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 0;
          flag_isoc99 = 0;
-         flag_digraphs = 1;
+         flag_isoc94 = 0;
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
        {
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
        {
@@ -577,8 +593,9 @@ c_decode_option (argc, argv)
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
+         flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 1;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
+         flag_isoc94 = 1;
        }
       else
        error ("unknown C standard `%s'", argstart);
        }
       else
        error ("unknown C standard `%s'", argstart);
@@ -631,6 +648,14 @@ c_decode_option (argc, argv)
     flag_no_builtin = 0;
   else if (!strcmp (p, "-fno-builtin"))
     flag_no_builtin = 1;
     flag_no_builtin = 0;
   else if (!strcmp (p, "-fno-builtin"))
     flag_no_builtin = 1;
+  else if ((option_value
+           = skip_leading_substring (p, "-fdump-translation-unit-")))
+    {
+      if (p[22] == '\0')
+       error ("no file specified with -fdump-translation-unit");
+      else
+       flag_dump_translation_unit = option_value;
+    }
   else if (!strcmp (p, "-ansi"))
     goto iso_1990;
   else if (!strcmp (p, "-Werror-implicit-function-declaration"))
   else if (!strcmp (p, "-ansi"))
     goto iso_1990;
   else if (!strcmp (p, "-Werror-implicit-function-declaration"))
@@ -647,7 +672,7 @@ c_decode_option (argc, argv)
     {
       warn_implicit_int = 1;
       if (mesg_implicit_function_declaration != 2)
     {
       warn_implicit_int = 1;
       if (mesg_implicit_function_declaration != 2)
-        mesg_implicit_function_declaration = 1;
+       mesg_implicit_function_declaration = 1;
     }
   else if (!strcmp (p, "-Wno-implicit"))
     warn_implicit_int = 0, mesg_implicit_function_declaration = 0;
     }
   else if (!strcmp (p, "-Wno-implicit"))
     warn_implicit_int = 0, mesg_implicit_function_declaration = 0;
@@ -671,6 +696,10 @@ c_decode_option (argc, argv)
     warn_missing_noreturn = 1;
   else if (!strcmp (p, "-Wno-missing-noreturn"))
     warn_missing_noreturn = 0;
     warn_missing_noreturn = 1;
   else if (!strcmp (p, "-Wno-missing-noreturn"))
     warn_missing_noreturn = 0;
+  else if (!strcmp (p, "-Wmissing-format-attribute"))
+    warn_missing_format_attribute = 1;
+  else if (!strcmp (p, "-Wno-missing-format-attribute"))
+    warn_missing_format_attribute = 0;
   else if (!strcmp (p, "-Wpointer-arith"))
     warn_pointer_arith = 1;
   else if (!strcmp (p, "-Wno-pointer-arith"))
   else if (!strcmp (p, "-Wpointer-arith"))
     warn_pointer_arith = 1;
   else if (!strcmp (p, "-Wno-pointer-arith"))
@@ -721,6 +750,10 @@ c_decode_option (argc, argv)
     warn_return_type = 1;
   else if (!strcmp (p, "-Wno-return-type"))
     warn_return_type = 0;
     warn_return_type = 1;
   else if (!strcmp (p, "-Wno-return-type"))
     warn_return_type = 0;
+  else if (!strcmp (p, "-Wsequence-point"))
+    warn_sequence_point = 1;
+  else if (!strcmp (p, "-Wno-sequence-point"))
+    warn_sequence_point = 0;
   else if (!strcmp (p, "-Wcomment"))
     ; /* cpp handles this one.  */
   else if (!strcmp (p, "-Wno-comment"))
   else if (!strcmp (p, "-Wcomment"))
     ; /* cpp handles this one.  */
   else if (!strcmp (p, "-Wno-comment"))
@@ -782,6 +815,7 @@ c_decode_option (argc, argv)
       warn_format = 1;
       warn_char_subscripts = 1;
       warn_parentheses = 1;
       warn_format = 1;
       warn_char_subscripts = 1;
       warn_parentheses = 1;
+      warn_sequence_point = 1;
       warn_missing_braces = 1;
       /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn
         it off only if it's not explicit.  */
       warn_missing_braces = 1;
       /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn
         it off only if it's not explicit.  */
@@ -825,11 +859,19 @@ print_lang_identifier (file, node, indent)
   print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
   print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
   print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
   print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
   print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
   print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
+  if (C_IS_RESERVED_WORD (node))
+    {
+      tree rid = ridpointers[C_RID_CODE (node)];
+      indent_to (file, indent + 4);
+      fprintf (file, "rid ");
+      fprintf (file, HOST_PTR_PRINTF, (void *)rid);
+      fprintf (file, " \"%s\"", IDENTIFIER_POINTER (rid));
+    }
 }
 \f
 /* Hook called at end of compilation to assume 1 elt
 }
 \f
 /* Hook called at end of compilation to assume 1 elt
-   for a top-level array decl that wasn't complete before.  */
-   
+   for a top-level tentative array defn that wasn't complete before.  */
+
 void
 finish_incomplete_decl (decl)
      tree decl;
 void
 finish_incomplete_decl (decl)
      tree decl;
@@ -839,10 +881,10 @@ finish_incomplete_decl (decl)
       tree type = TREE_TYPE (decl);
       if (type != error_mark_node
          && TREE_CODE (type) == ARRAY_TYPE
       tree type = TREE_TYPE (decl);
       if (type != error_mark_node
          && TREE_CODE (type) == ARRAY_TYPE
+         && ! DECL_EXTERNAL (decl)
          && TYPE_DOMAIN (type) == 0)
        {
          && TYPE_DOMAIN (type) == 0)
        {
-         if (! DECL_EXTERNAL (decl))
-           warning_with_decl (decl, "array `%s' assumed to have one element");
+         warning_with_decl (decl, "array `%s' assumed to have one element");
 
          complete_array_type (type, NULL_TREE, 1);
 
 
          complete_array_type (type, NULL_TREE, 1);
 
@@ -853,8 +895,7 @@ finish_incomplete_decl (decl)
 \f
 /* Create a new `struct binding_level'.  */
 
 \f
 /* Create a new `struct binding_level'.  */
 
-static
-struct binding_level *
+static struct binding_level *
 make_binding_level ()
 {
   /* NOSTRICT */
 make_binding_level ()
 {
   /* NOSTRICT */
@@ -955,7 +996,7 @@ pushlevel (tag_transparent)
   keep_next_if_subblocks = 0;
 }
 
   keep_next_if_subblocks = 0;
 }
 
-/* Clear the limbo values of all identifiers defined in BLOCK or a subblock. */
+/* Clear the limbo values of all identifiers defined in BLOCK or a subblock.  */
 
 static void
 clear_limbo_values (block)
 
 static void
 clear_limbo_values (block)
@@ -970,7 +1011,7 @@ clear_limbo_values (block)
   for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
     clear_limbo_values (tem);
 }
   for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
     clear_limbo_values (tem);
 }
-    
+
 /* Exit a binding level.
    Pop the level off, and restore the state of the identifier-decl mappings
    that were in effect when this level was entered.
 /* Exit a binding level.
    Pop the level off, and restore the state of the identifier-decl mappings
    that were in effect when this level was entered.
@@ -1059,14 +1100,14 @@ poplevel (keep, reverse, functionbody)
        if (DECL_ABSTRACT_ORIGIN (decl) != 0
            && DECL_ABSTRACT_ORIGIN (decl) != decl)
          TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
        if (DECL_ABSTRACT_ORIGIN (decl) != 0
            && DECL_ABSTRACT_ORIGIN (decl) != decl)
          TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
-       else if (DECL_SAVED_INSNS (decl) != 0)
-         {
-           push_function_context ();
-           output_inline_function (decl);
-           pop_function_context ();
-         }
       }
 
       }
 
+  /* We used to warn about unused variables in expand_end_bindings,
+     i.e. while generating RTL.  But in function-at-a-time mode we may
+     choose to never expand a function at all (e.g. auto inlining), so
+     we do this explicitly now.  */
+  warn_about_unused_variables (getdecls ());
+
   /* If there were any declarations or structure tags in that level,
      or if this level is a function body,
      create a BLOCK to record them for the life of this function.  */
   /* If there were any declarations or structure tags in that level,
      or if this level is a function body,
      create a BLOCK to record them for the life of this function.  */
@@ -1171,8 +1212,8 @@ poplevel (keep, reverse, functionbody)
   else if (block)
     {
       if (!block_previously_created)
   else if (block)
     {
       if (!block_previously_created)
-        current_binding_level->blocks
-          = chainon (current_binding_level->blocks, block);
+       current_binding_level->blocks
+         = chainon (current_binding_level->blocks, block);
     }
   /* If we did not make a block for the level just exited,
      any blocks made for inner levels
     }
   /* If we did not make a block for the level just exited,
      any blocks made for inner levels
@@ -1195,8 +1236,7 @@ poplevel (keep, reverse, functionbody)
      cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
      in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
      node which will represent the "scope" for these "parameter list local"
      cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
      in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
      node which will represent the "scope" for these "parameter list local"
-     tagged types.
-  */
+     tagged types.  */
 
   if (functionbody)
     for (link = tags; link; link = TREE_CHAIN (link))
 
   if (functionbody)
     for (link = tags; link; link = TREE_CHAIN (link))
@@ -1207,6 +1247,7 @@ poplevel (keep, reverse, functionbody)
 
   if (block)
     TREE_USED (block) = 1;
 
   if (block)
     TREE_USED (block) = 1;
+
   return block;
 }
 
   return block;
 }
 
@@ -1306,7 +1347,7 @@ pop_label_level ()
                            DECL_NAME (TREE_VALUE (link)));
            }
          else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
                            DECL_NAME (TREE_VALUE (link)));
            }
          else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
-           warning_with_decl (TREE_VALUE (link), 
+           warning_with_decl (TREE_VALUE (link),
                               "label `%s' defined but not used");
          IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
 
                               "label `%s' defined but not used");
          IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
 
@@ -1406,7 +1447,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
 
   if (DECL_P (olddecl))
     DECL_MACHINE_ATTRIBUTES (newdecl)
 
   if (DECL_P (olddecl))
     DECL_MACHINE_ATTRIBUTES (newdecl)
-      =  merge_machine_decl_attributes (olddecl, newdecl);
+      = merge_machine_decl_attributes (olddecl, newdecl);
 
   if (TREE_CODE (newtype) == ERROR_MARK
       || TREE_CODE (oldtype) == ERROR_MARK)
 
   if (TREE_CODE (newtype) == ERROR_MARK
       || TREE_CODE (oldtype) == ERROR_MARK)
@@ -1444,7 +1485,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                               "built-in function `%s' declared as non-function");
          else
            warning_with_decl (newdecl,
                               "built-in function `%s' declared as non-function");
          else
            warning_with_decl (newdecl,
-                            "built-in function `%s' declared as non-function");
+                              "built-in function `%s' declared as non-function");
        }
       else
        {
        }
       else
        {
@@ -1488,18 +1529,18 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
        }
       else if (!types_match)
        {
        }
       else if (!types_match)
        {
-          /* Accept the return type of the new declaration if same modes.  */
+         /* Accept the return type of the new declaration if same modes.  */
          tree oldreturntype = TREE_TYPE (oldtype);
          tree newreturntype = TREE_TYPE (newtype);
 
          tree oldreturntype = TREE_TYPE (oldtype);
          tree newreturntype = TREE_TYPE (newtype);
 
-          if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
-            {
+         if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
+           {
              /* Function types may be shared, so we can't just modify
                 the return type of olddecl's function type.  */
              tree trytype
                = build_function_type (newreturntype,
                                       TYPE_ARG_TYPES (oldtype));
              /* Function types may be shared, so we can't just modify
                 the return type of olddecl's function type.  */
              tree trytype
                = build_function_type (newreturntype,
                                       TYPE_ARG_TYPES (oldtype));
-             
+
               types_match = comptypes (newtype, trytype);
              if (types_match)
                oldtype = trytype;
               types_match = comptypes (newtype, trytype);
              if (types_match)
                oldtype = trytype;
@@ -1517,11 +1558,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                 the return type of olddecl's function type.  */
              tree trytype
                = build_function_type (TREE_TYPE (oldtype),
                 the return type of olddecl's function type.  */
              tree trytype
                = build_function_type (TREE_TYPE (oldtype),
-                                      tree_cons (NULL_TREE, 
+                                      tree_cons (NULL_TREE,
                                                  TREE_VALUE (TYPE_ARG_TYPES (newtype)),
                                                  TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
                                                  TREE_VALUE (TYPE_ARG_TYPES (newtype)),
                                                  TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
-             
-              types_match = comptypes (newtype, trytype);
+
+             types_match = comptypes (newtype, trytype);
              if (types_match)
                oldtype = trytype;
            }
              if (types_match)
                oldtype = trytype;
            }
@@ -1656,11 +1697,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                            : "`%s' previously declared here"));
        }
       else if (TREE_CODE (newdecl) == TYPE_DECL
                            : "`%s' previously declared here"));
        }
       else if (TREE_CODE (newdecl) == TYPE_DECL
-               && (DECL_IN_SYSTEM_HEADER (olddecl) 
+               && (DECL_IN_SYSTEM_HEADER (olddecl)
                    || DECL_IN_SYSTEM_HEADER (newdecl)))
        {
          warning_with_decl (newdecl, "redefinition of `%s'");
                    || DECL_IN_SYSTEM_HEADER (newdecl)))
        {
          warning_with_decl (newdecl, "redefinition of `%s'");
-         warning_with_decl 
+         warning_with_decl
            (olddecl,
             ((DECL_INITIAL (olddecl)
               && current_binding_level == global_binding_level)
            (olddecl,
             ((DECL_INITIAL (olddecl)
               && current_binding_level == global_binding_level)
@@ -1693,7 +1734,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
              if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
                  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
                {
              if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
                  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
                {
-                 error_with_decl (newdecl, "prototype for `%s' follows and number of arguments doesn't match");
+                 error_with_decl (newdecl,
+                                  "prototype for `%s' follows and number of arguments doesn't match");
                  error_with_decl (olddecl, "non-prototype definition here");
                  errmsg = 1;
                  break;
                  error_with_decl (olddecl, "non-prototype definition here");
                  errmsg = 1;
                  break;
@@ -1740,8 +1782,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
            warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
 
          /* If warn_traditional, warn when a non-static function
            warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
 
          /* If warn_traditional, warn when a non-static function
-            declaration follows a static one. */
-         if (warn_traditional
+            declaration follows a static one.  */
+         if (warn_traditional && !in_system_header
              && TREE_CODE (olddecl) == FUNCTION_DECL
              && !TREE_PUBLIC (olddecl)
              && TREE_PUBLIC (newdecl))
              && TREE_CODE (olddecl) == FUNCTION_DECL
              && !TREE_PUBLIC (olddecl)
              && TREE_PUBLIC (newdecl))
@@ -1912,7 +1954,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
     }
 
   /* Merge the storage class information.  */
     }
 
   /* Merge the storage class information.  */
-  DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);    
+  DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);
   /* For functions, static overrides non-static.  */
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
   /* For functions, static overrides non-static.  */
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -1928,8 +1970,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
     }
   if (DECL_EXTERNAL (newdecl))
     {
     }
   if (DECL_EXTERNAL (newdecl))
     {
-      TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
-      DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
+      if (! different_binding_level)
+       {
+         /* Don't mess with these flags on local externs; they remain
+            external even if there's a declaration at file scope which
+            isn't.  */
+         TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
+         DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
+       }
       /* An extern decl does not override previous storage class.  */
       TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
       if (! DECL_EXTERNAL (newdecl))
       /* An extern decl does not override previous storage class.  */
       TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
       if (! DECL_EXTERNAL (newdecl))
@@ -1988,28 +2036,16 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
        }
     }
   if (different_binding_level)
        }
     }
   if (different_binding_level)
-    {
-      /* Don't output a duplicate symbol or debugging information for this
-        declaration.
-
-        Do not set TREE_ASM_WRITTEN for a FUNCTION_DECL since we may actually
-        just have two declarations without a definition.  VAR_DECLs may need
-        the same treatment, I'm not sure.  */
-      if (TREE_CODE (newdecl) == FUNCTION_DECL)
-       DECL_IGNORED_P (newdecl) = 1;
-      else
-       TREE_ASM_WRITTEN (newdecl) = DECL_IGNORED_P (newdecl) = 1;
-      return 0;
-    }
+    return 0;
 
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
      But preserve OLDDECL's DECL_UID.  */
   {
     register unsigned olddecl_uid = DECL_UID (olddecl);
 
 
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
      But preserve OLDDECL's DECL_UID.  */
   {
     register unsigned olddecl_uid = DECL_UID (olddecl);
 
-    bcopy ((char *) newdecl + sizeof (struct tree_common),
-          (char *) olddecl + sizeof (struct tree_common),
-          sizeof (struct tree_decl) - sizeof (struct tree_common));
+    memcpy ((char *) olddecl + sizeof (struct tree_common),
+           (char *) newdecl + sizeof (struct tree_common),
+           sizeof (struct tree_decl) - sizeof (struct tree_common));
     DECL_UID (olddecl) = olddecl_uid;
   }
 
     DECL_UID (olddecl) = olddecl_uid;
   }
 
@@ -2040,8 +2076,8 @@ pushdecl (x)
   /* A local extern declaration for a function doesn't constitute nesting.
      A local auto declaration does, since it's a forward decl
      for a nested function coming later.  */
   /* A local extern declaration for a function doesn't constitute nesting.
      A local auto declaration does, since it's a forward decl
      for a nested function coming later.  */
-  if (TREE_CODE (x) == FUNCTION_DECL && DECL_INITIAL (x) == 0
-      && DECL_EXTERNAL (x))
+  if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+      && DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x))
     DECL_CONTEXT (x) = 0;
 
   if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level
     DECL_CONTEXT (x) = 0;
 
   if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level
@@ -2160,23 +2196,23 @@ pushdecl (x)
          on a standard type by checking the current value of lineno.  */
 
       if (TREE_CODE (x) == TYPE_DECL)
          on a standard type by checking the current value of lineno.  */
 
       if (TREE_CODE (x) == TYPE_DECL)
-        {
-          if (DECL_SOURCE_LINE (x) == 0)
-            {
+       {
+         if (DECL_SOURCE_LINE (x) == 0)
+           {
              if (TYPE_NAME (TREE_TYPE (x)) == 0)
              if (TYPE_NAME (TREE_TYPE (x)) == 0)
-               TYPE_NAME (TREE_TYPE (x)) = x;
-            }
-          else if (TREE_TYPE (x) != error_mark_node
+               TYPE_NAME (TREE_TYPE (x)) = x;
+           }
+         else if (TREE_TYPE (x) != error_mark_node
                   && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
                   && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
-            {
-              tree tt = TREE_TYPE (x);
+           {
+             tree tt = TREE_TYPE (x);
              DECL_ORIGINAL_TYPE (x) = tt;
              DECL_ORIGINAL_TYPE (x) = tt;
-              tt = build_type_copy (tt);
-              TYPE_NAME (tt) = x;
+             tt = build_type_copy (tt);
+             TYPE_NAME (tt) = x;
              TREE_USED (tt) = TREE_USED (x);
              TREE_USED (tt) = TREE_USED (x);
-              TREE_TYPE (x) = tt;
-            }
-        }
+             TREE_TYPE (x) = tt;
+           }
+       }
 
       /* Multiple external decls of the same identifier ought to match.
         Check against both global declarations (when traditional) and out of
 
       /* Multiple external decls of the same identifier ought to match.
         Check against both global declarations (when traditional) and out of
@@ -2261,7 +2297,7 @@ pushdecl (x)
       if (b == global_binding_level)
        {
          /* Install a global value.  */
       if (b == global_binding_level)
        {
          /* Install a global value.  */
-         
+
          /* If the first global decl has external linkage,
             warn if we later see static one.  */
          if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))
          /* If the first global decl has external linkage,
             warn if we later see static one.  */
          if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))
@@ -2351,7 +2387,8 @@ pushdecl (x)
                      DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
                      DECL_RESULT (x) = DECL_RESULT (oldglobal);
                      TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
                      DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
                      DECL_RESULT (x) = DECL_RESULT (oldglobal);
                      TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
-                     DECL_ABSTRACT_ORIGIN (x) = DECL_ORIGIN (oldglobal);
+                     DECL_ABSTRACT_ORIGIN (x)
+                       = DECL_ABSTRACT_ORIGIN (oldglobal);
                    }
                  /* Inner extern decl is built-in if global one is.  */
                  if (DECL_BUILT_IN (oldglobal))
                    }
                  /* Inner extern decl is built-in if global one is.  */
                  if (DECL_BUILT_IN (oldglobal))
@@ -2367,7 +2404,8 @@ pushdecl (x)
                }
            }
 
                }
            }
 
-#if 0 /* This case is probably sometimes the right thing to do.  */
+#if 0
+         /* This case is probably sometimes the right thing to do.  */
          /* If we have a local external declaration,
             then any file-scope declaration should not
             have been static.  */
          /* If we have a local external declaration,
             then any file-scope declaration should not
             have been static.  */
@@ -2386,7 +2424,7 @@ pushdecl (x)
              && TREE_PUBLIC (x))
            {
              if (oldglobal == 0)
              && TREE_PUBLIC (x))
            {
              if (oldglobal == 0)
-               TREE_PUBLIC (name) = 1;
+               TREE_PUBLIC (name) = 1;
 
              /* Save this decl, so that we can do type checking against
                 other decls after it falls out of scope.
 
              /* Save this decl, so that we can do type checking against
                 other decls after it falls out of scope.
@@ -2424,7 +2462,7 @@ pushdecl (x)
                   /* No shadow warnings for vars made for inlining.  */
                   && ! DECL_FROM_INLINE (x))
            {
                   /* No shadow warnings for vars made for inlining.  */
                   && ! DECL_FROM_INLINE (x))
            {
-             char *id = IDENTIFIER_POINTER (name);
+             const char *id = IDENTIFIER_POINTER (name);
 
              if (TREE_CODE (x) == PARM_DECL
                  && current_binding_level->level_chain->parm_flag)
 
              if (TREE_CODE (x) == PARM_DECL
                  && current_binding_level->level_chain->parm_flag)
@@ -2496,9 +2534,11 @@ implicitly_declare (functionid)
   /* We used to reuse an old implicit decl here,
      but this loses with inline functions because it can clobber
      the saved decl chains.  */
   /* We used to reuse an old implicit decl here,
      but this loses with inline functions because it can clobber
      the saved decl chains.  */
-/*  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
+#if 0
+  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
     decl = IDENTIFIER_IMPLICIT_DECL (functionid);
     decl = IDENTIFIER_IMPLICIT_DECL (functionid);
-  else  */
+  else
+#endif
     decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
 
   /* Warn of implicit decl following explicit local extern decl.
     decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
 
   /* Warn of implicit decl following explicit local extern decl.
@@ -2525,15 +2565,8 @@ implicitly_declare (functionid)
 
   rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
 
 
   rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
 
-  if (mesg_implicit_function_declaration && implicit_warning)
-    {
-      if (mesg_implicit_function_declaration == 2)
-        error ("implicit declaration of function `%s'",
-                 IDENTIFIER_POINTER (functionid));
-      else
-        warning ("implicit declaration of function `%s'",
-                 IDENTIFIER_POINTER (functionid));
-    }
+  if (implicit_warning)
+    implicit_decl_warning (functionid);
   else if (warn_traditional && traditional_warning)
     warning ("function `%s' was previously declared within a block",
             IDENTIFIER_POINTER (functionid));
   else if (warn_traditional && traditional_warning)
     warning ("function `%s' was previously declared within a block",
             IDENTIFIER_POINTER (functionid));
@@ -2546,6 +2579,17 @@ implicitly_declare (functionid)
   return decl;
 }
 
   return decl;
 }
 
+void
+implicit_decl_warning (id)
+     tree id;
+{
+  const char *name = IDENTIFIER_POINTER (id);
+  if (mesg_implicit_function_declaration == 2)
+    error ("implicit declaration of function `%s'", name);
+  else if (mesg_implicit_function_declaration == 1)
+    warning ("implicit declaration of function `%s'", name);
+}
+
 /* Return zero if the declaration NEWDECL is valid
    when the declaration OLDDECL (assumed to be for the same name)
    has already been seen.
 /* Return zero if the declaration NEWDECL is valid
    when the declaration OLDDECL (assumed to be for the same name)
    has already been seen.
@@ -2566,7 +2610,7 @@ redeclaration_error_message (newdecl, olddecl)
         is equivalent to what this code used to do before the build_type_copy
         call.  The variant type distinction should not matter for traditional
         code, because it doesn't have type qualifiers.  */
         is equivalent to what this code used to do before the build_type_copy
         call.  The variant type distinction should not matter for traditional
         code, because it doesn't have type qualifiers.  */
-      if (flag_traditional 
+      if (flag_traditional
          && TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
        return 0;
       if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
          && TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
        return 0;
       if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
@@ -2587,7 +2631,7 @@ redeclaration_error_message (newdecl, olddecl)
        return 1;
       return 0;
     }
        return 1;
       return 0;
     }
-  else if (current_binding_level == global_binding_level)
+  else if (DECL_CONTEXT (newdecl) == NULL_TREE)
     {
       /* Objects declared at top level:  */
       /* If at least one is a reference, it's ok.  */
     {
       /* Objects declared at top level:  */
       /* If at least one is a reference, it's ok.  */
@@ -2647,9 +2691,6 @@ lookup_label (id)
 
   decl = build_decl (LABEL_DECL, id, void_type_node);
 
 
   decl = build_decl (LABEL_DECL, id, void_type_node);
 
-  /* Make sure every label has an rtx.  */
-  label_rtx (decl);
-
   /* A label not explicitly declared must be local to where it's ref'd.  */
   DECL_CONTEXT (decl) = current_function_decl;
 
   /* A label not explicitly declared must be local to where it's ref'd.  */
   DECL_CONTEXT (decl) = current_function_decl;
 
@@ -2690,7 +2731,7 @@ shadow_label (name)
       for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
        if (TREE_VALUE (dup) == decl)
          {
       for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
        if (TREE_VALUE (dup) == decl)
          {
-           error ("duplicate label declaration `%s'", 
+           error ("duplicate label declaration `%s'",
                   IDENTIFIER_POINTER (name));
            error_with_decl (TREE_VALUE (dup),
                             "this is a previous declaration");
                   IDENTIFIER_POINTER (name));
            error_with_decl (TREE_VALUE (dup),
                             "this is a previous declaration");
@@ -2725,13 +2766,15 @@ define_label (filename, line, name)
       decl = lookup_label (name);
     }
 
       decl = lookup_label (name);
     }
 
-  if (warn_traditional && lookup_name (name))
-    warning ("traditional C lacks a separate namespace for labels, identifier `%s' conflicts",
-            IDENTIFIER_POINTER (name));
-  
+  if (warn_traditional && !in_system_header && lookup_name (name))
+    warning_with_file_and_line (filename, line,
+                               "traditional C lacks a separate namespace for labels, identifier `%s' conflicts",
+                               IDENTIFIER_POINTER (name));
+
   if (DECL_INITIAL (decl) != 0)
     {
   if (DECL_INITIAL (decl) != 0)
     {
-      error ("duplicate label `%s'", IDENTIFIER_POINTER (name));
+      error_with_file_and_line (filename, line, "duplicate label `%s'",
+                               IDENTIFIER_POINTER (name));
       return 0;
     }
   else
       return 0;
     }
   else
@@ -2873,6 +2916,7 @@ lookup_name (name)
      tree name;
 {
   register tree val;
      tree name;
 {
   register tree val;
+
   if (current_binding_level != global_binding_level
       && IDENTIFIER_LOCAL_VALUE (name))
     val = IDENTIFIER_LOCAL_VALUE (name);
   if (current_binding_level != global_binding_level
       && IDENTIFIER_LOCAL_VALUE (name))
     val = IDENTIFIER_LOCAL_VALUE (name);
@@ -2904,7 +2948,7 @@ lookup_name_current_level (name)
 \f
 /* Mark ARG for GC.  */
 
 \f
 /* Mark ARG for GC.  */
 
-static void 
+static void
 mark_binding_level (arg)
      void *arg;
 {
 mark_binding_level (arg)
      void *arg;
 {
@@ -2939,7 +2983,9 @@ init_decl_processing ()
   named_labels = NULL;
   current_binding_level = NULL_BINDING_LEVEL;
   free_binding_level = NULL_BINDING_LEVEL;
   named_labels = NULL;
   current_binding_level = NULL_BINDING_LEVEL;
   free_binding_level = NULL_BINDING_LEVEL;
-  pushlevel (0);       /* make the binding_level structure for global names */
+
+  /* Make the binding_level structure for global names.  */
+  pushlevel (0);
   global_binding_level = current_binding_level;
 
   build_common_tree_nodes (flag_signed_char);
   global_binding_level = current_binding_level;
 
   build_common_tree_nodes (flag_signed_char);
@@ -2987,19 +3033,21 @@ init_decl_processing ()
      Note that stddef.h uses `unsigned long',
      and this must agree, even if long and int are the same size.  */
   t = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
      Note that stddef.h uses `unsigned long',
      and this must agree, even if long and int are the same size.  */
   t = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
+  signed_size_type_node = signed_type (t);
   if (flag_traditional && TREE_UNSIGNED (t))
     t = signed_type (t);
   if (flag_traditional && TREE_UNSIGNED (t))
     t = signed_type (t);
-    
+
+  c_size_type_node = t;
   set_sizetype (t);
 
   set_sizetype (t);
 
-  /* Create the widest literal types. */
+  /* Create the widest literal types.  */
   widest_integer_literal_type_node
     = make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
   widest_unsigned_literal_type_node
     = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
   widest_integer_literal_type_node
     = make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
   widest_unsigned_literal_type_node
     = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, 
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE,
                        widest_integer_literal_type_node));
                        widest_integer_literal_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, 
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE,
                        widest_unsigned_literal_type_node));
 
   build_common_tree_nodes_2 (flag_short_double);
                        widest_unsigned_literal_type_node));
 
   build_common_tree_nodes_2 (flag_short_double);
@@ -3033,10 +3081,31 @@ init_decl_processing ()
   signed_wchar_type_node = signed_type (wchar_type_node);
   unsigned_wchar_type_node = unsigned_type (wchar_type_node);
 
   signed_wchar_type_node = signed_type (wchar_type_node);
   unsigned_wchar_type_node = unsigned_type (wchar_type_node);
 
+  wint_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
+
+  intmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
+  uintmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
+
   boolean_type_node = integer_type_node;
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_node;
 
   boolean_type_node = integer_type_node;
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_node;
 
+  /* With GCC, C99's _Bool is always of size 1.  */
+  c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+  TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
+  TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
+  TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
+  TYPE_PRECISION (c_bool_type_node) = 1;
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
+                       c_bool_type_node));
+  c_bool_false_node = build_int_2 (0, 0);
+  TREE_TYPE (c_bool_false_node) = c_bool_type_node;
+  c_bool_true_node = build_int_2 (1, 0);
+  TREE_TYPE (c_bool_true_node) = c_bool_type_node;
+
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
     = build_pointer_type (build_type_variant (char_type_node, 1, 0));
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
     = build_pointer_type (build_type_variant (char_type_node, 1, 0));
@@ -3051,8 +3120,7 @@ init_decl_processing ()
   /* make a type for arrays of characters.
      With luck nothing will ever really depend on the length of this
      array type.  */
   /* make a type for arrays of characters.
      With luck nothing will ever really depend on the length of this
      array type.  */
-  char_array_type_node
-    = build_array_type (char_type_node, array_domain_type);
+  char_array_type_node = build_array_type (char_type_node, array_domain_type);
 
   /* Likewise for arrays of ints.  */
   int_array_type_node
 
   /* Likewise for arrays of ints.  */
   int_array_type_node
@@ -3064,12 +3132,12 @@ init_decl_processing ()
 
   void_list_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
 
 
   void_list_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
 
-  default_function_type
-    = build_function_type (integer_type_node, NULL_TREE);
+  default_function_type = build_function_type (integer_type_node, NULL_TREE);
   ptrdiff_type_node
     = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
   ptrdiff_type_node
     = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
+  unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
 
 
-  c_common_nodes_and_builtins (0, flag_no_builtin, flag_no_nonansi_builtin);
+  c_common_nodes_and_builtins ();
 
   endlink = void_list_node;
   ptr_ftype_void = build_function_type (ptr_type_node, endlink);
 
   endlink = void_list_node;
   ptr_ftype_void = build_function_type (ptr_type_node, endlink);
@@ -3078,7 +3146,7 @@ init_decl_processing ()
                           tree_cons (NULL_TREE, ptr_type_node, endlink));
 
   /* Types which are common to the fortran compiler and libf2c.  When
                           tree_cons (NULL_TREE, ptr_type_node, endlink));
 
   /* Types which are common to the fortran compiler and libf2c.  When
-     changing these, you also need to be concerned with f/com.h. */
+     changing these, you also need to be concerned with f/com.h.  */
 
   if (TYPE_PRECISION (float_type_node)
       == TYPE_PRECISION (long_integer_type_node))
 
   if (TYPE_PRECISION (float_type_node)
       == TYPE_PRECISION (long_integer_type_node))
@@ -3152,14 +3220,18 @@ init_decl_processing ()
                          tree_cons (NULL_TREE, ptr_type_node,
                                     tree_cons (NULL_TREE,
                                                type_for_mode (ptr_mode, 0),
                          tree_cons (NULL_TREE, ptr_type_node,
                                     tree_cons (NULL_TREE,
                                                type_for_mode (ptr_mode, 0),
-                                               tree_cons (NULL_TREE,
+                                               tree_cons (NULL_TREE,
                                                           ptr_type_node,
                                                           endlink)))),
      BUILT_IN_EH_RETURN, BUILT_IN_NORMAL, NULL_PTR);
 
   pedantic_lvalues = pedantic;
 
                                                           ptr_type_node,
                                                           endlink)))),
      BUILT_IN_EH_RETURN, BUILT_IN_NORMAL, NULL_PTR);
 
   pedantic_lvalues = pedantic;
 
-  /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__.  */
+  /* Create the global bindings for __FUNCTION__, __PRETTY_FUNCTION__,
+     and __func__.  */
+  function_id_node = get_identifier ("__FUNCTION__");
+  pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__");
+  func_id_node = get_identifier ("__func__");
   make_fname_decl = c_make_fname_decl;
   declare_function_name ();
 
   make_fname_decl = c_make_fname_decl;
   declare_function_name ();
 
@@ -3168,13 +3240,13 @@ init_decl_processing ()
   /* Prepare to check format strings against argument lists.  */
   init_function_format_info ();
 
   /* Prepare to check format strings against argument lists.  */
   init_function_format_info ();
 
-  init_iterators ();
-
   incomplete_decl_finalize_hook = finish_incomplete_decl;
 
   /* Record our roots.  */
 
   ggc_add_tree_root (c_global_trees, CTI_MAX);
   incomplete_decl_finalize_hook = finish_incomplete_decl;
 
   /* Record our roots.  */
 
   ggc_add_tree_root (c_global_trees, CTI_MAX);
+  ggc_add_root (&c_stmt_tree, 1, sizeof c_stmt_tree, mark_stmt_tree);
+  ggc_add_tree_root (&c_scope_stmt_stack, 1);
   ggc_add_tree_root (&named_labels, 1);
   ggc_add_tree_root (&shadowed_labels, 1);
   ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
   ggc_add_tree_root (&named_labels, 1);
   ggc_add_tree_root (&shadowed_labels, 1);
   ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
@@ -3191,7 +3263,7 @@ init_decl_processing ()
    delayed emission of static data, we mark the decl as emitted
    so it is not placed in the output.  Anything using it must therefore pull
    out the STRING_CST initializer directly.  This does mean that these names
    delayed emission of static data, we mark the decl as emitted
    so it is not placed in the output.  Anything using it must therefore pull
    out the STRING_CST initializer directly.  This does mean that these names
-   are string merging candidates, which C99 does not permit.  */
+   are string merging candidates, which is wrong for C99's __func__.  FIXME.  */
 
 static tree
 c_make_fname_decl (id, name, type_dep)
 
 static tree
 c_make_fname_decl (id, name, type_dep)
@@ -3218,7 +3290,7 @@ c_make_fname_decl (id, name, type_dep)
   TREE_TYPE (init) = type;
   DECL_INITIAL (decl) = init;
   finish_decl (pushdecl (decl), init, NULL_TREE);
   TREE_TYPE (init) = type;
   DECL_INITIAL (decl) = init;
   finish_decl (pushdecl (decl), init, NULL_TREE);
-  
+
   return decl;
 }
 
   return decl;
 }
 
@@ -3398,8 +3470,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
                                       NORMAL, initialized);
   register tree tem;
 
                                       NORMAL, initialized);
   register tree tem;
 
-  if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL 
-      && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "main"))
+  if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
+      && MAIN_NAME_P (DECL_NAME (decl)))
     warning_with_decl (decl, "`%s' is usually a function");
 
   if (initialized)
     warning_with_decl (decl, "`%s' is usually a function");
 
   if (initialized)
@@ -3436,7 +3508,12 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
       default:
        /* Don't allow initializations for incomplete types
           except for arrays which might be completed by the initialization.  */
       default:
        /* Don't allow initializations for incomplete types
           except for arrays which might be completed by the initialization.  */
-       if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
+
+       /* This can happen if the array size is an undefined macro.  We already
+          gave a warning, so we don't need another one.  */
+       if (TREE_TYPE (decl) == error_mark_node)
+         initialized = 0;
+       else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
          {
            /* A complete type is ok if size is fixed.  */
 
          {
            /* A complete type is ok if size is fixed.  */
 
@@ -3463,7 +3540,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
 
   if (initialized)
     {
 
   if (initialized)
     {
-#if 0  /* Seems redundant with grokdeclarator.  */
+#if 0
+      /* Seems redundant with grokdeclarator.  */
       if (current_binding_level != global_binding_level
          && DECL_EXTERNAL (decl)
          && TREE_CODE (decl) != FUNCTION_DECL)
       if (current_binding_level != global_binding_level
          && DECL_EXTERNAL (decl)
          && TREE_CODE (decl) != FUNCTION_DECL)
@@ -3510,9 +3588,11 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
       /* But not if this is a duplicate decl
         and we preserved the rtl from the previous one
         (which may or may not happen).  */
       /* But not if this is a duplicate decl
         and we preserved the rtl from the previous one
         (which may or may not happen).  */
-      && DECL_RTL (tem) == 0)
+      && DECL_RTL (tem) == 0
+      && !DECL_CONTEXT (tem))
     {
     {
-      if (COMPLETE_TYPE_P (TREE_TYPE (tem)))
+      if (TREE_TYPE (tem) != error_mark_node
+         && COMPLETE_TYPE_P (TREE_TYPE (tem)))
        expand_decl (tem);
       else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
               && DECL_INITIAL (tem) != 0)
        expand_decl (tem);
       else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
               && DECL_INITIAL (tem) != 0)
@@ -3534,7 +3614,7 @@ finish_decl (decl, init, asmspec_tree)
 {
   register tree type = TREE_TYPE (decl);
   int was_incomplete = (DECL_SIZE (decl) == 0);
 {
   register tree type = TREE_TYPE (decl);
   int was_incomplete = (DECL_SIZE (decl) == 0);
-  char *asmspec = 0;
+  const char *asmspec = 0;
 
   /* If a name was specified, get the string.   */
   if (asmspec_tree)
 
   /* If a name was specified, get the string.   */
   if (asmspec_tree)
@@ -3548,14 +3628,6 @@ finish_decl (decl, init, asmspec_tree)
   if (TREE_CODE (decl) == PARM_DECL)
     init = 0;
 
   if (TREE_CODE (decl) == PARM_DECL)
     init = 0;
 
-  if (ITERATOR_P (decl))
-    {
-      if (init == 0)
-       error_with_decl (decl, "iterator has no initial value");
-      else
-       init = save_expr (init);
-    }
-
   if (init)
     {
       if (TREE_CODE (decl) != TYPE_DECL)
   if (init)
     {
       if (TREE_CODE (decl) != TYPE_DECL)
@@ -3589,7 +3661,7 @@ finish_decl (decl, init, asmspec_tree)
       if (failure == 1)
        error_with_decl (decl, "initializer fails to determine size of `%s'");
 
       if (failure == 1)
        error_with_decl (decl, "initializer fails to determine size of `%s'");
 
-      if (failure == 2)
+      else if (failure == 2)
        {
          if (do_default)
            error_with_decl (decl, "array size missing in `%s'");
        {
          if (do_default)
            error_with_decl (decl, "array size missing in `%s'");
@@ -3606,8 +3678,8 @@ finish_decl (decl, init, asmspec_tree)
       /* 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.  */
       /* 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.  */
-      if (pedantic && TYPE_DOMAIN (type) != 0
-         && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+      else if (pedantic && TYPE_DOMAIN (type) != 0
+             && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
        error_with_decl (decl, "zero or negative size array `%s'");
 
       layout_decl (decl, 0);
        error_with_decl (decl, "zero or negative size array `%s'");
 
       layout_decl (decl, 0);
@@ -3615,10 +3687,13 @@ finish_decl (decl, init, asmspec_tree)
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
-      if (DECL_SIZE (decl) == 0 && COMPLETE_TYPE_P (TREE_TYPE (decl)))
+      if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node
+         && COMPLETE_TYPE_P (TREE_TYPE (decl)))
        layout_decl (decl, 0);
 
       if (DECL_SIZE (decl) == 0
        layout_decl (decl, 0);
 
       if (DECL_SIZE (decl) == 0
+         /* Don't give an error if we already gave one earlier.  */
+         && TREE_TYPE (decl) != error_mark_node
          && (TREE_STATIC (decl)
              ?
                /* A static variable with an incomplete type
          && (TREE_STATIC (decl)
              ?
                /* A static variable with an incomplete type
@@ -3626,11 +3701,8 @@ finish_decl (decl, init, asmspec_tree)
                   Also if it is not file scope.
                   Otherwise, let it through, but if it is not `extern'
                   then it may cause an error message later.  */
                   Also if it is not file scope.
                   Otherwise, let it through, but if it is not `extern'
                   then it may cause an error message later.  */
-             /* A duplicate_decls call could have changed an extern
-                declaration into a file scope one.  This can be detected
-                by TREE_ASM_WRITTEN being set.  */
                (DECL_INITIAL (decl) != 0
                (DECL_INITIAL (decl) != 0
-                || (DECL_CONTEXT (decl) != 0 && ! TREE_ASM_WRITTEN (decl)))
+                || DECL_CONTEXT (decl) != 0)
              :
                /* An automatic variable with an incomplete type
                   is an error.  */
              :
                /* An automatic variable with an incomplete type
                   is an error.  */
@@ -3649,7 +3721,7 @@ finish_decl (decl, init, asmspec_tree)
            error_with_decl (decl, "storage size of `%s' isn't constant");
        }
 
            error_with_decl (decl, "storage size of `%s' isn't constant");
        }
 
-      if (TREE_USED  (type))
+      if (TREE_USED (type))
        TREE_USED (decl) = 1;
     }
 
        TREE_USED (decl) = 1;
     }
 
@@ -3657,11 +3729,11 @@ finish_decl (decl, init, asmspec_tree)
      builtin any more.  Also reset DECL_RTL so we can give it its new
      name.  */
   if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
      builtin any more.  Also reset DECL_RTL so we can give it its new
      name.  */
   if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
-      {
-       DECL_BUILT_IN_CLASS (decl) = NOT_BUILT_IN;
-       DECL_RTL (decl) = 0;
-       DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
-      }
+    {
+      DECL_BUILT_IN_CLASS (decl) = NOT_BUILT_IN;
+      DECL_RTL (decl) = 0;
+      DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+    }
 
   /* Output the assembler code and/or RTL code for variables and functions,
      unless the type is an undefined structure or union.
 
   /* Output the assembler code and/or RTL code for variables and functions,
      unless the type is an undefined structure or union.
@@ -3671,9 +3743,20 @@ finish_decl (decl, init, asmspec_tree)
     {
       /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
       maybe_objc_check_decl (decl);
     {
       /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
       maybe_objc_check_decl (decl);
-      rest_of_decl_compilation (decl, asmspec,
-                               (DECL_CONTEXT (decl) == 0
-                                || TREE_ASM_WRITTEN (decl)), 0);
+
+      if (!DECL_CONTEXT (decl))
+       rest_of_decl_compilation (decl, asmspec,
+                                 (DECL_CONTEXT (decl) == 0
+                                  || TREE_ASM_WRITTEN (decl)), 0);
+      else
+       {
+         if (asmspec)
+           {
+             DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+             DECL_C_HARD_REGISTER (decl) = 1;
+           }
+         add_decl_stmt (decl);
+       }
 
       if (DECL_CONTEXT (decl) != 0)
        {
 
       if (DECL_CONTEXT (decl) != 0)
        {
@@ -3687,11 +3770,7 @@ finish_decl (decl, init, asmspec_tree)
              /* If it's still incomplete now, no init will save it.  */
              if (DECL_SIZE (decl) == 0)
                DECL_INITIAL (decl) = 0;
              /* If it's still incomplete now, no init will save it.  */
              if (DECL_SIZE (decl) == 0)
                DECL_INITIAL (decl) = 0;
-             expand_decl (decl);
            }
            }
-         /* Compute and store the initial value.  */
-         if (TREE_CODE (decl) != FUNCTION_DECL)
-           expand_decl_init (decl);
        }
     }
 
        }
     }
 
@@ -3745,7 +3824,8 @@ push_parm_decl (parm)
       tree olddecl;
       olddecl = lookup_name (DECL_NAME (decl));
       if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL)
       tree olddecl;
       olddecl = lookup_name (DECL_NAME (decl));
       if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL)
-       pedwarn_with_decl (decl, "ANSI C forbids parameter `%s' shadowing typedef");
+       pedwarn_with_decl (decl,
+                          "ANSI C forbids parameter `%s' shadowing typedef");
     }
 #endif
 
     }
 #endif
 
@@ -3964,7 +4044,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
     {
 
   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
     {
-      register int i;
       register tree id = TREE_VALUE (spec);
 
       if (id == ridpointers[(int) RID_INT])
       register tree id = TREE_VALUE (spec);
 
       if (id == ridpointers[(int) RID_INT])
@@ -3972,36 +4051,36 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       if (id == ridpointers[(int) RID_CHAR])
        explicit_char = 1;
 
       if (id == ridpointers[(int) RID_CHAR])
        explicit_char = 1;
 
-      if (TREE_CODE (id) == IDENTIFIER_NODE)
-       for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++)
-         {
-           if (ridpointers[i] == id)
-             {
-               if (i == (int) RID_LONG && specbits & (1<<i))
-                 {
-                   if (longlong)
-                     error ("`long long long' is too long for GCC");
-                   else
-                     {
-                       if (pedantic && !flag_isoc99 && ! in_system_header
-                           && warn_long_long)
-                         pedwarn ("ANSI C does not support `long long'");
-                       longlong = 1;
-                     }
-                 }
-               else if (specbits & (1 << i))
-                 pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
-               specbits |= 1 << i;
-               goto found;
-             }
-         }
+      if (TREE_CODE (id) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (id))
+       {
+         enum rid i = C_RID_CODE (id);
+         if (i <= RID_LAST_MODIFIER)
+           {
+             if (i == RID_LONG && specbits & (1<<i))
+               {
+                 if (longlong)
+                   error ("`long long long' is too long for GCC");
+                 else
+                   {
+                     if (pedantic && !flag_isoc99 && ! in_system_header
+                         && warn_long_long)
+                       pedwarn ("ISO C89 does not support `long long'");
+                     longlong = 1;
+                   }
+               }
+             else if (specbits & (1 << i))
+               pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
+             specbits |= 1 << i;
+             goto found;
+           }
+       }
       if (type)
        error ("two or more data types in declaration of `%s'", name);
       /* Actual typedefs come to us as TYPE_DECL nodes.  */
       else if (TREE_CODE (id) == TYPE_DECL)
        {
          type = TREE_TYPE (id);
       if (type)
        error ("two or more data types in declaration of `%s'", name);
       /* Actual typedefs come to us as TYPE_DECL nodes.  */
       else if (TREE_CODE (id) == TYPE_DECL)
        {
          type = TREE_TYPE (id);
-          decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id);
+         decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id);
          typedef_decl = id;
        }
       /* Built-in types come as identifiers.  */
          typedef_decl = id;
        }
       /* Built-in types come as identifiers.  */
@@ -4022,7 +4101,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       else if (TREE_CODE (id) != ERROR_MARK)
        type = id;
 
       else if (TREE_CODE (id) != ERROR_MARK)
        type = id;
 
-    found: {}
+    found:
+      ;
     }
 
   typedef_type = type;
     }
 
   typedef_type = type;
@@ -4036,7 +4116,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
     {
       if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
                          | (1 << (int) RID_SIGNED)
     {
       if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
                          | (1 << (int) RID_SIGNED)
-                         | (1 << (int) RID_UNSIGNED))))
+                         | (1 << (int) RID_UNSIGNED)
+                         | (1 << (int) RID_COMPLEX))))
          /* Don't warn about typedef foo = bar.  */
          && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
          && ! in_system_header)
          /* Don't warn about typedef foo = bar.  */
          && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
          && ! in_system_header)
@@ -4047,7 +4128,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          if ((warn_implicit_int || warn_return_type) && funcdef_flag)
            warn_about_return_type = 1;
          else if (warn_implicit_int || flag_isoc99)
          if ((warn_implicit_int || warn_return_type) && funcdef_flag)
            warn_about_return_type = 1;
          else if (warn_implicit_int || flag_isoc99)
-           pedwarn_c99 ("type defaults to `int' in declaration of `%s'", name);
+           pedwarn_c99 ("type defaults to `int' in declaration of `%s'",
+                        name);
        }
 
       defaulted_int = 1;
        }
 
       defaulted_int = 1;
@@ -4062,7 +4144,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
   if ((specbits & 1 << (int) RID_LONG) && ! longlong
       && TYPE_MAIN_VARIANT (type) == double_type_node)
     {
   if ((specbits & 1 << (int) RID_LONG) && ! longlong
       && TYPE_MAIN_VARIANT (type) == double_type_node)
     {
-      specbits &= ~ (1 << (int) RID_LONG);
+      specbits &= ~(1 << (int) RID_LONG);
       type = long_double_type_node;
     }
 
       type = long_double_type_node;
     }
 
@@ -4123,7 +4205,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
     {
       error ("complex invalid for `%s'", name);
       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
     {
       error ("complex invalid for `%s'", name);
-      specbits &= ~ (1 << (int) RID_COMPLEX);
+      specbits &= ~(1 << (int) RID_COMPLEX);
     }
 
   /* Decide whether an integer type is signed or not.
     }
 
   /* Decide whether an integer type is signed or not.
@@ -4166,6 +4248,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   if (specbits & 1 << (int) RID_COMPLEX)
     {
 
   if (specbits & 1 << (int) RID_COMPLEX)
     {
+      if (pedantic && !flag_isoc99)
+       pedwarn ("ISO C89 does not support complex types");
       /* If we just have "complex", it is equivalent to
         "complex double", but if any modifiers at all are specified it is
         the complex form of TYPE.  E.g, "complex short" is
       /* If we just have "complex", it is equivalent to
         "complex double", but if any modifiers at all are specified it is
         the complex form of TYPE.  E.g, "complex short" is
@@ -4175,9 +4259,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
                            | (1 << (int) RID_SIGNED)
                            | (1 << (int) RID_UNSIGNED))))
          && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
                            | (1 << (int) RID_SIGNED)
                            | (1 << (int) RID_UNSIGNED))))
-       type = complex_double_type_node;
+       {
+         if (pedantic)
+           pedwarn ("ISO C does not support plain `complex' meaning `double complex'");
+         type = complex_double_type_node;
+       }
       else if (type == integer_type_node)
       else if (type == integer_type_node)
-       type = complex_integer_type_node;
+       {
+         if (pedantic)
+           pedwarn ("ISO C does not support complex integer types");
+         type = complex_integer_type_node;
+       }
       else if (type == float_type_node)
        type = complex_float_type_node;
       else if (type == double_type_node)
       else if (type == float_type_node)
        type = complex_float_type_node;
       else if (type == double_type_node)
@@ -4185,7 +4277,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       else if (type == long_double_type_node)
        type = complex_long_double_type_node;
       else
       else if (type == long_double_type_node)
        type = complex_long_double_type_node;
       else
-       type = build_complex_type (type);
+       {
+         if (pedantic)
+           pedwarn ("ISO C does not support complex integer types");
+         type = build_complex_type (type);
+       }
     }
 
   /* Figure out the type qualifiers for the declaration.  There are
     }
 
   /* Figure out the type qualifiers for the declaration.  There are
@@ -4219,7 +4315,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
     if (specbits & 1 << (int) RID_EXTERN) nclasses++;
     if (specbits & 1 << (int) RID_REGISTER) nclasses++;
     if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
     if (specbits & 1 << (int) RID_EXTERN) nclasses++;
     if (specbits & 1 << (int) RID_REGISTER) nclasses++;
     if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
-    if (specbits & 1 << (int) RID_ITERATOR) nclasses++;
 
     /* Warn about storage classes that are invalid for certain
        kinds of declarations (parameters, typenames, etc.).  */
 
     /* Warn about storage classes that are invalid for certain
        kinds of declarations (parameters, typenames, etc.).  */
@@ -4239,8 +4334,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          error ("function definition declared `register'");
        if (specbits & 1 << (int) RID_TYPEDEF)
          error ("function definition declared `typedef'");
          error ("function definition declared `register'");
        if (specbits & 1 << (int) RID_TYPEDEF)
          error ("function definition declared `typedef'");
-       specbits &= ~ ((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
-                      | (1 << (int) RID_AUTO));
+       specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
+                     | (1 << (int) RID_AUTO));
       }
     else if (decl_context != NORMAL && nclasses > 0)
       {
       }
     else if (decl_context != NORMAL && nclasses > 0)
       {
@@ -4251,7 +4346,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            switch (decl_context)
              {
              case FIELD:
            switch (decl_context)
              {
              case FIELD:
-               error ("storage class specified for structure field `%s'", name);
+               error ("storage class specified for structure field `%s'",
+                      name);
                break;
              case PARM:
                error ("storage class specified for parameter `%s'", name);
                break;
              case PARM:
                error ("storage class specified for parameter `%s'", name);
@@ -4260,9 +4356,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                error ("storage class specified for typename");
                break;
              }
                error ("storage class specified for typename");
                break;
              }
-           specbits &= ~ ((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
-                          | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
-                          | (1 << (int) RID_EXTERN));
+           specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
+                         | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
+                         | (1 << (int) RID_EXTERN));
          }
       }
     else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
          }
       }
     else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
@@ -4279,18 +4375,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
     else if (current_binding_level == global_binding_level
             && specbits & (1 << (int) RID_AUTO))
       error ("top-level declaration of `%s' specifies `auto'", name);
     else if (current_binding_level == global_binding_level
             && specbits & (1 << (int) RID_AUTO))
       error ("top-level declaration of `%s' specifies `auto'", name);
-    else if ((specbits & 1 << (int) RID_ITERATOR)
-            && TREE_CODE (declarator) != IDENTIFIER_NODE)
-      {
-       error ("iterator `%s' has derived type", name);
-       type = error_mark_node;
-      }
-    else if ((specbits & 1 << (int) RID_ITERATOR)
-            && TREE_CODE (type) != INTEGER_TYPE)
-      {
-       error ("iterator `%s' has noninteger type", name);
-       type = error_mark_node;
-      }
   }
 
   /* Now figure out the structure of the declarator proper.
   }
 
   /* Now figure out the structure of the declarator proper.
@@ -4365,7 +4449,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                }
 
              if (pedantic && integer_zerop (size))
                }
 
              if (pedantic && integer_zerop (size))
-               pedwarn ("ANSI C forbids zero-size array `%s'", name);
+               pedwarn ("ISO C forbids zero-size array `%s'", name);
 
              if (TREE_CODE (size) == INTEGER_CST)
                {
 
              if (TREE_CODE (size) == INTEGER_CST)
                {
@@ -4385,37 +4469,66 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                  if (pedantic)
                    {
                      if (TREE_CONSTANT (size))
                  if (pedantic)
                    {
                      if (TREE_CONSTANT (size))
-                       pedwarn ("ANSI C forbids array `%s' whose size can't be evaluated", name);
+                       pedwarn ("ISO C89 forbids array `%s' whose size can't be evaluated",
+                                name);
                      else
                      else
-                       pedwarn ("ANSI C forbids variable-size array `%s'", name);
+                       pedwarn ("ISO C89 forbids variable-size array `%s'",
+                                name);
                    }
                }
 
                    }
                }
 
-             /* Convert size to index_type, so that if it is a variable
-                the computations will be done in the proper mode.  */
-             itype = fold (build (MINUS_EXPR, index_type,
-                                  convert (index_type, size),
-                                  convert (index_type, size_one_node)));
-
-             /* If that overflowed, the array is too big.
-                ??? While a size of INT_MAX+1 technically shouldn't cause
-                an overflow (because we subtract 1), the overflow is recorded
-                during the conversion to index_type, before the subtraction.
-                Handling this case seems like an unnecessary complication.  */
-             if (TREE_OVERFLOW (itype))
+             if (integer_zerop (size))
                {
                {
-                 error ("size of array `%s' is too large", name);
-                 type = error_mark_node;
-                 continue;
+                 /* A zero-length array cannot be represented with an
+                    unsigned index type, which is what we'll get with
+                    build_index_type.  Create an open-ended range instead.  */
+                 itype = build_range_type (sizetype, size, NULL_TREE);
                }
                }
+             else
+               {
+                 /* 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 done in the
+                    proper mode.  */
+                 itype = fold (build (MINUS_EXPR, index_type,
+                                      convert (index_type, size),
+                                      convert (index_type, size_one_node)));
+
+                 /* If that overflowed, the array is too big.
+                    ??? While a size of INT_MAX+1 technically shouldn't
+                    cause an overflow (because we subtract 1), the overflow
+                    is recorded during the conversion to index_type, before
+                    the subtraction.  Handling this case seems like an
+                    unnecessary complication.  */
+                 if (TREE_OVERFLOW (itype))
+                   {
+                     error ("size of array `%s' is too large", name);
+                     type = error_mark_node;
+                     continue;
+                   }
 
 
-             if (size_varies)
-               itype = variable_size (itype);
-             itype = build_index_type (itype);
+                 if (size_varies)
+                   itype = variable_size (itype);
+                 itype = build_index_type (itype);
+               }
            }
            }
+         else if (decl_context == FIELD)
+           {
+             /* ??? Need to check somewhere that this is a structure
+                and not a union, that this field is last, and that 
+                this structure has at least one other named member.  */
 
 
-#if 0 /* This had bad results for pointers to arrays, as in
-        union incomplete (*foo)[4];  */
+             if (pedantic && !flag_isoc99 && !in_system_header)
+               pedwarn ("ISO C89 does not support flexible array members");
+
+             /* ISO C99 Flexible array members are effectively identical
+                to GCC's zero-length array extension.  */
+             itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+           }
+
+#if 0
+         /* This had bad results for pointers to arrays, as in
+            union incomplete (*foo)[4];  */
          /* Complain about arrays of incomplete types, except in typedefs.  */
 
          if (!COMPLETE_TYPE_P (type)
          /* Complain about arrays of incomplete types, except in typedefs.  */
 
          if (!COMPLETE_TYPE_P (type)
@@ -4426,8 +4539,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            warning ("array type has incomplete element type");
 #endif
 
            warning ("array type has incomplete element type");
 #endif
 
-#if 0  /* We shouldn't have a function type here at all!
-         Functions aren't allowed as array elements.  */
+#if 0
+         /* We shouldn't have a function type here at all!
+            Functions aren't allowed as array elements.  */
          if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
              && (constp || volatilep))
            pedwarn ("ANSI C forbids const or volatile function types");
          if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
              && (constp || volatilep))
            pedwarn ("ANSI C forbids const or volatile function types");
@@ -4442,8 +4556,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          if (type_quals)
            type = c_build_qualified_type (type, type_quals);
 
          if (type_quals)
            type = c_build_qualified_type (type, type_quals);
 
-#if 0  /* don't clear these; leave them set so that the array type
-          or the variable is itself const or volatile.  */
+#if 0
+         /* Don't clear these; leave them set so that the array type
+            or the variable is itself const or volatile.  */
          type_quals = TYPE_UNQUALIFIED;
 #endif
 
          type_quals = TYPE_UNQUALIFIED;
 #endif
 
@@ -4493,7 +4608,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          /* Type qualifiers before the return type of the function
             qualify the return type, not the function type.  */
          if (type_quals)
          /* Type qualifiers before the return type of the function
             qualify the return type, not the function type.  */
          if (type_quals)
-           type = c_build_qualified_type (type, type_quals);
+           {
+             /* Type qualifiers on a function return type are normally
+                permitted by the standard but have no effect, so give a
+                warning at -W.  Qualifiers on a void return type have
+                meaning as a GNU extension, and are banned on function
+                definitions in ISO C.  FIXME: strictly we shouldn't
+                pedwarn for qualified void return types except on function
+                definitions, but not doing so could lead to the undesirable
+                state of a "volatile void" function return type not being
+                warned about, and a use of the function being compiled
+                with GNU semantics, with no diagnostics under -pedantic.  */
+             if (VOID_TYPE_P (type) && pedantic && !in_system_header)
+               pedwarn ("ISO C forbids qualified void function return type");
+             else if (extra_warnings
+                      && !(VOID_TYPE_P (type)
+                           && type_quals == TYPE_QUAL_VOLATILE))
+               warning ("type qualifiers ignored on function return type");
+
+             type = c_build_qualified_type (type, type_quals);
+           }
          type_quals = TYPE_UNQUALIFIED;
 
          type = build_function_type (type, arg_types);
          type_quals = TYPE_UNQUALIFIED;
 
          type = build_function_type (type, arg_types);
@@ -4519,7 +4653,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
          if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
              && type_quals)
 
          if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
              && type_quals)
-           pedwarn ("ANSI C forbids qualified function types");
+           pedwarn ("ISO C forbids qualified function types");
          if (type_quals)
            type = c_build_qualified_type (type, type_quals);
          type_quals = TYPE_UNQUALIFIED;
          if (type_quals)
            type = c_build_qualified_type (type, type_quals);
          type_quals = TYPE_UNQUALIFIED;
@@ -4543,18 +4677,23 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                {
                  tree qualifier = TREE_VALUE (typemodlist);
 
                {
                  tree qualifier = TREE_VALUE (typemodlist);
 
-                 if (qualifier == ridpointers[(int) RID_CONST])
-                   constp++;
-                 else if (qualifier == ridpointers[(int) RID_VOLATILE])
-                   volatilep++;
-                 else if (qualifier == ridpointers[(int) RID_RESTRICT])
-                   restrictp++;
-                 else if (!erred)
+                 if (C_IS_RESERVED_WORD (qualifier))
                    {
                    {
-                     erred = 1;
-                     error ("invalid type modifier within pointer declarator");
+                     if (C_RID_CODE (qualifier) == RID_CONST)
+                       constp++;
+                     else if (C_RID_CODE (qualifier) == RID_VOLATILE)
+                       volatilep++;
+                     else if (C_RID_CODE (qualifier) == RID_RESTRICT)
+                       restrictp++;
+                     else
+                       erred++;
                    }
                    }
+                 else
+                   erred++;
                }
                }
+
+             if (erred)
+               error ("invalid type modifier within pointer declarator");
              if (constp > 1 && ! flag_isoc99)
                pedwarn ("duplicate `const'");
              if (volatilep > 1 && ! flag_isoc99)
              if (constp > 1 && ! flag_isoc99)
                pedwarn ("duplicate `const'");
              if (volatilep > 1 && ! flag_isoc99)
@@ -4592,7 +4731,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
         in typenames, fields or parameters */
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
         in typenames, fields or parameters */
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
-       pedwarn ("ANSI C forbids qualified function types");
+       pedwarn ("ISO C forbids qualified function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       decl = build_decl (TYPE_DECL, declarator, type);
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       decl = build_decl (TYPE_DECL, declarator, type);
@@ -4609,8 +4748,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
      controlled separately by its own initializer.  */
 
   if (type != 0 && typedef_type != 0
      controlled separately by its own initializer.  */
 
   if (type != 0 && typedef_type != 0
-      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type)
-      && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0)
+      && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
+      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
     {
       type = build_array_type (TREE_TYPE (type), 0);
       if (size_varies)
     {
       type = build_array_type (TREE_TYPE (type), 0);
       if (size_varies)
@@ -4626,7 +4765,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
         in typenames, fields or parameters */
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
         in typenames, fields or parameters */
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
-       pedwarn ("ANSI C forbids const or volatile function types");
+       pedwarn ("ISO C forbids const or volatile function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       return type;
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       return type;
@@ -4676,7 +4815,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
            if (pedantic && type_quals)
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
            if (pedantic && type_quals)
-             pedwarn ("ANSI C forbids qualified function types");
+             pedwarn ("ISO C forbids qualified function types");
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
            type = build_pointer_type (type);
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
            type = build_pointer_type (type);
@@ -4725,7 +4864,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
                                                             type_quals),
                                     TYPE_DOMAIN (type));
            type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
                                                             type_quals),
                                     TYPE_DOMAIN (type));
-#if 0 /* Leave the field const or volatile as well.  */
+#if 0
+           /* Leave the field const or volatile as well.  */
            type_quals = TYPE_UNQUALIFIED;
 #endif
          }
            type_quals = TYPE_UNQUALIFIED;
 #endif
          }
@@ -4762,13 +4902,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        decl = build_decl_attribute_variant (decl, decl_machine_attr);
 
        if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
        decl = build_decl_attribute_variant (decl, decl_machine_attr);
 
        if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
-         pedwarn ("ANSI C forbids qualified function types");
-
-       if (pedantic
-           && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
-           && TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
-           && ! DECL_IN_SYSTEM_HEADER (decl))
-         pedwarn ("ANSI C forbids qualified void function return type");
+         pedwarn ("ISO C forbids qualified function types");
 
        /* GNU C interprets a `volatile void' return type to indicate
           that the function does not return.  */
 
        /* GNU C interprets a `volatile void' return type to indicate
           that the function does not return.  */
@@ -4785,7 +4919,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        /* Record presence of `inline', if it is reasonable.  */
        if (inlinep)
          {
        /* Record presence of `inline', if it is reasonable.  */
        if (inlinep)
          {
-           if (! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+           if (MAIN_NAME_P (declarator))
              warning ("cannot inline function `main'");
            else
              /* Assume that otherwise the function can be inlined.  */
              warning ("cannot inline function `main'");
            else
              /* Assume that otherwise the function can be inlined.  */
@@ -4837,9 +4971,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
            TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
          }
            TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
            TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
          }
-
-       if (specbits & 1 << (int) RID_ITERATOR)
-         ITERATOR_P (decl) = 1;
       }
 
     /* Record `register' declaration for warnings on &
       }
 
     /* Record `register' declaration for warnings on &
@@ -4937,8 +5068,10 @@ grokparms (parms_info, funcdef_flag)
                      TREE_TYPE (parm) = error_mark_node;
                    }
                }
                      TREE_TYPE (parm) = error_mark_node;
                    }
                }
-#if 0  /* This has been replaced by parm_tags_warning
-         which uses a more accurate criterion for what to warn about.  */
+#if 0
+             /* This has been replaced by parm_tags_warning, which
+                uses a more accurate criterion for what to warn
+                about.  */
              else
                {
                  /* Now warn if is a pointer to an incomplete type.  */
              else
                {
                  /* Now warn if is a pointer to an incomplete type.  */
@@ -4959,11 +5092,10 @@ grokparms (parms_info, funcdef_flag)
              typelt = TREE_CHAIN (typelt);
            }
 
              typelt = TREE_CHAIN (typelt);
            }
 
-       return first_parm;
+      return first_parm;
     }
 }
 
     }
 }
 
-
 /* Return a tree_list node with info on a parameter list just parsed.
    The TREE_PURPOSE is a chain of decls of those parms.
    The TREE_VALUE is a list of structure, union and enum tags defined.
 /* Return a tree_list node with info on a parameter list just parsed.
    The TREE_PURPOSE is a chain of decls of those parms.
    The TREE_VALUE is a list of structure, union and enum tags defined.
@@ -4985,10 +5117,17 @@ get_parm_info (void_at_end)
   tree new_parms = 0;
   tree order = current_binding_level->parm_order;
 
   tree new_parms = 0;
   tree order = current_binding_level->parm_order;
 
-  /* Just `void' (and no ellipsis) is special.  There are really no parms.  */
+  /* Just `void' (and no ellipsis) is special.  There are really no parms.
+     But if the `void' is qualified (by `const' or `volatile') or has a
+     storage class specifier (`register'), then the behavior is undefined;
+     by not counting it as the special case of `void' we will cause an
+     error later.  Typedefs for `void' are OK (see DR#157).  */
   if (void_at_end && parms != 0
       && TREE_CHAIN (parms) == 0
       && VOID_TYPE_P (TREE_TYPE (parms))
   if (void_at_end && parms != 0
       && TREE_CHAIN (parms) == 0
       && VOID_TYPE_P (TREE_TYPE (parms))
+      && ! TREE_THIS_VOLATILE (parms)
+      && ! TREE_READONLY (parms)
+      && ! DECL_REGISTER (parms)
       && DECL_NAME (parms) == 0)
     {
       parms = NULL_TREE;
       && DECL_NAME (parms) == 0)
     {
       parms = NULL_TREE;
@@ -4999,7 +5138,7 @@ get_parm_info (void_at_end)
 
   /* Extract enumerator values and other non-parms declared with the parms.
      Likewise any forward parm decls that didn't have real parm decls.  */
 
   /* Extract enumerator values and other non-parms declared with the parms.
      Likewise any forward parm decls that didn't have real parm decls.  */
-  for (decl = parms; decl; )
+  for (decl = parms; decl;)
     {
       tree next = TREE_CHAIN (decl);
 
     {
       tree next = TREE_CHAIN (decl);
 
@@ -5010,7 +5149,8 @@ get_parm_info (void_at_end)
        }
       else if (TREE_ASM_WRITTEN (decl))
        {
        }
       else if (TREE_ASM_WRITTEN (decl))
        {
-         error_with_decl (decl, "parameter `%s' has just a forward declaration");
+         error_with_decl (decl,
+                          "parameter `%s' has just a forward declaration");
          TREE_CHAIN (decl) = new_parms;
          new_parms = decl;
        }
          TREE_CHAIN (decl) = new_parms;
          new_parms = decl;
        }
@@ -5087,13 +5227,13 @@ parmlist_tags_warning ()
                  : "enum"),
                 IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
       else
                  : "enum"),
                 IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
       else
-        {
-          /* For translation these need to be seperate warnings */
-          if (code == RECORD_TYPE)
+       {
+         /* For translation these need to be seperate warnings */
+         if (code == RECORD_TYPE)
            warning ("anonymous struct declared inside parameter list");
          else if (code == UNION_TYPE)
            warning ("anonymous union declared inside parameter list");
            warning ("anonymous struct declared inside parameter list");
          else if (code == UNION_TYPE)
            warning ("anonymous union declared inside parameter list");
-         else    
+         else
            warning ("anonymous enum declared inside parameter list");
        }
       if (! already)
            warning ("anonymous enum declared inside parameter list");
        }
       if (! already)
@@ -5133,7 +5273,7 @@ xref_tag (code, name)
     {
       /* (In ANSI, Enums can be referred to only if already defined.)  */
       if (pedantic)
     {
       /* (In ANSI, Enums can be referred to only if already defined.)  */
       if (pedantic)
-       pedwarn ("ANSI C forbids forward references to `enum' types");
+       pedwarn ("ISO C forbids forward references to `enum' types");
       /* Give the type a default layout like unsigned int
         to avoid crashing if it does not get defined.  */
       TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
       /* Give the type a default layout like unsigned int
         to avoid crashing if it does not get defined.  */
       TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
@@ -5313,6 +5453,7 @@ finish_struct (t, fieldlist, attributes)
       /* Detect invalid bit-field type.  */
       if (DECL_INITIAL (x)
          && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
       /* Detect invalid bit-field type.  */
       if (DECL_INITIAL (x)
          && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
+         && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
          && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
        {
          error_with_decl (x, "bit-field `%s' has invalid type");
          && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
        {
          error_with_decl (x, "bit-field `%s' has invalid type");
@@ -5322,20 +5463,25 @@ finish_struct (t, fieldlist, attributes)
       if (DECL_INITIAL (x) && pedantic
          && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
          && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
       if (DECL_INITIAL (x) && pedantic
          && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
          && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
+         && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
          /* Accept an enum that's equivalent to int or unsigned int.  */
          && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
               && (TYPE_PRECISION (TREE_TYPE (x))
                   == TYPE_PRECISION (integer_type_node))))
          /* Accept an enum that's equivalent to int or unsigned int.  */
          && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
               && (TYPE_PRECISION (TREE_TYPE (x))
                   == TYPE_PRECISION (integer_type_node))))
-       pedwarn_with_decl (x, "bit-field `%s' type invalid in ANSI C");
+       pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
 
       /* Detect and ignore out of range field width and process valid
         field widths.  */
       if (DECL_INITIAL (x))
        {
 
       /* Detect and ignore out of range field width and process valid
         field widths.  */
       if (DECL_INITIAL (x))
        {
+         int max_width;
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node)
+           max_width = CHAR_TYPE_SIZE;
+         else
+           max_width = TYPE_PRECISION (TREE_TYPE (x));
          if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
            error_with_decl (x, "negative width in bit-field `%s'");
          if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
            error_with_decl (x, "negative width in bit-field `%s'");
-         else if (0 < compare_tree_int (DECL_INITIAL (x), 
-                                        TYPE_PRECISION (TREE_TYPE (x))))
+         else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
            pedwarn_with_decl (x, "width of `%s' exceeds its type");
          else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
            error_with_decl (x, "zero width for bit-field `%s'");
            pedwarn_with_decl (x, "width of `%s' exceeds its type");
          else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
            error_with_decl (x, "zero width for bit-field `%s'");
@@ -5355,7 +5501,8 @@ finish_struct (t, fieldlist, attributes)
                                   "`%s' is narrower than values of its type");
 
              DECL_SIZE (x) = bitsize_int (width);
                                   "`%s' is narrower than values of its type");
 
              DECL_SIZE (x) = bitsize_int (width);
-             DECL_BIT_FIELD (x) = DECL_C_BIT_FIELD (x) = 1;
+             DECL_BIT_FIELD (x) = 1;
+             SET_DECL_C_BIT_FIELD (x);
 
              if (width == 0)
                {
 
              if (width == 0)
                {
@@ -5398,7 +5545,7 @@ finish_struct (t, fieldlist, attributes)
     else
       {
        register tree y = fieldlist;
     else
       {
        register tree y = fieldlist;
-         
+
        while (1)
          {
            if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
        while (1)
          {
            if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
@@ -5412,7 +5559,8 @@ finish_struct (t, fieldlist, attributes)
            error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
            TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
          }
            error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
            TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
          }
-       else x = TREE_CHAIN (x);
+       else
+         x = TREE_CHAIN (x);
       }
 
   /* Now we have the nearly final fieldlist.  Record it,
       }
 
   /* Now we have the nearly final fieldlist.  Record it,
@@ -5463,7 +5611,7 @@ finish_struct (t, fieldlist, attributes)
       tree decl;
       for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl))
        {
       tree decl;
       for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl))
        {
-         if (TREE_TYPE (decl) == t
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
              && TREE_CODE (decl) != TYPE_DECL)
            {
              layout_decl (decl, 0);
              && TREE_CODE (decl) != TYPE_DECL)
            {
              layout_decl (decl, 0);
@@ -5721,7 +5869,7 @@ build_enumerator (name, value)
 
   if (pedantic && ! int_fits_type_p (value, integer_type_node))
     {
 
   if (pedantic && ! int_fits_type_p (value, integer_type_node))
     {
-      pedwarn ("ANSI C restricts enumerator values to range of `int'");
+      pedwarn ("ISO C restricts enumerator values to range of `int'");
       value = convert (integer_type_node, value);
     }
 
       value = convert (integer_type_node, value);
     }
 
@@ -5744,6 +5892,7 @@ build_enumerator (name, value)
 
   return tree_cons (decl, value, NULL_TREE);
 }
 
   return tree_cons (decl, value, NULL_TREE);
 }
+
 \f
 /* Create the FUNCTION_DECL for a function definition.
    DECLSPECS, DECLARATOR, PREFIX_ATTRIBUTES and ATTRIBUTES are the parts of
 \f
 /* Create the FUNCTION_DECL for a function definition.
    DECLSPECS, DECLARATOR, PREFIX_ATTRIBUTES and ATTRIBUTES are the parts of
@@ -5840,7 +5989,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
   else if (warn_missing_prototypes
           && TREE_PUBLIC (decl1)
           && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)
   else if (warn_missing_prototypes
           && TREE_PUBLIC (decl1)
           && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)
-          && strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))))
+          && ! MAIN_NAME_P (DECL_NAME (decl1)))
     warning_with_decl (decl1, "no previous prototype for `%s'");
   /* Optionally warn of any def with no previous prototype
      if the function has already been used.  */
     warning_with_decl (decl1, "no previous prototype for `%s'");
   /* Optionally warn of any def with no previous prototype
      if the function has already been used.  */
@@ -5848,12 +5997,12 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
           && old_decl != 0 && TREE_USED (old_decl)
           && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
     warning_with_decl (decl1,
           && old_decl != 0 && TREE_USED (old_decl)
           && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
     warning_with_decl (decl1,
-                     "`%s' was used with no prototype before its definition");
+                      "`%s' was used with no prototype before its definition");
   /* Optionally warn of any global def with no previous declaration.  */
   else if (warn_missing_declarations
           && TREE_PUBLIC (decl1)
           && old_decl == 0
   /* Optionally warn of any global def with no previous declaration.  */
   else if (warn_missing_declarations
           && TREE_PUBLIC (decl1)
           && old_decl == 0
-          && strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))))
+          && ! MAIN_NAME_P (DECL_NAME (decl1)))
     warning_with_decl (decl1, "no previous declaration for `%s'");
   /* Optionally warn of any def with no previous declaration
      if the function has already been used.  */
     warning_with_decl (decl1, "no previous declaration for `%s'");
   /* Optionally warn of any def with no previous declaration
      if the function has already been used.  */
@@ -5861,7 +6010,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
           && old_decl != 0 && TREE_USED (old_decl)
           && old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
     warning_with_decl (decl1,
           && old_decl != 0 && TREE_USED (old_decl)
           && old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
     warning_with_decl (decl1,
-                   "`%s' was used with no declaration before its definition");
+                      "`%s' was used with no declaration before its definition");
 
   /* This is a definition, not a reference.
      So normally clear DECL_EXTERNAL.
 
   /* This is a definition, not a reference.
      So normally clear DECL_EXTERNAL.
@@ -5872,7 +6021,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
 #ifdef SET_DEFAULT_DECL_ATTRIBUTES
   SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes);
 #endif
 #ifdef SET_DEFAULT_DECL_ATTRIBUTES
   SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes);
 #endif
-  
+
   /* This function exists in static storage.
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
   /* This function exists in static storage.
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
@@ -5881,15 +6030,14 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
   if (current_function_decl != 0)
     TREE_PUBLIC (decl1) = 0;
 
   if (current_function_decl != 0)
     TREE_PUBLIC (decl1) = 0;
 
-  /* Warn for unlikely, improbable, or stupid declarations of `main'. */
-  if (warn_main > 0
-      && strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))) == 0)
+  /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
+  if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
     {
       tree args;
       int argct = 0;
 
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
     {
       tree args;
       int argct = 0;
 
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
-          != integer_type_node)
+         != integer_type_node)
        pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
 
       for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
        pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
 
       for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
@@ -5915,7 +6063,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
                  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                      != char_type_node))
                pedwarn_with_decl (decl1,
                  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                      != char_type_node))
                pedwarn_with_decl (decl1,
-                              "second argument of `%s' should be `char **'");
+                                  "second argument of `%s' should be `char **'");
              break;
 
            case 3:
              break;
 
            case 3:
@@ -5924,14 +6072,14 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
                  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                      != char_type_node))
                pedwarn_with_decl (decl1,
                  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                      != char_type_node))
                pedwarn_with_decl (decl1,
-                  "third argument of `%s' should probably be `char **'");
+                                  "third argument of `%s' should probably be `char **'");
              break;
            }
        }
 
       /* It is intentional that this message does not mention the third
         argument, which is warned for only pedantically, because it's
              break;
            }
        }
 
       /* It is intentional that this message does not mention the third
         argument, which is warned for only pedantically, because it's
-        blessed by mention in an appendix of the standard. */
+        blessed by mention in an appendix of the standard.  */
       if (argct > 0 && (argct < 2 || argct > 3))
        pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments");
 
       if (argct > 0 && (argct < 2 || argct > 3))
        pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments");
 
@@ -6096,8 +6244,7 @@ store_parm_decls ()
             won't depend on its type.  */
          TREE_TYPE (dummy) = integer_type_node;
          DECL_ARG_TYPE (dummy) = integer_type_node;
             won't depend on its type.  */
          TREE_TYPE (dummy) = integer_type_node;
          DECL_ARG_TYPE (dummy) = integer_type_node;
-         DECL_ARGUMENTS (fndecl)
-           = chainon (DECL_ARGUMENTS (fndecl), dummy);
+         DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), dummy);
        }
 #endif
 
        }
 #endif
 
@@ -6190,14 +6337,16 @@ store_parm_decls ()
              DECL_ARG_TYPE (found) = TREE_TYPE (found);
              DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
              DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
              DECL_ARG_TYPE (found) = TREE_TYPE (found);
              DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
              DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
-             if (extra_warnings)
+             if (flag_isoc99)
+               pedwarn_with_decl (found, "type of `%s' defaults to `int'");
+             else if (extra_warnings)
                warning_with_decl (found, "type of `%s' defaults to `int'");
              pushdecl (found);
            }
 
          TREE_PURPOSE (parm) = found;
 
                warning_with_decl (found, "type of `%s' defaults to `int'");
              pushdecl (found);
            }
 
          TREE_PURPOSE (parm) = found;
 
-         /* Mark this decl as "already found" */
+         /* Mark this decl as "already found" */
          DECL_WEAK (found) = 1;
        }
 
          DECL_WEAK (found) = 1;
        }
 
@@ -6208,7 +6357,7 @@ store_parm_decls ()
         any actual PARM_DECLs not matched with any names.  */
 
       nonparms = 0;
         any actual PARM_DECLs not matched with any names.  */
 
       nonparms = 0;
-      for (parm = parmdecls; parm; )
+      for (parm = parmdecls; parm;)
        {
          tree next = TREE_CHAIN (parm);
          TREE_CHAIN (parm) = 0;
        {
          tree next = TREE_CHAIN (parm);
          TREE_CHAIN (parm) = 0;
@@ -6219,19 +6368,19 @@ store_parm_decls ()
            {
              /* Complain about args with incomplete types.  */
              if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
            {
              /* Complain about args with incomplete types.  */
              if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
-               {
-                 error_with_decl (parm, "parameter `%s' has incomplete type");
-                 TREE_TYPE (parm) = error_mark_node;
-               }
+               {
+                 error_with_decl (parm, "parameter `%s' has incomplete type");
+                 TREE_TYPE (parm) = error_mark_node;
+               }
 
              if (! DECL_WEAK (parm))
 
              if (! DECL_WEAK (parm))
-               {
-                 error_with_decl (parm,
-                                  "declaration for parameter `%s' but no such parameter");
+               {
+                 error_with_decl (parm,
+                                  "declaration for parameter `%s' but no such parameter");
                  /* Pretend the parameter was not missing.
                     This gets us to a standard state and minimizes
                     further error messages.  */
                  /* Pretend the parameter was not missing.
                     This gets us to a standard state and minimizes
                     further error messages.  */
-                 specparms
+                 specparms
                    = chainon (specparms,
                               tree_cons (parm, NULL_TREE, NULL_TREE));
                }
                    = chainon (specparms,
                               tree_cons (parm, NULL_TREE, NULL_TREE));
                }
@@ -6240,8 +6389,9 @@ store_parm_decls ()
          parm = next;
        }
 
          parm = next;
        }
 
-      /* Chain the declarations together in the order of the list of names.  */
-      /* Store that chain in the function decl, replacing the list of names.  */
+      /* Chain the declarations together in the order of the list of
+         names.  Store that chain in the function decl, replacing the
+         list of names.  */
       parm = specparms;
       DECL_ARGUMENTS (fndecl) = 0;
       {
       parm = specparms;
       DECL_ARGUMENTS (fndecl) = 0;
       {
@@ -6391,25 +6541,20 @@ store_parm_decls ()
 
   init_function_start (fndecl, input_filename, lineno);
 
 
   init_function_start (fndecl, input_filename, lineno);
 
-  /* If this is a varargs function, inform function.c.  */
-
-  if (c_function_varargs)
-    mark_varargs ();
-
-  /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function.  */
+  /* Begin the statement tree for this function.  */
+  DECL_LANG_SPECIFIC (current_function_decl) 
+    =((struct lang_decl *) ggc_alloc (sizeof (struct lang_decl)));
+  begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
 
 
-  declare_function_name ();
-
-  /* Set up parameters and prepare for return, for the function.  */
+  /* This function is being processed in whole-function mode.  */
+  cfun->x_whole_function_mode_p = 1;
 
 
-  expand_function_start (fndecl, 0);
-
-  /* If this function is `main', emit a call to `__main'
-     to run global initializers, etc.  */
-  if (DECL_NAME (fndecl)
-      && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
-      && DECL_CONTEXT (fndecl) == NULL_TREE)
-    expand_main_function ();
+  /* Even though we're inside a function body, we still don't want to
+     call expand_expr to calculate the size of a variable-sized array.
+     We haven't necessarily assigned RTL to all variables yet, so it's
+     not safe to try to expand expressions involving them.  */
+  immediate_size_expand = 0;
+  cfun->x_dont_save_pending_sizes_p = 1;
 }
 \f
 /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes
 }
 \f
 /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes
@@ -6500,7 +6645,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
 
   /* Complain about any actual PARM_DECLs not matched with any names.  */
 
 
   /* Complain about any actual PARM_DECLs not matched with any names.  */
 
-  for (parm = parmdecls; parm; )
+  for (parm = parmdecls; parm;)
     {
       tree next = TREE_CHAIN (parm);
       TREE_CHAIN (parm) = 0;
     {
       tree next = TREE_CHAIN (parm);
       TREE_CHAIN (parm) = 0;
@@ -6547,7 +6692,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
          types = tree_cons (NULL_TREE, TREE_TYPE (parm), types);
        }
   }
          types = tree_cons (NULL_TREE, TREE_TYPE (parm), types);
        }
   }
-  
+
   if (void_at_end)
     return tree_cons (parmdecls, nonparms,
                      nreverse (tree_cons (NULL_TREE, void_type_node, types)));
   if (void_at_end)
     return tree_cons (parmdecls, nonparms,
                      nreverse (tree_cons (NULL_TREE, void_type_node, types)));
@@ -6587,13 +6732,13 @@ finish_function (nested)
       setjmp_protect_args ();
     }
 
       setjmp_protect_args ();
     }
 
-  if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main"))
+  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
          != integer_type_node)
        {
          /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
          != integer_type_node)
        {
          /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
-            If warn_main is -1 (-Wno-main) we don't want to be warned. */
+            If warn_main is -1 (-Wno-main) we don't want to be warned.  */
          if (! warn_main)
            pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
        }
          if (! warn_main)
            pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
        }
@@ -6602,47 +6747,115 @@ finish_function (nested)
 #ifdef DEFAULT_MAIN_RETURN
          /* Make it so that `main' always returns success by default.  */
          DEFAULT_MAIN_RETURN;
 #ifdef DEFAULT_MAIN_RETURN
          /* Make it so that `main' always returns success by default.  */
          DEFAULT_MAIN_RETURN;
+#else
+         if (flag_isoc99)
+           c_expand_return (integer_zero_node);
 #endif
        }
     }
 
 #endif
        }
     }
 
+  /* Tie off the statement tree for this function.  */
+  finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
+  /* Clear out memory we no longer need.  */
+  free_after_parsing (cfun);
+  /* Since we never call rest_of_compilation, we never clear
+     CFUN.  Do so explicitly.  */
+  free_after_compilation (cfun);
+  cfun = NULL;
+
+  if (! nested)
+    {
+      /* Generate RTL for the body of this function.  */
+      c_expand_body (fndecl, nested);
+      /* Let the error reporting routines know that we're outside a
+        function.  For a nested function, this value is used in
+        pop_c_function_context and then reset via pop_function_context.  */
+      current_function_decl = NULL;
+      c_function_name_declared_p = 0;
+    }
+}
+
+/* Generate the RTL for the body of FNDECL.  If NESTED_P is non-zero,
+   then we are already in the process of generating RTL for another
+   function.  */
+
+static void
+c_expand_body (fndecl, nested_p)
+     tree fndecl;
+     int nested_p;
+{
+  /* There's no reason to do any of the work here if we're only doing
+     semantic analysis; this code just generates RTL.  */
+  if (flag_syntax_only)
+    return;
+
+  /* Squirrel away our current state.  */
+  if (nested_p)
+    push_function_context ();
+
+  /* Initialize the RTL code for the function.  */
+  current_function_decl = fndecl;
+  init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
+
+  /* This function is being processed in whole-function mode.  */
+  cfun->x_whole_function_mode_p = 1;
+
+  /* Even though we're inside a function body, we still don't want to
+     call expand_expr to calculate the size of a variable-sized array.
+     We haven't necessarily assigned RTL to all variables yet, so it's
+     not safe to try to expand expressions involving them.  */
+  immediate_size_expand = 0;
+  cfun->x_dont_save_pending_sizes_p = 1;
+
+  /* If this is a varargs function, inform function.c.  */
+  if (c_function_varargs)
+    mark_varargs ();
+
+  /* Set up parameters and prepare for return, for the function.  */
+  expand_function_start (fndecl, 0);
+
+  /* If this function is `main', emit a call to `__main'
+     to run global initializers, etc.  */
+  if (DECL_NAME (fndecl)
+      && MAIN_NAME_P (DECL_NAME (fndecl))
+      && DECL_CONTEXT (fndecl) == NULL_TREE)
+    expand_main_function ();
+
+  /* Generate the RTL for this function.  */
+  expand_stmt (DECL_SAVED_TREE (fndecl));
+  /* Allow the body of the function to be garbage collected.  */
+  DECL_SAVED_TREE (fndecl) = NULL_TREE;
+
+  /* We hard-wired immediate_size_expand to zero in start_function.
+     expand_function_end will decrement this variable.  So, we set the
+     variable to one here, so that after the decrement it will remain
+     zero.  */
+  immediate_size_expand = 1;
+
+  /* Allow language dialects to perform special processing.  */
+  if (lang_expand_function_end)
+    (*lang_expand_function_end) ();
+
   /* Generate rtl for function exit.  */
   expand_function_end (input_filename, lineno, 0);
 
   /* Generate rtl for function exit.  */
   expand_function_end (input_filename, lineno, 0);
 
-  /* So we can tell if jump_optimize sets it to 1.  */
-  can_reach_end = 0;
-
   /* If this is a nested function, protect the local variables in the stack
      above us from being collected while we're compiling this function.  */
   /* If this is a nested function, protect the local variables in the stack
      above us from being collected while we're compiling this function.  */
-  if (nested)
+  if (nested_p)
     ggc_push_context ();
 
   /* Run the optimizers and output the assembler code for this function.  */
   rest_of_compilation (fndecl);
 
   /* Undo the GC context switch.  */
     ggc_push_context ();
 
   /* Run the optimizers and output the assembler code for this function.  */
   rest_of_compilation (fndecl);
 
   /* Undo the GC context switch.  */
-  if (nested)
+  if (nested_p)
     ggc_pop_context ();
 
     ggc_pop_context ();
 
-  current_function_returns_null |= can_reach_end;
-
-  if (warn_missing_noreturn
-      && !TREE_THIS_VOLATILE (fndecl)
-      && !current_function_returns_null
-      && !current_function_returns_value)
-    warning ("function might be possible candidate for attribute `noreturn'");
-
-  if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
-    warning ("`noreturn' function does return");
-  else if (warn_return_type && can_reach_end
-          && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
-    /* If this function returns non-void and control can drop through,
-       complain.  */
-    warning ("control reaches end of non-void function");
   /* With just -W, complain only if function returns both with
      and without a value.  */
   /* With just -W, complain only if function returns both with
      and without a value.  */
-  else if (extra_warnings
-          && current_function_returns_value && current_function_returns_null)
+  if (extra_warnings
+      && current_function_returns_value
+      && current_function_returns_null)
     warning ("this function may return with or without a value");
 
   /* If requested, warn about function definitions where the function will
     warning ("this function may return with or without a value");
 
   /* If requested, warn about function definitions where the function will
@@ -6666,16 +6879,16 @@ finish_function (nested)
                               size_as_int);
          else
            warning_with_decl (fndecl,
                               size_as_int);
          else
            warning_with_decl (fndecl,
-                      "size of return value of `%s' is larger than %d bytes",
+                              "size of return value of `%s' is larger than %d bytes",
                               larger_than_size);
        }
     }
 
                               larger_than_size);
        }
     }
 
-  if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested)
+  if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested_p)
     {
     {
-      /* Stop pointing to the local nodes about to be freed. 
+      /* Stop pointing to the local nodes about to be freed.
         But DECL_INITIAL must remain nonzero so we know this
         But DECL_INITIAL must remain nonzero so we know this
-        was an actual function definition. 
+        was an actual function definition.
         For a nested function, this is done in pop_c_function_context.
         If rest_of_compilation set this to 0, leave it 0.  */
       if (DECL_INITIAL (fndecl) != 0)
         For a nested function, this is done in pop_c_function_context.
         If rest_of_compilation set this to 0, leave it 0.  */
       if (DECL_INITIAL (fndecl) != 0)
@@ -6691,7 +6904,7 @@ finish_function (nested)
        static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
       else
 #endif
        static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
       else
 #endif
-       assemble_constructor (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))); 
+       assemble_constructor (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
 
     }
   if (DECL_STATIC_DESTRUCTOR (fndecl))
 
     }
   if (DECL_STATIC_DESTRUCTOR (fndecl))
@@ -6704,12 +6917,68 @@ finish_function (nested)
        assemble_destructor (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
     }
 
        assemble_destructor (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
     }
 
-  if (! nested)
+  if (nested_p)
     {
     {
-      /* Let the error reporting routines know that we're outside a
-        function.  For a nested function, this value is used in
-        pop_c_function_context and then reset via pop_function_context.  */
-      current_function_decl = NULL;
+      /* Return to the enclosing function.  */
+      pop_function_context ();
+      /* If the nested function was inline, write it out if that is
+        necessary.  */
+      if (!TREE_ASM_WRITTEN (fndecl) && TREE_ADDRESSABLE (fndecl))
+       {
+         push_function_context ();
+         output_inline_function (fndecl);
+         pop_function_context ();
+       }
+    }
+      
+}
+\f
+/* Check the declarations given in a for-loop for satisfying the C99
+   constraints.  */
+void
+check_for_loop_decls ()
+{
+  tree t;
+
+  if (!flag_isoc99)
+    {
+      /* If we get here, declarations have been used in a for loop without
+        the C99 for loop scope.  This doesn't make much sense, so don't
+        allow it.  */
+      error ("`for' loop initial declaration used outside C99 mode");
+      return;
+    }
+  /* C99 subclause 6.8.5 paragraph 3:
+
+       [#3]  The  declaration  part  of  a for statement shall only
+       declare identifiers for objects having storage class auto or
+       register.
+
+     It isn't clear whether, in this sentence, "identifiers" binds to
+     "shall only declare" or to "objects" - that is, whether all identifiers
+     declared must be identifiers for objects, or whether the restriction
+     only applies to those that are.  (A question on this in comp.std.c
+     in November 2000 received no answer.)  We implement the strictest
+     interpretation, to avoid creating an extension which later causes
+     problems.  */
+
+  for (t = gettags (); t; t = TREE_CHAIN (t))
+    {
+      if (TREE_PURPOSE (t) != 0)
+       error ("`%s %s' declared in `for' loop initial declaration",
+              (TREE_CODE (TREE_VALUE (t)) == RECORD_TYPE ? "struct"
+               : TREE_CODE (TREE_VALUE (t)) == UNION_TYPE ? "union"
+               : "enum"),
+              IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+    }
+  for (t = getdecls (); t; t = TREE_CHAIN (t))
+    {
+      if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
+       error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
+      else if (TREE_STATIC (t))
+       error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
+      else if (DECL_EXTERNAL (t))
+       error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
     }
 }
 \f
     }
 }
 \f
@@ -6717,8 +6986,9 @@ finish_function (nested)
    that keep track of the progress of compilation of the current function.
    Used for nested functions.  */
 
    that keep track of the progress of compilation of the current function.
    Used for nested functions.  */
 
-struct language_function
+struct c_language_function
 {
 {
+  struct language_function base;
   tree named_labels;
   tree shadowed_labels;
   int returns_value;
   tree named_labels;
   tree shadowed_labels;
   int returns_value;
@@ -6735,10 +7005,14 @@ void
 push_c_function_context (f)
      struct function *f;
 {
 push_c_function_context (f)
      struct function *f;
 {
-  struct language_function *p;
-  p = (struct language_function *) xmalloc (sizeof (struct language_function));
-  f->language = p;
-
+  struct c_language_function *p;
+  p = ((struct c_language_function *) 
+       xmalloc (sizeof (struct c_language_function)));
+  f->language = (struct language_function *) p;
+
+  p->base.x_stmt_tree = c_stmt_tree;
+  p->base.x_scope_stmt_stack = c_scope_stmt_stack;
+  p->base.x_function_name_declared_p = c_function_name_declared_p;
   p->named_labels = named_labels;
   p->shadowed_labels = shadowed_labels;
   p->returns_value = current_function_returns_value;
   p->named_labels = named_labels;
   p->shadowed_labels = shadowed_labels;
   p->returns_value = current_function_returns_value;
@@ -6754,7 +7028,8 @@ void
 pop_c_function_context (f)
      struct function *f;
 {
 pop_c_function_context (f)
      struct function *f;
 {
-  struct language_function *p = f->language;
+  struct c_language_function *p 
+    = (struct c_language_function *) f->language;
   tree link;
 
   /* Bring back all the labels that were shadowed.  */
   tree link;
 
   /* Bring back all the labels that were shadowed.  */
@@ -6763,7 +7038,8 @@ pop_c_function_context (f)
       IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
        = TREE_VALUE (link);
 
       IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
        = TREE_VALUE (link);
 
-  if (DECL_SAVED_INSNS (current_function_decl) == 0)
+  if (DECL_SAVED_INSNS (current_function_decl) == 0
+      && DECL_SAVED_TREE (current_function_decl) == NULL_TREE)
     {
       /* Stop pointing to the local nodes about to be freed.  */
       /* But DECL_INITIAL must remain nonzero so we know this
     {
       /* Stop pointing to the local nodes about to be freed.  */
       /* But DECL_INITIAL must remain nonzero so we know this
@@ -6772,6 +7048,9 @@ pop_c_function_context (f)
       DECL_ARGUMENTS (current_function_decl) = 0;
     }
 
       DECL_ARGUMENTS (current_function_decl) = 0;
     }
 
+  c_stmt_tree = p->base.x_stmt_tree;
+  c_scope_stmt_stack = p->base.x_scope_stmt_stack;
+  c_function_name_declared_p = p->base.x_function_name_declared_p;
   named_labels = p->named_labels;
   shadowed_labels = p->shadowed_labels;
   current_function_returns_value = p->returns_value;
   named_labels = p->named_labels;
   shadowed_labels = p->shadowed_labels;
   current_function_returns_value = p->returns_value;
@@ -6785,40 +7064,42 @@ pop_c_function_context (f)
 }
 
 /* Mark the language specific parts of F for GC.  */
 }
 
 /* Mark the language specific parts of F for GC.  */
+
 void
 mark_c_function_context (f)
      struct function *f;
 {
 void
 mark_c_function_context (f)
      struct function *f;
 {
-  struct language_function *p = f->language;
+  struct c_language_function *p 
+    = (struct c_language_function *) f->language;
 
   if (p == 0)
     return;
 
 
   if (p == 0)
     return;
 
+  mark_c_language_function (&p->base);
   ggc_mark_tree (p->shadowed_labels);
   ggc_mark_tree (p->named_labels);
   mark_binding_level (&p->binding_level);
 }
 
   ggc_mark_tree (p->shadowed_labels);
   ggc_mark_tree (p->named_labels);
   mark_binding_level (&p->binding_level);
 }
 
-/* integrate_decl_tree calls this function, but since we don't use the
-   DECL_LANG_SPECIFIC field, this is a no-op.  */
+/* Copy the DECL_LANG_SEPECIFIC data associated with NODE.  */
 
 void
 
 void
-copy_lang_decl (node)
-     tree node ATTRIBUTE_UNUSED;
+copy_lang_decl (decl)
+     tree decl;
 {
 {
-}
+  struct lang_decl *ld;
 
 
-/* Mark ARG for GC.  */
-void
-lang_mark_false_label_stack (arg)
-     struct label_node *arg;
-{
-  /* C doesn't use false_label_stack.  It better be NULL.  */
-  if (arg != NULL)
-    abort();
+  if (!DECL_LANG_SPECIFIC (decl))
+    return;
+
+  ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl));
+  memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl),
+         sizeof (struct lang_decl));
+  DECL_LANG_SPECIFIC (decl) = ld;
 }
 
 /* Mark the language specific bits in T for GC.  */
 }
 
 /* Mark the language specific bits in T for GC.  */
+
 void
 lang_mark_tree (t)
      tree t;
 void
 lang_mark_tree (t)
      tree t;
@@ -6835,12 +7116,17 @@ lang_mark_tree (t)
     }
   else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
     ggc_mark (TYPE_LANG_SPECIFIC (t));
     }
   else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
     ggc_mark (TYPE_LANG_SPECIFIC (t));
+  else if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+    {
+      ggc_mark (DECL_LANG_SPECIFIC (t));
+      c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base);
+    }
 }
 
 /* The functions below are required for functionality of doing
    function at once processing in the C front end. Currently these
    functions are not called from anywhere in the C front end, but as
 }
 
 /* The functions below are required for functionality of doing
    function at once processing in the C front end. Currently these
    functions are not called from anywhere in the C front end, but as
-   these changes continue, that will change. */
+   these changes continue, that will change.  */
 
 /* Returns non-zero if the current statement is a full expression,
    i.e. temporaries created during that statement should be destroyed
 
 /* Returns non-zero if the current statement is a full expression,
    i.e. temporaries created during that statement should be destroyed
@@ -6852,109 +7138,74 @@ stmts_are_full_exprs_p ()
   return 0;
 }
 
   return 0;
 }
 
-/* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
-   C. */
+/* Returns the stmt_tree (if any) to which statements are currently
+   being added.  If there is no active statement-tree, NULL is
+   returned.  */
 
 
-int 
-anon_aggr_type_p (node)
-     tree node ATTRIBUTE_UNUSED;
+stmt_tree
+current_stmt_tree ()
 {
 {
-  return 0;
+  return &c_stmt_tree;
+}
+
+/* Returns the stack of SCOPE_STMTs for the current function.  */
+
+tree *
+current_scope_stmt_stack ()
+{
+  return &c_scope_stmt_stack;
 }
 
 }
 
-/* One if we have already declared __FUNCTION__ (and related
-   variables) in the current function.  Two if we are in the process
-   of doing so.  */
+/* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
+   C.  */
 
 int
 
 int
-current_function_name_declared ()
+anon_aggr_type_p (node)
+     tree node ATTRIBUTE_UNUSED;
 {
 {
-  abort ();
   return 0;
 }
 
   return 0;
 }
 
-/* Code to generate the RTL for a case label in C. */
+/* Dummy function in place of callback used by C++.  */
 
 void
 
 void
-do_case (low_value, high_value)
-     tree low_value;
-     tree high_value;
+extract_interface_info ()
 {
 {
-  tree value1 = NULL_TREE, value2 = NULL_TREE, label;
-
-  if (low_value != NULL_TREE)
-    value1 = check_case_value (low_value);
-  if (high_value != NULL_TREE)
-    value2 = check_case_value (high_value);
-
-  label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-  
-  if (pedantic && (high_value != NULL_TREE))
-    pedwarn ("ANSI C forbids case ranges");
-
-  if (value1 != error_mark_node && value2 != error_mark_node)
-    {
-      tree duplicate;
-      int success;
-      
-      if (high_value == NULL_TREE && value1 != NULL_TREE &&
-         pedantic && ! INTEGRAL_TYPE_P (TREE_TYPE (value1)))
-       pedwarn ("label must have integral type in ANSI C");
-      
-      if (low_value == NULL_TREE)
-       success = pushcase (NULL_TREE, 0, label, &duplicate);
-      else if (high_value == NULL_TREE)
-       success = pushcase (value1, convert_and_check, label,
-                           &duplicate);
-      else
-       success = pushcase_range (value1, value2, convert_and_check,
-                                 label, &duplicate);
-      
-      if (success == 1)
-       {
-         if (low_value == NULL_TREE)
-           error ("default label not within a switch statement");
-         else
-           error ("case label not within a switch statement");
-       }
-      else if (success == 2) {
-       if (low_value == NULL_TREE) 
-         {
-           error ("multiple default labels in one switch");
-           error_with_decl (duplicate, "this is the first default label");
-         }
-       else
-         error ("dupicate case value");
-       if (high_value != NULL_TREE)
-         error_with_decl (duplicate, "this is the first entry for that value");
-      }
-      else if (low_value != NULL_TREE) 
-       {
-         if (success == 3)
-           warning ("case value out of range");
-         else if (success == 5)
-           error ("case label within scope of cleanup or variable array");
-       }
-    }
 }
 
 }
 
-/* Language specific handler of tree nodes used when generating RTL
-   from a tree. */
+/* Return a new COMPOUND_STMT, after adding it to the current
+   statement tree.  */
 
 tree
 
 tree
-lang_expand_stmt (t)
-     tree t ATTRIBUTE_UNUSED;
+c_begin_compound_stmt ()
 {
 {
-  abort ();
-  return NULL_TREE;
+  tree stmt;
+
+  /* Create the COMPOUND_STMT.  */
+  stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
+  /* If we haven't already declared __FUNCTION__ and its ilk then this
+     is the opening curly brace of the function.  Declare them now.  */
+  if (!c_function_name_declared_p) 
+    {
+      c_function_name_declared_p = 1;
+      declare_function_name ();
+    }
+  
+  return stmt;
 }
 
 }
 
-/* Accessor to set the 'current_function_name_declared' flag. */
+/* Expand T (a DECL_STMT) if it declares an entity not handled by the
+   common code.  */
 
 void
 
 void
-set_current_function_name_declared (i)
-     int i ATTRIBUTE_UNUSED;
+c_expand_decl_stmt (t)
+     tree t;
 {
 {
-  abort ();
+  tree decl = DECL_STMT_DECL (t);
+  
+  /* Expand nested functions.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && DECL_CONTEXT (decl) == current_function_decl
+      && DECL_SAVED_TREE (decl))
+    c_expand_body (decl, /*nested_p=*/1);
 }
 }
-