[clang] 5daa25f - clang-format: support aligned nested conditionals formatting
Author: Francois Ferrand Date: 2020-04-22T17:36:33+02:00 New Revision: 5daa25fd7a184524759b6ad065a8bd7e95aa149a URL: https://github.com/llvm/llvm-project/commit/5daa25fd7a184524759b6ad065a8bd7e95aa149a DIFF: https://github.com/llvm/llvm-project/commit/5daa25fd7a184524759b6ad065a8bd7e95aa149a.diff LOG: clang-format: support aligned nested conditionals formatting When multiple ternary operators are chained, e.g. like an if/else-if/ else-if/.../else sequence, clang-format will keep aligning the colon with the question mark, which increases the indent for each conditionals: int a = condition1 ? result1 : condition2 ? result2 : condition3 ? result3 : result4; This patch detects the situation (e.g. conditionals used in false branch of another conditional), to avoid indenting in that case: int a = condition1 ? result1 : condition2 ? result2 : condition3 ? result3 : result4; When BreakBeforeTernaryOperators is false, this will format like this: int a = condition1 ? result1 : condition2 ? result2 : conditino3 ? result3 : result4; Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/ContinuationIndenter.h clang/lib/Format/WhitespaceManager.cpp clang/lib/Format/WhitespaceManager.h clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index e70ae7efb0c3..8f1089dc81cb 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -367,6 +367,12 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() && !Current.isOneOf(tok::r_paren, tok::r_brace)) return true; + if (State.Stack.back().IsChainedConditional && + ((Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) && +Current.is(tok::colon)) || + (!Style.BreakBeforeTernaryOperators && Previous.is(TT_ConditionalExpr) && +Previous.is(tok::colon +return true; if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) || (Previous.is(TT_ArrayInitializerLSquare) && Previous.ParameterCount > 1) || @@ -1022,8 +1028,21 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { if (State.Stack.back().QuestionColumn != 0 && ((NextNonComment->is(tok::colon) && NextNonComment->is(TT_ConditionalExpr)) || - Previous.is(TT_ConditionalExpr))) + Previous.is(TT_ConditionalExpr))) { +if (((NextNonComment->is(tok::colon) && NextNonComment->Next && + !NextNonComment->Next->FakeLParens.empty() && + NextNonComment->Next->FakeLParens.back() == prec::Conditional) || + (Previous.is(tok::colon) && !Current.FakeLParens.empty() && + Current.FakeLParens.back() == prec::Conditional)) && +!State.Stack.back().IsWrappedConditional) { + //NOTE: we may tweak this slightly: + //* not remove the 'lead' ContinuationIndentWidth + //* always un-indent by the operator when BreakBeforeTernaryOperators=true + unsigned Indent = State.Stack.back().Indent - Style.ContinuationIndentWidth; + return Indent; +} return State.Stack.back().QuestionColumn; + } if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) return State.Stack.back().VariablePos; if ((PreviousNonComment && @@ -1144,6 +1163,10 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, if (Current.is(TT_ArraySubscriptLSquare) && State.Stack.back().StartOfArraySubscripts == 0) State.Stack.back().StartOfArraySubscripts = State.Column; + if (Current.is(TT_ConditionalExpr) && Current.is(tok::question) && + ((Current.MustBreakBefore) || + (Current.getNextNonComment() && Current.getNextNonComment()->MustBreakBefore))) +State.Stack.back().IsWrappedConditional = true; if (Style.BreakBeforeTernaryOperators && Current.is(tok::question)) State.Stack.back().QuestionColumn = State.Column; if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) { @@ -1284,6 +1307,8 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, NewParenState.Tok = nullptr; NewParenState.ContainsLineBreak = false; NewParenState.LastOperatorWrapped = true; +NewParenState.IsChainedConditional = false; +NewParenState.IsWrappedConditional = false; NewParenState.NoLineBreak = NewParenState.NoLineBreak || State.Stack.back().NoLineBreakInOperand; @@ -1316,14 +1341,20 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
[clang] 3d61b11 - clang-format: Introduce stricter AlignOperands flag
Author: Francois Ferrand Date: 2020-04-22T17:36:38+02:00 New Revision: 3d61b1120e8267aa39f4c9a33d618dbaec4ec6fa URL: https://github.com/llvm/llvm-project/commit/3d61b1120e8267aa39f4c9a33d618dbaec4ec6fa DIFF: https://github.com/llvm/llvm-project/commit/3d61b1120e8267aa39f4c9a33d618dbaec4ec6fa.diff LOG: clang-format: Introduce stricter AlignOperands flag Summary: Even when BreakBeforeBinaryOperators is set, AlignOperands kept aligning the beginning of the line, even when it could align the actual operands (e.g. after an assignment). With this patch, there is an option to actually align the operands, so that the operator gets right-aligned with the equal sign or return operator: int a = bb + cc; return aaa && bbb; This not happen in parentheses, to avoid 'breaking' the indentation: if (a && b) return; Reviewers: krasimir, djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D32478 Added: Modified: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/ContinuationIndenter.h clang/lib/Format/Format.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/FormatTestJS.cpp Removed: diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 6d486224e3c2..e5a69fdb9c5a 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -270,17 +270,49 @@ the configuration (without a prefix: ``Auto``). -**AlignOperands** (``bool``) +**AlignOperands** (``OperandAlignmentStyle``) If ``true``, horizontally align operands of binary and ternary expressions. - Specifically, this aligns operands of a single expression that needs to be - split over multiple lines, e.g.: + Possible values: + + * ``OAS_DontAlign`` (in configuration: ``DontAlign``) +Do not align operands of binary and ternary expressions. +The wrapped lines are indented ``ContinuationIndentWidth`` spaces from +the start of the line. + + * ``OAS_Align`` (in configuration: ``Align``) +Horizontally align operands of binary and ternary expressions. + +Specifically, this aligns operands of a single expression that needs +to be split over multiple lines, e.g.: + +.. code-block:: c++ + + int aaa = bbb + +ccc; + +When ``BreakBeforeBinaryOperators`` is set, the wrapped operator is +aligned with the operand on the first line. + +.. code-block:: c++ + + int aaa = bbb ++ ccc; + + * ``OAS_AlignAfterOperator`` (in configuration: ``AlignAfterOperator``) +Horizontally align operands of binary and ternary expressions. + +This is similar to ``AO_Align``, except when +``BreakBeforeBinaryOperators`` is set, the operator is un-indented so +that the wrapped operand is aligned with the operand on the first line. + +.. code-block:: c++ + + int aaa = bbb + + ccc; - .. code-block:: c++ -int aaa = bbb + - ccc; **AlignTrailingComments** (``bool``) If ``true``, aligns trailing comments. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 2b2edc4adc11..f5fa6b44a127 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -153,16 +153,43 @@ struct FormatStyle { /// Options for aligning backslashes in escaped newlines. EscapedNewlineAlignmentStyle AlignEscapedNewlines; + /// Different styles for aligning operands. + enum OperandAlignmentStyle { +/// Do not align operands of binary and ternary expressions. +/// The wrapped lines are indented ``ContinuationIndentWidth`` spaces from +/// the start of the line. +OAS_DontAlign, +/// Horizontally align operands of binary and ternary expressions. +/// +/// Specifically, this aligns operands of a single expression that needs +/// to be split over multiple lines, e.g.: +/// \code +/// int aaa = bbb + +/// ccc; +/// \endcode +/// +/// When ``BreakBeforeBinaryOperators`` is set, the wrapped operator is +/// aligned with the operand on the first line. +/// \code +/// int aaa = bbb +/// + ccc; +/// \endcode +OAS_Align, +/// Horizontally align operands of binary and ternary expressions. +/// +/// This is similar to ``AO_Align``, except when +/// ``BreakBeforeBinaryOperators`` is set, the operator is un-indented so +/// that the wrapped operand is aligned with the operand on the first line. +/// \code +/// int aaa = bbb +
[clang] 4db9409 - clang-format: support aligned nested conditionals formatting
Author: Francois Ferrand Date: 2020-05-15T16:38:25+02:00 New Revision: 4db94094b469b4715d08ef37f1799bf3ea7ca8ea URL: https://github.com/llvm/llvm-project/commit/4db94094b469b4715d08ef37f1799bf3ea7ca8ea DIFF: https://github.com/llvm/llvm-project/commit/4db94094b469b4715d08ef37f1799bf3ea7ca8ea.diff LOG: clang-format: support aligned nested conditionals formatting Summary: When multiple ternary operators are chained, e.g. like an if/else-if/ else-if/.../else sequence, clang-format will keep aligning the colon with the question mark, which increases the indent for each conditionals: int a = condition1 ? result1 : condition2 ? result2 : condition3 ? result3 : result4; This patch detects the situation (e.g. conditionals used in false branch of another conditional), to avoid indenting in that case: int a = condition1 ? result1 : condition2 ? result2 : condition3 ? result3 : result4; When BreakBeforeTernaryOperators is false, this will format like this: int a = condition1 ? result1 : condition2 ? result2 : conditino3 ? result3 : result4; This formatting style is referenced here: https://www.fluentcpp.com/2018/02/27/replace-else-if-ternary-operator/ and here: https://marcmutz.wordpress.com/2010/10/14/top-5-reasons-you-should-love-your-ternary-operator/ Reviewers: krasimir, djasper, klimek, MyDeveloperDay Reviewed By: MyDeveloperDay Subscribers: hokein, dyung, MyDeveloperDay, acoomans, cfe-commits Tags: #clang, #clang-format Differential Revision: https://reviews.llvm.org/D50078 Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/ContinuationIndenter.h clang/lib/Format/WhitespaceManager.cpp clang/lib/Format/WhitespaceManager.h clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index cf885240a4f2..5dc45732ed15 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -367,6 +367,12 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() && !Current.isOneOf(tok::r_paren, tok::r_brace)) return true; + if (State.Stack.back().IsChainedConditional && + ((Style.BreakBeforeTernaryOperators && Current.is(TT_ConditionalExpr) && +Current.is(tok::colon)) || + (!Style.BreakBeforeTernaryOperators && Previous.is(TT_ConditionalExpr) && +Previous.is(tok::colon +return true; if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) || (Previous.is(TT_ArrayInitializerLSquare) && Previous.ParameterCount > 1) || @@ -1022,8 +1028,23 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { if (State.Stack.back().QuestionColumn != 0 && ((NextNonComment->is(tok::colon) && NextNonComment->is(TT_ConditionalExpr)) || - Previous.is(TT_ConditionalExpr))) + Previous.is(TT_ConditionalExpr))) { +if (((NextNonComment->is(tok::colon) && NextNonComment->Next && + !NextNonComment->Next->FakeLParens.empty() && + NextNonComment->Next->FakeLParens.back() == prec::Conditional) || + (Previous.is(tok::colon) && !Current.FakeLParens.empty() && + Current.FakeLParens.back() == prec::Conditional)) && +!State.Stack.back().IsWrappedConditional) { + // NOTE: we may tweak this slightly: + //* not remove the 'lead' ContinuationIndentWidth + //* always un-indent by the operator when + //BreakBeforeTernaryOperators=true + unsigned Indent = + State.Stack.back().Indent - Style.ContinuationIndentWidth; + return Indent; +} return State.Stack.back().QuestionColumn; + } if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) return State.Stack.back().VariablePos; if ((PreviousNonComment && @@ -1144,6 +1165,11 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, if (Current.is(TT_ArraySubscriptLSquare) && State.Stack.back().StartOfArraySubscripts == 0) State.Stack.back().StartOfArraySubscripts = State.Column; + if (Current.is(TT_ConditionalExpr) && Current.is(tok::question) && + ((Current.MustBreakBefore) || + (Current.getNextNonComment() && +Current.getNextNonComment()->MustBreakBefore))) +State.Stack.back().IsWrappedConditional = true; if (Style.BreakBeforeTernaryOperators && Current.is(tok::question)) State.Stack.back().QuestionColumn = State.Column; if (!Style.BreakBeforeTernaryOperators && Current.isNot(tok::colon)) { @@ -1284,6 +1310,8 @@ void ContinuationIndenter::moveStat
[clang] 0ee04e6 - [clang-format] Fix AlignOperands when BreakBeforeBinaryOperators is set
Author: Francois Ferrand Date: 2020-05-15T16:40:31+02:00 New Revision: 0ee04e6e0d0e1c808dc6c70ff7b92b35f960b627 URL: https://github.com/llvm/llvm-project/commit/0ee04e6e0d0e1c808dc6c70ff7b92b35f960b627 DIFF: https://github.com/llvm/llvm-project/commit/0ee04e6e0d0e1c808dc6c70ff7b92b35f960b627.diff LOG: [clang-format] Fix AlignOperands when BreakBeforeBinaryOperators is set Summary: Even when BreakBeforeBinaryOperators is set, AlignOperands kept aligning the beginning of the line, even when it could align the actual operands (e.g. after an assignment). With this patch, the operands are actually aligned, and the operator gets aligned with the equal sign: int a = bb + cc; This not happen in tests, to avoid 'breaking' the indentation: if (a && b) return; Reviewers: krasimir, djasper, klimek, MyDeveloperDay Reviewed By: MyDeveloperDay Subscribers: MyDeveloperDay, acoomans, cfe-commits, klimek Tags: #clang, #clang-format Differential Revision: https://reviews.llvm.org/D32478 Added: Modified: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/ContinuationIndenter.h clang/lib/Format/Format.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/FormatTestJS.cpp Removed: diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 3ea503a592ac..e367c3620e16 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -270,17 +270,49 @@ the configuration (without a prefix: ``Auto``). -**AlignOperands** (``bool``) +**AlignOperands** (``OperandAlignmentStyle``) If ``true``, horizontally align operands of binary and ternary expressions. - Specifically, this aligns operands of a single expression that needs to be - split over multiple lines, e.g.: + Possible values: + + * ``OAS_DontAlign`` (in configuration: ``DontAlign``) +Do not align operands of binary and ternary expressions. +The wrapped lines are indented ``ContinuationIndentWidth`` spaces from +the start of the line. + + * ``OAS_Align`` (in configuration: ``Align``) +Horizontally align operands of binary and ternary expressions. + +Specifically, this aligns operands of a single expression that needs +to be split over multiple lines, e.g.: + +.. code-block:: c++ + + int aaa = bbb + +ccc; + +When ``BreakBeforeBinaryOperators`` is set, the wrapped operator is +aligned with the operand on the first line. + +.. code-block:: c++ + + int aaa = bbb ++ ccc; + + * ``OAS_AlignAfterOperator`` (in configuration: ``AlignAfterOperator``) +Horizontally align operands of binary and ternary expressions. + +This is similar to ``AO_Align``, except when +``BreakBeforeBinaryOperators`` is set, the operator is un-indented so +that the wrapped operand is aligned with the operand on the first line. + +.. code-block:: c++ + + int aaa = bbb + + ccc; - .. code-block:: c++ -int aaa = bbb + - ccc; **AlignTrailingComments** (``bool``) If ``true``, aligns trailing comments. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index f8f2903dde57..9bc08a775647 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -153,16 +153,43 @@ struct FormatStyle { /// Options for aligning backslashes in escaped newlines. EscapedNewlineAlignmentStyle AlignEscapedNewlines; + /// Different styles for aligning operands. + enum OperandAlignmentStyle { +/// Do not align operands of binary and ternary expressions. +/// The wrapped lines are indented ``ContinuationIndentWidth`` spaces from +/// the start of the line. +OAS_DontAlign, +/// Horizontally align operands of binary and ternary expressions. +/// +/// Specifically, this aligns operands of a single expression that needs +/// to be split over multiple lines, e.g.: +/// \code +/// int aaa = bbb + +/// ccc; +/// \endcode +/// +/// When ``BreakBeforeBinaryOperators`` is set, the wrapped operator is +/// aligned with the operand on the first line. +/// \code +/// int aaa = bbb +/// + ccc; +/// \endcode +OAS_Align, +/// Horizontally align operands of binary and ternary expressions. +/// +/// This is similar to ``AO_Align``, except when +/// ``BreakBeforeBinaryOperators`` is set, the operator is un-indented so +/// that the wrapped operand is aligned with the operand on the first line. +/// \co
r332434 - clang-format: tweak formatting of variable initialization blocks
Author: typz Date: Wed May 16 01:03:52 2018 New Revision: 332434 URL: http://llvm.org/viewvc/llvm-project?rev=332434&view=rev Log: clang-format: tweak formatting of variable initialization blocks Summary: This patch changes the behavior of PenaltyBreakBeforeFirstCallParameter so that is does not apply after a brace, when Cpp11BracedListStyle is false. This way, variable initialization is wrapped more like an initializer than like a function call, which is more consistent with user expectations for this braced list style. With PenaltyBreakBeforeFirstCallParameter=200, this gives the following code: (with Cpp11BracedListStyle=false) Before : const std::unordered_map Something::MyHashTable = { { "a", 0 }, { "b", 1 }, { "c", 2 } }; After : const std::unordered_set Something::MyUnorderedSet = { { "a", 0 }, { "b", 1 }, { "c", 2 } }; Reviewers: krasimir, djasper, klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D43290 Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=332434&r1=332433&r2=332434&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Wed May 16 01:03:52 2018 @@ -2311,6 +2311,8 @@ unsigned TokenAnnotator::splitPenalty(co if (Left.opensScope()) { if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign) return 0; +if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle) + return 19; return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter : 19; } @@ -3048,6 +3050,9 @@ bool TokenAnnotator::canBreakBefore(cons if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) && Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0) return false; + if (Left.is(tok::equal) && Right.is(tok::l_brace) && + !Style.Cpp11BracedListStyle) +return false; if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen)) return false; if (Left.is(tok::l_paren) && Left.Previous && Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=332434&r1=332433&r2=332434&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Wed May 16 01:03:52 2018 @@ -6708,6 +6708,15 @@ TEST_F(FormatTest, LayoutCxx11BraceIniti "};"); verifyFormat("#define A {a, a},"); + // Avoid breaking between equal sign and opening brace + FormatStyle AvoidBreakingFirstArgument = getLLVMStyle(); + AvoidBreakingFirstArgument.PenaltyBreakBeforeFirstCallParameter = 200; + verifyFormat("const std::unordered_map MyHashTable =\n" + "{{\"a\", 0},\n" + " {\"b\", 1},\n" + " {\"c\", 2}};", + AvoidBreakingFirstArgument); + // Binpacking only if there is no trailing comma verifyFormat("const Aa a = {aa, bb,\n" " cc, dd};", @@ -6864,6 +6873,21 @@ TEST_F(FormatTest, LayoutCxx11BraceIniti verifyFormat("vector foo = { ::SomeGlobalFunction() };", ExtraSpaces); verifyFormat("const struct A a = { .a = 1, .b = 2 };", ExtraSpaces); verifyFormat("const struct A a = { [0] = 1, [1] = 2 };", ExtraSpaces); + + // Avoid breaking between initializer/equal sign and opening brace + ExtraSpaces.PenaltyBreakBeforeFirstCallParameter = 200; + verifyFormat("const std::unordered_map MyHashTable = {\n" + " { \"a\", 0 },\n" + " { \"b\", 1 },\n" + " { \"c\", 2 }\n" + "};", + ExtraSpaces); + verifyFormat("const std::unordered_map MyHashTable{\n" + " { \"a\", 0 },\n" + " { \"b\", 1 },\n" + " { \"c\", 2 }\n" + "};", + ExtraSpaces); } TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r326426 - [clang-format] Add SpaceBeforeColon option
Author: typz Date: Thu Mar 1 02:09:13 2018 New Revision: 326426 URL: http://llvm.org/viewvc/llvm-project?rev=326426&view=rev Log: [clang-format] Add SpaceBeforeColon option Summary: When disabled, this option allows removing the space before colon, making it act more like the semi-colon. When enabled (default), the current behavior is not affected. This mostly affects C++11 loop, initializer list, inheritance list and container literals: class Foo: Bar {} Foo::Foo(): a(a) {} for (auto i: myList) {} f({a: 1, b: 2, c: 3}); Reviewers: krasimir, djasper Reviewed By: djasper Subscribers: xvallspl, teemperor, karies, cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D32525 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=326426&r1=326425&r2=326426&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Thu Mar 1 02:09:13 2018 @@ -1681,6 +1681,23 @@ the configuration (without a prefix: ``A int a = 5; vs. int a=5; a += 42a+=42; +**SpaceBeforeCtorInitializerColon** (``bool``) + If ``false``, spaces will be removed before constructor initializer + colon. + + .. code-block:: c++ + + true: false: + Foo::Foo() : a(a) {} Foo::Foo(): a(a) {} + +**SpaceBeforeInheritanceColon** (``bool``) + If ``false``, spaces will be removed before inheritance colon. + + .. code-block:: c++ + + true: false: + class Foo : Bar {} vs. class Foo: Bar {} + **SpaceBeforeParens** (``SpaceBeforeParensOptions``) Defines in which cases to put a space before opening parentheses. @@ -1725,6 +1742,15 @@ the configuration (without a prefix: ``A +**SpaceBeforeRangeBasedForLoopColon** (``bool``) + If ``false``, spaces will be removed before range-based for loop + colon. + + .. code-block:: c++ + + true: false: + for (auto v : values) {} vs. for(auto v: values) {} + **SpaceInEmptyParentheses** (``bool``) If ``true``, spaces may be inserted into ``()``. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=326426&r1=326425&r2=326426&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Thu Mar 1 02:09:13 2018 @@ -1525,6 +1525,21 @@ struct FormatStyle { /// \endcode bool SpaceBeforeAssignmentOperators; + /// \brief If ``false``, spaces will be removed before constructor initializer + /// colon. + /// \code + ///true: false: + ///Foo::Foo() : a(a) {} Foo::Foo(): a(a) {} + /// \endcode + bool SpaceBeforeCtorInitializerColon; + + /// \brief If ``false``, spaces will be removed before inheritance colon. + /// \code + ///true: false: + ///class Foo : Bar {} vs. class Foo: Bar {} + /// \endcode + bool SpaceBeforeInheritanceColon; + /// \brief Different ways to put a space before opening parentheses. enum SpaceBeforeParensOptions { /// Never put a space before opening parentheses. @@ -1563,6 +1578,14 @@ struct FormatStyle { /// \brief Defines in which cases to put a space before opening parentheses. SpaceBeforeParensOptions SpaceBeforeParens; + /// \brief If ``false``, spaces will be removed before range-based for loop + /// colon. + /// \code + ///true: false: + ///for (auto v : values) {} vs. for(auto v: values) {} + /// \endcode + bool SpaceBeforeRangeBasedForLoopColon; + /// \brief If ``true``, spaces may be inserted into ``()``. /// \code ///true:false: @@ -1744,7 +1767,12 @@ struct FormatStyle { SpaceAfterCStyleCast == R.SpaceAfterCStyleCast && SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword && SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators && + SpaceBeforeCtorInitializerColon == + R.SpaceBeforeCtorInitializerColon && + SpaceBeforeInheritanceColon == R.SpaceBeforeInheritanceColon && SpaceBeforeParens == R.SpaceBeforeParens && + SpaceBeforeRangeBasedForLoopColon == + R.SpaceBeforeRangeBasedForLoopColon &&
r332436 - clang-format: Allow optimizer to break template declaration.
Author: typz Date: Wed May 16 01:25:03 2018 New Revision: 332436 URL: http://llvm.org/viewvc/llvm-project?rev=332436&view=rev Log: clang-format: Allow optimizer to break template declaration. Summary: Introduce `PenaltyBreakTemplateDeclaration` to control the penalty, and change `AlwaysBreakTemplateDeclarations` to an enum with 3 modes: * `No` for regular, penalty based, wrapping of template declaration * `MultiLine` for always wrapping before multi-line declarations (e.g. same as legacy behavior when `AlwaysBreakTemplateDeclarations=false`) * `Yes` for always wrapping (e.g. same as legacy behavior when `AlwaysBreakTemplateDeclarations=true`) Reviewers: krasimir, djasper, klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D42684 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=332436&r1=332435&r2=332436&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Wed May 16 01:25:03 2018 @@ -490,15 +490,50 @@ the configuration (without a prefix: ``A """"; ""; -**AlwaysBreakTemplateDeclarations** (``bool``) - If ``true``, always break after the ``template<...>`` of a template - declaration. +**AlwaysBreakTemplateDeclarations** (``BreakTemplateDeclarationsStyle``) + The template declaration breaking style to use. + + Possible values: + + * ``BTDS_No`` (in configuration: ``No``) +Do not force break before declaration. +``PenaltyBreakTemplateDeclaration`` is taken into account. + +.. code-block:: c++ + + template T foo() { + } + template T foo(int a, + int b) { + } + + * ``BTDS_MultiLine`` (in configuration: ``MultiLine``) +Force break after template declaration only when the following +declaration spans multiple lines. + +.. code-block:: c++ + + template T foo() { + } + template + T foo(int a, + int b) { + } + + * ``BTDS_Yes`` (in configuration: ``Yes``) +Always break after template declaration. + +.. code-block:: c++ + + template + T foo() { + } + template + T foo(int a, + int b) { + } - .. code-block:: c++ - true: false: - template vs. template class C {}; - class C {}; **BinPackArguments** (``bool``) If ``false``, a function call's arguments will either be all on the @@ -1590,6 +1625,9 @@ the configuration (without a prefix: ``A **PenaltyBreakString** (``unsigned``) The penalty for each line break introduced inside a string literal. +**PenaltyBreakTemplateDeclaration** (``unsigned``) + The penalty for breaking after template declaration. + **PenaltyExcessCharacter** (``unsigned``) The penalty for each character outside of the column limit. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=332436&r1=332435&r2=332436&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed May 16 01:25:03 2018 @@ -351,14 +351,44 @@ struct FormatStyle { /// \endcode bool AlwaysBreakBeforeMultilineStrings; - /// If ``true``, always break after the ``template<...>`` of a template - /// declaration. - /// \code - ///true: false: - ///template vs. template class C {}; - ///class C {}; - /// \endcode - bool AlwaysBreakTemplateDeclarations; + /// Different ways to break after the template declaration. + enum BreakTemplateDeclarationsStyle { + /// Do not force break before declaration. + /// ``PenaltyBreakTemplateDeclaration`` is taken into account. + /// \code + ///template T foo() { + ///} + ///template T foo(int a, + ///int b) { + ///} + /// \endcode + BTDS_No, + /// Force break after template declaration only when the following + /// declaration spans multiple lines. + /// \code + ///template T foo() { + ///} + ///template + ///T foo(int
r324741 - clang-format: keep ObjC colon alignment with short object name
Author: typz Date: Fri Feb 9 07:41:56 2018 New Revision: 324741 URL: http://llvm.org/viewvc/llvm-project?rev=324741&view=rev Log: clang-format: keep ObjC colon alignment with short object name Summary: When the target object expression is short and the first selector name is long, clang-format used to break the colon alignment: [I performSelectorOnMainThread:@selector(loadAccessories) withObject:nil waitUntilDone:false]; This happens because the colon is placed at `ContinuationIndent + LongestObjCSelectorName`, so that any selector can be wrapped. This is however not needed in case the longest selector is the firstone, and not wrapped. To overcome this, this patch does not include the first selector in `LongestObjCSelectorName` computation (in TokenAnnotator), and lets `ContinuationIndenter` decide how to account for the first selector when wrapping. (Note this was already partly the case, see line 521 of ContinuationIndenter.cpp) This way, the code gets properly aligned whenever possible without breaking the continuation indent. [I performSelectorOnMainThread:@selector(loadAccessories) withObject:nil waitUntilDone:false]; [I // force break performSelectorOnMainThread:@selector(loadAccessories) withObject:nil waitUntilDone:false]; [I perform:@selector(loadAccessories) withSelectorOnMainThread:true waitUntilDone:false]; Reviewers: krasimir, djasper, klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D43121 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=324741&r1=324740&r2=324741&view=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Fri Feb 9 07:41:56 2018 @@ -701,7 +701,8 @@ unsigned ContinuationIndenter::addTokenO ? std::max(State.Stack.back().Indent, State.FirstIndent + Style.ContinuationIndentWidth) : State.Stack.back().Indent) + -NextNonComment->LongestObjCSelectorName; +std::max(NextNonComment->LongestObjCSelectorName, + NextNonComment->ColumnWidth); } } else if (State.Stack.back().AlignColons && State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) { @@ -900,7 +901,8 @@ unsigned ContinuationIndenter::getNewLin ? std::max(State.Stack.back().Indent, State.FirstIndent + Style.ContinuationIndentWidth) : State.Stack.back().Indent) + - NextNonComment->LongestObjCSelectorName - + std::max(NextNonComment->LongestObjCSelectorName, + NextNonComment->ColumnWidth) - NextNonComment->ColumnWidth; } if (!State.Stack.back().AlignColons) Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=324741&r1=324740&r2=324741&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri Feb 9 07:41:56 2018 @@ -591,12 +591,12 @@ private: BeforePrevious->is(tok::r_square) || Contexts.back().LongestObjCSelectorName == 0) { Tok->Previous->Type = TT_SelectorName; - if (Tok->Previous->ColumnWidth > - Contexts.back().LongestObjCSelectorName) -Contexts.back().LongestObjCSelectorName = -Tok->Previous->ColumnWidth; if (!Contexts.back().FirstObjCSelectorName) Contexts.back().FirstObjCSelectorName = Tok->Previous; + else if (Tok->Previous->ColumnWidth > + Contexts.back().LongestObjCSelectorName) +Contexts.back().LongestObjCSelectorName = +Tok->Previous->ColumnWidth; } } else if (Contexts.back().ColonIsForRangeExpr) { Tok->Type = TT_RangeBasedForLoopColon; Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=324741&r1=324740&r2=324741&view=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Fri Feb 9 07:41:56 2018 @@ -693,8 +693,8 @@ TEST_F(FormatTestObjC, FormatObjCMethodE // Formats pair-parameters. verifyFormat("[I drawRectOn:s
r326191 - clang-format: fix formatting of ObjC @synchronized blocks
Author: typz Date: Tue Feb 27 05:48:21 2018 New Revision: 326191 URL: http://llvm.org/viewvc/llvm-project?rev=326191&view=rev Log: clang-format: fix formatting of ObjC @synchronized blocks Summary: The blocks used to be formatted using the "default" behavior, and would thus be mistaken for function calls followed by blocks: this could lead to unexpected inlining of the block and extra line-break before the opening brace. They are now formatted similarly to `@autoreleasepool` blocks, as expected: @synchronized(self) { f(); } Reviewers: krasimir, djasper, klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D43114 Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=326191&r1=326190&r2=326191&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Feb 27 05:48:21 2018 @@ -1135,6 +1135,18 @@ void UnwrappedLineParser::parseStructura } addUnwrappedLine(); return; + case tok::objc_synchronized: +nextToken(); +if (FormatTok->Tok.is(tok::l_paren)) + // Skip synchronization object + parseParens(); +if (FormatTok->Tok.is(tok::l_brace)) { + if (Style.BraceWrapping.AfterObjCDeclaration) +addUnwrappedLine(); + parseBlock(/*MustBeDeclaration=*/false); +} +addUnwrappedLine(); +return; case tok::objc_try: // This branch isn't strictly necessary (the kw_try case below would // do this too after the tok::at is parsed above). But be explicit. Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=326191&r1=326190&r2=326191&view=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Tue Feb 27 05:48:21 2018 @@ -209,6 +209,24 @@ TEST_F(FormatTestObjC, FormatObjCGeneric "a);\n"); } +TEST_F(FormatTestObjC, FormatObjCSynchronized) { + verifyFormat("@synchronized(self) {\n" + " f();\n" + "}\n" + "@synchronized(self) {\n" + " f();\n" + "}\n"); + Style.BreakBeforeBraces = FormatStyle::BS_Allman; + verifyFormat("@synchronized(self)\n" + "{\n" + " f();\n" + "}\n" + "@synchronized(self)\n" + "{\n" + " f();\n" + "}\n"); +} + TEST_F(FormatTestObjC, FormatObjCInterface) { verifyFormat("@interface Foo : NSObject {\n" "@public\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r326192 - clang-format: use AfterControlStatement to format ObjC control blocks
Author: typz Date: Tue Feb 27 05:48:27 2018 New Revision: 326192 URL: http://llvm.org/viewvc/llvm-project?rev=326192&view=rev Log: clang-format: use AfterControlStatement to format ObjC control blocks ObjC defines `@autoreleasepool` and `@synchronized` control blocks. These used to be formatted according to the `AfterObjCDeclaration` brace- wrapping flag, which is not very consistent. This patch changes the behavior to use the `AfterControlStatement` flag instead. This should not affect the behavior unless a custom brace wrapping mode is used. Reviewers: krasimir, djasper, klimek, benhamilton Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D43232 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=326192&r1=326191&r2=326192&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Tue Feb 27 05:48:27 2018 @@ -662,7 +662,9 @@ struct FormatStyle { /// } /// \endcode bool AfterNamespace; -/// \brief Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..). +/// \brief Wrap ObjC definitions (interfaces, implementations...). +/// \note @autoreleasepool and @synchronized blocks are wrapped +/// according to `AfterControlStatement` flag. bool AfterObjCDeclaration; /// \brief Wrap struct definitions. /// \code Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=326192&r1=326191&r2=326192&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Tue Feb 27 05:48:27 2018 @@ -314,6 +314,14 @@ private: } return MergedLines; } +// Don't merge block with left brace wrapped after ObjC special blocks +if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() && +I[-1]->First->is(tok::at) && I[-1]->First->Next) { + tok::ObjCKeywordKind kwId = I[-1]->First->Next->Tok.getObjCKeywordID(); + if (kwId == clang::tok::objc_autoreleasepool || + kwId == clang::tok::objc_synchronized) +return 0; +} // Try to merge a block with left brace wrapped that wasn't yet covered if (TheLine->Last->is(tok::l_brace)) { return !Style.BraceWrapping.AfterFunction || Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=326192&r1=326191&r2=326192&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Feb 27 05:48:27 2018 @@ -1129,7 +1129,7 @@ void UnwrappedLineParser::parseStructura case tok::objc_autoreleasepool: nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BraceWrapping.AfterObjCDeclaration) + if (Style.BraceWrapping.AfterControlStatement) addUnwrappedLine(); parseBlock(/*MustBeDeclaration=*/false); } @@ -1141,7 +1141,7 @@ void UnwrappedLineParser::parseStructura // Skip synchronization object parseParens(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BraceWrapping.AfterObjCDeclaration) + if (Style.BraceWrapping.AfterControlStatement) addUnwrappedLine(); parseBlock(/*MustBeDeclaration=*/false); } Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=326192&r1=326191&r2=326192&view=diff == --- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Tue Feb 27 05:48:27 2018 @@ -187,7 +187,8 @@ TEST_F(FormatTestObjC, FormatObjCAutorel "@autoreleasepool {\n" " f();\n" "}\n"); - Style.BreakBeforeBraces = FormatStyle::BS_Allman; + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterControlStatement = true; verifyFormat("@autoreleasepool\n" "{\n" " f();\n" @@ -216,7 +217,8 @@ TEST_F(FormatTestObjC, FormatObjCSynchro "@synchronized(self) {\n" " f();\n" "}\n"); - Style.BreakBeforeBraces = FormatStyle::BS_Allman; + Style.BreakBefore
r334408 - clang-format: Introduce BreakInheritanceList option
Author: typz Date: Mon Jun 11 07:41:26 2018 New Revision: 334408 URL: http://llvm.org/viewvc/llvm-project?rev=334408&view=rev Log: clang-format: Introduce BreakInheritanceList option Summary: This option replaces the BreakBeforeInheritanceComma option with an enum, thus introducing a mode where the colon stays on the same line as constructor declaration: // When it fits on line: class A : public B, public C { ... }; // When it does not fit: class A : public B, public C { ... }; This matches the behavior of the `BreakConstructorInitializers` option, introduced in https://reviews.llvm.org/D32479. Reviewers: djasper, klimek Reviewed By: djasper Subscribers: mzeren-vmw, cfe-commits Differential Revision: https://reviews.llvm.org/D43015 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=334408&r1=334407&r2=334408&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Mon Jun 11 07:41:26 2018 @@ -994,18 +994,6 @@ the configuration (without a prefix: ``A -**BreakBeforeInheritanceComma** (``bool``) - If ``true``, in the class inheritance expression clang-format will - break before ``:`` and ``,`` if there is multiple inheritance. - - .. code-block:: c++ - - true: false: - class MyClass vs. class MyClass : public X, public Y { - : public X }; - , public Y { - }; - **BreakBeforeTernaryOperators** (``bool``) If ``true``, ternary operators will be placed after line breaks. @@ -1056,6 +1044,42 @@ the configuration (without a prefix: ``A +**BreakInheritanceList** (``BreakInheritanceListStyle``) + The inheritance list style to use. + + Possible values: + + * ``BILS_BeforeColon`` (in configuration: ``BeforeColon``) +Break inheritance list before the colon and after the commas. + +.. code-block:: c++ + +class Foo +: Base1, + Base2 +{}; + + * ``BILS_BeforeComma`` (in configuration: ``BeforeComma``) +Break inheritance list before the colon and commas, and align +the commas with the colon. + +.. code-block:: c++ + +Constructor() +: initializer1() +, initializer2() + + * ``BILS_AfterColon`` (in configuration: ``AfterColon``) +Break inheritance list after the colon and commas. + +.. code-block:: c++ + +Constructor() : +initializer1(), +initializer2() + + + **BreakStringLiterals** (``bool``) Allow breaking string literals when formatting. @@ -1122,7 +1146,7 @@ the configuration (without a prefix: ``A **ConstructorInitializerIndentWidth** (``unsigned``) The number of characters to use for indentation of constructor - initializer lists. + initializer lists as well as inheritance lists. **ContinuationIndentWidth** (``unsigned``) Indent width for line continuations. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=334408&r1=334407&r2=334408&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Mon Jun 11 07:41:26 2018 @@ -893,16 +893,35 @@ struct FormatStyle { /// \endcode std::string CommentPragmas; - /// If ``true``, in the class inheritance expression clang-format will - /// break before ``:`` and ``,`` if there is multiple inheritance. - /// \code - ///true: false: - ///class MyClass vs. class MyClass : public X, public Y { - ///: public X }; - ///, public Y { - ///}; - /// \endcode - bool BreakBeforeInheritanceComma; + /// Different ways to break inheritance list. + enum BreakInheritanceListStyle { +/// Break inheritance list before the colon and after the commas. +/// \code +/// class Foo +/// : Base1, +/// Base2 +/// {}; +/// \endcode +BILS_BeforeColon, +/// Break inheritance list before the colon and commas, and align +/// the commas with the colon. +/// \code +/// Constructor() +/// : initializer1() +/// , initializer2() +/// \endcode +BILS_BeforeComma, +/// Break inheritance list after the colon and commas. +/// \code +/// Constructor() : +/// initializer1(), +/// initializer2() +/// \end
r334709 - clang-format: Fix documentation generation
Author: typz Date: Thu Jun 14 06:32:14 2018 New Revision: 334709 URL: http://llvm.org/viewvc/llvm-project?rev=334709&view=rev Log: clang-format: Fix documentation generation Summary: It seems that the changes done to `ClangFormatStyleOptions.rst` @334408 are causing the generation of the documentation to fail, with the following error: Warning, treated as error: /llvm/tools/clang/docs/ClangFormatStyleOptions.rst:1060: WARNING: Definition list ends without a blank line; unexpected unindent. This is due to missing indent in some code block, and fixed by this patch. Reviewers: krasimir, djasper, klimek Reviewed By: krasimir Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D48161 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=334709&r1=334708&r2=334709&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Thu Jun 14 06:32:14 2018 @@ -1019,9 +1019,9 @@ the configuration (without a prefix: ``A .. code-block:: c++ -Constructor() -: initializer1(), - initializer2() + Constructor() + : initializer1(), + initializer2() * ``BCIS_BeforeComma`` (in configuration: ``BeforeComma``) Break constructor initializers before the colon and commas, and align @@ -1029,18 +1029,18 @@ the configuration (without a prefix: ``A .. code-block:: c++ -Constructor() -: initializer1() -, initializer2() + Constructor() + : initializer1() + , initializer2() * ``BCIS_AfterColon`` (in configuration: ``AfterColon``) Break constructor initializers after the colon and commas. .. code-block:: c++ -Constructor() : -initializer1(), -initializer2() + Constructor() : + initializer1(), + initializer2() @@ -1054,10 +1054,10 @@ the configuration (without a prefix: ``A .. code-block:: c++ -class Foo -: Base1, - Base2 -{}; + class Foo + : Base1, + Base2 + {}; * ``BILS_BeforeComma`` (in configuration: ``BeforeComma``) Break inheritance list before the colon and commas, and align @@ -1065,18 +1065,20 @@ the configuration (without a prefix: ``A .. code-block:: c++ -Constructor() -: initializer1() -, initializer2() + class Foo + : Base1 + , Base2 + {}; * ``BILS_AfterColon`` (in configuration: ``AfterColon``) Break inheritance list after the colon and commas. .. code-block:: c++ -Constructor() : -initializer1(), -initializer2() + class Foo : + Base1, + Base2 + {}; Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=334709&r1=334708&r2=334709&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Thu Jun 14 06:32:14 2018 @@ -840,24 +840,24 @@ struct FormatStyle { enum BreakConstructorInitializersStyle { /// Break constructor initializers before the colon and after the commas. /// \code -/// Constructor() -/// : initializer1(), -/// initializer2() +///Constructor() +///: initializer1(), +/// initializer2() /// \endcode BCIS_BeforeColon, /// Break constructor initializers before the colon and commas, and align /// the commas with the colon. /// \code -/// Constructor() -/// : initializer1() -/// , initializer2() +///Constructor() +///: initializer1() +///, initializer2() /// \endcode BCIS_BeforeComma, /// Break constructor initializers after the colon and commas. /// \code -/// Constructor() : -/// initializer1(), -/// initializer2() +///Constructor() : +///initializer1(), +///initializer2() /// \endcode BCIS_AfterColon }; @@ -897,25 +897,27 @@ struct FormatStyle { enum BreakInheritanceListStyle { /// Break inheritance list before the colon and after the commas. /// \code -/// class Foo -/// : Base1, -/// Base2 -/// {}; +///class Foo +///: Base1, +/// Base2 +///{}; /// \endcode BILS_BeforeColon, /// Break inheritance list before the colon and commas, and align /// the commas with the colon. /// \code -/// Constructor() -/// : initializer
r361984 - [NFC] clang-format: Use LLVM style in NamespaceEndCommentsFixerTest
Author: typz Date: Wed May 29 09:22:43 2019 New Revision: 361984 URL: http://llvm.org/viewvc/llvm-project?rev=361984&view=rev Log: [NFC] clang-format: Use LLVM style in NamespaceEndCommentsFixerTest As pointed out in https://reviews.llvm.org/D37813#inline-555026, the code which is formatted does not match LLVM formatting style. Technically this is not a problem since these tests bypass most of the formatter, but it can be misleading. Modified: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Modified: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp?rev=361984&r1=361983&r2=361984&view=diff == --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp (original) +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Wed May 29 09:22:43 2019 @@ -45,124 +45,124 @@ protected: TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) { EXPECT_EQ("namespace {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace", fixNamespaceEndComments("namespace {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}")); EXPECT_EQ("namespace {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace\n", fixNamespaceEndComments("namespace {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}\n")); EXPECT_EQ("namespace A {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace A", fixNamespaceEndComments("namespace A {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}")); EXPECT_EQ("inline namespace A {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace A", fixNamespaceEndComments("inline namespace A {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}")); EXPECT_EQ("namespace ::A {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace ::A", fixNamespaceEndComments("namespace ::A {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}")); EXPECT_EQ("namespace ::A::B {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace ::A::B", fixNamespaceEndComments("namespace ::A::B {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}")); EXPECT_EQ("namespace /**/::/**/A/**/::/**/B/**/ {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// namespace ::A::B", fixNamespaceEndComments("namespace /**/::/**/A/**/::/**/B/**/ {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}")); EXPECT_EQ("namespace A {\n" "namespace B {\n" -" int i;\n" +"int i;\n" "}\n" "}// namespace A", fixNamespaceEndComments("namespace A {\n" "namespace B {\n" -" int i;\n" +"int i;\n" "}\n" "}")); EXPECT_EQ("namespace A {\n" "namespace B {\n" -" int i;\n" -" int j;\n" +"int i;\n" +"int j;\n" "}// na
r361986 - [clang-format] Allow configuring list of function-like macros that resolve to a type
Author: typz Date: Wed May 29 09:30:47 2019 New Revision: 361986 URL: http://llvm.org/viewvc/llvm-project?rev=361986&view=rev Log: [clang-format] Allow configuring list of function-like macros that resolve to a type Summary: Adds a `TypenameMacros` configuration option that causes certain identifiers to be handled in a way similar to `typeof()`. This is enough to: - Prevent misinterpreting declarations of pointers to such types as expressions (`STACK_OF(int) * foo` -> `STACK_OF(int) *foo`), - Avoid surprising line breaks in variable/struct field declarations (`STACK_OF(int)\nfoo;` -> `STACK_OF(int) foo;`, see https://bugs.llvm.org/show_bug.cgi?id=30353). Reviewers: Typz, krasimir, djasper Reviewed By: Typz Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57184 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/FormatTokenLexer.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=361986&r1=361985&r2=361986&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Wed May 29 09:30:47 2019 @@ -1367,6 +1367,24 @@ the configuration (without a prefix: ``A For example: BOOST_FOREACH. +**TypenameMacros** (``std::vector``) + A vector of macros that should be interpreted as type declarations + instead of as function calls. + + These are expected to be macros of the form: + + .. code-block: c++ + +STACK_OF(...) + + In the .clang-format configuration file, this can be configured like: + + .. code-block: yaml + +TypenameMacros: ['STACK_OF', 'LIST'] + + For example: OpenSSL STACK_OF, BSD LIST_ENTRY. + **IncludeBlocks** (``IncludeBlocksStyle``) Dependent on the value, multiple ``#include`` blocks can be sorted as one and divided based on category. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=361986&r1=361985&r2=361986&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed May 29 09:30:47 2019 @@ -1160,6 +1160,22 @@ struct FormatStyle { /// For example: BOOST_FOREACH. std::vector ForEachMacros; + /// \brief A vector of macros that should be interpreted as type declarations + /// instead of as function calls. + /// + /// These are expected to be macros of the form: + /// \code + /// STACK_OF(...) + /// \endcode + /// + /// In the .clang-format configuration file, this can be configured like: + /// \code{.yaml} + /// TypenameMacros: ['STACK_OF', 'LIST'] + /// \endcode + /// + /// For example: OpenSSL STACK_OF, BSD LIST_ENTRY. + std::vector TypenameMacros; + /// A vector of macros that should be interpreted as complete /// statements. /// @@ -1952,7 +1968,8 @@ struct FormatStyle { SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && Standard == R.Standard && TabWidth == R.TabWidth && - StatementMacros == R.StatementMacros && UseTab == R.UseTab; + StatementMacros == R.StatementMacros && UseTab == R.UseTab && + TypenameMacros == R.TypenameMacros; } llvm::Optional GetLanguageStyle(LanguageKind Language) const; Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=361986&r1=361985&r2=361986&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Wed May 29 09:30:47 2019 @@ -505,6 +505,7 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=361986&r1=361985&r2=361986&view=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Wed May 29 09:30:47 2019 @@ -96,6 +96,7 @@ namespace format { TYPE(TrailingAnnotation) \ TYPE(TrailingReturnArrow) \ TYPE(TrailingUnaryOperator) \ + TYPE(TypenameMacro) \ TYPE(UnaryOperator) \ TYPE(CSharpStringLiteral)
r362740 - clang-format: better handle namespace macros
Author: typz Date: Thu Jun 6 13:06:23 2019 New Revision: 362740 URL: http://llvm.org/viewvc/llvm-project?rev=362740&view=rev Log: clang-format: better handle namespace macros Summary: Other macros are used to declare namespaces, and should thus be handled similarly. This is the case for crpcut's TESTSUITE macro, or for unittest-cpp's SUITE macro: TESTSUITE(Foo) { TEST(MyFirstTest) { assert(0); } } // TESTSUITE(Foo) This patch deals with this cases by introducing a new option to specify lists of namespace macros. Internally, it re-uses the system already in place for foreach and statement macros, to ensure there is no impact on performance. Reviewers: krasimir, djasper, klimek Reviewed By: klimek Subscribers: acoomans, cfe-commits, klimek Tags: #clang Differential Revision: https://reviews.llvm.org/D37813 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/FormatTokenLexer.cpp cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/lib/Format/TokenAnnotator.h cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=362740&r1=362739&r2=362740&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Thu Jun 6 13:06:23 2019 @@ -1782,6 +1782,19 @@ the configuration (without a prefix: ``A +**NamespaceMacros** (``std::vector``) + A vector of macros which are used to open namespace blocks. + + These are expected to be macros of the form: + + .. code-block:: c++ + +NAMESPACE(, ...) { + +} + + For example: TESTSUITE + **ObjCBinPackProtocolList** (``BinPackStyle``) Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when they go over ``ColumnLimit``. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=362740&r1=362739&r2=362740&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Thu Jun 6 13:06:23 2019 @@ -1195,6 +1195,18 @@ struct FormatStyle { /// For example: Q_UNUSED std::vector StatementMacros; + /// A vector of macros which are used to open namespace blocks. + /// + /// These are expected to be macros of the form: + /// \code + /// NAMESPACE(, ...) { + /// + /// } + /// \endcode + /// + /// For example: TESTSUITE + std::vector NamespaceMacros; + tooling::IncludeStyle IncludeStyle; /// Indent case labels one level from the switch statement. @@ -1942,6 +1954,7 @@ struct FormatStyle { MacroBlockEnd == R.MacroBlockEnd && MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && NamespaceIndentation == R.NamespaceIndentation && + NamespaceMacros == R.NamespaceMacros && ObjCBinPackProtocolList == R.ObjCBinPackProtocolList && ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=362740&r1=362739&r2=362740&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Thu Jun 6 13:06:23 2019 @@ -455,6 +455,7 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=362740&r1=362739&r2=362740&view=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Thu Jun 6 13:06:23 2019 @@ -71,6 +71,7 @@ namespace format { TYPE(LineComment) \ TYPE(MacroBlockBegin) \ TYPE(MacroBlockEnd) \ + TYPE(NamespaceMacro) \ TYPE(ObjCBlockLBrace) \ TYPE(ObjCBlockLParen) \ TYPE(ObjCDecl) \ @@ -531,8 +532,10 @@ struct
r343602 - clang-format: better handle statement macros
Author: typz Date: Tue Oct 2 09:37:51 2018 New Revision: 343602 URL: http://llvm.org/viewvc/llvm-project?rev=343602&view=rev Log: clang-format: better handle statement macros Summary: Some macros are used in the body of function, and actually contain the trailing semicolon: they should thus be automatically followed by a new line, and not get merged with the next line. This is for example the case with Qt's Q_UNUSED macro: void foo(int a, int b) { Q_UNUSED(a) return b; } This patch deals with these cases by introducing a new option to specify list of statement macros. This re-uses the system already in place for foreach macros, to ensure there is no impact on performance. Reviewers: krasimir, djasper, klimek Reviewed By: krasimir Subscribers: acoomans, mgrang, alexfh, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D33440 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/FormatTokenLexer.cpp cfe/trunk/lib/Format/FormatTokenLexer.h cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/lib/Format/UnwrappedLineParser.h cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=343602&r1=343601&r2=343602&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Tue Oct 2 09:37:51 2018 @@ -1979,6 +1979,15 @@ the configuration (without a prefix: ``A +**StatementMacros** (``std::vector``) + A vector of macros that should be interpreted as complete statements. + + Typical macros are expressions, and require a semi-colon to be + added; sometimes this is not the case, and this allows to make + clang-format aware of such cases. + + For example: Q_UNUSED + **TabWidth** (``unsigned``) The number of columns used for tab stops. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=343602&r1=343601&r2=343602&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Tue Oct 2 09:37:51 2018 @@ -1051,6 +1051,16 @@ struct FormatStyle { /// For example: BOOST_FOREACH. std::vector ForEachMacros; + /// A vector of macros that should be interpreted as complete + /// statements. + /// + /// Typical macros are expressions, and require a semi-colon to be + /// added; sometimes this is not the case, and this allows to make + /// clang-format aware of such cases. + /// + /// For example: Q_UNUSED + std::vector StatementMacros; + tooling::IncludeStyle IncludeStyle; /// Indent case labels one level from the switch statement. @@ -1766,7 +1776,7 @@ struct FormatStyle { SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && Standard == R.Standard && TabWidth == R.TabWidth && - UseTab == R.UseTab; + StatementMacros == R.StatementMacros && UseTab == R.UseTab; } llvm::Optional GetLanguageStyle(LanguageKind Language) const; Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=343602&r1=343601&r2=343602&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Tue Oct 2 09:37:51 2018 @@ -469,6 +469,7 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=343602&r1=343601&r2=343602&view=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Tue Oct 2 09:37:51 2018 @@ -86,6 +86,7 @@ namespace format { TYPE(RegexLiteral) \ TYPE(SelectorName) \ TYPE(StartOfName) \ + TYPE(StatementMacro) \ TYPE(StructuredBindingLSquare) \ TYPE(TemplateCloser) \ TYPE(TemplateOpener) \ Modified: cfe/trunk/lib/Format/FormatTokenLexer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatTokenLexer.cpp?rev=343602&r1=343601&r2=343602&view=diff ==
r305272 - clang-format: add option to merge empty function body
Author: typz Date: Tue Jun 13 02:02:43 2017 New Revision: 305272 URL: http://llvm.org/viewvc/llvm-project?rev=305272&view=rev Log: clang-format: add option to merge empty function body Summary: This option supplements the AllowShortFunctionsOnASingleLine flag, to merge empty function body at the beginning of the line: e.g. when the function is not short-enough and breaking braces after function. int f() {} Reviewers: krasimir, djasper Reviewed By: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D33447 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Tue Jun 13 02:02:43 2017 @@ -688,6 +688,18 @@ struct FormatStyle { bool BeforeElse; /// \brief Indent the wrapped braces themselves. bool IndentBraces; +/// \brief If ``false``, empty function body can be put on a single line. +/// This option is used only if the opening brace of the function has +/// already been wrapped, i.e. the `AfterFunction` brace wrapping mode is +/// set, and the function could/should not be put on a single line (as per +/// `AllowShortFunctionsOnASingleLine` and constructor formatting options). +/// \code +/// int f() vs. inf f() +/// {} { +/// } +/// \endcode +/// +bool SplitEmptyFunctionBody; }; /// \brief Control of individual brace wrapping cases. Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Tue Jun 13 02:02:43 2017 @@ -410,6 +410,7 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Tue Jun 13 02:02:43 2017 @@ -186,6 +186,12 @@ private: ? 0 : Limit - TheLine->Last->TotalLength; +if (TheLine->Last->is(TT_FunctionLBrace) && +TheLine->First == TheLine->Last && +!Style.BraceWrapping.SplitEmptyFunctionBody && +I[1]->First->is(tok::r_brace)) + return tryMergeSimpleBlock(I, E, Limit); + // FIXME: TheLine->Level != 0 might or might not be the right check to do. // If necessary, change to something smarter. bool MergeShortFunctions = @@ -215,7 +221,10 @@ private: Limit -= 2; unsigned MergedLines = 0; - if (MergeShortFunctions) { + if (MergeShortFunctions || + (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && + I[1]->First == I[1]->Last && I + 2 != E && + I[2]->First->is(tok::r_brace))) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); // If we managed to merge the block, count the function header, which is // on a separate line. Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Jun 13 02:02:43 2017 @@ -6239,6 +6239,35 @@ TEST_F(FormatTest, PullTrivialFunctionDe getLLVMStyleWithColumns(23)); } +TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) { + FormatStyle MergeEmptyOnly = getLLVMStyle(); + MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeEmptyOnly); + verifyFormat("class C {\n" + " int f() {\n" + "return 42;\n" + " }\n" + "};", + MergeEmptyOnly); + verifyFormat("int f() {}", MergeEmptyOnly); + verifyFormat("int f() {\n" + " return 42;\n" + "}", + MergeEmptyOnly); + + // Also verify behavior when BraceWrapping.AfterFunction = true + MergeEmptyOnly.BreakBeforeBraces = FormatStyle::BS_Custom; + MergeEmptyOnly.BraceWrapping.AfterFunction = true; + verify
r305384 - clang-format: Add CompactNamespaces option
Author: typz Date: Wed Jun 14 07:29:47 2017 New Revision: 305384 URL: http://llvm.org/viewvc/llvm-project?rev=305384&view=rev Log: clang-format: Add CompactNamespaces option Summary: Add CompactNamespaces option, to pack namespace declarations on the same line (somewhat similar to C++17 nested namespace definition). With this option, consecutive namespace declarations are kept on the same line: namespace foo { namespace bar { ... }} // namespace foo::bar Reviewers: krasimir, djasper, klimek Reviewed By: djasper Subscribers: kimgr, cfe-commits, klimek Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D32480 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=305384&r1=305383&r2=305384&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed Jun 14 07:29:47 2017 @@ -791,6 +791,29 @@ struct FormatStyle { /// \endcode bool BreakBeforeInheritanceComma; + /// \brief If ``true``, consecutive namespace declarations will be on the same + /// line. If ``false``, each namespace is declared on a new line. + /// \code + /// true: + /// namespace Foo { namespace Bar { + /// }} + /// + /// false: + /// namespace Foo { + /// namespace Bar { + /// } + /// } + /// \endcode + /// + /// If it does not fit on a single line, the overflowing namespaces get + /// wrapped: + /// \code + /// namespace Foo { namespace Bar { + /// namespace Extra { + /// }}} + /// \endcode + bool CompactNamespaces; + /// \brief If the constructor initializers don't fit on a line, put each /// initializer on its own line. /// \code @@ -1422,6 +1445,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakConstructorInitializers == R.BreakConstructorInitializers && + CompactNamespaces == R.CompactNamespaces && BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations && BreakStringLiterals == R.BreakStringLiterals && ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas && Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=305384&r1=305383&r2=305384&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Wed Jun 14 07:29:47 2017 @@ -310,6 +310,8 @@ template <> struct MappingTraits struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp?rev=305384&r1=305383&r2=305384&view=diff == --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp (original) +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp Wed Jun 14 07:29:47 2017 @@ -107,6 +107,24 @@ void updateEndComment(const FormatToken << llvm::toString(std::move(Err)) << "\n"; } } + +const FormatToken * +getNamespaceToken(const AnnotatedLine *line, + const SmallVectorImpl &AnnotatedLines) { + if (!line->Affected || line->InPPDirective || !line->startsWith(tok::r_brace)) +return nullptr; + size_t StartLineIndex = line->MatchingOpeningBlockLineIndex; + if (StartLineIndex == UnwrappedLine::kInvalidIndex) +return nullptr; + assert(StartLineIndex < AnnotatedLines.size()); + const FormatToken *NamespaceTok = AnnotatedLines[StartLineIndex]->First; + // Detect "(inline)? namespace" in the beginning of a line. + if (NamespaceTok->is(tok::kw_inline)) +NamespaceTok = NamespaceTok->getNextNonComment(); + if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace)) +return nullptr; + return NamespaceTok; +} } // namespace NamespaceEndCommentsFixer::NamespaceEndCommentsFixer(const Environment &Env, @@ -120,20 +138,14 @@ tooling::Replacements NamespaceEndCommen AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(), AnnotatedLines.end()); tooling::Replacements Fixes; + std::string AllNamespaceNames = ""; + size_t StartLineIndex = SIZE_MAX; + unsigned int CompactedNamespacesCount = 0; for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) { -if (!AnnotatedLines[I]->Affected || AnnotatedLines[I]->InPPDirective || -!Annot
r305696 - clang-format: Fix C99 designated initializers corner cases
Author: typz Date: Mon Jun 19 09:41:21 2017 New Revision: 305696 URL: http://llvm.org/viewvc/llvm-project?rev=305696&view=rev Log: clang-format: Fix C99 designated initializers corner cases Summary: This fixes the missing space before the designated initializer when `Cpp11BracedListStyle=false` : const struct A a = { .a = 1, .b = 2 }; ^ Also, wrapping between opening brace and designated array initializers used to have an excessive penalty (like breaking between an expression and the subscript operator), leading to unexpected wrapping: const struct Aaaa aa = {[1] = aaa, [2] = bbb}; instead of: const struct Aaaa aa = { [1] = aaa, [2] = bbb}; Finally, designated array initializers are not binpacked, just like designated member initializers. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, krasimir, klimek Differential Revision: https://reviews.llvm.org/D33491 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=305696&r1=305695&r2=305696&view=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Mon Jun 19 09:41:21 2017 @@ -1050,7 +1050,9 @@ void ContinuationIndenter::moveStatePast (Current.is(TT_ArrayInitializerLSquare) && EndsInComma) || Current.is(TT_DictLiteral) || Style.Language == FormatStyle::LK_Proto || !Style.BinPackArguments || -(NextNoComment && NextNoComment->is(TT_DesignatedInitializerPeriod)); +(NextNoComment && + NextNoComment->isOneOf(TT_DesignatedInitializerPeriod, +TT_DesignatedInitializerLSquare)); if (Current.ParameterCount > 1) NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1); } else { Modified: cfe/trunk/lib/Format/FormatToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=305696&r1=305695&r2=305696&view=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Mon Jun 19 09:41:21 2017 @@ -39,6 +39,7 @@ namespace format { TYPE(ConflictStart) \ TYPE(CtorInitializerColon) \ TYPE(CtorInitializerComma) \ + TYPE(DesignatedInitializerLSquare) \ TYPE(DesignatedInitializerPeriod) \ TYPE(DictLiteral) \ TYPE(ForEachMacro) \ Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=305696&r1=305695&r2=305696&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon Jun 19 09:41:21 2017 @@ -340,6 +340,9 @@ private: Contexts.back().ContextKind == tok::l_brace && Parent->isOneOf(tok::l_brace, tok::comma)) { Left->Type = TT_JsComputedPropertyName; + } else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace && + Parent && Parent->isOneOf(tok::l_brace, tok::comma)) { +Left->Type = TT_DesignatedInitializerLSquare; } else if (CurrentToken->is(tok::r_square) && Parent && Parent->is(TT_TemplateCloser)) { Left->Type = TT_ArraySubscriptLSquare; @@ -392,7 +395,8 @@ private: if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace)) return false; if (CurrentToken->is(tok::colon)) { -if (Left->is(TT_ArraySubscriptLSquare)) { +if (Left->isOneOf(TT_ArraySubscriptLSquare, + TT_DesignatedInitializerLSquare)) { Left->Type = TT_ObjCMethodExpr; StartsObjCMethodExpr = true; Contexts.back().ColonIsObjCMethodExpr = true; @@ -1975,7 +1979,8 @@ unsigned TokenAnnotator::splitPenalty(co if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal)) return 35; if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare, - TT_ArrayInitializerLSquare)) + TT_ArrayInitializerLSquare, + TT_DesignatedInitializerLSquare)) return 500; } @@ -2196,7 +2201,8 @@ bool TokenAnnotator::spaceRequiredBetwee (Style.SpacesInSquareBrackets && Right.MatchingParen->is(TT_ArraySubscriptLSquare))); if (Right.is(tok::l_square) && - !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare)
r305912 - clang-format: introduce InlineOnly short function style
Author: typz Date: Wed Jun 21 08:56:02 2017 New Revision: 305912 URL: http://llvm.org/viewvc/llvm-project?rev=305912&view=rev Log: clang-format: introduce InlineOnly short function style Summary: This is the same as Inline, except it does not imply all empty functions are merged: with this style, empty functions are merged only if they also match the 'inline' criteria (i.e. defined in a class). This is helpful to avoid inlining functions in implementations files. Reviewers: djasper, krasimir Reviewed By: djasper Subscribers: klimek, rengolin, cfe-commits Differential Revision: https://reviews.llvm.org/D34399 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=305912&r1=305911&r2=305912&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed Jun 21 08:56:02 2017 @@ -184,9 +184,23 @@ struct FormatStyle { enum ShortFunctionStyle { /// \brief Never merge functions into a single line. SFS_None, +/// \brief Only merge functions defined inside a class. Same as "inline", +/// except it does not implies "empty": i.e. top level empty functions +/// are not merged either. +/// \code +/// class Foo { +/// void f() { foo(); } +/// }; +/// void f() { +/// foo(); +/// } +/// void f() { +/// } +/// \endcode +SFS_InlineOnly, /// \brief Only merge empty functions. /// \code -/// void f() { bar(); } +/// void f() {} /// void f2() { /// bar2(); /// } @@ -197,6 +211,10 @@ struct FormatStyle { /// class Foo { /// void f() { foo(); } /// }; +/// void f() { +/// foo(); +/// } +/// void f() {} /// \endcode SFS_Inline, /// \brief Merge all functions fitting on a single line. Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=305912&r1=305911&r2=305912&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Wed Jun 21 08:56:02 2017 @@ -97,6 +97,7 @@ template <> struct ScalarEnumerationTrai IO.enumCase(Value, "All", FormatStyle::SFS_All); IO.enumCase(Value, "true", FormatStyle::SFS_All); IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline); +IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly); IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty); } }; Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=305912&r1=305911&r2=305912&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Wed Jun 21 08:56:02 2017 @@ -2480,8 +2480,8 @@ bool TokenAnnotator::mustBreakBefore(con return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None || Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty || (Left.NestingLevel == 0 && Line.Level == 0 && - Style.AllowShortFunctionsOnASingleLine == - FormatStyle::SFS_Inline); + Style.AllowShortFunctionsOnASingleLine & + FormatStyle::SFS_InlineOnly); } else if (Style.Language == FormatStyle::LK_Java) { if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next && Right.Next->is(tok::string_literal)) Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=305912&r1=305911&r2=305912&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Wed Jun 21 08:56:02 2017 @@ -226,7 +226,7 @@ private: Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All || (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && I[1]->First->is(tok::r_brace)) || -(Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline && +(Style.AllowShortFunctionsOnASingleLine & FormatStyle::SFS_InlineOnly && TheLine->Level != 0); if (Style.CompactNamespaces) { Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?r
r306868 - clang-format: Do not binpack initialization lists
Author: typz Date: Fri Jun 30 13:00:02 2017 New Revision: 306868 URL: http://llvm.org/viewvc/llvm-project?rev=306868&view=rev Log: clang-format: Do not binpack initialization lists Summary: This patch tries to avoid binpacking when initializing lists/arrays, to allow things like: static int types[] = { registerType1(), registerType2(), registerType3(), }; std::map x = { { 0, "foo fjakfjaklf kljj" }, { 1, "bar fjakfjaklf kljj" }, { 2, "stuff fjakfjaklf kljj" }, }; This is similar to how dictionnaries are formatted, and actually corresponds to the same conditions: when initializing a container (and not just 'calling' a constructor). Such formatting involves 2 things: * Line breaks around the content of the block. This can be forced by adding a comma or comment after the last element * Elements should not be binpacked This patch considers the block is an initializer list if it either ends with a comma, or follows an assignment, which seems to provide a sensible approximation. Reviewers: krasimir, djasper Reviewed By: djasper Subscribers: malcolm.parsons, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D34238 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/FormatTestJava.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=306868&r1=306867&r2=306868&view=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Fri Jun 30 13:00:02 2017 @@ -1063,12 +1063,12 @@ void ContinuationIndenter::moveStatePast Current.MatchingParen->Previous && Current.MatchingParen->Previous->is(tok::comma); AvoidBinPacking = -(Current.is(TT_ArrayInitializerLSquare) && EndsInComma) || -Current.is(TT_DictLiteral) || +EndsInComma || Current.is(TT_DictLiteral) || Style.Language == FormatStyle::LK_Proto || !Style.BinPackArguments || (NextNoComment && NextNoComment->isOneOf(TT_DesignatedInitializerPeriod, TT_DesignatedInitializerLSquare)); +BreakBeforeParameter = EndsInComma; if (Current.ParameterCount > 1) NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1); } else { Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=306868&r1=306867&r2=306868&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Jun 30 13:00:02 2017 @@ -6004,7 +6004,10 @@ TEST_F(FormatTest, LayoutBraceInitialize TEST_F(FormatTest, LayoutCxx11BraceInitializers) { verifyFormat("vector x{1, 2, 3, 4};"); verifyFormat("vector x{\n" - "1, 2, 3, 4,\n" + "1,\n" + "2,\n" + "3,\n" + "4,\n" "};"); verifyFormat("vector x{{}, {}, {}, {}};"); verifyFormat("f({1, 2});"); @@ -6049,6 +6052,17 @@ TEST_F(FormatTest, LayoutCxx11BraceIniti "};"); verifyFormat("#define A {a, a},"); + // Binpacking only if there is no trailing comma + verifyFormat("const Aa a = {aa, bb,\n" + " cc, dd};", + getLLVMStyleWithColumns(50)); + verifyFormat("const Aa a = {\n" + "aaa,\n" + "bbb,\n" + "ccc,\n" + "ddd,\n" + "};", getLLVMStyleWithColumns(50)); + // Cases where distinguising braced lists and blocks is hard. verifyFormat("vector v{12} GUARDED_BY(mutex);"); verifyFormat("void f() {\n" @@ -6128,10 +6142,12 @@ TEST_F(FormatTest, LayoutCxx11BraceIniti " // Second element:\n" " 2};", getLLVMStyleWithColumns(30))); - // A trailing comma should still lead to an enforced line break. + // A trailing comma should still lead to an enforced line break and no + // binpacking. EXPECT_EQ("vector SomeVector = {\n" "// aaa\n" -"1, 2,\n" +"1,\n" +"2,\n" "};", format("vector SomeVector = { // aaa\n" "1, 2, };")); @@ -6297,7 +6313,7 @@ TEST_F(FormatTest, FormatsBracedListsInC " , a, aa, a, aaa}};"); // No column layout should be used here. - verifyFormat("aaa = {
r306874 - clang-format: add options to merge empty record body
Author: typz Date: Fri Jun 30 13:25:55 2017 New Revision: 306874 URL: http://llvm.org/viewvc/llvm-project?rev=306874&view=rev Log: clang-format: add options to merge empty record body Summary: This patch introduces a few extra BraceWrapping options, similar to `SplitEmptyFunction`, to allow merging empty 'record' bodies (e.g. class, struct, union and namespace): * SplitEmptyClass * SplitEmptyStruct * SplitEmptyUnion * SplitEmptyNamespace The `SplitEmptyFunction` option name has also been simplified/ shortened (from `SplitEmptyFunctionBody`). These options are helpful when the correspond AfterXXX option is enabled, to allow merging the empty record: class Foo {}; In addition, this fixes an unexpected merging of short records, when the After options are used, which caused to be formatted like this: class Foo { void Foo(); }; This is now properly formatted as: class Foo { void Foo(); }; Reviewers: djasper, krasimir Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D34395 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=306874&r1=306873&r2=306874&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Fri Jun 30 13:25:55 2017 @@ -717,7 +717,29 @@ struct FormatStyle { /// } /// \endcode /// -bool SplitEmptyFunctionBody; +bool SplitEmptyFunction; +/// \brief If ``false``, empty record (e.g. class, struct or union) body +/// can be put on a single line. This option is used only if the opening +/// brace of the record has already been wrapped, i.e. the `AfterClass` +/// (for classes) brace wrapping mode is set. +/// \code +/// class Foo vs. class Foo +/// {} { +///} +/// \endcode +/// +bool SplitEmptyRecord; +/// \brief If ``false``, empty namespace body can be put on a single line. +/// This option is used only if the opening brace of the namespace has +/// already been wrapped, i.e. the `AfterNamespace` brace wrapping mode is +/// set. +/// \code +/// namespace Foo vs. namespace Foo +/// {} { +///} +/// \endcode +/// +bool SplitEmptyNamespace; }; /// \brief Control of individual brace wrapping cases. Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=306874&r1=306873&r2=306874&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Fri Jun 30 13:25:55 2017 @@ -414,7 +414,9 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=306874&r1=306873&r2=306874&view=diff == --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Fri Jun 30 13:25:55 2017 @@ -476,6 +476,19 @@ struct FormatToken { return MatchingParen && MatchingParen->opensBlockOrBlockTypeList(Style); } + /// \brief Return the actual namespace token, if this token starts a namespace + /// block. + const FormatToken *getNamespaceToken() const { +const FormatToken *NamespaceTok = this; +if (is(tok::comment)) + NamespaceTok = NamespaceTok->getNextNonComment(); +// Detect "(inline)? namespace" in the beginning of a line. +if (NamespaceTok && NamespaceTok->is(tok::kw_inline)) + NamespaceTok = NamespaceTok->getNextNonComment(); +return NamespaceTok && NamespaceTok->is(tok::kw_namespace) ? NamespaceTok + : nullptr; + } + private: // Disallow copying. FormatToken(const FormatToken &) = delete; Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=306874&r1=306873&r2=306874&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Fri Jun 30 13:25:55 2017 @@ -136,10 +136,7 @@ private: bool isNamespaceDeclaration(const AnnotatedLine *Line) { const FormatToken *NamespaceTok = Line->First; - // Detect "(inline)? namespace" in the beginning of a line. - if (NamespaceTok->is(tok::kw_inline)) -NamespaceTok = Namesp
r303534 - clang-format: Allow customizing the penalty for breaking assignment
Author: typz Date: Mon May 22 03:28:17 2017 New Revision: 303534 URL: http://llvm.org/viewvc/llvm-project?rev=303534&view=rev Log: clang-format: Allow customizing the penalty for breaking assignment Summary: Add option to customize the penalty for breaking assignment This allows increasing the priority of the assignment, to prefer spliting an operation instead of splitting the assignment, e.g. : int a = + ; Reviewers: krasimir, djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D32477 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=303534&r1=303533&r2=303534&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Mon May 22 03:28:17 2017 @@ -1133,6 +1133,9 @@ struct FormatStyle { /// ``Foo `` instead of ``Foo``. bool ObjCSpaceBeforeProtocolList; + /// \brief The penalty for breaking around an assignment operator. + unsigned PenaltyBreakAssignment; + /// \brief The penalty for breaking a function call after ``call(``. unsigned PenaltyBreakBeforeFirstCallParameter; @@ -1420,6 +1423,8 @@ struct FormatStyle { ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && + PenaltyBreakAssignment == + R.PenaltyBreakAssignment && PenaltyBreakBeforeFirstCallParameter == R.PenaltyBreakBeforeFirstCallParameter && PenaltyBreakComment == R.PenaltyBreakComment && Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=303534&r1=303533&r2=303534&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Mon May 22 03:28:17 2017 @@ -343,6 +343,8 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=303534&r1=303533&r2=303534&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon May 22 03:28:17 2017 @@ -2093,9 +2093,10 @@ unsigned TokenAnnotator::splitPenalty(co if (Left.is(TT_ConditionalExpr)) return prec::Conditional; prec::Level Level = Left.getPrecedence(); - if (Level != prec::Unknown) -return Level; - Level = Right.getPrecedence(); + if (Level == prec::Unknown) +Level = Right.getPrecedence(); + if (Level == prec::Assignment) +return Style.PenaltyBreakAssignment; if (Level != prec::Unknown) return Level; Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=303534&r1=303533&r2=303534&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Mon May 22 03:28:17 2017 @@ -3457,6 +3457,18 @@ TEST_F(FormatTest, BreaksAfterAssignment "1;"); } +TEST_F(FormatTest, ConfigurableBreakAssignmentPenalty) { + FormatStyle Style = getLLVMStyle(); + verifyFormat("int aa =\n" + "bb + cc;", + Style); + + Style.PenaltyBreakAssignment = 20; + verifyFormat("int aa = bb +\n" + " cc;", + Style); +} + TEST_F(FormatTest, AlignsAfterAssignments) { verifyFormat( "int Result = a + a +\n" @@ -8802,6 +8814,8 @@ TEST_F(FormatTest, ParsesConfiguration) CHECK_PARSE("ObjCBlockIndentWidth: 1234", ObjCBlockIndentWidth, 1234u); CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u); CHECK_PARSE("MaxEmptyLinesToKeep: 1234", MaxEmptyLinesToKeep, 1234u); + CHECK_PARSE("PenaltyBreakAssignment: 1234", + PenaltyBreakAssignment, 1234u); CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234", PenaltyBreakBeforeFirstCallParameter, 1234u); CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listin
r303556 - clang-format: do not reflow bullet lists
Author: typz Date: Mon May 22 09:47:17 2017 New Revision: 303556 URL: http://llvm.org/viewvc/llvm-project?rev=303556&view=rev Log: clang-format: do not reflow bullet lists Summary: This patch prevents reflowing bullet lists in block comments. It handles all lists supported by doxygen and markdown, e.g. bullet lists starting with '-', '*', '+', as well as numbered lists starting with -# or a number followed by a dot. Reviewers: krasimir Reviewed By: krasimir Subscribers: djasper, klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D33285 Modified: cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/unittests/Format/FormatTestComments.cpp Modified: cfe/trunk/lib/Format/BreakableToken.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.cpp?rev=303556&r1=303555&r2=303556&view=diff == --- cfe/trunk/lib/Format/BreakableToken.cpp (original) +++ cfe/trunk/lib/Format/BreakableToken.cpp Mon May 22 09:47:17 2017 @@ -78,6 +78,14 @@ static BreakableToken::Split getCommentS } StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes); + + // Do not split before a number followed by a dot: this would be interpreted + // as a numbered list, which would prevent re-flowing in subsequent passes. + static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\."); + if (SpaceOffset != StringRef::npos && + kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks))) +SpaceOffset = Text.find_last_of(Blanks, SpaceOffset); + if (SpaceOffset == StringRef::npos || // Don't break at leading whitespace. Text.find_last_not_of(Blanks, SpaceOffset) == StringRef::npos) { @@ -299,8 +307,9 @@ const FormatToken &BreakableComment::tok static bool mayReflowContent(StringRef Content) { Content = Content.trim(Blanks); // Lines starting with '@' commonly have special meaning. - static const SmallVector kSpecialMeaningPrefixes = { - "@", "TODO", "FIXME", "XXX"}; + // Lines starting with '-', '-#', '+' or '*' are bulleted/numbered lists. + static const SmallVector kSpecialMeaningPrefixes = { + "@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* " }; bool hasSpecialMeaningPrefix = false; for (StringRef Prefix : kSpecialMeaningPrefixes) { if (Content.startswith(Prefix)) { @@ -308,6 +317,14 @@ static bool mayReflowContent(StringRef C break; } } + + // Numbered lists may also start with a number followed by '.' + // To avoid issues if a line starts with a number which is actually the end + // of a previous line, we only consider numbers with up to 2 digits. + static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\. "); + hasSpecialMeaningPrefix = hasSpecialMeaningPrefix || +kNumberedListRegexp.match(Content); + // Simple heuristic for what to reflow: content should contain at least two // characters and either the first or second character must be // non-punctuation. Modified: cfe/trunk/unittests/Format/FormatTestComments.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestComments.cpp?rev=303556&r1=303555&r2=303556&view=diff == --- cfe/trunk/unittests/Format/FormatTestComments.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestComments.cpp Mon May 22 09:47:17 2017 @@ -1577,7 +1577,7 @@ TEST_F(FormatTestComments, ReflowsCommen " *\n" " * long */", getLLVMStyleWithColumns(20))); - + // Don't reflow lines having content that is a single character. EXPECT_EQ("// long long long\n" "// long\n" @@ -1602,7 +1602,7 @@ TEST_F(FormatTestComments, ReflowsCommen format("// long long long long\n" "// @param arg", getLLVMStyleWithColumns(20))); - + // Don't reflow lines starting with 'TODO'. EXPECT_EQ("// long long long\n" "// long\n" @@ -1671,6 +1671,69 @@ TEST_F(FormatTestComments, ReflowsCommen "// long", getLLVMStyleWithColumns(20))); + // Don't reflow separate bullets in list + EXPECT_EQ("// - long long long\n" +"// long\n" +"// - long", +format("// - long long long long\n" + "// - long", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("// * long long long\n" +"// long\n" +"// * long", +format("// * long long long long\n" + "// * long", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("// + long long long\n" +"// long\n" +"// + long", +format("// + long long long long\n" + "// + long", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("// 1. long long
r303739 - clang-format: Introduce BreakConstructorInitializers option
Author: typz Date: Wed May 24 06:36:58 2017 New Revision: 303739 URL: http://llvm.org/viewvc/llvm-project?rev=303739&view=rev Log: clang-format: Introduce BreakConstructorInitializers option Summary: This option replaces the BreakConstructorInitializersBeforeComma option with an enum, thus introducing a mode where the colon stays on the same line as constructor declaration: // When it fits on line: Constructor() : initializer1(), initializer2() {} // When it does not fit: Constructor() : initializer1(), initializer2() {} // When ConstructorInitializerAllOnOneLineOrOnePerLine = true: Constructor() : initializer1(), initializer2() {} Reviewers: krasimir, djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D32479 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=303739&r1=303738&r2=303739&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed May 24 06:36:58 2017 @@ -710,16 +710,35 @@ struct FormatStyle { /// \endcode bool BreakBeforeTernaryOperators; - /// \brief Always break constructor initializers before commas and align - /// the commas with the colon. - /// \code - ///true: false: - ///SomeClass::Constructor() vs. SomeClass::Constructor() : a(a), - ///: a(a) b(b), - ///, b(b) c(c) {} - ///, c(c) {} - /// \endcode - bool BreakConstructorInitializersBeforeComma; + /// \brief Different ways to break initializers. + enum BreakConstructorInitializersStyle + { +/// Break constructor initializers before the colon and after the commas. +/// \code +/// Constructor() +/// : initializer1(), +/// initializer2() +/// \endcode +BCIS_BeforeColon, +/// Break constructor initializers before the colon and commas, and align +/// the commas with the colon. +/// \code +/// Constructor() +/// : initializer1() +/// , initializer2() +/// \endcode +BCIS_BeforeComma, +/// Break constructor initializers after the colon and commas. +/// \code +/// Constructor() : +/// initializer1(), +/// initializer2() +/// \endcode +BCIS_AfterColon + }; + + /// \brief The constructor initializers style to use.. + BreakConstructorInitializersStyle BreakConstructorInitializers; /// \brief Break after each annotation on a field in Java files. /// \code{.java} @@ -1390,8 +1409,7 @@ struct FormatStyle { BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && - BreakConstructorInitializersBeforeComma == - R.BreakConstructorInitializersBeforeComma && + BreakConstructorInitializers == R.BreakConstructorInitializers && BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations && BreakStringLiterals == R.BreakStringLiterals && ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas && Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=303739&r1=303738&r2=303739&view=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Wed May 24 06:36:58 2017 @@ -54,13 +54,14 @@ static bool startsNextParameter(const Fo const FormatStyle &Style) { const FormatToken &Previous = *Current.Previous; if (Current.is(TT_CtorInitializerComma) && - Style.BreakConstructorInitializersBeforeComma) + Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma) return true; return Previous.is(tok::comma) && !Current.isTrailingComment() && ((Previous.isNot(TT_CtorInitializerComma) || - !Style.BreakConstructorInitializersBeforeComma) && + Style.BreakConstructorInitializers != + FormatStyle::BCIS_BeforeComma) && (Previous.isNot(TT_InheritanceComma) || - !Style.BreakBeforeInheritanceComma)); + !Style.BreakBeforeInheritanceComma)); } ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style, @@ -178,13 +179
r309370 - clang-format: merge short case labels with trailing comments
Author: typz Date: Fri Jul 28 00:56:18 2017 New Revision: 309370 URL: http://llvm.org/viewvc/llvm-project?rev=309370&view=rev Log: clang-format: merge short case labels with trailing comments Summary: Allow merging short case labels when they actually end with a comment (like a comment after the ``break``) and when followed by switch-level comments (e.g. aligned with next case): switch(a) { case 0: break; // comment at end of case case 1: return value; // comment related to next case // comment related to next case case 2: } Reviewers: krasimir, djasper Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D35557 Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=309370&r1=309369&r2=309370&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Fri Jul 28 00:56:18 2017 @@ -382,7 +382,9 @@ private: return 0; unsigned NumStmts = 0; unsigned Length = 0; +bool EndsWithComment = false; bool InPPDirective = I[0]->InPPDirective; +const unsigned Level = I[0]->Level; for (; NumStmts < 3; ++NumStmts) { if (I + 1 + NumStmts == E) break; @@ -392,9 +394,26 @@ private: if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace)) break; if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch, - tok::kw_while, tok::comment) || - Line->Last->is(tok::comment)) + tok::kw_while) || + EndsWithComment) return 0; + if (Line->First->is(tok::comment)) { +if (Level != Line->Level) + return 0; +SmallVectorImpl::const_iterator J = I + 2 + NumStmts; +for (; J != E; ++J) { + Line = *J; + if (Line->InPPDirective != InPPDirective) +break; + if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace)) +break; + if (Line->First->isNot(tok::comment) || Level != Line->Level) +return 0; +} +break; + } + if (Line->Last->is(tok::comment)) +EndsWithComment = true; Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space. } if (NumStmts == 0 || NumStmts == 3 || Length > Limit) Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=309370&r1=309369&r2=309370&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Jul 28 00:56:18 2017 @@ -907,6 +907,77 @@ TEST_F(FormatTest, ShortCaseLabels) { "}", Style); verifyFormat("switch (a) {\n" + "case 0: return; // comment\n" + "case 1: break; // comment\n" + "case 2: return;\n" + "// comment\n" + "case 3: return;\n" + "// comment 1\n" + "// comment 2\n" + "// comment 3\n" + "case 4: break; /* comment */\n" + "case 5:\n" + " // comment\n" + " break;\n" + "case 6: /* comment */ x = 1; break;\n" + "case 7: x = /* comment */ 1; break;\n" + "case 8:\n" + " x = 1; /* comment */\n" + " break;\n" + "case 9:\n" + " break; // comment line 1\n" + " // comment line 2\n" + "}", + Style); + EXPECT_EQ("switch (a) {\n" +"case 1:\n" +" x = 8;\n" +" // fall through\n" +"case 2: x = 8;\n" +"// comment\n" +"case 3:\n" +" return; /* comment line 1\n" +" * comment line 2 */\n" +"case 4: i = 8;\n" +"// something else\n" +"#if FOO\n" +"case 5: break;\n" +"#endif\n" +"}", +format("switch (a) {\n" + "case 1: x = 8;\n" + " // fall through\n" + "case 2:\n" + " x = 8;\n" + "// comment\n" + "case 3:\n" + " return; /* comment line 1\n" + " * comment line 2 */\n" + "case 4:\n" + " i = 8;\n" + "// something else\n" + "#if FOO\n" + "case 5: break;\n" +
r309369 - clang-format: fix block OpeningLineIndex around preprocessor
Author: typz Date: Fri Jul 28 00:56:14 2017 New Revision: 309369 URL: http://llvm.org/viewvc/llvm-project?rev=309369&view=rev Log: clang-format: fix block OpeningLineIndex around preprocessor Summary: The current code would return an incorrect value when a preprocessor directive is present immediately after the opening brace: this causes the nanespace end comment fixer to break in some places, for exemple it would not add the comment in this case: namespace a { #define FOO } Fixing the computation is simple enough, but it was breaking a feature, as it would cause comments to be added also when the namespace declaration was dependant on conditional compilation. To fix this, a hash of the current preprocessor stack/branches is computed at the beginning of parseBlock(), so that we explicitely do not store the OpeningLineIndex when the beginning and end of the block are not in the same preprocessor conditions. Tthe hash is computed based on the line, but this could propbably be improved by using the actual condition, so that clang-format would be able to match multiple identical #ifdef blocks. Reviewers: krasimir, djasper Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D35483 Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/lib/Format/UnwrappedLineParser.h cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=309369&r1=309368&r2=309369&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Fri Jul 28 00:56:14 2017 @@ -452,6 +452,21 @@ void UnwrappedLineParser::calculateBrace FormatTok = Tokens->setPosition(StoredPosition); } +template +static inline void hash_combine(std::size_t &seed, const T &v) { + std::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + +size_t UnwrappedLineParser::computePPHash() const { + size_t h = 0; + for (const auto &i : PPStack) { +hash_combine(h, size_t(i.Kind)); +hash_combine(h, i.Line); + } + return h; +} + void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel, bool MunchSemi) { assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) && @@ -459,16 +474,21 @@ void UnwrappedLineParser::parseBlock(boo const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin); FormatTok->BlockKind = BK_Block; + size_t PPStartHash = computePPHash(); + unsigned InitialLevel = Line->Level; nextToken(/*LevelDifference=*/AddLevel ? 1 : 0); if (MacroBlock && FormatTok->is(tok::l_paren)) parseParens(); + size_t NbPreprocessorDirectives = + CurrentLines == &Lines ? PreprocessorDirectives.size() : 0; addUnwrappedLine(); - size_t OpeningLineIndex = CurrentLines->empty() -? (UnwrappedLine::kInvalidIndex) -: (CurrentLines->size() - 1); + size_t OpeningLineIndex = + CurrentLines->empty() + ? (UnwrappedLine::kInvalidIndex) + : (CurrentLines->size() - 1 - NbPreprocessorDirectives); ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, MustBeDeclaration); @@ -486,6 +506,8 @@ void UnwrappedLineParser::parseBlock(boo return; } + size_t PPEndHash = computePPHash(); + // Munch the closing brace. nextToken(/*LevelDifference=*/AddLevel ? -1 : 0); @@ -495,11 +517,14 @@ void UnwrappedLineParser::parseBlock(boo if (MunchSemi && FormatTok->Tok.is(tok::semi)) nextToken(); Line->Level = InitialLevel; - Line->MatchingOpeningBlockLineIndex = OpeningLineIndex; - if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) { -// Update the opening line to add the forward reference as well -(*CurrentLines)[OpeningLineIndex].MatchingOpeningBlockLineIndex = -CurrentLines->size() - 1; + + if (PPStartHash == PPEndHash) { +Line->MatchingOpeningBlockLineIndex = OpeningLineIndex; +if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) { + // Update the opening line to add the forward reference as well + (*CurrentLines)[OpeningLineIndex].MatchingOpeningBlockLineIndex = + CurrentLines->size() - 1; +} } } @@ -607,10 +632,15 @@ void UnwrappedLineParser::parsePPDirecti } void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) { - if (Unreachable || (!PPStack.empty() && PPStack.back() == PP_Unreachable)) -PPStack.push_back(PP_Unreachable); + size_t Line = CurrentLines->size(); + if (CurrentLines == &PreprocessorDirectives) +Line += Lines.size(); + + if (Unreachable || + (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable)) +P