Fixed #6752 (wrong AST when there is lambda function)

This commit is contained in:
Daniel Marjamäki 2015-06-17 19:32:44 +02:00
parent 06e818f89d
commit a884362817
2 changed files with 30 additions and 16 deletions

View File

@ -596,16 +596,15 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
// What we do here: // What we do here:
// - Nest the round bracket under the square bracket. // - Nest the round bracket under the square bracket.
// - Nest what follows the lambda (if anything) with the lambda opening [ // - Nest what follows the lambda (if anything) with the lambda opening [
// - Compile the content of the lambda function as separate tree // - Compile the content of the lambda function as separate tree (this is done later)
Token* squareBracket = tok; Token* squareBracket = tok;
Token* roundBracket = squareBracket->link()->next(); Token* roundBracket = squareBracket->link()->next();
Token* curlyBracket = Token::findsimplematch(roundBracket->link()->next(), "{"); Token* curlyBracket = Token::findsimplematch(roundBracket->link()->next(), "{");
if (!curlyBracket) if (!curlyBracket)
break; break;
tok = curlyBracket->next(); squareBracket->astOperand1(roundBracket);
compileExpression(tok, state); roundBracket->astOperand1(curlyBracket);
state.op.push(roundBracket); state.op.push(squareBracket);
compileUnaryOp(squareBracket, state, nullptr);
tok = curlyBracket->link()->next(); tok = curlyBracket->link()->next();
} else { } else {
Token* tok2 = tok; Token* tok2 = tok;
@ -947,15 +946,24 @@ static Token * createAstAtToken(Token *tok, bool cpp)
if (endToken == tok1) if (endToken == tok1)
return tok1; return tok1;
// Compile inner expressions inside inner ({..}) // Compile inner expressions inside inner ({..}) and lambda bodies
for (tok = tok1->next(); tok && tok != endToken; tok = tok ? tok->next() : NULL) { for (tok = tok1->next(); tok && tok != endToken; tok = tok ? tok->next() : NULL) {
if (!Token::simpleMatch(tok, "( {")) if (tok->str() != "{")
continue; continue;
if (tok->next() == endToken)
if (Token::simpleMatch(tok->previous(), "( {"))
;
else if (Token::simpleMatch(tok->astParent(), "(") &&
Token::simpleMatch(tok->astParent()->astParent(), "[") &&
tok == tok->astParent()->astParent()->astOperand1()->astOperand1())
;
else
continue;
if (Token::simpleMatch(tok->previous(), "( { ."))
break; break;
if (Token::simpleMatch(tok, "( { ."))
break; const Token * const endToken2 = tok->link();
const Token * const endToken2 = tok->linkAt(1);
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : NULL) for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : NULL)
tok = createAstAtToken(tok, cpp); tok = createAstAtToken(tok, cpp);
} }

View File

@ -8663,12 +8663,18 @@ private:
} }
void astlambda() const { void astlambda() const {
ASSERT_EQUALS("([(return 0return", testAst("return [](){ return 0; }();")); // a lambda expression '[x](y){}' is compiled as:
ASSERT_EQUALS("([(return 0return", testAst("return []() -> int { return 0; }();")); // [
ASSERT_EQUALS("([(return 0return", testAst("return [something]() -> int { return 0; }();")); // `-(
ASSERT_EQUALS("([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);")); // `-{
ASSERT_EQUALS("x{([( ai=", testAst("x([&a](int i){a=i;});"));
ASSERT_EQUALS("x([= 0return", testAst("x = [](){return 0; };")); ASSERT_EQUALS("{([(return 0return", testAst("return [](){ return 0; }();"));
ASSERT_EQUALS("{([(return 0return", testAst("return []() -> int { return 0; }();"));
ASSERT_EQUALS("{([(return 0return", testAst("return [something]() -> int { return 0; }();"));
ASSERT_EQUALS("{([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);"));
ASSERT_EQUALS("x{([= 0return", testAst("x = [](){return 0; };"));
} }
void compileLimits() { void compileLimits() {