diff options
author | Erik Verbruggen <erik.verbruggen@nokia.com> | 2009-07-29 10:06:14 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@nokia.com> | 2009-07-29 10:06:14 +0200 |
commit | f04dbf05b918375c064113c612273ef0207a04ab (patch) | |
tree | 5e36961a7f196db9cee9b4ae2d96cf78d76a0967 /src/shared/cplusplus | |
parent | 61123092ab0e1c39a81b296071f13f851a91e3df (diff) | |
download | qt-creator-f04dbf05b918375c064113c612273ef0207a04ab.tar.gz |
Fix for ObjC fast-enumeration parsing.
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r-- | src/shared/cplusplus/AST.cpp | 4 | ||||
-rw-r--r-- | src/shared/cplusplus/AST.h | 8 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTClone.cpp | 11 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTVisit.cpp | 4 | ||||
-rw-r--r-- | src/shared/cplusplus/Parser.cpp | 63 |
5 files changed, 60 insertions, 30 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 967894cc74..0a16fa774c 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2554,6 +2554,10 @@ unsigned ObjCFastEnumerationAST::lastToken() const return in_token + 1; else if (initializer) return initializer->lastToken(); + else if (declarator) + return declarator->lastToken(); + else if (type_specifiers) + return type_specifiers->lastToken(); else if (lparen_token) return lparen_token + 1; else diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index df54fc106c..ee22f1a453 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -3208,7 +3208,13 @@ class CPLUSPLUS_EXPORT ObjCFastEnumerationAST: public StatementAST public: unsigned for_token; unsigned lparen_token; - StatementAST *initializer; + + // declaration + SpecifierAST *type_specifiers; + DeclaratorAST *declarator; + // or an expression + ExpressionAST *initializer; + unsigned in_token; ExpressionAST *fast_enumeratable_expression; unsigned rparen_token; diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 24717e300a..1fbb5a651b 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1541,14 +1541,13 @@ ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const ObjCFastEnumerationAST *ast = new (pool) ObjCFastEnumerationAST; ast->for_token = for_token; ast->lparen_token = lparen_token; - if (initializer) - ast->initializer = initializer->clone(pool); + if (type_specifiers) ast->type_specifiers = type_specifiers->clone(pool); + if (declarator) ast->declarator = declarator->clone(pool); + if (initializer) ast->initializer = initializer->clone(pool); ast->in_token = in_token; - if (fast_enumeratable_expression) - ast->fast_enumeratable_expression = fast_enumeratable_expression->clone(pool); + if (fast_enumeratable_expression) ast->fast_enumeratable_expression = fast_enumeratable_expression->clone(pool); ast->rparen_token = rparen_token; - if (body_statement) - ast->body_statement = body_statement->clone(pool); + if (body_statement) ast->body_statement = body_statement->clone(pool); return ast; } diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index dbf8d0a91d..f258ac1125 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1511,6 +1511,10 @@ void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjCFastEnumerationAST + if (type_specifiers) + accept(type_specifiers, visitor); + if (declarator) + accept(declarator, visitor); if (initializer) accept(initializer, visitor); if (fast_enumeratable_expression) 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; } |