Hi! I've noticed that if we preprocess source with multi-line raw-string literals (or -save-temps compile), the lines can be off if the multi-line raw-string literal contains just a few lines (under the threshold to emit #line directive); we already have a function for that for CPP_COMMENT tokens and it seems it can be used for all raw string literals too.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-07-05 Jakub Jelinek <ja...@redhat.com> * c-ppoutput.c (scan_translation_unit): Call account_for_newlines for all CPP_TOKEN_FLD_STR tokens, not just CPP_COMMENT. * include/cpplib.h (cpp_token_val_index): Change parameter type to const cpp_token *. * lex.c (cpp_token_val_index): Likewise. * c-c++-common/raw-string-18.c: New test. * c-c++-common/raw-string-19.c: New test. --- gcc/c-family/c-ppoutput.c.jj 2013-02-13 17:05:52.948743047 +0100 +++ gcc/c-family/c-ppoutput.c 2013-07-05 12:45:50.225852614 +0200 @@ -251,7 +251,7 @@ scan_translation_unit (cpp_reader *pfile cpp_output_token (token, print.outf); } - if (token->type == CPP_COMMENT) + if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR) account_for_newlines (token->val.str.text, token->val.str.len); } } --- libcpp/include/cpplib.h.jj 2013-04-28 23:35:36.000000000 +0200 +++ libcpp/include/cpplib.h 2013-07-05 12:47:06.356659944 +0200 @@ -248,7 +248,7 @@ struct GTY(()) cpp_token { }; /* Say which field is in use. */ -extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok); +extern enum cpp_token_fld_kind cpp_token_val_index (const cpp_token *tok); /* A type wide enough to hold any multibyte source character. cpplib's character constant interpreter requires an unsigned type. --- libcpp/lex.c.jj 2013-07-04 19:16:26.000000000 +0200 +++ libcpp/lex.c 2013-07-05 12:46:33.751190308 +0200 @@ -3168,7 +3168,7 @@ _cpp_aligned_alloc (cpp_reader *pfile, s /* Say which field of TOK is in use. */ enum cpp_token_fld_kind -cpp_token_val_index (cpp_token *tok) +cpp_token_val_index (const cpp_token *tok) { switch (TOKEN_SPELL (tok)) { --- gcc/testsuite/c-c++-common/raw-string-18.c.jj 2013-07-05 12:51:16.393902794 +0200 +++ gcc/testsuite/c-c++-common/raw-string-18.c 2013-07-05 12:55:15.795931265 +0200 @@ -0,0 +1,21 @@ +/* PR preprocessor/57824 */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -fdump-tree-optimized-lineno" { target c } } */ +/* { dg-options "-std=c++11 -fdump-tree-optimized-lineno" { target c++ } } */ + +const char x[] = R"( +abc +def +ghi +)"; + +int +main () +{ + extern void foo (); foo (); + return 0; +} + +/* Verify call to foo is on line 15. */ +/* { dg-final { scan-tree-dump ": 15\[]:]\[^\n\r]*foo" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ --- gcc/testsuite/c-c++-common/raw-string-19.c.jj 2013-07-05 12:55:23.596803291 +0200 +++ gcc/testsuite/c-c++-common/raw-string-19.c 2013-07-05 12:55:51.418347139 +0200 @@ -0,0 +1,22 @@ +/* PR preprocessor/57824 */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -fdump-tree-optimized-lineno -save-temps" { target c } } */ +/* { dg-options "-std=c++11 -fdump-tree-optimized-lineno -save-temps" { target c++ } } */ + +const char x[] = R"( +abc +def +ghi +)"; + +int +main () +{ + extern void foo (); foo (); + return 0; +} + +/* Verify call to foo is on line 15. */ +/* { dg-final { scan-tree-dump ": 15\[]:]\[^\n\r]*foo" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ +/* { dg-final { cleanup-saved-temps } } */ Jakub