OSDN Git Service

* i386.c (incdec_operand): Accept only 1 and -1.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 6d08dfc..0c08662 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
-   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -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.  */
 
-
 /* 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.  */
@@ -39,14 +38,9 @@ Boston, MA 02111-1307, USA.  */
 #include "c-tree.h"
 #include "c-lex.h"
 #include "toplev.h"
-#include "defaults.h"
 #include "ggc.h"
 #include "tm_p.h"
-
-#if USE_CPPLIB
 #include "cpplib.h"
-extern cpp_reader parse_in;
-#endif
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -57,31 +51,7 @@ enum decl_context
   BITFIELD,                    /* Likewise but with specified width */
   TYPENAME};                   /* Typename (inside cast or sizeof)  */
 
-/* We let tm.h override the types used here, to handle trivial differences
-   such as the choice of unsigned int or long unsigned int for size_t.
-   When machines start needing nontrivial differences in the size type,
-   it would be best to do something here to figure out automatically
-   from other information what type to use.  */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
-
-#ifndef WINT_TYPE
-#define WINT_TYPE "unsigned int"
-#endif
 \f
-/* Do GC.  */
-int ggc_p = 1;
-
 /* Nonzero if we have seen an invalid cross reference
    to a struct, union, or enum, but not yet printed the message.  */
 
@@ -126,6 +96,14 @@ static tree current_function_parm_tags;
 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;
+
 /* 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.  */
@@ -227,7 +205,7 @@ struct binding_level
     /* 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;
 
@@ -238,7 +216,7 @@ struct binding_level
   };
 
 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
-  
+
 /* The binding level currently in effect.  */
 
 static struct binding_level *current_binding_level;
@@ -267,7 +245,7 @@ static int keep_next_level_flag;
    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
@@ -296,7 +274,8 @@ static tree grokdeclarator          PARAMS ((tree, tree, enum decl_context,
                                                 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 tree c_make_fname_decl           PARAMS ((tree, int));
+static void c_expand_body               PARAMS ((tree, int));
 \f
 /* C-specific option variables.  */
 
@@ -305,32 +284,15 @@ static tree c_make_fname_decl           PARAMS ((tree, const char *, int));
 
 int flag_cond_mismatch;
 
-/* Nonzero means give `double' the same size as `float'.  */
-
-int flag_short_double;
-
-/* Nonzero means give `wchar_t' the same size as `short'.  */
-
-int flag_short_wchar;
-
 /* Nonzero means don't recognize the keyword `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 enable C89 Amendment 1 features, other than digraphs.  */
+/* Nonzero means enable C89 Amendment 1 features.  */
 
 int flag_isoc94 = 0;
 
@@ -338,14 +300,15 @@ int flag_isoc94 = 0;
 
 int flag_isoc99 = 0;
 
-/* Nonzero means accept digraphs.  */
-
-int flag_digraphs = 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;
@@ -355,7 +318,7 @@ int flag_allow_single_precision = 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;
 
@@ -364,7 +327,7 @@ int warn_implicit_int;
 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 = -1;
 
@@ -385,9 +348,9 @@ int warn_cast_qual;
 
 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.  */
 
@@ -426,10 +389,6 @@ int warn_redundant_decls = 0;
 
 int warn_nested_externs = 0;
 
-/* Warn about *printf or *scanf format/argument anomalies.  */
-
-int warn_format;
-
 /* Warn about a subscript that has type char.  */
 
 int warn_char_subscripts = 0;
@@ -452,14 +411,14 @@ int warn_main;
 
 /* 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 testing equality of floating point numbers. */
+/* Warn about testing equality of floating point numbers.  */
 
 int warn_float_equal = 0;
 
@@ -467,10 +426,6 @@ int warn_float_equal = 0;
 
 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;
@@ -485,25 +440,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.  */
-   
+
 int
 c_decode_option (argc, argv)
      int argc ATTRIBUTE_UNUSED;
      char **argv;
 {
   int strings_processed;
+  const char *option_value = NULL;
   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;
-      flag_digraphs = 0;
     }
   else if (!strcmp (p, "-fallow-single-precision"))
     flag_allow_single_precision = 1;
@@ -524,7 +476,6 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
-      flag_digraphs = 1;
     }
   else if (!strncmp (p, "-std=", 5))
     {
@@ -544,20 +495,19 @@ c_decode_option (argc, argv)
          || !strcmp (argstart, "c89"))
        {
        iso_1990:
-         flag_digraphs = 0;
          flag_isoc94 = 0;
-       iso_1990_digraphs:
+       iso_1994:
          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_digraphs = 1;
          flag_isoc94 = 1;
-         goto iso_1990_digraphs;
+         goto iso_1994;
        }
       else if (!strcmp (argstart, "iso9899:199x")
               || !strcmp (argstart, "iso9899:1999")
@@ -568,8 +518,8 @@ c_decode_option (argc, argv)
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
+         flag_noniso_default_format_attributes = 0;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
          flag_isoc94 = 1;
        }
       else if (!strcmp (argstart, "gnu89"))
@@ -578,8 +528,8 @@ c_decode_option (argc, argv)
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
+         flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 0;
-         flag_digraphs = 1;
          flag_isoc94 = 0;
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
@@ -588,8 +538,8 @@ c_decode_option (argc, argv)
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
+         flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
          flag_isoc94 = 1;
        }
       else
@@ -643,6 +593,14 @@ c_decode_option (argc, argv)
     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"))
@@ -659,7 +617,7 @@ c_decode_option (argc, argv)
     {
       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;
@@ -679,10 +637,12 @@ c_decode_option (argc, argv)
     warn_bad_function_cast = 1;
   else if (!strcmp (p, "-Wno-bad-function-cast"))
     warn_bad_function_cast = 0;
-  else if (!strcmp (p, "-Wmissing-noreturn"))
-    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"))
@@ -712,11 +672,27 @@ c_decode_option (argc, argv)
   else if (!strcmp (p, "-Wno-traditional"))
     warn_traditional = 0;
   else if (!strncmp (p, "-Wformat=", 9))
-    warn_format = atol (p + 9);
+    set_Wformat (atoi (p + 9));
   else if (!strcmp (p, "-Wformat"))
-    warn_format = 1;
+    set_Wformat (1);
   else if (!strcmp (p, "-Wno-format"))
-    warn_format = 0;
+    set_Wformat (0);
+  else if (!strcmp (p, "-Wformat-y2k"))
+    warn_format_y2k = 1;
+  else if (!strcmp (p, "-Wno-format-y2k"))
+    warn_format_y2k = 0;
+  else if (!strcmp (p, "-Wformat-extra-args"))
+    warn_format_extra_args = 1;
+  else if (!strcmp (p, "-Wno-format-extra-args"))
+    warn_format_extra_args = 0;
+  else if (!strcmp (p, "-Wformat-nonliteral"))
+    warn_format_nonliteral = 1;
+  else if (!strcmp (p, "-Wno-format-nonliteral"))
+    warn_format_nonliteral = 0;
+  else if (!strcmp (p, "-Wformat-security"))
+    warn_format_security = 1;
+  else if (!strcmp (p, "-Wno-format-security"))
+    warn_format_security = 0;
   else if (!strcmp (p, "-Wchar-subscripts"))
     warn_char_subscripts = 1;
   else if (!strcmp (p, "-Wno-char-subscripts"))
@@ -733,6 +709,10 @@ c_decode_option (argc, argv)
     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"))
@@ -791,9 +771,10 @@ c_decode_option (argc, argv)
       warn_return_type = 1;
       set_Wunused (1);
       warn_switch = 1;
-      warn_format = 1;
+      set_Wformat (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.  */
@@ -837,11 +818,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);
+  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
-   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;
@@ -851,10 +840,10 @@ finish_incomplete_decl (decl)
       tree type = TREE_TYPE (decl);
       if (type != error_mark_node
          && TREE_CODE (type) == ARRAY_TYPE
+         && ! DECL_EXTERNAL (decl)
          && 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);
 
@@ -865,8 +854,7 @@ finish_incomplete_decl (decl)
 \f
 /* Create a new `struct binding_level'.  */
 
-static
-struct binding_level *
+static struct binding_level *
 make_binding_level ()
 {
   /* NOSTRICT */
@@ -967,7 +955,7 @@ pushlevel (tag_transparent)
   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)
@@ -982,7 +970,7 @@ clear_limbo_values (block)
   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.
@@ -1071,14 +1059,14 @@ poplevel (keep, reverse, functionbody)
        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.  */
@@ -1183,8 +1171,8 @@ poplevel (keep, reverse, functionbody)
   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
@@ -1207,8 +1195,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"
-     tagged types.
-  */
+     tagged types.  */
 
   if (functionbody)
     for (link = tags; link; link = TREE_CHAIN (link))
@@ -1219,6 +1206,7 @@ poplevel (keep, reverse, functionbody)
 
   if (block)
     TREE_USED (block) = 1;
+
   return block;
 }
 
@@ -1267,6 +1255,10 @@ set_block (block)
      register tree block;
 {
   current_binding_level->this_block = block;
+  current_binding_level->names = chainon (current_binding_level->names,
+                                         BLOCK_VARS (block));
+  current_binding_level->blocks = chainon (current_binding_level->blocks,
+                                          BLOCK_SUBBLOCKS (block));
 }
 \f
 void
@@ -1318,7 +1310,7 @@ pop_label_level ()
                            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;
 
@@ -1418,7 +1410,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
 
   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)
@@ -1456,7 +1448,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");
+                              "built-in function `%s' declared as non-function");
        }
       else
        {
@@ -1500,24 +1492,24 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
        }
       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);
 
-          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));
-             
+
               types_match = comptypes (newtype, trytype);
              if (types_match)
                oldtype = trytype;
            }
          /* Accept harmless mismatch in first argument type also.
-            This is for ffs.  */
+            This is for the ffs and fprintf builtins.  */
          if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0
              && TYPE_ARG_TYPES (oldtype) != 0
              && TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0
@@ -1529,11 +1521,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                 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))));
-             
-              types_match = comptypes (newtype, trytype);
+
+             types_match = comptypes (newtype, trytype);
              if (types_match)
                oldtype = trytype;
            }
@@ -1668,11 +1660,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                            : "`%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'");
-         warning_with_decl 
+         warning_with_decl
            (olddecl,
             ((DECL_INITIAL (olddecl)
               && current_binding_level == global_binding_level)
@@ -1705,7 +1697,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)
                {
-                 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;
@@ -1752,8 +1745,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
-            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))
@@ -1805,11 +1798,17 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
       if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
        {
          if (different_binding_level)
-           TREE_TYPE (newdecl)
-             = build_type_attribute_variant
-               (newtype,
-                merge_attributes (TYPE_ATTRIBUTES (newtype),
-                                  TYPE_ATTRIBUTES (oldtype)));
+           {
+             if (TYPE_ARG_TYPES (oldtype) != 0
+                 && TYPE_ARG_TYPES (newtype) == 0)
+               TREE_TYPE (newdecl) = common_type (newtype, oldtype);
+             else
+               TREE_TYPE (newdecl)
+                 = build_type_attribute_variant
+                   (newtype,
+                    merge_attributes (TYPE_ATTRIBUTES (newtype),
+                                      TYPE_ATTRIBUTES (oldtype)));
+           }
          else
            TREE_TYPE (newdecl)
              = TREE_TYPE (olddecl)
@@ -1841,7 +1840,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
        }
 
       /* Keep the old rtl since we can safely use it.  */
-      DECL_RTL (newdecl) = DECL_RTL (olddecl);
+      COPY_DECL_RTL (olddecl, newdecl);
 
       /* Merge the type qualifiers.  */
       if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1898,7 +1897,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
 
       /* Copy the assembler name.
         Currently, it can only be defined in the prototype.  */
