Commit ea411f84 by Ian Lance Taylor

compiler: Permit "for range x" clauses.

Fixes Issue 8370.

From-SVN: r216051
parent 3369b919
...@@ -3836,6 +3836,12 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp, ...@@ -3836,6 +3836,12 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
this->unget_token(Token::make_identifier_token(identifier, is_exported, this->unget_token(Token::make_identifier_token(identifier, is_exported,
location)); location));
} }
else if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
{
Typed_identifier_list til;
this->range_clause_decl(&til, p_range_clause);
return NULL;
}
Expression* exp = this->expression(PRECEDENCE_NORMAL, true, Expression* exp = this->expression(PRECEDENCE_NORMAL, true,
may_be_composite_lit, may_be_composite_lit,
...@@ -5278,7 +5284,7 @@ Parse::for_clause(Expression** cond, Block** post) ...@@ -5278,7 +5284,7 @@ Parse::for_clause(Expression** cond, Block** post)
} }
} }
// RangeClause = IdentifierList ( "=" | ":=" ) "range" Expression . // RangeClause = [ IdentifierList ( "=" | ":=" ) ] "range" Expression .
// This is the := version. It is called with a list of identifiers. // This is the := version. It is called with a list of identifiers.
...@@ -5291,7 +5297,6 @@ Parse::range_clause_decl(const Typed_identifier_list* til, ...@@ -5291,7 +5297,6 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
p_range_clause->found = true; p_range_clause->found = true;
go_assert(til->size() >= 1);
if (til->size() > 2) if (til->size() > 2)
error_at(this->location(), "too many variables for range clause"); error_at(this->location(), "too many variables for range clause");
...@@ -5300,6 +5305,9 @@ Parse::range_clause_decl(const Typed_identifier_list* til, ...@@ -5300,6 +5305,9 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
NULL); NULL);
p_range_clause->range = expr; p_range_clause->range = expr;
if (til->empty())
return;
bool any_new = false; bool any_new = false;
const Typed_identifier* pti = &til->front(); const Typed_identifier* pti = &til->front();
...@@ -5347,6 +5355,9 @@ Parse::range_clause_expr(const Expression_list* vals, ...@@ -5347,6 +5355,9 @@ Parse::range_clause_expr(const Expression_list* vals,
p_range_clause->range = this->expression(PRECEDENCE_NORMAL, false, false, p_range_clause->range = this->expression(PRECEDENCE_NORMAL, false, false,
NULL, NULL); NULL, NULL);
if (vals->empty())
return;
p_range_clause->index = vals->front(); p_range_clause->index = vals->front();
if (vals->size() == 1) if (vals->size() == 1)
p_range_clause->value = NULL; p_range_clause->value = NULL;
......
...@@ -5305,8 +5305,12 @@ Statement::make_for_statement(Block* init, Expression* cond, Block* post, ...@@ -5305,8 +5305,12 @@ Statement::make_for_statement(Block* init, Expression* cond, Block* post,
int int
For_range_statement::do_traverse(Traverse* traverse) For_range_statement::do_traverse(Traverse* traverse)
{ {
if (this->traverse_expression(traverse, &this->index_var_) == TRAVERSE_EXIT) if (this->index_var_ != NULL)
{
if (this->traverse_expression(traverse, &this->index_var_)
== TRAVERSE_EXIT)
return TRAVERSE_EXIT; return TRAVERSE_EXIT;
}
if (this->value_var_ != NULL) if (this->value_var_ != NULL)
{ {
if (this->traverse_expression(traverse, &this->value_var_) if (this->traverse_expression(traverse, &this->value_var_)
...@@ -5434,12 +5438,13 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing, ...@@ -5434,12 +5438,13 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
if (iter_init != NULL) if (iter_init != NULL)
body->add_statement(Statement::make_block_statement(iter_init, loc)); body->add_statement(Statement::make_block_statement(iter_init, loc));
if (this->index_var_ != NULL)
{
Statement* assign; Statement* assign;
Expression* index_ref = Expression::make_temporary_reference(index_temp, loc); Expression* index_ref =
Expression::make_temporary_reference(index_temp, loc);
if (this->value_var_ == NULL) if (this->value_var_ == NULL)
{
assign = Statement::make_assignment(this->index_var_, index_ref, loc); assign = Statement::make_assignment(this->index_var_, index_ref, loc);
}
else else
{ {
Expression_list* lhs = new Expression_list(); Expression_list* lhs = new Expression_list();
...@@ -5453,6 +5458,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing, ...@@ -5453,6 +5458,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
assign = Statement::make_tuple_assignment(lhs, rhs, loc); assign = Statement::make_tuple_assignment(lhs, rhs, loc);
} }
body->add_statement(assign); body->add_statement(assign);
}
body->add_statement(Statement::make_block_statement(this->statements_, loc)); body->add_statement(Statement::make_block_statement(this->statements_, loc));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment