[clang-format] Make ignored files unformatted instead of empty. (#170416)
Tools rely on the expectation that clang-format will output a formatted
file. In the case of ignored files, the formatted file should just be
the input file, untouched.
Fixes #170407
diff --git a/clang/test/Format/clang-format-ignore.cpp b/clang/test/Format/clang-format-ignore.cpp
index 6689137..11e7b0e 100644
--- a/clang/test/Format/clang-format-ignore.cpp
+++ b/clang/test/Format/clang-format-ignore.cpp
@@ -46,26 +46,24 @@
// CHECK5-NEXT: {{Formatting \[4/5] .*foo\.c}}
// CHECK5-NOT: foo.js
+// Check that ignored files are unformatted, but still output.
// RUN: echo "foo.*" > .clang-format-ignore
// RUN: echo "int i ;" > foo.c
-// RUN: clang-format -assume-filename=foo.c < foo.c \
-// RUN: | FileCheck %s -check-prefix=CHECK6 -allow-empty
-// CHECK6-NOT: int
-
+// RUN: clang-format -assume-filename=foo.c < foo.c | diff foo.c -
// RUN: clang-format -assume-filename=bar.c < foo.c \
-// RUN: | FileCheck %s -check-prefix=CHECK7 -match-full-lines
-// CHECK7: int i;
+// RUN: | FileCheck %s -check-prefix=CHECK6 -match-full-lines
+// CHECK6: int i;
// RUN: echo "foo.h" > .clang-format-ignore
// RUN: echo "!foo.c" >> .clang-format-ignore
// RUN: echo "int i ;" > foo.c
// RUN: echo "int i ;" > foo.h
// RUN: clang-format -verbose foo.c 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK8 -match-full-lines
-// CHECK8: Formatting [1/1] foo.c
+// RUN: | FileCheck %s -check-prefix=CHECK7 -match-full-lines
+// CHECK7: Formatting [1/1] foo.c
// RUN: clang-format -verbose foo.h 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK9 -allow-empty
-// CHECK9-NOT: int
+// RUN: | FileCheck %s -check-prefix=CHECK8 -allow-empty
+// CHECK8-NOT: int
// RUN: mkdir -p %t.dir/ignore.dir/format.dir
// RUN: echo "ignore.dir/*" > .clang-format-ignore
@@ -73,26 +71,26 @@
// RUN: echo "int i ;" > ignore.dir/foo.c
// RUN: echo "int i ;" > ignore.dir/format.dir/bar.c
// RUN: clang-format -verbose ignore.dir/**/*.c 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK10 -match-full-lines
-// CHECK10: {{Formatting \[1/1] .*ignore\.dir[/\\]format\.dir[/\\]bar\.c}}
+// RUN: | FileCheck %s -check-prefix=CHECK9 -match-full-lines
+// CHECK9: {{Formatting \[1/1] .*ignore\.dir[/\\]format\.dir[/\\]bar\.c}}
// RUN: echo "foo.*" > .clang-format-ignore
// RUN: clang-format -verbose foo.c 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK11 -allow-empty
-// CHECK11-NOT: int
+// RUN: | FileCheck %s -check-prefix=CHECK10 -allow-empty
+// CHECK10-NOT: int
// RUN: echo "!foo.c" >> .clang-format-ignore
// RUN: clang-format -verbose foo.c 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK12 -match-full-lines
-// CHECK12: Formatting [1/1] foo.c
+// RUN: | FileCheck %s -check-prefix=CHECK11 -match-full-lines
+// CHECK11: Formatting [1/1] foo.c
// RUN: echo "!foo.*" > .clang-format-ignore
// RUN: clang-format -verbose foo.c 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK13 -match-full-lines
-// CHECK13: Formatting [1/1] foo.c
+// RUN: | FileCheck %s -check-prefix=CHECK12 -match-full-lines
+// CHECK12: Formatting [1/1] foo.c
// RUN: echo "foo.c" >> .clang-format-ignore
// RUN: clang-format -verbose foo.c 2>&1 \
-// RUN: | FileCheck %s -check-prefix=CHECK14 -allow-empty
-// CHECK14-NOT: int
+// RUN: | FileCheck %s -check-prefix=CHECK13 -allow-empty
+// CHECK13-NOT: int
// RUN: cd ..
// RUN: rm -r %t.dir
diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp
index 1a38ef1..de513d9 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -701,8 +701,15 @@
}
if (FileNames.empty()) {
- if (isIgnored(AssumeFileName))
+ if (isIgnored(AssumeFileName)) {
+ // The user should be able to expect that running
+ // `cat foo | clang-format --assume-filename foo` and writing the output
+ // to foo will format foo.
+ // Thus, we need to just output stdin untouched if it is ignored.
+ if (!OutputXML)
+ outs() << MemoryBuffer::getSTDIN()->get()->getBuffer();
return 0;
+ }
return clang::format::format("-", FailOnIncompleteFormat);
}