-      DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl);
+      COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
 
       if (TREE_CODE (newdecl) == FUNCTION_DECL)
        {
@@ -1924,7 +1923,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
     }
 
   /* 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)
     {
@@ -1940,8 +1939,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
     }
   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))
@@ -1955,12 +1960,27 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
-      /* If either decl says `inline', this fn is inline,
-        unless its definition was passed already.  */
-      if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
-       DECL_INLINE (olddecl) = 1;
+      /* If we're redefining a function previously defined as extern
+        inline, make sure we emit debug info for the inline before we
+        throw it away, in case it was inlined into a function that hasn't
+        been written out yet.  */
+      if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl))
+       {
+         note_outlining_of_inline_function (olddecl);
+
+         /* The new defn must not be inline.  */
+         DECL_INLINE (newdecl) = 0;
+         DECL_UNINLINABLE (newdecl) = 1;
+       }
+      else
+       {
+         /* If either decl says `inline', this fn is inline,
+            unless its definition was passed already.  */
+         if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
+           DECL_INLINE (olddecl) = 1;
 
-      DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
+         DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
+       }
 
       if (DECL_BUILT_IN (olddecl))
        {
@@ -1984,7 +2004,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
        }
       /* Also preserve various other info from the definition.  */
       else if (! new_is_definition)
-       DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
+       DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
       if (! new_is_definition)
        {
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
@@ -2000,28 +2020,16 @@ duplicate_decls (newdecl, olddecl, 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);
 
-    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;
   }
 
@@ -2052,8 +2060,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.  */
-  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
@@ -2172,23 +2180,23 @@ pushdecl (x)
          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)
-               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)
-            {
-              tree tt = TREE_TYPE (x);
+           {
+             tree tt = TREE_TYPE (x);
              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_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
@@ -2273,7 +2281,7 @@ pushdecl (x)
       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))
@@ -2359,11 +2367,12 @@ pushdecl (x)
                      DECL_INITIAL (x) = (current_function_decl == oldglobal
                                          ? 0 : DECL_INITIAL (oldglobal));
                      DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal);
-                     DECL_FRAME_SIZE (x) = DECL_FRAME_SIZE (oldglobal);
+                     DECL_NUM_STMTS (x) = DECL_NUM_STMTS (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))
@@ -2379,7 +2388,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.  */
@@ -2398,7 +2408,7 @@ pushdecl (x)
              && 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.
@@ -2436,7 +2446,7 @@ pushdecl (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)
@@ -2508,9 +2518,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.  */
-/*  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
+#if 0
+  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
     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.
@@ -2535,7 +2547,7 @@ implicitly_declare (functionid)
   /* 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, NULL_PTR, 0, 0);
+  rest_of_decl_compilation (decl, NULL, 0, 0);
 
   if (implicit_warning)
     implicit_decl_warning (functionid);
@@ -2555,7 +2567,7 @@ void
 implicit_decl_warning (id)
      tree id;
 {
-  char *name = IDENTIFIER_POINTER (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)
@@ -2582,7 +2594,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.  */
-      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))
@@ -2603,7 +2615,7 @@ redeclaration_error_message (newdecl, olddecl)
        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.  */
@@ -2663,9 +2675,6 @@ lookup_label (id)
 
   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;
 
@@ -2706,7 +2715,7 @@ shadow_label (name)
       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");
@@ -2741,13 +2750,15 @@ define_label (filename, line, 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)
     {
-      error ("duplicate label `%s'", IDENTIFIER_POINTER (name));
+      error_with_file_and_line (filename, line, "duplicate label `%s'",
+                               IDENTIFIER_POINTER (name));
       return 0;
     }
   else
@@ -2818,6 +2829,7 @@ lookup_tag (code, name, binding_level, thislevel_only)
      int thislevel_only;
 {
   register struct binding_level *level;
+  int thislevel = 1;
 
   for (level = binding_level; level; level = level->level_chain)
     {
@@ -2832,12 +2844,22 @@ lookup_tag (code, name, binding_level, thislevel_only)
                  pending_invalid_xref = name;
                  pending_invalid_xref_file = input_filename;
                  pending_invalid_xref_line = lineno;
+                 /* If in the same binding level as a declaration as a tag
+                    of a different type, this must not be allowed to
+                    shadow that tag, so give the error immediately.
+                    (For example, "struct foo; union foo;" is invalid.)  */
+                 if (thislevel)
+                   pending_xref_error ();
                }
              return TREE_VALUE (tail);
            }
        }
-      if (thislevel_only && ! level->tag_transparent)
-       return NULL_TREE;
+      if (! level->tag_transparent)
+       {
+         if (thislevel_only)
+           return NULL_TREE;
+         thislevel = 0;
+       }
     }
   return NULL_TREE;
 }
@@ -2889,6 +2911,7 @@ lookup_name (name)
      tree name;
 {
   register tree val;
+
   if (current_binding_level != global_binding_level
       && IDENTIFIER_LOCAL_VALUE (name))
     val = IDENTIFIER_LOCAL_VALUE (name);
@@ -2920,7 +2943,7 @@ lookup_name_current_level (name)
 \f
 /* Mark ARG for GC.  */
 
-static void 
+static void
 mark_binding_level (arg)
      void *arg;
 {
@@ -2947,147 +2970,36 @@ init_decl_processing ()
 {
   register tree endlink;
   tree ptr_ftype_void, ptr_ftype_ptr;
-  int wchar_type_size;
-  tree array_domain_type;
-  tree t;
 
   current_function_decl = NULL;
   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);
 
-  /* Define `int' and `char' first so that dbx will output them first.  */
-  pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_INT],
-                       integer_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
-                       char_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
-                       long_integer_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
-                       unsigned_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
-                       long_unsigned_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
-                       long_long_integer_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
-                       long_long_unsigned_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
-                       short_integer_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
-                       short_unsigned_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
-                       signed_char_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
-                       unsigned_char_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
-#endif
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
-#endif
-
-  /* `unsigned long' is the standard type for sizeof.
-     Traditionally, use a signed 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)));
-  if (flag_traditional && TREE_UNSIGNED (t))
-    t = signed_type (t);
-    
-  set_sizetype (t);
-
-  /* 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);
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, 
-                       widest_integer_literal_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, 
-                       widest_unsigned_literal_type_node));
-
-  build_common_tree_nodes_2 (flag_short_double);
-
-  pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT],
-                       float_type_node));
-  pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_DOUBLE],
-                       double_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
-                       long_double_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
-                       complex_integer_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
-                       complex_float_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
-                       complex_double_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
-                       complex_long_double_type_node));
-  pushdecl (build_decl (TYPE_DECL,
-                       ridpointers[(int) RID_VOID], void_type_node));
-
-#ifdef MD_INIT_BUILTINS
-  MD_INIT_BUILTINS;
-#endif
-
-  wchar_type_node = get_identifier (flag_short_wchar
-                                   ? "short unsigned int"
-                                   : WCHAR_TYPE);
-  wchar_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (wchar_type_node));
-  wchar_type_size = TYPE_PRECISION (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)));
+  c_common_nodes_and_builtins ();
 
   boolean_type_node = integer_type_node;
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_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));
-
-  /* Make a type to be the domain of a few array types
-     whose domains don't really matter.
-     200 is small enough that it always fits in size_t
-     and large enough that it can hold most function names for the
-     initializations of __FUNCTION__ and __PRETTY_FUNCTION__.  */
-  array_domain_type = build_index_type (build_int_2 (200, 0));
-
-  /* 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);
-
-  /* Likewise for arrays of ints.  */
-  int_array_type_node
-    = build_array_type (integer_type_node, array_domain_type);
-
-  /* This is for wide string constants.  */
-  wchar_array_type_node
-    = build_array_type (wchar_type_node, array_domain_type);
-
-  void_list_node = tree_cons (NULL_TREE, void_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)));
-
-  c_common_nodes_and_builtins (0, flag_no_builtin, flag_no_nonansi_builtin);
+  /* 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;
 
   endlink = void_list_node;
   ptr_ftype_void = build_function_type (ptr_type_node, endlink);
@@ -3096,7 +3008,7 @@ init_decl_processing ()
                           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))
@@ -3147,52 +3059,50 @@ init_decl_processing ()
   builtin_function ("__builtin_aggregate_incoming_address",
                    build_function_type (ptr_type_node, NULL_TREE),
                    BUILT_IN_AGGREGATE_INCOMING_ADDRESS,
-                   BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_NORMAL, NULL);
 
   /* Hooks for the DWARF 2 __throw routine.  */
   builtin_function ("__builtin_unwind_init",
                    build_function_type (void_type_node, endlink),
-                   BUILT_IN_UNWIND_INIT, BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_UNWIND_INIT, BUILT_IN_NORMAL, NULL);
   builtin_function ("__builtin_dwarf_cfa", ptr_ftype_void,
-                   BUILT_IN_DWARF_CFA, BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_DWARF_CFA, BUILT_IN_NORMAL, NULL);
   builtin_function ("__builtin_dwarf_fp_regnum",
                    build_function_type (unsigned_type_node, endlink),
-                   BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL);
   builtin_function ("__builtin_init_dwarf_reg_size_table", void_ftype_ptr,
-                   BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_NORMAL, NULL);
   builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr,
-                   BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL);
   builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
-                   BUILT_IN_EXTRACT_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR);
+                   BUILT_IN_EXTRACT_RETURN_ADDR, BUILT_IN_NORMAL, NULL);
   builtin_function
     ("__builtin_eh_return",
      build_function_type (void_type_node,
-                         tree_cons (NULL_TREE, ptr_type_node,
+                         tree_cons (NULL_TREE,
+                                    type_for_mode (ptr_mode, 0),
                                     tree_cons (NULL_TREE,
-                                               type_for_mode (ptr_mode, 0),
-                                               tree_cons (NULL_TREE,
-                                                          ptr_type_node,
-                                                          endlink)))),
-     BUILT_IN_EH_RETURN, BUILT_IN_NORMAL, NULL_PTR);
+                                               ptr_type_node,
+                                               endlink))),
+     BUILT_IN_EH_RETURN, BUILT_IN_NORMAL, NULL);
 
   pedantic_lvalues = pedantic;
 
-  /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__.  */
   make_fname_decl = c_make_fname_decl;
-  declare_function_name ();
+  start_fname_decls ();
 
   start_identifier_warnings ();
 
   /* 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);
+  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,
@@ -3209,34 +3119,37 @@ 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
-   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)
+c_make_fname_decl (id, type_dep)
      tree id;
-     const char *name;
-     int type_dep ATTRIBUTE_UNUSED;
+     int type_dep;
 {
+  const char *name = fname_as_string (type_dep);
   tree decl, type, init;
   size_t length = strlen (name);
 
   type =  build_array_type
           (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
-          build_index_type (build_int_2 (length, 0)));
+          build_index_type (size_int (length)));
 
   decl = build_decl (VAR_DECL, id, type);
+  /* We don't push the decl, so have to set its context here. */
+  DECL_CONTEXT (decl) = current_function_decl;
+  
   TREE_STATIC (decl) = 1;
   TREE_READONLY (decl) = 1;
-  TREE_ASM_WRITTEN (decl) = 1;
-  DECL_SOURCE_LINE (decl) = 0;
   DECL_ARTIFICIAL (decl) = 1;
-  DECL_IN_SYSTEM_HEADER (decl) = 1;
-  DECL_IGNORED_P (decl) = 1;
+  
   init = build_string (length + 1, name);
   TREE_TYPE (init) = type;
   DECL_INITIAL (decl) = init;
-  finish_decl (pushdecl (decl), init, NULL_TREE);
+
+  TREE_USED (decl) = 1;
   
+  finish_decl (decl, init, NULL_TREE);
+
   return decl;
 }
 
@@ -3265,8 +3178,8 @@ builtin_function (name, type, function_code, class, library_name)
   if (flag_traditional && name[0] != '_')
     DECL_BUILT_IN_NONANSI (decl) = 1;
   if (library_name)
-    DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
-  make_decl_rtl (decl, NULL_PTR, 1);
+    SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
+  make_decl_rtl (decl, NULL);
   pushdecl (decl);
   DECL_BUILT_IN_CLASS (decl) = class;
   DECL_FUNCTION_CODE (decl) = function_code;
