OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index c3ba279..1f773d9 100644 (file)
@@ -29,15 +29,19 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "intl.h"
 #include "tree.h"
+#include "rtl.h"
 #include "flags.h"
 #include "function.h"
 #include "output.h"
+#include "expr.h"
 #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"
@@ -70,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;
@@ -79,7 +87,7 @@ int ggc_p = 1;
 
 tree pending_invalid_xref;
 /* File and line to appear in the eventual error message.  */
-char *pending_invalid_xref_file;
+const char *pending_invalid_xref_file;
 int pending_invalid_xref_line;
 
 /* While defining an enum type, this is 1 plus the last enumerator
@@ -115,7 +123,7 @@ static tree current_function_parm_tags;
 
 /* Similar, for the file and line that the prototype came from if this is
    an old-style definition.  */
-static char *current_function_prototype_file;
+static const char *current_function_prototype_file;
 static int current_function_prototype_line;
 
 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
@@ -322,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;
@@ -350,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
@@ -451,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
@@ -479,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;
@@ -499,6 +524,7 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
+      flag_digraphs = 1;
     }
   else if (!strncmp (p, "-std=", 5))
     {
@@ -518,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;
@@ -526,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")
@@ -539,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"))
        {
@@ -547,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"))
        {
@@ -555,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);
@@ -753,7 +789,7 @@ c_decode_option (argc, argv)
       warn_implicit_int = 1;
       mesg_implicit_function_declaration = 1;
       warn_return_type = 1;
-      warn_unused = 1;
+      set_Wunused (1);
       warn_switch = 1;
       warn_format = 1;
       warn_char_subscripts = 1;
@@ -1120,7 +1156,7 @@ poplevel (keep, reverse, functionbody)
              define_label (input_filename, lineno,
                            DECL_NAME (label));
            }
-         else if (warn_unused && !TREE_USED (label))
+         else if (warn_unused_label && !TREE_USED (label))
            warning_with_decl (label, "label `%s' defined but not used");
          IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
 
@@ -1281,7 +1317,7 @@ pop_label_level ()
              define_label (input_filename, lineno,
                            DECL_NAME (TREE_VALUE (link)));
            }
-         else if (warn_unused && !TREE_USED (TREE_VALUE (link)))
+         else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
            warning_with_decl (TREE_VALUE (link), 
                               "label `%s' defined but not used");
          IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
@@ -1380,7 +1416,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
   tree newtype = TREE_TYPE (newdecl);
   int errmsg = 0;
 
-  if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
+  if (DECL_P (olddecl))
     DECL_MACHINE_ATTRIBUTES (newdecl)
       =  merge_machine_decl_attributes (olddecl, newdecl);
 
@@ -1798,22 +1834,35 @@ 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.  */
       DECL_RTL (newdecl) = DECL_RTL (olddecl);
 
       /* Merge the type qualifiers.  */
-      if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
-         && !TREE_THIS_VOLATILE (newdecl))
+      if (TREE_CODE (olddecl) == FUNCTION_DECL
+         && DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
+         && ! TREE_THIS_VOLATILE (newdecl))
        TREE_THIS_VOLATILE (write_olddecl) = 0;
+
       if (TREE_READONLY (newdecl))
        TREE_READONLY (write_olddecl) = 1;
+
       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);
        }
 
@@ -1904,14 +1953,15 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
       TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
     }
 
-  /* 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);
-
   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;
+
+      DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
+
       if (DECL_BUILT_IN (olddecl))
        {
          /* Get rid of any built-in function if new arg types don't match it
@@ -1946,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)
@@ -2014,7 +2064,7 @@ pushdecl (x)
 
   if (name)
     {
-      char *file;
+      const char *file;
       int line;
       int different_binding_level = 0;
 
@@ -2135,6 +2185,7 @@ pushdecl (x)
              DECL_ORIGINAL_TYPE (x) = tt;
               tt = build_type_copy (tt);
               TYPE_NAME (tt) = x;
+             TREE_USED (tt) = TREE_USED (x);
               TREE_TYPE (x) = tt;
             }
         }
@@ -2145,7 +2196,8 @@ pushdecl (x)
 
         We get warnings about inline functions where they are defined.
         Avoid duplicate warnings where they are used.  */
