[clang] [clang-format] Option to ignore PP directives (PR #70338)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 13 01:59:21 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Tomek (tomekpaszek)
<details>
<summary>Changes</summary>
Sometimes macro definitions contain a layout we don't want to change in any context. This PR adds a new style option `IgnorePPDefinitions` that prevents clang-format from touching PP directives.
This PR addresses issue #<!-- -->67991
---
Full diff: https://github.com/llvm/llvm-project/pull/70338.diff
7 Files Affected:
- (modified) clang/docs/ClangFormatStyleOptions.rst (+5)
- (modified) clang/include/clang/Format/Format.h (+5)
- (modified) clang/lib/Format/Format.cpp (+2)
- (modified) clang/lib/Format/UnwrappedLineFormatter.cpp (+2)
- (modified) clang/lib/Format/UnwrappedLineParser.cpp (+8)
- (modified) clang/unittests/Format/ConfigParseTest.cpp (+1)
- (modified) clang/unittests/Format/FormatTest.cpp (+47)
``````````diff
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 21342e1b89ea866..80565620d8f24bf 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3160,6 +3160,11 @@ the configuration (without a prefix: ``Auto``).
For example: `KJ_IF_MAYBE
<https://github.com/capnproto/capnproto/blob/master/kjdoc/tour.md#maybes>`_
+.. _IgnorePPDefinitions:
+
+**IgnorePPDefinitions** (``Boolean``) :versionbadge:`clang-format 18` :ref:`¶ <IgnorePPDefinitions>`
+ Ignore formatting in preprocessor definitions.
+
.. _IncludeBlocks:
**IncludeBlocks** (``IncludeBlocksStyle``) :versionbadge:`clang-format 6` :ref:`¶ <IncludeBlocks>`
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 3e9d1915badd87f..3af7241441c8b13 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2442,6 +2442,10 @@ struct FormatStyle {
/// <https://github.com/capnproto/capnproto/blob/master/kjdoc/tour.md#maybes>`_
/// \version 13
std::vector<std::string> IfMacros;
+
+ /// Ignore formatting in preprocessor definitions.
+ /// \version 18
+ bool IgnorePPDefinitions;
/// Specify whether access modifiers should have their own indentation level.
///
@@ -4719,6 +4723,7 @@ struct FormatStyle {
R.IncludeStyle.IncludeIsMainRegex &&
IncludeStyle.IncludeIsMainSourceRegex ==
R.IncludeStyle.IncludeIsMainSourceRegex &&
+ IgnorePPDefinitions == R.IgnorePPDefinitions &&
IndentAccessModifiers == R.IndentAccessModifiers &&
IndentCaseBlocks == R.IndentCaseBlocks &&
IndentCaseLabels == R.IndentCaseLabels &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index edb33f4af4defef..6e5ec754dfdcdd9 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1000,6 +1000,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
IO.mapOptional("ForEachMacros", Style.ForEachMacros);
IO.mapOptional("IfMacros", Style.IfMacros);
+ IO.mapOptional("IgnorePPDefinitions", Style.IgnorePPDefinitions);
IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
@@ -1504,6 +1505,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
+ LLVMStyle.IgnorePPDefinitions = false;
LLVMStyle.IncludeStyle.IncludeCategories = {
{"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
{"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 280485d9a90d1bf..bbf6383ff7673f6 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1355,6 +1355,8 @@ unsigned UnwrappedLineFormatter::format(
bool FixIndentation = (FixBadIndentation || ContinueFormatting) &&
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
+ if (Style.IgnorePPDefinitions && TheLine.Type == LT_PreprocessorDirective)
+ ShouldFormat = false;
// We cannot format this line; if the reason is that the line had a
// parsing error, remember that.
if (ShouldFormat && TheLine.Type == LT_Invalid && Status) {
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 488d8dc07b1eae3..07cf966a08ff5e5 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1134,6 +1134,14 @@ void UnwrappedLineParser::parsePPDefine() {
return;
}
+ if (Style.IgnorePPDefinitions) {
+ do {
+ nextToken();
+ } while (!eof());
+ addUnwrappedLine();
+ return;
+ }
+
if (IncludeGuard == IG_IfNdefed &&
IncludeGuardToken->TokenText == FormatTok->TokenText) {
IncludeGuard = IG_Defined;
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index f90ed178d99c286..7ce9ae26b36fbb9 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -166,6 +166,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(DerivePointerAlignment);
CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
CHECK_PARSE_BOOL(DisableFormat);
+ CHECK_PARSE_BOOL(IgnorePPDefinitions);
CHECK_PARSE_BOOL(IndentAccessModifiers);
CHECK_PARSE_BOOL(IndentCaseLabels);
CHECK_PARSE_BOOL(IndentCaseBlocks);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index b2d84f2ee389551..19cf521107c604b 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24153,6 +24153,53 @@ TEST_F(FormatTest, WhitespaceSensitiveMacros) {
verifyNoChange("FOO(String-ized&Messy+But: :Still=Intentional);", Style);
}
+TEST_F(FormatTest, IgnorePPDefinitions) {
+ FormatStyle Style = getLLVMStyle();
+ Style.IgnorePPDefinitions = true;
+
+ verifyNoChange("#define A", Style);
+ verifyNoChange("#define A b", Style);
+ verifyNoChange("#define A ( args )", Style);
+ verifyNoChange("#define A ( args ) = func ( args )", Style);
+
+ verifyNoChange("#define A x:", Style);
+ verifyNoChange("#define A a. b", Style);
+
+ // Surrounded with formatted code
+ verifyFormat("int a;\n"
+ "#define A a\n"
+ "int a;",
+ "int a ;\n"
+ "#define A a\n"
+ "int a ;",
+ Style);
+
+ // Columns are not broken when a limit is set
+ Style.ColumnLimit = 10;
+ verifyNoChange("#define A a a a a", Style);
+ Style.ColumnLimit = 0;
+
+ // Multiline definition
+ verifyNoChange("#define A \\\n"
+ "Line one with spaces . \\\n"
+ " Line two.",
+ Style);
+ verifyNoChange("#define A \\\n"
+ "a a \\\n"
+ "a \\\na",
+ Style);
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ verifyNoChange("#define A \\\n"
+ "a a \\\n"
+ "a \\\na",
+ Style);
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Right;
+ verifyNoChange("#define A \\\n"
+ "a a \\\n"
+ "a \\\na",
+ Style);
+}
+
TEST_F(FormatTest, VeryLongNamespaceCommentSplit) {
// These tests are not in NamespaceEndCommentsFixerTest because that doesn't
// test its interaction with line wrapping
``````````
</details>
https://github.com/llvm/llvm-project/pull/70338
More information about the cfe-commits
mailing list