OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 75e50b5..1f773d9 100644 (file)
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "intl.h"
 #include "tree.h"
 #include "rtl.h"
 #include "flags.h"
@@ -73,6 +74,10 @@ enum decl_context
 #ifndef WCHAR_TYPE
 #define WCHAR_TYPE "int"
 #endif
+
+#ifndef WINT_TYPE
+#define WINT_TYPE "unsigned int"
+#endif
 \f
 /* Do GC.  */
 int ggc_p = 1;
@@ -325,10 +330,18 @@ int flag_no_nonansi_builtin;
 
 int flag_traditional;
 
+/* Nonzero means enable C89 Amendment 1 features, other than digraphs.  */
+
+int flag_isoc94 = 0;
+
 /* Nonzero means use the ISO C99 dialect of C.  */
 
 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;
@@ -353,7 +366,7 @@ int warn_long_long = 1;
 /* Nonzero means message about use of implicit function declarations;
  1 means warning; 2 means error. */
 
-int mesg_implicit_function_declaration;
+int mesg_implicit_function_declaration = -1;
 
 /* Nonzero means give string constants the type `const char *'
    to get extra warnings from them.  These warnings will be too numerous
@@ -454,6 +467,14 @@ 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;
+
 /* Nonzero means `$' can be in an identifier.  */
 
 #ifndef DOLLARS_IN_IDENTIFIERS
@@ -482,6 +503,7 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 1;
       flag_writable_strings = 1;
+      flag_digraphs = 0;
     }
   else if (!strcmp (p, "-fallow-single-precision"))
     flag_allow_single_precision = 1;
@@ -502,6 +524,7 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
+      flag_digraphs = 1;
     }
   else if (!strncmp (p, "-std=", 5))
     {
@@ -521,6 +544,9 @@ c_decode_option (argc, argv)
          || !strcmp (argstart, "c89"))
        {
        iso_1990:
+         flag_digraphs = 0;
+         flag_isoc94 = 0;
+       iso_1990_digraphs:
          flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
@@ -529,8 +555,9 @@ c_decode_option (argc, argv)
        }
       else if (!strcmp (argstart, "iso9899:199409"))
        {
-         /* ??? The changes since ISO C 1990 are not supported.  */
-         goto iso_1990;
+         flag_digraphs = 1;
+         flag_isoc94 = 1;
+         goto iso_1990_digraphs;
        }
       else if (!strcmp (argstart, "iso9899:199x")
               || !strcmp (argstart, "iso9899:1999")
@@ -542,6 +569,8 @@ c_decode_option (argc, argv)
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
          flag_isoc99 = 1;
+         flag_digraphs = 1;
+         flag_isoc94 = 1;
        }
       else if (!strcmp (argstart, "gnu89"))
        {
@@ -550,6 +579,8 @@ c_decode_option (argc, argv)
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
          flag_isoc99 = 0;
+         flag_digraphs = 1;
+         flag_isoc94 = 0;
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
        {
@@ -558,6 +589,8 @@ c_decode_option (argc, argv)
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
          flag_isoc99 = 1;
+         flag_digraphs = 1;
+         flag_isoc94 = 1;
        }
       else
        error ("unknown C standard `%s'", argstart);
@@ -1801,7 +1834,10 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
          DECL_MODE (newdecl) = DECL_MODE (olddecl);
          if (TREE_CODE (olddecl) != FUNCTION_DECL)
            if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
-             DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+             {
+               DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+               DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
+             }
        }
 
       /* Keep the old rtl since we can safely use it.  */
@@ -1819,7 +1855,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
       if (TREE_THIS_VOLATILE (newdecl))
        {
          TREE_THIS_VOLATILE (write_olddecl) = 1;
-         if (TREE_CODE (newdecl) == VAR_DECL)
+         if (TREE_CODE (newdecl) == VAR_DECL
+             /* If an automatic variable is re-declared in the same
+                function scope, but the old declaration was not
+                volatile, make_var_volatile() would crash because the
+                variable would have been assigned to a pseudo, not a
+                MEM.  Since this duplicate declaration is invalid
+                anyway, we just skip the call.  */
+             && errmsg == 0)
            make_var_volatile (newdecl);
        }
 
