[clang] [clang-format] Add ConfigFile option (PR #113864)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 31 21:33:12 PDT 2024
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/113864
>From 85f78a4879a37fb367dccd5299b35d1c75c2b46f Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Sun, 27 Oct 2024 22:22:11 -0700
Subject: [PATCH 1/2] [clang-format] Add ConfigFile option
Closes #107808.
---
clang/docs/ClangFormatStyleOptions.rst | 5 ++++
clang/include/clang/Format/Format.h | 5 ++++
clang/lib/Format/Format.cpp | 38 ++++++++++++++++++++++++--
3 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 9ef1fd5f36d1d3..9033bdc9018ae7 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3727,6 +3727,11 @@ the configuration (without a prefix: ``Auto``).
namespace Extra {
}}}
+.. _ConfigFile:
+
+**ConfigFile** (``String``) :versionbadge:`clang-format 20` :ref:`¶ <ConfigFile>`
+ Specify the absolute or relative path of another config file to process.
+
.. _ConstructorInitializerAllOnOneLineOrOnePerLine:
**ConstructorInitializerAllOnOneLineOrOnePerLine** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ <ConstructorInitializerAllOnOneLineOrOnePerLine>`
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index c9b72e65cb236d..44ea7d25ee0e77 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2481,6 +2481,10 @@ struct FormatStyle {
/// \version 5
bool CompactNamespaces;
+ /// Specify the absolute or relative path of another config file to process.
+ /// \version 20
+ std::string ConfigFile;
+
/// This option is **deprecated**. See ``CurrentLine`` of
/// ``PackConstructorInitializers``.
/// \version 3.7
@@ -5195,6 +5199,7 @@ struct FormatStyle {
BreakTemplateDeclarations == R.BreakTemplateDeclarations &&
ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas &&
CompactNamespaces == R.CompactNamespaces &&
+ ConfigFile == R.ConfigFile &&
ConstructorInitializerIndentWidth ==
R.ConstructorInitializerIndentWidth &&
ContinuationIndentWidth == R.ContinuationIndentWidth &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 0cf4cdbeab31f3..e835cf7c8b3b45 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1163,6 +1163,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("TemplateNames", Style.TemplateNames);
IO.mapOptional("TypeNames", Style.TypeNames);
IO.mapOptional("TypenameMacros", Style.TypenameMacros);
+ IO.mapOptional("ConfigFile", Style.ConfigFile);
IO.mapOptional("UseTab", Style.UseTab);
IO.mapOptional("VerilogBreakBetweenInstancePorts",
Style.VerilogBreakBetweenInstancePorts);
@@ -2046,6 +2047,11 @@ ParseError validateQualifierOrder(FormatStyle *Style) {
return ParseError::Success;
}
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
+ FormatStyle *Style, bool AllowUnknownOptions,
+ llvm::SourceMgr::DiagHandlerTy DiagHandler);
+
std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
FormatStyle *Style, bool AllowUnknownOptions,
llvm::SourceMgr::DiagHandlerTy DiagHandler,
@@ -2107,8 +2113,36 @@ std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
// See comment on FormatStyle::TSC_Wrapped.
return make_error_code(ParseError::BinPackTrailingCommaConflict);
}
- if (Style->QualifierAlignment != FormatStyle::QAS_Leave)
- return make_error_code(validateQualifierOrder(Style));
+ if (Style->QualifierAlignment != FormatStyle::QAS_Leave) {
+ const auto EC = validateQualifierOrder(Style);
+ if (EC != ParseError::Success)
+ return make_error_code(EC);
+ }
+ if (!Style->InheritsParentConfig && !Style->ConfigFile.empty()) {
+ auto *FS = llvm::vfs::getRealFileSystem().get();
+ assert(FS);
+ SmallString<128> ConfigFile{Style->ConfigFile};
+ Style->ConfigFile.clear();
+ switch (ConfigFile[0]) {
+ case '~':
+ llvm::sys::fs::expand_tilde(ConfigFile, ConfigFile);
+ break;
+ case '/':
+ break;
+ default:
+ llvm::sys::fs::make_absolute(
+ llvm::sys::path::parent_path(Config.getBufferIdentifier()),
+ ConfigFile);
+ }
+ if (!llvm::sys::fs::exists(ConfigFile)) {
+ llvm::errs() << ConfigFile << ": " << "file not found\n";
+ return make_error_code(ParseError::Error);
+ }
+ const auto Text = loadAndParseConfigFile(ConfigFile, FS, Style,
+ AllowUnknownOptions, DiagHandler);
+ if (Text.getError())
+ return make_error_code(ParseError::Error);
+ }
return make_error_code(ParseError::Success);
}
>From 73587ff7f377e021b030a2efad4d8a810ec05ad1 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Thu, 31 Oct 2024 21:30:14 -0700
Subject: [PATCH 2/2] Handle command-line option `-style='{ConfigFile:
pathname}'`
---
clang/lib/Format/Format.cpp | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index e835cf7c8b3b45..b502e8022de42e 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -2052,6 +2052,8 @@ loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
FormatStyle *Style, bool AllowUnknownOptions,
llvm::SourceMgr::DiagHandlerTy DiagHandler);
+static constexpr StringRef Source{"<command-line>"};
+
std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
FormatStyle *Style, bool AllowUnknownOptions,
llvm::SourceMgr::DiagHandlerTy DiagHandler,
@@ -2129,10 +2131,15 @@ std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
break;
case '/':
break;
- default:
- llvm::sys::fs::make_absolute(
- llvm::sys::path::parent_path(Config.getBufferIdentifier()),
- ConfigFile);
+ default: {
+ const auto BufferId = Config.getBufferIdentifier();
+ if (BufferId == Source) {
+ llvm::sys::fs::make_absolute(ConfigFile);
+ } else {
+ llvm::sys::fs::make_absolute(llvm::sys::path::parent_path(BufferId),
+ ConfigFile);
+ }
+ }
}
if (!llvm::sys::fs::exists(ConfigFile)) {
llvm::errs() << ConfigFile << ": " << "file not found\n";
@@ -4066,7 +4073,6 @@ Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
if (StyleName.starts_with("{")) {
// Parse YAML/JSON style from the command line.
- StringRef Source = "<command-line>";
if (std::error_code ec =
parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
AllowUnknownOptions, DiagHandler)) {
More information about the cfe-commits
mailing list