Skip to content

Commit 9c8b31d

Browse files
committed
Treat escaped newlines as whitespace in Lexer::getRawToken.
The Lexer used in getRawToken is not told to keep whitespace, so when it skips over escaped newlines, it also ignores whitespace, regardless of getRawToken's IgnoreWhiteSpace parameter. My suspicion is that users that want to not IgnoreWhiteSpace and therefore return true for a whitespace character would also safely accept true for an escaped newline. For users that do use IgnoreWhiteSpace, there is no behavior change, and the handling of escaped newlines is already correct. If an escaped newline should not be considered whitespace, then instead of this change, getRawToken should be modified to return true when whitespace follows the escaped newline present at `Loc`, perhaps by using isWhitespace(SkipEscapedNewLines(StrData)[0]). However, this is incompatible with functions like clang::tidy::utils::lexer::getPreviousTokenAndStart. getPreviousTokenAndStart loops backwards through source location offsets, always decrementing by 1 without regard for potential character sizes larger than 1, such as escaped newlines. It seems more likely to me that there are more functions like this that would break than there are users who rely on escaped newlines not being treated as whitespace by getRawToken, but I'm open to that not being true. The modified test was printing `\\nF` for the name of the expanded macro and now does not find a macro name. In my opinion, this is not an indication that the new behavior for getRawToken is incorrect. Rather, this is, both before and after this change, due to an incorrect storage of the backslash's source location as the spelling location of the expansion location of `F`.
1 parent 33fcd6a commit 9c8b31d

File tree

2 files changed

+4
-3
lines changed

2 files changed

+4
-3
lines changed

clang/lib/Lex/Lexer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,9 @@ bool Lexer::getRawToken(SourceLocation Loc, Token &Result,
527527

528528
const char *StrData = Buffer.data()+LocInfo.second;
529529

530-
if (!IgnoreWhiteSpace && isWhitespace(StrData[0]))
530+
if (!IgnoreWhiteSpace && (isWhitespace(StrData[0]) ||
531+
// Treat escaped newlines as whitespace.
532+
SkipEscapedNewLines(StrData) != StrData))
531533
return true;
532534

533535
// Create a lexer starting at the beginning of this token.

clang/test/Frontend/highlight-text.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ int a = M;
1212
// CHECK-NEXT: :5:11: note: expanded from macro 'M'
1313
// CHECK-NEXT: 5 | #define M \
1414
// CHECK-NEXT: | ^
15-
// CHECK-NEXT: :3:14: note: expanded from macro '\
16-
// CHECK-NEXT: F'
15+
// CHECK-NEXT: :3:14: note: expanded from here
1716
// CHECK-NEXT: 3 | #define F (1 << 99)
1817
// CHECK-NEXT: | ^ ~~
1918
// CHECK-NEXT: :8:9: warning: shift count >= width of type [-Wshift-count-overflow]

0 commit comments

Comments
 (0)