forked from OSchip/llvm-project
Fix layout of lambda captures.
Before: int c = [ &, &a, a]{ [ =, c, &d]{ return b++; }(); }(); After: int c = [&, &a, a] { [=, c, &d] { return b++; }(); }(); llvm-svn: 189924
This commit is contained in:
parent
5b2000e4d9
commit
bab25fdfa5
|
@ -624,7 +624,9 @@ private:
|
||||||
Current.Type = determineIncrementUsage(Current);
|
Current.Type = determineIncrementUsage(Current);
|
||||||
} else if (Current.is(tok::exclaim)) {
|
} else if (Current.is(tok::exclaim)) {
|
||||||
Current.Type = TT_UnaryOperator;
|
Current.Type = TT_UnaryOperator;
|
||||||
} else if (Current.isBinaryOperator()) {
|
} else if (Current.isBinaryOperator() &&
|
||||||
|
(!Current.Previous ||
|
||||||
|
Current.Previous->isNot(tok::l_square))) {
|
||||||
Current.Type = TT_BinaryOperator;
|
Current.Type = TT_BinaryOperator;
|
||||||
} else if (Current.is(tok::comment)) {
|
} else if (Current.is(tok::comment)) {
|
||||||
if (Current.TokenText.startswith("//"))
|
if (Current.TokenText.startswith("//"))
|
||||||
|
@ -1188,6 +1190,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
||||||
return false;
|
return false;
|
||||||
if (Right.is(tok::ellipsis))
|
if (Right.is(tok::ellipsis))
|
||||||
return false;
|
return false;
|
||||||
|
if (Left.is(tok::l_square) && Right.is(tok::amp))
|
||||||
|
return false;
|
||||||
if (Right.Type == TT_PointerOrReference)
|
if (Right.Type == TT_PointerOrReference)
|
||||||
return Left.Tok.isLiteral() ||
|
return Left.Tok.isLiteral() ||
|
||||||
((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
|
((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
|
||||||
|
@ -1236,7 +1240,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
||||||
return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
|
return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
|
||||||
(Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr);
|
(Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr);
|
||||||
if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) &&
|
if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) &&
|
||||||
Right.is(tok::l_brace) && Right.getNextNonComment())
|
Right.is(tok::l_brace) && Right.getNextNonComment() &&
|
||||||
|
Right.BlockKind != BK_Block)
|
||||||
return false;
|
return false;
|
||||||
if (Left.is(tok::period) || Right.is(tok::period))
|
if (Left.is(tok::period) || Right.is(tok::period))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -278,13 +278,11 @@ void UnwrappedLineParser::calculateBraceTypes() {
|
||||||
if (!LBraceStack.empty()) {
|
if (!LBraceStack.empty()) {
|
||||||
if (LBraceStack.back()->BlockKind == BK_Unknown) {
|
if (LBraceStack.back()->BlockKind == BK_Unknown) {
|
||||||
// If there is a comma, semicolon or right paren after the closing
|
// If there is a comma, semicolon or right paren after the closing
|
||||||
// brace, we assume this is a braced initializer list.
|
// brace, we assume this is a braced initializer list. Note that
|
||||||
|
// regardless how we mark inner braces here, we will overwrite the
|
||||||
// FIXME: Note that this currently works only because we do not
|
// BlockKind later if we parse a braced list (where all blocks inside
|
||||||
// use the brace information while inside a braced init list.
|
// are by default braced lists), or when we explicitly detect blocks
|
||||||
// Thus, if the parent is a braced init list, we consider all
|
// (for example while parsing lambdas).
|
||||||
// brace blocks inside it braced init list. That works good enough
|
|
||||||
// for now, but we will need to fix it to correctly handle lambdas.
|
|
||||||
//
|
//
|
||||||
// We exclude + and - as they can be ObjC visibility modifiers.
|
// We exclude + and - as they can be ObjC visibility modifiers.
|
||||||
if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren,
|
if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren,
|
||||||
|
@ -315,12 +313,13 @@ void UnwrappedLineParser::calculateBraceTypes() {
|
||||||
}
|
}
|
||||||
Tok = NextTok;
|
Tok = NextTok;
|
||||||
Position += ReadTokens;
|
Position += ReadTokens;
|
||||||
} while (Tok->Tok.isNot(tok::eof));
|
} while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty());
|
||||||
// Assume other blocks for all unclosed opening braces.
|
// Assume other blocks for all unclosed opening braces.
|
||||||
for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
|
for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
|
||||||
if (LBraceStack[i]->BlockKind == BK_Unknown)
|
if (LBraceStack[i]->BlockKind == BK_Unknown)
|
||||||
LBraceStack[i]->BlockKind = BK_Block;
|
LBraceStack[i]->BlockKind = BK_Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatTok = Tokens->setPosition(StoredPosition);
|
FormatTok = Tokens->setPosition(StoredPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,6 +674,7 @@ void UnwrappedLineParser::tryToParseLambda() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FormatTok->BlockKind = BK_Block;
|
||||||
nextToken();
|
nextToken();
|
||||||
{
|
{
|
||||||
ScopedLineState LineState(*this);
|
ScopedLineState LineState(*this);
|
||||||
|
@ -745,6 +745,9 @@ void UnwrappedLineParser::parseBracedList() {
|
||||||
tryToParseLambda();
|
tryToParseLambda();
|
||||||
break;
|
break;
|
||||||
case tok::l_brace:
|
case tok::l_brace:
|
||||||
|
// Assume there are no blocks inside a braced init list apart
|
||||||
|
// from the ones we explicitly parse out (like lambdas).
|
||||||
|
FormatTok->BlockKind = BK_BracedInit;
|
||||||
parseBracedList();
|
parseBracedList();
|
||||||
break;
|
break;
|
||||||
case tok::r_brace:
|
case tok::r_brace:
|
||||||
|
|
|
@ -6262,37 +6262,37 @@ TEST_F(FormatTest, FormatsLambdas) {
|
||||||
// parsing of the unwrapped lines doesn't regress.
|
// parsing of the unwrapped lines doesn't regress.
|
||||||
verifyFormat(
|
verifyFormat(
|
||||||
"int c = [b]() mutable {\n"
|
"int c = [b]() mutable {\n"
|
||||||
" return [&b]{\n"
|
" return [&b] {\n"
|
||||||
" return b++;\n"
|
" return b++;\n"
|
||||||
" }();\n"
|
" }();\n"
|
||||||
"}();\n");
|
"}();\n");
|
||||||
verifyFormat(
|
verifyFormat(
|
||||||
"int c = [&]{\n"
|
"int c = [&] {\n"
|
||||||
" [ = ]{\n"
|
" [=] {\n"
|
||||||
" return b++;\n"
|
" return b++;\n"
|
||||||
" }();\n"
|
" }();\n"
|
||||||
"}();\n");
|
"}();\n");
|
||||||
verifyFormat(
|
verifyFormat(
|
||||||
"int c = [ &, &a, a]{\n"
|
"int c = [&, &a, a] {\n"
|
||||||
" [ =, c, &d]{\n"
|
" [=, c, &d] {\n"
|
||||||
" return b++;\n"
|
" return b++;\n"
|
||||||
" }();\n"
|
" }();\n"
|
||||||
"}();\n");
|
"}();\n");
|
||||||
verifyFormat(
|
verifyFormat(
|
||||||
"int c = [&a, &a, a]{\n"
|
"int c = [&a, &a, a] {\n"
|
||||||
" [ =, a, b, &c]{\n"
|
" [=, a, b, &c] {\n"
|
||||||
" return b++;\n"
|
" return b++;\n"
|
||||||
" }();\n"
|
" }();\n"
|
||||||
"}();\n");
|
"}();\n");
|
||||||
verifyFormat(
|
verifyFormat(
|
||||||
"auto c = {[&a, &a, a]{\n"
|
"auto c = {[&a, &a, a] {\n"
|
||||||
" [ =, a, b, &c]{\n"
|
" [=, a, b, &c] {\n"
|
||||||
" return b++;\n"
|
" return b++;\n"
|
||||||
" }();\n"
|
" }();\n"
|
||||||
"} }\n");
|
"} }\n");
|
||||||
verifyFormat(
|
verifyFormat(
|
||||||
"auto c = {[&a, &a, a]{\n"
|
"auto c = {[&a, &a, a] {\n"
|
||||||
" [ =, a, b, &c]{\n"
|
" [=, a, b, &c] {\n"
|
||||||
" }();\n"
|
" }();\n"
|
||||||
"} }\n");
|
"} }\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue