[clang] c6b0b16 - [Preprocessor] -E -P: Ensure newline after 8 skipped lines.

Michael Kruse via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 28 20:51:49 PDT 2021


Author: Michael Kruse
Date: 2021-07-28T22:50:54-05:00
New Revision: c6b0b16c0f55c34f4eaa05184815bbbe97f4b750

URL: https://github.com/llvm/llvm-project/commit/c6b0b16c0f55c34f4eaa05184815bbbe97f4b750
DIFF: https://github.com/llvm/llvm-project/commit/c6b0b16c0f55c34f4eaa05184815bbbe97f4b750.diff

LOG: [Preprocessor] -E -P: Ensure newline after 8 skipped lines.

The implementation of -fminimize-whitespace (D104601) revised the logic
when to emit newlines. There was no case to handle when more than
8 lines were skippped in -P (DisableLineMarkers) mode and instead fell
through the case intended for -fminimize-whitespace, i.e. emit nothing.
This patch will emit one newline in this case.

The newline logic is slightly reorganized. The `-P -fminimize-whitespace`
case is handled explicitly and emitting at least one newline is the new
fallback case. The choice between emitting a line marker or up to
7 empty lines is now a choice only with enabled line markers. The up to
8 newlines likely are fewer characters than a line directive, but
in -P mode this had the paradoxic effect that it would print up to
7 empty lines, but none at all if more than 8 lines had to be skipped.
Now with DisableLineMarkers, we don't consider printing empty lines
(just start a new line) which matches gcc's behavior.

The line-directive-output-mincol.c test is replaced with a more
comprehensive test skip-empty-lines.c also testing the more than
8 skipped lines behaviour with all flag combinations.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D106924

Added: 
    clang/test/Preprocessor/skip-empty-lines.c

Modified: 
    clang/lib/Frontend/PrintPreprocessedOutput.cpp
    clang/test/Preprocessor/minimize-whitespace.c

Removed: 
    clang/test/Preprocessor/line-directive-output-mincol.c


################################################################################
diff  --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
index b7259569595d6..1759485de24db 100644
--- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -276,20 +276,27 @@ bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo,
   // otherwise print a #line directive.
   if (CurLine == LineNo) {
     // Nothing to do if we are already on the correct line.
-  } else if (!StartedNewLine && (!MinimizeWhitespace || !DisableLineMarkers) &&
-             LineNo - CurLine == 1) {
+  } else if (MinimizeWhitespace && DisableLineMarkers) {
+    // With -E -P -fminimize-whitespace, don't emit anything if not necessary.
+  } else if (!StartedNewLine && LineNo - CurLine == 1) {
     // Printing a single line has priority over printing a #line directive, even
     // when minimizing whitespace which otherwise would print #line directives
     // for every single line.
     OS << '\n';
     StartedNewLine = true;
-  } else if (!MinimizeWhitespace && LineNo - CurLine <= 8) {
-    const char *NewLines = "\n\n\n\n\n\n\n\n";
-    OS.write(NewLines, LineNo - CurLine);
-    StartedNewLine = true;
   } else if (!DisableLineMarkers) {
-    // Emit a #line or line marker.
-    WriteLineInfo(LineNo, nullptr, 0);
+    if (LineNo - CurLine <= 8) {
+      const char *NewLines = "\n\n\n\n\n\n\n\n";
+      OS.write(NewLines, LineNo - CurLine);
+    } else {
+      // Emit a #line or line marker.
+      WriteLineInfo(LineNo, nullptr, 0);
+    }
+    StartedNewLine = true;
+  } else if (!StartedNewLine) {
+    // If we are not on the correct line and don't need to be line-correct,
+    // at least ensure we start on a new line.
+    OS << '\n';
     StartedNewLine = true;
   }
 

diff  --git a/clang/test/Preprocessor/line-directive-output-mincol.c b/clang/test/Preprocessor/line-directive-output-mincol.c
deleted file mode 100644
index 0f2466ebee971..0000000000000
--- a/clang/test/Preprocessor/line-directive-output-mincol.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: %clang_cc1 -E -fminimize-whitespace %s 2>&1 | FileCheck %s -strict-whitespace
-
-// CHECK:      # 6 "{{.*}}line-directive-output-mincol.c"
-// CHECK-NEXT: int x;
-// CHECK-NEXT: int y;
-int x;
-int y;
-// CHECK-NEXT: # 10 "{{.*}}line-directive-output-mincol.c"
-// CHECK-NEXT: int z;
-int z;
-

diff  --git a/clang/test/Preprocessor/minimize-whitespace.c b/clang/test/Preprocessor/minimize-whitespace.c
index 3608e318dc135..137efe8393795 100644
--- a/clang/test/Preprocessor/minimize-whitespace.c
+++ b/clang/test/Preprocessor/minimize-whitespace.c
@@ -2,6 +2,12 @@
 // RUN: %clang_cc1 -fminimize-whitespace -E -C %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=MINCCOL
 // RUN: %clang_cc1 -fminimize-whitespace -E -P %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=MINWS
 // RUN: %clang_cc1 -fminimize-whitespace -E -C -P %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=MINCWS
+// The follow empty lines ensure that a #line directive is emitted instead of newline padding after the RUN comments.
+
+
+
+
+
 
 #define NOT_OMP  omp  something
 #define HASH #
@@ -16,11 +22,11 @@ HASH  pragma  NOT_OMP
 f  ;
 
 
-// MINCOL:      {{^}}# 9 "{{.*}}minimize-whitespace.c"{{$}}
+// MINCOL:      {{^}}# 15 "{{.*}}minimize-whitespace.c"{{$}}
 // MINCOL:      {{^}}int a;{{$}}
 // MINCOL-NEXT: {{^}}int b;{{$}}
 // MINCOL-NEXT: {{^}}#pragma omp barrier{{$}}
-// MINCOL-NEXT: # 11 "{{.*}}minimize-whitespace.c"
+// MINCOL-NEXT: # 17 "{{.*}}minimize-whitespace.c"
 // MINCOL-NEXT: {{^}}x{{$}}
 // MINCOL-NEXT: {{^}}#pragma omp nothing{{$}}
 // MINCOL-NEXT: {{^ }}#pragma omp something{{$}}
@@ -28,11 +34,11 @@ f  ;
 // MINCOL-NEXT: {{^}}int f;{{$}}
 
 // FIXME: Comments after pragmas disappear, even without -fminimize-whitespace
-// MINCCOL:      {{^}}# 9 "{{.*}}minimize-whitespace.c"{{$}}
+// MINCCOL:      {{^}}# 15 "{{.*}}minimize-whitespace.c"{{$}}
 // MINCCOL:      {{^}}int a;/*  span-comment  */{{$}}
 // MINCCOL-NEXT: {{^}}int b;//  line-comment{{$}}
 // MINCCOL-NEXT: {{^}}#pragma omp barrier{{$}}
-// MINCCOL-NEXT: # 11 "{{.*}}minimize-whitespace.c"
+// MINCCOL-NEXT: # 17 "{{.*}}minimize-whitespace.c"
 // MINCCOL-NEXT: {{^}}x//  more line-comments{{$}}
 // MINCCOL-NEXT: {{^}}#pragma omp nothing{{$}}
 // MINCCOL-NEXT: {{^ }}#pragma omp something{{$}}

diff  --git a/clang/test/Preprocessor/skip-empty-lines.c b/clang/test/Preprocessor/skip-empty-lines.c
new file mode 100644
index 0000000000000..6d248d748e293
--- /dev/null
+++ b/clang/test/Preprocessor/skip-empty-lines.c
@@ -0,0 +1,45 @@
+  int  a ;
+  int  b ;
+// A single empty line
+  int  c ;
+/*
+
+more than 8 empty lines
+(forces a line marker instead of newline padding)
+
+
+
+
+*/
+  int  d ;
+
+// RUN: %clang_cc1 -E %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=LINEMARKERS
+// RUN: %clang_cc1 -E -P %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=COLSONLY
+// RUN: %clang_cc1 -E -fminimize-whitespace %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=MINCOL
+// RUN: %clang_cc1 -E -P -fminimize-whitespace %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=MINWS
+
+// Check behavior after varying number of lines without emitted tokens.
+
+// LINEMARKERS:       {{^}}# 1 "{{.*}}skip-empty-lines.c" 2
+// LINEMARKERS-NEXT: {{^}}  int a ;
+// LINEMARKERS-NEXT: {{^}}  int b ;
+// LINEMARKERS-EMPTY:
+// LINEMARKERS-NEXT: {{^}}  int c ;
+// LINEMARKERS-NEXT: {{^}}# 14 "{{.*}}skip-empty-lines.c"
+// LINEMARKERS-NEXT: {{^}}  int d ;
+
+// COLSONLY:      {{^}}  int a ;
+// COLSONLY-NEXT: {{^}}  int b ;
+// COLSONLY-NEXT: {{^}}  int c ;
+// COLSONLY-NEXT: {{^}}  int d ;
+
+// MINCOL:      {{^}}# 1 "{{.*}}skip-empty-lines.c" 2
+// MINCOL-NEXT: {{^}}int a;
+// MINCOL-NEXT: {{^}}int b;
+// MINCOL-EMPTY:
+// MINCOL-NEXT: {{^}}int c;
+// MINCOL-NEXT: {{^}}# 14 "{{.*}}skip-empty-lines.c"
+// MINCOL-NEXT: {{^}}int d;
+
+// MINWS: {{^}}int a;int b;int c;int d;
+


        


More information about the cfe-commits mailing list