[clang] [clang-format] Handle .h files for LK_C and LK_ObjC (PR #141714)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Tue May 27 20:53:03 PDT 2025
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 <owenpiano at 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;
More information about the cfe-commits
mailing list