[clang] b99bf0e - [clang-format][PR45816] Add AlignConsecutiveBitFields
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 19 23:43:13 PDT 2020
Author: mydeveloperday
Date: 2020-05-20T07:42:58+01:00
New Revision: b99bf0e08be4faa4527709541dfdc29240e0c75c
URL: https://github.com/llvm/llvm-project/commit/b99bf0e08be4faa4527709541dfdc29240e0c75c
DIFF: https://github.com/llvm/llvm-project/commit/b99bf0e08be4faa4527709541dfdc29240e0c75c.diff
LOG: [clang-format][PR45816] Add AlignConsecutiveBitFields
Summary:
The following revision follows D80115 since @MyDeveloperDay and I apparently both had the same idea at the same time, for https://bugs.llvm.org/show_bug.cgi?id=45816 and my efforts on tooling support for AMDVLK, respectively.
This option aligns adjacent bitfield separators across lines, in a manner similar to AlignConsecutiveAssignments and friends.
Example:
```
struct RawFloat {
uint32_t sign : 1;
uint32_t exponent : 8;
uint32_t mantissa : 23;
};
```
would become
```
struct RawFloat {
uint32_t sign : 1;
uint32_t exponent : 8;
uint32_t mantissa : 23;
};
```
This also handles c++2a style bitfield-initializers with AlignConsecutiveAssignments.
```
struct RawFloat {
uint32_t sign : 1 = 0;
uint32_t exponent : 8 = 127;
uint32_t mantissa : 23 = 0;
}; // defaults to 1.0f
```
Things this change does not do:
- Align multiple comma-chained bitfield variables. None of the other
AlignConsecutive* options seem to implement that either.
- Detect bitfields that have a width specified with something other
than a numeric literal (ie, `int a : SOME_MACRO;`). That'd be fairly
difficult to parse and is rare.
Patch By: JakeMerdichAMD
Reviewed By: MyDeveloperDay
Subscribers: cfe-commits, MyDeveloperDay
Tags: #clang, #clang-format
Differential Revision: https://reviews.llvm.org/D80176
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/WhitespaceManager.cpp
clang/lib/Format/WhitespaceManager.h
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index e367c3620e16..c4d6c1d50d13 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -204,6 +204,18 @@ the configuration (without a prefix: ``Auto``).
int b = 23;
int ccc = 23;
+**AlignConsecutiveBitFields** (``bool``)
+ If ``true``, aligns consecutive bitfield members.
+
+ This will align the bitfield separators of consecutive lines. This
+ will result in formattings like
+
+ .. code-block:: c++
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
**AlignConsecutiveDeclarations** (``bool``)
If ``true``, aligns consecutive declarations.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8dd22887a195..06b01420ca4e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -297,6 +297,21 @@ clang-format
bar();
});
+- Option ``AlignConsecutiveBitFields`` has been added to align bit field
+ declarations across multiple adjacent lines
+
+ .. code-block:: c++
+
+ true:
+ bool aaa : 1;
+ bool a : 1;
+ bool bb : 1;
+
+ false:
+ bool aaa : 1;
+ bool a : 1;
+ bool bb : 1;
+
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
old mode 100644
new mode 100755
index 9bc08a775647..7083a46b5b14
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -108,6 +108,17 @@ struct FormatStyle {
/// \endcode
bool AlignConsecutiveAssignments;
+ /// If ``true``, aligns consecutive bitfield members.
+ ///
+ /// This will align the bitfield separators of consecutive lines. This
+ /// will result in formattings like
+ /// \code
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ /// \endcode
+ bool AlignConsecutiveBitFields;
+
/// If ``true``, aligns consecutive declarations.
///
/// This will align the declaration names of consecutive lines. This
@@ -2011,8 +2022,8 @@ struct FormatStyle {
/// \endcode
SBPO_ControlStatements,
/// Same as ``SBPO_ControlStatements`` except this option doesn't apply to
- /// ForEach macros. This is useful in projects where ForEach macros are
- /// treated as function calls instead of control statements.
+ /// ForEach macros. This is useful in projects where ForEach macros are
+ /// treated as function calls instead of control statements.
/// \code
/// void f() {
/// Q_FOREACH(...) {
@@ -2218,6 +2229,7 @@ struct FormatStyle {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
AlignConsecutiveAssignments == R.AlignConsecutiveAssignments &&
+ AlignConsecutiveBitFields == R.AlignConsecutiveBitFields &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index cda4baffb3d5..418ace7376ff 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -403,6 +403,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
IO.mapOptional("AlignConsecutiveAssignments",
Style.AlignConsecutiveAssignments);
+ IO.mapOptional("AlignConsecutiveBitFields",
+ Style.AlignConsecutiveBitFields);
IO.mapOptional("AlignConsecutiveDeclarations",
Style.AlignConsecutiveDeclarations);
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
@@ -766,6 +768,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AlignConsecutiveAssignments = false;
+ LLVMStyle.AlignConsecutiveBitFields = false;
LLVMStyle.AlignConsecutiveDeclarations = false;
LLVMStyle.AlignConsecutiveMacros = false;
LLVMStyle.AllowAllArgumentsOnNextLine = true;
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index fd1d74933925..32e0b685ea0f 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -95,6 +95,7 @@ const tooling::Replacements &WhitespaceManager::generateReplacements() {
calculateLineBreakInformation();
alignConsecutiveMacros();
alignConsecutiveDeclarations();
+ alignConsecutiveBitFields();
alignConsecutiveAssignments();
alignChainedConditionals();
alignTrailingComments();
@@ -617,6 +618,26 @@ void WhitespaceManager::alignConsecutiveAssignments() {
Changes, /*StartAt=*/0);
}
+void WhitespaceManager::alignConsecutiveBitFields() {
+ if (!Style.AlignConsecutiveBitFields)
+ return;
+
+ AlignTokens(
+ Style,
+ [&](Change const &C) {
+ // Do not align on ':' that is first on a line.
+ if (C.NewlinesBefore > 0)
+ return false;
+
+ // Do not align on ':' that is last on a line.
+ if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
+ return false;
+
+ return C.Tok->is(TT_BitFieldColon);
+ },
+ Changes, /*StartAt=*/0);
+}
+
void WhitespaceManager::alignConsecutiveDeclarations() {
if (!Style.AlignConsecutiveDeclarations)
return;
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index 87f24e97f0fb..1398a3aee2b8 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -184,6 +184,9 @@ class WhitespaceManager {
/// Align consecutive assignments over all \c Changes.
void alignConsecutiveAssignments();
+ /// Align consecutive bitfields over all \c Changes.
+ void alignConsecutiveBitFields();
+
/// Align consecutive declarations over all \c Changes.
void alignConsecutiveDeclarations();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 5eefe99214b2..9f1b88bf6a6f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12022,6 +12022,48 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
Alignment));
}
+TEST_F(FormatTest, AlignConsecutiveBitFields) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveBitFields = true;
+ verifyFormat("int const a : 5;\n"
+ "int oneTwoThree : 23;",
+ Alignment);
+
+ // Initializers are allowed starting with c++2a
+ verifyFormat("int const a : 5 = 1;\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+
+ Alignment.AlignConsecutiveDeclarations = true;
+ verifyFormat("int const a : 5;\n"
+ "int oneTwoThree : 23;",
+ Alignment);
+
+ verifyFormat("int const a : 5; // comment\n"
+ "int oneTwoThree : 23; // comment",
+ Alignment);
+
+ verifyFormat("int const a : 5 = 1;\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+
+ Alignment.AlignConsecutiveAssignments = true;
+ verifyFormat("int const a : 5 = 1;\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+ verifyFormat("int const a : 5 = {1};\n"
+ "int oneTwoThree : 23 = 0;",
+ Alignment);
+
+ // Known limitations: ':' is only recognized as a bitfield colon when
+ // followed by a number.
+ /*
+ verifyFormat("int oneTwoThree : SOME_CONSTANT;\n"
+ "int a : 5;",
+ Alignment);
+ */
+}
+
TEST_F(FormatTest, AlignConsecutiveDeclarations) {
FormatStyle Alignment = getLLVMStyle();
Alignment.AlignConsecutiveMacros = true;
@@ -13436,6 +13478,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
Style.Language = FormatStyle::LK_Cpp;
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
+ CHECK_PARSE_BOOL(AlignConsecutiveBitFields);
CHECK_PARSE_BOOL(AlignConsecutiveDeclarations);
CHECK_PARSE_BOOL(AlignConsecutiveMacros);
CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
More information about the cfe-commits
mailing list