From: Manuel Klimek Date: Tue, 19 Sep 2017 09:59:30 +0000 (+0000) Subject: Fix formatting of lambda introducers with initializers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b3beec43959d827795128837b6adc58cae027a2;p=clang Fix formatting of lambda introducers with initializers. Most of the work was already done when we introduced a look-behind based lambda introducer detection. This patch finishes the transition by completely relying on the simple lambda introducer detection and simply recursing into normal brace-parsing code to parse until the end of the introducer. This fixes initializers in lambdas, including nested lambdas. Before: auto a = [b = [c = 42]{}]{}; auto b = [c = &i + 23]{}; After: auto a = [b = [c = 42] {}] {}; auto b = [c = &i + 23] {}; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313622 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 40d133ff0d..8722d80a39 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -1314,14 +1314,6 @@ bool UnwrappedLineParser::tryToParseLambda() { nextToken(); return false; } - const FormatToken* Previous = getPreviousToken(); - if (Previous && - (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new, - tok::kw_delete) || - Previous->closesScope() || Previous->isSimpleTypeSpecifier())) { - nextToken(); - return false; - } assert(FormatTok->is(tok::l_square)); FormatToken &LSquare = *FormatTok; if (!tryToParseLambdaIntroducer()) @@ -1364,49 +1356,17 @@ bool UnwrappedLineParser::tryToParseLambda() { } bool UnwrappedLineParser::tryToParseLambdaIntroducer() { - nextToken(); - if (FormatTok->is(tok::equal)) { - nextToken(); - if (FormatTok->is(tok::r_square)) { - nextToken(); - return true; - } - if (FormatTok->isNot(tok::comma)) - return false; - nextToken(); - } else if (FormatTok->is(tok::amp)) { - nextToken(); - if (FormatTok->is(tok::r_square)) { - nextToken(); - return true; - } - if (!FormatTok->isOneOf(tok::comma, tok::identifier)) { - return false; - } - if (FormatTok->is(tok::comma)) - nextToken(); - } else if (FormatTok->is(tok::r_square)) { + const FormatToken* Previous = getPreviousToken(); + if (Previous && + (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new, + tok::kw_delete) || + Previous->closesScope() || Previous->isSimpleTypeSpecifier())) { nextToken(); - return true; + return false; } - do { - if (FormatTok->is(tok::amp)) - nextToken(); - if (!FormatTok->isOneOf(tok::identifier, tok::kw_this)) - return false; - nextToken(); - if (FormatTok->is(tok::ellipsis)) - nextToken(); - if (FormatTok->is(tok::comma)) { - nextToken(); - } else if (FormatTok->is(tok::r_square)) { - nextToken(); - return true; - } else { - return false; - } - } while (!eof()); - return false; + nextToken(); + parseSquare(/*LambdaIntroducer=*/true); + return true; } void UnwrappedLineParser::tryToParseJSFunction() { @@ -1608,10 +1568,12 @@ void UnwrappedLineParser::parseParens() { } while (!eof()); } -void UnwrappedLineParser::parseSquare() { - assert(FormatTok->Tok.is(tok::l_square) && "'[' expected."); - if (tryToParseLambda()) - return; +void UnwrappedLineParser::parseSquare(bool LambdaIntroducer) { + if (!LambdaIntroducer) { + assert(FormatTok->Tok.is(tok::l_square) && "'[' expected."); + if (tryToParseLambda()) + return; + } do { switch (FormatTok->Tok.getKind()) { case tok::l_paren: diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 2637b23e1e..93b3bfafba 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -96,7 +96,7 @@ private: bool parseBracedList(bool ContinueOnSemicolons = false, tok::TokenKind ClosingBraceKind = tok::r_brace); void parseParens(); - void parseSquare(); + void parseSquare(bool LambdaIntroducer = false); void parseIfThenElse(); void parseTryCatch(); void parseForOrWhileLoop(); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index e974550f22..34206e9e41 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -10770,6 +10770,8 @@ TEST_F(FormatTest, FormatsLambdas) { verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n"); verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n"); verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n"); + verifyFormat("auto c = [a = [b = 42] {}] {};\n"); + verifyFormat("auto c = [a = &i + 10, b = [] {}] {};\n"); verifyFormat("int x = f(*+[] {});"); verifyFormat("void f() {\n" " other(x.begin(), x.end(), [&](int, int) { return 1; });\n"