forked from qt-creator/qt-creator
Fix for ObjC fast-enumeration parsing.
This commit is contained in:
@@ -2554,6 +2554,10 @@ unsigned ObjCFastEnumerationAST::lastToken() const
|
|||||||
return in_token + 1;
|
return in_token + 1;
|
||||||
else if (initializer)
|
else if (initializer)
|
||||||
return initializer->lastToken();
|
return initializer->lastToken();
|
||||||
|
else if (declarator)
|
||||||
|
return declarator->lastToken();
|
||||||
|
else if (type_specifiers)
|
||||||
|
return type_specifiers->lastToken();
|
||||||
else if (lparen_token)
|
else if (lparen_token)
|
||||||
return lparen_token + 1;
|
return lparen_token + 1;
|
||||||
else
|
else
|
||||||
|
@@ -3208,7 +3208,13 @@ class CPLUSPLUS_EXPORT ObjCFastEnumerationAST: public StatementAST
|
|||||||
public:
|
public:
|
||||||
unsigned for_token;
|
unsigned for_token;
|
||||||
unsigned lparen_token;
|
unsigned lparen_token;
|
||||||
StatementAST *initializer;
|
|
||||||
|
// declaration
|
||||||
|
SpecifierAST *type_specifiers;
|
||||||
|
DeclaratorAST *declarator;
|
||||||
|
// or an expression
|
||||||
|
ExpressionAST *initializer;
|
||||||
|
|
||||||
unsigned in_token;
|
unsigned in_token;
|
||||||
ExpressionAST *fast_enumeratable_expression;
|
ExpressionAST *fast_enumeratable_expression;
|
||||||
unsigned rparen_token;
|
unsigned rparen_token;
|
||||||
|
@@ -1541,14 +1541,13 @@ ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const
|
|||||||
ObjCFastEnumerationAST *ast = new (pool) ObjCFastEnumerationAST;
|
ObjCFastEnumerationAST *ast = new (pool) ObjCFastEnumerationAST;
|
||||||
ast->for_token = for_token;
|
ast->for_token = for_token;
|
||||||
ast->lparen_token = lparen_token;
|
ast->lparen_token = lparen_token;
|
||||||
if (initializer)
|
if (type_specifiers) ast->type_specifiers = type_specifiers->clone(pool);
|
||||||
ast->initializer = initializer->clone(pool);
|
if (declarator) ast->declarator = declarator->clone(pool);
|
||||||
|
if (initializer) ast->initializer = initializer->clone(pool);
|
||||||
ast->in_token = in_token;
|
ast->in_token = in_token;
|
||||||
if (fast_enumeratable_expression)
|
if (fast_enumeratable_expression) ast->fast_enumeratable_expression = fast_enumeratable_expression->clone(pool);
|
||||||
ast->fast_enumeratable_expression = fast_enumeratable_expression->clone(pool);
|
|
||||||
ast->rparen_token = rparen_token;
|
ast->rparen_token = rparen_token;
|
||||||
if (body_statement)
|
if (body_statement) ast->body_statement = body_statement->clone(pool);
|
||||||
ast->body_statement = body_statement->clone(pool);
|
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1511,6 +1511,10 @@ void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor)
|
|||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
// visit ObjCFastEnumerationAST
|
// visit ObjCFastEnumerationAST
|
||||||
|
if (type_specifiers)
|
||||||
|
accept(type_specifiers, visitor);
|
||||||
|
if (declarator)
|
||||||
|
accept(declarator, visitor);
|
||||||
if (initializer)
|
if (initializer)
|
||||||
accept(initializer, visitor);
|
accept(initializer, visitor);
|
||||||
if (fast_enumeratable_expression)
|
if (fast_enumeratable_expression)
|
||||||
|
@@ -2178,38 +2178,55 @@ bool Parser::parseForStatement(StatementAST *&node)
|
|||||||
unsigned lparen_token = 0;
|
unsigned lparen_token = 0;
|
||||||
match(T_LPAREN, &lparen_token);
|
match(T_LPAREN, &lparen_token);
|
||||||
|
|
||||||
// FIXME: for ObjC fast enumeration, this needs a semicolon before the "in" token, which is obviously wrong.
|
unsigned startOfTypeSpecifier = cursor();
|
||||||
StatementAST *initializer = 0;
|
bool blocked = blockErrors(true);
|
||||||
parseForInitStatement(initializer);
|
|
||||||
unsigned in_token = 0;
|
|
||||||
|
|
||||||
if (parseObjCContextKeyword(Token_in, in_token)) {
|
if (objCEnabled()) {
|
||||||
ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST;
|
ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST;
|
||||||
|
|
||||||
ast->for_token = for_token;
|
ast->for_token = for_token;
|
||||||
ast->lparen_token = lparen_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;
|
if (parseTypeSpecifier(ast->type_specifiers))
|
||||||
} else {
|
parseDeclarator(ast->declarator);
|
||||||
ForStatementAST *ast = new (_pool) ForStatementAST;
|
|
||||||
|
|
||||||
ast->for_token = for_token;
|
if (! ast->type_specifiers || ! ast->declarator) {
|
||||||
ast->lparen_token = lparen_token;
|
ast->type_specifiers = 0;
|
||||||
ast->initializer = initializer;
|
ast->declarator = 0;
|
||||||
parseExpression(ast->condition);
|
|
||||||
match(T_SEMICOLON, &ast->semicolon_token);
|
|
||||||
parseExpression(ast->expression);
|
|
||||||
match(T_RPAREN, &ast->rparen_token);
|
|
||||||
parseStatement(ast->statement);
|
|
||||||
|
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user