@@ -3416,8 +3329,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
                                       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)
@@ -3454,7 +3367,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.  */
-       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.  */
 
@@ -3481,7 +3399,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
 
   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)
@@ -3528,9 +3447,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).  */
-      && DECL_RTL (tem) == 0)
+      && !DECL_RTL_SET_P (tem)
+      && !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)
@@ -3552,28 +3473,20 @@ finish_decl (decl, init, asmspec_tree)
 {
   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)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
   /* If `start_decl' didn't like having an initialization, ignore it now.  */
-
   if (init != 0 && DECL_INITIAL (decl) == 0)
     init = 0;
+  
   /* Don't crash if parm is initialized.  */
   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)
@@ -3587,7 +3500,6 @@ finish_decl (decl, init, asmspec_tree)
     }
 
   /* Deduce size of array from initialization, if not already known */
-
   if (TREE_CODE (type) == ARRAY_TYPE
       && TYPE_DOMAIN (type) == 0
       && TREE_CODE (decl) != TYPE_DECL)
@@ -3607,7 +3519,7 @@ finish_decl (decl, init, asmspec_tree)
       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'");
@@ -3624,8 +3536,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.  */
-      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);
@@ -3633,10 +3545,13 @@ finish_decl (decl, init, asmspec_tree)
 
   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
+         /* 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
@@ -3644,11 +3559,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.  */
-             /* 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_CONTEXT (decl) != 0 && ! TREE_ASM_WRITTEN (decl)))
+                || DECL_CONTEXT (decl) != 0)
              :
                /* An automatic variable with an incomplete type
                   is an error.  */
@@ -3667,7 +3579,7 @@ finish_decl (decl, init, asmspec_tree)
            error_with_decl (decl, "storage size of `%s' isn't constant");
        }
 
-      if (TREE_USED  (type))
+      if (TREE_USED (type))
        TREE_USED (decl) = 1;
     }
 
@@ -3675,11 +3587,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)
-      {
-       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;
+      SET_DECL_RTL (decl, NULL_RTX);
+      SET_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.
@@ -3689,9 +3601,47 @@ 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);
-      rest_of_decl_compilation (decl, asmspec,
-                               (DECL_CONTEXT (decl) == 0
-                                || TREE_ASM_WRITTEN (decl)), 0);
+
+      if (!DECL_CONTEXT (decl))
+       {
+         if (DECL_INITIAL (decl) == NULL_TREE
+             || DECL_INITIAL (decl) == error_mark_node)
+           /* Don't output anything
+              when a tentative file-scope definition is seen.
+              But at end of compilation, do output code for them.  */
+           DECL_DEFER_OUTPUT (decl) = 1;
+         rest_of_decl_compilation (decl, asmspec,
+                                   (DECL_CONTEXT (decl) == 0
+                                    || TREE_ASM_WRITTEN (decl)), 0);
+       }
+      else
+       {
+         /* This is a local variable.  If there is an ASMSPEC, the
+            user has requested that we handle it specially.  */
+         if (asmspec)
+           {
+             /* In conjunction with an ASMSPEC, the `register'
+                keyword indicates that we should place the variable
+                in a particular register.  */
+             if (DECL_REGISTER (decl))
+               DECL_C_HARD_REGISTER (decl) = 1;
+
+             /* If this is not a static variable, issue a warning.
+                It doesn't make any sense to give an ASMSPEC for an
+                ordinary, non-register local variable.  Historically,
+                GCC has accepted -- but ignored -- the ASMSPEC in
+                this case.  */
+             if (TREE_CODE (decl) == VAR_DECL 
+                 && !DECL_REGISTER (decl)
+                 && !TREE_STATIC (decl))
+               warning_with_decl (decl,
+                                  "ignoring asm-specifier for non-static local variable `%s'");
+             else
+               SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+           }
+
+         add_decl_stmt (decl);
+       }
 
       if (DECL_CONTEXT (decl) != 0)
        {
@@ -3705,11 +3655,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;
-             expand_decl (decl);
            }
-         /* Compute and store the initial value.  */
-         if (TREE_CODE (decl) != FUNCTION_DECL)
-           expand_decl_init (decl);
        }
     }
 
@@ -3717,7 +3663,7 @@ 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);
-      rest_of_decl_compilation (decl, NULL_PTR, DECL_CONTEXT (decl) == 0, 0);
+      rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0);
     }
 
   /* At the end of a declaration, throw away any variable type sizes
@@ -3763,7 +3709,8 @@ push_parm_decl (parm)
       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
 
@@ -3982,7 +3929,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
     {
-      register int i;
       register tree id = TREE_VALUE (spec);
 
       if (id == ridpointers[(int) RID_INT])
@@ -3990,36 +3936,36 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       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 ((int) i <= (int) RID_LAST_MODIFIER)
+           {
+             if (i == RID_LONG && (specbits & (1 << (int) 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 << (int) i))
+               pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
+             specbits |= 1 << (int) 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);
-          decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id);
+         decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id);
          typedef_decl = id;
        }
       /* Built-in types come as identifiers.  */
@@ -4040,7 +3986,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       else if (TREE_CODE (id) != ERROR_MARK)
        type = id;
 
-    found: {}
+    found:
+      ;
     }
 
   typedef_type = type;
@@ -4054,7 +4001,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
     {
       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)
@@ -4062,10 +4010,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          /* Issue a warning if this is an ISO C 99 program or if -Wreturn-type
             and this is a function, or if -Wimplicit; prefer the former
             warning since it is more explicit.  */
-         if ((warn_implicit_int || warn_return_type) && funcdef_flag)
+         if ((warn_implicit_int || warn_return_type || flag_isoc99)
+             && funcdef_flag)
            warn_about_return_type = 1;
          else if (warn_implicit_int || flag_isoc99)
-           pedwarn_c99 ("type defaults to `int' in declaration of `%s'", name);
+           pedwarn_c99 ("type defaults to `int' in declaration of `%s'",
+                        name);
        }
 
       defaulted_int = 1;
