diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d3fcba646f62eb79f85e10c5a41c8b8e3e014b79..78895ad6f24cae5706e45f635f025d0c892c3f99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2004-07-09  Zack Weinberg  <zack@codesourcery.com>
+	    Andrew Pinski  <apinski@apple.com>
+
+	* c-opts.c (c_common_post_options): Force unit-at-a-time mode
+	on when we have more than one input file.
+	(c_common_parse_file): Restore loop over all input files.
+	Clarify diagnostic for -dy when YYDEBUG wasn't defined.
+
+	* c-decl.c (set_type_context): New function.
+	(pop_scope): Use it to set context of types.  When we
+	encounter a TYPE_DECL, set the context of the attached type too.
+	(pop_file_scope): Don't call cpp_undef_all here.
+	(diagnose_mismatched_decls): Do not complain about a second
+	definition of an 'extern inline' function if it's not in the
+	same translation unit.  Do not complain about inline
+	declaration after use if the use was in a different
+	translation unit.
+	(merge_decls): Don't clobber olddecl's DECL_CONTEXT.
+	(pushdecl): Do not put DECL_EXTERNAL, !TREE_PUBLIC decls in
+	the external scope.
+	(pushdecl_top_level): Likewise.
+	(grokdeclarator): Clarify what is going on with setting
+	DECL_EXTERNAL on function types, a little.
+	(c_write_global_declarations): Don't do anything if
+	-fsyntax-only or errors have been encountered.
+
 2004-07-09  Zack Weinberg  <zack@codesourcery.com>
 
 	* vec.c, vec.h (vec_assert_fail): Use unsigned int for LINE argument.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 8346c8a82e779b22f49266fbee771660140fadf9..6ff2dff081f29b4eecb7bb56f995d104ea70c4e9 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -622,6 +622,16 @@ push_scope (void)
     }
 }
 
+/* Set the TYPE_CONTEXT of all of TYPE's variants to CONTEXT.  */
+
+static void
+set_type_context (tree type, tree context)
+{
+  for (type = TYPE_MAIN_VARIANT (type); type;
+       type = TYPE_NEXT_VARIANT (type))
+    TYPE_CONTEXT (type) = context;
+}
+
 /* Exit a scope.  Restore the state of the identifier-decl mappings
    that were in effect when this scope was entered.  Return a BLOCK
    node containing all the DECLs in this scope that are of interest
@@ -711,7 +721,7 @@ pop_scope (void)
 	case ENUMERAL_TYPE:
 	case UNION_TYPE:
 	case RECORD_TYPE:
-	  TYPE_CONTEXT (p) = context;
+	  set_type_context (p, context);
 
 	  /* Types may not have tag-names, in which case the type
 	     appears in the bindings list with b->id NULL.  */
@@ -767,7 +777,11 @@ pop_scope (void)
 	     This makes same_translation_unit_p work, and causes
 	     static declarations to be given disambiguating suffixes.  */
 	  if (scope == file_scope && num_in_fnames > 1)
-	    DECL_CONTEXT (p) = context;
+	    {
+	      DECL_CONTEXT (p) = context;
+	      if (TREE_CODE (p) == TYPE_DECL)
+		set_type_context (TREE_TYPE (p), context);
+	    }
 
 	  /* Fall through.  */
 	  /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
@@ -865,7 +879,6 @@ pop_file_scope (void)
   /* Pop off the file scope and close this translation unit.  */
   pop_scope ();
   file_scope = 0;
-  cpp_undef_all (parse_in);
   cgraph_finalize_compilation_unit ();
 }
 
