JakeMerdichAMD created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The following revision follows https://reviews.llvm.org/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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D80176 Files: 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
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -11955,6 +11955,48 @@ 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; @@ -13369,6 +13411,7 @@ 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); Index: clang/lib/Format/WhitespaceManager.h =================================================================== --- clang/lib/Format/WhitespaceManager.h +++ clang/lib/Format/WhitespaceManager.h @@ -184,6 +184,9 @@ /// 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(); Index: clang/lib/Format/WhitespaceManager.cpp =================================================================== --- clang/lib/Format/WhitespaceManager.cpp +++ clang/lib/Format/WhitespaceManager.cpp @@ -95,6 +95,7 @@ calculateLineBreakInformation(); alignConsecutiveMacros(); alignConsecutiveDeclarations(); + alignConsecutiveBitFields(); alignConsecutiveAssignments(); alignChainedConditionals(); alignTrailingComments(); @@ -609,6 +610,25 @@ 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; Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -403,6 +403,8 @@ 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 @@ LLVMStyle.AlignOperands = FormatStyle::OAS_Align; LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = false; + LLVMStyle.AlignConsecutiveBitFields = false; LLVMStyle.AlignConsecutiveDeclarations = false; LLVMStyle.AlignConsecutiveMacros = false; LLVMStyle.AllowAllArgumentsOnNextLine = true; Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -108,6 +108,17 @@ /// \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 @@ -2218,6 +2229,7 @@ return AccessModifierOffset == R.AccessModifierOffset && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && + AlignConsecutiveBitFields == R.AlignConsecutiveBitFields && AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -297,6 +297,21 @@ 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 -------- Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -204,6 +204,18 @@ int b = 23; int ccc = 23; +**AlignConsecutiveBitFields** (``bool``) + If ``true``, aligns consecutive bitfield members. + + This will align the bitfield separator 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits