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