diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-03-25 05:14:57 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-03-25 05:14:57 +0000 |
commit | fe052134f692c852e092a94917dfdec7b13612c0 (patch) | |
tree | ace019ab5161d52cce663b4c7408d746727efc5c /gcc/go | |
parent | e533b2a4c9ce8ee4fd207728dba3a9e2ffc5374a (diff) | |
download | gcc-fe052134f692c852e092a94917dfdec7b13612c0.zip gcc-fe052134f692c852e092a94917dfdec7b13612c0.tar.gz gcc-fe052134f692c852e092a94917dfdec7b13612c0.tar.bz2 |
Remove closed function. Fix tuple receive in select.
From-SVN: r171440
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 38 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 20 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 69 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.h | 6 |
5 files changed, 67 insertions, 68 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 125715b..861d5c0c 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6530,7 +6530,6 @@ class Builtin_call_expression : public Call_expression BUILTIN_APPEND, BUILTIN_CAP, BUILTIN_CLOSE, - BUILTIN_CLOSED, BUILTIN_COMPLEX, BUILTIN_COPY, BUILTIN_IMAG, @@ -6588,8 +6587,6 @@ Builtin_call_expression::Builtin_call_expression(Gogo* gogo, this->code_ = BUILTIN_CAP; else if (name == "close") this->code_ = BUILTIN_CLOSE; - else if (name == "closed") - this->code_ = BUILTIN_CLOSED; else if (name == "complex") this->code_ = BUILTIN_COMPLEX; else if (name == "copy") @@ -7185,9 +7182,6 @@ Builtin_call_expression::do_type() case BUILTIN_PRINTLN: return Type::make_void_type(); - case BUILTIN_CLOSED: - return Type::lookup_bool_type(); - case BUILTIN_RECOVER: return Type::make_interface_type(NULL, BUILTINS_LOCATION); @@ -7451,7 +7445,6 @@ Builtin_call_expression::do_check_types(Gogo*) break; case BUILTIN_CLOSE: - case BUILTIN_CLOSED: if (this->check_one_arg()) { if (this->one_arg()->type()->channel_type() == NULL) @@ -7936,7 +7929,6 @@ Builtin_call_expression::do_get_tree(Translate_context* context) } case BUILTIN_CLOSE: - case BUILTIN_CLOSED: { const Expression_list* args = this->args(); gcc_assert(args != NULL && args->size() == 1); @@ -7944,28 +7936,14 @@ Builtin_call_expression::do_get_tree(Translate_context* context) tree arg_tree = arg->get_tree(context); if (arg_tree == error_mark_node) return error_mark_node; - if (this->code_ == BUILTIN_CLOSE) - { - static tree close_fndecl; - return Gogo::call_builtin(&close_fndecl, - location, - "__go_builtin_close", - 1, - void_type_node, - TREE_TYPE(arg_tree), - arg_tree); - } - else - { - static tree closed_fndecl; - return Gogo::call_builtin(&closed_fndecl, - location, - "__go_builtin_closed", - 1, - boolean_type_node, - TREE_TYPE(arg_tree), - arg_tree); - } + static tree close_fndecl; + return Gogo::call_builtin(&close_fndecl, + location, + "__go_builtin_close", + 1, + void_type_node, + TREE_TYPE(arg_tree), + arg_tree); } case BUILTIN_SIZEOF: diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index f39124c..a6411d3 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -173,15 +173,6 @@ Gogo::Gogo(int int_type_size, int pointer_size) close_type->set_is_builtin(); this->globals_->add_function_declaration("close", NULL, close_type, loc); - Typed_identifier_list* closed_result = new Typed_identifier_list(); - closed_result->push_back(Typed_identifier("", Type::lookup_bool_type(), - loc)); - Function_type* closed_type = Type::make_function_type(NULL, NULL, - closed_result, loc); - closed_type->set_is_varargs(); - closed_type->set_is_builtin(); - this->globals_->add_function_declaration("closed", NULL, closed_type, loc); - Typed_identifier_list* copy_result = new Typed_identifier_list(); copy_result->push_back(Typed_identifier("", int_type, loc)); Function_type* copy_type = Type::make_function_type(NULL, NULL, @@ -3506,12 +3497,15 @@ Variable::determine_type() true); this->init_ = NULL; } + else if (this->type_from_chan_element_) + { + Expression* init = this->init_; + init->determine_type_no_context(); + this->type_ = this->type_from_chan_element(init, true); + this->init_ = NULL; + } else { - // type_from_chan_element_ should have been cleared during - // lowering. - gcc_assert(!this->type_from_chan_element_); - Type_context context(this->type_, false); this->init_->determine_type(&context); if (this->type_ == NULL) diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 1f6e687..f1b9342 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -1717,6 +1717,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type, Statement* s = Statement::make_tuple_receive_assignment(val_var, received_var, receive->channel(), + false, location); if (!this->gogo_->in_global_scope()) @@ -3629,6 +3630,7 @@ Parse::tuple_assignment(Expression_list* lhs, Range_clause* p_range_clause) Expression* channel = receive->channel(); Statement* s = Statement::make_tuple_receive_assignment(val, success, channel, + false, location); this->gogo_->add_statement(s); } diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index f9b0853..d24d98f 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -1148,10 +1148,10 @@ class Tuple_receive_assignment_statement : public Statement { public: Tuple_receive_assignment_statement(Expression* val, Expression* closed, - Expression* channel, + Expression* channel, bool for_select, source_location location) : Statement(STATEMENT_TUPLE_RECEIVE_ASSIGNMENT, location), - val_(val), closed_(closed), channel_(channel) + val_(val), closed_(closed), channel_(channel), for_select_(for_select) { } protected: @@ -1176,6 +1176,8 @@ class Tuple_receive_assignment_statement : public Statement Expression* closed_; // The channel on which we receive the value. Expression* channel_; + // Whether this is for a select statement. + bool for_select_; }; // Traversal. @@ -1228,6 +1230,7 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, b->add_statement(closed_temp); // func chanrecv2(c chan T, val *T) bool + // func chanrecv3(c chan T, val *T) bool (if for_select) source_location bloc = BUILTINS_LOCATION; Typed_identifier_list* param_types = new Typed_identifier_list(); param_types->push_back(Typed_identifier("c", channel_type, bloc)); @@ -1239,12 +1242,22 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, Function_type* fntype = Type::make_function_type(NULL, param_types, ret_types, bloc); - Named_object* chanrecv2 = - Named_object::make_function_declaration("chanrecv2", NULL, fntype, bloc); - chanrecv2->func_declaration_value()->set_asm_name("runtime.chanrecv2"); + Named_object* chanrecv; + if (!this->for_select_) + { + chanrecv = Named_object::make_function_declaration("chanrecv2", NULL, + fntype, bloc); + chanrecv->func_declaration_value()->set_asm_name("runtime.chanrecv2"); + } + else + { + chanrecv = Named_object::make_function_declaration("chanrecv3", NULL, + fntype, bloc); + chanrecv->func_declaration_value()->set_asm_name("runtime.chanrecv3"); + } - // closed_temp = chanrecv2(channel, &val_temp) - Expression* func = Expression::make_func_reference(chanrecv2, NULL, loc); + // closed_temp = chanrecv[23](channel, &val_temp) + Expression* func = Expression::make_func_reference(chanrecv, NULL, loc); Expression_list* params = new Expression_list(); params->push_back(this->channel_); Expression* ref = Expression::make_temporary_reference(val_temp, loc); @@ -1272,10 +1285,11 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, Statement* Statement::make_tuple_receive_assignment(Expression* val, Expression* closed, Expression* channel, + bool for_select, source_location location) { return new Tuple_receive_assignment_statement(val, closed, channel, - location); + for_select, location); } // An assignment to a pair of values from a type guard. This is a @@ -4151,7 +4165,7 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function, this->val_ = Expression::make_sink(loc); Statement* s = Statement::make_tuple_receive_assignment(this->val_, this->closed_, - ref, loc); + ref, true, loc); init->add_statement(s); } else if (this->closedvar_ != NULL) @@ -4165,8 +4179,14 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function, Expression* closed = Expression::make_var_reference(this->closedvar_, loc); Statement* s = Statement::make_tuple_receive_assignment(val, closed, ref, - loc); - init->add_statement(s); + true, loc); + // We have to put S in STATEMENTS_, because that is where the + // variables are declared. + gcc_assert(this->statements_ != NULL); + this->statements_->add_statement_at_front(s); + // We have to lower STATEMENTS_ again, to lower the tuple + // receive assignment we just added. + gogo->lower_block(function, this->statements_); } else { @@ -5281,7 +5301,7 @@ For_range_statement::lower_range_map(Gogo* gogo, // Lower a for range over a channel. void -For_range_statement::lower_range_channel(Gogo* gogo, +For_range_statement::lower_range_channel(Gogo*, Block*, Block* body_block, Named_object* range_object, @@ -5299,12 +5319,11 @@ For_range_statement::lower_range_channel(Gogo* gogo, // The loop we generate: // for { - // index_temp = <-range - // if closed(range) { + // index_temp, ok_temp = <-range + // if !ok_temp { // break // } // index = index_temp - // value = value_temp // original body // } @@ -5315,26 +5334,30 @@ For_range_statement::lower_range_channel(Gogo* gogo, *ppost = NULL; // Set *PITER_INIT to - // index_temp = <-range - // if closed(range) { + // index_temp, ok_temp = <-range + // if !ok_temp { // break // } Block* iter_init = new Block(body_block, loc); - Expression* ref = this->make_range_ref(range_object, range_temp, loc); - Expression* cond = this->call_builtin(gogo, "closed", ref, loc); + Temporary_statement* ok_temp = + Statement::make_temporary(Type::lookup_bool_type(), NULL, loc); + iter_init->add_statement(ok_temp); - ref = this->make_range_ref(range_object, range_temp, loc); - Expression* recv = Expression::make_receive(ref, loc); - ref = Expression::make_temporary_reference(index_temp, loc); - Statement* s = Statement::make_assignment(ref, recv, loc); + Expression* cref = this->make_range_ref(range_object, range_temp, loc); + Expression* iref = Expression::make_temporary_reference(index_temp, loc); + Expression* oref = Expression::make_temporary_reference(ok_temp, loc); + Statement* s = Statement::make_tuple_receive_assignment(iref, oref, cref, + false, loc); iter_init->add_statement(s); Block* then_block = new Block(iter_init, loc); s = Statement::make_break_statement(this->break_label(), loc); then_block->add_statement(s); + oref = Expression::make_temporary_reference(ok_temp, loc); + Expression* cond = Expression::make_unary(OPERATOR_NOT, oref, loc); s = Statement::make_if_statement(cond, then_block, NULL, loc); iter_init->add_statement(s); diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h index bb2922f..5199981 100644 --- a/gcc/go/gofrontend/statements.h +++ b/gcc/go/gofrontend/statements.h @@ -160,10 +160,12 @@ class Statement Expression* should_set, source_location); // Make an assignment from a nonblocking receive to a pair of - // variables. + // variables. FOR_SELECT is true is this is being created for a + // case x, ok := <-c in a select statement. static Statement* make_tuple_receive_assignment(Expression* val, Expression* closed, - Expression* channel, source_location); + Expression* channel, bool for_select, + source_location); // Make an assignment from a type guard to a pair of variables. static Statement* |