diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index 0bab93b..aab82a1 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -214,6 +214,10 @@ pph_in_start_record (pph_stream *stream, unsigned *cache_ix)
       *cache_ix = -1;
     }
 
+  /* If we just requested a replacement on next insert, the upcoming
+     record better be a new record.  */
+  gcc_assert (!stream->cache.replace_next_by || marker == PPH_RECORD_START);
+
   return marker;
 }
 
@@ -1181,6 +1185,7 @@ pph_in_scope_chain (pph_stream *stream)
 {
   struct cp_binding_level *pph_bindings;
 
+  pph_cache_replace_next_by (stream, scope_chain->bindings);
   pph_bindings = pph_in_binding_level (stream);
 
   /* Merge the bindings obtained from STREAM in the global namespace.  */
diff --git a/gcc/cp/pph-streamer.c b/gcc/cp/pph-streamer.c
index b7ad486..4bc43cb 100644
--- a/gcc/cp/pph-streamer.c
+++ b/gcc/cp/pph-streamer.c
@@ -140,6 +140,7 @@ pph_stream_open (const char *name, const char *mode)
 	pph_init_read (stream);
       stream->cache.v = NULL;
       stream->cache.m = pointer_map_create ();
+      stream->cache.replace_next_by = NULL;
     }
 
   return stream;
@@ -340,13 +341,21 @@ pph_trace_bitpack (pph_stream *stream, struct bitpack_d *bp)
 
 
 /* Insert DATA in STREAM's pickle cache at slot IX.  If DATA already
-   existed in the cache, IX must be the same as the previous entry.  */
+   existed in the cache, IX must be the same as the previous entry.
+   If replace_next_by is set in the cache, discard DATA and use that
+   instead.  */
 
 void
 pph_cache_insert_at (pph_stream *stream, void *data, unsigned ix)
 {
   void **map_slot;
 
+    if (stream->cache.replace_next_by)
+      {
+	data = stream->cache.replace_next_by;
+	stream->cache.replace_next_by = NULL;
+      }
+
   map_slot = pointer_map_insert (stream->cache.m, data);
   if (*map_slot)
     {
diff --git a/gcc/cp/pph-streamer.h b/gcc/cp/pph-streamer.h
index 8d0c024..8ab098d 100644
--- a/gcc/cp/pph-streamer.h
+++ b/gcc/cp/pph-streamer.h
@@ -77,6 +77,12 @@ typedef struct pph_pickle_cache {
 
   /* Map between slots in the array and pointers.  */
   struct pointer_map_t *m;
+
+  /* On the next call to pph_cache_insert_at, put this pointer in the cache
+     instead of the one passed as a parameter. This is used on read to redirect
+     pointers to global structure that already exist in the reader.
+     Regular behavior is maintained if this is NULL.  */
+  void *replace_next_by;
 } pph_pickle_cache;
 
 
@@ -403,4 +409,13 @@ pph_in_bitpack (pph_stream *stream)
   return bp;
 }
 
+
+/* Replace the next cache insert in STREAM by NEW_P.  */
+
+static inline void
+pph_cache_replace_next_by (pph_stream *stream, void *new_p)
+{
+  stream->cache.replace_next_by = new_p;
+}
+
 #endif  /* GCC_CP_PPH_STREAMER_H  */
