diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-24 06:01:27 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-24 06:01:27 +0000 |
commit | 66a133bfe80d2ab4156c4026669bda2cf73ec0c7 (patch) | |
tree | 7d40ea09a03f835f95092ac120d9da2db544b0a1 /gcc/go/gofrontend/statements.cc | |
parent | d022fa241834e3c570a3bb0248e9ad67bfba3f75 (diff) | |
download | gcc-66a133bfe80d2ab4156c4026669bda2cf73ec0c7.tar.gz |
Tuple receives indicate whether channel is closed.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171380 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go/gofrontend/statements.cc')
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 119 |
1 files changed, 78 insertions, 41 deletions
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 0a6ef8cea95..f9b0853e2ea 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -638,7 +638,7 @@ class Assignment_operation_statement : public Statement { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -667,7 +667,8 @@ Assignment_operation_statement::do_traverse(Traverse* traverse) // statement. Statement* -Assignment_operation_statement::do_lower(Gogo*, Block* enclosing) +Assignment_operation_statement::do_lower(Gogo*, Named_object*, + Block* enclosing) { source_location loc = this->location(); @@ -764,7 +765,7 @@ class Tuple_assignment_statement : public Statement { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -791,7 +792,7 @@ Tuple_assignment_statement::do_traverse(Traverse* traverse) // up into a set of single assignments. Statement* -Tuple_assignment_statement::do_lower(Gogo*, Block* enclosing) +Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing) { source_location loc = this->location(); @@ -891,7 +892,7 @@ public: { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -920,7 +921,8 @@ Tuple_map_assignment_statement::do_traverse(Traverse* traverse) // Lower a tuple map assignment. Statement* -Tuple_map_assignment_statement::do_lower(Gogo*, Block* enclosing) +Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*, + Block* enclosing) { source_location loc = this->location(); @@ -1037,7 +1039,7 @@ class Map_assignment_statement : public Statement { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -1066,7 +1068,7 @@ Map_assignment_statement::do_traverse(Traverse* traverse) // Lower a map assignment to a function call. Statement* -Map_assignment_statement::do_lower(Gogo*, Block* enclosing) +Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing) { source_location loc = this->location(); @@ -1145,11 +1147,11 @@ Statement::make_map_assignment(Expression* map_index, class Tuple_receive_assignment_statement : public Statement { public: - Tuple_receive_assignment_statement(Expression* val, Expression* success, + Tuple_receive_assignment_statement(Expression* val, Expression* closed, Expression* channel, source_location location) : Statement(STATEMENT_TUPLE_RECEIVE_ASSIGNMENT, location), - val_(val), success_(success), channel_(channel) + val_(val), closed_(closed), channel_(channel) { } protected: @@ -1161,7 +1163,7 @@ class Tuple_receive_assignment_statement : public Statement { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -1170,8 +1172,8 @@ class Tuple_receive_assignment_statement : public Statement private: // Lvalue which receives the value from the channel. Expression* val_; - // Lvalue which receives whether the read succeeded or failed. - Expression* success_; + // Lvalue which receives whether the channel is closed. + Expression* closed_; // The channel on which we receive the value. Expression* channel_; }; @@ -1182,7 +1184,7 @@ int Tuple_receive_assignment_statement::do_traverse(Traverse* traverse) { if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT - || this->traverse_expression(traverse, &this->success_) == TRAVERSE_EXIT) + || this->traverse_expression(traverse, &this->closed_) == TRAVERSE_EXIT) return TRAVERSE_EXIT; return this->traverse_expression(traverse, &this->channel_); } @@ -1190,7 +1192,8 @@ Tuple_receive_assignment_statement::do_traverse(Traverse* traverse) // Lower to a function call. Statement* -Tuple_receive_assignment_statement::do_lower(Gogo*, Block* enclosing) +Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, + Block* enclosing) { source_location loc = this->location(); @@ -1212,17 +1215,17 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Block* enclosing) // evaluated in the right order. Move_ordered_evals moe(b); this->val_->traverse_subexpressions(&moe); - this->success_->traverse_subexpressions(&moe); + this->closed_->traverse_subexpressions(&moe); // var val_temp ELEMENT_TYPE Temporary_statement* val_temp = Statement::make_temporary(channel_type->element_type(), NULL, loc); b->add_statement(val_temp); - // var success_temp bool - Temporary_statement* success_temp = + // var closed_temp bool + Temporary_statement* closed_temp = Statement::make_temporary(Type::lookup_bool_type(), NULL, loc); - b->add_statement(success_temp); + b->add_statement(closed_temp); // func chanrecv2(c chan T, val *T) bool source_location bloc = BUILTINS_LOCATION; @@ -1240,14 +1243,14 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Block* enclosing) Named_object::make_function_declaration("chanrecv2", NULL, fntype, bloc); chanrecv2->func_declaration_value()->set_asm_name("runtime.chanrecv2"); - // success_temp = chanrecv2(channel, &val_temp) + // closed_temp = chanrecv2(channel, &val_temp) Expression* func = Expression::make_func_reference(chanrecv2, NULL, loc); Expression_list* params = new Expression_list(); params->push_back(this->channel_); Expression* ref = Expression::make_temporary_reference(val_temp, loc); params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); Expression* call = Expression::make_call(func, params, false, loc); - ref = Expression::make_temporary_reference(success_temp, loc); + ref = Expression::make_temporary_reference(closed_temp, loc); Statement* s = Statement::make_assignment(ref, call, loc); b->add_statement(s); @@ -1256,9 +1259,9 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Block* enclosing) s = Statement::make_assignment(this->val_, ref, loc); b->add_statement(s); - // success = success_temp - ref = Expression::make_temporary_reference(success_temp, loc); - s = Statement::make_assignment(this->success_, ref, loc); + // closed = closed_temp + ref = Expression::make_temporary_reference(closed_temp, loc); + s = Statement::make_assignment(this->closed_, ref, loc); b->add_statement(s); return Statement::make_block_statement(b, loc); @@ -1267,11 +1270,11 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Block* enclosing) // Make a nonblocking receive statement. Statement* -Statement::make_tuple_receive_assignment(Expression* val, Expression* success, +Statement::make_tuple_receive_assignment(Expression* val, Expression* closed, Expression* channel, source_location location) { - return new Tuple_receive_assignment_statement(val, success, channel, + return new Tuple_receive_assignment_statement(val, closed, channel, location); } @@ -1297,7 +1300,7 @@ class Tuple_type_guard_assignment_statement : public Statement { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -1338,7 +1341,8 @@ Tuple_type_guard_assignment_statement::do_traverse(Traverse* traverse) // Lower to a function call. Statement* -Tuple_type_guard_assignment_statement::do_lower(Gogo*, Block* enclosing) +Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*, + Block* enclosing) { source_location loc = this->location(); @@ -1643,7 +1647,7 @@ class Inc_dec_statement : public Statement { gcc_unreachable(); } Statement* - do_lower(Gogo*, Block*); + do_lower(Gogo*, Named_object*, Block*); tree do_get_tree(Translate_context*) @@ -1659,7 +1663,7 @@ class Inc_dec_statement : public Statement // Lower to += or -=. Statement* -Inc_dec_statement::do_lower(Gogo*, Block*) +Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*) { source_location loc = this->location(); @@ -2429,7 +2433,7 @@ Return_statement::do_traverse_assignments(Traverse_assignments* tassign) // panic/recover work correctly. Statement* -Return_statement::do_lower(Gogo*, Block* enclosing) +Return_statement::do_lower(Gogo*, Named_object*, Block* enclosing) { if (this->vals_ == NULL) return this; @@ -3530,7 +3534,7 @@ Switch_statement::do_traverse(Traverse* traverse) // of if statements. Statement* -Switch_statement::do_lower(Gogo*, Block* enclosing) +Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing) { source_location loc = this->location(); @@ -3871,7 +3875,7 @@ Type_switch_statement::do_traverse(Traverse* traverse) // equality testing. Statement* -Type_switch_statement::do_lower(Gogo*, Block* enclosing) +Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing) { const source_location loc = this->location(); @@ -4079,6 +4083,11 @@ Select_clauses::Select_clause::traverse(Traverse* traverse) if (Expression::traverse(&this->val_, traverse) == TRAVERSE_EXIT) return TRAVERSE_EXIT; } + if (this->closed_ != NULL) + { + if (Expression::traverse(&this->closed_, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + } } if (this->statements_ != NULL) { @@ -4093,7 +4102,8 @@ Select_clauses::Select_clause::traverse(Traverse* traverse) // receive statements to the clauses. void -Select_clauses::Select_clause::lower(Block* b) +Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function, + Block* b) { if (this->is_default_) { @@ -4134,6 +4144,30 @@ Select_clauses::Select_clause::lower(Block* b) send->set_for_select(); init->add_statement(send); } + else if (this->closed_ != NULL && !this->closed_->is_sink_expression()) + { + gcc_assert(this->var_ == NULL && this->closedvar_ == NULL); + if (this->val_ == NULL) + this->val_ = Expression::make_sink(loc); + Statement* s = Statement::make_tuple_receive_assignment(this->val_, + this->closed_, + ref, loc); + init->add_statement(s); + } + else if (this->closedvar_ != NULL) + { + gcc_assert(this->val_ == NULL); + Expression* val; + if (this->var_ == NULL) + val = Expression::make_sink(loc); + else + val = Expression::make_var_reference(this->var_, loc); + Expression* closed = Expression::make_var_reference(this->closedvar_, + loc); + Statement* s = Statement::make_tuple_receive_assignment(val, closed, ref, + loc); + init->add_statement(s); + } else { Receive_expression* recv = Expression::make_receive(ref, loc); @@ -4151,11 +4185,13 @@ Select_clauses::Select_clause::lower(Block* b) } else { - recv->discarding_value(); init->add_statement(Statement::make_statement(recv)); } } + // Lower any statements we just created. + gogo->lower_block(function, init); + if (this->statements_ != NULL) init->add_statement(Statement::make_block_statement(this->statements_, loc)); @@ -4222,12 +4258,12 @@ Select_clauses::traverse(Traverse* traverse) // receive statements to the clauses. void -Select_clauses::lower(Block* b) +Select_clauses::lower(Gogo* gogo, Named_object* function, Block* b) { for (Clauses::iterator p = this->clauses_.begin(); p != this->clauses_.end(); ++p) - p->lower(b); + p->lower(gogo, function, b); } // Determine types. @@ -4464,12 +4500,13 @@ Select_statement::break_label() // explicit statements in the clauses. Statement* -Select_statement::do_lower(Gogo*, Block* enclosing) +Select_statement::do_lower(Gogo* gogo, Named_object* function, + Block* enclosing) { if (this->is_lowered_) return this; Block* b = new Block(enclosing, this->location()); - this->clauses_->lower(b); + this->clauses_->lower(gogo, function, b); this->is_lowered_ = true; b->add_statement(this); return Statement::make_block_statement(b, this->location()); @@ -4521,7 +4558,7 @@ For_statement::do_traverse(Traverse* traverse) // complex statements make it easier to handle garbage collection. Statement* -For_statement::do_lower(Gogo*, Block* enclosing) +For_statement::do_lower(Gogo*, Named_object*, Block* enclosing) { Statement* s; source_location loc = this->location(); @@ -4652,7 +4689,7 @@ For_range_statement::do_traverse(Traverse* traverse) // statements. Statement* -For_range_statement::do_lower(Gogo* gogo, Block* enclosing) +For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing) { Type* range_type = this->range_->type(); if (range_type->points_to() != NULL |