@@ -4080,7 +4030,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
   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;
     }
 
@@ -4141,7 +4091,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       && 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.
@@ -4184,6 +4134,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   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
@@ -4193,9 +4145,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          && ! (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)
-       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)
@@ -4203,7 +4163,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       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
@@ -4237,7 +4201,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_ITERATOR) nclasses++;
 
     /* Warn about storage classes that are invalid for certain
        kinds of declarations (parameters, typenames, etc.).  */
@@ -4257,8 +4220,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          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)
       {
@@ -4269,7 +4232,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            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);
@@ -4278,9 +4242,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                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)
@@ -4297,18 +4261,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 ((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.
@@ -4383,7 +4335,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                }
 
              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)
                {
@@ -4403,49 +4355,71 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                  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
-                       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))
+               {
+                 /* 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
                {
-                 error ("size of array `%s' is too large", name);
-                 type = error_mark_node;
-                 continue;
+                 /* 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);
                }
+           }
+         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 (pedantic && !flag_isoc99 && !in_system_header)
+               pedwarn ("ISO C89 does not support flexible array members");
 
-             if (size_varies)
-               itype = variable_size (itype);
-             itype = build_index_type (itype);
+             /* 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 pedantic, complain about arrays of incomplete types.  */
 
-         if (!COMPLETE_TYPE_P (type)
-             /* Avoid multiple warnings for nested array types.  */
-             && TREE_CODE (type) != ARRAY_TYPE
-             && !(specbits & (1 << (int) RID_TYPEDEF))
-             && !C_TYPE_BEING_DEFINED (type))
-           warning ("array type has incomplete element type");
-#endif
+         if (pedantic && !COMPLETE_TYPE_P (type))
+           pedwarn ("array type has incomplete element type");
 
-#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");
@@ -4460,13 +4434,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          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.  */
-         type_quals = TYPE_UNQUALIFIED;
-#endif
-
          if (size_varies)
            C_TYPE_VARIABLE_SIZE (type) = 1;
+
+         /* The GCC extension for zero-length arrays differs from
+            ISO flexible array members in that sizeof yields zero.  */
+         if (size && integer_zerop (size))
+           {
+             layout_type (type);
+             TYPE_SIZE (type) = bitsize_zero_node;
+             TYPE_SIZE_UNIT (type) = size_zero_node;
+           }
        }
       else if (TREE_CODE (declarator) == CALL_EXPR)
        {
@@ -4511,7 +4489,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 = 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);
@@ -4537,7 +4534,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
          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;
@@ -4561,18 +4558,23 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                {
                  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)
@@ -4599,7 +4601,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
   if (TREE_CODE (type) == ARRAY_TYPE
       && COMPLETE_TYPE_P (type)
       && TREE_OVERFLOW (TYPE_SIZE (type)))
-    error ("size of array `%s' is too large", name);
+    {
+      error ("size of array `%s' is too large", name);
+      /* If we proceed with the array type as it is, we'll eventully
+        crash in tree_low_cst().  */
+      type = error_mark_node;
+    }
 
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
 
@@ -4610,7 +4617,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
         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);
@@ -4627,8 +4634,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
      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)
@@ -4644,7 +4651,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
         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;
@@ -4694,7 +4701,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        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);
@@ -4743,7 +4750,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            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
          }
@@ -4780,13 +4788,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))
-         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.  */
@@ -4803,7 +4805,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        /* 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.  */
@@ -4822,9 +4824,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        /* Move type qualifiers down to element of an array.  */
        if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
          {
+           int saved_align = TYPE_ALIGN(type);
            type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
                                                             type_quals),
                                     TYPE_DOMAIN (type));
+           TYPE_ALIGN (type) = saved_align;
 #if 0 /* Leave the variable const or volatile as well.  */
            type_quals = TYPE_UNQUALIFIED;
 #endif
@@ -4855,9 +4859,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            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 &
@@ -4942,6 +4943,8 @@ grokparms (parms_info, funcdef_flag)
            {
              /* Barf if the parameter itself has an incomplete type.  */
              tree type = TREE_VALUE (typelt);
+             if (type == error_mark_node)
+               continue;
              if (!COMPLETE_TYPE_P (type))
                {
                  if (funcdef_flag && DECL_NAME (parm) != 0)
@@ -4955,8 +4958,10 @@ grokparms (parms_info, funcdef_flag)
                      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.  */
@@ -4977,11 +4982,10 @@ grokparms (parms_info, funcdef_flag)
              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.
@@ -5007,8 +5011,7 @@ get_parm_info (void_at_end)
      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).
-  */
+     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))
@@ -5025,7 +5028,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.  */
-  for (decl = parms; decl; )
+  for (decl = parms; decl;)
     {
       tree next = TREE_CHAIN (decl);
 
@@ -5036,7 +5039,8 @@ get_parm_info (void_at_end)
        }
       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;
        }
@@ -5113,13 +5117,13 @@ parmlist_tags_warning ()
                  : "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");
-         else    
+         else
            warning ("anonymous enum declared inside parameter list");
        }
       if (! already)
@@ -5157,9 +5161,6 @@ xref_tag (code, name)
   ref = make_node (code);
   if (code == ENUMERAL_TYPE)
     {
-      /* (In ANSI, Enums can be referred to only if already defined.)  */
-      if (pedantic)
-       pedwarn ("ANSI 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);
@@ -5250,6 +5251,7 @@ finish_struct (t, fieldlist, attributes)
 {
   register tree x;
   int toplevel = global_binding_level == current_binding_level;
+  int saw_named_field;
 
   /* If this type was previously laid out as a forward reference,
      make sure we lay it out again.  */
@@ -5288,6 +5290,7 @@ finish_struct (t, fieldlist, attributes)
      Store 0 there, except for ": 0" fields (so we can find them
      and delete them, below).  */
 
+  saw_named_field = 0;
   for (x = fieldlist; x; x = TREE_CHAIN (x))
     {
       DECL_CONTEXT (x) = t;
@@ -5339,6 +5342,7 @@ finish_struct (t, fieldlist, attributes)
       /* 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");
@@ -5348,20 +5352,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
+         && 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))))
-       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))
        {
+         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'");
-         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'");
@@ -5381,7 +5390,8 @@ finish_struct (t, fieldlist, attributes)
                                   "`%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)
                {
@@ -5414,6 +5424,22 @@ finish_struct (t, fieldlist, attributes)
        }
 
       DECL_INITIAL (x) = 0;
+
+      /* Detect flexible array member in an invalid context.  */
+      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+         && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
+         && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
+         && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
+       {
+         if (TREE_CODE (t) == UNION_TYPE)
+           error_with_decl (x, "flexible array member in union");
+         else if (TREE_CHAIN (x) != NULL_TREE)
+           error_with_decl (x, "flexible array member not at end of struct");
+         else if (! saw_named_field)
+           error_with_decl (x, "flexible array member in otherwise empty struct");
+       }
+      if (DECL_NAME (x))
+       saw_named_field = 1;
     }
 
   /* Delete all duplicate fields from the fieldlist */
@@ -5424,7 +5450,7 @@ finish_struct (t, fieldlist, attributes)
     else
       {
        register tree y = fieldlist;
-         
+
        while (1)
          {
            if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
@@ -5438,7 +5464,8 @@ finish_struct (t, fieldlist, attributes)
            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,
@@ -5458,8 +5485,8 @@ finish_struct (t, fieldlist, attributes)
        fieldlistp = &TREE_CHAIN (*fieldlistp);
   }
 
-  /*  Now we have the truly final field list.
-      Store it in this type and in the variants.  */
+  /* Now we have the truly final field list.
+     Store it in this type and in the variants.  */
 
   TYPE_FIELDS (t) = fieldlist;
 
@@ -5489,13 +5516,13 @@ finish_struct (t, fieldlist, attributes)
       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);
              /* 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, NULL_PTR, toplevel, 0);
+             rest_of_decl_compilation (decl, NULL, toplevel, 0);
              if (! toplevel)
                expand_decl (decl);
              --current_binding_level->n_incomplete;
@@ -5621,13 +5648,19 @@ finish_enum (enumtype, values, attributes)
   unsign = (tree_int_cst_sgn (minnode) >= 0);
   precision = MAX (min_precision (minnode, unsign),
                   min_precision (maxnode, unsign));
-  if (!TYPE_PACKED (enumtype))
-    precision = MAX (precision, TYPE_PRECISION (integer_type_node));
-  if (type_for_size (precision, unsign) == 0)
+  if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
-      warning ("enumeration values exceed range of largest integer");
-      precision = TYPE_PRECISION (long_long_integer_type_node);
+      tree narrowest = type_for_size (precision, unsign);
+      if (narrowest == 0)
+       {
+         warning ("enumeration values exceed range of largest integer");
+         narrowest = long_long_integer_type_node;
+       }
+
+      precision = TYPE_PRECISION (narrowest);
     }
+  else
+    precision = TYPE_PRECISION (integer_type_node);
 
   if (precision == TYPE_PRECISION (integer_type_node))
     enum_value_type = type_for_size (precision, 0);
@@ -5747,7 +5780,7 @@ build_enumerator (name, value)
 
   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);
     }
 
@@ -5770,6 +5803,7 @@ build_enumerator (name, value)
 
   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
@@ -5860,13 +5894,19 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
   /* Optionally warn of old-fashioned def with no previous prototype.  */
   if (warn_strict_prototypes
       && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
-      && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0))
+      && !(old_decl != 0
+          && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
+              || (DECL_BUILT_IN (old_decl)
+                  && ! C_DECL_ANTICIPATED (old_decl)))))
     warning ("function declaration isn't a prototype");
   /* Optionally warn of any global def with no previous prototype.  */
   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))))
+          && !(old_decl != 0
+               && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
+                   || (DECL_BUILT_IN (old_decl)
+                       && ! C_DECL_ANTICIPATED (old_decl))))
+          && ! 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.  */
@@ -5874,12 +5914,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,
-                     "`%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
-          && 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.  */
@@ -5887,7 +5927,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,
-                   "`%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.
@@ -5898,7 +5938,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
 #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;
@@ -5907,15 +5947,14 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
   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)))
-          != 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;
@@ -5941,7 +5980,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
                  || (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:
@@ -5950,20 +5989,17 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
                  || (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
-        blessed by mention in an appendix of the standard. */
+        argument because it's only mentioned 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 == 3 && pedantic)
-       pedwarn_with_decl (decl1, "third argument of `%s' is deprecated");
-
       if (! TREE_PUBLIC (decl1))
        pedwarn_with_decl (decl1, "`%s' is normally a non-static function");
     }
@@ -5978,11 +6014,11 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
   declare_parm_level (1);
   current_binding_level->subblocks_tag_transparent = 1;
 
-  make_function_rtl (current_function_decl);
+  make_decl_rtl (current_function_decl, NULL);
 
   restype = TREE_TYPE (TREE_TYPE (current_function_decl));
   /* Promote the value to int before returning it.  */
-  if (C_PROMOTING_INTEGER_TYPE_P (restype))
+  if (c_promoting_integer_type_p (restype))
     {
       /* It retains unsignedness if traditional
         or if not really getting wider.  */
@@ -6004,6 +6040,8 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
 
   immediate_size_expand = old_immediate_size_expand;
 
+  start_fname_decls ();
+  
   return 1;
 }
 
@@ -6122,8 +6160,7 @@ store_parm_decls ()
             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
 
@@ -6225,7 +6262,7 @@ store_parm_decls ()
 
          TREE_PURPOSE (parm) = found;
 
-         /* Mark this decl as "already found" */
+         /* Mark this decl as "already found" */
          DECL_WEAK (found) = 1;
        }
 
@@ -6236,7 +6273,7 @@ store_parm_decls ()
         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;
