https://github.com/jh7370 created https://github.com/llvm/llvm-project/pull/160270
This allows disabling variable alignment declarations while still having function alignment. It also distinguishes between class member variables and other variables (e.g. function local variables). Fixes #143947. >From f08a439bf3aa968e0d15c483ecab2f2457c78e8d Mon Sep 17 00:00:00 2001 From: James Henderson <[email protected]> Date: Mon, 22 Sep 2025 16:41:38 +0100 Subject: [PATCH] [clang-format] Support fine-grained alignment of variable declarations This allows disabling variable alignment declarations while still having function alignment. It also distinguishes between class member variables and other variables (e.g. function local variables). Fixes #143947. --- clang/docs/ClangFormatStyleOptions.rst | 210 +++++++++++++++++++++ clang/include/clang/Format/Format.h | 31 +++ clang/lib/Format/Format.cpp | 81 +++++--- clang/lib/Format/FormatToken.h | 6 +- clang/lib/Format/TokenAnnotator.cpp | 2 + clang/lib/Format/WhitespaceManager.cpp | 6 + clang/unittests/Format/ConfigParseTest.cpp | 82 ++++---- clang/unittests/Format/FormatTest.cpp | 59 ++++++ 8 files changed, 411 insertions(+), 66 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index b746df5dab264..58d1fb43821b7 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -396,6 +396,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -428,6 +443,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. @@ -554,6 +584,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -586,6 +631,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. @@ -712,6 +772,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -744,6 +819,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. @@ -871,6 +961,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -903,6 +1008,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. @@ -1149,6 +1269,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -1181,6 +1316,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. @@ -1305,6 +1455,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -1337,6 +1502,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. @@ -1461,6 +1641,21 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; + * ``bool AlignFreeVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int v1; + float v2; + size_t v3; + + false: + unsigned int v1; + float v2; + size_t v3; + * ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations are aligned. @@ -1493,6 +1688,21 @@ the configuration (without a prefix: ``Auto``). int *p; int (*f)(); + * ``bool AlignMemberVariableDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + variable declarations are aligned. + + .. code-block:: c++ + + true: + unsigned int member1; + float member2; + size_t member3; + + false: + unsigned int member1; + float member2; + size_t member3; + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment operators are left-padded to the same length as long ones in order to put all assignment operators to the right of the left hand side. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 3df5b92654094..b18524b7f67a2 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -226,6 +226,20 @@ struct FormatStyle { /// bbb = 2; /// \endcode bool AlignCompound; + /// Only for ``AlignConsecutiveDeclarations``. Whether non-member variable + /// declarations are aligned. + /// \code + /// true: + /// unsigned int v1; + /// float v2; + /// size_t v3; + /// + /// false: + /// unsigned int v1; + /// float v2; + /// size_t v3; + /// \endcode + bool AlignFreeVariableDeclarations; /// Only for ``AlignConsecutiveDeclarations``. Whether function declarations /// are aligned. /// \code @@ -256,6 +270,20 @@ struct FormatStyle { /// int (*f)(); /// \endcode bool AlignFunctionPointers; + /// Only for ``AlignConsecutiveDeclarations``. Whether class/struct member + /// variable declarations are aligned. + /// \code + /// true: + /// unsigned int member1; + /// float member2; + /// size_t member3; + /// + /// false: + /// unsigned int member1; + /// float member2; + /// size_t member3; + /// \endcode + bool AlignMemberVariableDeclarations; /// Only for ``AlignConsecutiveAssignments``. Whether short assignment /// operators are left-padded to the same length as long ones in order to /// put all assignment operators to the right of the left hand side. @@ -279,8 +307,11 @@ struct FormatStyle { return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines && AcrossComments == R.AcrossComments && AlignCompound == R.AlignCompound && + AlignFreeVariableDeclarations == R.AlignFreeVariableDeclarations && AlignFunctionDeclarations == R.AlignFunctionDeclarations && AlignFunctionPointers == R.AlignFunctionPointers && + AlignMemberVariableDeclarations == + R.AlignMemberVariableDeclarations && PadOperators == R.PadOperators; } bool operator!=(const AlignConsecutiveStyle &R) const { diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index b38f2810c0a74..c374445939efe 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -47,38 +47,53 @@ struct ScalarEnumerationTraits<FormatStyle::BreakBeforeNoexceptSpecifierStyle> { template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> { static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) { IO.enumCase(Value, "None", FormatStyle::AlignConsecutiveStyle({})); - IO.enumCase(Value, "Consecutive", - FormatStyle::AlignConsecutiveStyle( - {/*Enabled=*/true, /*AcrossEmptyLines=*/false, - /*AcrossComments=*/false, /*AlignCompound=*/false, - /*AlignFunctionDeclarations=*/true, - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); - IO.enumCase(Value, "AcrossEmptyLines", - FormatStyle::AlignConsecutiveStyle( - {/*Enabled=*/true, /*AcrossEmptyLines=*/true, - /*AcrossComments=*/false, /*AlignCompound=*/false, - /*AlignFunctionDeclarations=*/true, - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); - IO.enumCase(Value, "AcrossComments", - FormatStyle::AlignConsecutiveStyle( - {/*Enabled=*/true, /*AcrossEmptyLines=*/false, - /*AcrossComments=*/true, /*AlignCompound=*/false, - /*AlignFunctionDeclarations=*/true, - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); - IO.enumCase(Value, "AcrossEmptyLinesAndComments", - FormatStyle::AlignConsecutiveStyle( - {/*Enabled=*/true, /*AcrossEmptyLines=*/true, - /*AcrossComments=*/true, /*AlignCompound=*/false, - /*AlignFunctionDeclarations=*/true, - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); + IO.enumCase( + Value, "Consecutive", + FormatStyle::AlignConsecutiveStyle( + {/*Enabled=*/true, /*AcrossEmptyLines=*/false, + /*AcrossComments=*/false, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/true, + /*AlignFunctionDeclarations=*/true, + /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/true, /*PadOperators=*/true})); + IO.enumCase( + Value, "AcrossEmptyLines", + FormatStyle::AlignConsecutiveStyle( + {/*Enabled=*/true, /*AcrossEmptyLines=*/true, + /*AcrossComments=*/false, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/true, + /*AlignFunctionDeclarations=*/true, + /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/true, /*PadOperators=*/true})); + IO.enumCase( + Value, "AcrossComments", + FormatStyle::AlignConsecutiveStyle( + {/*Enabled=*/true, /*AcrossEmptyLines=*/false, + /*AcrossComments=*/true, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/true, + /*AlignFunctionDeclarations=*/true, + /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/true, /*PadOperators=*/true})); + IO.enumCase( + Value, "AcrossEmptyLinesAndComments", + FormatStyle::AlignConsecutiveStyle( + {/*Enabled=*/true, /*AcrossEmptyLines=*/true, + /*AcrossComments=*/true, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/true, + /*AlignFunctionDeclarations=*/true, + /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/true, /*PadOperators=*/true})); // For backward compatibility. - IO.enumCase(Value, "true", - FormatStyle::AlignConsecutiveStyle( - {/*Enabled=*/true, /*AcrossEmptyLines=*/false, - /*AcrossComments=*/false, /*AlignCompound=*/false, - /*AlignFunctionDeclarations=*/true, - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); + IO.enumCase( + Value, "true", + FormatStyle::AlignConsecutiveStyle( + {/*Enabled=*/true, /*AcrossEmptyLines=*/false, + /*AcrossComments=*/false, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/true, + /*AlignFunctionDeclarations=*/true, + /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/true, /*PadOperators=*/true})); IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({})); } @@ -87,9 +102,13 @@ template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> { IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines); IO.mapOptional("AcrossComments", Value.AcrossComments); IO.mapOptional("AlignCompound", Value.AlignCompound); + IO.mapOptional("AlignFreeVariableDeclarations", + Value.AlignFreeVariableDeclarations); IO.mapOptional("AlignFunctionDeclarations", Value.AlignFunctionDeclarations); IO.mapOptional("AlignFunctionPointers", Value.AlignFunctionPointers); + IO.mapOptional("AlignMemberVariableDeclarations", + Value.AlignMemberVariableDeclarations); IO.mapOptional("PadOperators", Value.PadOperators); } }; @@ -1555,7 +1574,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.AlignConsecutiveAssignments.PadOperators = true; LLVMStyle.AlignConsecutiveBitFields = {}; LLVMStyle.AlignConsecutiveDeclarations = {}; + LLVMStyle.AlignConsecutiveDeclarations.AlignFreeVariableDeclarations = true; LLVMStyle.AlignConsecutiveDeclarations.AlignFunctionDeclarations = true; + LLVMStyle.AlignConsecutiveDeclarations.AlignMemberVariableDeclarations = true; LLVMStyle.AlignConsecutiveMacros = {}; LLVMStyle.AlignConsecutiveShortCaseStatements = {}; LLVMStyle.AlignConsecutiveTableGenBreakingDAGArgColons = {}; diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index e04b0e7af10c0..3a94de29461d0 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -313,7 +313,7 @@ struct FormatToken { EndsBinaryExpression(false), PartOfMultiVariableDeclStmt(false), ContinuesLineCommentSection(false), Finalized(false), ClosesRequiresClause(false), EndsCppAttributeGroup(false), - BlockKind(BK_Unknown), Decision(FD_Unformatted), + IsInClassScope(false), BlockKind(BK_Unknown), Decision(FD_Unformatted), PackingKind(PPK_Inconclusive), TypeIsFinalized(false), Type(TT_Unknown) {} @@ -391,6 +391,10 @@ struct FormatToken { /// \c true if this token ends a group of C++ attributes. unsigned EndsCppAttributeGroup : 1; + /// \c true if this token is within a class-like scope and not within a + /// function inside that scope. + unsigned IsInClassScope : 1; + private: /// Contains the kind of block if this token is a brace. unsigned BlockKind : 2; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 4bfb803ebedf7..da7f50d5f7c2f 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1313,6 +1313,8 @@ class AnnotatingParser { } FormatToken *Tok = CurrentToken; next(); + if (!Scopes.empty() && Scopes.back() == ST_Class) + Tok->IsInClassScope = true; // In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal // operators. if (Tok->is(TT_VerilogTableItem)) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index cc3cc0f6906cc..2c4ad3d1dfbbc 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -1016,6 +1016,12 @@ void WhitespaceManager::alignConsecutiveDeclarations() { return Style.AlignConsecutiveDeclarations.AlignFunctionPointers; if (C.Tok->is(TT_FunctionDeclarationName)) return Style.AlignConsecutiveDeclarations.AlignFunctionDeclarations; + if (C.Tok->IsInClassScope && !Style.AlignConsecutiveDeclarations + .AlignMemberVariableDeclarations) + return false; + if (!C.Tok->IsInClassScope && + !Style.AlignConsecutiveDeclarations.AlignFreeVariableDeclarations) + return false; if (C.Tok->isNot(TT_StartOfName)) return false; if (C.Tok->Previous && diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index bb4d38bb741ec..1c63c3c580179 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -327,51 +327,63 @@ TEST(ConfigParseTest, ParsesConfiguration) { Style.FIELD.Enabled = true; \ CHECK_PARSE(#FIELD ": None", FIELD, \ FormatStyle::AlignConsecutiveStyle({})); \ - CHECK_PARSE( \ - #FIELD ": Consecutive", FIELD, \ - FormatStyle::AlignConsecutiveStyle( \ - {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ - /*AcrossComments=*/false, /*AlignCompound=*/false, \ - /*AlignFunctionDeclarations=*/true, \ - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \ - CHECK_PARSE( \ - #FIELD ": AcrossEmptyLines", FIELD, \ - FormatStyle::AlignConsecutiveStyle( \ - {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \ - /*AcrossComments=*/false, /*AlignCompound=*/false, \ - /*AlignFunctionDeclarations=*/true, \ - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \ - CHECK_PARSE( \ - #FIELD ": AcrossComments", FIELD, \ - FormatStyle::AlignConsecutiveStyle( \ - {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ - /*AcrossComments=*/true, /*AlignCompound=*/false, \ - /*AlignFunctionDeclarations=*/true, \ - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \ - CHECK_PARSE( \ - #FIELD ": AcrossEmptyLinesAndComments", FIELD, \ - FormatStyle::AlignConsecutiveStyle( \ - {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \ - /*AcrossComments=*/true, /*AlignCompound=*/false, \ - /*AlignFunctionDeclarations=*/true, \ - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \ + CHECK_PARSE(#FIELD ": Consecutive", FIELD, \ + FormatStyle::AlignConsecutiveStyle( \ + {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ + /*AcrossComments=*/false, /*AlignCompound=*/false, \ + /*AlignFreeVariableDeclarations=*/true, \ + /*AlignFunctionDeclarations=*/true, \ + /*AlignFunctionPointers=*/false, \ + /*AlgnMemberVariableDeclarations=*/true, \ + /*PadOperators=*/true})); \ + CHECK_PARSE(#FIELD ": AcrossEmptyLines", FIELD, \ + FormatStyle::AlignConsecutiveStyle( \ + {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \ + /*AcrossComments=*/false, /*AlignCompound=*/false, \ + /*AlignFreeVariableDeclarations=*/true, \ + /*AlignFunctionDeclarations=*/true, \ + /*AlignFunctionPointers=*/false, \ + /*AlgnMemberVariableDeclarations=*/true, \ + /*PadOperators=*/true})); \ + CHECK_PARSE(#FIELD ": AcrossComments", FIELD, \ + FormatStyle::AlignConsecutiveStyle( \ + {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ + /*AcrossComments=*/true, /*AlignCompound=*/false, \ + /*AlignFreeVariableDeclarations=*/true, \ + /*AlignFunctionDeclarations=*/true, \ + /*AlignFunctionPointers=*/false, \ + /*AlgnMemberVariableDeclarations=*/true, \ + /*PadOperators=*/true})); \ + CHECK_PARSE(#FIELD ": AcrossEmptyLinesAndComments", FIELD, \ + FormatStyle::AlignConsecutiveStyle( \ + {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \ + /*AcrossComments=*/true, /*AlignCompound=*/false, \ + /*AlignFreeVariableDeclarations=*/true, \ + /*AlignFunctionDeclarations=*/true, \ + /*AlignFunctionPointers=*/false, \ + /*AlgnMemberVariableDeclarations=*/true, \ + /*PadOperators=*/true})); \ /* For backwards compability, false / true should still parse */ \ CHECK_PARSE(#FIELD ": false", FIELD, \ FormatStyle::AlignConsecutiveStyle({})); \ - CHECK_PARSE( \ - #FIELD ": true", FIELD, \ - FormatStyle::AlignConsecutiveStyle( \ - {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ - /*AcrossComments=*/false, /*AlignCompound=*/false, \ - /*AlignFunctionDeclarations=*/true, \ - /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \ + CHECK_PARSE(#FIELD ": true", FIELD, \ + FormatStyle::AlignConsecutiveStyle( \ + {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ + /*AcrossComments=*/false, /*AlignCompound=*/false, \ + /*AlignFreeVariableDeclarations=*/true, \ + /*AlignFunctionDeclarations=*/true, \ + /*AlignFunctionPointers=*/false, \ + /*AlgnMemberVariableDeclarations=*/true, \ + /*PadOperators=*/true})); \ \ CHECK_PARSE_NESTED_BOOL(FIELD, Enabled); \ CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines); \ CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments); \ CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound); \ + CHECK_PARSE_NESTED_BOOL(FIELD, AlignFreeVariableDeclarations); \ CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations); \ CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers); \ + CHECK_PARSE_NESTED_BOOL(FIELD, AlignMemberVariableDeclarations); \ CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators); \ } while (false) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 7d550143be5df..1b4fa57bd0dfb 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -20323,6 +20323,61 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "void f2(void);\n" "size_t f3(void);", Alignment); + + Alignment.AlignConsecutiveDeclarations.AlignFreeVariableDeclarations = false; + verifyFormat("int func() { //\n" + " int local1;\n" + " unsigned local2;\n" + "}\n" + "class Z {\n" + " int member1;\n" + " unsigned member2;\n" + " int funcInClass() {\n" + " int localInClass1;\n" + " unsigned localInClass2;\n" + " }\n" + "};\n" + "int global1;\n" + "unsigned global2;", + Alignment); + + Alignment.AlignConsecutiveDeclarations.AlignFreeVariableDeclarations = true; + Alignment.AlignConsecutiveDeclarations.AlignMemberVariableDeclarations = + false; + verifyFormat("int func() { //\n" + " int local1;\n" + " unsigned local2;\n" + "}\n" + "class Z {\n" + " int member1;\n" + " unsigned member2;\n" + " int funcInClass() {\n" + " int localInClass1;\n" + " unsigned localInClass2;\n" + " }\n" + "};\n" + "int global1;\n" + "unsigned global2;", + Alignment); + + Alignment.AlignConsecutiveDeclarations.AlignFreeVariableDeclarations = false; + Alignment.AlignConsecutiveDeclarations.AlignMemberVariableDeclarations = + false; + verifyFormat("int func() { //\n" + " int local1;\n" + " unsigned local2;\n" + "}\n" + "class Z {\n" + " int member1;\n" + " unsigned member2;\n" + " int funcInClass() {\n" + " int localInClass1;\n" + " unsigned localInClass2;\n" + " }\n" + "};\n" + "int global1;\n" + "unsigned global2;", + Alignment); } TEST_F(FormatTest, AlignConsecutiveShortCaseStatements) { @@ -20566,15 +20621,19 @@ TEST_F(FormatTest, AlignWithLineBreaks) { FormatStyle::AlignConsecutiveStyle( {/*Enabled=*/false, /*AcrossEmptyLines=*/false, /*AcrossComments=*/false, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/false, /*AlignFunctionDeclarations=*/false, /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/false, /*PadOperators=*/true})); EXPECT_EQ(Style.AlignConsecutiveDeclarations, FormatStyle::AlignConsecutiveStyle( {/*Enabled=*/false, /*AcrossEmptyLines=*/false, /*AcrossComments=*/false, /*AlignCompound=*/false, + /*AlignFreeVariableDeclarations=*/true, /*AlignFunctionDeclarations=*/true, /*AlignFunctionPointers=*/false, + /*AlignMemberVariableDeclarations=*/true, /*PadOperators=*/false})); verifyFormat("void foo() {\n" " int myVar = 5;\n" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
