[clang] d813af7 - [Format] Fix detection of languages when reading from stdin (#79051)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 23 12:32:45 PST 2024


Author: Ben Hamilton (Ben Gertzfield)
Date: 2024-01-23T13:32:41-07:00
New Revision: d813af73f70f6b2fd41621d640cc35e595b9da4c

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

LOG: [Format] Fix detection of languages when reading from stdin (#79051)

The code cleanup in #74794 accidentally broke detection of languages by
reading file content from stdin, e.g. via `clang-format -dump-config - <
/path/to/filename`.

This PR adds unit and integration tests to reproduce the issue and adds
a fix.

Fixes: #79023

Added: 
    clang/test/Format/dump-config-objc-stdin.m

Modified: 
    clang/tools/clang-format/ClangFormat.cpp
    clang/unittests/Format/FormatTestObjC.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Format/dump-config-objc-stdin.m b/clang/test/Format/dump-config-objc-stdin.m
new file mode 100644
index 00000000000000..b22ff7b3328caa
--- /dev/null
+++ b/clang/test/Format/dump-config-objc-stdin.m
@@ -0,0 +1,5 @@
+// RUN: clang-format -dump-config - < %s | FileCheck %s
+
+// CHECK: Language: ObjC
+ at interface Foo
+ at end

diff  --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp
index 49ab7677a3ee9c..5ee6092bb9bb7f 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -547,18 +547,20 @@ static void PrintVersion(raw_ostream &OS) {
 // Dump the configuration.
 static int dumpConfig(bool IsSTDIN) {
   std::unique_ptr<llvm::MemoryBuffer> Code;
-  // We can't read the code to detect the language if there's no file name.
-  if (!IsSTDIN) {
-    // Read in the code in case the filename alone isn't enough to detect the
-    // language.
-    ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
-        MemoryBuffer::getFileOrSTDIN(FileNames[0]);
-    if (std::error_code EC = CodeOrErr.getError()) {
-      llvm::errs() << EC.message() << "\n";
-      return 1;
-    }
-    Code = std::move(CodeOrErr.get());
+
+  // `FileNames` must have at least "-" in it even if no file was specified.
+  assert(!FileNames.empty());
+
+  // Read in the code in case the filename alone isn't enough to detect the
+  // language.
+  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
+      MemoryBuffer::getFileOrSTDIN(FileNames[0]);
+  if (std::error_code EC = CodeOrErr.getError()) {
+    llvm::errs() << EC.message() << "\n";
+    return 1;
   }
+  Code = std::move(CodeOrErr.get());
+
   llvm::Expected<clang::format::FormatStyle> FormatStyle =
       clang::format::getStyle(Style, IsSTDIN ? AssumeFileName : FileNames[0],
                               FallbackStyle, Code ? Code->getBuffer() : "");

diff  --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp
index cd4f9d934127bf..d2c3459e0f846d 100644
--- a/clang/unittests/Format/FormatTestObjC.cpp
+++ b/clang/unittests/Format/FormatTestObjC.cpp
@@ -31,6 +31,14 @@ class FormatTestObjC : public FormatTestBase {
   _verifyIncompleteFormat(__FILE__, __LINE__, __VA_ARGS__)
 #define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
 
+TEST(FormatTestObjCStyle, DetectsObjCInStdin) {
+  auto Style = getStyle("LLVM", "<stdin>", "none",
+                        "@interface\n"
+                        "- (id)init;");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+}
+
 TEST(FormatTestObjCStyle, DetectsObjCInHeaders) {
   auto Style = getStyle("LLVM", "a.h", "none",
                         "@interface\n"


        


More information about the cfe-commits mailing list