@@ -1953,7 +1996,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
          DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
          DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
          if (DECL_INLINE (newdecl))
-           DECL_ABSTRACT_ORIGIN (newdecl) = DECL_ORIGIN (olddecl);
+           DECL_ABSTRACT_ORIGIN (newdecl) = DECL_ABSTRACT_ORIGIN (olddecl);
        }
     }
   if (different_binding_level)
@@ -2418,8 +2461,12 @@ pushdecl (x)
            b->shadowed = tree_cons (name, oldlocal, b->shadowed);
        }
 
-      /* Keep count of variables in this level with incomplete type.  */
-      if (!COMPLETE_TYPE_P (TREE_TYPE (x)))
+      /* Keep count of variables in this level with incomplete type.
+        If the input is erroneous, we can have error_mark in the type
+        slot (e.g. "f(void a, ...)") - that doesn't count as an
+        incomplete type.  */
+      if (TREE_TYPE (x) != error_mark_node
+         && !COMPLETE_TYPE_P (TREE_TYPE (x)))
        ++b->n_incomplete;
     }
 
@@ -2490,15 +2537,8 @@ implicitly_declare (functionid)
 
   rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
 
-  if (mesg_implicit_function_declaration && implicit_warning)
-    {
-      if (mesg_implicit_function_declaration == 2)
-        error ("implicit declaration of function `%s'",
-                 IDENTIFIER_POINTER (functionid));
-      else
-        warning ("implicit declaration of function `%s'",
-                 IDENTIFIER_POINTER (functionid));
-    }
+  if (implicit_warning)
+    implicit_decl_warning (functionid);
   else if (warn_traditional && traditional_warning)
     warning ("function `%s' was previously declared within a block",
             IDENTIFIER_POINTER (functionid));
@@ -2511,6 +2551,17 @@ implicitly_declare (functionid)
   return decl;
 }
 
+void
+implicit_decl_warning (id)
+     tree id;
+{
+  char *name = IDENTIFIER_POINTER (id);
+  if (mesg_implicit_function_declaration == 2)
+    error ("implicit declaration of function `%s'", name);
+  else if (mesg_implicit_function_declaration == 1)
+    warning ("implicit declaration of function `%s'", name);
+}
+
 /* Return zero if the declaration NEWDECL is valid
    when the declaration OLDDECL (assumed to be for the same name)
    has already been seen.
@@ -2690,6 +2741,10 @@ 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 (DECL_INITIAL (decl) != 0)
     {
       error ("duplicate label `%s'", IDENTIFIER_POINTER (name));
@@ -2948,6 +3003,7 @@ init_decl_processing ()
      Note that stddef.h uses `unsigned long',
      and this must agree, even if long and int are the same size.  */
   t = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
+  signed_size_type_node = signed_type (t);
   if (flag_traditional && TREE_UNSIGNED (t))
     t = signed_type (t);
     
@@ -2994,6 +3050,8 @@ init_decl_processing ()
   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)));
+
   boolean_type_node = integer_type_node;
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_node;
@@ -3029,6 +3087,7 @@ init_decl_processing ()
     = build_function_type (integer_type_node, NULL_TREE);
   ptrdiff_type_node
     = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
+  unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
 
   c_common_nodes_and_builtins (0, flag_no_builtin, flag_no_nonansi_builtin);
 
@@ -3944,7 +4003,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                      error ("`long long long' is too long for GCC");
                    else
                      {
-                       if (pedantic && ! in_system_header && warn_long_long)
+                       if (pedantic && !flag_isoc99 && ! in_system_header
+                           && warn_long_long)
                          pedwarn ("ANSI C does not support `long long'");
                        longlong = 1;
                      }
@@ -4007,7 +4067,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          if ((warn_implicit_int || warn_return_type) && funcdef_flag)
            warn_about_return_type = 1;
          else if (warn_implicit_int || flag_isoc99)
-           warning ("type defaults to `int' in declaration of `%s'", name);
+           pedwarn_c99 ("type defaults to `int' in declaration of `%s'", name);
        }
 
       defaulted_int = 1;
@@ -4157,11 +4217,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
   restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
   volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
   inlinep = !! (specbits & (1 << (int) RID_INLINE));
-  if (constp > 1)
+  if (constp > 1 && ! flag_isoc99)
     pedwarn ("duplicate `const'");
-  if (restrictp > 1)
+  if (restrictp > 1 && ! flag_isoc99)
     pedwarn ("duplicate `restrict'");
-  if (volatilep > 1)
+  if (volatilep > 1 && ! flag_isoc99)
     pedwarn ("duplicate `volatile'");
   if (! flag_gen_aux_info && (TYPE_QUALS (type)))
     type = TYPE_MAIN_VARIANT (type);
@@ -4290,7 +4350,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
          /* Check for some types that there cannot be arrays of.  */
 
-         if (TYPE_MAIN_VARIANT (type) == void_type_node)
+         if (VOID_TYPE_P (type))
            {
              error ("declaration of `%s' as array of voids", name);
              type = error_mark_node;
@@ -4515,11 +4575,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                      error ("invalid type modifier within pointer declarator");
                    }
                }
-             if (constp > 1)
+             if (constp > 1 && ! flag_isoc99)
                pedwarn ("duplicate `const'");
-             if (volatilep > 1)
+             if (volatilep > 1 && ! flag_isoc99)
                pedwarn ("duplicate `volatile'");
