[clang-tools-extra] [clang] [llvm] [clang-format] Option to ignore macro definitions (PR #70338)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 18 19:57:58 PST 2024
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/70338
>From 25ca978ef9caf372997f2ebf227fb2b2ca443aa0 Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Sat, 11 Nov 2023 19:38:00 +0100
Subject: [PATCH 01/15] Added an option to ignore macro definitions.
---
clang/include/clang/Format/Format.h | 5 +++++
clang/lib/Format/Format.cpp | 2 ++
clang/lib/Format/UnwrappedLineFormatter.cpp | 2 ++
clang/unittests/Format/ConfigParseTest.cpp | 3 ++-
clang/unittests/Format/FormatTest.cpp | 16 ++++++++++++++++
5 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 37cb3b5cc06732..fce68d70f4dd69 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2512,6 +2512,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.
///
@@ -4790,6 +4794,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 db0cb8a3108495..a6e451595527e7 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1002,6 +1002,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);
@@ -1507,6 +1508,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 280485d9a90d1b..bbf6383ff7673f 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/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 0c9f68f303d865..fa4e1469e8cc13 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -167,6 +167,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);
@@ -199,7 +200,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
-
+
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
AcrossEmptyLines);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 420afe5992f2a0..e04ffc146404f1 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24219,6 +24219,22 @@ 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 TEXT Text . With periods.", Style);
+ verifyNoChange("#define TEXT \\\nLine number one . \\\nNumber two .",
+ Style);
+
+ // TODO
+ // verifyNoChange("/* comment */ #define A ( args )", Style);
+}
+
TEST_F(FormatTest, VeryLongNamespaceCommentSplit) {
// These tests are not in NamespaceEndCommentsFixerTest because that doesn't
// test its interaction with line wrapping
>From e19a3a7ac17a8afd57a3776aa52699e8d4e2c01f Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Fri, 27 Oct 2023 13:57:50 +0200
Subject: [PATCH 02/15] Added edge cases to the test and code that fixes
handling them
---
clang/lib/Format/UnwrappedLineParser.cpp | 8 ++++++++
clang/unittests/Format/FormatTest.cpp | 3 ++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 7b4ec25a8938fc..bd4e15feb0d289 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1138,6 +1138,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/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index e04ffc146404f1..9338739334d3d7 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24227,9 +24227,10 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
verifyNoChange("#define A b", Style);
verifyNoChange("#define A ( args )", Style);
verifyNoChange("#define A ( args ) = func ( args )", Style);
- verifyNoChange("#define TEXT Text . With periods.", Style);
verifyNoChange("#define TEXT \\\nLine number one . \\\nNumber two .",
Style);
+ verifyNoChange("#define A x:", Style);
+ verifyNoChange("#define A a. b", Style);
// TODO
// verifyNoChange("/* comment */ #define A ( args )", Style);
>From 4ec984677c5779eafc34e456b894b032ef10dc50 Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Sat, 11 Nov 2023 19:28:25 +0100
Subject: [PATCH 03/15] Added more tests
---
clang/unittests/Format/ConfigParseTest.cpp | 2 +-
clang/unittests/Format/FormatTest.cpp | 40 +++++++++++++++++++---
2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index fa4e1469e8cc13..7a93ec71388eb7 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -200,7 +200,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
-
+
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
AcrossEmptyLines);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 9338739334d3d7..91243d5caeb5b4 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24227,13 +24227,43 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
verifyNoChange("#define A b", Style);
verifyNoChange("#define A ( args )", Style);
verifyNoChange("#define A ( args ) = func ( args )", Style);
- verifyNoChange("#define TEXT \\\nLine number one . \\\nNumber two .",
- Style);
+
verifyNoChange("#define A x:", Style);
verifyNoChange("#define A a. b", Style);
-
- // TODO
- // verifyNoChange("/* comment */ #define A ( args )", 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) {
>From 1640ab6481abeb306bcc1b62dd21a72b4a77046c Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Mon, 13 Nov 2023 10:58:12 +0100
Subject: [PATCH 04/15] Updated documentation files
---
clang/docs/ClangFormatStyleOptions.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 37d76d5c2dd58c..e1d6d5756822e9 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3232,6 +3232,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>`
>From 4d2be7958751264cfe59ababb2949e89f98cbafb Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Mon, 13 Nov 2023 11:06:17 +0100
Subject: [PATCH 05/15] Reformatted changes
---
clang/include/clang/Format/Format.h | 2 +-
clang/unittests/Format/FormatTest.cpp | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index fce68d70f4dd69..18ab712af4cff0 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2512,7 +2512,7 @@ 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;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 91243d5caeb5b4..f0cc20fc06a597 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24230,7 +24230,7 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
verifyNoChange("#define A x:", Style);
verifyNoChange("#define A a. b", Style);
-
+
// Surrounded with formatted code
verifyFormat("int a;\n"
"#define A a\n"
@@ -24239,17 +24239,17 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
"#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);
+ Style);
verifyNoChange("#define A \\\n"
"a a \\\n"
"a \\\na",
@@ -24262,7 +24262,7 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
Style.AlignEscapedNewlines = FormatStyle::ENAS_Right;
verifyNoChange("#define A \\\n"
"a a \\\n"
- "a \\\na",
+ "a \\\na",
Style);
}
>From dc12a24229a9feb90f5fcd87e5efa9136a4385ac Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Mon, 13 Nov 2023 16:43:10 +0100
Subject: [PATCH 06/15] Fixed code order
---
clang/include/clang/Format/Format.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 18ab712af4cff0..c48c8c94559ca7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4788,13 +4788,13 @@ struct FormatStyle {
R.ExperimentalAutoDetectBinPacking &&
FixNamespaceComments == R.FixNamespaceComments &&
ForEachMacros == R.ForEachMacros &&
+ IgnorePPDefinitions == R.IgnorePPDefinitions &&
IncludeStyle.IncludeBlocks == R.IncludeStyle.IncludeBlocks &&
IncludeStyle.IncludeCategories == R.IncludeStyle.IncludeCategories &&
IncludeStyle.IncludeIsMainRegex ==
R.IncludeStyle.IncludeIsMainRegex &&
IncludeStyle.IncludeIsMainSourceRegex ==
R.IncludeStyle.IncludeIsMainSourceRegex &&
- IgnorePPDefinitions == R.IgnorePPDefinitions &&
IndentAccessModifiers == R.IndentAccessModifiers &&
IndentCaseBlocks == R.IndentCaseBlocks &&
IndentCaseLabels == R.IndentCaseLabels &&
>From 9debd8b86b928560b519d644a59fa0a7fa8bb230 Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Mon, 13 Nov 2023 16:44:50 +0100
Subject: [PATCH 07/15] Added more tests to cover PP indentation and fixed
readability in other tests
---
clang/unittests/Format/FormatTest.cpp | 44 +++++++++++++++++++++++----
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index f0cc20fc06a597..48b069598c34b8 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24231,7 +24231,7 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
verifyNoChange("#define A x:", Style);
verifyNoChange("#define A a. b", Style);
- // Surrounded with formatted code
+ // Surrounded with formatted code.
verifyFormat("int a;\n"
"#define A a\n"
"int a;",
@@ -24240,29 +24240,61 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
"int a ;",
Style);
- // Columns are not broken when a limit is set
+ // 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
+ // Multiline definition.
verifyNoChange("#define A \\\n"
"Line one with spaces . \\\n"
" Line two.",
Style);
verifyNoChange("#define A \\\n"
"a a \\\n"
- "a \\\na",
+ "a \\\n"
+ "a",
Style);
Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
verifyNoChange("#define A \\\n"
"a a \\\n"
- "a \\\na",
+ "a \\\n"
+ "a",
Style);
Style.AlignEscapedNewlines = FormatStyle::ENAS_Right;
verifyNoChange("#define A \\\n"
"a a \\\n"
- "a \\\na",
+ "a \\\n"
+ "a",
+ Style);
+
+ // Adjust indendations but don't change the definition.
+ Style.IndentPPDirectives = FormatStyle::PPDIS_None;
+ verifyNoChange("#if A\n"
+ "#define A a\n"
+ "#endif",
+ Style);
+ verifyNoChange("#if A\n"
+ "#define A a\\\n"
+ " a a\n"
+ "#endif",
+ Style);
+ verifyFormat("#if A\n"
+ "#define A a\n"
+ "#endif",
+ "#if A\n"
+ " #define A a\n"
+ "#endif",
+ Style);
+ Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash;
+ verifyNoChange("#if A\n"
+ "# define A a\n"
+ "#endif",
+ Style);
+ Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;
+ verifyNoChange("#if A\n"
+ " #define A a\n"
+ "#endif",
Style);
}
>From 1faffeb0134ef2d6d0fcf0bbf493ece1cc68d22d Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Tue, 14 Nov 2023 11:10:04 +0100
Subject: [PATCH 08/15] Fixed the option affecting other PP directives
---
clang/lib/Format/UnwrappedLineFormatter.cpp | 5 +++-
clang/unittests/Format/FormatTest.cpp | 28 +++++++++++++++------
2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index bbf6383ff7673f..7bfb25089ac06e 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1355,8 +1355,11 @@ unsigned UnwrappedLineFormatter::format(
bool FixIndentation = (FixBadIndentation || ContinueFormatting) &&
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
- if (Style.IgnorePPDefinitions && TheLine.Type == LT_PreprocessorDirective)
+ if (Style.IgnorePPDefinitions && TheLine.Type == LT_PreprocessorDirective &&
+ TheLine.getFirstNonComment()->Next->is(tok::pp_define)) {
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/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 48b069598c34b8..f3f17d4bd3ccf7 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24272,10 +24272,11 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
Style.IndentPPDirectives = FormatStyle::PPDIS_None;
verifyNoChange("#if A\n"
"#define A a\n"
- "#endif",
+ "#endif\n",
Style);
- verifyNoChange("#if A\n"
- "#define A a\\\n"
+ verifyNoChange("#define UNITY 1\n"
+ "#if A\n"
+ "# define A a\\\n"
" a a\n"
"#endif",
Style);
@@ -24287,15 +24288,28 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
"#endif",
Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash;
- verifyNoChange("#if A\n"
- "# define A a\n"
- "#endif",
- Style);
+ verifyFormat("#if A\n"
+ "# define A a\n"
+ "#endif",
+ "#if A\n"
+ " # define A a\n"
+ "#endif",
+ Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;
verifyNoChange("#if A\n"
" #define A a\n"
"#endif",
Style);
+
+ Style.IndentPPDirectives = FormatStyle::PPDIS_None;
+ // IgnorePPDefinitions should not affect other PP directives
+ verifyFormat("#if !defined(A)\n"
+ "# define A a\n"
+ "#endif",
+ "#if ! defined ( A )\n"
+ " # define A a\n"
+ "#endif",
+ Style);
}
TEST_F(FormatTest, VeryLongNamespaceCommentSplit) {
>From afdcba3084da008cc206ce67b64c60fffe77bf6b Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Tue, 14 Nov 2023 12:52:54 +0100
Subject: [PATCH 09/15] Added test cases for trailing comments
---
clang/unittests/Format/FormatTest.cpp | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index f3f17d4bd3ccf7..4de4701cd352e8 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24243,6 +24243,20 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
// Columns are not broken when a limit is set.
Style.ColumnLimit = 10;
verifyNoChange("#define A a a a a", Style);
+
+ Style.ColumnLimit = 15;
+ verifyNoChange("#define A //a very long comment\n", Style);
+ // in the following examples, since second line will not be formtted, it won't
+ // take into considertaion the alignment from the first line. The third line
+ // will follow the second line's alignment.
+ verifyFormat("int aaaaaa; // a\n"
+ "#define A // a\n"
+ "int a; // a\n",
+ "int aaaaaa; // a\n"
+ "#define A // a\n"
+ "int a; // a\n",
+ Style);
+
Style.ColumnLimit = 0;
// Multiline definition.
>From 3d2a56bfa8e2eb3f5a3b8ee05135cec664dc76ee Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Sat, 18 Nov 2023 13:47:53 +0100
Subject: [PATCH 10/15] Refactored condition to ignore PP directives other than
#define
---
clang/lib/Format/UnwrappedLineFormatter.cpp | 12 +++++++++---
clang/unittests/Format/FormatTest.cpp | 18 ++++++++++++++----
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 7bfb25089ac06e..0a49e1cc282372 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1308,6 +1308,13 @@ class OptimizingLineFormatter : public LineFormatter {
} // anonymous namespace
+static bool lineContainsPPDefinition(const AnnotatedLine &Line) {
+ auto *Tok = Line.getFirstNonComment();
+ if (!Tok || !Tok->is(tok::hash) || !Tok->Next)
+ return false;
+ return Tok->Next->is(tok::pp_define);
+}
+
unsigned UnwrappedLineFormatter::format(
const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn,
@@ -1355,10 +1362,9 @@ unsigned UnwrappedLineFormatter::format(
bool FixIndentation = (FixBadIndentation || ContinueFormatting) &&
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
- if (Style.IgnorePPDefinitions && TheLine.Type == LT_PreprocessorDirective &&
- TheLine.getFirstNonComment()->Next->is(tok::pp_define)) {
+
+ if (Style.IgnorePPDefinitions && lineContainsPPDefinition(TheLine))
ShouldFormat = false;
- }
// We cannot format this line; if the reason is that the line had a
// parsing error, remember that.
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 4de4701cd352e8..d6eb5378b813cc 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24245,16 +24245,16 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
verifyNoChange("#define A a a a a", Style);
Style.ColumnLimit = 15;
- verifyNoChange("#define A //a very long comment\n", Style);
+ verifyNoChange("#define A //a very long comment", Style);
// in the following examples, since second line will not be formtted, it won't
// take into considertaion the alignment from the first line. The third line
// will follow the second line's alignment.
verifyFormat("int aaaaaa; // a\n"
"#define A // a\n"
- "int a; // a\n",
+ "int a; // a",
"int aaaaaa; // a\n"
"#define A // a\n"
- "int a; // a\n",
+ "int a; // a",
Style);
Style.ColumnLimit = 0;
@@ -24286,7 +24286,7 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
Style.IndentPPDirectives = FormatStyle::PPDIS_None;
verifyNoChange("#if A\n"
"#define A a\n"
- "#endif\n",
+ "#endif",
Style);
verifyNoChange("#define UNITY 1\n"
"#if A\n"
@@ -24324,6 +24324,16 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
" # define A a\n"
"#endif",
Style);
+
+ // With comments.
+ verifyNoChange("/* */ # define A a // a a", Style);
+ verifyFormat("int a; // a\n"
+ "#define A // a\n"
+ "int aaa; // a",
+ "int a; // a\n"
+ "#define A // a\n"
+ "int aaa; // a",
+ Style);
}
TEST_F(FormatTest, VeryLongNamespaceCommentSplit) {
>From 7d73cc8d002eaa8dbabc834deea639e88ed7adf6 Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Wed, 22 Nov 2023 13:36:51 +0100
Subject: [PATCH 11/15] Fixed code style
---
clang/lib/Format/UnwrappedLineFormatter.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 0a49e1cc282372..4ff483bde02264 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1308,7 +1308,7 @@ class OptimizingLineFormatter : public LineFormatter {
} // anonymous namespace
-static bool lineContainsPPDefinition(const AnnotatedLine &Line) {
+static bool LineContainsPPDefinition(const AnnotatedLine &Line) {
auto *Tok = Line.getFirstNonComment();
if (!Tok || !Tok->is(tok::hash) || !Tok->Next)
return false;
@@ -1363,7 +1363,7 @@ unsigned UnwrappedLineFormatter::format(
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
- if (Style.IgnorePPDefinitions && lineContainsPPDefinition(TheLine))
+ if (Style.IgnorePPDefinitions && LineContainsPPDefinition(TheLine))
ShouldFormat = false;
// We cannot format this line; if the reason is that the line had a
>From 4ab55bd1c1e3de1871d0e5a0db9086a5af90ea9e Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Thu, 23 Nov 2023 15:45:35 +0100
Subject: [PATCH 12/15] Renamed the option name to SkipMacroDefinition based on
feedback
---
clang/docs/ClangFormatStyleOptions.rst | 10 +++++-----
clang/docs/ReleaseNotes.rst | 2 +-
clang/include/clang/Format/Format.h | 10 +++++-----
clang/lib/Format/Format.cpp | 4 ++--
clang/lib/Format/UnwrappedLineFormatter.cpp | 2 +-
clang/lib/Format/UnwrappedLineParser.cpp | 2 +-
clang/unittests/Format/ConfigParseTest.cpp | 2 +-
clang/unittests/Format/FormatTest.cpp | 8 ++++----
8 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index e1d6d5756822e9..2abf6bccafdff9 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3232,11 +3232,6 @@ 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>`
@@ -4905,6 +4900,11 @@ the configuration (without a prefix: ``Auto``).
int bar; int bar;
} // namespace b } // namespace b
+.. _SkipMacroDefinition:
+
+**SkipMacroDefinition** (``Boolean``) :versionbadge:`clang-format 18` :ref:`¶ <SkipMacroDefinition>`
+ Do not format macro definitions.
+
.. _SortIncludes:
**SortIncludes** (``SortIncludesOptions``) :versionbadge:`clang-format 3.8` :ref:`¶ <SortIncludes>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e2e8ee8d76d2e1..a1cc6bc4c85a46 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -960,8 +960,8 @@ clang-format
------------
- Add ``AllowBreakBeforeNoexceptSpecifier`` option.
- Add ``AllowShortCompoundRequirementOnASingleLine`` option.
-- Change ``BreakAfterAttributes`` from ``Never`` to ``Leave`` in LLVM style.
- Add ``BreakAdjacentStringLiterals`` option.
+- Change ``BreakAfterAttributes`` from ``Never`` to ``Leave`` in LLVM style.
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index c48c8c94559ca7..4b2a772052c1d1 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2513,10 +2513,6 @@ struct FormatStyle {
/// \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.
///
/// When ``false``, access modifiers are indented (or outdented) relative to
@@ -3888,6 +3884,10 @@ struct FormatStyle {
/// \version 13
unsigned ShortNamespaceLines;
+ /// Do not format macro definitions.
+ /// \version 18
+ bool SkipMacroDefinition;
+
/// Include sorting options.
enum SortIncludesOptions : int8_t {
/// Includes are never sorted.
@@ -4788,7 +4788,6 @@ struct FormatStyle {
R.ExperimentalAutoDetectBinPacking &&
FixNamespaceComments == R.FixNamespaceComments &&
ForEachMacros == R.ForEachMacros &&
- IgnorePPDefinitions == R.IgnorePPDefinitions &&
IncludeStyle.IncludeBlocks == R.IncludeStyle.IncludeBlocks &&
IncludeStyle.IncludeCategories == R.IncludeStyle.IncludeCategories &&
IncludeStyle.IncludeIsMainRegex ==
@@ -4850,6 +4849,7 @@ struct FormatStyle {
RequiresExpressionIndentation == R.RequiresExpressionIndentation &&
SeparateDefinitionBlocks == R.SeparateDefinitionBlocks &&
ShortNamespaceLines == R.ShortNamespaceLines &&
+ SkipMacroDefinition == R.SkipMacroDefinition &&
SortIncludes == R.SortIncludes &&
SortJavaStaticImport == R.SortJavaStaticImport &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index a6e451595527e7..b5d023e83f96d2 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1002,7 +1002,6 @@ 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);
@@ -1082,6 +1081,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.RequiresExpressionIndentation);
IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
+ IO.mapOptional("SkipMacroDefinition", Style.SkipMacroDefinition);
IO.mapOptional("SortIncludes", Style.SortIncludes);
IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
@@ -1508,7 +1508,6 @@ 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},
@@ -1557,6 +1556,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
LLVMStyle.ShortNamespaceLines = 1;
+ LLVMStyle.SkipMacroDefinition = false;
LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
LLVMStyle.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 4ff483bde02264..1fde54d407e100 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1363,7 +1363,7 @@ unsigned UnwrappedLineFormatter::format(
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
- if (Style.IgnorePPDefinitions && LineContainsPPDefinition(TheLine))
+ if (Style.SkipMacroDefinition && LineContainsPPDefinition(TheLine))
ShouldFormat = false;
// We cannot format this line; if the reason is that the line had a
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index bd4e15feb0d289..13006993e80eec 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1138,7 +1138,7 @@ void UnwrappedLineParser::parsePPDefine() {
return;
}
- if (Style.IgnorePPDefinitions) {
+ if (Style.SkipMacroDefinition) {
do {
nextToken();
} while (!eof());
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 7a93ec71388eb7..f1fd478a4c3d1e 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -167,7 +167,6 @@ 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);
@@ -185,6 +184,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(ReflowComments);
CHECK_PARSE_BOOL(RemoveBracesLLVM);
CHECK_PARSE_BOOL(RemoveSemicolon);
+ CHECK_PARSE_BOOL(SkipMacroDefinition);
CHECK_PARSE_BOOL(SpacesInSquareBrackets);
CHECK_PARSE_BOOL(SpaceInEmptyBlock);
CHECK_PARSE_BOOL(SpacesInContainerLiterals);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index d6eb5378b813cc..876bf19cbf61bb 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24219,9 +24219,9 @@ TEST_F(FormatTest, WhitespaceSensitiveMacros) {
verifyNoChange("FOO(String-ized&Messy+But: :Still=Intentional);", Style);
}
-TEST_F(FormatTest, IgnorePPDefinitions) {
- FormatStyle Style = getLLVMStyle();
- Style.IgnorePPDefinitions = true;
+TEST_F(FormatTest, SkipMacroDefinition) {
+ auto Style = getLLVMStyle();
+ Style.SkipMacroDefinition = true;
verifyNoChange("#define A", Style);
verifyNoChange("#define A b", Style);
@@ -24316,7 +24316,7 @@ TEST_F(FormatTest, IgnorePPDefinitions) {
Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_None;
- // IgnorePPDefinitions should not affect other PP directives
+ // SkipMacroDefinition should not affect other PP directives
verifyFormat("#if !defined(A)\n"
"# define A a\n"
"#endif",
>From a0388addc03de16661d41588673360debc8233d9 Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Thu, 23 Nov 2023 16:14:11 +0100
Subject: [PATCH 13/15] Simplified condition
---
clang/lib/Format/UnwrappedLineFormatter.cpp | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 1fde54d407e100..0db2b738c11002 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1308,13 +1308,6 @@ class OptimizingLineFormatter : public LineFormatter {
} // anonymous namespace
-static bool LineContainsPPDefinition(const AnnotatedLine &Line) {
- auto *Tok = Line.getFirstNonComment();
- if (!Tok || !Tok->is(tok::hash) || !Tok->Next)
- return false;
- return Tok->Next->is(tok::pp_define);
-}
-
unsigned UnwrappedLineFormatter::format(
const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn,
@@ -1363,7 +1356,7 @@ unsigned UnwrappedLineFormatter::format(
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
- if (Style.SkipMacroDefinition && LineContainsPPDefinition(TheLine))
+ if (Style.SkipMacroDefinition && TheLine.startsWith(tok::hash, tok::pp_define))
ShouldFormat = false;
// We cannot format this line; if the reason is that the line had a
>From edc929ba16701e4ca5fe17f1e745f3c348f06a4f Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Tue, 28 Nov 2023 16:07:25 +0100
Subject: [PATCH 14/15] changed the logic to only ignore the body of a PP
define
---
clang/lib/Format/ContinuationIndenter.cpp | 15 ++++-
clang/lib/Format/ContinuationIndenter.h | 8 ++-
clang/lib/Format/UnwrappedLineFormatter.cpp | 3 -
clang/lib/Format/UnwrappedLineParser.cpp | 18 +++---
clang/unittests/Format/FormatTest.cpp | 69 +++++++++++++--------
5 files changed, 71 insertions(+), 42 deletions(-)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 8fffdccd35c059..12b3fccecc4430 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -739,8 +739,18 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
}
if (!DryRun) {
- Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces,
- State.Column + Spaces + PPColumnCorrection);
+ if (Style.SkipMacroDefinition && CurrentState.IsPPDefineBody &&
+ !Current.is(tok::comment)) {
+ Whitespaces.addUntouchableToken(Current, State.Line->InPPDirective);
+ } else {
+ Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces,
+ State.Column + Spaces + PPColumnCorrection);
+ }
+ }
+
+ if (Style.SkipMacroDefinition && Previous.is(tok::pp_define)) {
+ CurrentState.NoLineBreak = true;
+ CurrentState.IsPPDefineBody = true;
}
// If "BreakBeforeInheritanceComma" mode, don't break within the inheritance
@@ -1888,6 +1898,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
NewState.NestedBlockIndent = NestedBlockIndent;
NewState.BreakBeforeParameter = BreakBeforeParameter;
NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
+ NewState.IsPPDefineBody = CurrentState.IsPPDefineBody;
if (Style.BraceWrapping.BeforeLambdaBody && Current.Next &&
Current.is(tok::l_paren)) {
diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h
index 057b85bd32d505..d1a611bfa3aafe 100644
--- a/clang/lib/Format/ContinuationIndenter.h
+++ b/clang/lib/Format/ContinuationIndenter.h
@@ -212,7 +212,8 @@ struct ParenState {
ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false),
NestedBlockInlined(false), IsInsideObjCArrayLiteral(false),
IsCSharpGenericTypeConstraint(false), IsChainedConditional(false),
- IsWrappedConditional(false), UnindentOperator(false) {}
+ IsPPDefineBody(false), IsWrappedConditional(false),
+ UnindentOperator(false) {}
/// \brief The token opening this parenthesis level, or nullptr if this level
/// is opened by fake parenthesis.
@@ -349,6 +350,9 @@ struct ParenState {
/// a chained conditional expression (e.g. else-if)
bool IsChainedConditional : 1;
+ /// \brief true if in pre-processor define body
+ bool IsPPDefineBody : 1;
+
/// \brief true if there conditionnal was wrapped on the first operator (the
/// question mark)
bool IsWrappedConditional : 1;
@@ -402,6 +406,8 @@ struct ParenState {
return IsCSharpGenericTypeConstraint;
if (IsChainedConditional != Other.IsChainedConditional)
return IsChainedConditional;
+ if (IsPPDefineBody != Other.IsPPDefineBody)
+ return IsPPDefineBody;
if (IsWrappedConditional != Other.IsWrappedConditional)
return IsWrappedConditional;
if (UnindentOperator != Other.UnindentOperator)
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 0db2b738c11002..2b66bb18edf9b3 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1356,9 +1356,6 @@ unsigned UnwrappedLineFormatter::format(
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
- if (Style.SkipMacroDefinition && TheLine.startsWith(tok::hash, tok::pp_define))
- 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 13006993e80eec..01b01fbfce1234 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1138,14 +1138,6 @@ void UnwrappedLineParser::parsePPDefine() {
return;
}
- if (Style.SkipMacroDefinition) {
- do {
- nextToken();
- } while (!eof());
- addUnwrappedLine();
- return;
- }
-
if (IncludeGuard == IG_IfNdefed &&
IncludeGuardToken->TokenText == FormatTok->TokenText) {
IncludeGuard = IG_Defined;
@@ -1165,7 +1157,15 @@ void UnwrappedLineParser::parsePPDefine() {
// guard processing above, and changes preprocessing nesting.
FormatTok->Tok.setKind(tok::identifier);
FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
- nextToken();
+
+ if (Style.SkipMacroDefinition) {
+ do {
+ nextToken();
+ } while (!eof());
+ } else {
+ nextToken();
+ }
+
if (FormatTok->Tok.getKind() == tok::l_paren &&
!FormatTok->hasWhitespaceBefore()) {
parseParens();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 876bf19cbf61bb..abeb5609025ef1 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24223,17 +24223,24 @@ TEST_F(FormatTest, SkipMacroDefinition) {
auto Style = getLLVMStyle();
Style.SkipMacroDefinition = true;
- verifyNoChange("#define A", Style);
+ verifyFormat("#define A", "#define A", Style);
+ verifyFormat("#define A a aa", "#define A a aa", Style);
verifyNoChange("#define A b", Style);
verifyNoChange("#define A ( args )", Style);
verifyNoChange("#define A ( args ) = func ( args )", Style);
+ verifyNoChange("#define A ( args ) { int a = 1 ; }", Style);
+ verifyNoChange("#define A ( args ) \\\n"
+ " {\\\n"
+ " int a = 1 ;\\\n"
+ "}",
+ Style);
verifyNoChange("#define A x:", Style);
verifyNoChange("#define A a. b", Style);
// Surrounded with formatted code.
verifyFormat("int a;\n"
- "#define A a\n"
+ "#define A a\n"
"int a;",
"int a ;\n"
"#define A a\n"
@@ -24242,21 +24249,15 @@ TEST_F(FormatTest, SkipMacroDefinition) {
// Columns are not broken when a limit is set.
Style.ColumnLimit = 10;
+ verifyFormat("#define A a a a a", " # define A a a a a ", Style);
verifyNoChange("#define A a a a a", Style);
Style.ColumnLimit = 15;
- verifyNoChange("#define A //a very long comment", Style);
- // in the following examples, since second line will not be formtted, it won't
- // take into considertaion the alignment from the first line. The third line
- // will follow the second line's alignment.
- verifyFormat("int aaaaaa; // a\n"
- "#define A // a\n"
- "int a; // a",
- "int aaaaaa; // a\n"
- "#define A // a\n"
- "int a; // a",
- Style);
-
+ verifyFormat("#define A // a\n"
+ " // very\n"
+ " // long\n"
+ " // comment",
+ "#define A //a very long comment", Style);
Style.ColumnLimit = 0;
// Multiline definition.
@@ -24288,12 +24289,6 @@ TEST_F(FormatTest, SkipMacroDefinition) {
"#define A a\n"
"#endif",
Style);
- verifyNoChange("#define UNITY 1\n"
- "#if A\n"
- "# define A a\\\n"
- " a a\n"
- "#endif",
- Style);
verifyFormat("#if A\n"
"#define A a\n"
"#endif",
@@ -24302,11 +24297,15 @@ TEST_F(FormatTest, SkipMacroDefinition) {
"#endif",
Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash;
+ verifyNoChange("#if A\n"
+ "# define A a\n"
+ "#endif",
+ Style);
verifyFormat("#if A\n"
"# define A a\n"
"#endif",
"#if A\n"
- " # define A a\n"
+ " #define A a\n"
"#endif",
Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;
@@ -24314,26 +24313,42 @@ TEST_F(FormatTest, SkipMacroDefinition) {
" #define A a\n"
"#endif",
Style);
+ verifyFormat("#if A\n"
+ " #define A a\n"
+ "#endif",
+ "#if A\n"
+ " # define A a\n"
+ "#endif",
+ Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_None;
// SkipMacroDefinition should not affect other PP directives
verifyFormat("#if !defined(A)\n"
- "# define A a\n"
+ "#define A a\n"
"#endif",
"#if ! defined ( A )\n"
- " # define A a\n"
+ " #define A a\n"
"#endif",
Style);
// With comments.
- verifyNoChange("/* */ # define A a // a a", Style);
- verifyFormat("int a; // a\n"
- "#define A // a\n"
- "int aaa; // a",
+ verifyFormat("/* */ #define A a // a a", "/* */ # define A a // a a",
+ Style);
+ verifyNoChange("/* */ #define A a // a a", Style);
+
+ verifyFormat("int a; // a\n"
+ "#define A // a\n"
+ "int aaa; // a",
"int a; // a\n"
"#define A // a\n"
"int aaa; // a",
Style);
+
+ // multiline macro definitions
+ verifyNoChange("#define A a\\\n"
+ " A a \\\n "
+ " A a",
+ Style);
}
TEST_F(FormatTest, VeryLongNamespaceCommentSplit) {
>From 75ae623406b1f7cac1d0224ecdd3ac6c33debfe1 Mon Sep 17 00:00:00 2001
From: Tomek Paszek <tomek at unity3d.com>
Date: Tue, 28 Nov 2023 16:13:57 +0100
Subject: [PATCH 15/15] renamed the setting to SkipMacroDefinitionBody
---
clang/docs/ClangFormatStyleOptions.rst | 6 +++---
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/Format/Format.h | 6 +++---
clang/lib/Format/ContinuationIndenter.cpp | 4 ++--
clang/lib/Format/Format.cpp | 4 ++--
clang/lib/Format/UnwrappedLineFormatter.cpp | 1 -
clang/lib/Format/UnwrappedLineParser.cpp | 2 +-
clang/unittests/Format/ConfigParseTest.cpp | 2 +-
clang/unittests/Format/FormatTest.cpp | 6 +++---
9 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 2abf6bccafdff9..262318a8b833a3 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -4900,10 +4900,10 @@ the configuration (without a prefix: ``Auto``).
int bar; int bar;
} // namespace b } // namespace b
-.. _SkipMacroDefinition:
+.. _SkipMacroDefinitionBody:
-**SkipMacroDefinition** (``Boolean``) :versionbadge:`clang-format 18` :ref:`¶ <SkipMacroDefinition>`
- Do not format macro definitions.
+**SkipMacroDefinitionBody** (``Boolean``) :versionbadge:`clang-format 18` :ref:`¶ <SkipMacroDefinitionBody>`
+ Do not format macro definition body.
.. _SortIncludes:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a1cc6bc4c85a46..124ee3d7ea21bd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -961,6 +961,7 @@ clang-format
- Add ``AllowBreakBeforeNoexceptSpecifier`` option.
- Add ``AllowShortCompoundRequirementOnASingleLine`` option.
- Add ``BreakAdjacentStringLiterals`` option.
+- Add ``SkipMacroDefinitionBody`` option.
- Change ``BreakAfterAttributes`` from ``Never`` to ``Leave`` in LLVM style.
libclang
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 4b2a772052c1d1..247e336656f5e6 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -3884,9 +3884,9 @@ struct FormatStyle {
/// \version 13
unsigned ShortNamespaceLines;
- /// Do not format macro definitions.
+ /// Do not format macro definition body.
/// \version 18
- bool SkipMacroDefinition;
+ bool SkipMacroDefinitionBody;
/// Include sorting options.
enum SortIncludesOptions : int8_t {
@@ -4849,7 +4849,7 @@ struct FormatStyle {
RequiresExpressionIndentation == R.RequiresExpressionIndentation &&
SeparateDefinitionBlocks == R.SeparateDefinitionBlocks &&
ShortNamespaceLines == R.ShortNamespaceLines &&
- SkipMacroDefinition == R.SkipMacroDefinition &&
+ SkipMacroDefinitionBody == R.SkipMacroDefinitionBody &&
SortIncludes == R.SortIncludes &&
SortJavaStaticImport == R.SortJavaStaticImport &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 12b3fccecc4430..33b9d7f15cb3cb 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -739,7 +739,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
}
if (!DryRun) {
- if (Style.SkipMacroDefinition && CurrentState.IsPPDefineBody &&
+ if (Style.SkipMacroDefinitionBody && CurrentState.IsPPDefineBody &&
!Current.is(tok::comment)) {
Whitespaces.addUntouchableToken(Current, State.Line->InPPDirective);
} else {
@@ -748,7 +748,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
}
}
- if (Style.SkipMacroDefinition && Previous.is(tok::pp_define)) {
+ if (Style.SkipMacroDefinitionBody && Previous.is(tok::pp_define)) {
CurrentState.NoLineBreak = true;
CurrentState.IsPPDefineBody = true;
}
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index b5d023e83f96d2..bb7411d9e70381 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1081,7 +1081,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.RequiresExpressionIndentation);
IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
- IO.mapOptional("SkipMacroDefinition", Style.SkipMacroDefinition);
+ IO.mapOptional("SkipMacroDefinitionBody", Style.SkipMacroDefinitionBody);
IO.mapOptional("SortIncludes", Style.SortIncludes);
IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
@@ -1556,7 +1556,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
LLVMStyle.ShortNamespaceLines = 1;
- LLVMStyle.SkipMacroDefinition = false;
+ LLVMStyle.SkipMacroDefinitionBody = false;
LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
LLVMStyle.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 2b66bb18edf9b3..280485d9a90d1b 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1355,7 +1355,6 @@ unsigned UnwrappedLineFormatter::format(
bool FixIndentation = (FixBadIndentation || ContinueFormatting) &&
Indent != TheLine.First->OriginalColumn;
bool ShouldFormat = TheLine.Affected || FixIndentation;
-
// 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 01b01fbfce1234..970c31d0d4cde9 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1158,7 +1158,7 @@ void UnwrappedLineParser::parsePPDefine() {
FormatTok->Tok.setKind(tok::identifier);
FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
- if (Style.SkipMacroDefinition) {
+ if (Style.SkipMacroDefinitionBody) {
do {
nextToken();
} while (!eof());
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index f1fd478a4c3d1e..52f84525159a18 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -184,7 +184,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(ReflowComments);
CHECK_PARSE_BOOL(RemoveBracesLLVM);
CHECK_PARSE_BOOL(RemoveSemicolon);
- CHECK_PARSE_BOOL(SkipMacroDefinition);
+ CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
CHECK_PARSE_BOOL(SpacesInSquareBrackets);
CHECK_PARSE_BOOL(SpaceInEmptyBlock);
CHECK_PARSE_BOOL(SpacesInContainerLiterals);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index abeb5609025ef1..0da133d56baf25 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24219,9 +24219,9 @@ TEST_F(FormatTest, WhitespaceSensitiveMacros) {
verifyNoChange("FOO(String-ized&Messy+But: :Still=Intentional);", Style);
}
-TEST_F(FormatTest, SkipMacroDefinition) {
+TEST_F(FormatTest, SkipMacroDefinitionBody) {
auto Style = getLLVMStyle();
- Style.SkipMacroDefinition = true;
+ Style.SkipMacroDefinitionBody = true;
verifyFormat("#define A", "#define A", Style);
verifyFormat("#define A a aa", "#define A a aa", Style);
@@ -24322,7 +24322,7 @@ TEST_F(FormatTest, SkipMacroDefinition) {
Style);
Style.IndentPPDirectives = FormatStyle::PPDIS_None;
- // SkipMacroDefinition should not affect other PP directives
+ // SkipMacroDefinitionBody should not affect other PP directives
verifyFormat("#if !defined(A)\n"
"#define A a\n"
"#endif",
More information about the cfe-commits
mailing list