diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-09-13 21:32:24 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-09-13 21:32:24 +0000 |
commit | 84cdf51de42f823b4ed0d65ef20ab0142607917b (patch) | |
tree | b7d94851b891d2529f5f7eb23386a86f07563097 /gcc/go | |
parent | 283b9cafbd73b92b106e3f23b07f59af6761c78b (diff) | |
download | gcc-84cdf51de42f823b4ed0d65ef20ab0142607917b.zip gcc-84cdf51de42f823b4ed0d65ef20ab0142607917b.tar.gz gcc-84cdf51de42f823b4ed0d65ef20ab0142607917b.tar.bz2 |
compiler, runtime: open code select
This is the gofrontend version of https://golang.org/cl/37933,
https://golang.org/cl/37934, and https://golang.org/cl/37935.
Open code the initialization of select cases.
This is a step toward updating libgo to the 1.11 release.
Reviewed-on: https://go-review.googlesource.com/135000
From-SVN: r264290
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/escape.cc | 25 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.def | 20 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 232 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.h | 50 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 46 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 2 |
7 files changed, 217 insertions, 160 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3d640b2..6650b03 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -f68c03e509b26e7f483f2800eb70a5fbf3f74d0b +f2cd046a4e0d681c3d21ee547b437d3eab8af268 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc index e32ae5b..9c31525 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -1361,7 +1361,13 @@ Escape_analysis_assign::statement(Block*, size_t*, Statement* s) { Expression* init = s->temporary_statement()->init(); if (init != NULL) - this->assign(Node::make_node(s), Node::make_node(init)); + { + Node* n = Node::make_node(init); + if (s->temporary_statement()->value_escapes()) + this->assign(this->context_->sink(), n); + else + this->assign(Node::make_node(s), n); + } } break; @@ -1616,15 +1622,6 @@ Escape_analysis_assign::expression(Expression** pexpr) } break; - case Runtime::SELECTSEND: - { - // Send to a channel, lose track. The last argument is - // the address of the value to send. - Node* arg_node = Node::make_node(call->args()->back()); - this->assign_deref(this->context_->sink(), arg_node); - } - break; - case Runtime::IFACEE2T2: case Runtime::IFACEI2T2: { @@ -2228,8 +2225,12 @@ Escape_analysis_assign::assign(Node* dst, Node* src) case Expression::EXPRESSION_TEMPORARY_REFERENCE: { // Temporary is tracked through the underlying Temporary_statement. - Statement* t = dst->expr()->temporary_reference_expression()->statement(); - dst = Node::make_node(t); + Temporary_statement* t = + dst->expr()->temporary_reference_expression()->statement(); + if (t->value_escapes()) + dst = this->context_->sink(); + else + dst = Node::make_node(t); } break; diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index fdb159e..1486cd8 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -152,22 +152,10 @@ DEF_GO_RUNTIME(CHANRECV1, "runtime.chanrecv1", P2(CHAN, POINTER), R0()) DEF_GO_RUNTIME(CHANRECV2, "runtime.chanrecv2", P2(CHAN, POINTER), R1(BOOL)) -// Start building a select statement. -DEF_GO_RUNTIME(NEWSELECT, "runtime.newselect", P3(POINTER, INT64, INT32), R0()) - -// Add a default clause to a select statement. -DEF_GO_RUNTIME(SELECTDEFAULT, "runtime.selectdefault", P1(POINTER), R0()) - -// Add a send clause to a select statement. -DEF_GO_RUNTIME(SELECTSEND, "runtime.selectsend", P3(POINTER, CHAN, POINTER), - R0()) - -// Add a receive clause to a select statement. -DEF_GO_RUNTIME(SELECTRECV, "runtime.selectrecv", - P4(POINTER, CHAN, POINTER, BOOLPTR), R0()) - -// Run a select, returning the index of the selected clause. -DEF_GO_RUNTIME(SELECTGO, "runtime.selectgo", P1(POINTER), R1(INT)) +// Run a select, returning the index of the selected clause and +// whether that channel received a value. +DEF_GO_RUNTIME(SELECTGO, "runtime.selectgo", P3(POINTER, POINTER, INT), + R2(INT, BOOL)) // Panic. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 19a07d4..1df676f 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -4548,17 +4548,19 @@ Select_clauses::Select_clause::traverse(Traverse* traverse) void Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function, - Block* b, Temporary_statement* sel) + Block* b, Temporary_statement* scases, + size_t index, Temporary_statement* recvok) { Location loc = this->location_; - Expression* selref = Expression::make_temporary_reference(sel, loc); - selref = Expression::make_unary(OPERATOR_AND, selref, loc); + Expression* scase = Expression::make_temporary_reference(scases, loc); + Expression* index_expr = Expression::make_integer_ul(index, NULL, loc); + scase = Expression::make_array_index(scase, index_expr, NULL, NULL, loc); if (this->is_default_) { go_assert(this->channel_ == NULL && this->val_ == NULL); - this->lower_default(b, selref); + this->lower_default(b, scase); this->is_lowered_ = true; return; } @@ -4572,9 +4574,9 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function, loc); if (this->is_send_) - this->lower_send(b, selref, chanref); + this->lower_send(b, scase, chanref); else - this->lower_recv(gogo, function, b, selref, chanref); + this->lower_recv(gogo, function, b, scase, chanref, recvok); // Now all references should be handled through the statements, not // through here. @@ -4585,18 +4587,16 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function, // Lower a default clause in a select statement. void -Select_clauses::Select_clause::lower_default(Block* b, Expression* selref) +Select_clauses::Select_clause::lower_default(Block* b, Expression* scase) { Location loc = this->location_; - Expression* call = Runtime::make_call(Runtime::SELECTDEFAULT, loc, 1, - selref); - b->add_statement(Statement::make_statement(call, true)); + this->set_case(b, scase, Expression::make_nil(loc), NULL, caseDefault); } // Lower a send clause in a select statement. void -Select_clauses::Select_clause::lower_send(Block* b, Expression* selref, +Select_clauses::Select_clause::lower_send(Block* b, Expression* scase, Expression* chanref) { Location loc = this->location_; @@ -4611,22 +4611,29 @@ Select_clauses::Select_clause::lower_send(Block* b, Expression* selref, // evaluate the send values in the required order. Temporary_statement* val = Statement::make_temporary(valtype, this->val_, loc); + // The value here escapes, because it might be sent on a channel. + // We record that via the Temporary_statement, so that the escape + // analysis pass can pick it up. The gc compiler lowers select + // statements after escape analysis, so it doesn't have to worry + // about this. + val->set_value_escapes(); b->add_statement(val); Expression* valref = Expression::make_temporary_reference(val, loc); Expression* valaddr = Expression::make_unary(OPERATOR_AND, valref, loc); + Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type()); + valaddr = Expression::make_cast(unsafe_pointer_type, valaddr, loc); - Expression* call = Runtime::make_call(Runtime::SELECTSEND, loc, 3, selref, - chanref, valaddr); - b->add_statement(Statement::make_statement(call, true)); + this->set_case(b, scase, chanref, valaddr, caseSend); } // Lower a receive clause in a select statement. void Select_clauses::Select_clause::lower_recv(Gogo* gogo, Named_object* function, - Block* b, Expression* selref, - Expression* chanref) + Block* b, Expression* scase, + Expression* chanref, + Temporary_statement* recvok) { Location loc = this->location_; @@ -4640,26 +4647,10 @@ Select_clauses::Select_clause::lower_recv(Gogo* gogo, Named_object* function, Expression* valref = Expression::make_temporary_reference(val, loc); Expression* valaddr = Expression::make_unary(OPERATOR_AND, valref, loc); + Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type()); + valaddr = Expression::make_cast(unsafe_pointer_type, valaddr, loc); - Temporary_statement* closed_temp = NULL; - - Expression* caddr; - if (this->closed_ == NULL && this->closedvar_ == NULL) - caddr = Expression::make_nil(loc); - else - { - closed_temp = Statement::make_temporary(Type::lookup_bool_type(), NULL, - loc); - b->add_statement(closed_temp); - Expression* cref = Expression::make_temporary_reference(closed_temp, - loc); - caddr = Expression::make_unary(OPERATOR_AND, cref, loc); - } - - Expression* call = Runtime::make_call(Runtime::SELECTRECV, loc, 4, selref, - chanref, valaddr, caddr); - - b->add_statement(Statement::make_statement(call, true)); + this->set_case(b, scase, chanref, valaddr, caseRecv); // If the block of statements is executed, arrange for the received // value to move from VAL to the place where the statements expect @@ -4684,16 +4675,14 @@ Select_clauses::Select_clause::lower_recv(Gogo* gogo, Named_object* function, if (this->closedvar_ != NULL) { go_assert(this->closed_ == NULL); - Expression* cref = Expression::make_temporary_reference(closed_temp, - loc); + Expression* cref = Expression::make_temporary_reference(recvok, loc); this->closedvar_->var_value()->set_init(cref); } else if (this->closed_ != NULL && !this->closed_->is_sink_expression()) { if (init == NULL) init = new Block(b, loc); - Expression* cref = Expression::make_temporary_reference(closed_temp, - loc); + Expression* cref = Expression::make_temporary_reference(recvok, loc); init->add_statement(Statement::make_assignment(this->closed_, cref, loc)); } @@ -4709,6 +4698,45 @@ Select_clauses::Select_clause::lower_recv(Gogo* gogo, Named_object* function, } } +// Set the fields of an scase struct, an element in the array that we +// pass to the runtime function selectgo. + +void +Select_clauses::Select_clause::set_case(Block* b, + Expression* scase, + Expression* chanref, + Expression* elem, + int kind) +{ + Location loc = this->location_; + Struct_type* scase_type = scase->type()->struct_type(); + + int field_index = 0; + go_assert(scase_type->field(field_index)->is_field_name("c")); + Expression* ref = Expression::make_field_reference(scase, field_index, loc); + Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type()); + chanref = Expression::make_unsafe_cast(unsafe_pointer_type, chanref, loc); + Statement* s = Statement::make_assignment(ref, chanref, loc); + b->add_statement(s); + + if (elem != NULL) + { + field_index = 1; + go_assert(scase_type->field(field_index)->is_field_name("elem")); + ref = Expression::make_field_reference(scase->copy(), field_index, loc); + s = Statement::make_assignment(ref, elem, loc); + b->add_statement(s); + } + + field_index = 2; + go_assert(scase_type->field(field_index)->is_field_name("kind")); + Type* uint16_type = Type::lookup_integer_type("uint16"); + Expression* k = Expression::make_integer_ul(kind, uint16_type, loc); + ref = Expression::make_field_reference(scase->copy(), field_index, loc); + s = Statement::make_assignment(ref, k, loc); + b->add_statement(s); +} + // Determine types. void @@ -4828,12 +4856,13 @@ Select_clauses::traverse(Traverse* traverse) void Select_clauses::lower(Gogo* gogo, Named_object* function, Block* b, - Temporary_statement* sel) + Temporary_statement* scases, Temporary_statement* recvok) { + size_t i = 0; for (Clauses::iterator p = this->clauses_.begin(); p != this->clauses_.end(); - ++p) - p->lower(gogo, function, b, sel); + ++p, ++i) + p->lower(gogo, function, b, scases, i, recvok); } // Determine types. @@ -4872,13 +4901,13 @@ Select_clauses::may_fall_through() const return false; } -// Convert to the backend representation. We have already accumulated -// all the select information. Now we call selectgo, which will -// return the index of the clause to execute. +// Convert to the backend representation. Assemble the clauses and +// build a switch statement on the index value returned by the call to +// selectgo. Bstatement* Select_clauses::get_backend(Translate_context* context, - Temporary_statement* sel, + Temporary_statement* index, Unnamed_label *break_label, Location location) { @@ -4909,21 +4938,14 @@ Select_clauses::get_backend(Translate_context* context, clauses[i] = context->backend()->compound_statement(s, g); } - Expression* selref = Expression::make_temporary_reference(sel, location); - selref = Expression::make_unary(OPERATOR_AND, selref, location); - Expression* call = Runtime::make_call(Runtime::SELECTGO, location, 1, - selref); - context->gogo()->lower_expression(context->function(), NULL, &call); - Bexpression* bcall = call->get_backend(context); - - if (count == 0) - { - Bfunction* bfunction = context->function()->func_value()->get_decl(); - return context->backend()->expression_statement(bfunction, bcall); - } + Expression* ref = Expression::make_temporary_reference(index, location); + Bexpression* bindex = ref->get_backend(context); Bfunction* bfunction = context->function()->func_value()->get_decl(); + if (count == 0) + return context->backend()->expression_statement(bfunction, bindex); + Expression* crash = Runtime::make_call(Runtime::UNREACHABLE, location, 0); Bexpression* bcrash = crash->get_backend(context); clauses[count] = context->backend()->expression_statement(bfunction, bcrash); @@ -4932,7 +4954,7 @@ Select_clauses::get_backend(Translate_context* context, statements.reserve(2); Bstatement* switch_stmt = context->backend()->switch_statement(bfunction, - bcall, + bindex, cases, clauses, location); @@ -4943,6 +4965,7 @@ Select_clauses::get_backend(Translate_context* context, return context->backend()->statement_list(statements); } + // Dump the AST representation for select clauses. void @@ -4967,10 +4990,10 @@ Select_statement::break_label() return this->break_label_; } -// Lower a select statement. This will still return a select -// statement, but it will be modified to implement the order of -// evaluation rules, and to include the send and receive statements as -// explicit statements in the clauses. +// Lower a select statement. This will return a block containing this +// select statement. The block will implement the order of evaluation +// rules, include the send and receive statements as explicit +// statements in the clauses, and call the runtime selectgo function. Statement* Select_statement::do_lower(Gogo* gogo, Named_object* function, @@ -4983,30 +5006,69 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function, Block* b = new Block(enclosing, loc); - go_assert(this->sel_ == NULL); - int ncases = this->clauses_->size(); - Type* selstruct_type = Channel_type::select_type(ncases); - this->sel_ = Statement::make_temporary(selstruct_type, NULL, loc); - b->add_statement(this->sel_); + Type* scase_type = Channel_type::select_case_type(); + Expression* ncases_expr = + Expression::make_integer_ul(ncases, NULL, + Linemap::predeclared_location()); + Array_type* scases_type = Type::make_array_type(scase_type, ncases_expr); + scases_type->set_is_array_incomparable(); + + Temporary_statement* scases = Statement::make_temporary(scases_type, NULL, + loc); + b->add_statement(scases); - int64_t selstruct_size; - if (!selstruct_type->backend_type_size(gogo, &selstruct_size)) - { - go_assert(saw_errors()); - return Statement::make_error_statement(loc); - } + Expression* ncases2_expr = + Expression::make_integer_ul(ncases * 2, NULL, + Linemap::predeclared_location()); + Type* uint16_type = Type::lookup_integer_type("uint16"); + Array_type* order_type = Type::make_array_type(uint16_type, ncases2_expr); + order_type->set_is_array_incomparable(); + + Temporary_statement* order = Statement::make_temporary(order_type, NULL, + loc); + b->add_statement(order); - Expression* ref = Expression::make_temporary_reference(this->sel_, loc); - ref = Expression::make_unary(OPERATOR_AND, ref, loc); - Expression* selstruct_size_expr = - Expression::make_integer_int64(selstruct_size, NULL, loc); - Expression* size_expr = Expression::make_integer_ul(ncases, NULL, loc); - Expression* call = Runtime::make_call(Runtime::NEWSELECT, loc, 3, - ref, selstruct_size_expr, size_expr); - b->add_statement(Statement::make_statement(call, true)); + Type* int_type = Type::lookup_integer_type("int"); + this->index_ = Statement::make_temporary(int_type, NULL, loc); + b->add_statement(this->index_); + + Type* bool_type = Type::lookup_bool_type(); + Temporary_statement* recvok = Statement::make_temporary(bool_type, NULL, + loc); + b->add_statement(recvok); + + // Initialize the scases array. + this->clauses_->lower(gogo, function, b, scases, recvok); + + // Build the call to selectgo. Later, in do_get_backend, we will + // build a switch on the result that branches to the various cases. + + Expression* scases_ref = Expression::make_temporary_reference(scases, loc); + scases_ref = Expression::make_unary(OPERATOR_AND, scases_ref, loc); + Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type()); + scases_ref = Expression::make_cast(unsafe_pointer_type, scases_ref, loc); + + Expression* order_ref = Expression::make_temporary_reference(order, loc); + order_ref = Expression::make_unary(OPERATOR_AND, order_ref, loc); + order_ref = Expression::make_cast(unsafe_pointer_type, order_ref, loc); + + Expression* count_expr = Expression::make_integer_ul(ncases, int_type, loc); + + Call_expression* call = Runtime::make_call(Runtime::SELECTGO, loc, 3, + scases_ref, order_ref, + count_expr); + + Expression* result = Expression::make_call_result(call, 0); + Expression* ref = Expression::make_temporary_reference(this->index_, loc); + Statement* s = Statement::make_assignment(ref, result, loc); + b->add_statement(s); + + result = Expression::make_call_result(call, 1); + ref = Expression::make_temporary_reference(recvok, loc); + s = Statement::make_assignment(ref, result, loc); + b->add_statement(s); - this->clauses_->lower(gogo, function, b, this->sel_); this->is_lowered_ = true; b->add_statement(this); @@ -5031,8 +5093,8 @@ Select_statement::do_may_fall_through() const Bstatement* Select_statement::do_get_backend(Translate_context* context) { - return this->clauses_->get_backend(context, this->sel_, this->break_label(), - this->location()); + return this->clauses_->get_backend(context, this->index_, + this->break_label(), this->location()); } // Dump the AST representation for a select statement. diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h index c9ab4d6..81b26b3 100644 --- a/gcc/go/gofrontend/statements.h +++ b/gcc/go/gofrontend/statements.h @@ -622,7 +622,8 @@ class Temporary_statement : public Statement public: Temporary_statement(Type* type, Expression* init, Location location) : Statement(STATEMENT_TEMPORARY, location), - type_(type), init_(init), bvariable_(NULL), is_address_taken_(false) + type_(type), init_(init), bvariable_(NULL), is_address_taken_(false), + value_escapes_(false) { } // Return the type of the temporary variable. @@ -640,6 +641,16 @@ class Temporary_statement : public Statement set_is_address_taken() { this->is_address_taken_ = true; } + // Whether the value escapes. + bool + value_escapes() const + { return this->value_escapes_; } + + // Record that the value escapes. + void + set_value_escapes() + { this->value_escapes_ = true; } + // Return the temporary variable. This should not be called until // after the statement itself has been converted. Bvariable* @@ -676,6 +687,9 @@ class Temporary_statement : public Statement Bvariable* bvariable_; // True if something takes the address of this temporary variable. bool is_address_taken_; + // True if the value assigned to this temporary variable escapes. + // This is used for select statements. + bool value_escapes_; }; // A variable declaration. This marks the point in the code where a @@ -851,7 +865,7 @@ class Send_statement : public Statement Expression* channel() - { return this->channel_; } + { return this->channel_; } Expression* val() @@ -924,7 +938,8 @@ class Select_clauses // Lower statements. void - lower(Gogo*, Named_object*, Block*, Temporary_statement*); + lower(Gogo*, Named_object*, Block*, Temporary_statement*, + Temporary_statement*); // Determine types. void @@ -941,7 +956,7 @@ class Select_clauses // Convert to the backend representation. Bstatement* - get_backend(Translate_context*, Temporary_statement* sel, + get_backend(Translate_context*, Temporary_statement* index, Unnamed_label* break_label, Location); // Dump AST representation. @@ -974,7 +989,8 @@ class Select_clauses // Lower statements. void - lower(Gogo*, Named_object*, Block*, Temporary_statement*); + lower(Gogo*, Named_object*, Block*, Temporary_statement*, size_t, + Temporary_statement*); // Determine types. void @@ -1027,6 +1043,14 @@ class Select_clauses dump_clause(Ast_dump_context*) const; private: + // These values must match the values in libgo/go/runtime/select.go. + enum + { + caseRecv = 1, + caseSend = 2, + caseDefault = 3, + }; + void lower_default(Block*, Expression*); @@ -1034,7 +1058,11 @@ class Select_clauses lower_send(Block*, Expression*, Expression*); void - lower_recv(Gogo*, Named_object*, Block*, Expression*, Expression*); + lower_recv(Gogo*, Named_object*, Block*, Expression*, Expression*, + Temporary_statement*); + + void + set_case(Block*, Expression*, Expression*, Expression*, int); // The channel. Expression* channel_; @@ -1072,7 +1100,7 @@ class Select_statement : public Statement public: Select_statement(Location location) : Statement(STATEMENT_SELECT, location), - clauses_(NULL), sel_(NULL), break_label_(NULL), is_lowered_(false) + clauses_(NULL), index_(NULL), break_label_(NULL), is_lowered_(false) { } // Add the clauses. @@ -1115,8 +1143,8 @@ class Select_statement : public Statement private: // The select clauses. Select_clauses* clauses_; - // A temporary which holds the select structure we build up at runtime. - Temporary_statement* sel_; + // A temporary that holds the index value returned by selectgo. + Temporary_statement* index_; // The break label. Unnamed_label* break_label_; // Whether this statement has been lowered. @@ -1609,7 +1637,7 @@ class Case_clauses // Dump the AST representation to a dump context. void dump_clauses(Ast_dump_context*) const; - + private: // For a constant switch we need to keep a record of constants we // have already seen. @@ -1683,7 +1711,7 @@ class Case_clauses // Dump the AST representation to a dump context. void dump_clause(Ast_dump_context*) const; - + private: // The list of case expressions. Expression_list* cases_; diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 00098da..cc07bfc 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -8557,51 +8557,29 @@ Channel_type::do_import(Import* imp) return Type::make_channel_type(may_send, may_receive, element_type); } -// Return the type to manage a select statement with ncases case -// statements. A value of this type is allocated on the stack. This -// must match the type hselect in libgo/go/runtime/select.go. +// Return the type that the runtime package uses for one case of a +// select statement. An array of values of this type is allocated on +// the stack. This must match scase in libgo/go/runtime/select.go. Type* -Channel_type::select_type(int ncases) +Channel_type::select_case_type() { - Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type()); - Type* uint16_type = Type::lookup_integer_type("uint16"); - static Struct_type* scase_type; if (scase_type == NULL) { - Type* uintptr_type = Type::lookup_integer_type("uintptr"); - Type* uint64_type = Type::lookup_integer_type("uint64"); + Type* unsafe_pointer_type = + Type::make_pointer_type(Type::make_void_type()); + Type* uint16_type = Type::lookup_integer_type("uint16"); + Type* int64_type = Type::lookup_integer_type("int64"); scase_type = - Type::make_builtin_struct_type(7, + Type::make_builtin_struct_type(4, + "c", unsafe_pointer_type, "elem", unsafe_pointer_type, - "chan", unsafe_pointer_type, - "pc", uintptr_type, "kind", uint16_type, - "index", uint16_type, - "receivedp", unsafe_pointer_type, - "releasetime", uint64_type); + "releasetime", int64_type); scase_type->set_is_struct_incomparable(); } - - Expression* ncases_expr = - Expression::make_integer_ul(ncases, NULL, Linemap::predeclared_location()); - Array_type* scases = Type::make_array_type(scase_type, ncases_expr); - scases->set_is_array_incomparable(); - Array_type* order = Type::make_array_type(uint16_type, ncases_expr); - order->set_is_array_incomparable(); - - Struct_type* ret = - Type::make_builtin_struct_type(7, - "tcase", uint16_type, - "ncase", uint16_type, - "pollorder", unsafe_pointer_type, - "lockorder", unsafe_pointer_type, - "scase", scases, - "lockorderarr", order, - "pollorderarr", order); - ret->set_is_struct_incomparable(); - return ret; + return scase_type; } // Make a new channel type. diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 0f85c3a..e011236 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2981,7 +2981,7 @@ class Channel_type : public Type make_chan_type_descriptor_type(); static Type* - select_type(int ncases); + select_case_type(); protected: int |