-             if (restrictp > 1)
+             if (restrictp > 1 && ! flag_isoc99)
                pedwarn ("duplicate `restrict'");
 
              type_quals = ((constp ? TYPE_QUAL_CONST : 0)
@@ -4598,7 +4658,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
      We don't complain about parms either, but that is because
      a better error message can be made later.  */
 
-  if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM
+  if (VOID_TYPE_P (type) && decl_context != PARM
       && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
            && ((specbits & (1 << (int) RID_EXTERN))
                || (current_binding_level == global_binding_level
@@ -4725,7 +4785,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          pedwarn ("ANSI C forbids qualified function types");
 
        if (pedantic
-           && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
+           && 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");
@@ -4733,7 +4793,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        /* GNU C interprets a `volatile void' return type to indicate
           that the function does not return.  */
        if ((type_quals & TYPE_QUAL_VOLATILE)
-           && TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
+           && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
          warning ("`noreturn' function returns non-void value");
 
        if (extern_ref)
@@ -4945,10 +5005,18 @@ get_parm_info (void_at_end)
   tree new_parms = 0;
   tree order = current_binding_level->parm_order;
 
-  /* Just `void' (and no ellipsis) is special.  There are really no parms.  */
+  /* Just `void' (and no ellipsis) is special.  There are really no parms.
+     But if the `void' is qualified (by `const' or `volatile') or has a
+     storage class specifier (`register'), then the behavior is undefined;
+     by not counting it as the special case of `void' we will cause an
+     error later.  Typedefs for `void' are OK (see DR#157).
+  */
   if (void_at_end && parms != 0
       && TREE_CHAIN (parms) == 0
-      && TYPE_MAIN_VARIANT (TREE_TYPE (parms)) == void_type_node
+      && VOID_TYPE_P (TREE_TYPE (parms))
+      && ! TREE_THIS_VOLATILE (parms)
+      && ! TREE_READONLY (parms)
+      && ! DECL_REGISTER (parms)
       && DECL_NAME (parms) == 0)
     {
       parms = NULL_TREE;
@@ -5009,7 +5077,7 @@ get_parm_info (void_at_end)
          DECL_ARG_TYPE (decl) = integer_type_node;
 
        types = tree_cons (NULL_TREE, TREE_TYPE (decl), types);
-       if (TYPE_MAIN_VARIANT (TREE_VALUE (types)) == void_type_node && ! erred
+       if (VOID_TYPE_P (TREE_VALUE (types)) && ! erred
            && DECL_NAME (decl) == 0)
          {
            error ("`void' in parameter list must be the entire list");
@@ -5047,11 +5115,15 @@ parmlist_tags_warning ()
                  : "enum"),
                 IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
       else
-       warning ("anonymous %s declared inside parameter list",
-                (code == RECORD_TYPE ? "struct"
-                 : code == UNION_TYPE ? "union"
-                 : "enum"));
-
+        {
+          /* 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    
+           warning ("anonymous enum declared inside parameter list");
+       }
       if (! already)
        {
          warning ("its scope is only this definition or declaration, which is probably not what you want.");
@@ -5094,6 +5166,7 @@ xref_tag (code, name)
         to avoid crashing if it does not get defined.  */
       TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
       TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
+      TYPE_USER_ALIGN (ref) = 0;
       TREE_UNSIGNED (ref) = 1;
       TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
       TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
@@ -5194,10 +5267,10 @@ finish_struct (t, fieldlist, attributes)
       {
        if (pedantic)
          pedwarn ("%s defined inside parms",
-                  TREE_CODE (t) == UNION_TYPE ? "union" : "structure");
+                  TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
        else if (! flag_traditional)
          warning ("%s defined inside parms",
-                  TREE_CODE (t) == UNION_TYPE ? "union" : "structure");
+                  TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
       }
 
   if (pedantic)
@@ -5207,9 +5280,9 @@ finish_struct (t, fieldlist, attributes)
          break;
 
       if (x == 0)
-       pedwarn ("%s has no %smembers",
-                TREE_CODE (t) == UNION_TYPE ? "union" : "struct",
-                fieldlist ? "named " : "");
+       pedwarn ("%s has no %s",
+                TREE_CODE (t) == UNION_TYPE ? _("union") : _("struct"),
+                fieldlist ? _("named members") : _("members"));
     }
 
   /* Install struct as DECL_CONTEXT of each field decl.
@@ -5320,8 +5393,11 @@ finish_struct (t, fieldlist, attributes)
 #endif
 #ifdef PCC_BITFIELD_TYPE_MATTERS
                  if (PCC_BITFIELD_TYPE_MATTERS)
-                   DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
-                                         TYPE_ALIGN (TREE_TYPE (x)));
+                   {
+                     DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
+                                           TYPE_ALIGN (TREE_TYPE (x)));
+                     DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
+                   }
 #endif
                }
            }
@@ -5335,6 +5411,8 @@ finish_struct (t, fieldlist, attributes)
          /* Non-bit-fields are aligned for their type, except packed
             fields which require only BITS_PER_UNIT alignment.  */
          DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
+         if (! DECL_PACKED (x))
+           DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
        }
 
       DECL_INITIAL (x) = 0;
@@ -5392,6 +5470,7 @@ finish_struct (t, fieldlist, attributes)
       TYPE_FIELDS (x) = TYPE_FIELDS (t);
       TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
       TYPE_ALIGN (x) = TYPE_ALIGN (t);
+      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
     }
 
   /* If this was supposed to be a transparent union, but we can't
@@ -5511,7 +5590,7 @@ finish_enum (enumtype, values, attributes)
      tree attributes;
 {
   register tree pair, tem;
-  tree minnode = 0, maxnode = 0;
+  tree minnode = 0, maxnode = 0, enum_value_type;
   int precision, unsign;
   int toplevel = (global_binding_level == current_binding_level);
 
@@ -5552,6 +5631,11 @@ finish_enum (enumtype, values, attributes)
       precision = TYPE_PRECISION (long_long_integer_type_node);
     }
 
+  if (precision == TYPE_PRECISION (integer_type_node))
+    enum_value_type = type_for_size (precision, 0);
+  else
+    enum_value_type = enumtype;
+
   TYPE_MIN_VALUE (enumtype) = minnode;
   TYPE_MAX_VALUE (enumtype) = maxnode;
   TYPE_PRECISION (enumtype) = precision;
@@ -5576,8 +5660,20 @@ finish_enum (enumtype, values, attributes)
          DECL_SIZE (enu) = TYPE_SIZE (enumtype);
          DECL_SIZE_UNIT (enu) = TYPE_SIZE_UNIT (enumtype);
          DECL_ALIGN (enu) = TYPE_ALIGN (enumtype);
+         DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype);
          DECL_MODE (enu) = TYPE_MODE (enumtype);
-         DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
+
+         /* The ISO C Standard mandates enumerators to have type int,
+            even though the underlying type of an enum type is
+            unspecified.  Here we convert any enumerators that fit in
+            an int to type int, to avoid promotions to unsigned types
+            when comparing integers with enumerators that fit in the
+            int range.  When -pedantic is given, build_enumerator()
+            would have already taken care of those that don't fit.  */
+         if (int_fits_type_p (DECL_INITIAL (enu), enum_value_type))
+           DECL_INITIAL (enu) = convert (enum_value_type, DECL_INITIAL (enu));
+         else
+           DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
 
          TREE_PURPOSE (pair) = DECL_NAME (enu);
          TREE_VALUE (pair) = DECL_INITIAL (enu);
@@ -5599,6 +5695,7 @@ finish_enum (enumtype, values, attributes)
       TYPE_MODE (tem) = TYPE_MODE (enumtype);
       TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
+      TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
       TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
     }
 
@@ -5653,7 +5750,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'");
-      value = integer_zero_node;
+      value = convert (integer_type_node, value);
     }
 
   /* Set basis for default for next value.  */
@@ -5723,7 +5820,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
 
   if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1))))
     {
-      error ("return-type is an incomplete type");
+      error ("return type is an incomplete type");
       /* Make it return void instead.  */
       TREE_TYPE (decl1)
        = build_function_type (void_type_node,
@@ -5731,7 +5828,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes)
     }
 
   if (warn_about_return_type)
