diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 8c8627e..3ee5860 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1419,12 +1419,17 @@ c_finish_options (void)
     {
       size_t i;
 
-      cb_file_change (parse_in,
-		      linemap_add (line_table, LC_RENAME, 0,
-				   _("<built-in>"), 0));
+      {
+	/* Make sure all of the builtins about to be declared have
+	  BUILTINS_LOCATION has their source_location.  */
+	source_location builtins_loc = BUILTINS_LOCATION;
+	cpp_force_token_locations (parse_in, &builtins_loc);
 
-      cpp_init_builtins (parse_in, flag_hosted);
-      c_cpp_builtins (parse_in);
+	cpp_init_builtins (parse_in, flag_hosted);
+	c_cpp_builtins (parse_in);
+
+	cpp_stop_forcing_token_locations (parse_in);
+      }
 
       /* We're about to send user input to cpplib, so make it warn for
 	 things that we previously (when we sent it internal definitions)
diff --git a/gcc/cp/pph-streamer-out.c b/gcc/cp/pph-streamer-out.c
index b7a965c..1c5c5d4 100644
--- a/gcc/cp/pph-streamer-out.c
+++ b/gcc/cp/pph-streamer-out.c
@@ -94,11 +94,19 @@ pph_write_location (struct output_block *ob, location_t loc)
      streaming some builtins, we probably want to figure out what those are and
      simply add them to the cache in the preload.  */
   struct bitpack_d bp;
-  location_t highest_builtin_loc = line_table->maps[2].start_location - 1;
+  location_t first_non_builtin_loc =
+    line_table->maps[PPH_NUM_IGNORED_LINE_TABLE_ENTRIES].start_location;
 
   bp = bitpack_create (ob->main_stream);
-  if (loc < highest_builtin_loc)
-    bp_pack_value (&bp, true, 1);
+  if (loc < first_non_builtin_loc)
+    {
+      /* We should never stream out trees with locations between builtins
+	 and user locations (e.g. <command-line>).  */
+      if (loc > BUILTINS_LOCATION)
+        gcc_unreachable ();
+
+      bp_pack_value (&bp, true, 1);
+    }
   else
     {
       gcc_assert (loc >=
diff --git a/gcc/cp/pph-streamer.h b/gcc/cp/pph-streamer.h
index 19578fd..415995b 100644
--- a/gcc/cp/pph-streamer.h
+++ b/gcc/cp/pph-streamer.h
@@ -72,13 +72,13 @@ enum pph_symtab_marker {
    exactly 8 bytes in the file.  */
 static const char pph_id_str[] = "PPH0x42";
 
-/* When streaming out the line_table we will ignore the first 3 entries.
-   The first one is the entrance in the header, the second one is for
-   builtins, the third one is the command line, the fourth one is finally
-   the LC_RENAME back to the header file, we want to stream out starting at
-   that one, changing it's reason to LC_ENTER (as we ignored the original
-   entrance), and then streaming every other entry as is from that point on.  */
-#define PPH_NUM_IGNORED_LINE_TABLE_ENTRIES 3
+/* When streaming out the line_table we will ignore the first 2 entries.
+   The first one is the entrance in the header, the second one is the command
+   line, the third one is the LC_RENAME back to the header file: we want to
+   stream out starting at that one, changing it's reason to LC_ENTER (as we
+   ignored the original entrance), and then streaming every other entry as is
+   from that point on.  */
+#define PPH_NUM_IGNORED_LINE_TABLE_ENTRIES 2
 
 /* Structure of the header of a PPH file.  */
 typedef struct pph_file_header {
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 97df9bb..06623fe 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -1043,4 +1043,8 @@ extern void cpp_prepare_state (cpp_reader *, struct save_macro_data **);
 extern int cpp_read_state (cpp_reader *, const char *, FILE *,
 			   struct save_macro_data *);
 
+/* In lex.c */
+extern void cpp_force_token_locations (cpp_reader *, source_location *);
+extern void cpp_stop_forcing_token_locations (cpp_reader *);
+
 #endif /* ! LIBCPP_CPPLIB_H */
diff --git a/libcpp/init.c b/libcpp/init.c
index f3953d5..987482b 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -221,6 +221,9 @@ cpp_create_reader (enum c_lang lang, hash_table *table,
   /* Initialize table for push_macro/pop_macro.  */
   pfile->pushed_macros = 0;
 
+  /* Do not force token locations by default.  */
+  pfile->forced_token_location_p = NULL;
+
   /* The expression parser stack.  */
   _cpp_expand_op_stack (pfile);
 
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 31bb477..a8458aa 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -554,6 +554,10 @@ struct cpp_reader
 
   /* List of saved macros by push_macro.  */
   struct def_pragma_macro *pushed_macros;
+
+  /* If non-null, the lexer will use this location for the next token
+     instead of getting a location from the linemap.  */
+  source_location *forced_token_location_p;
 };
 
 /* Character classes.  Based on the more primitive macros in safe-ctype.h.
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 2a06b4f..0e3c27c 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1974,8 +1974,11 @@ _cpp_lex_direct (cpp_reader *pfile)
     }
   c = *buffer->cur++;
 
-  result->src_loc = linemap_position_for_column (pfile->line_table,
-			                                    CPP_BUF_COLUMN (buffer, buffer->cur));
+  if (pfile->forced_token_location_p)
+    result->src_loc = *pfile->forced_token_location_p;
+  else
+    result->src_loc = linemap_position_for_column (pfile->line_table,
+					  CPP_BUF_COLUMN (buffer, buffer->cur));
 
   switch (c)
     {
@@ -2836,3 +2839,19 @@ cpp_token_val_index (cpp_token *tok)
       return CPP_TOKEN_FLD_NONE;
     }
 }
+
+/* All tokens lexed in R after calling this function will be forced to have
+   their source_location the same as the location referenced by P, until
+   cpp_stop_forcing_token_locations is called for R.  */
+
+void cpp_force_token_locations (cpp_reader *r, source_location *p)
+{
+  r->forced_token_location_p = p;
+}
+
+/* Go back to assigning locations naturally for lexed tokens.  */
+
+void cpp_stop_forcing_token_locations (cpp_reader *r)
+{
+  r->forced_token_location_p = NULL;
+}