-      if (TREE_PUBLIC (x) && ! DECL_INLINE (x))
+      if (TREE_PUBLIC (x)
+         && ! (TREE_CODE (x) == FUNCTION_DECL && DECL_INLINE (x)))
        {
          tree decl;
 
@@ -2195,7 +2247,7 @@ pushdecl (x)
            {
              if (type == error_mark_node)
                break;
-             if (TYPE_CONTEXT (type))
+             if (TYPE_CONTEXT (type))
                {
                  warning_with_decl (x, "type of external `%s' is not global");
                  /* By exiting the loop early, we leave TYPE nonzero,
@@ -2282,15 +2334,16 @@ pushdecl (x)
          /* Here to install a non-global value.  */
          tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
          tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
+
          IDENTIFIER_LOCAL_VALUE (name) = x;
 
          /* If this is an extern function declaration, see if we
             have a global definition or declaration for the function.  */
          if (oldlocal == 0
-             && DECL_EXTERNAL (x) && !DECL_INLINE (x)
              && oldglobal != 0
              && TREE_CODE (x) == FUNCTION_DECL
-             && TREE_CODE (oldglobal) == FUNCTION_DECL)
+             && TREE_CODE (oldglobal) == FUNCTION_DECL
+             && DECL_EXTERNAL (x) && ! DECL_INLINE (x))
            {
              /* We have one.  Their types must agree.  */
              if (! comptypes (TREE_TYPE (x),
@@ -2408,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;
     }
 
@@ -2480,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));
@@ -2501,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.
@@ -2537,8 +2598,8 @@ redeclaration_error_message (newdecl, olddecl)
       if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
          /* However, defining once as extern inline and a second
             time in another way is ok.  */
-         && !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
-              && !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
+         && ! (DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
+              && ! (DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
        return 1;
       return 0;
     }
@@ -2666,7 +2727,7 @@ shadow_label (name)
 
 tree
 define_label (filename, line, name)
-     char *filename;
+     const char *filename;
      int line;
      tree name;
 {
@@ -2680,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));
@@ -2854,13 +2919,14 @@ lookup_name_current_level (name)
 }
 \f
 /* Mark ARG for GC.  */
+
 static void 
 mark_binding_level (arg)
      void *arg;
 {
   struct binding_level *level = *(struct binding_level **) arg;
 
-  while (level)
+  for (; level != 0; level = level->level_chain)
     {
       ggc_mark_tree (level->names);
       ggc_mark_tree (level->tags);
@@ -2868,7 +2934,6 @@ mark_binding_level (arg)
       ggc_mark_tree (level->blocks);
       ggc_mark_tree (level->this_block);
       ggc_mark_tree (level->parm_order);
-      level = level->level_chain;
     }
 }
 
@@ -2938,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);
     
@@ -2984,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;
@@ -3004,9 +3072,11 @@ init_decl_processing ()
      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);
@@ -3017,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);
 
@@ -3026,6 +3097,55 @@ init_decl_processing ()
     = build_function_type (ptr_type_node,
                           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. */
+
+  if (TYPE_PRECISION (float_type_node)
+      == TYPE_PRECISION (long_integer_type_node))
+    {
+      g77_integer_type_node = long_integer_type_node;
+      g77_uinteger_type_node = long_unsigned_type_node;
+    }
+  else if (TYPE_PRECISION (float_type_node)
+          == TYPE_PRECISION (integer_type_node))
+    {
+      g77_integer_type_node = integer_type_node;
+      g77_uinteger_type_node = unsigned_type_node;
+    }
+  else
+    g77_integer_type_node = g77_uinteger_type_node = NULL_TREE;
+
+  if (g77_integer_type_node != NULL_TREE)
+    {
+      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_integer"),
+                           g77_integer_type_node));
+      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_uinteger"),
+                           g77_uinteger_type_node));
+    }
+
+  if (TYPE_PRECISION (float_type_node) * 2
+      == TYPE_PRECISION (long_integer_type_node))
+    {
+      g77_longint_type_node = long_integer_type_node;
+      g77_ulongint_type_node = long_unsigned_type_node;
+    }
+  else if (TYPE_PRECISION (float_type_node) * 2
+          == TYPE_PRECISION (long_long_integer_type_node))
+    {
+      g77_longint_type_node = long_long_integer_type_node;
+      g77_ulongint_type_node = long_long_unsigned_type_node;
+    }
+  else
+    g77_longint_type_node = g77_ulongint_type_node = NULL_TREE;
+
+  if (g77_longint_type_node != NULL_TREE)
+    {
+      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_longint"),
+                           g77_longint_type_node));
+      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_ulongint"),
+                           g77_ulongint_type_node));
+    }
+
   builtin_function ("__builtin_aggregate_incoming_address",
                    build_function_type (ptr_type_node, NULL_TREE),
                    BUILT_IN_AGGREGATE_INCOMING_ADDRESS,
@@ -3072,8 +3192,6 @@ init_decl_processing ()
 
   incomplete_decl_finalize_hook = finish_incomplete_decl;
 
-  lang_get_alias_set = c_get_alias_set;
-
   /* Record our roots.  */
 
   ggc_add_tree_root (c_global_trees, CTI_MAX);
@@ -3885,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;
                      }
@@ -3948,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;
@@ -4098,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);
@@ -4231,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;
@@ -4456,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)
@@ -4539,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
@@ -4631,6 +4750,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 #endif
          }
        decl = build_decl (FIELD_DECL, declarator, type);
+       DECL_NONADDRESSABLE_P (decl) = bitfield;
+
        if (size_varies)
          C_DECL_VARIABLE_SIZE (decl) = 1;
       }
@@ -4664,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");
@@ -4672,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)
@@ -4884,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;
@@ -4948,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");
@@ -4986,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.");
@@ -5033,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);
@@ -5133,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)
@@ -5146,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.
@@ -5259,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
                }
            }
