bmoody created this revision. bmoody added a reviewer: rsmith. Herald added a subscriber: cfe-commits.
Previously the location of a token immediately following an escaped newline was the location of the backslash character in the escaped newline. The change to test/SemaTemplate/instantiation-depth.cpp is to work around a side-effect of this fix - the expected-error comment was getting the location of the backslash on the previous line before. I added the extra slashes so that the comment starts on the correct line. Repository: rC Clang https://reviews.llvm.org/D52855 Files: lib/Lex/Lexer.cpp test/Misc/escaped-newline-loc.c test/SemaTemplate/instantiation-depth.cpp Index: test/SemaTemplate/instantiation-depth.cpp =================================================================== --- test/SemaTemplate/instantiation-depth.cpp +++ test/SemaTemplate/instantiation-depth.cpp @@ -4,7 +4,7 @@ #ifndef NOEXCEPT -template<typename T> struct X : X<T*> { }; \ +template<typename T> struct X : X<T*> { }; // \ // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ // expected-note 3 {{instantiation of template class}} \ // expected-note {{skipping 2 contexts in backtrace}} \ @@ -19,7 +19,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s template<typename T> struct S { - S() noexcept(noexcept(S<S>())); \ + S() noexcept(noexcept(S<S>())); // \ // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ // expected-note 3 {{in instantiation of exception spec}} \ // expected-note {{skipping 2 contexts in backtrace}} \ Index: test/Misc/escaped-newline-loc.c =================================================================== --- /dev/null +++ test/Misc/escaped-newline-loc.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wno-backslash-newline-escape + +// Test that the location of a token that immediately follows an escaped +// newline is correct, and doesn't point to the backslash + +void f() { + \ +error1; // expected-error {{use of undeclared identifier 'error1'}} + + // Escaped newline with space + \ +error2; // expected-error {{use of undeclared identifier 'error2'}} + + // Escaped newline with two spaces + \ +error3; // expected-error {{use of undeclared identifier 'error3'}} +} Index: lib/Lex/Lexer.cpp =================================================================== --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -3193,6 +3193,17 @@ // Read a character, advancing over it. char Char = getAndAdvanceChar(CurPtr, Result); + + // If we had to skip over an escaped newline to get this character then + // update BufferPtr to point to the character we got, instead of pointing + // at the backslash. This fixes the source location for tokens that + // immediately follow an escaped newline. + if (!isKeepWhitespaceMode() && + Result.needsCleaning() && CurPtr[-1] == Char) { + Result.clearFlag(Token::NeedsCleaning); + BufferPtr = CurPtr - 1; + } + tok::TokenKind Kind; switch (Char) {
Index: test/SemaTemplate/instantiation-depth.cpp =================================================================== --- test/SemaTemplate/instantiation-depth.cpp +++ test/SemaTemplate/instantiation-depth.cpp @@ -4,7 +4,7 @@ #ifndef NOEXCEPT -template<typename T> struct X : X<T*> { }; \ +template<typename T> struct X : X<T*> { }; // \ // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ // expected-note 3 {{instantiation of template class}} \ // expected-note {{skipping 2 contexts in backtrace}} \ @@ -19,7 +19,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s template<typename T> struct S { - S() noexcept(noexcept(S<S>())); \ + S() noexcept(noexcept(S<S>())); // \ // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ // expected-note 3 {{in instantiation of exception spec}} \ // expected-note {{skipping 2 contexts in backtrace}} \ Index: test/Misc/escaped-newline-loc.c =================================================================== --- /dev/null +++ test/Misc/escaped-newline-loc.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wno-backslash-newline-escape + +// Test that the location of a token that immediately follows an escaped +// newline is correct, and doesn't point to the backslash + +void f() { + \ +error1; // expected-error {{use of undeclared identifier 'error1'}} + + // Escaped newline with space + \ +error2; // expected-error {{use of undeclared identifier 'error2'}} + + // Escaped newline with two spaces + \ +error3; // expected-error {{use of undeclared identifier 'error3'}} +} Index: lib/Lex/Lexer.cpp =================================================================== --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -3193,6 +3193,17 @@ // Read a character, advancing over it. char Char = getAndAdvanceChar(CurPtr, Result); + + // If we had to skip over an escaped newline to get this character then + // update BufferPtr to point to the character we got, instead of pointing + // at the backslash. This fixes the source location for tokens that + // immediately follow an escaped newline. + if (!isKeepWhitespaceMode() && + Result.needsCleaning() && CurPtr[-1] == Char) { + Result.clearFlag(Token::NeedsCleaning); + BufferPtr = CurPtr - 1; + } + tok::TokenKind Kind; switch (Char) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits