diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 570cab262c115..0b4a4849f6ccc 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -197,57 +197,29 @@ the configuration (without a prefix: ``Auto``). .. _AlignAfterOpenBracket: -**AlignAfterOpenBracket** (``BracketAlignmentStyle``) :versionbadge:`clang-format 3.8` :ref:`¶ ` +**AlignAfterOpenBracket** (``Boolean``) :versionbadge:`clang-format 3.8` :ref:`¶ ` If ``true``, horizontally aligns arguments after an open bracket. - This applies to round brackets (parentheses), angle brackets and square - brackets. - - Possible values: - - * ``BAS_Align`` (in configuration: ``Align``) - Align parameters on the open bracket, e.g.: - - .. code-block:: c++ - - someLongFunction(argument1, - argument2); - - * ``BAS_DontAlign`` (in configuration: ``DontAlign``) - Don't align, instead use ``ContinuationIndentWidth``, e.g.: - - .. code-block:: c++ - - someLongFunction(argument1, - argument2); - - * ``BAS_AlwaysBreak`` (in configuration: ``AlwaysBreak``) - Always break after an open bracket, if the parameters don't fit - on a single line, e.g.: - - .. code-block:: c++ - someLongFunction( - argument1, argument2); - - * ``BAS_BlockIndent`` (in configuration: ``BlockIndent``) - Always break after an open bracket, if the parameters don't fit - on a single line. Closing brackets will be placed on a new line. - E.g.: - - .. code-block:: c++ + .. code-block:: c++ - someLongFunction( - argument1, argument2 - ) + true: vs. false + someLongFunction(argument1, someLongFunction(argument1, + argument2); argument2); - .. note:: - - This currently only applies to braced initializer lists (when - ``Cpp11BracedListStyle`` is not ``Block``) and parentheses. + .. note:: + As of clang-format 22 this option is a bool with the previous + option of ``Align`` replaced with ``true``, ``DontAlign`` replaced + with ``false``, and the options of ``AlwaysBreak`` and ``BlockIndent`` + replaced with ``true`` and with setting of new style options using + ``BreakAfterOpenBracketBracedList``, ``BreakAfterOpenBracketFunction``, + ``BreakAfterOpenBracketIf``, ``BreakBeforeCloseBracketBracedList``, + ``BreakBeforeCloseBracketFunction``, and ``BreakBeforeCloseBracketIf``. + This applies to round brackets (parentheses), angle brackets and square + brackets. .. _AlignArrayOfStructures: @@ -2746,6 +2718,67 @@ the configuration (without a prefix: ``Auto``). @Mock DataLoad loader; +.. _BreakAfterOpenBracketBracedList: + +**BreakAfterOpenBracketBracedList** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break after the left bracket of a braced initializer list (when + ``Cpp11BracedListStyle`` is ``true``) when the list exceeds the column + limit. + + .. code-block:: c++ + + true: false: + vector x { vs. vector x {1, + 1, 2, 3} 2, 3} + +.. _BreakAfterOpenBracketFunction: + +**BreakAfterOpenBracketFunction** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break after the left parenthesis of a function (declaration, + definition, call) when the parameters exceed the column limit. + + .. code-block:: c++ + + true: false: + foo ( vs. foo (a, + a , b) b) + +.. _BreakAfterOpenBracketIf: + +**BreakAfterOpenBracketIf** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break after the left parenthesis of an if control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + if constexpr ( vs. if constexpr (a || + a || b) b) + +.. _BreakAfterOpenBracketLoop: + +**BreakAfterOpenBracketLoop** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break after the left parenthesis of a loop control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + while ( vs. while (a && + a && b) { b) { + +.. _BreakAfterOpenBracketSwitch: + +**BreakAfterOpenBracketSwitch** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break after the left parenthesis of a switch control statement + when the expression exceeds the column limit. + + .. code-block:: c++ + + true: false: + switch ( vs. switch (a + + a + b) { b) { + .. _BreakAfterReturnType: **BreakAfterReturnType** (``ReturnTypeBreakingStyle``) :versionbadge:`clang-format 19` :ref:`¶ ` @@ -3383,6 +3416,79 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeCloseBracketBracedList: + +**BreakBeforeCloseBracketBracedList** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break before the right bracket of a braced initializer list (when + ``Cpp11BracedListStyle`` is ``true``) when the list exceeds the column + limit. The break before the right bracket is only made if there is a + break after the opening bracket. + + .. code-block:: c++ + + true: false: + vector x { vs. vector x { + 1, 2, 3 1, 2, 3} + } + +.. _BreakBeforeCloseBracketFunction: + +**BreakBeforeCloseBracketFunction** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break before the right parenthesis of a function (declaration, + definition, call) when the parameters exceed the column limit. + + .. code-block:: c++ + + true: false: + foo ( vs. foo ( + a , b a , b) + ) + +.. _BreakBeforeCloseBracketIf: + +**BreakBeforeCloseBracketIf** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break before the right parenthesis of an if control statement + when the expression exceeds the column limit. The break before the + closing parenthesis is only made if there is a break after the opening + parenthesis. + + .. code-block:: c++ + + true: false: + if constexpr ( vs. if constexpr ( + a || b a || b ) + ) + +.. _BreakBeforeCloseBracketLoop: + +**BreakBeforeCloseBracketLoop** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break before the right parenthesis of a loop control statement + when the expression exceeds the column limit. The break before the + closing parenthesis is only made if there is a break after the opening + parenthesis. + + .. code-block:: c++ + + true: false: + while ( vs. while ( + a && b a && b) { + ) { + +.. _BreakBeforeCloseBracketSwitch: + +**BreakBeforeCloseBracketSwitch** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Force break before the right parenthesis of a switch control statement + when the expression exceeds the column limit. The break before the + closing parenthesis is only made if there is a break after the opening + parenthesis. + + .. code-block:: c++ + + true: false: + switch ( vs. switch ( + a + b a + b) { + ) { + .. _BreakBeforeConceptDeclarations: **BreakBeforeConceptDeclarations** (``BreakBeforeConceptDeclarationsStyle``) :versionbadge:`clang-format 12` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8435f367029a5..ba737b9efb003 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -613,6 +613,14 @@ clang-format literals. - Add ``Leave`` suboption to ``IndentPPDirectives``. - Add ``AllowBreakBeforeQtProperty`` option. +- Add ``BreakAfterOpenBracketBracedList'', ``BreakAfterOpenBracketFunction'', + ``BreakAfterOpenBracketIf``, ``BreakAfterOpenBracketLoop``, + ``BreakAfterOpenBracketSwitch``, ``BreakBeforeCloseBracketBracedList'', + ``BreakBeforeCloseBracketFunction``, ``BreakBeforeCloseBracketIf``, + ``BreakBeforeCloseBracketLoop``, ``BreakBeforeCloseBracketSwitch`` options. +- Deprecate ``AlwaysBreak`` and ``BlockIndent`` suboptions from the + ``AlignAfterOpenBracket`` option, and make ``AlignAfterOpenBracket`` a + ``bool`` type. libclang -------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 2852c4a2916a4..f246defc1fe81 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -62,49 +62,28 @@ struct FormatStyle { /// \version 3.3 int AccessModifierOffset; - /// Different styles for aligning after open brackets. - enum BracketAlignmentStyle : int8_t { - /// Align parameters on the open bracket, e.g.: - /// \code - /// someLongFunction(argument1, - /// argument2); - /// \endcode - BAS_Align, - /// Don't align, instead use ``ContinuationIndentWidth``, e.g.: - /// \code - /// someLongFunction(argument1, - /// argument2); - /// \endcode - BAS_DontAlign, - /// Always break after an open bracket, if the parameters don't fit - /// on a single line, e.g.: - /// \code - /// someLongFunction( - /// argument1, argument2); - /// \endcode - BAS_AlwaysBreak, - /// Always break after an open bracket, if the parameters don't fit - /// on a single line. Closing brackets will be placed on a new line. - /// E.g.: - /// \code - /// someLongFunction( - /// argument1, argument2 - /// ) - /// \endcode - /// - /// \note - /// This currently only applies to braced initializer lists (when - /// ``Cpp11BracedListStyle`` is not ``Block``) and parentheses. - /// \endnote - BAS_BlockIndent, - }; - /// If ``true``, horizontally aligns arguments after an open bracket. /// + /// \code + /// true: vs. false + /// someLongFunction(argument1, someLongFunction(argument1, + /// argument2); argument2); + /// \endcode + /// + /// \note + /// As of clang-format 22 this option is a bool with the previous + /// option of ``Align`` replaced with ``true``, ``DontAlign`` replaced + /// with ``false``, and the options of ``AlwaysBreak`` and ``BlockIndent`` + /// replaced with ``true`` and with setting of new style options using + /// ``BreakAfterOpenBracketBracedList``, ``BreakAfterOpenBracketFunction``, + /// ``BreakAfterOpenBracketIf``, ``BreakBeforeCloseBracketBracedList``, + /// ``BreakBeforeCloseBracketFunction``, and ``BreakBeforeCloseBracketIf``. + /// \endnote + /// /// This applies to round brackets (parentheses), angle brackets and square /// brackets. /// \version 3.8 - BracketAlignmentStyle AlignAfterOpenBracket; + bool AlignAfterOpenBracket; /// Different style for aligning array initializers. enum ArrayInitializerAlignmentStyle : int8_t { @@ -1708,6 +1687,57 @@ struct FormatStyle { /// \version 16 AttributeBreakingStyle BreakAfterAttributes; + /// Force break after the left bracket of a braced initializer list (when + /// ``Cpp11BracedListStyle`` is ``true``) when the list exceeds the column + /// limit. + /// \code + /// true: false: + /// vector x { vs. vector x {1, + /// 1, 2, 3} 2, 3} + /// \endcode + /// \version 22 + bool BreakAfterOpenBracketBracedList; + + /// Force break after the left parenthesis of a function (declaration, + /// definition, call) when the parameters exceed the column limit. + /// \code + /// true: false: + /// foo ( vs. foo (a, + /// a , b) b) + /// \endcode + /// \version 22 + bool BreakAfterOpenBracketFunction; + + /// Force break after the left parenthesis of an if control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// if constexpr ( vs. if constexpr (a || + /// a || b) b) + /// \endcode + /// \version 22 + bool BreakAfterOpenBracketIf; + + /// Force break after the left parenthesis of a loop control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// while ( vs. while (a && + /// a && b) { b) { + /// \endcode + /// \version 22 + bool BreakAfterOpenBracketLoop; + + /// Force break after the left parenthesis of a switch control statement + /// when the expression exceeds the column limit. + /// \code + /// true: false: + /// switch ( vs. switch (a + + /// a + b) { b) { + /// \endcode + /// \version 22 + bool BreakAfterOpenBracketSwitch; + /// The function declaration return type breaking style to use. /// \version 19 ReturnTypeBreakingStyle BreakAfterReturnType; @@ -2221,6 +2251,69 @@ struct FormatStyle { /// \version 3.7 BraceBreakingStyle BreakBeforeBraces; + /// Force break before the right bracket of a braced initializer list (when + /// ``Cpp11BracedListStyle`` is ``true``) when the list exceeds the column + /// limit. The break before the right bracket is only made if there is a + /// break after the opening bracket. + /// \code + /// true: false: + /// vector x { vs. vector x { + /// 1, 2, 3 1, 2, 3} + /// } + /// \endcode + /// \version 22 + bool BreakBeforeCloseBracketBracedList; + + /// Force break before the right parenthesis of a function (declaration, + /// definition, call) when the parameters exceed the column limit. + /// \code + /// true: false: + /// foo ( vs. foo ( + /// a , b a , b) + /// ) + /// \endcode + /// \version 22 + bool BreakBeforeCloseBracketFunction; + + /// Force break before the right parenthesis of an if control statement + /// when the expression exceeds the column limit. The break before the + /// closing parenthesis is only made if there is a break after the opening + /// parenthesis. + /// \code + /// true: false: + /// if constexpr ( vs. if constexpr ( + /// a || b a || b ) + /// ) + /// \endcode + /// \version 22 + bool BreakBeforeCloseBracketIf; + + /// Force break before the right parenthesis of a loop control statement + /// when the expression exceeds the column limit. The break before the + /// closing parenthesis is only made if there is a break after the opening + /// parenthesis. + /// \code + /// true: false: + /// while ( vs. while ( + /// a && b a && b) { + /// ) { + /// \endcode + /// \version 22 + bool BreakBeforeCloseBracketLoop; + + /// Force break before the right parenthesis of a switch control statement + /// when the expression exceeds the column limit. The break before the + /// closing parenthesis is only made if there is a break after the opening + /// parenthesis. + /// \code + /// true: false: + /// switch ( vs. switch ( + /// a + b a + b) { + /// ) { + /// \endcode + /// \version 22 + bool BreakBeforeCloseBracketSwitch; + /// Different ways to break before concept declarations. enum BreakBeforeConceptDeclarationsStyle : int8_t { /// Keep the template declaration line together with ``concept``. @@ -5530,10 +5623,23 @@ struct FormatStyle { BreakAdjacentStringLiterals == R.BreakAdjacentStringLiterals && BreakAfterAttributes == R.BreakAfterAttributes && BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations && + BreakAfterOpenBracketBracedList == + R.BreakAfterOpenBracketBracedList && + BreakAfterOpenBracketFunction == R.BreakAfterOpenBracketFunction && + BreakAfterOpenBracketIf == R.BreakAfterOpenBracketIf && + BreakAfterOpenBracketLoop == R.BreakAfterOpenBracketLoop && + BreakAfterOpenBracketSwitch == R.BreakAfterOpenBracketSwitch && BreakAfterReturnType == R.BreakAfterReturnType && BreakArrays == R.BreakArrays && BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && BreakBeforeBraces == R.BreakBeforeBraces && + BreakBeforeCloseBracketBracedList == + R.BreakBeforeCloseBracketBracedList && + BreakBeforeCloseBracketFunction == + R.BreakBeforeCloseBracketFunction && + BreakBeforeCloseBracketIf == R.BreakBeforeCloseBracketIf && + BreakBeforeCloseBracketLoop == R.BreakBeforeCloseBracketLoop && + BreakBeforeCloseBracketSwitch == R.BreakBeforeCloseBracketSwitch && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && BreakBeforeTemplateCloser == R.BreakBeforeTemplateCloser && diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index e5abf833194d4..9ab024a03fbd7 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -356,9 +356,11 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return CurrentState.BreakBeforeClosingBrace; } - // Allow breaking before the right parens with block indentation if there was - // a break after the left parens, which is tracked by BreakBeforeClosingParen. - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + // Check need to break before the right parens if there was a break after + // the left parens, which is tracked by BreakBeforeClosingParen. + if ((Style.BreakBeforeCloseBracketFunction || + Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop || + Style.BreakBeforeCloseBracketSwitch) && Current.is(tok::r_paren)) { return CurrentState.BreakBeforeClosingParen; } @@ -837,32 +839,38 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) && Style.Cpp11BracedListStyle != FormatStyle::BLS_Block; }; - if (Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) && - !IsStartOfBracedList()) { + if (IsStartOfBracedList()) + return Style.BreakAfterOpenBracketBracedList; + if (Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square)) return false; - } if (!Tok.Previous) return true; if (Tok.Previous->isIf()) - return Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak; - return Tok.Previous->isNoneOf(TT_CastRParen, tok::kw_for, tok::kw_while, - tok::kw_switch) && - !(Style.isJavaScript() && Tok.Previous->is(Keywords.kw_await)); + return Style.BreakAfterOpenBracketIf; + if (Tok.Previous->isLoop(Style)) + return Style.BreakAfterOpenBracketLoop; + if (Tok.Previous->is(tok::kw_switch)) + return Style.BreakAfterOpenBracketSwitch; + if (Style.BreakAfterOpenBracketFunction) { + return !Tok.Previous->is(TT_CastRParen) && + !(Style.isJavaScript() && Tok.is(Keywords.kw_await)); + } + return false; }; auto IsFunctionCallParen = [](const FormatToken &Tok) { return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && Tok.Previous->is(tok::identifier); }; - auto IsInTemplateString = [this](const FormatToken &Tok) { + auto IsInTemplateString = [this](const FormatToken &Tok, bool NestBlocks) { if (!Style.isJavaScript()) return false; for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) { if (Prev->is(TT_TemplateString) && Prev->opensScope()) return true; - if (Prev->opensScope() || - (Prev->is(TT_TemplateString) && Prev->closesScope())) { - break; - } + if (Prev->opensScope() && !NestBlocks) + return false; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) + return false; } return false; }; @@ -884,21 +892,25 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) { return true; } - if (const auto *Previous = Tok.Previous; - !Previous || (Previous->isNoneOf(TT_FunctionDeclarationLParen, - TT_LambdaDefinitionLParen) && - !IsFunctionCallParen(*Previous))) { + const auto *Previous = TokAfterLParen.Previous; + assert(Previous); // IsOpeningBracket(Previous) + if (Previous->Previous && + (Previous->Previous->isIf() || Previous->Previous->isLoop(Style) || + Previous->Previous->is(tok::kw_switch))) { + return false; + } + if (Previous->isNoneOf(TT_FunctionDeclarationLParen, + TT_LambdaDefinitionLParen) && + !IsFunctionCallParen(*Previous)) { return true; } - if (IsOpeningBracket(Tok) || IsInTemplateString(Tok)) + if (IsOpeningBracket(Tok) || IsInTemplateString(Tok, true)) return true; const auto *Next = Tok.Next; return !Next || Next->isMemberAccess() || Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next); }; - if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && - IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && + if (IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // @@ -920,7 +932,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, // Note: This doesn't apply to macro expansion lines, which are MACRO( , , ) // with args as children of the '(' and ',' tokens. It does not make sense to // align the commas with the opening paren. - if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign && + if (Style.AlignAfterOpenBracket && !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() && Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause, TT_TableGenDAGArgOpener, @@ -933,7 +945,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, Previous.Previous->isNoneOf(tok::identifier, tok::l_paren, BK_BracedInit))) || Previous.is(TT_VerilogMultiLineListLParen)) && - !IsInTemplateString(Current)) { + !IsInTemplateString(Current, false)) { CurrentState.Indent = State.Column + Spaces; CurrentState.IsAligned = true; } @@ -1271,8 +1283,20 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, } if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) { - CurrentState.BreakBeforeClosingParen = - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + if (auto Previous = PreviousNonComment->Previous) { + if (Previous->isIf()) { + CurrentState.BreakBeforeClosingParen = Style.BreakBeforeCloseBracketIf; + } else if (Previous->isLoop(Style)) { + CurrentState.BreakBeforeClosingParen = + Style.BreakBeforeCloseBracketLoop; + } else if (Previous->is(tok::kw_switch)) { + CurrentState.BreakBeforeClosingParen = + Style.BreakBeforeCloseBracketSwitch; + } else { + CurrentState.BreakBeforeClosingParen = + Style.BreakBeforeCloseBracketFunction; + } + } } if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) @@ -1416,13 +1440,17 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; } - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && - (Current.is(tok::r_paren) || - (Current.is(tok::r_brace) && Current.MatchingParen && - Current.MatchingParen->is(BK_BracedInit))) && + if (Style.BreakBeforeCloseBracketBracedList && Current.is(tok::r_brace) && + Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit) && State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; } + if ((Style.BreakBeforeCloseBracketFunction || + Style.BreakBeforeCloseBracketIf || Style.BreakBeforeCloseBracketLoop || + Style.BreakBeforeCloseBracketSwitch) && + Current.is(tok::r_paren) && State.Stack.size() > 1) { + return State.Stack[State.Stack.size() - 2].LastSpace; + } if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) && State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; @@ -1844,8 +1872,8 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, PrecedenceLevel < prec::Assignment) && (!Previous || Previous->isNot(tok::kw_return) || (!Style.isJava() && PrecedenceLevel > 0)) && - (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign || - PrecedenceLevel > prec::Comma || Current.NestingLevel == 0) && + (Style.AlignAfterOpenBracket || PrecedenceLevel > prec::Comma || + Current.NestingLevel == 0) && (!Style.isTableGen() || (Previous && Previous->isOneOf(TT_TableGenDAGArgListComma, TT_TableGenDAGArgListCommaToBreak)))) { @@ -1885,8 +1913,7 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, if (PrecedenceLevel > prec::Unknown) NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column); if (PrecedenceLevel != prec::Conditional && - Current.isNot(TT_UnaryOperator) && - Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) { + Current.isNot(TT_UnaryOperator) && Style.AlignAfterOpenBracket) { NewParenState.StartOfFunctionCall = State.Column; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index edd126c7724b8..dd14fcd72922f 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -32,6 +32,13 @@ using clang::format::FormatStyle; LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat) +enum BracketAlignmentStyle : int8_t { + BAS_Align, + BAS_DontAlign, + BAS_AlwaysBreak, + BAS_BlockIndent +}; + namespace llvm { namespace yaml { template <> @@ -204,16 +211,16 @@ template <> struct MappingTraits { } }; -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) { - IO.enumCase(Value, "Align", FormatStyle::BAS_Align); - IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign); - IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak); - IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent); +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, BracketAlignmentStyle &Value) { + IO.enumCase(Value, "Align", BAS_Align); + IO.enumCase(Value, "DontAlign", BAS_DontAlign); // For backward compatibility. - IO.enumCase(Value, "true", FormatStyle::BAS_Align); - IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign); + IO.enumCase(Value, "true", BAS_Align); + IO.enumCase(Value, "false", BAS_DontAlign); + IO.enumCase(Value, "AlwaysBreak", BAS_AlwaysBreak); + IO.enumCase(Value, "BlockIndent", BAS_BlockIndent); } }; @@ -979,6 +986,54 @@ template <> struct MappingTraits { bool SpacesInCStyleCastParentheses = false; bool SpacesInParentheses = false; + if (IO.outputting()) { + IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); + } else { + // For backward compatibility. + BracketAlignmentStyle LocalBAS = BAS_Align; + if (IsGoogleOrChromium) { + FormatStyle::LanguageKind Language = Style.Language; + if (Language == FormatStyle::LK_None) + Language = ((FormatStyle *)IO.getContext())->Language; + if (Language == FormatStyle::LK_JavaScript) + LocalBAS = BAS_AlwaysBreak; + else if (Language == FormatStyle::LK_Java) + LocalBAS = BAS_DontAlign; + } else if (BasedOnStyle.equals_insensitive("webkit")) { + LocalBAS = BAS_DontAlign; + } + IO.mapOptional("AlignAfterOpenBracket", LocalBAS); + Style.BreakAfterOpenBracketBracedList = false; + Style.BreakAfterOpenBracketFunction = false; + Style.BreakAfterOpenBracketIf = false; + Style.BreakAfterOpenBracketLoop = false; + Style.BreakAfterOpenBracketSwitch = false; + Style.BreakBeforeCloseBracketBracedList = false; + Style.BreakBeforeCloseBracketFunction = false; + Style.BreakBeforeCloseBracketIf = false; + Style.BreakBeforeCloseBracketLoop = false; + Style.BreakBeforeCloseBracketSwitch = false; + + switch (LocalBAS) { + case BAS_DontAlign: + Style.AlignAfterOpenBracket = false; + break; + case BAS_BlockIndent: + Style.BreakBeforeCloseBracketBracedList = true; + Style.BreakBeforeCloseBracketFunction = true; + Style.BreakBeforeCloseBracketIf = true; + [[fallthrough]]; + case BAS_AlwaysBreak: + Style.BreakAfterOpenBracketBracedList = true; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakAfterOpenBracketIf = true; + [[fallthrough]]; + case BAS_Align: + Style.AlignAfterOpenBracket = true; + break; + } + } + // For backward compatibility. if (!IO.outputting()) { IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines); @@ -1014,7 +1069,6 @@ template <> struct MappingTraits { } IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); - IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures); IO.mapOptional("AlignConsecutiveAssignments", Style.AlignConsecutiveAssignments); @@ -1079,10 +1133,29 @@ template <> struct MappingTraits { IO.mapOptional("BreakAfterAttributes", Style.BreakAfterAttributes); IO.mapOptional("BreakAfterJavaFieldAnnotations", Style.BreakAfterJavaFieldAnnotations); + IO.mapOptional("BreakAfterOpenBracketBracedList", + Style.BreakAfterOpenBracketBracedList); + IO.mapOptional("BreakAfterOpenBracketFunction", + Style.BreakAfterOpenBracketFunction); + IO.mapOptional("BreakAfterOpenBracketIf", Style.BreakAfterOpenBracketIf); + IO.mapOptional("BreakAfterOpenBracketLoop", + Style.BreakAfterOpenBracketLoop); + IO.mapOptional("BreakAfterOpenBracketSwitch", + Style.BreakAfterOpenBracketSwitch); IO.mapOptional("BreakAfterReturnType", Style.BreakAfterReturnType); IO.mapOptional("BreakArrays", Style.BreakArrays); IO.mapOptional("BreakBeforeBinaryOperators", Style.BreakBeforeBinaryOperators); + IO.mapOptional("BreakBeforeCloseBracketBracedList", + Style.BreakBeforeCloseBracketBracedList); + IO.mapOptional("BreakBeforeCloseBracketFunction", + Style.BreakBeforeCloseBracketFunction); + IO.mapOptional("BreakBeforeCloseBracketIf", + Style.BreakBeforeCloseBracketIf); + IO.mapOptional("BreakBeforeCloseBracketLoop", + Style.BreakBeforeCloseBracketLoop); + IO.mapOptional("BreakBeforeCloseBracketSwitch", + Style.BreakBeforeCloseBracketSwitch); IO.mapOptional("BreakBeforeConceptDeclarations", Style.BreakBeforeConceptDeclarations); IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); @@ -1561,7 +1634,7 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) { FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { FormatStyle LLVMStyle; LLVMStyle.AccessModifierOffset = -2; - LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; + LLVMStyle.AlignAfterOpenBracket = true; LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None; LLVMStyle.AlignConsecutiveAssignments = {}; LLVMStyle.AlignConsecutiveAssignments.PadOperators = true; @@ -1621,10 +1694,20 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakAdjacentStringLiterals = true; LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Leave; LLVMStyle.BreakAfterJavaFieldAnnotations = false; + LLVMStyle.BreakAfterOpenBracketBracedList = false; + LLVMStyle.BreakAfterOpenBracketFunction = false; + LLVMStyle.BreakAfterOpenBracketIf = false; + LLVMStyle.BreakAfterOpenBracketLoop = false; + LLVMStyle.BreakAfterOpenBracketSwitch = false; LLVMStyle.BreakAfterReturnType = FormatStyle::RTBS_None; LLVMStyle.BreakArrays = true; LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; + LLVMStyle.BreakBeforeCloseBracketBracedList = false; + LLVMStyle.BreakBeforeCloseBracketFunction = false; + LLVMStyle.BreakBeforeCloseBracketIf = false; + LLVMStyle.BreakBeforeCloseBracketLoop = false; + LLVMStyle.BreakBeforeCloseBracketSwitch = false; LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always; LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline; LLVMStyle.BreakBeforeTemplateCloser = false; @@ -1877,7 +1960,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200; if (Language == FormatStyle::LK_Java) { - GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + GoogleStyle.AlignAfterOpenBracket = false; GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; GoogleStyle.AlignTrailingComments = {}; GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never; @@ -1889,7 +1972,9 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.SpaceAfterCStyleCast = true; GoogleStyle.SpacesBeforeTrailingComments = 1; } else if (Language == FormatStyle::LK_JavaScript) { - GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + GoogleStyle.BreakAfterOpenBracketBracedList = true; + GoogleStyle.BreakAfterOpenBracketFunction = true; + GoogleStyle.BreakAfterOpenBracketIf = true; GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; // TODO: still under discussion whether to switch to SLS_All. @@ -2026,7 +2111,7 @@ FormatStyle getMozillaStyle() { FormatStyle getWebKitStyle() { FormatStyle Style = getLLVMStyle(); Style.AccessModifierOffset = -4; - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; Style.AlignOperands = FormatStyle::OAS_DontAlign; Style.AlignTrailingComments = {}; Style.AlignTrailingComments.Kind = FormatStyle::TCAS_Never; diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index d1c62642efd43..28fdbcbf0e47f 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -68,7 +68,7 @@ bool FormatToken::isBlockIndentedInitRBrace(const FormatStyle &Style) const { assert(MatchingParen); assert(MatchingParen->is(tok::l_brace)); if (Style.Cpp11BracedListStyle == FormatStyle::BLS_Block || - Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent) { + !Style.BreakBeforeCloseBracketBracedList) { return false; } const auto *LBrace = MatchingParen; @@ -198,7 +198,7 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) { return; // Column format doesn't really make sense if we don't align after brackets. - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign) + if (!Style.AlignAfterOpenBracket) return; FormatToken *ItemBegin = Token->Next; diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 6f3d24aefc1ca..d833130a538f1 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -666,6 +666,12 @@ struct FormatToken { (endsSequence(tok::identifier, tok::kw_if) && AllowConstexprMacro); } + bool isLoop(const FormatStyle &Style) const { + return isOneOf(tok::kw_for, tok::kw_while) || + (Style.isJavaScript() && isNot(tok::l_paren) && Previous && + Previous->is(tok::kw_for)); + } + bool closesScopeAfterBlock() const { if (getBlockKind() == BK_Block) return true; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 021d8c658eb11..8e227da2a79ab 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4427,10 +4427,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0) return Style.PenaltyBreakOpenParenthesis; - if (Left.is(tok::l_paren) && InFunctionDecl && - Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) { + if (Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket) return 100; - } if (Left.is(tok::l_paren) && Left.Previous && (Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) || Left.Previous->isIf())) { @@ -4446,7 +4444,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, // If we aren't aligning after opening parens/braces we can always break // here unless the style does not want us to place all arguments on the // next line. - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign && + if (!Style.AlignAfterOpenBracket && (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) { return 0; } @@ -6226,24 +6224,31 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, (Right.isBlockIndentedInitRBrace(Style))); } - // We only break before r_paren if we're in a block indented context. + // We can break before r_paren if we're in a block indented context or + // a control statement with an explicit style option. if (Right.is(tok::r_paren)) { - if (Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent || - !Right.MatchingParen) { + if (!Right.MatchingParen) return false; - } auto Next = Right.Next; if (Next && Next->is(tok::r_paren)) Next = Next->Next; if (Next && Next->is(tok::l_paren)) return false; const FormatToken *Previous = Right.MatchingParen->Previous; - return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf())); + if (!Previous) + return false; + if (Previous->isIf()) + return Style.BreakBeforeCloseBracketIf; + if (Previous->isLoop(Style)) + return Style.BreakBeforeCloseBracketLoop; + if (Previous->is(tok::kw_switch)) + return Style.BreakBeforeCloseBracketSwitch; + return Style.BreakBeforeCloseBracketFunction; } if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) && Right.is(TT_TrailingAnnotation) && - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { + Style.BreakBeforeCloseBracketFunction) { return false; } diff --git a/clang/unittests/Format/AlignBracketsTest.cpp b/clang/unittests/Format/AlignBracketsTest.cpp index ea8db51a4d18e..10ca5fb7da1ce 100644 --- a/clang/unittests/Format/AlignBracketsTest.cpp +++ b/clang/unittests/Format/AlignBracketsTest.cpp @@ -28,7 +28,7 @@ TEST_F(AlignBracketsTest, AlignsAfterOpenBracket) { "SomeLongVariableName->someFunction(foooooooo(aaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaa));"); FormatStyle Style = getLLVMStyle(); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaa aaaaaaaa, aaaaaaaaa aaaaaaa) {}", Style); @@ -64,7 +64,7 @@ TEST_F(AlignBracketsTest, AlignsAfterOpenBracket) { Style); Style.ColumnLimit = 80; - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; Style.BinPackArguments = false; Style.BinPackParameters = FormatStyle::BPPS_OnePerLine; verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" @@ -115,7 +115,9 @@ TEST_F(AlignBracketsTest, AlignsAfterOpenBracket) { " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZZZZZZZZZZZZZZZZZZZZZZZZZ()));", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakBeforeCloseBracketFunction = true; + Style.BreakBeforeCloseBracketBracedList = true; Style.BinPackArguments = false; Style.BinPackParameters = FormatStyle::BPPS_OnePerLine; verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" @@ -254,7 +256,8 @@ TEST_F(AlignBracketsTest, AlignAfterOpenBracketBlockIndent) { "argument5));", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakBeforeCloseBracketFunction = true; verifyFormat(Short, Style); verifyFormat( @@ -378,7 +381,8 @@ TEST_F(AlignBracketsTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakBeforeCloseBracketFunction = true; verifyFormat("if (foo()) {\n" " return;\n" @@ -440,7 +444,8 @@ TEST_F(AlignBracketsTest, AlignAfterOpenBracketBlockIndentForStatement) { "}", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakBeforeCloseBracketFunction = true; verifyFormat("for (int i = 0; i < 5; ++i) {\n" " doSomething();\n" @@ -457,7 +462,8 @@ TEST_F(AlignBracketsTest, AlignAfterOpenBracketBlockIndentForStatement) { TEST_F(AlignBracketsTest, AlignAfterOpenBracketBlockIndentInitializers) { auto Style = getLLVMStyleWithColumns(60); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketBracedList = true; + Style.BreakBeforeCloseBracketBracedList = true; // Aggregate initialization. verifyFormat("int LooooooooooooooooooooooooongVariable[2] = {\n" " 10000000, 20000000\n" @@ -611,13 +617,13 @@ TEST_F(AlignBracketsTest, AllowAllArgumentsOnNextLineDontAlign) { StringRef Input = "functionCall(paramA, paramB, paramC);\n" "void functionDecl(int A, int B, int C);"; Style.AllowAllArgumentsOnNextLine = false; - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; verifyFormat(StringRef("functionCall(paramA, paramB,\n" " paramC);\n" "void functionDecl(int A, int B,\n" " int C);"), Input, Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; + Style.AlignAfterOpenBracket = true; verifyFormat(StringRef("functionCall(paramA, paramB,\n" " paramC);\n" "void functionDecl(int A, int B,\n" @@ -625,13 +631,14 @@ TEST_F(AlignBracketsTest, AllowAllArgumentsOnNextLineDontAlign) { Input, Style); // However, BAS_AlwaysBreak and BAS_BlockIndent should take precedence over // AllowAllArgumentsOnNextLine. - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; verifyFormat(StringRef("functionCall(\n" " paramA, paramB, paramC);\n" "void functionDecl(\n" " int A, int B, int C);"), Input, Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakBeforeCloseBracketFunction = true; verifyFormat("functionCall(\n" " paramA, paramB, paramC\n" ");\n" @@ -639,11 +646,12 @@ TEST_F(AlignBracketsTest, AllowAllArgumentsOnNextLineDontAlign) { " int A, int B, int C\n" ");", Input, Style); + Style.BreakBeforeCloseBracketFunction = false; // When AllowAllArgumentsOnNextLine is set, we prefer breaking before the // first argument. Style.AllowAllArgumentsOnNextLine = true; - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; verifyFormat(StringRef("functionCall(\n" " paramA, paramB, paramC);\n" "void functionDecl(\n" @@ -651,13 +659,14 @@ TEST_F(AlignBracketsTest, AllowAllArgumentsOnNextLineDontAlign) { Input, Style); // It wouldn't fit on one line with aligned parameters so this setting // doesn't change anything for BAS_Align. - Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; + Style.AlignAfterOpenBracket = true; + Style.BreakAfterOpenBracketFunction = false; verifyFormat(StringRef("functionCall(paramA, paramB,\n" " paramC);\n" "void functionDecl(int A, int B,\n" " int C);"), Input, Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.BreakAfterOpenBracketFunction = true; verifyFormat(StringRef("functionCall(\n" " paramA, paramB, paramC);\n" "void functionDecl(\n" @@ -678,13 +687,14 @@ TEST_F(AlignBracketsTest, FormatsDeclarationBreakAlways) { // Ensure AlignAfterOpenBracket interacts correctly with BinPackParameters set // to BPPS_AlwaysOnePerLine. - BreakAlways.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + BreakAlways.BreakAfterOpenBracketFunction = true; verifyFormat( "void someLongFunctionName(\n" " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " int b);", BreakAlways); - BreakAlways.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + BreakAlways.BreakAfterOpenBracketFunction = true; + BreakAlways.BreakBeforeCloseBracketFunction = true; verifyFormat( "void someLongFunctionName(\n" " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" @@ -734,7 +744,7 @@ TEST_F(AlignBracketsTest, FormatsDefinitionBreakAlways) { // Ensure AlignAfterOpenBracket interacts correctly with BinPackParameters set // to BPPS_AlwaysOnePerLine. - BreakAlways.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + BreakAlways.BreakAfterOpenBracketFunction = true; verifyFormat( "void someLongFunctionName(\n" " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" @@ -743,7 +753,8 @@ TEST_F(AlignBracketsTest, FormatsDefinitionBreakAlways) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, b);\n" "}", BreakAlways); - BreakAlways.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + BreakAlways.BreakAfterOpenBracketFunction = true; + BreakAlways.BreakBeforeCloseBracketFunction = true; verifyFormat( "void someLongFunctionName(\n" " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" @@ -761,17 +772,17 @@ TEST_F(AlignBracketsTest, ParenthesesAndOperandAlignment) { verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" " bbbbbbbbbbbbbbbbbbbbbb);", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; + Style.AlignAfterOpenBracket = true; Style.AlignOperands = FormatStyle::OAS_DontAlign; verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" " bbbbbbbbbbbbbbbbbbbbbb);", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; Style.AlignOperands = FormatStyle::OAS_Align; verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" " bbbbbbbbbbbbbbbbbbbbbb);", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; Style.AlignOperands = FormatStyle::OAS_DontAlign; verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" " bbbbbbbbbbbbbbbbbbbbbb);", @@ -781,7 +792,10 @@ TEST_F(AlignBracketsTest, ParenthesesAndOperandAlignment) { TEST_F(AlignBracketsTest, BlockIndentAndNamespace) { auto Style = getLLVMStyleWithColumns(120); Style.AllowShortNamespacesOnASingleLine = true; - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakAfterOpenBracketBracedList = true; + Style.BreakBeforeCloseBracketFunction = true; + Style.BreakBeforeCloseBracketBracedList = true; verifyNoCrash( "namespace {\n" diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 6488e38badee7..43b21176962ea 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -172,6 +172,16 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(BinPackLongBracedList); CHECK_PARSE_BOOL(BreakAdjacentStringLiterals); CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations); + CHECK_PARSE_BOOL(BreakAfterOpenBracketBracedList); + CHECK_PARSE_BOOL(BreakAfterOpenBracketFunction); + CHECK_PARSE_BOOL(BreakAfterOpenBracketIf); + CHECK_PARSE_BOOL(BreakAfterOpenBracketLoop); + CHECK_PARSE_BOOL(BreakAfterOpenBracketSwitch); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketBracedList); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketFunction); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketIf); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketLoop); + CHECK_PARSE_BOOL(BreakBeforeCloseBracketSwitch); CHECK_PARSE_BOOL(BreakBeforeTemplateCloser); CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); CHECK_PARSE_BOOL(BreakStringLiterals); @@ -533,20 +543,23 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma, FormatStyle::ETC_Remove); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, - FormatStyle::BAS_Align); - CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, - FormatStyle::BAS_DontAlign); + Style.AlignAfterOpenBracket = false; + CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, true); + CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, false); + // For backward compatibility: CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket, - FormatStyle::BAS_AlwaysBreak); + true); + CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak\n" + "BreakAfterOpenBracketIf: false", + BreakAfterOpenBracketIf, false); + CHECK_PARSE("BreakAfterOpenBracketLoop: true\n" + "AlignAfterOpenBracket: AlwaysBreak", + BreakAfterOpenBracketLoop, true); + CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, false); CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket, - FormatStyle::BAS_BlockIndent); - // For backward compatibility: - CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, - FormatStyle::BAS_DontAlign); - CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, - FormatStyle::BAS_Align); + true); + Style.AlignAfterOpenBracket = false; + CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, true); Style.AlignEscapedNewlines = FormatStyle::ENAS_Left; CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines, diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d45babe1b82ad..ca9e7925e5e95 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -5126,7 +5126,8 @@ TEST_F(FormatTest, DesignatedInitializers) { TEST_F(FormatTest, BracedInitializerIndentWidth) { auto Style = getLLVMStyleWithColumns(60); Style.BinPackArguments = true; - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakAfterOpenBracketBracedList = true; Style.BracedInitializerIndentWidth = 6; // Non-initializing braces are unaffected by BracedInitializerIndentWidth. @@ -5302,7 +5303,8 @@ TEST_F(FormatTest, BracedInitializerIndentWidth) { Style); // Aligning after open braces unaffected by BracedInitializerIndentWidth. - Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; + Style.AlignAfterOpenBracket = true; + Style.BreakAfterOpenBracketBracedList = false; verifyFormat("SomeStruct s{\"xxxxxxxxxxxxx\", \"yyyyyyyyyyyyy\",\n" " \"zzzzzzzzzzzzz\"};", Style); @@ -7459,7 +7461,7 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { Style.IndentWidth = 4; Style.TabWidth = 4; Style.UseTab = FormatStyle::UT_Always; - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; Style.AlignOperands = FormatStyle::OAS_DontAlign; verifyFormat("return someVeryVeryLongConditionThatBarelyFitsOnALine\n" "\t&& (someOtherLongishConditionPart1\n" @@ -7470,7 +7472,7 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { Style); Style = getLLVMStyleWithColumns(20); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; Style.BinPackParameters = FormatStyle::BPPS_OnePerLine; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; Style.ContinuationIndentWidth = 2; @@ -7632,7 +7634,7 @@ TEST_F(FormatTest, NoOperandAlignment) { " * cccccccccccccccccccccccccccccccccccc;", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; verifyFormat("return (a > b\n" " // comment1\n" " // comment2\n" @@ -11248,7 +11250,7 @@ TEST_F(FormatTest, BreakBeforeTemplateCloser) { TEST_F(FormatTest, WrapsTemplateParameters) { FormatStyle Style = getLLVMStyle(); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; verifyFormat( "template struct q {};\n" @@ -11256,7 +11258,7 @@ TEST_F(FormatTest, WrapsTemplateParameters) { " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n" " y;", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.AlignAfterOpenBracket = false; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; verifyFormat( "template struct r {};\n" @@ -11264,7 +11266,7 @@ TEST_F(FormatTest, WrapsTemplateParameters) { " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n" " y;", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; verifyFormat("template struct s {};\n" "extern s<\n" @@ -11274,7 +11276,7 @@ TEST_F(FormatTest, WrapsTemplateParameters) { "aaaaaaaaaaaaaaaaaaaaaa>\n" " y;", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; verifyFormat("template struct t {};\n" "extern t<\n" @@ -14302,7 +14304,7 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { "};", NoBinPacking); - NoBinPacking.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + NoBinPacking.BreakAfterOpenBracketBracedList = true; verifyFormat("static uint8 CddDp83848Reg[] = {\n" " CDDDP83848_BMCR_REGISTER,\n" " CDDDP83848_BMSR_REGISTER,\n" @@ -15972,13 +15974,14 @@ TEST_F(FormatTest, BreaksStringLiteralOperands) { // In a function call with two operands, with AlignAfterOpenBracket enabled, // the first must be broken with a line break before it. FormatStyle Style = getLLVMStyleWithColumns(25); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; verifyFormat("someFunction(\n" " \"long long long \"\n" " \"long\",\n" " a);", "someFunction(\"long long long long\", a);", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Style.BreakAfterOpenBracketFunction = true; + Style.BreakBeforeCloseBracketFunction = true; verifyFormat("someFunction(\n" " \"long long long \"\n" " \"long\",\n" @@ -17773,7 +17776,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) { Spaces.ColumnLimit = 80; Spaces.IndentWidth = 4; - Spaces.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Spaces.BreakAfterOpenBracketFunction = true; verifyFormat("void foo( ) {\n" " size_t foo = (*(function))(\n" " Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, " @@ -17798,7 +17801,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) { "}", Spaces); - Spaces.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + Spaces.BreakAfterOpenBracketFunction = true; + Spaces.BreakBeforeCloseBracketFunction = true; verifyFormat("void foo( ) {\n" " size_t foo = (*(function))(\n" " Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, " @@ -22827,7 +22831,7 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) { ": aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; verifyFormat( "SomeLongTemplateVariableName<\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>", @@ -24082,7 +24086,7 @@ TEST_F(FormatTest, FormatsLambdas) { " return aFunkyFunctionCall(qux);\n" " }} {}", Style); - Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakAfterOpenBracketFunction = true; // FIXME: The following test should pass, but fails at the time of writing. #if 0 // As long as all the non-lambda arguments fit on a single line, AlwaysBreak diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 91577b9a49167..4847151c14b33 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -2883,7 +2883,7 @@ TEST_F(FormatTestJS, DontBreakFieldsAsGoToLabels) { TEST_F(FormatTestJS, BreakAfterOpenBracket) { auto Style = getGoogleStyle(FormatStyle::LK_JavaScript); - EXPECT_EQ(Style.AlignAfterOpenBracket, FormatStyle::BAS_AlwaysBreak); + EXPECT_EQ(Style.BreakAfterOpenBracketFunction, true); verifyFormat("ctrl.onCopy(/** @type {!WizEvent}*/ (\n" " {event, targetElement: {el: () => selectedElement}}));", Style);