-    warning ("return-type defaults to `int'");
+    pedwarn_c99 ("return type defaults to `int'");
 
   /* Save the parm names or decls from this function's declarator
      where store_parm_decls will find them.  */
@@ -5993,8 +6090,7 @@ store_parm_decls ()
              if (DECL_NAME (parm) == 0)
                error_with_decl (parm, "parameter name omitted");
              else if (TREE_CODE (TREE_TYPE (parm)) != ERROR_MARK
-                      && (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
-                          == void_type_node))
+                      && VOID_TYPE_P (TREE_TYPE (parm)))
                {
                  error_with_decl (parm, "parameter `%s' declared void");
                  /* Change the type to error_mark_node so this parameter
@@ -6097,7 +6193,7 @@ store_parm_decls ()
            }
 
          /* If the declaration says "void", complain and ignore it.  */
-         if (found && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == void_type_node)
+         if (found && VOID_TYPE_P (TREE_TYPE (found)))
            {
              error_with_decl (found, "parameter `%s' declared void");
              TREE_TYPE (found) = integer_type_node;
@@ -6122,7 +6218,9 @@ store_parm_decls ()
              DECL_ARG_TYPE (found) = TREE_TYPE (found);
              DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
              DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
-             if (extra_warnings)
+             if (flag_isoc99)
+               pedwarn_with_decl (found, "type of `%s' defaults to `int'");
+             else if (extra_warnings)
                warning_with_decl (found, "type of `%s' defaults to `int'");
              pushdecl (found);
            }
@@ -6395,7 +6493,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
        }
 
       /* If the declaration says "void", complain and ignore it.  */
