-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[clang-format] Add option to separate comment alignment between ... #165033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang-format @llvm/pr-subscribers-clang Author: Björn Schäpers (HazardyKnusperkeks) Changesnormal lines and PP directives. Handling PP directives differently can be desired, like in #161848. Changing the default is not an option, there are tests for exactly the current behaviour. Full diff: https://github.com/llvm/llvm-project/pull/165033.diff 7 Files Affected:
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 570cab262c115..0381573793621 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1701,6 +1701,16 @@ the configuration (without a prefix: ``Auto``).
int abcdef; // but this isn't
+ * ``bool AlignPPAndNotPP`` If comments following preprocessor directive should be aligned with
+ comments that don't.
+
+ .. code-block:: c++
+
+ true: false:
+ #define A // Comment vs. #define A // Comment
+ #define AB // Aligned #define AB // Aligned
+ int i; // Aligned int i; // Not aligned
+
.. _AllowAllArgumentsOnNextLine:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fe77f917bb801..5680ea74d8efe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -609,6 +609,7 @@ clang-format
literals.
- Add ``Leave`` suboption to ``IndentPPDirectives``.
- Add ``AllowBreakBeforeQtProperty`` option.
+- Add ``AlignPPAndNotPP`` suboption to ``AlignTrailingComments``.
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 2852c4a2916a4..82c3a215fc94d 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -622,9 +622,19 @@ struct FormatStyle {
/// int abcdef; // but this isn't
/// \endcode
unsigned OverEmptyLines;
+ /// If comments following preprocessor directive should be aligned with
+ /// comments that don't.
+ /// \code
+ /// true: false:
+ /// #define A // Comment vs. #define A // Comment
+ /// #define AB // Aligned #define AB // Aligned
+ /// int i; // Aligned int i; // Not aligned
+ /// \endcode
+ bool AlignPPAndNotPP;
bool operator==(const TrailingCommentsAlignmentStyle &R) const {
- return Kind == R.Kind && OverEmptyLines == R.OverEmptyLines;
+ return Kind == R.Kind && OverEmptyLines == R.OverEmptyLines &&
+ AlignPPAndNotPP == R.AlignPPAndNotPP;
}
bool operator!=(const TrailingCommentsAlignmentStyle &R) const {
return !(*this == R);
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index edd126c7724b8..62b97fbe0ffc4 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -869,27 +869,28 @@ template <> struct MappingTraits<FormatStyle::TrailingCommentsAlignmentStyle> {
FormatStyle::TrailingCommentsAlignmentStyle &Value) {
IO.enumCase(Value, "Leave",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Leave, 0}));
+ {FormatStyle::TCAS_Leave, 0, true}));
IO.enumCase(Value, "Always",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 0}));
+ {FormatStyle::TCAS_Always, 0, true}));
IO.enumCase(Value, "Never",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 0}));
+ {FormatStyle::TCAS_Never, 0, true}));
// For backwards compatibility
IO.enumCase(Value, "true",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 0}));
+ {FormatStyle::TCAS_Always, 0, true}));
IO.enumCase(Value, "false",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 0}));
+ {FormatStyle::TCAS_Never, 0, true}));
}
static void mapping(IO &IO,
FormatStyle::TrailingCommentsAlignmentStyle &Value) {
+ IO.mapOptional("AlignPPAndNotPP", Value.AlignPPAndNotPP);
IO.mapOptional("Kind", Value.Kind);
IO.mapOptional("OverEmptyLines", Value.OverEmptyLines);
}
@@ -1578,6 +1579,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AlignTrailingComments = {};
LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always;
LLVMStyle.AlignTrailingComments.OverEmptyLines = 0;
+ LLVMStyle.AlignTrailingComments.AlignPPAndNotPP = true;
LLVMStyle.AllowAllArgumentsOnNextLine = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowBreakBeforeNoexceptSpecifier = FormatStyle::BBNSS_Never;
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 65fc65e79fdc3..c5f738ebe42ad 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -997,9 +997,13 @@ void WhitespaceManager::alignTrailingComments() {
return;
const int Size = Changes.size();
+ if (Size == 0)
+ return;
+
int MinColumn = 0;
int StartOfSequence = 0;
bool BreakBeforeNext = false;
+ bool IsInPP = Changes.front().Tok->Tok.is(tok::hash);
int NewLineThreshold = 1;
if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Always)
NewLineThreshold = Style.AlignTrailingComments.OverEmptyLines + 1;
@@ -1008,7 +1012,19 @@ void WhitespaceManager::alignTrailingComments() {
auto &C = Changes[I];
if (C.StartOfBlockComment)
continue;
- Newlines += C.NewlinesBefore;
+ if (C.NewlinesBefore != 0) {
+ Newlines += C.NewlinesBefore;
+ const bool WasInPP = std::exchange(
+ IsInPP, C.Tok->Tok.is(tok::hash) || (IsInPP && C.IsTrailingComment) ||
+ C.ContinuesPPDirective);
+ if (IsInPP != WasInPP && !Style.AlignTrailingComments.AlignPPAndNotPP) {
+ alignTrailingComments(StartOfSequence, I, MinColumn);
+ MinColumn = 0;
+ MaxColumn = INT_MAX;
+ StartOfSequence = I;
+ Newlines = 0;
+ }
+ }
if (!C.IsTrailingComment)
continue;
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 6488e38badee7..de22c9f7e2a15 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -576,20 +576,20 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("AlignTrailingComments: Leave", AlignTrailingComments,
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Leave, 0}));
+ {FormatStyle::TCAS_Leave, 0, true}));
CHECK_PARSE("AlignTrailingComments: Always", AlignTrailingComments,
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 0}));
+ {FormatStyle::TCAS_Always, 0, true}));
CHECK_PARSE("AlignTrailingComments: Never", AlignTrailingComments,
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 0}));
+ {FormatStyle::TCAS_Never, 0, true}));
// For backwards compatibility
CHECK_PARSE("AlignTrailingComments: true", AlignTrailingComments,
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 0}));
+ {FormatStyle::TCAS_Always, 0, true}));
CHECK_PARSE("AlignTrailingComments: false", AlignTrailingComments,
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 0}));
+ {FormatStyle::TCAS_Never, 0, true}));
CHECK_PARSE_NESTED_VALUE("Kind: Always", AlignTrailingComments, Kind,
FormatStyle::TCAS_Always);
CHECK_PARSE_NESTED_VALUE("Kind: Never", AlignTrailingComments, Kind,
@@ -598,6 +598,7 @@ TEST(ConfigParseTest, ParsesConfiguration) {
FormatStyle::TCAS_Leave);
CHECK_PARSE_NESTED_VALUE("OverEmptyLines: 1234", AlignTrailingComments,
OverEmptyLines, 1234u);
+ CHECK_PARSE_NESTED_BOOL(AlignTrailingComments, AlignPPAndNotPP);
Style.UseTab = FormatStyle::UT_ForIndentation;
CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp
index 6b433bb384864..e7e93cd5986f4 100644
--- a/clang/unittests/Format/FormatTestComments.cpp
+++ b/clang/unittests/Format/FormatTestComments.cpp
@@ -3501,6 +3501,54 @@ TEST_F(FormatTestComments, DontAlignOverScope) {
"int foobar; // group");
}
+TEST_F(FormatTestComments, DontAlignOverPPDirective) {
+ auto Style = getLLVMStyle();
+ Style.AlignTrailingComments.AlignPPAndNotPP = false;
+
+ verifyFormat("int i; // Aligned\n"
+ "int long; // with this\n"
+ "#define FOO // only aligned\n"
+ "#define LOOONG // with other pp directives\n"
+ "int loooong; // new alignment",
+ "int i;//Aligned\n"
+ "int long;//with this\n"
+ "#define FOO //only aligned\n"
+ "#define LOOONG //with other pp directives\n"
+ "int loooong; //new alignment",
+ Style);
+
+ verifyFormat("#define A // Comment\n"
+ "#define AB // Comment",
+ Style);
+
+ Style.ColumnLimit = 30;
+ verifyNoChange("#define A // Comment\n"
+ " // Continued\n"
+ "int i = 0; // New Stuff\n"
+ " // Continued\n"
+ "#define Func(X) \\\n"
+ " X(); \\\n"
+ " X(); // Comment\n"
+ " // Continued\n"
+ "long loong = 1; // Dont align",
+ Style);
+
+ Style.AlignTrailingComments.OverEmptyLines = 1;
+ verifyNoChange("#define A // Comment\n"
+ "\n"
+ " // Continued\n"
+ "int i = 0; // New Stuff\n"
+ "\n"
+ " // Continued\n"
+ "#define Func(X) \\\n"
+ " X(); \\\n"
+ " X(); // Comment\n"
+ "\n"
+ " // Continued\n"
+ "long loong = 1; // Dont align",
+ Style);
+}
+
TEST_F(FormatTestComments, AlignsBlockCommentDecorations) {
EXPECT_EQ("/*\n"
" */",
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
b4bd206 to
0bce319
Compare
|
If the input contains a long comment following a preprocessor directive, the formatter will fold the comment to the next line. Will the next line be aligned? |
Yes it will, I've extended the tests. |
|
Looks like this can be moved into the |
There it is. |
normal lines and PP directives. Handling PP directives differently can be desired, like in llvm#161848. Changing the default is not an option, there are tests for exactly the current behaviour.
a110811 to
78dbff8
Compare
normal lines and PP directives.
Handling PP directives differently can be desired, like in #161848. Changing the default is not an option, there are tests for exactly the current behaviour.