diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-07-07 11:28:59 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-07-07 11:40:04 -0700 |
commit | 6bf2ff0d52a90acdc54f18c75d1978f6b4de4609 (patch) | |
tree | 9b411964bcaef7d64711f4ebd372e095be34adca /libcpp/directives.c | |
parent | 6f9c9ea40a1e937ea1b549625cf7762d4a8a2078 (diff) | |
download | gcc-6bf2ff0d52a90acdc54f18c75d1978f6b4de4609.zip gcc-6bf2ff0d52a90acdc54f18c75d1978f6b4de4609.tar.gz gcc-6bf2ff0d52a90acdc54f18c75d1978f6b4de4609.tar.bz2 |
preprocessor: Better line info for <builtin> & <command-line>
With C++ module header units it becomes important to distinguish
between macros defined in forced headers (& commandline & builtins)
from those defined in the header file being processed. We weren't
making that easy because we treated the builtins and command-line
locations somewhat file-like, with incrementing line numbers, and
showing them as included from line 1 of the main file. This patch does
3 things:
0) extend the idiom that 'line 0' of a file means 'the file as a whole'
1) builtins and command-line macros are shown as-if included from line zero.
2) when emitting preprocessed output we keep resetting the line number
so that re-reading that preprocessed output will get the same set of
locations for the command line etc.
For instance the new c-c++-common/cpp/line-2.c test, now emits
In file included from <command-line>:
./line-2.h:4:2: error: #error wrong
4 | #error wrong
| ^~~~~
line-2.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0
3 | int bill(1);
| ^
In file included from <command-line>:
./line-2.h:3: note: macro "bill" defined here
3 | #define bill() 2
|
Before it told you about including from <command-line>:31.
the preprocessed output looks like:
...
(There's a new optimization in do_line_marker to stop each of these
line markers causing a new line map. We can simply rewind the
location, and keep using the same line map.)
libcpp/
* directives.c (do_linemarker): Optimize rewinding to line zero.
* files.c (_cpp_stack_file): Start on line zero when about to inject
headers.
(cpp_push_include, cpp_push_default_include): Use highest_line as
the location.
* include/cpplib.h (cpp_read_main_file): Add injecting parm.
* init.c (cpp_read_main_file): Likewise, inform _cpp_stack_file.
* internal.h (enum include_type): Add IT_MAIN_INJECT.
gcc/c-family/
* c-opts.c (c_common_post_options): Add 'injecting' arg to
cpp_read_main_file.
(c_finish_options): Add linemap_line_start calls for builtin and cmd
maps. Force token position to line_table's highest line.
* c-ppoutput.c (print_line_1): Refactor, print line zero.
(cb_define): Always increment source line.
gcc/testsuite/
* c-c++-common/cpp/line-2.c: New.
* c-c++-common/cpp/line-2.h: New.
* c-c++-common/cpp/line-3.c: New.
* c-c++-common/cpp/line-4.c: New.
* c-c++-common/cpp/line-4.h: New.
Diffstat (limited to 'libcpp/directives.c')
-rw-r--r-- | libcpp/directives.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/libcpp/directives.c b/libcpp/directives.c index bbfdfcd..f597187 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -940,7 +940,7 @@ strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped) /* Interpret #line command. Note that the filename string (if any) is a true string constant - (escapes are interpreted), unlike in #line. */ + (escapes are interpreted). */ static void do_line (cpp_reader *pfile) { @@ -1115,27 +1115,43 @@ do_linemarker (cpp_reader *pfile) line_table->seen_line_directive = true; } -/* Arrange the file_change callback. pfile->line has changed to - FILE_LINE of TO_FILE, for reason REASON. SYSP is 1 for a system - header, 2 for a system header that needs to be extern "C" protected, - and zero otherwise. */ +/* Arrange the file_change callback. Changing to TO_FILE:TO_LINE for + REASON. SYSP is 1 for a system header, 2 for a system header that + needs to be extern "C" protected, and zero otherwise. */ void _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, - const char *to_file, linenum_type file_line, + const char *to_file, linenum_type to_line, unsigned int sysp) { linemap_assert (reason != LC_ENTER_MACRO); - const struct line_map *map = linemap_add (pfile->line_table, reason, sysp, - to_file, file_line); + const line_map_ordinary *ord_map = NULL; - if (map != NULL) - { - ord_map = linemap_check_ordinary (map); - linemap_line_start (pfile->line_table, - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map), - 127); + if (!to_line && reason == LC_RENAME_VERBATIM) + { + /* A linemarker moving to line zero. If we're on the second + line of the current map, and it also starts at zero, just + rewind -- we're probably reading the builtins of a + preprocessed source. */ + line_map_ordinary *last = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table); + if (!ORDINARY_MAP_STARTING_LINE_NUMBER (last) + && SOURCE_LINE (last, pfile->line_table->highest_line) == 2) + { + ord_map = last; + pfile->line_table->highest_location + = pfile->line_table->highest_line = MAP_START_LOCATION (last); + } } + if (!ord_map) + if (const line_map *map = linemap_add (pfile->line_table, reason, sysp, + to_file, to_line)) + { + ord_map = linemap_check_ordinary (map); + linemap_line_start (pfile->line_table, + ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map), + 127); + } + if (pfile->cb.file_change) pfile->cb.file_change (pfile, ord_map); } |