https://github.com/DaanDeMeyer updated https://github.com/llvm/llvm-project/pull/169160
>From e0700f1508d344a957e713ad033aa47c96bc851c Mon Sep 17 00:00:00 2001 From: Daan De Meyer <[email protected]> Date: Fri, 21 Nov 2025 23:11:45 +0100 Subject: [PATCH 1/2] [clang-format][NFC] Upgrade PointerAlignment option to a struct This allows adding other suboptions e.g. ReturnType for #136597. --- clang/docs/ClangFormatStyleOptions.rst | 107 +++++++++++++----- clang/include/clang/Format/Format.h | 59 +++++++++- clang/lib/Format/Format.cpp | 63 +++++++++-- clang/lib/Format/TokenAnnotator.cpp | 16 +-- clang/lib/Format/WhitespaceManager.cpp | 10 +- clang/unittests/Format/ConfigParseTest.cpp | 34 ++++-- clang/unittests/Format/FormatTest.cpp | 123 +++++++++++---------- 7 files changed, 286 insertions(+), 126 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 94d6f0d27619f..ab21290260005 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5668,31 +5668,54 @@ the configuration (without a prefix: ``Auto``). .. _PointerAlignment: -**PointerAlignment** (``PointerAlignmentStyle``) :versionbadge:`clang-format 3.7` :ref:`¶ <PointerAlignment>` +**PointerAlignment** (``PointerAlignmentOptions``) :versionbadge:`clang-format 3.7` :ref:`¶ <PointerAlignment>` Pointer and reference alignment style. - Possible values: + Acceptable values (configured as a single string or with suboptions): + * ``Left`` + * ``Right`` + * ``Middle`` - * ``PAS_Left`` (in configuration: ``Left``) - Align pointer to the left. + For example, to configure left pointer alignment: - .. code-block:: c++ + .. code-block:: yaml - int* a; + PointerAlignment: Left - * ``PAS_Right`` (in configuration: ``Right``) - Align pointer to the right. + # or - .. code-block:: c++ + PointerAlignment: + Default: Left + + Nested configuration flags: - int *a; + Pointer and reference alignment options. - * ``PAS_Middle`` (in configuration: ``Middle``) - Align pointer in the middle. + * ``PointerAlignmentStyle Default`` + The default alignment for pointers and references. - .. code-block:: c++ + Possible values: + + * ``PAS_Left`` (in configuration: ``Left``) + Align pointer to the left. + + .. code-block:: c++ + + int* a; + + * ``PAS_Right`` (in configuration: ``Right``) + Align pointer to the right. + + .. code-block:: c++ + + int *a; + + * ``PAS_Middle`` (in configuration: ``Middle``) + Align pointer in the middle. + + .. code-block:: c++ - int * a; + int * a; @@ -5824,34 +5847,58 @@ the configuration (without a prefix: ``Auto``). .. _ReferenceAlignment: -**ReferenceAlignment** (``ReferenceAlignmentStyle``) :versionbadge:`clang-format 13` :ref:`¶ <ReferenceAlignment>` +**ReferenceAlignment** (``ReferenceAlignmentOptions``) :versionbadge:`clang-format 13` :ref:`¶ <ReferenceAlignment>` Reference alignment style (overrides ``PointerAlignment`` for references). - Possible values: + Acceptable values (configured as a single string or with suboptions): + * ``Pointer`` + * ``Left`` + * ``Right`` + * ``Middle`` - * ``RAS_Pointer`` (in configuration: ``Pointer``) - Align reference like ``PointerAlignment``. + For example, to configure right reference alignment: - * ``RAS_Left`` (in configuration: ``Left``) - Align reference to the left. + .. code-block:: yaml - .. code-block:: c++ + ReferenceAlignment: Right - int& a; + # or - * ``RAS_Right`` (in configuration: ``Right``) - Align reference to the right. + ReferenceAlignment: + Default: Right - .. code-block:: c++ + Nested configuration flags: - int &a; + Reference alignment options. - * ``RAS_Middle`` (in configuration: ``Middle``) - Align reference in the middle. + * ``ReferenceAlignmentStyle Default`` + The default alignment for references. - .. code-block:: c++ + Possible values: + + * ``RAS_Pointer`` (in configuration: ``Pointer``) + Align reference like ``PointerAlignment``. + + * ``RAS_Left`` (in configuration: ``Left``) + Align reference to the left. + + .. code-block:: c++ + + int& a; + + * ``RAS_Right`` (in configuration: ``Right``) + Align reference to the right. + + .. code-block:: c++ + + int &a; + + * ``RAS_Middle`` (in configuration: ``Middle``) + Align reference in the middle. + + .. code-block:: c++ - int & a; + int & a; diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index b6f124f948b59..2cd446366cfa4 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4036,9 +4036,36 @@ struct FormatStyle { PAS_Middle }; + /// Pointer and reference alignment options. + struct PointerAlignmentOptions { + /// The default alignment for pointers and references. + PointerAlignmentStyle Default; + bool operator==(const PointerAlignmentOptions &R) const { + return Default == R.Default; + } + bool operator!=(const PointerAlignmentOptions &R) const { + return !(*this == R); + } + }; + /// Pointer and reference alignment style. + /// + /// Acceptable values (configured as a single string or with suboptions): + /// * ``Left`` + /// * ``Right`` + /// * ``Middle`` + /// + /// For example, to configure left pointer alignment: + /// \code{.yaml} + /// PointerAlignment: Left + /// + /// # or + /// + /// PointerAlignment: + /// Default: Left + /// \endcode /// \version 3.7 - PointerAlignmentStyle PointerAlignment; + PointerAlignmentOptions PointerAlignment; /// The number of columns to use for indentation of preprocessor statements. /// When set to -1 (default) ``IndentWidth`` is used also for preprocessor @@ -4208,9 +4235,37 @@ struct FormatStyle { RAS_Middle }; + /// Reference alignment options. + struct ReferenceAlignmentOptions { + /// The default alignment for references. + ReferenceAlignmentStyle Default; + bool operator==(const ReferenceAlignmentOptions &R) const { + return Default == R.Default; + } + bool operator!=(const ReferenceAlignmentOptions &R) const { + return !(*this == R); + } + }; + /// Reference alignment style (overrides ``PointerAlignment`` for references). + /// + /// Acceptable values (configured as a single string or with suboptions): + /// * ``Pointer`` + /// * ``Left`` + /// * ``Right`` + /// * ``Middle`` + /// + /// For example, to configure right reference alignment: + /// \code{.yaml} + /// ReferenceAlignment: Right + /// + /// # or + /// + /// ReferenceAlignment: + /// Default: Right + /// \endcode /// \version 13 - ReferenceAlignmentStyle ReferenceAlignment; + ReferenceAlignmentOptions ReferenceAlignment; // clang-format off /// Types of comment reflow style. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 9bbb33cb14502..b82c387df877d 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -541,10 +541,32 @@ template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> { IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle); IO.enumCase(Value, "Left", FormatStyle::PAS_Left); IO.enumCase(Value, "Right", FormatStyle::PAS_Right); + } +}; + +template <> struct MappingTraits<FormatStyle::PointerAlignmentOptions> { + static void enumInput(IO &IO, FormatStyle::PointerAlignmentOptions &Value) { + IO.enumCase(Value, "Middle", + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Middle})); + IO.enumCase(Value, "Left", + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Left})); + IO.enumCase(Value, "Right", + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); // For backward compatibility. - IO.enumCase(Value, "true", FormatStyle::PAS_Left); - IO.enumCase(Value, "false", FormatStyle::PAS_Right); + IO.enumCase(Value, "true", + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Left})); + IO.enumCase(Value, "false", + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); + } + + static void mapping(IO &IO, FormatStyle::PointerAlignmentOptions &Value) { + IO.mapOptional("Default", Value.Default); } }; @@ -589,6 +611,27 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ReflowCommentsStyle> { } }; +template <> struct MappingTraits<FormatStyle::ReferenceAlignmentOptions> { + static void enumInput(IO &IO, FormatStyle::ReferenceAlignmentOptions &Value) { + IO.enumCase(Value, "Pointer", + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Pointer})); + IO.enumCase(Value, "Middle", + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Middle})); + IO.enumCase(Value, "Left", + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Left})); + IO.enumCase(Value, "Right", + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Right})); + } + + static void mapping(IO &IO, FormatStyle::ReferenceAlignmentOptions &Value) { + IO.mapOptional("Default", Value.Default); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> { static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) { @@ -1785,10 +1828,10 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.ObjCSpaceAfterProperty = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack; - LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; + LLVMStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; LLVMStyle.PPIndentWidth = -1; LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave; - LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; + LLVMStyle.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer}; LLVMStyle.ReflowComments = FormatStyle::RCS_Always; LLVMStyle.RemoveBracesLLVM = false; LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false; @@ -1910,7 +1953,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.ObjCSpaceAfterProperty = false; GoogleStyle.ObjCSpaceBeforeProtocolList = true; GoogleStyle.PackConstructorInitializers = FormatStyle::PCIS_NextLine; - GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; + GoogleStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; GoogleStyle.RawStringFormats = { { FormatStyle::LK_Cpp, @@ -2105,7 +2148,7 @@ FormatStyle getMozillaStyle() { MozillaStyle.ObjCSpaceAfterProperty = true; MozillaStyle.ObjCSpaceBeforeProtocolList = false; MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; - MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; + MozillaStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; MozillaStyle.SpaceAfterTemplateKeyword = false; return MozillaStyle; } @@ -2128,7 +2171,7 @@ FormatStyle getWebKitStyle() { Style.NamespaceIndentation = FormatStyle::NI_Inner; Style.ObjCBlockIndentWidth = 4; Style.ObjCSpaceAfterProperty = true; - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; Style.SpaceBeforeCpp11BracedList = true; Style.SpaceInEmptyBraces = FormatStyle::SIEB_Always; return Style; @@ -2862,10 +2905,10 @@ class Formatter : public TokenAnalyzer { if (Style.DerivePointerAlignment) { const auto NetRightCount = countVariableAlignments(AnnotatedLines); if (NetRightCount > 0) - Style.PointerAlignment = FormatStyle::PAS_Right; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; else if (NetRightCount < 0) - Style.PointerAlignment = FormatStyle::PAS_Left; - Style.ReferenceAlignment = FormatStyle::RAS_Pointer; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer}; } if (Style.Standard == FormatStyle::LS_Auto) { Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index cb41756c56bf7..f48a02c49c562 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4732,7 +4732,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (BeforeLeft->is(tok::coloncolon)) { if (Left.isNot(tok::star)) return false; - assert(Style.PointerAlignment != FormatStyle::PAS_Right); + assert(Style.PointerAlignment.Default != FormatStyle::PAS_Right); if (!Right.startsSequence(tok::identifier, tok::r_paren)) return true; assert(Right.Next); @@ -4744,7 +4744,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, // Ensure right pointer alignment with ellipsis e.g. int *...P if (Left.is(tok::ellipsis) && BeforeLeft && BeforeLeft->isPointerOrReference()) { - return Style.PointerAlignment != FormatStyle::PAS_Right; + return Style.PointerAlignment.Default != FormatStyle::PAS_Right; } if (Right.is(tok::star) && Left.is(tok::l_paren)) @@ -4782,9 +4782,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, // dependent on PointerAlignment style. if (Previous) { if (Previous->endsSequence(tok::kw_operator)) - return Style.PointerAlignment != FormatStyle::PAS_Left; + return Style.PointerAlignment.Default != FormatStyle::PAS_Left; if (Previous->isOneOf(tok::kw_const, tok::kw_volatile)) { - return (Style.PointerAlignment != FormatStyle::PAS_Left) || + return (Style.PointerAlignment.Default != FormatStyle::PAS_Left) || (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After) || (Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both); @@ -6543,9 +6543,9 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const { FormatStyle::PointerAlignmentStyle TokenAnnotator::getTokenReferenceAlignment(const FormatToken &Reference) const { assert(Reference.isOneOf(tok::amp, tok::ampamp)); - switch (Style.ReferenceAlignment) { + switch (Style.ReferenceAlignment.Default) { case FormatStyle::RAS_Pointer: - return Style.PointerAlignment; + return Style.PointerAlignment.Default; case FormatStyle::RAS_Left: return FormatStyle::PAS_Left; case FormatStyle::RAS_Right: @@ -6554,7 +6554,7 @@ TokenAnnotator::getTokenReferenceAlignment(const FormatToken &Reference) const { return FormatStyle::PAS_Middle; } assert(0); //"Unhandled value of ReferenceAlignment" - return Style.PointerAlignment; + return Style.PointerAlignment.Default; } FormatStyle::PointerAlignmentStyle @@ -6563,7 +6563,7 @@ TokenAnnotator::getTokenPointerOrReferenceAlignment( if (PointerOrReference.isOneOf(tok::amp, tok::ampamp)) return getTokenReferenceAlignment(PointerOrReference); assert(PointerOrReference.is(tok::star)); - return Style.PointerAlignment; + return Style.PointerAlignment.Default; } } // namespace format diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 94ccf9eb7842a..3834f3ca743d6 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -384,14 +384,14 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, // If PointerAlignment is PAS_Right, keep *s or &s next to the token, // except if the token is equal, then a space is needed. - if ((Style.PointerAlignment == FormatStyle::PAS_Right || - Style.ReferenceAlignment == FormatStyle::RAS_Right) && + if ((Style.PointerAlignment.Default == FormatStyle::PAS_Right || + Style.ReferenceAlignment.Default == FormatStyle::RAS_Right) && CurrentChange.Spaces != 0 && CurrentChange.Tok->isNoneOf(tok::equal, tok::r_paren, TT_TemplateCloser)) { const bool ReferenceNotRightAligned = - Style.ReferenceAlignment != FormatStyle::RAS_Right && - Style.ReferenceAlignment != FormatStyle::RAS_Pointer; + Style.ReferenceAlignment.Default != FormatStyle::RAS_Right && + Style.ReferenceAlignment.Default != FormatStyle::RAS_Pointer; for (int Previous = i - 1; Previous >= 0 && Changes[Previous].Tok->is(TT_PointerOrReference); --Previous) { @@ -399,7 +399,7 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, if (Changes[Previous].Tok->isNot(tok::star)) { if (ReferenceNotRightAligned) continue; - } else if (Style.PointerAlignment != FormatStyle::PAS_Right) { + } else if (Style.PointerAlignment.Default != FormatStyle::PAS_Right) { continue; } Changes[Previous + 1].Spaces -= Shift; diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index d578fa7a1a1e8..882f7b1342cc4 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -391,29 +391,39 @@ TEST(ConfigParseTest, ParsesConfiguration) { #undef CHECK_ALIGN_CONSECUTIVE - Style.PointerAlignment = FormatStyle::PAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; CHECK_PARSE("PointerAlignment: Left", PointerAlignment, - FormatStyle::PAS_Left); + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Left})); CHECK_PARSE("PointerAlignment: Right", PointerAlignment, - FormatStyle::PAS_Right); + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, - FormatStyle::PAS_Middle); - Style.ReferenceAlignment = FormatStyle::RAS_Middle; + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Middle})); + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Middle}; CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment, - FormatStyle::RAS_Pointer); + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Pointer})); CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment, - FormatStyle::RAS_Left); + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Left})); CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment, - FormatStyle::RAS_Right); + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Right})); CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment, - FormatStyle::RAS_Middle); + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Middle})); // For backward compatibility: CHECK_PARSE("PointerBindsToType: Left", PointerAlignment, - FormatStyle::PAS_Left); + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Left})); CHECK_PARSE("PointerBindsToType: Right", PointerAlignment, - FormatStyle::PAS_Right); + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment, - FormatStyle::PAS_Middle); + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Middle})); Style.ReflowComments = FormatStyle::RCS_Always; CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 81fa7d1d11aa4..741a6e1740af6 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,8 +2047,11 @@ TEST_F(FormatTest, ElseIf) { TEST_F(FormatTest, SeparatePointerReferenceAlignment) { FormatStyle Style = getLLVMStyle(); - EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right); - EXPECT_EQ(Style.ReferenceAlignment, FormatStyle::RAS_Pointer); + EXPECT_EQ(Style.PointerAlignment, FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); + EXPECT_EQ(Style.ReferenceAlignment, + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Pointer})); verifyFormat("int *f1(int *a, int &b, int &&c);", Style); verifyFormat("int &f2(int &&c, int *a, int &b);", Style); verifyFormat("int &&f3(int &b, int &&c, int *a);", Style); @@ -2104,7 +2107,7 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "Const unsigned h;", Style); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("int* f1(int* a, int& b, int&& c);", Style); verifyFormat("int& f2(int&& c, int* a, int& b);", Style); verifyFormat("int&& f3(int& b, int&& c, int* a);", Style); @@ -2162,8 +2165,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "Const unsigned h;", Style); - Style.PointerAlignment = FormatStyle::PAS_Right; - Style.ReferenceAlignment = FormatStyle::RAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Left}; verifyFormat("int *f1(int *a, int& b, int&& c);", Style); verifyFormat("int& f2(int&& c, int *a, int& b);", Style); verifyFormat("int&& f3(int& b, int&& c, int *a);", Style); @@ -2200,8 +2203,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "Const unsigned h;", Style); - Style.PointerAlignment = FormatStyle::PAS_Left; - Style.ReferenceAlignment = FormatStyle::RAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Middle}; verifyFormat("int* f1(int* a, int & b, int && c);", Style); verifyFormat("int & f2(int && c, int* a, int & b);", Style); verifyFormat("int && f3(int & b, int && c, int* a);", Style); @@ -2253,8 +2256,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "Const unsigned h;", Style); - Style.PointerAlignment = FormatStyle::PAS_Middle; - Style.ReferenceAlignment = FormatStyle::RAS_Right; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Right}; verifyFormat("int * f1(int * a, int &b, int &&c);", Style); verifyFormat("int &f2(int &&c, int * a, int &b);", Style); verifyFormat("int &&f3(int &b, int &&c, int * a);", Style); @@ -2376,7 +2379,7 @@ TEST_F(FormatTest, FormatsForLoop) { NoBinPacking); FormatStyle AlignLeft = getLLVMStyle(); - AlignLeft.PointerAlignment = FormatStyle::PAS_Left; + AlignLeft.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("for (A* a = start; a < end; ++a, ++value) {\n}", AlignLeft); } @@ -8638,7 +8641,7 @@ TEST_F(FormatTest, BreaksFunctionDeclarations) { " void f();"); auto Style = getLLVMStyle(); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaa* const aaaaaaaaaaaa) {}", Style); @@ -9975,7 +9978,7 @@ TEST_F(FormatTest, DeclarationsOfMultipleVariables) { " ***c = ccccccccccccccccccc, ***d = ddddddddddddddd;"); FormatStyle Style = getGoogleStyle(); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; Style.DerivePointerAlignment = false; verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaa,\n" @@ -11465,15 +11468,16 @@ TEST_F(FormatTest, UnderstandsPointersToMembers) { " aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); FormatStyle Style = getLLVMStyle(); - EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right); + EXPECT_EQ(Style.PointerAlignment, FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); verifyFormat("typedef bool *(Class::*Member)() const;", Style); verifyFormat("void f(int A::*p) { int A::*v = &A::B; }", Style); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("typedef bool* (Class::*Member)() const;", Style); verifyFormat("void f(int A::* p) { int A::* v = &A::B; }", Style); - Style.PointerAlignment = FormatStyle::PAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("typedef bool * (Class::*Member)() const;", Style); verifyFormat("void f(int A::* p) { int A::* v = &A::B; }", Style); } @@ -11533,7 +11537,7 @@ TEST_F(FormatTest, UnderstandsUnaryOperators) { // Check that * is not treated as a binary operator when we set // PointerAlignment as PAS_Left after a keyword and not a declaration. FormatStyle PASLeftStyle = getLLVMStyle(); - PASLeftStyle.PointerAlignment = FormatStyle::PAS_Left; + PASLeftStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("co_return *a;", PASLeftStyle); verifyFormat("co_await *a;", PASLeftStyle); verifyFormat("co_yield *a", PASLeftStyle); @@ -11661,7 +11665,7 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("template <typename T> void operator=(T) && {}"); FormatStyle AlignLeft = getLLVMStyle(); - AlignLeft.PointerAlignment = FormatStyle::PAS_Left; + AlignLeft.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("void A::b() && {}", AlignLeft); verifyFormat("void A::b() && noexcept {}", AlignLeft); verifyFormat("Deleted& operator=(const Deleted&) & = default;", AlignLeft); @@ -11693,7 +11697,7 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("for (foo<void() &&>& cb : X)", AlignLeft); FormatStyle AlignMiddle = getLLVMStyle(); - AlignMiddle.PointerAlignment = FormatStyle::PAS_Middle; + AlignMiddle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("void A::b() && {}", AlignMiddle); verifyFormat("void A::b() && noexcept {}", AlignMiddle); verifyFormat("Deleted & operator=(const Deleted &) & = default;", @@ -11776,7 +11780,7 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { FormatStyle AlignLeftBreakTemplate = getLLVMStyle(); AlignLeftBreakTemplate.BreakTemplateDeclarations = FormatStyle::BTDS_Yes; - AlignLeftBreakTemplate.PointerAlignment = FormatStyle::PAS_Left; + AlignLeftBreakTemplate.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("struct f {\n" " template <class T>\n" @@ -11860,19 +11864,20 @@ TEST_F(FormatTest, PointerAlignmentFallback) { "int *q;\n" "int * r;"); - EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right); + EXPECT_EQ(Style.PointerAlignment, FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right})); verifyFormat("int *p;\n" "int *q;\n" "int *r;", Code, Style); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("int* p;\n" "int* q;\n" "int* r;", Code, Style); - Style.PointerAlignment = FormatStyle::PAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("int * p;\n" "int * q;\n" "int * r;", @@ -12068,7 +12073,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { "void f(int i = 0, SomeType** temps = NULL);"); FormatStyle Left = getLLVMStyle(); - Left.PointerAlignment = FormatStyle::PAS_Left; + Left.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("x = *a(x) = *a(y);", Left); verifyFormat("for (;; *a = b) {\n}", Left); verifyFormat("return *this += 1;", Left); @@ -12214,7 +12219,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { getGoogleStyleWithColumns(68)); FormatStyle Style = getLLVMStyle(); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("struct {\n" "}* ptr;", Style); @@ -12238,7 +12243,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { Style); verifyFormat("bool b = 3 == int{3} && true;"); - Style.PointerAlignment = FormatStyle::PAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("struct {\n" "} * ptr;", Style); @@ -12258,7 +12263,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { "} && ptr = {};", Style); - Style.PointerAlignment = FormatStyle::PAS_Right; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; verifyFormat("struct {\n" "} *ptr;", Style); @@ -12278,7 +12283,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { "} &&ptr = {};", Style); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("delete[] *ptr;", Style); verifyFormat("delete[] **ptr;", Style); verifyFormat("delete[] *(ptr);", Style); @@ -12369,7 +12374,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("foo<a<b && c> d> v;"); FormatStyle PointerMiddle = getLLVMStyle(); - PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle; + PointerMiddle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("delete *x;", PointerMiddle); verifyFormat("int * x;", PointerMiddle); verifyFormat("int *[] x;", PointerMiddle); @@ -12476,7 +12481,7 @@ TEST_F(FormatTest, UnderstandsAttributes) { auto Style = getLLVMStyleWithColumns(60); Style.AttributeMacros.push_back("my_fancy_attr"); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("void foo(const MyLongTypeNameeeeeeeeeeeee* my_fancy_attr\n" " testttttttttt);", Style); @@ -12504,7 +12509,7 @@ TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) { // determine that the expression is a cast to a pointer type. FormatStyle LongPointerRight = getLLVMStyleWithColumns(999); FormatStyle LongPointerLeft = getLLVMStyleWithColumns(999); - LongPointerLeft.PointerAlignment = FormatStyle::PAS_Left; + LongPointerLeft.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; StringRef AllQualifiers = "const volatile restrict __attribute__((foo)) _Nonnull _Null_unspecified " "_Nullable [[clang::attr]] __ptr32 __ptr64 __capability"; @@ -12640,12 +12645,12 @@ TEST_F(FormatTest, UnderstandsEllipsis) { verifyFormat("template <int *...PP> a;", Style); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("template <class... Ts> void Foo(Ts*... ts) {}", Style); verifyFormat("template <int*... PP> a;", Style); - Style.PointerAlignment = FormatStyle::PAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("template <int *... PP> a;", Style); } @@ -16253,15 +16258,15 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { FormatStyle TabAlignment = Tab; TabAlignment.AlignConsecutiveDeclarations.Enabled = true; - TabAlignment.PointerAlignment = FormatStyle::PAS_Left; + TabAlignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("unsigned long long big;\n" "char*\t\t ptr;", TabAlignment); - TabAlignment.PointerAlignment = FormatStyle::PAS_Middle; + TabAlignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("unsigned long long big;\n" "char *\t\t ptr;", TabAlignment); - TabAlignment.PointerAlignment = FormatStyle::PAS_Right; + TabAlignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; verifyFormat("unsigned long long big;\n" "char\t\t *ptr;", TabAlignment); @@ -16309,19 +16314,19 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { Tab); TabAlignment.UseTab = FormatStyle::UT_ForIndentation; - TabAlignment.PointerAlignment = FormatStyle::PAS_Left; + TabAlignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("void f() {\n" "\tunsigned long long big;\n" "\tchar* ptr;\n" "}", TabAlignment); - TabAlignment.PointerAlignment = FormatStyle::PAS_Middle; + TabAlignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("void f() {\n" "\tunsigned long long big;\n" "\tchar * ptr;\n" "}", TabAlignment); - TabAlignment.PointerAlignment = FormatStyle::PAS_Right; + TabAlignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; verifyFormat("void f() {\n" "\tunsigned long long big;\n" "\tchar *ptr;\n" @@ -18227,13 +18232,13 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeColon) { TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) { FormatStyle Style = getLLVMStyle(); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default; verifyFormat("void* const* x = NULL;", Style); #define verifyQualifierSpaces(Code, Pointers, Qualifiers) \ do { \ - Style.PointerAlignment = FormatStyle::Pointers; \ + Style.PointerAlignment = {/*Default=*/FormatStyle::Pointers}; \ Style.SpaceAroundPointerQualifiers = FormatStyle::Qualifiers; \ verifyFormat(Code, Style); \ } while (false) @@ -18279,7 +18284,7 @@ TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) { FormatStyle Spaces = getLLVMStyle(); Spaces.AttributeMacros.push_back("qualified"); - Spaces.PointerAlignment = FormatStyle::PAS_Right; + Spaces.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default; verifyFormat("SomeType *volatile *a = NULL;", Spaces); verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces); @@ -18294,7 +18299,7 @@ TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) { verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); // Check that SAPQ_Before doesn't result in extra spaces for PAS_Left. - Spaces.PointerAlignment = FormatStyle::PAS_Left; + Spaces.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Before; verifyFormat("SomeType* volatile* a = NULL;", Spaces); verifyFormat("SomeType* __attribute__((attr))* a = NULL;", Spaces); @@ -18310,7 +18315,7 @@ TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) { verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); // PAS_Middle should not have any noticeable changes even for SAPQ_Both - Spaces.PointerAlignment = FormatStyle::PAS_Middle; + Spaces.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_After; verifyFormat("SomeType * volatile * a = NULL;", Spaces); verifyFormat("SomeType * __attribute__((attr)) * a = NULL;", Spaces); @@ -19756,7 +19761,7 @@ TEST_F(FormatTest, AlignConsecutiveBitFields) { TEST_F(FormatTest, AlignConsecutiveDeclarations) { FormatStyle Alignment = getLLVMStyle(); Alignment.AlignConsecutiveMacros.Enabled = true; - Alignment.PointerAlignment = FormatStyle::PAS_Right; + Alignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; verifyFormat("float const a = 5;\n" "int oneTwoThree = 123;", Alignment); @@ -20023,7 +20028,7 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { // PAS_Left FormatStyle AlignmentLeft = Alignment; - AlignmentLeft.PointerAlignment = FormatStyle::PAS_Left; + AlignmentLeft.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("void SomeFunction(int parameter = 0) {\n" " int const i = 1;\n" " int* j = 2;\n" @@ -20097,7 +20102,7 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { // PAS_Middle FormatStyle AlignmentMiddle = Alignment; - AlignmentMiddle.PointerAlignment = FormatStyle::PAS_Middle; + AlignmentMiddle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("void SomeFunction(int parameter = 0) {\n" " int const i = 1;\n" " int * j = 2;\n" @@ -20313,14 +20318,14 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { Alignment.ColumnLimit = 80; // Bug 33507 - Alignment.PointerAlignment = FormatStyle::PAS_Middle; + Alignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat( "auto found = range::find_if(vsProducts, [&](auto * aProduct) {\n" " static const Version verVs2017;\n" " return true;\n" "});", Alignment); - Alignment.PointerAlignment = FormatStyle::PAS_Right; + Alignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; // See llvm.org/PR35641 Alignment.AlignConsecutiveDeclarations.Enabled = true; @@ -20337,7 +20342,7 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "foo(int a);", "DECOR1 /**/ int8_t /**/ DECOR2 /**/ foo (int a);", Style); - Alignment.PointerAlignment = FormatStyle::PAS_Left; + Alignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("unsigned int* a;\n" "int* b;\n" "unsigned int Const* c;\n" @@ -20353,7 +20358,7 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "Const unsigned h;", Alignment); - Alignment.PointerAlignment = FormatStyle::PAS_Middle; + Alignment.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("unsigned int * a;\n" "int * b;\n" "unsigned int Const * c;\n" @@ -25086,7 +25091,7 @@ TEST_F(FormatTest, StructuredBindings) { // Make sure we don't mistake structured bindings for lambdas. FormatStyle PointerMiddle = getLLVMStyle(); - PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle; + PointerMiddle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyGoogleFormat("auto [a1, b]{A * i};"); verifyFormat("auto [a2, b]{A * i};"); verifyFormat("auto [a3, b]{A * i};", PointerMiddle); @@ -25330,7 +25335,7 @@ TEST_F(FormatTest, TypenameMacros) { verifyFormat("vector<LIST(uint64_t) *attr> x;", Macros); verifyFormat("vector<LIST(uint64_t) *const> f(LIST(uint64_t) *arg);", Macros); - Macros.PointerAlignment = FormatStyle::PAS_Left; + Macros.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("STACK_OF(int)* a;", Macros); verifyFormat("STACK_OF(int*)* a;", Macros); verifyFormat("x = (STACK_OF(uint64_t))*a;", Macros); @@ -25361,7 +25366,7 @@ TEST_F(FormatTest, AtomicQualifier) { verifyFormat("_Atomic(uint64_t) *s(InitValue);"); verifyFormat("_Atomic(uint64_t) *s{InitValue};"); FormatStyle Style = getLLVMStyle(); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("_Atomic(uint64_t)* s(InitValue);", Style); verifyFormat("_Atomic(uint64_t)* s{InitValue};", Style); verifyFormat("_Atomic(int)* a;", Style); @@ -25424,9 +25429,9 @@ TEST_F(FormatTest, C11Generic) { TEST_F(FormatTest, AmbersandInLamda) { // Test case reported in https://bugs.llvm.org/show_bug.cgi?id=41899 FormatStyle AlignStyle = getLLVMStyle(); - AlignStyle.PointerAlignment = FormatStyle::PAS_Left; + AlignStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("auto lambda = [&a = a]() { a = 2; };", AlignStyle); - AlignStyle.PointerAlignment = FormatStyle::PAS_Right; + AlignStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; verifyFormat("auto lambda = [&a = a]() { a = 2; };", AlignStyle); } @@ -25554,7 +25559,7 @@ TEST_F(FormatTest, STLWhileNotDefineChed) { TEST_F(FormatTest, OperatorSpacing) { FormatStyle Style = getLLVMStyle(); - Style.PointerAlignment = FormatStyle::PAS_Right; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; verifyFormat("Foo::operator*();", Style); verifyFormat("Foo::operator void *();", Style); verifyFormat("Foo::operator void **();", Style); @@ -25610,7 +25615,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("operator const FooRight<Object> *&()", Style); verifyFormat("operator const FooRight<Object> *&&()", Style); - Style.PointerAlignment = FormatStyle::PAS_Left; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; verifyFormat("Foo::operator*();", Style); verifyFormat("Foo::operator**();", Style); verifyFormat("Foo::operator void*();", Style); @@ -25681,7 +25686,7 @@ TEST_F(FormatTest, OperatorSpacing) { verifyFormat("operator/*a*/ const /*b*/ Foo /*c*/<X> /*d*/ ::Bar<Y>*();", Style); - Style.PointerAlignment = FormatStyle::PAS_Middle; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; verifyFormat("Foo::operator*();", Style); verifyFormat("Foo::operator void *();", Style); verifyFormat("Foo::operator()(void *);", Style); @@ -27940,7 +27945,7 @@ TEST_F(FormatTest, BreakAfterAttributes) { "Foo &operator-(Foo &);", Style); - Style.ReferenceAlignment = FormatStyle::RAS_Left; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Left}; verifyFormat("[[nodiscard]]\n" "Foo& operator-(Foo&);", Style); >From 400c5fb9d824e14915129c09be6e43077c1e050f Mon Sep 17 00:00:00 2001 From: Daan De Meyer <[email protected]> Date: Sat, 22 Nov 2025 11:35:28 +0100 Subject: [PATCH 2/2] [clang-format] Allow custom pointer/ref alignment in return types I would like to adopt clang-format in systemd (https://github.com/systemd/systemd). One major blocker is that systemd right-aligns pointers by default, except in function return types, where they are left-aligned. Let's introduce a ReturnType customization for PointerAlignment and ReferenceAlignment that allows overriding the alignment used in return types. Fixes #136597 --- clang/docs/ClangFormatStyleOptions.rst | 60 ++++++++++ clang/include/clang/Format/Format.h | 29 ++++- clang/lib/Format/Format.cpp | 69 ++++++++--- clang/lib/Format/TokenAnnotator.cpp | 47 ++++++++ clang/unittests/Format/ConfigParseTest.cpp | 52 ++++++-- clang/unittests/Format/FormatTest.cpp | 131 ++++++++++++++++++++- 6 files changed, 351 insertions(+), 37 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ab21290260005..e08e22964691d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5718,6 +5718,36 @@ the configuration (without a prefix: ``Auto``). int * a; + * ``ReturnTypeAlignmentStyle ReturnType`` + The alignment for pointers in return types. + + Possible values: + + * ``RTAS_Default`` (in configuration: ``Default``) + Use default alignment. + + * ``RTAS_Left`` (in configuration: ``Left``) + Align pointer/reference to the left. + + .. code-block:: c++ + + int* a(void); + + * ``RTAS_Right`` (in configuration: ``Right``) + Align pointer/reference to the right. + + .. code-block:: c++ + + int * a(void); + + * ``RTAS_Middle`` (in configuration: ``Middle``) + Align pointer/reference in the middle. + + .. code-block:: c++ + + int *a(void); + + .. _QualifierAlignment: @@ -5901,6 +5931,36 @@ the configuration (without a prefix: ``Auto``). int & a; + * ``ReturnTypeAlignmentStyle ReturnType`` + The alignment for references in return types. + + Possible values: + + * ``RTAS_Default`` (in configuration: ``Default``) + Use default alignment. + + * ``RTAS_Left`` (in configuration: ``Left``) + Align pointer/reference to the left. + + .. code-block:: c++ + + int* a(void); + + * ``RTAS_Right`` (in configuration: ``Right``) + Align pointer/reference to the right. + + .. code-block:: c++ + + int * a(void); + + * ``RTAS_Middle`` (in configuration: ``Middle``) + Align pointer/reference in the middle. + + .. code-block:: c++ + + int *a(void); + + .. _ReflowComments: diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 2cd446366cfa4..a84a558ae3288 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4017,6 +4017,27 @@ struct FormatStyle { /// \version 3.7 unsigned PenaltyReturnTypeOnItsOwnLine; + /// \brief The pointer/reference alignment style for specialized cases. + enum SpecializedAlignmentStyle : int8_t { + /// Use default alignment. + SAS_Default, + /// Align pointer/reference to the left. + /// \code + /// int* a(void); + /// \endcode + SAS_Left, + /// Align pointer/reference to the right. + /// \code + /// int * a(void); + /// \endcode + SAS_Right, + /// Align pointer/reference in the middle. + /// \code + /// int *a(void); + /// \endcode + SAS_Middle + }; + /// The ``&``, ``&&`` and ``*`` alignment style. enum PointerAlignmentStyle : int8_t { /// Align pointer to the left. @@ -4040,8 +4061,10 @@ struct FormatStyle { struct PointerAlignmentOptions { /// The default alignment for pointers and references. PointerAlignmentStyle Default; + /// The alignment for pointers in return types. + SpecializedAlignmentStyle ReturnType; bool operator==(const PointerAlignmentOptions &R) const { - return Default == R.Default; + return Default == R.Default && ReturnType == R.ReturnType; } bool operator!=(const PointerAlignmentOptions &R) const { return !(*this == R); @@ -4239,8 +4262,10 @@ struct FormatStyle { struct ReferenceAlignmentOptions { /// The default alignment for references. ReferenceAlignmentStyle Default; + /// The alignment for references in return types. + SpecializedAlignmentStyle ReturnType; bool operator==(const ReferenceAlignmentOptions &R) const { - return Default == R.Default; + return Default == R.Default && ReturnType == R.ReturnType; } bool operator!=(const ReferenceAlignmentOptions &R) const { return !(*this == R); diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index b82c387df877d..dbbb6bdf565aa 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -548,25 +548,42 @@ template <> struct MappingTraits<FormatStyle::PointerAlignmentOptions> { static void enumInput(IO &IO, FormatStyle::PointerAlignmentOptions &Value) { IO.enumCase(Value, "Middle", FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Middle})); + {/*Default=*/FormatStyle::PAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default})); IO.enumCase(Value, "Left", FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Left})); + {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default})); IO.enumCase(Value, "Right", FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Right})); + {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); // For backward compatibility. IO.enumCase(Value, "true", FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Left})); + {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default})); IO.enumCase(Value, "false", FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Right})); + {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); } static void mapping(IO &IO, FormatStyle::PointerAlignmentOptions &Value) { IO.mapOptional("Default", Value.Default); + IO.mapOptional("ReturnType", Value.ReturnType); + } +}; + +template <> +struct ScalarEnumerationTraits<FormatStyle::SpecializedAlignmentStyle> { + static void enumeration(IO &IO, + FormatStyle::SpecializedAlignmentStyle &Value) { + IO.enumCase(Value, "Default", FormatStyle::SAS_Default); + IO.enumCase(Value, "Middle", FormatStyle::SAS_Middle); + IO.enumCase(Value, "Left", FormatStyle::SAS_Left); + IO.enumCase(Value, "Right", FormatStyle::SAS_Right); } }; @@ -615,20 +632,25 @@ template <> struct MappingTraits<FormatStyle::ReferenceAlignmentOptions> { static void enumInput(IO &IO, FormatStyle::ReferenceAlignmentOptions &Value) { IO.enumCase(Value, "Pointer", FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Pointer})); + {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Default})); IO.enumCase(Value, "Middle", FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Middle})); + {/*Default=*/FormatStyle::RAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default})); IO.enumCase(Value, "Left", FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Left})); + {/*Default=*/FormatStyle::RAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default})); IO.enumCase(Value, "Right", FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Right})); + {/*Default=*/FormatStyle::RAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); } static void mapping(IO &IO, FormatStyle::ReferenceAlignmentOptions &Value) { IO.mapOptional("Default", Value.Default); + IO.mapOptional("ReturnType", Value.ReturnType); } }; @@ -1828,10 +1850,12 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.ObjCSpaceAfterProperty = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack; - LLVMStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; + LLVMStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default}; LLVMStyle.PPIndentWidth = -1; LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave; - LLVMStyle.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer}; + LLVMStyle.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Default}; LLVMStyle.ReflowComments = FormatStyle::RCS_Always; LLVMStyle.RemoveBracesLLVM = false; LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false; @@ -1953,7 +1977,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.ObjCSpaceAfterProperty = false; GoogleStyle.ObjCSpaceBeforeProtocolList = true; GoogleStyle.PackConstructorInitializers = FormatStyle::PCIS_NextLine; - GoogleStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; + GoogleStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default}; GoogleStyle.RawStringFormats = { { FormatStyle::LK_Cpp, @@ -2148,7 +2173,8 @@ FormatStyle getMozillaStyle() { MozillaStyle.ObjCSpaceAfterProperty = true; MozillaStyle.ObjCSpaceBeforeProtocolList = false; MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; - MozillaStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; + MozillaStyle.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default}; MozillaStyle.SpaceAfterTemplateKeyword = false; return MozillaStyle; } @@ -2171,7 +2197,8 @@ FormatStyle getWebKitStyle() { Style.NamespaceIndentation = FormatStyle::NI_Inner; Style.ObjCBlockIndentWidth = 4; Style.ObjCSpaceAfterProperty = true; - Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default}; Style.SpaceBeforeCpp11BracedList = true; Style.SpaceInEmptyBraces = FormatStyle::SIEB_Always; return Style; @@ -2904,11 +2931,15 @@ class Formatter : public TokenAnalyzer { } if (Style.DerivePointerAlignment) { const auto NetRightCount = countVariableAlignments(AnnotatedLines); - if (NetRightCount > 0) - Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right}; - else if (NetRightCount < 0) - Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; - Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer}; + if (NetRightCount > 0) { + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default}; + } else if (NetRightCount < 0) { + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default}; + } + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Default}; } if (Style.Standard == FormatStyle::LS_Auto) { Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f48a02c49c562..5c1cf94aa4bd2 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -6540,9 +6540,41 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const { llvm::errs() << "----\n"; } +static bool isReturnType(const FormatToken &Tok) { + // Look forward to see if there's a function declaration paren + const FormatToken *Next = Tok.Next; + while (Next) { + if (Next->isOneOf(TT_FunctionDeclarationLParen, TT_FunctionTypeLParen)) + return true; + // Stop at certain tokens that indicate we're not in a return type + if (Next->isOneOf(tok::semi, tok::l_brace, tok::comma, tok::equal, + TT_LambdaLSquare)) { + break; + } + + Next = Next->Next; + } + return false; +} + FormatStyle::PointerAlignmentStyle TokenAnnotator::getTokenReferenceAlignment(const FormatToken &Reference) const { assert(Reference.isOneOf(tok::amp, tok::ampamp)); + + if (Style.ReferenceAlignment.ReturnType != FormatStyle::SAS_Default && + isReturnType(Reference)) { + switch (Style.ReferenceAlignment.ReturnType) { + case FormatStyle::SAS_Left: + return FormatStyle::PAS_Left; + case FormatStyle::SAS_Right: + return FormatStyle::PAS_Right; + case FormatStyle::SAS_Middle: + return FormatStyle::PAS_Middle; + case FormatStyle::SAS_Default: + assert(0); + } + } + switch (Style.ReferenceAlignment.Default) { case FormatStyle::RAS_Pointer: return Style.PointerAlignment.Default; @@ -6563,6 +6595,21 @@ TokenAnnotator::getTokenPointerOrReferenceAlignment( if (PointerOrReference.isOneOf(tok::amp, tok::ampamp)) return getTokenReferenceAlignment(PointerOrReference); assert(PointerOrReference.is(tok::star)); + + if (Style.PointerAlignment.ReturnType != FormatStyle::SAS_Default && + isReturnType(PointerOrReference)) { + switch (Style.PointerAlignment.ReturnType) { + case FormatStyle::SAS_Left: + return FormatStyle::PAS_Left; + case FormatStyle::SAS_Right: + return FormatStyle::PAS_Right; + case FormatStyle::SAS_Middle: + return FormatStyle::PAS_Middle; + case FormatStyle::SAS_Default: + assert(0); + } + } + return Style.PointerAlignment.Default; } diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 882f7b1342cc4..a91512a703040 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -391,39 +391,67 @@ TEST(ConfigParseTest, ParsesConfiguration) { #undef CHECK_ALIGN_CONSECUTIVE - Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default}; CHECK_PARSE("PointerAlignment: Left", PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Left})); + {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("PointerAlignment: Right", PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Right})); + {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Middle})); - Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Middle}; + {/*Default=*/FormatStyle::PAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default})); + CHECK_PARSE("PointerAlignment:\n" + " Default: Right\n" + " ReturnType: Left", + PointerAlignment, + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Left})); + + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default}; CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment, FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Pointer})); + {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment, FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Left})); + {/*Default=*/FormatStyle::RAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment, FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Right})); + {/*Default=*/FormatStyle::RAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment, FormatStyle::ReferenceAlignmentOptions( - {/*Default=*/FormatStyle::RAS_Middle})); + {/*Default=*/FormatStyle::RAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default})); + CHECK_PARSE("ReferenceAlignment:\n" + " Default: Right\n" + " ReturnType: Left", + ReferenceAlignment, + FormatStyle::ReferenceAlignmentOptions( + {/*Default=*/FormatStyle::RAS_Right, + /*ReturnType=*/FormatStyle::SAS_Left})); + // For backward compatibility: CHECK_PARSE("PointerBindsToType: Left", PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Left})); + {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("PointerBindsToType: Right", PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Right})); + {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Middle})); + {/*Default=*/FormatStyle::PAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default})); Style.ReflowComments = FormatStyle::RCS_Always; CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 741a6e1740af6..c15543b41281b 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2299,6 +2299,125 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { // verifyFormat("int Add2(BTree * &Root, char * szToAdd)", Style); } +TEST_F(FormatTest, ReturnTypeAlignment) { + // Test that ReturnType overrides PointerAlignment for return types + FormatStyle Style = getLLVMStyle(); + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Left}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Left}; + + // Return type pointers should be left-aligned despite PAS_Right + verifyFormat("int* f1(int *a, int *b);", Style); + verifyFormat("int& f2(int &a, int &b);", Style); + verifyFormat("int&& f3(int &&a, int &&b);", Style); + + // Multiple pointers in return type + verifyFormat("int** f4(int **a);", Style); + verifyFormat("const int* f5(const int *a);", Style); + verifyFormat("int*** f6(int ***a);", Style); + + // Multiple pointers with const qualifiers + verifyFormat("const int** f7(const int **a);", Style); + verifyFormat("int* const* f8(int *const *a);", Style); + verifyFormat("const int* const* f9(const int *const *a);", Style); + verifyFormat("int** const f10(int **const a);", Style); + verifyFormat("const int** const f11(const int **const a);", Style); + + // Triple pointers with const + verifyFormat("int*** const f12(int ***const a);", Style); + verifyFormat("const int*** f13(const int ***a);", Style); + verifyFormat("int* const* const* f14(int *const *const *a);", Style); + verifyFormat("const int* const* const* f15(const int *const *const *a);", + Style); + + // Complex return types + verifyFormat("std::vector<int>* f16(std::vector<int> *a);", Style); + verifyFormat("const char* f17(const char *str);", Style); + verifyFormat("const char** f18(const char **argv);", Style); + verifyFormat("char* const* f19(char *const *envp);", Style); + + // Member functions + verifyFormat("int* Class::method(int *a);", Style); + verifyFormat("int& Class::method(int &a);", Style); + verifyFormat("int* (*f8())(int *a);", Style); + + // Variables should still follow the default alignment + verifyFormat("int *a = nullptr;", Style); + verifyFormat("int *b = f1(a, a);", Style); + + // Now test with PAS_Left base and SAS_Right return type + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Right}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Right}; + + // Return type pointers should be right-aligned despite PAS_Left + verifyFormat("int *f1(int* a, int* b);", Style); + verifyFormat("int &f2(int& a, int& b);", Style); + verifyFormat("int &&f3(int&& a, int&& b);", Style); + + // Multiple pointers with right alignment in return type + verifyFormat("int **f4(int** a);", Style); + verifyFormat("const int *f5(const int* a);", Style); + verifyFormat("int ***f6(int*** a);", Style); + + // Multiple pointers with const qualifiers, right-aligned return type + verifyFormat("const int **f7(const int** a);", Style); + verifyFormat("int *const *f8(int* const* a);", Style); + verifyFormat("const int *const *f9(const int* const* a);", Style); + verifyFormat("int **const f10(int** const a);", Style); + verifyFormat("const char **f11(const char** argv);", Style); + + // Variables should still follow PointerAlignment (PAS_Left) + verifyFormat("int* a = nullptr;", Style); + verifyFormat("int* b = f1(a, a);", Style); + + // Test with SAS_Middle + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Middle}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Middle}; + + verifyFormat("int * f1(int *a, int *b);", Style); + verifyFormat("int & f2(int &a, int &b);", Style); + verifyFormat("int && f3(int &&a, int &&b);", Style); + + // Multiple pointers with middle alignment in return type + verifyFormat("int ** f4(int **a);", Style); + verifyFormat("int *** f5(int ***a);", Style); + + // Multiple pointers with const qualifiers, middle-aligned return type + verifyFormat("const int * f6(const int *a);", Style); + verifyFormat("const int ** f7(const int **a);", Style); + verifyFormat("int * const * f8(int *const *a);", Style); + verifyFormat("const int * const * f9(const int *const *a);", Style); + verifyFormat("int ** const f10(int **const a);", Style); + verifyFormat("const char ** f11(const char **argv);", Style); + + // Variables should still follow PointerAlignment (PAS_Right) + verifyFormat("int *a = nullptr;", Style); + + // Test that default alignment is used when ReturnType is SAS_Default + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Default}; + + verifyFormat("int* f1(int* a, int* b);", Style); + verifyFormat("int& f2(int& a, int& b);", Style); + + // Test with ReferenceAlignment override + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Left}; + Style.ReferenceAlignment = {/*Default=*/FormatStyle::RAS_Pointer, + /*ReturnType=*/FormatStyle::SAS_Right}; + + verifyFormat("int* f1(int *a, int &b);", Style); + verifyFormat("int &f2(int &a, int *b);", Style); + verifyFormat("int &&f3(int &&a, int *b);", Style); +} + TEST_F(FormatTest, FormatsForLoop) { verifyFormat( "for (int VeryVeryLongLoopVariable = 0; VeryVeryLongLoopVariable < 10;\n" @@ -11468,16 +11587,20 @@ TEST_F(FormatTest, UnderstandsPointersToMembers) { " aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); FormatStyle Style = getLLVMStyle(); - EXPECT_EQ(Style.PointerAlignment, FormatStyle::PointerAlignmentOptions( - {/*Default=*/FormatStyle::PAS_Right})); + EXPECT_EQ(Style.PointerAlignment, + FormatStyle::PointerAlignmentOptions( + {/*Default=*/FormatStyle::PAS_Right, + /*ReturnType=*/FormatStyle::SAS_Default})); verifyFormat("typedef bool *(Class::*Member)() const;", Style); verifyFormat("void f(int A::*p) { int A::*v = &A::B; }", Style); - Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left}; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Left, + /*ReturnType=*/FormatStyle::SAS_Default}; verifyFormat("typedef bool* (Class::*Member)() const;", Style); verifyFormat("void f(int A::* p) { int A::* v = &A::B; }", Style); - Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle}; + Style.PointerAlignment = {/*Default=*/FormatStyle::PAS_Middle, + /*ReturnType=*/FormatStyle::SAS_Default}; verifyFormat("typedef bool * (Class::*Member)() const;", Style); verifyFormat("void f(int A::* p) { int A::* v = &A::B; }", Style); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
