[clang] [clang-format] Option to ignore PP directives (PR #70338)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 11 12:28:35 PST 2023
https://github.com/tomekpaszek updated https://github.com/llvm/llvm-project/pull/70338
>From 46a2ad3fd19697ab8b92b7de061346b1471a8eed 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 1/3] Added an option to ignore macro definitions.
---
clang/include/clang/Format/Format.h | 10 +++++++++-
clang/lib/Format/Format.cpp | 4 ++++
clang/lib/Format/UnwrappedLineFormatter.cpp | 2 ++
clang/unittests/Format/ConfigParseTest.cpp | 2 ++
clang/unittests/Format/FormatTest.cpp | 16 ++++++++++++++++
5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 3e9d1915badd87f..c19769911ea9c1b 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.
///
@@ -4648,6 +4652,8 @@ struct FormatStyle {
/// \version 11
std::vector<std::string> WhitespaceSensitiveMacros;
+ bool IgnorePPDefinitions;
+
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
@@ -4719,6 +4725,7 @@ struct FormatStyle {
R.IncludeStyle.IncludeIsMainRegex &&
IncludeStyle.IncludeIsMainSourceRegex ==
R.IncludeStyle.IncludeIsMainSourceRegex &&
+ IgnorePPDefinitions == R.IgnorePPDefinitions &&
IndentAccessModifiers == R.IndentAccessModifiers &&
IndentCaseBlocks == R.IndentCaseBlocks &&
IndentCaseLabels == R.IndentCaseLabels &&
@@ -4810,7 +4817,8 @@ struct FormatStyle {
UseTab == R.UseTab &&
VerilogBreakBetweenInstancePorts ==
R.VerilogBreakBetweenInstancePorts &&
- WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros;
+ WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros &&
+ IgnorePPDefinitions == R.IgnorePPDefinitions;
}
std::optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index edb33f4af4defef..f000983c881d551 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);
@@ -1127,6 +1128,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.VerilogBreakBetweenInstancePorts);
IO.mapOptional("WhitespaceSensitiveMacros",
Style.WhitespaceSensitiveMacros);
+ IO.mapOptional("IgnorePPDefinitions", Style.IgnorePPDefinitions);
// If AlwaysBreakAfterDefinitionReturnType was specified but
// AlwaysBreakAfterReturnType was not, initialize the latter from the
@@ -1504,6 +1506,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},
@@ -1591,6 +1594,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
+ LLVMStyle.IgnorePPDefinitions = false;
LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
LLVMStyle.PenaltyBreakComment = 300;
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/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index f90ed178d99c286..f3782b449554e02 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);
@@ -198,6 +199,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
+ CHECK_PARSE_BOOL(IgnorePPDefinitions);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index b2d84f2ee389551..659132dcb9c3970 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24153,6 +24153,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 28fee10bf67d8cddcaf45c21b114a0ced6f1010c 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 2/3] Added edge cases to the test and code that fixes handling
them
---
clang/include/clang/Format/Format.h | 2 ++
clang/lib/Format/UnwrappedLineParser.cpp | 8 ++++++++
clang/unittests/Format/FormatTest.cpp | 3 ++-
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index c19769911ea9c1b..fadb894e5f00908 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4652,6 +4652,8 @@ struct FormatStyle {
/// \version 11
std::vector<std::string> WhitespaceSensitiveMacros;
+ /// Ignore formatting in preprocessor definitions.
+ /// \version 18
bool IgnorePPDefinitions;
bool operator==(const FormatStyle &R) const {
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/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 659132dcb9c3970..a1f8961c3e5edb6 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24161,9 +24161,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 851a28a0a5e7312d189b600c040d43d24753a20d 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 3/3] Added more tests
---
clang/unittests/Format/FormatTest.cpp | 40 +++++++++++++++++++++++----
1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a1f8961c3e5edb6..19cf521107c604b 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24161,13 +24161,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) {
More information about the cfe-commits
mailing list