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 /gcc | |
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 'gcc')
-rw-r--r-- | gcc/c-family/c-opts.c | 10 | ||||
-rw-r--r-- | gcc/c-family/c-ppoutput.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/line-2.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/line-2.h | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/line-3.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/line-4.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/line-4.h | 3 |
7 files changed, 64 insertions, 12 deletions
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 9b6300f..ec3de86 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -1110,7 +1110,11 @@ c_common_post_options (const char **pfilename) input_location = UNKNOWN_LOCATION; *pfilename = this_input_filename - = cpp_read_main_file (parse_in, in_fnames[0]); + = cpp_read_main_file (parse_in, in_fnames[0], + /* We'll inject preamble pieces if this is + not preprocessed. */ + !cpp_opts->preprocessed); + /* Don't do any compilation or preprocessing if there is no input file. */ if (this_input_filename == NULL) { @@ -1429,6 +1433,7 @@ c_finish_options (void) = linemap_check_ordinary (linemap_add (line_table, LC_RENAME, 0, _("<built-in>"), 0)); cb_file_change (parse_in, bltin_map); + linemap_line_start (line_table, 0, 1); /* Make sure all of the builtins about to be declared have BUILTINS_LOCATION has their location_t. */ @@ -1452,9 +1457,10 @@ c_finish_options (void) = linemap_check_ordinary (linemap_add (line_table, LC_RENAME, 0, _("<command-line>"), 0)); cb_file_change (parse_in, cmd_map); + linemap_line_start (line_table, 0, 1); /* All command line defines must have the same location. */ - cpp_force_token_locations (parse_in, cmd_map->start_location); + cpp_force_token_locations (parse_in, line_table->highest_line); for (size_t i = 0; i < deferred_count; i++) { struct deferred_opt *opt = &deferred_opts[i]; diff --git a/gcc/c-family/c-ppoutput.c b/gcc/c-family/c-ppoutput.c index 1e2b32b..44c6f30 100644 --- a/gcc/c-family/c-ppoutput.c +++ b/gcc/c-family/c-ppoutput.c @@ -560,26 +560,23 @@ print_line_1 (location_t src_loc, const char *special_flags, FILE *stream) if (src_loc != UNKNOWN_LOCATION && !flag_no_line_commands) { const char *file_path = LOCATION_FILE (src_loc); - int sysp; size_t to_file_len = strlen (file_path); unsigned char *to_file_quoted = (unsigned char *) alloca (to_file_len * 4 + 1); - unsigned char *p; print.src_line = LOCATION_LINE (src_loc); print.src_file = file_path; /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ - p = cpp_quote_string (to_file_quoted, - (const unsigned char *) file_path, - to_file_len); + unsigned char *p = cpp_quote_string (to_file_quoted, + (const unsigned char *) file_path, + to_file_len); *p = '\0'; fprintf (stream, "# %u \"%s\"%s", - print.src_line == 0 ? 1 : print.src_line, - to_file_quoted, special_flags); + print.src_line, to_file_quoted, special_flags); - sysp = in_system_header_at (src_loc); + int sysp = in_system_header_at (src_loc); if (sysp == 2) fputs (" 3 4", stream); else if (sysp == 1) @@ -677,8 +674,7 @@ cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node) linemap_resolve_location (line_table, line, LRK_MACRO_DEFINITION_LOCATION, &map); - if (LINEMAP_LINE (map) != 0) - print.src_line++; + print.src_line++; } static void diff --git a/gcc/testsuite/c-c++-common/cpp/line-2.c b/gcc/testsuite/c-c++-common/cpp/line-2.c new file mode 100644 index 0000000..97cf398 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/line-2.c @@ -0,0 +1,11 @@ +int line1; +int f = bob; +int bill(1); +int line4; + +// { dg-do preprocess } +// { dg-options "-dD -include $srcdir/c-c++-common/cpp/line-2.h -nostdinc" } + +// { dg-regexp {In file included from <command-line>:\n[^\n]*/line-2.h:4:2: error: #error wrong\n} } + +// { dg-regexp {[^\n]*/line-2.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0\nIn file included from <command-line>:\n[^\n]*/line-2.h:3: note: macro "bill" defined here\n} } diff --git a/gcc/testsuite/c-c++-common/cpp/line-2.h b/gcc/testsuite/c-c++-common/cpp/line-2.h new file mode 100644 index 0000000..737bdfa --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/line-2.h @@ -0,0 +1,5 @@ +#define bob 1 +/* Comment */ +#define bill() 2 +#error wrong + diff --git a/gcc/testsuite/c-c++-common/cpp/line-3.c b/gcc/testsuite/c-c++-common/cpp/line-3.c new file mode 100644 index 0000000..2ffc449 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/line-3.c @@ -0,0 +1,20 @@ +# 0 ".../line-1.c" +# 0 "<built-in>" +# 0 "<command-line>" +# 1 "./line-2.h" 1 +#define bob 1 + +#define bill() 2 +#error wrong +# 0 "<command-line>" 2 +# 1 ".../line-3.c" +int line1; +int f = bob; +int bill(1); +int line4; + +// { dg-regexp {In file included from <command-line>:\n[^\n]*/line-2.h:4:2: error: #error wrong\n} } + +// { dg-regexp {[^\n]*/line-3.c:3:11: error: macro "bill" passed 1 arguments, but takes just 0\nIn file included from <command-line>:\n[^\n]*/line-2.h:3: note: macro "bill" defined here\n} } + +// { dg-options "-fpreprocessed -fdirectives-only" } diff --git a/gcc/testsuite/c-c++-common/cpp/line-4.c b/gcc/testsuite/c-c++-common/cpp/line-4.c new file mode 100644 index 0000000..810f159 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/line-4.c @@ -0,0 +1,11 @@ +int line1; +int f = bob; +int b = bill(); +int line4; + +// { dg-do preprocess } +// { dg-options "-dD -include $srcdir/c-c++-common/cpp/line-4.h -nostdinc" } + +// { dg-final { scan-file line-4.i {# 0 "[^\n]*/line-4.c"\n# 0 "<built-in>"\n} } } +// { dg-final { scan-file line-4.i {# 0 "<command-line>"\n# 1 "[^\n]*/line-4.h" 1\n#define bob 1\n} } } +// { dg-final { scan-file line-4.i {#define bill\(\) 2\n# 0 "<command-line>" 2\n# 1 "[^\n]*/line-4.c"\nint line1;\n} } } diff --git a/gcc/testsuite/c-c++-common/cpp/line-4.h b/gcc/testsuite/c-c++-common/cpp/line-4.h new file mode 100644 index 0000000..6ee05a3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/line-4.h @@ -0,0 +1,3 @@ +#define bob 1 +/* Comment */ +#define bill() 2 |