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

Reply via email to