-      if (found && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == void_type_node)
+      if (found && VOID_TYPE_P (TREE_TYPE (found)))
        {
          error_with_decl (found, "parameter `%s' declared void");
          TREE_TYPE (found) = integer_type_node;
@@ -6519,7 +6617,8 @@ finish_function (nested)
       setjmp_protect_args ();
     }
 
-  if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main"))
+  if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")
+      && flag_hosted)
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
          != integer_type_node)
@@ -6534,6 +6633,9 @@ finish_function (nested)
 #ifdef DEFAULT_MAIN_RETURN
          /* Make it so that `main' always returns success by default.  */
          DEFAULT_MAIN_RETURN;
+#else
+         if (flag_isoc99)
+           c_expand_return (integer_zero_node);
 #endif
        }
     }
@@ -6567,7 +6669,7 @@ finish_function (nested)
   if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
     warning ("`noreturn' function does return");
   else if (warn_return_type && can_reach_end
-          && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) != void_type_node)
+          && !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");
@@ -6768,3 +6870,125 @@ lang_mark_tree (t)
   else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
     ggc_mark (TYPE_LANG_SPECIFIC (t));
 }
+
+/* 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. */
+
+/* Returns non-zero if the current statement is a full expression,
+   i.e. temporaries created during that statement should be destroyed
+   at the end of the statement.  */
+
+int
+stmts_are_full_exprs_p ()
+{
+  return 0;
+}
+
+/* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
+   C. */
+
+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.  */
+
+int
+current_function_name_declared ()
+{
+  abort ();
+  return 0;
+}
+
+/* Code to generate the RTL for a case label in C. */
+
+void
+do_case (low_value, high_value)
+     tree low_value;
+     tree high_value;
+{
+  tree value1 = NULL_TREE, value2 = NULL_TREE, label;
+
+  if (low_value != NULL_TREE)
+    value1 = check_case_value (low_value);
+  if (high_value != NULL_TREE)
+    value2 = check_case_value (high_value);
+
+  label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+  
+  if (pedantic && (high_value != NULL_TREE))
+    pedwarn ("ANSI C forbids case ranges");
+
+  if (value1 != error_mark_node && value2 != error_mark_node)
+    {
+      tree duplicate;
+      int success;
+      
+      if (high_value == NULL_TREE && value1 != NULL_TREE &&
+         pedantic && ! INTEGRAL_TYPE_P (TREE_TYPE (value1)))
+       pedwarn ("label must have integral type in ANSI C");
+      
+      if (low_value == NULL_TREE)
+       success = pushcase (NULL_TREE, 0, label, &duplicate);
+      else if (high_value == NULL_TREE)
+       success = pushcase (value1, convert_and_check, label,
+                           &duplicate);
+      else
+       success = pushcase_range (value1, value2, convert_and_check,
+                                 label, &duplicate);
+      
+      if (success == 1)
+       {
+         if (low_value == NULL_TREE)
+           error ("default label not within a switch statement");
+         else
+           error ("case label not within a switch statement");
+       }
+      else if (success == 2) {
+       if (low_value == NULL_TREE) 
+         {
+           error ("multiple default labels in one switch");
+           error_with_decl (duplicate, "this is the first default label");
+         }
+       else
+         error ("dupicate case value");
+       if (high_value != NULL_TREE)
+         error_with_decl (duplicate, "this is the first entry for that value");
+      }
+      else if (low_value != NULL_TREE) 
+       {
+         if (success == 3)
+           warning ("case value out of range");
+         else if (success == 5)
+           error ("case label within scope of cleanup or variable array");
+       }
+    }
+}
+
+/* Language specific handler of tree nodes used when generating RTL
+   from a tree. */
+
+tree
+lang_expand_stmt (t)
+     tree t ATTRIBUTE_UNUSED;
+{
+  abort ();
+  return NULL_TREE;
+}
+
+/* Accessor to set the 'current_function_name_declared' flag. */
+
+void
+set_current_function_name_declared (i)
+     int i ATTRIBUTE_UNUSED;
+{
+  abort ();
+}
+