summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp9
-rw-r--r--clang/lib/Format/ContinuationIndenter.h8
-rw-r--r--clang/unittests/Format/FormatTest.cpp10
3 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 5317fb33ffb..d25ab68e396 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -566,6 +566,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
Current.LastInChainOfCalls ? 0 : State.Column + Current.ColumnWidth;
if (Current.Type == TT_ObjCSelectorName)
State.Stack.back().ObjCSelectorNameFound = true;
+ if (Current.Type == TT_LambdaLSquare)
+ ++State.Stack.back().LambdasFound;
if (Current.Type == TT_CtorInitializerColon) {
// Indent 2 from the column, so:
// SomeClass::SomeClass()
@@ -654,7 +656,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
bool BreakBeforeParameter = false;
if (Current.is(tok::l_brace) ||
Current.Type == TT_ArrayInitializerLSquare) {
- if (Current.MatchingParen && Current.BlockKind == BK_Block) {
+ if (Current.MatchingParen && Current.BlockKind == BK_Block &&
+ State.Stack.back().LambdasFound <= 1) {
// If this is an l_brace starting a nested block, we pretend (wrt. to
// indentation) that we already consumed the corresponding r_brace.
// Thus, we remove all ParenStates caused by fake parentheses that end
@@ -670,6 +673,10 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
// SomeFunction(a, [] {
// f(); // break
// });
+ //
+ // If we have already found more than one lambda introducers on this
+ // level, we opt out of this because similarity between the lambdas is
+ // more important.
for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i) {
assert(State.Stack.size() > 1);
if (State.Stack.size() == 1) {
diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h
index 9a3c118561e..04e31e68b1d 100644
--- a/clang/lib/Format/ContinuationIndenter.h
+++ b/clang/lib/Format/ContinuationIndenter.h
@@ -139,7 +139,7 @@ struct ParenState {
StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
CallContinuation(0), VariablePos(0), ContainsLineBreak(false),
ContainsUnwrappedBuilder(0), AlignColons(true),
- ObjCSelectorNameFound(false) {}
+ ObjCSelectorNameFound(false), LambdasFound(0) {}
/// \brief The position to which a specific parenthesis level needs to be
/// indented.
@@ -230,6 +230,12 @@ struct ParenState {
/// the same token.
bool ObjCSelectorNameFound;
+ /// \brief Counts the number of lambda introducers found on this level.
+ ///
+ /// Not considered for memoization as it will always have the same value at
+ /// the same token.
+ unsigned LambdasFound;
+
bool operator<(const ParenState &Other) const {
if (Indent != Other.Indent)
return Indent < Other.Indent;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index b9310abbbea..b932b274d70 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -8171,6 +8171,16 @@ TEST_F(FormatTest, FormatsLambdas) {
" return fffffffffffffffffffffffffffffffffffffff(i * j);\n"
"};");
+ // Multiple lambdas in the same parentheses change indentation rules.
+ verifyFormat("SomeFunction([]() {\n"
+ " int i = 42;\n"
+ " return i;\n"
+ " },\n"
+ " []() {\n"
+ " int j = 43;\n"
+ " return j;\n"
+ " });");
+
// Not lambdas.
verifyFormat("constexpr char hello[]{\"hello\"};");
verifyFormat("double &operator[](int i) { return 0; }\n"
OpenPOWER on IntegriCloud