@@ -1215,7 +1228,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	      && !(DECL_DECLARED_INLINE_P (olddecl)
 		   && DECL_EXTERNAL (olddecl)
 		   && !(DECL_DECLARED_INLINE_P (newdecl)
-			&& DECL_EXTERNAL (newdecl))))
+			&& DECL_EXTERNAL (newdecl)
+	    		&& same_translation_unit_p (olddecl, newdecl))))
 	    {
 	      error ("%Jredefinition of '%D'", newdecl, newdecl);
 	      locate_old_decl (olddecl, error);
@@ -1385,8 +1399,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 
       /* Inline declaration after use or definition.
 	 ??? Should we still warn about this now we have unit-at-a-time
-	 mode and can get it right?  */
-      if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl))
+	 mode and can get it right?
+	 Definitely don't complain if the decls are in different translation
+	 units.  */
+      if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
+	  && same_translation_unit_p (olddecl, newdecl))
 	{
 	  if (TREE_USED (olddecl))
 	    {
@@ -1669,14 +1686,16 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     }
 
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
-     But preserve OLDDECL's DECL_UID.  */
+     But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
   {
     unsigned olddecl_uid = DECL_UID (olddecl);
+    tree olddecl_context = DECL_CONTEXT (olddecl);
 
     memcpy ((char *) olddecl + sizeof (struct tree_common),
 	    (char *) newdecl + sizeof (struct tree_common),
 	    sizeof (struct tree_decl) - sizeof (struct tree_common));
     DECL_UID (olddecl) = olddecl_uid;
+    DECL_CONTEXT (olddecl) = olddecl_context;
   }
 
   /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
@@ -1897,14 +1916,13 @@ pushdecl (tree x)
 	 they are in different translation units.  In any case,
 	 the static does not go in the externals scope.  */
       if (b
-	  && (DECL_EXTERNAL (x) || TREE_PUBLIC (x)
-	      || same_translation_unit_p (x, b->decl))
+	  && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
 	  && duplicate_decls (x, b->decl))
 	{
 	  bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
 	  return b->decl;
 	}
-      else if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
+      else if (TREE_PUBLIC (x))
 	{
 	  bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
 	  nested = true;
@@ -1991,7 +2009,7 @@ pushdecl_top_level (tree x)
   if (I_SYMBOL_BINDING (name))
     abort ();
 
-  if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
+  if (TREE_PUBLIC (x))
     {
       bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
       nested = true;
@@ -4459,14 +4477,6 @@ grokdeclarator (tree declarator, tree declspecs,
       }
     else if (TREE_CODE (type) == FUNCTION_TYPE)
       {
-	/* Every function declaration is "external"
-	   except for those which are inside a function body
-	   in which `auto' is used.
-	   That is a case not specified by ANSI C,
-	   and we use it for forward declarations for nested functions.  */
-	int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
-			  || current_scope == file_scope);
-
 	if (specbits & (1 << (int) RID_AUTO)
 	    && (pedantic || current_scope == file_scope))
 	  pedwarn ("invalid storage class for function `%s'", name);
@@ -4497,8 +4507,16 @@ grokdeclarator (tree declarator, tree declspecs,
 	    && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
 	  warning ("`noreturn' function returns non-void value");
 
-	if (extern_ref)
+	/* Every function declaration is an external reference
+	   (DECL_EXTERNAL) except for those which are not at file
+	   scope and are explicitly declared "auto".  This is
+	   forbidden by standard C (C99 6.7.1p5) and is interpreted by
+	   GCC to signify a forward declaration of a nested function.  */
+	if ((specbits & (1 << RID_AUTO)) && current_scope != file_scope)
+	  DECL_EXTERNAL (decl) = 0;
+	else
 	  DECL_EXTERNAL (decl) = 1;
+	   
 	/* Record absence of global scope for `static' or `auto'.  */
 	TREE_PUBLIC (decl)
 	  = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
@@ -6630,6 +6648,11 @@ c_write_global_declarations (void)
   if (pch_file)
     return;
 
+  /* Don't waste time on further processing if -fsyntax-only or we've
+     encountered errors.  */
+  if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in))
+    return;
+
   /* Close the external scope.  */
   ext_block = pop_scope ();
   external_scope = 0;
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 6ae668b1a6c9de89e3836cefa5f4422118893bf2..da35c5327fa4f56c2d6014b6e4e7f5ea4fbc3b4e 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -943,6 +943,11 @@ c_common_post_options (const char **pfilename)
       flag_inline_functions = 0;
     }
 
+  /* If we are given more than one input file, we must use
+     unit-at-a-time mode.  */
+  if (num_in_fnames > 1)
+    flag_unit_at_a_time = 1;
+
   /* Default to ObjC sjlj exception handling if NeXT runtime.  */
   if (flag_objc_sjlj_exceptions < 0)
     flag_objc_sjlj_exceptions = flag_next_runtime;
@@ -1061,22 +1066,37 @@ c_common_init (void)
 void
 c_common_parse_file (int set_yydebug)
 {
+  unsigned int i;
+
+  /* Enable parser debugging, if requested and we can.  If requested
+     and we can't, notify the user.  */
 #if YYDEBUG != 0
   yydebug = set_yydebug;
 #else
   if (set_yydebug)
-    warning ("YYDEBUG not defined");
+    warning ("YYDEBUG was not defined at build time, -dy ignored");
 #endif
 
-  if (num_in_fnames > 1)
-    fatal_error ("sorry, inter-module analysis temporarily out of commission");
-
-  finish_options ();
-  pch_init ();
-  push_file_scope ();
-  c_parse_file ();
-  finish_file ();
-  pop_file_scope ();
+  i = 0;
+  for (;;)
+    {
+      finish_options ();
+      pch_init ();
+      push_file_scope ();
+      c_parse_file ();
+      finish_file ();
+      pop_file_scope ();
+
+      if (++i >= num_in_fnames)
+	break;
+      cpp_undef_all (parse_in);
+      this_input_filename
+	= cpp_read_main_file (parse_in, in_fnames[i]);
+      /* If an input file is missing, abandon further compilation.
+         cpplib has issued a diagnostic.  */
+      if (!this_input_filename)
+	break;
+    }
 }
 
 /* Common finish hook for the C, ObjC and C++ front ends.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 601892ef05204a5ee5f4a6dae1a17ab770273823..7548279c09a4fe9229c67bc93482d82d2b973301 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-07-09  Zack Weinberg  <zack@codesourcery.com>
+	    Andrew Pinski  <apinski@apple.com>
+
+	* gcc.dg/noncompile/init-4.c: Remove bogus dg-error marker.
+
 2004-07-09  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
 	* gfortran.fortran-torture/compile/name_clash2.f90: Remove outdated
@@ -6,7 +11,7 @@
 2004-07-09  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 	Paul Brook  <paul@codesourcery.com>
 
-	* gfortran.dg/dg.exp: Use revised wilcard for suffixes, also allow 
+	* gfortran.dg/dg.exp: Use revised wilcard for suffixes, also allow
 	'.f95' and '.F95'.
 
 2004-07-09  Diego Novillo  <dnovillo@redhat.com>
@@ -27,7 +32,7 @@
 	* gfortran.fortran-torture/compile/implicit_2.f90: New test.
 
 	* gfortran.dg/implicit_1.f90: New test.
-	
+
 2004-07-09  David Billinghurst (David.Billinghurst@riotinto.com)
 
 	* lib/gfortran-dg.exp (gfortran-dg-test):  Adapt regular
@@ -37,7 +42,7 @@
 
 2004-07-09  David Billinghurst (David.Billinghurst@riotinto.com)
 
-	* lib/fortran-torture.exp: Rename proc search_for to 
+	* lib/fortran-torture.exp: Rename proc search_for to
 	search_for_re.
 
 2004-07-09  Eric Botcazou  <ebotcazou@libertysurf.fr>
@@ -60,7 +65,7 @@
 
 2004-07-09  David Billinghurst (David.Billinghurst@riotinto.com)
 
-	* gfortran.dg/g77/f77-edit-s-out.f: Copy from g77.dg. XFAIL 
+	* gfortran.dg/g77/f77-edit-s-out.f: Copy from g77.dg. XFAIL
 	* gfortran.dg/g77/f77-edit-t-in.f: Likewise
 	* gfortran.dg/g77/f77-edit-x-out.f: Likewise
 
@@ -68,7 +73,7 @@
 
 	* gfortran.dg/g77/7388.f: Copy from g77.dg
 	* gfortran.dg/g77/f77-edit-i-out.f: Likewise
-	* gfortran.dg/g77/f77-edit-apostrophe-out.f: Likewise  
+	* gfortran.dg/g77/f77-edit-apostrophe-out.f: Likewise
 	* gfortran.dg/g77/f77-edit-slash-out.f: Likewise
 	* gfortran.dg/g77/f77-edit-colon-out.f: Likewise
 	* gfortran.dg/g77/f77-edit-t-out.f: Likewise
diff --git a/gcc/testsuite/gcc.dg/noncompile/init-4.c b/gcc/testsuite/gcc.dg/noncompile/init-4.c
index 906c115b8cc6ea768b5c1a0eeebda13d6505098b..2d8bef3cb016b702adaba93b4425506f349b313f 100644
--- a/gcc/testsuite/gcc.dg/noncompile/init-4.c
+++ b/gcc/testsuite/gcc.dg/noncompile/init-4.c
@@ -1,3 +1,2 @@
 struct a { char *b; } c[D] /* { dg-error "undeclared" } */
-  =                        /* { dg-error "storage size" } */
-    { { "" } } ;  /* { dg-warning "braces around scalar initializer|near" } */
+  = { { "" } } ;  /* { dg-warning "braces around scalar initializer|near" } */