summaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/statements.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go/gofrontend/statements.h')
-rw-r--r--gcc/go/gofrontend/statements.h83
1 files changed, 53 insertions, 30 deletions
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index 16914f16c37..4548ba6f56c 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -165,12 +165,10 @@ class Statement
Expression* should_set, Location);
// Make an assignment from a nonblocking receive to a pair of
- // variables. FOR_SELECT is true is this is being created for a
- // case x, ok := <-c in a select statement.
+ // variables.
static Statement*
make_tuple_receive_assignment(Expression* val, Expression* closed,
- Expression* channel, bool for_select,
- Location);
+ Expression* channel, Location);
// Make an assignment from a type guard to a pair of variables.
static Statement*
@@ -634,14 +632,9 @@ class Send_statement : public Statement
Send_statement(Expression* channel, Expression* val,
Location location)
: Statement(STATEMENT_SEND, location),
- channel_(channel), val_(val), for_select_(false)
+ channel_(channel), val_(val)
{ }
- // Note that this is for a select statement.
- void
- set_for_select()
- { this->for_select_ = true; }
-
protected:
int
do_traverse(Traverse* traverse);
@@ -663,8 +656,6 @@ class Send_statement : public Statement
Expression* channel_;
// The value to send.
Expression* val_;
- // Whether this is for a select statement.
- bool for_select_;
};
// Select_clauses holds the clauses of a select statement. This is
@@ -693,23 +684,32 @@ class Select_clauses
Named_object* var, Named_object* closedvar, bool is_default,
Block* statements, Location location)
{
- this->clauses_.push_back(Select_clause(is_send, channel, val, closed, var,
- closedvar, is_default, statements,
- location));
+ int index = static_cast<int>(this->clauses_.size());
+ this->clauses_.push_back(Select_clause(index, is_send, channel, val,
+ closed, var, closedvar, is_default,
+ statements, location));
}
+ size_t
+ size() const
+ { return this->clauses_.size(); }
+
// Traverse the select clauses.
int
traverse(Traverse*);
// Lower statements.
void
- lower(Gogo*, Named_object*, Block*);
+ lower(Gogo*, Named_object*, Block*, Temporary_statement*);
// Determine types.
void
determine_types();
+ // Check types.
+ void
+ check_types();
+
// Whether the select clauses may fall through to the statement
// which follows the overall select statement.
bool
@@ -717,7 +717,8 @@ class Select_clauses
// Convert to the backend representation.
Bstatement*
- get_backend(Translate_context*, Unnamed_label* break_label, Location);
+ get_backend(Translate_context*, Temporary_statement* sel,
+ Unnamed_label* break_label, Location);
// Dump AST representation.
void
@@ -734,27 +735,37 @@ class Select_clauses
is_default_(false)
{ }
- Select_clause(bool is_send, Expression* channel, Expression* val,
- Expression* closed, Named_object* var,
+ Select_clause(int index, bool is_send, Expression* channel,
+ Expression* val, Expression* closed, Named_object* var,
Named_object* closedvar, bool is_default, Block* statements,
Location location)
- : channel_(channel), val_(val), closed_(closed), var_(var),
- closedvar_(closedvar), statements_(statements), location_(location),
- is_send_(is_send), is_default_(is_default), is_lowered_(false)
+ : index_(index), channel_(channel), val_(val), closed_(closed),
+ var_(var), closedvar_(closedvar), statements_(statements),
+ location_(location), is_send_(is_send), is_default_(is_default),
+ is_lowered_(false)
{ go_assert(is_default ? channel == NULL : channel != NULL); }
+ // Return the index of this clause.
+ int
+ index() const
+ { return this->index_; }
+
// Traverse the select clause.
int
traverse(Traverse*);
// Lower statements.
void
- lower(Gogo*, Named_object*, Block*);
+ lower(Gogo*, Named_object*, Block*, Temporary_statement*);
// Determine types.
void
determine_types();
+ // Check types.
+ void
+ check_types();
+
// Return true if this is the default clause.
bool
is_default() const
@@ -798,6 +809,18 @@ class Select_clauses
dump_clause(Ast_dump_context*) const;
private:
+ void
+ lower_default(Block*, Expression*, Expression*);
+
+ void
+ lower_send(Block*, Expression*, Expression*, Expression*);
+
+ void
+ lower_recv(Gogo*, Named_object*, Block*, Expression*, Expression*,
+ Expression*);
+
+ // The index of this case in the generated switch statement.
+ int index_;
// The channel.
Expression* channel_;
// The value to send or the lvalue to receive into.
@@ -822,12 +845,6 @@ class Select_clauses
bool is_lowered_;
};
- void
- add_clause_backend(Translate_context*, Location, int index,
- int case_value, Select_clause*, Unnamed_label*,
- std::vector<std::vector<Bexpression*> >* cases,
- std::vector<Bstatement*>* clauses);
-
typedef std::vector<Select_clause> Clauses;
Clauses clauses_;
@@ -840,7 +857,7 @@ class Select_statement : public Statement
public:
Select_statement(Location location)
: Statement(STATEMENT_SELECT, location),
- clauses_(NULL), break_label_(NULL), is_lowered_(false)
+ clauses_(NULL), sel_(NULL), break_label_(NULL), is_lowered_(false)
{ }
// Add the clauses.
@@ -867,6 +884,10 @@ class Select_statement : public Statement
do_determine_types()
{ this->clauses_->determine_types(); }
+ void
+ do_check_types(Gogo*)
+ { this->clauses_->check_types(); }
+
bool
do_may_fall_through() const
{ return this->clauses_->may_fall_through(); }
@@ -880,6 +901,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_;
// The break label.
Unnamed_label* break_label_;
// Whether this statement has been lowered.