@@ -6247,19 +6284,19 @@ store_parm_decls ()
            {
              /* 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))
-               {
-                 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.  */
-                 specparms
+                 specparms
                    = chainon (specparms,
                               tree_cons (parm, NULL_TREE, NULL_TREE));
                }
@@ -6268,8 +6305,9 @@ store_parm_decls ()
          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;
       {
@@ -6419,25 +6457,20 @@ store_parm_decls ()
 
   init_function_start (fndecl, input_filename, lineno);
 
-  /* If this is a varargs function, inform function.c.  */
+  /* 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));
 
-  if (c_function_varargs)
-    mark_varargs ();
-
-  /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function.  */
-
-  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
@@ -6528,7 +6561,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
 
   /* 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;
@@ -6575,7 +6608,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
          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)));
@@ -6615,14 +6648,13 @@ finish_function (nested)
       setjmp_protect_args ();
     }
 
-  if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")
-      && flag_hosted)
+  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 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'");
        }
@@ -6637,44 +6669,110 @@ finish_function (nested)
 #endif
        }
     }
+  
+  finish_fname_decls ();
+
+  /* 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;
+    }
+}
+
+/* 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);
 
-  /* 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 (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.  */
-  if (nested)
+  if (nested_p)
     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.  */
-  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
@@ -6685,7 +6783,8 @@ finish_function (nested)
     {
       tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
 
-      if (ret_type && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
+      if (ret_type && TYPE_SIZE_UNIT (ret_type)
+         && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
          && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
                                   larger_than_size))
        {
@@ -6698,16 +6797,16 @@ finish_function (nested)
                               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);
        }
     }
 
-  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
-        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)
@@ -6723,7 +6822,7 @@ finish_function (nested)
        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))
@@ -6736,12 +6835,68 @@ finish_function (nested)
        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
@@ -6749,8 +6904,9 @@ finish_function (nested)
    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;
@@ -6767,10 +6923,13 @@ void
 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->named_labels = named_labels;
   p->shadowed_labels = shadowed_labels;
   p->returns_value = current_function_returns_value;
@@ -6786,7 +6945,8 @@ void
 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.  */
@@ -6795,7 +6955,8 @@ pop_c_function_context (f)
       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
@@ -6804,6 +6965,8 @@ pop_c_function_context (f)
       DECL_ARGUMENTS (current_function_decl) = 0;
     }
 
+  c_stmt_tree = p->base.x_stmt_tree;
+  c_scope_stmt_stack = p->base.x_scope_stmt_stack;
   named_labels = p->named_labels;
   shadowed_labels = p->shadowed_labels;
   current_function_returns_value = p->returns_value;
@@ -6817,40 +6980,42 @@ pop_c_function_context (f)
 }
 
 /* Mark the language specific parts of F for GC.  */
+
 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;
 
+  mark_c_language_function (&p->base);
   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
-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.  */
+
 void
 lang_mark_tree (t)
      tree t;
@@ -6867,12 +7032,17 @@ lang_mark_tree (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
-   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
@@ -6884,109 +7054,102 @@ stmts_are_full_exprs_p ()
   return 0;
 }
 
+/* Returns the stmt_tree (if any) to which statements are currently
+   being added.  If there is no active statement-tree, NULL is
+   returned.  */
+
+stmt_tree
+current_stmt_tree ()
+{
+  return &c_stmt_tree;
+}
+
+/* Returns the stack of SCOPE_STMTs for the current function.  */
+
+tree *
+current_scope_stmt_stack ()
+{
+  return &c_scope_stmt_stack;
+}
+
 /* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
-   C. */
+   C.  */
 
-int 
+int
 anon_aggr_type_p (node)
      tree node ATTRIBUTE_UNUSED;
 {
   return 0;
 }
 
-/* One if we have already declared __FUNCTION__ (and related
-   variables) in the current function.  Two if we are in the process
-   of doing so.  */
+/* Dummy function in place of callback used by C++.  */
 
-int
-current_function_name_declared ()
+void
+extract_interface_info ()
 {
-  abort ();
-  return 0;
 }
 
-/* Code to generate the RTL for a case label in C. */
+/* Return a new COMPOUND_STMT, after adding it to the current
+   statement tree.  */
 
-void
-do_case (low_value, high_value)
-     tree low_value;
-     tree high_value;
+tree
+c_begin_compound_stmt ()
 {
-  tree value1 = NULL_TREE, value2 = NULL_TREE, label;
+  tree stmt;
 
-  if (low_value != NULL_TREE)
-    value1 = check_case_value (low_value);
-  if (high_value != NULL_TREE)
-    value2 = check_case_value (high_value);
+  /* Create the COMPOUND_STMT.  */
+  stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
 
-  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");
-       }
-    }
+  return stmt;
+}
+
+/* Expand T (a DECL_STMT) if it declares an entity not handled by the
+   common code.  */
+
+void
+c_expand_decl_stmt (t)
+     tree t;
+{
+  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);
 }
 
-/* Language specific handler of tree nodes used when generating RTL
-   from a tree. */
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
 
 tree
-lang_expand_stmt (t)
-     tree t ATTRIBUTE_UNUSED;
+identifier_global_value        (t)
+     tree t;
 {
-  abort ();
-  return NULL_TREE;
+  return IDENTIFIER_GLOBAL_VALUE (t);
 }
 
-/* Accessor to set the 'current_function_name_declared' flag. */
+/* Record a builtin type for C.  If NAME is non-NULL, it is the name used;
+   otherwise the name is found in ridpointers from RID_INDEX.  */
 
 void
-set_current_function_name_declared (i)
-     int i ATTRIBUTE_UNUSED;
+record_builtin_type (rid_index, name, type)
+     enum rid rid_index;
+     const char *name;
+     tree type;
 {
-  abort ();
+  tree id;
+  if (name == 0)
+    id = ridpointers[(int) rid_index];
+  else
+    id = get_identifier (name);
+  pushdecl (build_decl (TYPE_DECL, id, type));
 }
 
+/* Build the void_list_node (void_type_node having been created).  */
+tree
+build_void_list_node ()
+{
+  tree t = build_tree_list (NULL_TREE, void_type_node);
+  return t;
+}