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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits