This patch has yet to be committed to trunk, but I need it in pph. This doesn't change anything (except that we now removed the built-in entry in the line_table, so there are now only 2 ignored line table entries).
Tested with bootstrap and pph regression testing (full testing done with trunk patch pending review). Gab 2011-08-16 Gabriel Charette <gch...@google.com> gcc/c-family/ChangeLog.pph * c-opts.c (c_finish_options): Force BUILTINS_LOCATION for tokens defined in cpp_init_builtins and c_cpp_builtins. libcpp/ChangeLog.pph * init.c (cpp_create_reader): Inititalize forced_token_location_p. * internal.h (struct cpp_reader): Add field forced_token_location_p. * lex.c (_cpp_lex_direct): Use forced_token_location_p. (cpp_force_token_locations): New. (cpp_stop_forcing_token_locations): New. gcc/cp/ChangeLog.pph * pph-streamer-out.c (pph_write_location): Better asserts. * pph-streamer.h (PPH_NUM_IGNORED_LINE_TABLE_ENTRIES): Set to 2. 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; +} -- This patch is available for review at http://codereview.appspot.com/4907044