@@ -5274,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;
@@ -5331,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
@@ -5450,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);
 
@@ -5491,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;
@@ -5515,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);
@@ -5538,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);
     }
 
@@ -5592,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.  */
@@ -5609,8 +5767,7 @@ build_enumerator (name, value)
                         && TREE_UNSIGNED (type)));
 
   decl = build_decl (CONST_DECL, name, type);
-  DECL_INITIAL (decl) = value;
-  TREE_TYPE (value) = type;
+  DECL_INITIAL (decl) = convert (type, value);
   pushdecl (decl);
 
   return tree_cons (decl, value, NULL_TREE);
@@ -5663,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,
@@ -5671,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.  */
@@ -5932,7 +6089,8 @@ store_parm_decls ()
            {
              if (DECL_NAME (parm) == 0)
                error_with_decl (parm, "parameter name omitted");
-             else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
+             else if (TREE_CODE (TREE_TYPE (parm)) != ERROR_MARK
+                      && VOID_TYPE_P (TREE_TYPE (parm)))
                {
                  error_with_decl (parm, "parameter `%s' declared void");
                  /* Change the type to error_mark_node so this parameter
@@ -5999,8 +6157,10 @@ store_parm_decls ()
         Associate decls with the names and store the decls
         into the TREE_PURPOSE slots.  */
 
+      /* We use DECL_WEAK as a flag to show which parameters have been
+        seen already since it is not used on PARM_DECL or CONST_DECL.  */
       for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
-       DECL_RESULT (parm) = 0;
+       DECL_WEAK (parm) = 0;
 
       for (parm = specparms; parm; parm = TREE_CHAIN (parm))
        {
@@ -6008,7 +6168,8 @@ store_parm_decls ()
 
          if (TREE_VALUE (parm) == 0)
            {
-             error_with_decl (fndecl, "parameter name missing from parameter list");
+             error_with_decl (fndecl,
+                              "parameter name missing from parameter list");
              TREE_PURPOSE (parm) = 0;
              continue;
            }
@@ -6025,14 +6186,14 @@ store_parm_decls ()
 
          /* If declaration already marked, we have a duplicate name.
             Complain, and don't use this decl twice.   */
-         if (found && DECL_RESULT (found) != 0)
+         if (found && DECL_WEAK (found))
            {
              error_with_decl (found, "multiple parameters named `%s'");
              found = 0;
            }
 
          /* 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;
@@ -6057,17 +6218,17 @@ 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);
            }
 
          TREE_PURPOSE (parm) = found;
 
-         /* Mark this decl as "already found" -- see test, above.
-            It is safe to use DECL_RESULT for this
-            since it is not used in PARM_DECLs or CONST_DECLs.  */
-         DECL_RESULT (found) = error_mark_node;
+         /* Mark this decl as "already found" */
+         DECL_WEAK (found) = 1;
        }
 
       /* Put anything which is on the parmdecls chain and which is
@@ -6093,7 +6254,7 @@ store_parm_decls ()
                  TREE_TYPE (parm) = error_mark_node;
                }
 
-             if (DECL_RESULT (parm) == 0)
+             if (! DECL_WEAK (parm))
                {
                  error_with_decl (parm,
                                   "declaration for parameter `%s' but no such parameter");
@@ -6309,7 +6470,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
   tree types = 0;
 
   for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
-    DECL_RESULT (parm) = 0;
+    DECL_WEAK (parm) = 0;
 
   for (parm = specparms; parm; parm = TREE_CHAIN (parm))
     {
@@ -6325,14 +6486,14 @@ combine_parm_decls (specparms, parmlist, void_at_end)
 
       /* If declaration already marked, we have a duplicate name.
         Complain, and don't use this decl twice.   */
-      if (found && DECL_RESULT (found) != 0)
+      if (found && DECL_WEAK (found))
        {
          error_with_decl (found, "multiple parameters named `%s'");
          found = 0;
        }
 
       /* 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;
@@ -6363,10 +6524,8 @@ combine_parm_decls (specparms, parmlist, void_at_end)
 
       TREE_PURPOSE (parm) = found;
 
-      /* Mark this decl as "already found" -- see test, above.
-        It is safe to use DECL_RESULT for this
-        since it is not used in PARM_DECLs or CONST_DECLs.  */
-      DECL_RESULT (found) = error_mark_node;
+      /* Mark this decl as "already found".  */
+      DECL_WEAK (found) = 1;
     }
 
   /* Complain about any actual PARM_DECLs not matched with any names.  */
@@ -6383,7 +6542,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
          TREE_TYPE (parm) = error_mark_node;
        }
 
-      if (DECL_RESULT (parm) == 0)
+      if (! DECL_WEAK (parm))
        {
          error_with_decl (parm,
                           "declaration for parameter `%s' but no such parameter");
@@ -6458,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)
@@ -6473,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
        }
     }
@@ -6506,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");
@@ -6707,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 ();
+}
+