From 22234f56d2395ae470961d3eb5fdc65a7597af9a Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Wed, 18 Feb 2004 14:02:39 -0800 Subject: [PATCH] re PR preprocessor/14103 (ICEs on "gcc -E -imacros foo.h baz.c") * cpphash.h (struct cpp_buffer): Restore return_at_eof field. This partly reverts my 2003-10-01 change, because we're back to logically including inside the main line. * cpplex.c (_cpp_get_fresh_line): Check return_at_eof field. * cppmacro.c (cpp_scan_nooutput): Set return_at_eof of current buffer. Fixes PR preprocessor/14103. * cppfiles.c (_cpp_stack_include): When appropriate decrement line_table's highest_location, fixing LAST_SOURCE_LINE_LOCATION. (cpp_push_include): Don't need to increment pfile's line field. * line-map.h (LAST_SOURCE_LINE_LOCATION): Only decrement by 1. * c-ppoutput.c (print struct): New first_time field. (init_pp_output): Set print.first_time. (pp_file_change): Use print.first_time, rather than MAIN_FILE_P, which is set also for (say) . Clear print.first_time. * cppfiles.c (struct _cpp_file): Comment and type for pch field does not match the code, so fix both. (should_stack_file): Inline include_pch_p function. (include_pch_p): Remove pointless function. * cpphash.h (struct cpp_buffer): Remove unused search_cached field. From-SVN: r78049 --- gcc/ChangeLog | 26 ++++++++++++++++++++++++++ gcc/c-ppoutput.c | 6 ++++-- gcc/cppfiles.c | 35 +++++++++++++++++------------------ gcc/cpphash.h | 7 ++++--- gcc/cpplex.c | 7 +++++-- gcc/cppmacro.c | 4 ++++ gcc/line-map.h | 2 +- 7 files changed, 61 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d89ce3c1462..59750e81aa7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2004-02-18 Per Bothner + + * cpphash.h (struct cpp_buffer): Restore return_at_eof field. This + partly reverts my 2003-10-01 change, because we're back to logically + including inside the main line. + * cpplex.c (_cpp_get_fresh_line): Check return_at_eof field. + * cppmacro.c (cpp_scan_nooutput): Set return_at_eof of current buffer. + Fixes PR preprocessor/14103. + + * cppfiles.c (_cpp_stack_include): When appropriate decrement + line_table's highest_location, fixing LAST_SOURCE_LINE_LOCATION. + (cpp_push_include): Don't need to increment pfile's line field. + * line-map.h (LAST_SOURCE_LINE_LOCATION): Only decrement by 1. + + * c-ppoutput.c (print struct): New first_time field. + (init_pp_output): Set print.first_time. + (pp_file_change): Use print.first_time, rather than MAIN_FILE_P, + which is set also for (say) . Clear print.first_time. + + * cppfiles.c (struct _cpp_file): Comment and type for pch field + does not match the code, so fix both. + (should_stack_file): Inline include_pch_p function. + (include_pch_p): Remove pointless function. + + * cpphash.h (struct cpp_buffer): Remove unused search_cached field. + 2004-02-18 Kazu Hirata * config/h8300/h8300.md (four define_peephole2's): Use diff --git a/gcc/c-ppoutput.c b/gcc/c-ppoutput.c index 1dba766b42a..24be879acb3 100644 --- a/gcc/c-ppoutput.c +++ b/gcc/c-ppoutput.c @@ -36,6 +36,7 @@ static struct const cpp_token *source; /* Source token for spacing. */ int src_line; /* Line number currently being written. */ unsigned char printed; /* Nonzero if something output at line. */ + bool first_time; /* pp_file_change hasn't been called yet. */ } print; /* General output routines. */ @@ -118,6 +119,7 @@ init_pp_output (FILE *out_stream) print.printed = 0; print.prev = 0; print.outf = out_stream; + print.first_time = 1; } /* Writes out the preprocessed file, handling spacing and paste @@ -365,12 +367,12 @@ pp_file_change (const struct line_map *map) if (map != NULL) { - /* First time? */ - if (MAIN_FILE_P (map)) + if (print.first_time) { /* Avoid printing foo.i when the main file is foo.c. */ if (!cpp_get_options (parse_in)->preprocessed) print_line (map->start_location, flags); + print.first_time = 0; } else { diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 862be9f61d2..3a42e78639b 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -109,11 +109,8 @@ struct _cpp_file /* If BUFFER above contains the true contents of the file. */ bool buffer_valid; - /* 0: file not known to be a PCH. - 1: file is a PCH (on return from find_include_file). - 2: file is not and never will be a valid precompiled header. - 3: file is always a valid precompiled header. */ - uchar pch; + /* File is a PCH (on return from find_include_file). */ + bool pch; }; /* A singly-linked list for all searches for a given file name, with @@ -180,7 +177,6 @@ static void read_name_map (cpp_dir *dir); static char *remap_filename (cpp_reader *pfile, _cpp_file *file); static char *append_file_to_dir (const char *fname, cpp_dir *dir); static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname); -static bool include_pch_p (_cpp_file *file); static int pchf_adder (void **slot, void *data); static int pchf_save_compare (const void *e1, const void *e2); static int pchf_compare (const void *d_p, const void *e_p); @@ -577,7 +573,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) return false; /* Handle PCH files immediately; don't stack them. */ - if (include_pch_p (file)) + if (file->pch) { pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname); close (file->fd); @@ -747,13 +743,25 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, enum include_type type) { struct cpp_dir *dir; + _cpp_file *file; dir = search_path_head (pfile, fname, angle_brackets, type); if (!dir) return false; - return _cpp_stack_file (pfile, _cpp_find_file (pfile, fname, dir, false), - type == IT_IMPORT); + file = _cpp_find_file (pfile, fname, dir, false); + + /* Compensate for the increment in linemap_add. In the case of a + normal #include, we're currently at the start of the line + *following* the #include. A separate source_location for this + location makes no sense (until we do the LC_LEAVE), and + complicates LAST_SOURCE_LINE_LOCATION. This does not apply if we + found a PCH file (in which case linemap_add is not called) or we + were included from the command-line. */ + if (! file->pch && file->err_no == 0 && type != IT_CMDLINE) + pfile->line_table->highest_location--; + + return _cpp_stack_file (pfile, file, type == IT_IMPORT); } /* Could not open FILE. The complication is dependency output. */ @@ -1032,8 +1040,6 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname, bool cpp_push_include (cpp_reader *pfile, const char *fname) { - /* Make the command line directive take up a line. */ - pfile->line++; return _cpp_stack_include (pfile, fname, false, IT_CMDLINE); } @@ -1228,13 +1234,6 @@ remap_filename (cpp_reader *pfile, _cpp_file *file) } } -/* Return true if FILE is usable by PCH. */ -static bool -include_pch_p (_cpp_file *file) -{ - return file->pch & 1; -} - /* Returns true if PCHNAME is a valid PCH file for FILE. */ static bool validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname) diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 693d2ba7287..4e86bf37d5b 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -310,9 +310,10 @@ struct cpp_buffer buffers. */ unsigned int from_stage3 : 1; - /* Nonzero means that the directory to start searching for "" - include files has been calculated and stored in "dir" below. */ - unsigned char search_cached; + /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is + true, a CPP_EOF token is then returned. Otherwise, the next + token from the enclosing buffer is returned. */ + unsigned int return_at_eof : 1; /* One for a system header, two for a C system header file that therefore needs to be extern "C" protected in C++, and zero otherwise. */ diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 27ef0ee4441..9912aac559c 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -747,6 +747,8 @@ _cpp_lex_token (cpp_reader *pfile) bool _cpp_get_fresh_line (cpp_reader *pfile) { + int return_at_eof; + /* We can't get a new line until we leave the current directive. */ if (pfile->state.in_directive) return false; @@ -779,9 +781,10 @@ _cpp_get_fresh_line (cpp_reader *pfile) CPP_BUF_COLUMN (buffer, buffer->cur), "no newline at end of file"); } - + + return_at_eof = buffer->return_at_eof; _cpp_pop_buffer (pfile); - if (pfile->buffer == NULL) + if (pfile->buffer == NULL || return_at_eof) return false; } } diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index f396a9dbec4..f4e885740b4 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -1138,6 +1138,10 @@ cpp_sys_macro_p (cpp_reader *pfile) void cpp_scan_nooutput (cpp_reader *pfile) { + /* Request a CPP_EOF token at the end of this file, rather than + transparently continuing with the including file. */ + pfile->buffer->return_at_eof = true; + if (CPP_OPTION (pfile, traditional)) while (_cpp_read_logical_line_trad (pfile)) ; diff --git a/gcc/line-map.h b/gcc/line-map.h index 28c12c2d797..a3933a349e2 100644 --- a/gcc/line-map.h +++ b/gcc/line-map.h @@ -147,7 +147,7 @@ extern void linemap_print_containing_files (struct line_maps *, #define LAST_SOURCE_LINE(MAP) \ SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP)) #define LAST_SOURCE_LINE_LOCATION(MAP) \ - ((((MAP)[1].start_location - 2 - (MAP)->start_location) \ + ((((MAP)[1].start_location - 1 - (MAP)->start_location) \ & ~((1 << (MAP)->column_bits) - 1)) \ + (MAP)->start_location)