aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-03-25 05:14:57 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-03-25 05:14:57 +0000
commitfe052134f692c852e092a94917dfdec7b13612c0 (patch)
treeace019ab5161d52cce663b4c7408d746727efc5c /gcc/go
parente533b2a4c9ce8ee4fd207728dba3a9e2ffc5374a (diff)
downloadgcc-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.cc38
-rw-r--r--gcc/go/gofrontend/gogo.cc20
-rw-r--r--gcc/go/gofrontend/parse.cc2
-rw-r--r--gcc/go/gofrontend/statements.cc69
-rw-r--r--gcc/go/gofrontend/statements.h6
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*