diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-10-09 23:56:07 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-10-09 23:56:07 +0000 |
commit | ea411f8480a938fffab00a22b4405032689a6e50 (patch) | |
tree | 3d641cc1b7ab99508201c2ccffe850a875d924f4 /gcc | |
parent | 3369b9193606b86677e65bc96699939fb6a8d13e (diff) | |
download | gcc-ea411f8480a938fffab00a22b4405032689a6e50.zip gcc-ea411f8480a938fffab00a22b4405032689a6e50.tar.gz gcc-ea411f8480a938fffab00a22b4405032689a6e50.tar.bz2 |
compiler: Permit "for range x" clauses.
Fixes Issue 8370.
From-SVN: r216051
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 15 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 40 |
2 files changed, 36 insertions, 19 deletions
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index fd54edf..d77f462 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -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, 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, may_be_composite_lit, @@ -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. @@ -5291,7 +5297,6 @@ Parse::range_clause_decl(const Typed_identifier_list* til, p_range_clause->found = true; - go_assert(til->size() >= 1); if (til->size() > 2) error_at(this->location(), "too many variables for range clause"); @@ -5300,6 +5305,9 @@ Parse::range_clause_decl(const Typed_identifier_list* til, NULL); p_range_clause->range = expr; + if (til->empty()) + return; + bool any_new = false; const Typed_identifier* pti = &til->front(); @@ -5347,6 +5355,9 @@ Parse::range_clause_expr(const Expression_list* vals, p_range_clause->range = this->expression(PRECEDENCE_NORMAL, false, false, NULL, NULL); + if (vals->empty()) + return; + p_range_clause->index = vals->front(); if (vals->size() == 1) p_range_clause->value = NULL; diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index f847805..69073b5 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -5305,8 +5305,12 @@ Statement::make_for_statement(Block* init, Expression* cond, Block* post, int For_range_statement::do_traverse(Traverse* traverse) { - if (this->traverse_expression(traverse, &this->index_var_) == TRAVERSE_EXIT) - return TRAVERSE_EXIT; + if (this->index_var_ != NULL) + { + if (this->traverse_expression(traverse, &this->index_var_) + == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + } if (this->value_var_ != NULL) { if (this->traverse_expression(traverse, &this->value_var_) @@ -5434,25 +5438,27 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing, if (iter_init != NULL) body->add_statement(Statement::make_block_statement(iter_init, loc)); - Statement* assign; - Expression* index_ref = Expression::make_temporary_reference(index_temp, loc); - if (this->value_var_ == NULL) + if (this->index_var_ != NULL) { - assign = Statement::make_assignment(this->index_var_, index_ref, loc); - } - else - { - Expression_list* lhs = new Expression_list(); - lhs->push_back(this->index_var_); - lhs->push_back(this->value_var_); + Statement* assign; + Expression* index_ref = + Expression::make_temporary_reference(index_temp, loc); + if (this->value_var_ == NULL) + assign = Statement::make_assignment(this->index_var_, index_ref, loc); + else + { + Expression_list* lhs = new Expression_list(); + lhs->push_back(this->index_var_); + lhs->push_back(this->value_var_); - Expression_list* rhs = new Expression_list(); - rhs->push_back(index_ref); - rhs->push_back(Expression::make_temporary_reference(value_temp, loc)); + Expression_list* rhs = new Expression_list(); + rhs->push_back(index_ref); + rhs->push_back(Expression::make_temporary_reference(value_temp, loc)); - 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)); |