diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index e71f744..2e3545a 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -976,15 +976,14 @@ pph_in_lang_type (pph_stream *stream)
 }
 
 
-/* Add all the new names declared in NEW_NS to NS.  */
+/* Add all bindings declared in BL to NS.  */
 
 static void
-pph_add_names_to_namespace (tree ns, tree new_ns)
+pph_add_bindings_to_namespace (struct cp_binding_level *bl, tree ns)
 {
   tree t, chain;
-  struct cp_binding_level *level = NAMESPACE_LEVEL (new_ns);
 
-  for (t = level->names; t; t = chain)
+  for (t = bl->names; t; t = chain)
     {
       /* Pushing a decl into a scope clobbers its DECL_CHAIN.
 	 Preserve it.  */
@@ -992,18 +991,35 @@ pph_add_names_to_namespace (tree ns, tree new_ns)
       pushdecl_into_namespace (t, ns);
     }
 
-  for (t = level->namespaces; t; t = chain)
+  for (t = bl->namespaces; t; t = chain)
     {
       /* Pushing a decl into a scope clobbers its DECL_CHAIN.
 	 Preserve it.  */
       /* FIXME pph: we should first check to see if it isn't already there.  */
       chain = DECL_CHAIN (t);
       pushdecl_into_namespace (t, ns);
-      pph_add_names_to_namespace (t, t);
+      /* FIXME pph: this carried over from pph_add_names_to_namespace,
+	 it only makes sense to use this when merging names in an existing
+	 namespace.
+      pph_add_bindings_to_namespace (NAMESPACE_LEVEL (t), t);  */
     }
 }
 
 
+/* Merge scope_chain bindings from the stream into SS. */
+
+static void
+pph_in_scope_chain (pph_stream *stream)
+{
+  struct cp_binding_level *pph_bindings;
+
+  pph_bindings = pph_in_binding_level (stream);
+
+  /* Merge the bindings obtained from STREAM in the global namespace.  */
+  pph_add_bindings_to_namespace (pph_bindings, global_namespace);
+}
+
+
 /* Wrap a macro DEFINITION for printing in an error.  */
 
 static char *
@@ -1128,7 +1144,6 @@ pph_read_file_contents (pph_stream *stream)
   cpp_ident_use *bad_use;
   const char *cur_def;
   cpp_idents_used idents_used;
-  tree file_ns;
 
   pth_load_identifiers (&idents_used, stream);
 
@@ -1141,12 +1156,12 @@ pph_read_file_contents (pph_stream *stream)
   /* Re-instantiate all the pre-processor symbols defined by STREAM.  */
   cpp_lt_replay (parse_in, &idents_used);
 
-  /* Read global_namespace from STREAM and add all the names defined
-     there to the current global_namespace.  */
-  file_ns = pph_in_tree (stream);
+  /* Read the bindings from STREAM and merge them with the current bindings.  */
+  pph_in_scope_chain (stream);
+
   if (flag_pph_dump_tree)
-    pph_dump_namespace (pph_logfile, file_ns);
-  pph_add_names_to_namespace (global_namespace, file_ns);
+    pph_dump_namespace (pph_logfile, global_namespace);
+
   keyed_classes = pph_in_tree (stream);
   unemitted_tinfo_decls = pph_in_tree_vec (stream);
   /* FIXME pph: This call replaces the tinfo, we should merge instead.
diff --git a/gcc/cp/pph-streamer-out.c b/gcc/cp/pph-streamer-out.c
index 3187338..691cfdd 100644
--- a/gcc/cp/pph-streamer-out.c
+++ b/gcc/cp/pph-streamer-out.c
@@ -935,6 +935,33 @@ pph_out_lang_type (pph_stream *stream, tree type, bool ref_p)
 }
 
 
+/* Write saved_scope information stored in SS, does NOT output all fields,
+   meant to be used for the global variable "scope_chain" only.
+   Output bindings as references if REF_P is true.  */
+
+static void
+pph_out_scope_chain (pph_stream *stream, struct saved_scope *ss, bool ref_p)
+{
+  /* old_namespace should be global_namespace and all entries listed below
+     should be NULL or 0; otherwise the header parsed was incomplete.  */
+  gcc_assert ( ss->old_namespace == global_namespace
+      && !(ss->class_name || ss->class_type || ss->access_specifier
+	   || ss->function_decl || ss->template_parms || ss->x_saved_tree
+	   || ss->class_bindings || ss->prev || ss->unevaluated_operand
+	   || ss->inhibit_evaluation_warnings
+	   || ss->x_processing_template_decl
+	   || ss->x_processing_specialization
+	   || ss->x_processing_explicit_instantiation
+	   || ss->need_pop_function_context
+	   || ss->x_stmt_tree.x_cur_stmt_list
+	   || ss->x_stmt_tree.stmts_are_full_exprs_p));
+
+  /* We only need to write out the bindings, everything else should
+     be NULL or be some temporary disposable state.  */
+  pph_out_binding_level (stream, ss->bindings, ref_p);
+}
+
+
 /* Save the IDENTIFIERS to the STREAM.  */
 
 static void
@@ -991,9 +1018,9 @@ static void
 pph_write_file_contents (pph_stream *stream, cpp_idents_used *idents_used)
 { 
   pth_save_identifiers (idents_used, stream);
+  pph_out_scope_chain (stream, scope_chain, false);
   if (flag_pph_dump_tree)
     pph_dump_namespace (pph_logfile, global_namespace);
-  pph_out_tree (stream, global_namespace, false);
   pph_out_tree (stream, keyed_classes, false);
   pph_out_tree_vec (stream, unemitted_tinfo_decls, false);
 }
diff --git a/gcc/cp/pph-streamer.c b/gcc/cp/pph-streamer.c
index 7c9b862..1e0a8c4 100644
--- a/gcc/cp/pph-streamer.c
+++ b/gcc/cp/pph-streamer.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "version.h"
 #include "cppbuiltin.h"
+#include "name-lookup.h"
 
 /* Return true if the given tree T is streamable.  */
 
@@ -78,6 +79,8 @@ pph_preload_common_nodes (struct lto_streamer_cache_d *cache)
   for (i = 0; i < CTI_MAX; i++)
     if (c_global_trees[i])
       lto_streamer_cache_append (cache, c_global_trees[i]);
+
+  lto_streamer_cache_append (cache, global_namespace);
 }
 
 
