https://github.com/owenca created 
https://github.com/llvm/llvm-project/pull/141714

Fix #137792

>From 0afd41acb56fced29a7f8865b19cf2da95aaa26d Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpi...@gmail.com>
Date: Tue, 27 May 2025 20:50:56 -0700
Subject: [PATCH] [clang-format] Handle .h files for LK_C and LK_ObjC

Fix #137792
---
 clang/include/clang/Format/Format.h        | 10 ++++++----
 clang/lib/Format/Format.cpp                | 18 +++++++++++++-----
 clang/unittests/Format/ConfigParseTest.cpp | 16 ++++++++++++++++
 3 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 3ac4318824ac0..127b1d08919de 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -5536,7 +5536,7 @@ struct FormatStyle {
   parseConfiguration(llvm::MemoryBufferRef Config, FormatStyle *Style,
                      bool AllowUnknownOptions,
                      llvm::SourceMgr::DiagHandlerTy DiagHandler,
-                     void *DiagHandlerCtxt);
+                     void *DiagHandlerCtxt, bool IsDotHFile);
 };
 
 /// Returns a format style complying with the LLVM coding standards:
@@ -5602,13 +5602,15 @@ std::error_code
 parseConfiguration(llvm::MemoryBufferRef Config, FormatStyle *Style,
                    bool AllowUnknownOptions = false,
                    llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr,
-                   void *DiagHandlerCtx = nullptr);
+                   void *DiagHandlerCtx = nullptr, bool IsDotHFile = false);
 
 /// Like above but accepts an unnamed buffer.
 inline std::error_code parseConfiguration(StringRef Config, FormatStyle *Style,
-                                          bool AllowUnknownOptions = false) {
+                                          bool AllowUnknownOptions = false,
+                                          bool IsDotHFile = false) {
   return parseConfiguration(llvm::MemoryBufferRef(Config, "YAML"), Style,
-                            AllowUnknownOptions);
+                            AllowUnknownOptions, /*DiagHandler=*/nullptr,
+                            /*DiagHandlerCtx=*/nullptr, IsDotHFile);
 }
 
 /// Gets configuration in a YAML string.
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 0cfa061681053..bdaf264e9adce 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -2108,7 +2108,7 @@ ParseError validateQualifierOrder(FormatStyle *Style) {
 std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
                                    FormatStyle *Style, bool 
AllowUnknownOptions,
                                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
-                                   void *DiagHandlerCtxt) {
+                                   void *DiagHandlerCtxt, bool IsDotHFile) {
   assert(Style);
   FormatStyle::LanguageKind Language = Style->Language;
   assert(Language != FormatStyle::LK_None);
@@ -2155,6 +2155,10 @@ std::error_code parseConfiguration(llvm::MemoryBufferRef 
Config,
         // For backward compatibility.
         (Lang == FormatStyle::LK_Cpp && Language == FormatStyle::LK_C)) {
       LanguageFound = true;
+    } else if (IsDotHFile && Language == FormatStyle::LK_Cpp &&
+               (Lang == FormatStyle::LK_C || Lang == FormatStyle::LK_ObjC)) {
+      Language = Lang;
+      LanguageFound = true;
     }
   }
   if (!LanguageFound) {
@@ -4177,13 +4181,15 @@ const char *DefaultFallbackStyle = "LLVM";
 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
 loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
                        FormatStyle *Style, bool AllowUnknownOptions,
-                       llvm::SourceMgr::DiagHandlerTy DiagHandler) {
+                       llvm::SourceMgr::DiagHandlerTy DiagHandler,
+                       bool IsDotHFile) {
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
       FS->getBufferForFile(ConfigFile.str());
   if (auto EC = Text.getError())
     return EC;
   if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions,
-                                   DiagHandler)) {
+                                   DiagHandler, /*DiagHandlerCtx=*/nullptr,
+                                   IsDotHFile)) {
     return EC;
   }
   return Text;
@@ -4221,13 +4227,15 @@ Expected<FormatStyle> getStyle(StringRef StyleName, 
StringRef FileName,
     FS = llvm::vfs::getRealFileSystem().get();
   assert(FS);
 
+  const bool IsDotHFile = FileName.ends_with(".h");
+
   // User provided clang-format file using -style=file:path/to/format/file.
   if (!Style.InheritsParentConfig &&
       StyleName.starts_with_insensitive("file:")) {
     auto ConfigFile = StyleName.substr(5);
     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
         loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
-                               DiagHandler);
+                               DiagHandler, IsDotHFile);
     if (auto EC = Text.getError()) {
       return make_string_error("Error reading " + ConfigFile + ": " +
                                EC.message());
@@ -4303,7 +4311,7 @@ Expected<FormatStyle> getStyle(StringRef StyleName, 
StringRef FileName,
 
       llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
           loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions,
-                                 DiagHandler);
+                                 DiagHandler, IsDotHFile);
       if (auto EC = Text.getError()) {
         if (EC != ParseError::Unsuitable) {
           return make_string_error("Error reading " + ConfigFile + ": " +
diff --git a/clang/unittests/Format/ConfigParseTest.cpp 
b/clang/unittests/Format/ConfigParseTest.cpp
index 5b9055d0a80be..ecf7401626690 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -1267,6 +1267,22 @@ TEST(ConfigParseTest, AllowCppForC) {
             ParseError::Success);
 }
 
+TEST(ConfigParseTest, HandleNonCppDotHFile) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  EXPECT_EQ(parseConfiguration("Language: C", &Style,
+                               /*AllowUnknownOptions=*/false,
+                               /*IsDotHFile=*/true),
+            ParseError::Success);
+
+  Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  EXPECT_EQ(parseConfiguration("Language: ObjC", &Style,
+                               /*AllowUnknownOptions=*/false,
+                               /*IsDotHFile=*/true),
+            ParseError::Success);
+}
+
 TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
   FormatStyle Style = {};
   Style.Language = FormatStyle::LK_JavaScript;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to