forked from qt-creator/qt-creator
Fixed semantic check for ObjC fast-enumeration for-loops, then merged it with the semantic check for the foreach.
This commit is contained in:
@@ -2226,8 +2226,8 @@ unsigned ObjCFastEnumerationAST::firstToken() const
|
||||
|
||||
unsigned ObjCFastEnumerationAST::lastToken() const
|
||||
{
|
||||
if (body_statement)
|
||||
return body_statement->lastToken();
|
||||
if (statement)
|
||||
return statement->lastToken();
|
||||
else if (rparen_token)
|
||||
return rparen_token + 1;
|
||||
else if (fast_enumeratable_expression)
|
||||
|
||||
@@ -2690,7 +2690,7 @@ public:
|
||||
unsigned in_token;
|
||||
ExpressionAST *fast_enumeratable_expression;
|
||||
unsigned rparen_token;
|
||||
StatementAST *body_statement;
|
||||
StatementAST *statement;
|
||||
|
||||
public: // annotations
|
||||
Block *symbol;
|
||||
|
||||
@@ -2439,9 +2439,9 @@ bool ASTMatcher::match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pat
|
||||
|
||||
pattern->rparen_token = node->rparen_token;
|
||||
|
||||
if (! pattern->body_statement)
|
||||
pattern->body_statement = node->body_statement;
|
||||
else if (! AST::match(node->body_statement, pattern->body_statement, this))
|
||||
if (! pattern->statement)
|
||||
pattern->statement = node->statement;
|
||||
else if (! AST::match(node->statement, pattern->statement, this))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -880,13 +880,13 @@ public:
|
||||
return __ast;
|
||||
}
|
||||
|
||||
ObjCFastEnumerationAST *ObjCFastEnumeration(DeclaratorAST *declarator = 0, ExpressionAST *initializer = 0, ExpressionAST *fast_enumeratable_expression = 0, StatementAST *body_statement = 0)
|
||||
ObjCFastEnumerationAST *ObjCFastEnumeration(DeclaratorAST *declarator = 0, ExpressionAST *initializer = 0, ExpressionAST *fast_enumeratable_expression = 0, StatementAST *statement = 0)
|
||||
{
|
||||
ObjCFastEnumerationAST *__ast = new (&pool) ObjCFastEnumerationAST;
|
||||
__ast->declarator = declarator;
|
||||
__ast->initializer = initializer;
|
||||
__ast->fast_enumeratable_expression = fast_enumeratable_expression;
|
||||
__ast->body_statement = body_statement;
|
||||
__ast->statement = statement;
|
||||
return __ast;
|
||||
}
|
||||
|
||||
|
||||
@@ -1066,7 +1066,7 @@ void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor)
|
||||
accept(declarator, visitor);
|
||||
accept(initializer, visitor);
|
||||
accept(fast_enumeratable_expression, visitor);
|
||||
accept(body_statement, visitor);
|
||||
accept(statement, visitor);
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
@@ -155,61 +155,64 @@ bool CheckStatement::visit(ExpressionStatementAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckStatement::visit(ForeachStatementAST *ast)
|
||||
bool CheckStatement::forEachFastEnum(unsigned firstToken,
|
||||
unsigned lastToken,
|
||||
SpecifierListAST *type_specifier_list,
|
||||
DeclaratorAST *declarator,
|
||||
ExpressionAST *initializer,
|
||||
ExpressionAST *expression,
|
||||
StatementAST *statement,
|
||||
Block *&symbol)
|
||||
{
|
||||
Block *block = control()->newBlock(ast->foreach_token);
|
||||
block->setStartOffset(tokenAt(ast->firstToken()).offset);
|
||||
block->setEndOffset(tokenAt(ast->lastToken()).offset);
|
||||
ast->symbol = block;
|
||||
Block *block = control()->newBlock(firstToken);
|
||||
block->setStartOffset(tokenAt(firstToken).offset);
|
||||
block->setEndOffset(tokenAt(lastToken).offset);
|
||||
symbol = block;
|
||||
_scope->enterSymbol(block);
|
||||
Scope *previousScope = switchScope(block->members());
|
||||
if (ast->type_specifier_list && ast->declarator) {
|
||||
FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope);
|
||||
if (type_specifier_list && declarator) {
|
||||
FullySpecifiedType ty = semantic()->check(type_specifier_list, _scope);
|
||||
const Name *name = 0;
|
||||
ty = semantic()->check(ast->declarator, ty, _scope, &name);
|
||||
unsigned location = ast->declarator->firstToken();
|
||||
if (CoreDeclaratorAST *core_declarator = ast->declarator->core_declarator)
|
||||
ty = semantic()->check(declarator, ty, _scope, &name);
|
||||
unsigned location = declarator->firstToken();
|
||||
if (CoreDeclaratorAST *core_declarator = declarator->core_declarator)
|
||||
location = core_declarator->firstToken();
|
||||
Declaration *decl = control()->newDeclaration(location, name);
|
||||
decl->setType(ty);
|
||||
_scope->enterSymbol(decl);
|
||||
} else {
|
||||
FullySpecifiedType exprTy = semantic()->check(ast->initializer, _scope);
|
||||
FullySpecifiedType exprTy = semantic()->check(initializer, _scope);
|
||||
(void) exprTy;
|
||||
}
|
||||
|
||||
FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
|
||||
semantic()->check(ast->statement, _scope);
|
||||
FullySpecifiedType exprTy = semantic()->check(expression, _scope);
|
||||
semantic()->check(statement, _scope);
|
||||
(void) switchScope(previousScope);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckStatement::visit(ForeachStatementAST *ast)
|
||||
{
|
||||
return forEachFastEnum(ast->firstToken(),
|
||||
ast->lastToken(),
|
||||
ast->type_specifier_list,
|
||||
ast->declarator,
|
||||
ast->initializer,
|
||||
ast->expression,
|
||||
ast->statement,
|
||||
ast->symbol);
|
||||
}
|
||||
|
||||
bool CheckStatement::visit(ObjCFastEnumerationAST *ast)
|
||||
{
|
||||
Block *block = control()->newBlock(ast->for_token);
|
||||
block->setStartOffset(tokenAt(ast->firstToken()).offset);
|
||||
block->setEndOffset(tokenAt(ast->lastToken()).offset);
|
||||
ast->symbol = block;
|
||||
_scope->enterSymbol(block);
|
||||
Scope *previousScope = switchScope(block->members());
|
||||
if (ast->type_specifier_list && ast->declarator) {
|
||||
FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope);
|
||||
const Name *name = 0;
|
||||
ty = semantic()->check(ast->declarator, ty, _scope, &name);
|
||||
unsigned location = ast->declarator->firstToken();
|
||||
if (CoreDeclaratorAST *core_declarator = ast->declarator->core_declarator)
|
||||
location = core_declarator->firstToken();
|
||||
Declaration *decl = control()->newDeclaration(location, name);
|
||||
decl->setType(ty);
|
||||
_scope->enterSymbol(decl);
|
||||
} else {
|
||||
FullySpecifiedType exprTy = semantic()->check(ast->initializer, _scope);
|
||||
(void) exprTy;
|
||||
}
|
||||
|
||||
semantic()->check(ast->body_statement, _scope);
|
||||
(void) switchScope(previousScope);
|
||||
return false;
|
||||
return forEachFastEnum(ast->firstToken(),
|
||||
ast->lastToken(),
|
||||
ast->type_specifier_list,
|
||||
ast->declarator,
|
||||
ast->initializer,
|
||||
ast->fast_enumeratable_expression,
|
||||
ast->statement,
|
||||
ast->symbol);
|
||||
}
|
||||
|
||||
bool CheckStatement::visit(ForStatementAST *ast)
|
||||
|
||||
@@ -90,6 +90,14 @@ protected:
|
||||
virtual bool visit(WhileStatementAST *ast);
|
||||
virtual bool visit(QtMemberDeclarationAST *ast);
|
||||
|
||||
bool forEachFastEnum(unsigned firstToken,
|
||||
unsigned lastToken,
|
||||
SpecifierListAST *type_specifier_list,
|
||||
DeclaratorAST *declarator,
|
||||
ExpressionAST *initializer,
|
||||
ExpressionAST *expression,
|
||||
StatementAST *statement,
|
||||
Block *&symbol);
|
||||
private:
|
||||
StatementAST *_statement;
|
||||
Scope *_scope;
|
||||
|
||||
@@ -2433,7 +2433,7 @@ bool Parser::parseForStatement(StatementAST *&node)
|
||||
|
||||
parseExpression(ast->fast_enumeratable_expression);
|
||||
match(T_RPAREN, &ast->rparen_token);
|
||||
parseStatement(ast->body_statement);
|
||||
parseStatement(ast->statement);
|
||||
|
||||
node = ast;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user