summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2009-07-29 10:06:14 +0200
committerErik Verbruggen <erik.verbruggen@nokia.com>2009-07-29 10:06:14 +0200
commitf04dbf05b918375c064113c612273ef0207a04ab (patch)
tree5e36961a7f196db9cee9b4ae2d96cf78d76a0967 /src/shared/cplusplus
parent61123092ab0e1c39a81b296071f13f851a91e3df (diff)
downloadqt-creator-f04dbf05b918375c064113c612273ef0207a04ab.tar.gz
Fix for ObjC fast-enumeration parsing.
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp4
-rw-r--r--src/shared/cplusplus/AST.h8
-rw-r--r--src/shared/cplusplus/ASTClone.cpp11
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp4
-rw-r--r--src/shared/cplusplus/Parser.cpp63
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;
}