From f04dbf05b918375c064113c612273ef0207a04ab Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 29 Jul 2009 10:06:14 +0200 Subject: Fix for ObjC fast-enumeration parsing. --- src/shared/cplusplus/Parser.cpp | 63 ++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'src/shared/cplusplus/Parser.cpp') diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index b7151055a3..fbfe90893f 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -2178,38 +2178,55 @@ bool Parser::parseForStatement(StatementAST *&node) unsigned lparen_token = 0; match(T_LPAREN, &lparen_token); - // FIXME: for ObjC fast enumeration, this needs a semicolon before the "in" token, which is obviously wrong. - StatementAST *initializer = 0; - parseForInitStatement(initializer); - unsigned in_token = 0; + unsigned startOfTypeSpecifier = cursor(); + bool blocked = blockErrors(true); - if (parseObjCContextKeyword(Token_in, in_token)) { + if (objCEnabled()) { ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST; - ast->for_token = for_token; ast->lparen_token = lparen_token; - ast->initializer = initializer; - ast->in_token = in_token; - parseExpression(ast->fast_enumeratable_expression); - match(T_RPAREN, &ast->rparen_token); - parseStatement(ast->body_statement); - node = ast; - } else { - ForStatementAST *ast = new (_pool) ForStatementAST; + if (parseTypeSpecifier(ast->type_specifiers)) + parseDeclarator(ast->declarator); - ast->for_token = for_token; - ast->lparen_token = lparen_token; - ast->initializer = initializer; - parseExpression(ast->condition); - match(T_SEMICOLON, &ast->semicolon_token); - parseExpression(ast->expression); - match(T_RPAREN, &ast->rparen_token); - parseStatement(ast->statement); + if (! ast->type_specifiers || ! ast->declarator) { + ast->type_specifiers = 0; + ast->declarator = 0; - node = ast; + rewind(startOfTypeSpecifier); + parseAssignmentExpression(ast->initializer); + } + + if (parseObjCContextKeyword(Token_in, ast->in_token)) { + blockErrors(blocked); + + parseExpression(ast->fast_enumeratable_expression); + match(T_RPAREN, &ast->rparen_token); + parseStatement(ast->body_statement); + + node = ast; + return true; + } + + // there was no "in" token, so we continue with a normal for-statement + rewind(startOfTypeSpecifier); } + blockErrors(blocked); + + // Normal C/C++ for-statement parsing + ForStatementAST *ast = new (_pool) ForStatementAST; + + ast->for_token = for_token; + ast->lparen_token = lparen_token; + parseForInitStatement(ast->initializer); + parseExpression(ast->condition); + match(T_SEMICOLON, &ast->semicolon_token); + parseExpression(ast->expression); + match(T_RPAREN, &ast->rparen_token); + parseStatement(ast->statement); + + node = ast; return true; } -- cgit v1.2.1