OSDN Git Service

Unify handling of runtime support functions.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / statements.cc
1 // statements.cc -- Go frontend statements.
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 #include "go-system.h"
8
9 #include <gmp.h>
10
11 #ifndef ENABLE_BUILD_WITH_CXX
12 extern "C"
13 {
14 #endif
15
16 #include "intl.h"
17 #include "tree.h"
18 #include "gimple.h"
19 #include "convert.h"
20 #include "tree-iterator.h"
21 #include "tree-flow.h"
22 #include "real.h"
23
24 #ifndef ENABLE_BUILD_WITH_CXX
25 }
26 #endif
27
28 #include "go-c.h"
29 #include "types.h"
30 #include "expressions.h"
31 #include "gogo.h"
32 #include "runtime.h"
33 #include "backend.h"
34 #include "statements.h"
35
36 // Class Statement.
37
38 Statement::Statement(Statement_classification classification,
39                      source_location location)
40   : classification_(classification), location_(location)
41 {
42 }
43
44 Statement::~Statement()
45 {
46 }
47
48 // Traverse the tree.  The work of walking the components is handled
49 // by the subclasses.
50
51 int
52 Statement::traverse(Block* block, size_t* pindex, Traverse* traverse)
53 {
54   if (this->classification_ == STATEMENT_ERROR)
55     return TRAVERSE_CONTINUE;
56
57   unsigned int traverse_mask = traverse->traverse_mask();
58
59   if ((traverse_mask & Traverse::traverse_statements) != 0)
60     {
61       int t = traverse->statement(block, pindex, this);
62       if (t == TRAVERSE_EXIT)
63         return TRAVERSE_EXIT;
64       else if (t == TRAVERSE_SKIP_COMPONENTS)
65         return TRAVERSE_CONTINUE;
66     }
67
68   // No point in checking traverse_mask here--a statement may contain
69   // other blocks or statements, and if we got here we always want to
70   // walk them.
71   return this->do_traverse(traverse);
72 }
73
74 // Traverse the contents of a statement.
75
76 int
77 Statement::traverse_contents(Traverse* traverse)
78 {
79   return this->do_traverse(traverse);
80 }
81
82 // Traverse assignments.
83
84 bool
85 Statement::traverse_assignments(Traverse_assignments* tassign)
86 {
87   if (this->classification_ == STATEMENT_ERROR)
88     return false;
89   return this->do_traverse_assignments(tassign);
90 }
91
92 // Traverse an expression in a statement.  This is a helper function
93 // for child classes.
94
95 int
96 Statement::traverse_expression(Traverse* traverse, Expression** expr)
97 {
98   if ((traverse->traverse_mask()
99        & (Traverse::traverse_types | Traverse::traverse_expressions)) == 0)
100     return TRAVERSE_CONTINUE;
101   return Expression::traverse(expr, traverse);
102 }
103
104 // Traverse an expression list in a statement.  This is a helper
105 // function for child classes.
106
107 int
108 Statement::traverse_expression_list(Traverse* traverse,
109                                     Expression_list* expr_list)
110 {
111   if (expr_list == NULL)
112     return TRAVERSE_CONTINUE;
113   if ((traverse->traverse_mask()
114        & (Traverse::traverse_types | Traverse::traverse_expressions)) == 0)
115     return TRAVERSE_CONTINUE;
116   return expr_list->traverse(traverse);
117 }
118
119 // Traverse a type in a statement.  This is a helper function for
120 // child classes.
121
122 int
123 Statement::traverse_type(Traverse* traverse, Type* type)
124 {
125   if ((traverse->traverse_mask()
126        & (Traverse::traverse_types | Traverse::traverse_expressions)) == 0)
127     return TRAVERSE_CONTINUE;
128   return Type::traverse(type, traverse);
129 }
130
131 // Set type information for unnamed constants.  This is really done by
132 // the child class.
133
134 void
135 Statement::determine_types()
136 {
137   this->do_determine_types();
138 }
139
140 // If this is a thunk statement, return it.
141
142 Thunk_statement*
143 Statement::thunk_statement()
144 {
145   Thunk_statement* ret = this->convert<Thunk_statement, STATEMENT_GO>();
146   if (ret == NULL)
147     ret = this->convert<Thunk_statement, STATEMENT_DEFER>();
148   return ret;
149 }
150
151 // Get a tree for a Statement.  This is really done by the child
152 // class.
153
154 tree
155 Statement::get_tree(Translate_context* context)
156 {
157   if (this->classification_ == STATEMENT_ERROR)
158     return error_mark_node;
159
160   return this->do_get_tree(context);
161 }
162
163 // Build tree nodes and set locations.
164
165 tree
166 Statement::build_stmt_1(int tree_code_value, tree node)
167 {
168   tree ret = build1(static_cast<tree_code>(tree_code_value),
169                     void_type_node, node);
170   SET_EXPR_LOCATION(ret, this->location_);
171   return ret;
172 }
173
174 // Note that this statement is erroneous.  This is called by children
175 // when they discover an error.
176
177 void
178 Statement::set_is_error()
179 {
180   this->classification_ = STATEMENT_ERROR;
181 }
182
183 // For children to call to report an error conveniently.
184
185 void
186 Statement::report_error(const char* msg)
187 {
188   error_at(this->location_, "%s", msg);
189   this->set_is_error();
190 }
191
192 // An error statement, used to avoid crashing after we report an
193 // error.
194
195 class Error_statement : public Statement
196 {
197  public:
198   Error_statement(source_location location)
199     : Statement(STATEMENT_ERROR, location)
200   { }
201
202  protected:
203   int
204   do_traverse(Traverse*)
205   { return TRAVERSE_CONTINUE; }
206
207   tree
208   do_get_tree(Translate_context*)
209   { gcc_unreachable(); }
210 };
211
212 // Make an error statement.
213
214 Statement*
215 Statement::make_error_statement(source_location location)
216 {
217   return new Error_statement(location);
218 }
219
220 // Class Variable_declaration_statement.
221
222 Variable_declaration_statement::Variable_declaration_statement(
223     Named_object* var)
224   : Statement(STATEMENT_VARIABLE_DECLARATION, var->var_value()->location()),
225     var_(var)
226 {
227 }
228
229 // We don't actually traverse the variable here; it was traversed
230 // while traversing the Block.
231
232 int
233 Variable_declaration_statement::do_traverse(Traverse*)
234 {
235   return TRAVERSE_CONTINUE;
236 }
237
238 // Traverse the assignments in a variable declaration.  Note that this
239 // traversal is different from the usual traversal.
240
241 bool
242 Variable_declaration_statement::do_traverse_assignments(
243     Traverse_assignments* tassign)
244 {
245   tassign->initialize_variable(this->var_);
246   return true;
247 }
248
249 // Return the tree for a variable declaration.
250
251 tree
252 Variable_declaration_statement::do_get_tree(Translate_context* context)
253 {
254   tree val = this->var_->get_tree(context->gogo(), context->function());
255   if (val == error_mark_node || TREE_TYPE(val) == error_mark_node)
256     return error_mark_node;
257   Variable* variable = this->var_->var_value();
258
259   tree init = variable->get_init_tree(context->gogo(), context->function());
260   if (init == error_mark_node)
261     return error_mark_node;
262
263   // If this variable lives on the heap, we need to allocate it now.
264   if (!variable->is_in_heap())
265     {
266       DECL_INITIAL(val) = init;
267       return this->build_stmt_1(DECL_EXPR, val);
268     }
269   else
270     {
271       gcc_assert(TREE_CODE(val) == INDIRECT_REF);
272       tree decl = TREE_OPERAND(val, 0);
273       gcc_assert(TREE_CODE(decl) == VAR_DECL);
274       tree type = TREE_TYPE(decl);
275       gcc_assert(POINTER_TYPE_P(type));
276       tree size = TYPE_SIZE_UNIT(TREE_TYPE(type));
277       tree space = context->gogo()->allocate_memory(variable->type(), size,
278                                                     this->location());
279       space = fold_convert(TREE_TYPE(decl), space);
280       DECL_INITIAL(decl) = space;
281       return build2(COMPOUND_EXPR, void_type_node,
282                     this->build_stmt_1(DECL_EXPR, decl),
283                     build2(MODIFY_EXPR, void_type_node, val, init));
284     }
285 }
286
287 // Make a variable declaration.
288
289 Statement*
290 Statement::make_variable_declaration(Named_object* var)
291 {
292   return new Variable_declaration_statement(var);
293 }
294
295 // Class Temporary_statement.
296
297 // Return the type of the temporary variable.
298
299 Type*
300 Temporary_statement::type() const
301 {
302   return this->type_ != NULL ? this->type_ : this->init_->type();
303 }
304
305 // Return the tree for the temporary variable.
306
307 tree
308 Temporary_statement::get_decl() const
309 {
310   if (this->decl_ == NULL)
311     {
312       gcc_assert(saw_errors());
313       return error_mark_node;
314     }
315   return this->decl_;
316 }
317
318 // Traversal.
319
320 int
321 Temporary_statement::do_traverse(Traverse* traverse)
322 {
323   if (this->type_ != NULL
324       && this->traverse_type(traverse, this->type_) == TRAVERSE_EXIT)
325     return TRAVERSE_EXIT;
326   if (this->init_ == NULL)
327     return TRAVERSE_CONTINUE;
328   else
329     return this->traverse_expression(traverse, &this->init_);
330 }
331
332 // Traverse assignments.
333
334 bool
335 Temporary_statement::do_traverse_assignments(Traverse_assignments* tassign)
336 {
337   if (this->init_ == NULL)
338     return false;
339   tassign->value(&this->init_, true, true);
340   return true;
341 }
342
343 // Determine types.
344
345 void
346 Temporary_statement::do_determine_types()
347 {
348   if (this->type_ != NULL && this->type_->is_abstract())
349     this->type_ = this->type_->make_non_abstract_type();
350
351   if (this->init_ != NULL)
352     {
353       if (this->type_ == NULL)
354         this->init_->determine_type_no_context();
355       else
356         {
357           Type_context context(this->type_, false);
358           this->init_->determine_type(&context);
359         }
360     }
361
362   if (this->type_ == NULL)
363     {
364       this->type_ = this->init_->type();
365       gcc_assert(!this->type_->is_abstract());
366     }
367 }
368
369 // Check types.
370
371 void
372 Temporary_statement::do_check_types(Gogo*)
373 {
374   if (this->type_ != NULL && this->init_ != NULL)
375     {
376       std::string reason;
377       if (!Type::are_assignable(this->type_, this->init_->type(), &reason))
378         {
379           if (reason.empty())
380             error_at(this->location(), "incompatible types in assignment");
381           else
382             error_at(this->location(), "incompatible types in assignment (%s)",
383                      reason.c_str());
384           this->set_is_error();
385         }
386     }
387 }
388
389 // Return a tree.
390
391 tree
392 Temporary_statement::do_get_tree(Translate_context* context)
393 {
394   gcc_assert(this->decl_ == NULL_TREE);
395   tree type_tree = this->type()->get_tree(context->gogo());
396   tree init_tree = (this->init_ == NULL
397                     ? NULL_TREE
398                     : this->init_->get_tree(context));
399   if (type_tree == error_mark_node || init_tree == error_mark_node)
400     {
401       this->decl_ = error_mark_node;
402       return error_mark_node;
403     }
404   // We can only use create_tmp_var if the type is not addressable.
405   if (!TREE_ADDRESSABLE(type_tree))
406     {
407       this->decl_ = create_tmp_var(type_tree, "GOTMP");
408       DECL_SOURCE_LOCATION(this->decl_) = this->location();
409     }
410   else
411     {
412       gcc_assert(context->function() != NULL && context->block() != NULL);
413       tree decl = build_decl(this->location(), VAR_DECL,
414                              create_tmp_var_name("GOTMP"),
415                              type_tree);
416       DECL_ARTIFICIAL(decl) = 1;
417       DECL_IGNORED_P(decl) = 1;
418       TREE_USED(decl) = 1;
419       gcc_assert(current_function_decl != NULL_TREE);
420       DECL_CONTEXT(decl) = current_function_decl;
421
422       // We have to add this variable to the block so that it winds up
423       // in a BIND_EXPR.
424       tree block_tree = context->block_tree();
425       gcc_assert(block_tree != NULL_TREE);
426       DECL_CHAIN(decl) = BLOCK_VARS(block_tree);
427       BLOCK_VARS(block_tree) = decl;
428
429       this->decl_ = decl;
430     }
431   if (init_tree != NULL_TREE)
432     DECL_INITIAL(this->decl_) =
433       Expression::convert_for_assignment(context, this->type(),
434                                          this->init_->type(), init_tree,
435                                          this->location());
436   if (this->is_address_taken_)
437     TREE_ADDRESSABLE(this->decl_) = 1;
438   return this->build_stmt_1(DECL_EXPR, this->decl_);
439 }
440
441 // Make and initialize a temporary variable in BLOCK.
442
443 Temporary_statement*
444 Statement::make_temporary(Type* type, Expression* init,
445                           source_location location)
446 {
447   return new Temporary_statement(type, init, location);
448 }
449
450 // An assignment statement.
451
452 class Assignment_statement : public Statement
453 {
454  public:
455   Assignment_statement(Expression* lhs, Expression* rhs,
456                        source_location location)
457     : Statement(STATEMENT_ASSIGNMENT, location),
458       lhs_(lhs), rhs_(rhs)
459   { }
460
461  protected:
462   int
463   do_traverse(Traverse* traverse);
464
465   bool
466   do_traverse_assignments(Traverse_assignments*);
467
468   void
469   do_determine_types();
470
471   void
472   do_check_types(Gogo*);
473
474   tree
475   do_get_tree(Translate_context*);
476
477  private:
478   // Left hand side--the lvalue.
479   Expression* lhs_;
480   // Right hand side--the rvalue.
481   Expression* rhs_;
482 };
483
484 // Traversal.
485
486 int
487 Assignment_statement::do_traverse(Traverse* traverse)
488 {
489   if (this->traverse_expression(traverse, &this->lhs_) == TRAVERSE_EXIT)
490     return TRAVERSE_EXIT;
491   return this->traverse_expression(traverse, &this->rhs_);
492 }
493
494 bool
495 Assignment_statement::do_traverse_assignments(Traverse_assignments* tassign)
496 {
497   tassign->assignment(&this->lhs_, &this->rhs_);
498   return true;
499 }
500
501 // Set types for the assignment.
502
503 void
504 Assignment_statement::do_determine_types()
505 {
506   this->lhs_->determine_type_no_context();
507   Type_context context(this->lhs_->type(), false);
508   this->rhs_->determine_type(&context);
509 }
510
511 // Check types for an assignment.
512
513 void
514 Assignment_statement::do_check_types(Gogo*)
515 {
516   // The left hand side must be either addressable, a map index
517   // expression, or the blank identifier.
518   if (!this->lhs_->is_addressable()
519       && this->lhs_->map_index_expression() == NULL
520       && !this->lhs_->is_sink_expression())
521     {
522       if (!this->lhs_->type()->is_error())
523         this->report_error(_("invalid left hand side of assignment"));
524       return;
525     }
526
527   Type* lhs_type = this->lhs_->type();
528   Type* rhs_type = this->rhs_->type();
529   std::string reason;
530   if (!Type::are_assignable(lhs_type, rhs_type, &reason))
531     {
532       if (reason.empty())
533         error_at(this->location(), "incompatible types in assignment");
534       else
535         error_at(this->location(), "incompatible types in assignment (%s)",
536                  reason.c_str());
537       this->set_is_error();
538     }
539
540   if (lhs_type->is_error() || rhs_type->is_error())
541     this->set_is_error();
542 }
543
544 // Build a tree for an assignment statement.
545
546 tree
547 Assignment_statement::do_get_tree(Translate_context* context)
548 {
549   tree rhs_tree = this->rhs_->get_tree(context);
550
551   if (this->lhs_->is_sink_expression())
552     return rhs_tree;
553
554   tree lhs_tree = this->lhs_->get_tree(context);
555
556   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
557     return error_mark_node;
558
559   rhs_tree = Expression::convert_for_assignment(context, this->lhs_->type(),
560                                                 this->rhs_->type(), rhs_tree,
561                                                 this->location());
562   if (rhs_tree == error_mark_node)
563     return error_mark_node;
564
565   Bstatement* ret;
566   ret = context->backend()->assignment_statement(tree_to_expr(lhs_tree),
567                                                  tree_to_expr(rhs_tree),
568                                                  this->location());
569   return stat_to_tree(ret);
570 }
571
572 // Make an assignment statement.
573
574 Statement*
575 Statement::make_assignment(Expression* lhs, Expression* rhs,
576                            source_location location)
577 {
578   return new Assignment_statement(lhs, rhs, location);
579 }
580
581 // The Move_ordered_evals class is used to find any subexpressions of
582 // an expression that have an evaluation order dependency.  It creates
583 // temporary variables to hold them.
584
585 class Move_ordered_evals : public Traverse
586 {
587  public:
588   Move_ordered_evals(Block* block)
589     : Traverse(traverse_expressions),
590       block_(block)
591   { }
592
593  protected:
594   int
595   expression(Expression**);
596
597  private:
598   // The block where new temporary variables should be added.
599   Block* block_;
600 };
601
602 int
603 Move_ordered_evals::expression(Expression** pexpr)
604 {
605   // We have to look at subexpressions first.
606   if ((*pexpr)->traverse_subexpressions(this) == TRAVERSE_EXIT)
607     return TRAVERSE_EXIT;
608   if ((*pexpr)->must_eval_in_order())
609     {
610       source_location loc = (*pexpr)->location();
611       Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
612       this->block_->add_statement(temp);
613       *pexpr = Expression::make_temporary_reference(temp, loc);
614     }
615   return TRAVERSE_SKIP_COMPONENTS;
616 }
617
618 // An assignment operation statement.
619
620 class Assignment_operation_statement : public Statement
621 {
622  public:
623   Assignment_operation_statement(Operator op, Expression* lhs, Expression* rhs,
624                                  source_location location)
625     : Statement(STATEMENT_ASSIGNMENT_OPERATION, location),
626       op_(op), lhs_(lhs), rhs_(rhs)
627   { }
628
629  protected:
630   int
631   do_traverse(Traverse*);
632
633   bool
634   do_traverse_assignments(Traverse_assignments*)
635   { gcc_unreachable(); }
636
637   Statement*
638   do_lower(Gogo*, Named_object*, Block*);
639
640   tree
641   do_get_tree(Translate_context*)
642   { gcc_unreachable(); }
643
644  private:
645   // The operator (OPERATOR_PLUSEQ, etc.).
646   Operator op_;
647   // Left hand side.
648   Expression* lhs_;
649   // Right hand side.
650   Expression* rhs_;
651 };
652
653 // Traversal.
654
655 int
656 Assignment_operation_statement::do_traverse(Traverse* traverse)
657 {
658   if (this->traverse_expression(traverse, &this->lhs_) == TRAVERSE_EXIT)
659     return TRAVERSE_EXIT;
660   return this->traverse_expression(traverse, &this->rhs_);
661 }
662
663 // Lower an assignment operation statement to a regular assignment
664 // statement.
665
666 Statement*
667 Assignment_operation_statement::do_lower(Gogo*, Named_object*,
668                                          Block* enclosing)
669 {
670   source_location loc = this->location();
671
672   // We have to evaluate the left hand side expression only once.  We
673   // do this by moving out any expression with side effects.
674   Block* b = new Block(enclosing, loc);
675   Move_ordered_evals moe(b);
676   this->lhs_->traverse_subexpressions(&moe);
677
678   Expression* lval = this->lhs_->copy();
679
680   Operator op;
681   switch (this->op_)
682     {
683     case OPERATOR_PLUSEQ:
684       op = OPERATOR_PLUS;
685       break;
686     case OPERATOR_MINUSEQ:
687       op = OPERATOR_MINUS;
688       break;
689     case OPERATOR_OREQ:
690       op = OPERATOR_OR;
691       break;
692     case OPERATOR_XOREQ:
693       op = OPERATOR_XOR;
694       break;
695     case OPERATOR_MULTEQ:
696       op = OPERATOR_MULT;
697       break;
698     case OPERATOR_DIVEQ:
699       op = OPERATOR_DIV;
700       break;
701     case OPERATOR_MODEQ:
702       op = OPERATOR_MOD;
703       break;
704     case OPERATOR_LSHIFTEQ:
705       op = OPERATOR_LSHIFT;
706       break;
707     case OPERATOR_RSHIFTEQ:
708       op = OPERATOR_RSHIFT;
709       break;
710     case OPERATOR_ANDEQ:
711       op = OPERATOR_AND;
712       break;
713     case OPERATOR_BITCLEAREQ:
714       op = OPERATOR_BITCLEAR;
715       break;
716     default:
717       gcc_unreachable();
718     }
719
720   Expression* binop = Expression::make_binary(op, lval, this->rhs_, loc);
721   Statement* s = Statement::make_assignment(this->lhs_, binop, loc);
722   if (b->statements()->empty())
723     {
724       delete b;
725       return s;
726     }
727   else
728     {
729       b->add_statement(s);
730       return Statement::make_block_statement(b, loc);
731     }
732 }
733
734 // Make an assignment operation statement.
735
736 Statement*
737 Statement::make_assignment_operation(Operator op, Expression* lhs,
738                                      Expression* rhs, source_location location)
739 {
740   return new Assignment_operation_statement(op, lhs, rhs, location);
741 }
742
743 // A tuple assignment statement.  This differs from an assignment
744 // statement in that the right-hand-side expressions are evaluated in
745 // parallel.
746
747 class Tuple_assignment_statement : public Statement
748 {
749  public:
750   Tuple_assignment_statement(Expression_list* lhs, Expression_list* rhs,
751                              source_location location)
752     : Statement(STATEMENT_TUPLE_ASSIGNMENT, location),
753       lhs_(lhs), rhs_(rhs)
754   { }
755
756  protected:
757   int
758   do_traverse(Traverse* traverse);
759
760   bool
761   do_traverse_assignments(Traverse_assignments*)
762   { gcc_unreachable(); }
763
764   Statement*
765   do_lower(Gogo*, Named_object*, Block*);
766
767   tree
768   do_get_tree(Translate_context*)
769   { gcc_unreachable(); }
770
771  private:
772   // Left hand side--a list of lvalues.
773   Expression_list* lhs_;
774   // Right hand side--a list of rvalues.
775   Expression_list* rhs_;
776 };
777
778 // Traversal.
779
780 int
781 Tuple_assignment_statement::do_traverse(Traverse* traverse)
782 {
783   if (this->traverse_expression_list(traverse, this->lhs_) == TRAVERSE_EXIT)
784     return TRAVERSE_EXIT;
785   return this->traverse_expression_list(traverse, this->rhs_);
786 }
787
788 // Lower a tuple assignment.  We use temporary variables to split it
789 // up into a set of single assignments.
790
791 Statement*
792 Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
793 {
794   source_location loc = this->location();
795
796   Block* b = new Block(enclosing, loc);
797   
798   // First move out any subexpressions on the left hand side.  The
799   // right hand side will be evaluated in the required order anyhow.
800   Move_ordered_evals moe(b);
801   for (Expression_list::const_iterator plhs = this->lhs_->begin();
802        plhs != this->lhs_->end();
803        ++plhs)
804     (*plhs)->traverse_subexpressions(&moe);
805
806   std::vector<Temporary_statement*> temps;
807   temps.reserve(this->lhs_->size());
808
809   Expression_list::const_iterator prhs = this->rhs_->begin();
810   for (Expression_list::const_iterator plhs = this->lhs_->begin();
811        plhs != this->lhs_->end();
812        ++plhs, ++prhs)
813     {
814       gcc_assert(prhs != this->rhs_->end());
815
816       if ((*plhs)->is_error_expression()
817           || (*plhs)->type()->is_error()
818           || (*prhs)->is_error_expression()
819           || (*prhs)->type()->is_error())
820         continue;
821
822       if ((*plhs)->is_sink_expression())
823         {
824           b->add_statement(Statement::make_statement(*prhs));
825           continue;
826         }
827
828       Temporary_statement* temp = Statement::make_temporary((*plhs)->type(),
829                                                             *prhs, loc);
830       b->add_statement(temp);
831       temps.push_back(temp);
832
833     }
834   gcc_assert(prhs == this->rhs_->end());
835
836   prhs = this->rhs_->begin();
837   std::vector<Temporary_statement*>::const_iterator ptemp = temps.begin();
838   for (Expression_list::const_iterator plhs = this->lhs_->begin();
839        plhs != this->lhs_->end();
840        ++plhs, ++prhs)
841     {
842       if ((*plhs)->is_error_expression()
843           || (*plhs)->type()->is_error()
844           || (*prhs)->is_error_expression()
845           || (*prhs)->type()->is_error())
846         continue;
847
848       if ((*plhs)->is_sink_expression())
849         continue;
850
851       Expression* ref = Expression::make_temporary_reference(*ptemp, loc);
852       Statement* s = Statement::make_assignment(*plhs, ref, loc);
853       b->add_statement(s);
854       ++ptemp;
855     }
856   gcc_assert(ptemp == temps.end());
857
858   return Statement::make_block_statement(b, loc);
859 }
860
861 // Make a tuple assignment statement.
862
863 Statement*
864 Statement::make_tuple_assignment(Expression_list* lhs, Expression_list* rhs,
865                                  source_location location)
866 {
867   return new Tuple_assignment_statement(lhs, rhs, location);
868 }
869
870 // A tuple assignment from a map index expression.
871 //   v, ok = m[k]
872
873 class Tuple_map_assignment_statement : public Statement
874 {
875 public:
876   Tuple_map_assignment_statement(Expression* val, Expression* present,
877                                  Expression* map_index,
878                                  source_location location)
879     : Statement(STATEMENT_TUPLE_MAP_ASSIGNMENT, location),
880       val_(val), present_(present), map_index_(map_index)
881   { }
882
883  protected:
884   int
885   do_traverse(Traverse* traverse);
886
887   bool
888   do_traverse_assignments(Traverse_assignments*)
889   { gcc_unreachable(); }
890
891   Statement*
892   do_lower(Gogo*, Named_object*, Block*);
893
894   tree
895   do_get_tree(Translate_context*)
896   { gcc_unreachable(); }
897
898  private:
899   // Lvalue which receives the value from the map.
900   Expression* val_;
901   // Lvalue which receives whether the key value was present.
902   Expression* present_;
903   // The map index expression.
904   Expression* map_index_;
905 };
906
907 // Traversal.
908
909 int
910 Tuple_map_assignment_statement::do_traverse(Traverse* traverse)
911 {
912   if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT
913       || this->traverse_expression(traverse, &this->present_) == TRAVERSE_EXIT)
914     return TRAVERSE_EXIT;
915   return this->traverse_expression(traverse, &this->map_index_);
916 }
917
918 // Lower a tuple map assignment.
919
920 Statement*
921 Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*,
922                                          Block* enclosing)
923 {
924   source_location loc = this->location();
925
926   Map_index_expression* map_index = this->map_index_->map_index_expression();
927   if (map_index == NULL)
928     {
929       this->report_error(_("expected map index on right hand side"));
930       return Statement::make_error_statement(loc);
931     }
932   Map_type* map_type = map_index->get_map_type();
933   if (map_type == NULL)
934     return Statement::make_error_statement(loc);
935
936   Block* b = new Block(enclosing, loc);
937
938   // Move out any subexpressions to make sure that functions are
939   // called in the required order.
940   Move_ordered_evals moe(b);
941   this->val_->traverse_subexpressions(&moe);
942   this->present_->traverse_subexpressions(&moe);
943
944   // Copy the key value into a temporary so that we can take its
945   // address without pushing the value onto the heap.
946
947   // var key_temp KEY_TYPE = MAP_INDEX
948   Temporary_statement* key_temp =
949     Statement::make_temporary(map_type->key_type(), map_index->index(), loc);
950   b->add_statement(key_temp);
951
952   // var val_temp VAL_TYPE
953   Temporary_statement* val_temp =
954     Statement::make_temporary(map_type->val_type(), NULL, loc);
955   b->add_statement(val_temp);
956
957   // var present_temp bool
958   Temporary_statement* present_temp =
959     Statement::make_temporary(Type::lookup_bool_type(), NULL, loc);
960   b->add_statement(present_temp);
961
962   // present_temp = mapaccess2(MAP, &key_temp, &val_temp)
963   Expression* ref = Expression::make_temporary_reference(key_temp, loc);
964   Expression* a1 = Expression::make_unary(OPERATOR_AND, ref, loc);
965   ref = Expression::make_temporary_reference(val_temp, loc);
966   Expression* a2 = Expression::make_unary(OPERATOR_AND, ref, loc);
967   Expression* call = Runtime::make_call(Runtime::MAPACCESS2, loc, 3,
968                                         map_index->map(), a1, a2);
969
970   ref = Expression::make_temporary_reference(present_temp, loc);
971   Statement* s = Statement::make_assignment(ref, call, loc);
972   b->add_statement(s);
973
974   // val = val_temp
975   ref = Expression::make_temporary_reference(val_temp, loc);
976   s = Statement::make_assignment(this->val_, ref, loc);
977   b->add_statement(s);
978
979   // present = present_temp
980   ref = Expression::make_temporary_reference(present_temp, loc);
981   s = Statement::make_assignment(this->present_, ref, loc);
982   b->add_statement(s);
983
984   return Statement::make_block_statement(b, loc);
985 }
986
987 // Make a map assignment statement which returns a pair of values.
988
989 Statement*
990 Statement::make_tuple_map_assignment(Expression* val, Expression* present,
991                                      Expression* map_index,
992                                      source_location location)
993 {
994   return new Tuple_map_assignment_statement(val, present, map_index, location);
995 }
996
997 // Assign a pair of entries to a map.
998 //   m[k] = v, p
999
1000 class Map_assignment_statement : public Statement
1001 {
1002  public:
1003   Map_assignment_statement(Expression* map_index,
1004                            Expression* val, Expression* should_set,
1005                            source_location location)
1006     : Statement(STATEMENT_MAP_ASSIGNMENT, location),
1007       map_index_(map_index), val_(val), should_set_(should_set)
1008   { }
1009
1010  protected:
1011   int
1012   do_traverse(Traverse* traverse);
1013
1014   bool
1015   do_traverse_assignments(Traverse_assignments*)
1016   { gcc_unreachable(); }
1017
1018   Statement*
1019   do_lower(Gogo*, Named_object*, Block*);
1020
1021   tree
1022   do_get_tree(Translate_context*)
1023   { gcc_unreachable(); }
1024
1025  private:
1026   // A reference to the map index which should be set or deleted.
1027   Expression* map_index_;
1028   // The value to add to the map.
1029   Expression* val_;
1030   // Whether or not to add the value.
1031   Expression* should_set_;
1032 };
1033
1034 // Traverse a map assignment.
1035
1036 int
1037 Map_assignment_statement::do_traverse(Traverse* traverse)
1038 {
1039   if (this->traverse_expression(traverse, &this->map_index_) == TRAVERSE_EXIT
1040       || this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT)
1041     return TRAVERSE_EXIT;
1042   return this->traverse_expression(traverse, &this->should_set_);
1043 }
1044
1045 // Lower a map assignment to a function call.
1046
1047 Statement*
1048 Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
1049 {
1050   source_location loc = this->location();
1051
1052   Map_index_expression* map_index = this->map_index_->map_index_expression();
1053   if (map_index == NULL)
1054     {
1055       this->report_error(_("expected map index on left hand side"));
1056       return Statement::make_error_statement(loc);
1057     }
1058   Map_type* map_type = map_index->get_map_type();
1059   if (map_type == NULL)
1060     return Statement::make_error_statement(loc);
1061
1062   Block* b = new Block(enclosing, loc);
1063
1064   // Evaluate the map first to get order of evaluation right.
1065   // map_temp := m // we are evaluating m[k] = v, p
1066   Temporary_statement* map_temp = Statement::make_temporary(map_type,
1067                                                             map_index->map(),
1068                                                             loc);
1069   b->add_statement(map_temp);
1070
1071   // var key_temp MAP_KEY_TYPE = k
1072   Temporary_statement* key_temp =
1073     Statement::make_temporary(map_type->key_type(), map_index->index(), loc);
1074   b->add_statement(key_temp);
1075
1076   // var val_temp MAP_VAL_TYPE = v
1077   Temporary_statement* val_temp =
1078     Statement::make_temporary(map_type->val_type(), this->val_, loc);
1079   b->add_statement(val_temp);
1080
1081   // var insert_temp bool = p
1082   Temporary_statement* insert_temp =
1083     Statement::make_temporary(Type::lookup_bool_type(), this->should_set_,
1084                               loc);
1085   b->add_statement(insert_temp);
1086
1087   // mapassign2(map_temp, &key_temp, &val_temp, p)
1088   Expression* p1 = Expression::make_temporary_reference(map_temp, loc);
1089   Expression* ref = Expression::make_temporary_reference(key_temp, loc);
1090   Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc);
1091   ref = Expression::make_temporary_reference(val_temp, loc);
1092   Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc);
1093   Expression* p4 = Expression::make_temporary_reference(insert_temp, loc);
1094   Expression* call = Runtime::make_call(Runtime::MAPASSIGN2, loc, 4,
1095                                         p1, p2, p3, p4);
1096   Statement* s = Statement::make_statement(call);
1097   b->add_statement(s);
1098
1099   return Statement::make_block_statement(b, loc);
1100 }
1101
1102 // Make a statement which assigns a pair of entries to a map.
1103
1104 Statement*
1105 Statement::make_map_assignment(Expression* map_index,
1106                                Expression* val, Expression* should_set,
1107                                source_location location)
1108 {
1109   return new Map_assignment_statement(map_index, val, should_set, location);
1110 }
1111
1112 // A tuple assignment from a receive statement.
1113
1114 class Tuple_receive_assignment_statement : public Statement
1115 {
1116  public:
1117   Tuple_receive_assignment_statement(Expression* val, Expression* closed,
1118                                      Expression* channel, bool for_select,
1119                                      source_location location)
1120     : Statement(STATEMENT_TUPLE_RECEIVE_ASSIGNMENT, location),
1121       val_(val), closed_(closed), channel_(channel), for_select_(for_select)
1122   { }
1123
1124  protected:
1125   int
1126   do_traverse(Traverse* traverse);
1127
1128   bool
1129   do_traverse_assignments(Traverse_assignments*)
1130   { gcc_unreachable(); }
1131
1132   Statement*
1133   do_lower(Gogo*, Named_object*, Block*);
1134
1135   tree
1136   do_get_tree(Translate_context*)
1137   { gcc_unreachable(); }
1138
1139  private:
1140   // Lvalue which receives the value from the channel.
1141   Expression* val_;
1142   // Lvalue which receives whether the channel is closed.
1143   Expression* closed_;
1144   // The channel on which we receive the value.
1145   Expression* channel_;
1146   // Whether this is for a select statement.
1147   bool for_select_;
1148 };
1149
1150 // Traversal.
1151
1152 int
1153 Tuple_receive_assignment_statement::do_traverse(Traverse* traverse)
1154 {
1155   if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT
1156       || this->traverse_expression(traverse, &this->closed_) == TRAVERSE_EXIT)
1157     return TRAVERSE_EXIT;
1158   return this->traverse_expression(traverse, &this->channel_);
1159 }
1160
1161 // Lower to a function call.
1162
1163 Statement*
1164 Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
1165                                              Block* enclosing)
1166 {
1167   source_location loc = this->location();
1168
1169   Channel_type* channel_type = this->channel_->type()->channel_type();
1170   if (channel_type == NULL)
1171     {
1172       this->report_error(_("expected channel"));
1173       return Statement::make_error_statement(loc);
1174     }
1175   if (!channel_type->may_receive())
1176     {
1177       this->report_error(_("invalid receive on send-only channel"));
1178       return Statement::make_error_statement(loc);
1179     }
1180
1181   Block* b = new Block(enclosing, loc);
1182
1183   // Make sure that any subexpressions on the left hand side are
1184   // evaluated in the right order.
1185   Move_ordered_evals moe(b);
1186   this->val_->traverse_subexpressions(&moe);
1187   this->closed_->traverse_subexpressions(&moe);
1188
1189   // var val_temp ELEMENT_TYPE
1190   Temporary_statement* val_temp =
1191     Statement::make_temporary(channel_type->element_type(), NULL, loc);
1192   b->add_statement(val_temp);
1193
1194   // var closed_temp bool
1195   Temporary_statement* closed_temp =
1196     Statement::make_temporary(Type::lookup_bool_type(), NULL, loc);
1197   b->add_statement(closed_temp);
1198
1199   // closed_temp = chanrecv[23](channel, &val_temp)
1200   Expression* ref = Expression::make_temporary_reference(val_temp, loc);
1201   Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc);
1202   Expression* call = Runtime::make_call((this->for_select_
1203                                          ? Runtime::CHANRECV3
1204                                          : Runtime::CHANRECV2),
1205                                         loc, 2, this->channel_, p2);
1206   ref = Expression::make_temporary_reference(closed_temp, loc);
1207   Statement* s = Statement::make_assignment(ref, call, loc);
1208   b->add_statement(s);
1209
1210   // val = val_temp
1211   ref = Expression::make_temporary_reference(val_temp, loc);
1212   s = Statement::make_assignment(this->val_, ref, loc);
1213   b->add_statement(s);
1214
1215   // closed = closed_temp
1216   ref = Expression::make_temporary_reference(closed_temp, loc);
1217   s = Statement::make_assignment(this->closed_, ref, loc);
1218   b->add_statement(s);
1219
1220   return Statement::make_block_statement(b, loc);
1221 }
1222
1223 // Make a nonblocking receive statement.
1224
1225 Statement*
1226 Statement::make_tuple_receive_assignment(Expression* val, Expression* closed,
1227                                          Expression* channel,
1228                                          bool for_select,
1229                                          source_location location)
1230 {
1231   return new Tuple_receive_assignment_statement(val, closed, channel,
1232                                                 for_select, location);
1233 }
1234
1235 // An assignment to a pair of values from a type guard.  This is a
1236 // conditional type guard.  v, ok = i.(type).
1237
1238 class Tuple_type_guard_assignment_statement : public Statement
1239 {
1240  public:
1241   Tuple_type_guard_assignment_statement(Expression* val, Expression* ok,
1242                                         Expression* expr, Type* type,
1243                                         source_location location)
1244     : Statement(STATEMENT_TUPLE_TYPE_GUARD_ASSIGNMENT, location),
1245       val_(val), ok_(ok), expr_(expr), type_(type)
1246   { }
1247
1248  protected:
1249   int
1250   do_traverse(Traverse*);
1251
1252   bool
1253   do_traverse_assignments(Traverse_assignments*)
1254   { gcc_unreachable(); }
1255
1256   Statement*
1257   do_lower(Gogo*, Named_object*, Block*);
1258
1259   tree
1260   do_get_tree(Translate_context*)
1261   { gcc_unreachable(); }
1262
1263  private:
1264   Call_expression*
1265   lower_to_type(Runtime::Function);
1266
1267   void
1268   lower_to_object_type(Block*, Runtime::Function);
1269
1270   // The variable which recieves the converted value.
1271   Expression* val_;
1272   // The variable which receives the indication of success.
1273   Expression* ok_;
1274   // The expression being converted.
1275   Expression* expr_;
1276   // The type to which the expression is being converted.
1277   Type* type_;
1278 };
1279
1280 // Traverse a type guard tuple assignment.
1281
1282 int
1283 Tuple_type_guard_assignment_statement::do_traverse(Traverse* traverse)
1284 {
1285   if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT
1286       || this->traverse_expression(traverse, &this->ok_) == TRAVERSE_EXIT
1287       || this->traverse_type(traverse, this->type_) == TRAVERSE_EXIT)
1288     return TRAVERSE_EXIT;
1289   return this->traverse_expression(traverse, &this->expr_);
1290 }
1291
1292 // Lower to a function call.
1293
1294 Statement*
1295 Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
1296                                                 Block* enclosing)
1297 {
1298   source_location loc = this->location();
1299
1300   Type* expr_type = this->expr_->type();
1301   if (expr_type->interface_type() == NULL)
1302     {
1303       if (!expr_type->is_error() && !this->type_->is_error())
1304         this->report_error(_("type assertion only valid for interface types"));
1305       return Statement::make_error_statement(loc);
1306     }
1307
1308   Block* b = new Block(enclosing, loc);
1309
1310   // Make sure that any subexpressions on the left hand side are
1311   // evaluated in the right order.
1312   Move_ordered_evals moe(b);
1313   this->val_->traverse_subexpressions(&moe);
1314   this->ok_->traverse_subexpressions(&moe);
1315
1316   bool expr_is_empty = expr_type->interface_type()->is_empty();
1317   Call_expression* call;
1318   if (this->type_->interface_type() != NULL)
1319     {
1320       if (this->type_->interface_type()->is_empty())
1321         call = Runtime::make_call((expr_is_empty
1322                                    ? Runtime::IFACEE2E2
1323                                    : Runtime::IFACEI2E2),
1324                                   loc, 1, this->expr_);
1325       else
1326         call = this->lower_to_type(expr_is_empty
1327                                    ? Runtime::IFACEE2I2
1328                                    : Runtime::IFACEI2I2);
1329     }
1330   else if (this->type_->points_to() != NULL)
1331     call = this->lower_to_type(expr_is_empty
1332                                ? Runtime::IFACEE2T2P
1333                                : Runtime::IFACEI2T2P);
1334   else
1335     {
1336       this->lower_to_object_type(b,
1337                                  (expr_is_empty
1338                                   ? Runtime::IFACEE2T2
1339                                   : Runtime::IFACEI2T2));
1340       call = NULL;
1341     }
1342
1343   if (call != NULL)
1344     {
1345       Expression* res = Expression::make_call_result(call, 0);
1346       res = Expression::make_unsafe_cast(this->type_, res, loc);
1347       Statement* s = Statement::make_assignment(this->val_, res, loc);
1348       b->add_statement(s);
1349
1350       res = Expression::make_call_result(call, 1);
1351       s = Statement::make_assignment(this->ok_, res, loc);
1352       b->add_statement(s);
1353     }
1354
1355   return Statement::make_block_statement(b, loc);
1356 }
1357
1358 // Lower a conversion to a non-empty interface type or a pointer type.
1359
1360 Call_expression*
1361 Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code)
1362 {
1363   source_location loc = this->location();
1364   return Runtime::make_call(code, loc, 2,
1365                             Expression::make_type_descriptor(this->type_, loc),
1366                             this->expr_);
1367 }
1368
1369 // Lower a conversion to a non-interface non-pointer type.
1370
1371 void
1372 Tuple_type_guard_assignment_statement::lower_to_object_type(
1373     Block* b,
1374     Runtime::Function code)
1375 {
1376   source_location loc = this->location();
1377
1378   // var val_temp TYPE
1379   Temporary_statement* val_temp = Statement::make_temporary(this->type_,
1380                                                             NULL, loc);
1381   b->add_statement(val_temp);
1382
1383   // ok = CODE(type_descriptor, expr, &val_temp)
1384   Expression* p1 = Expression::make_type_descriptor(this->type_, loc);
1385   Expression* ref = Expression::make_temporary_reference(val_temp, loc);
1386   Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc);
1387   Expression* call = Runtime::make_call(code, loc, 3, p1, this->expr_, p3);
1388   Statement* s = Statement::make_assignment(this->ok_, call, loc);
1389   b->add_statement(s);
1390
1391   // val = val_temp
1392   ref = Expression::make_temporary_reference(val_temp, loc);
1393   s = Statement::make_assignment(this->val_, ref, loc);
1394   b->add_statement(s);
1395 }
1396
1397 // Make an assignment from a type guard to a pair of variables.
1398
1399 Statement*
1400 Statement::make_tuple_type_guard_assignment(Expression* val, Expression* ok,
1401                                             Expression* expr, Type* type,
1402                                             source_location location)
1403 {
1404   return new Tuple_type_guard_assignment_statement(val, ok, expr, type,
1405                                                    location);
1406 }
1407
1408 // An expression statement.
1409
1410 class Expression_statement : public Statement
1411 {
1412  public:
1413   Expression_statement(Expression* expr)
1414     : Statement(STATEMENT_EXPRESSION, expr->location()),
1415       expr_(expr)
1416   { }
1417
1418  protected:
1419   int
1420   do_traverse(Traverse* traverse)
1421   { return this->traverse_expression(traverse, &this->expr_); }
1422
1423   void
1424   do_determine_types()
1425   { this->expr_->determine_type_no_context(); }
1426
1427   bool
1428   do_may_fall_through() const;
1429
1430   tree
1431   do_get_tree(Translate_context* context);
1432
1433  private:
1434   Expression* expr_;
1435 };
1436
1437 // An expression statement may fall through unless it is a call to a
1438 // function which does not return.
1439
1440 bool
1441 Expression_statement::do_may_fall_through() const
1442 {
1443   const Call_expression* call = this->expr_->call_expression();
1444   if (call != NULL)
1445     {
1446       const Expression* fn = call->fn();
1447       const Func_expression* fe = fn->func_expression();
1448       if (fe != NULL)
1449         {
1450           const Named_object* no = fe->named_object();
1451
1452           Function_type* fntype;
1453           if (no->is_function())
1454             fntype = no->func_value()->type();
1455           else if (no->is_function_declaration())
1456             fntype = no->func_declaration_value()->type();
1457           else
1458             fntype = NULL;
1459
1460           // The builtin function panic does not return.
1461           if (fntype != NULL && fntype->is_builtin() && no->name() == "panic")
1462             return false;
1463         }
1464     }
1465   return true;
1466 }
1467
1468 // Convert to backend representation.
1469
1470 tree
1471 Expression_statement::do_get_tree(Translate_context* context)
1472 {
1473   tree expr_tree = this->expr_->get_tree(context);
1474   Bexpression* bexpr = tree_to_expr(expr_tree);
1475   Bstatement* ret = context->backend()->expression_statement(bexpr);
1476   return stat_to_tree(ret);
1477 }
1478
1479 // Make an expression statement from an Expression.
1480
1481 Statement*
1482 Statement::make_statement(Expression* expr)
1483 {
1484   return new Expression_statement(expr);
1485 }
1486
1487 // A block statement--a list of statements which may include variable
1488 // definitions.
1489
1490 class Block_statement : public Statement
1491 {
1492  public:
1493   Block_statement(Block* block, source_location location)
1494     : Statement(STATEMENT_BLOCK, location),
1495       block_(block)
1496   { }
1497
1498  protected:
1499   int
1500   do_traverse(Traverse* traverse)
1501   { return this->block_->traverse(traverse); }
1502
1503   void
1504   do_determine_types()
1505   { this->block_->determine_types(); }
1506
1507   bool
1508   do_may_fall_through() const
1509   { return this->block_->may_fall_through(); }
1510
1511   tree
1512   do_get_tree(Translate_context* context)
1513   { return this->block_->get_tree(context); }
1514
1515  private:
1516   Block* block_;
1517 };
1518
1519 // Make a block statement.
1520
1521 Statement*
1522 Statement::make_block_statement(Block* block, source_location location)
1523 {
1524   return new Block_statement(block, location);
1525 }
1526
1527 // An increment or decrement statement.
1528
1529 class Inc_dec_statement : public Statement
1530 {
1531  public:
1532   Inc_dec_statement(bool is_inc, Expression* expr)
1533     : Statement(STATEMENT_INCDEC, expr->location()),
1534       expr_(expr), is_inc_(is_inc)
1535   { }
1536
1537  protected:
1538   int
1539   do_traverse(Traverse* traverse)
1540   { return this->traverse_expression(traverse, &this->expr_); }
1541
1542   bool
1543   do_traverse_assignments(Traverse_assignments*)
1544   { gcc_unreachable(); }
1545
1546   Statement*
1547   do_lower(Gogo*, Named_object*, Block*);
1548
1549   tree
1550   do_get_tree(Translate_context*)
1551   { gcc_unreachable(); }
1552
1553  private:
1554   // The l-value to increment or decrement.
1555   Expression* expr_;
1556   // Whether to increment or decrement.
1557   bool is_inc_;
1558 };
1559
1560 // Lower to += or -=.
1561
1562 Statement*
1563 Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*)
1564 {
1565   source_location loc = this->location();
1566
1567   mpz_t oval;
1568   mpz_init_set_ui(oval, 1UL);
1569   Expression* oexpr = Expression::make_integer(&oval, NULL, loc);
1570   mpz_clear(oval);
1571
1572   Operator op = this->is_inc_ ? OPERATOR_PLUSEQ : OPERATOR_MINUSEQ;
1573   return Statement::make_assignment_operation(op, this->expr_, oexpr, loc);
1574 }
1575
1576 // Make an increment statement.
1577
1578 Statement*
1579 Statement::make_inc_statement(Expression* expr)
1580 {
1581   return new Inc_dec_statement(true, expr);
1582 }
1583
1584 // Make a decrement statement.
1585
1586 Statement*
1587 Statement::make_dec_statement(Expression* expr)
1588 {
1589   return new Inc_dec_statement(false, expr);
1590 }
1591
1592 // Class Thunk_statement.  This is the base class for go and defer
1593 // statements.
1594
1595 const char* const Thunk_statement::thunk_field_fn = "fn";
1596
1597 const char* const Thunk_statement::thunk_field_receiver = "receiver";
1598
1599 // Constructor.
1600
1601 Thunk_statement::Thunk_statement(Statement_classification classification,
1602                                  Call_expression* call,
1603                                  source_location location)
1604     : Statement(classification, location),
1605       call_(call), struct_type_(NULL)
1606 {
1607 }
1608
1609 // Return whether this is a simple statement which does not require a
1610 // thunk.
1611
1612 bool
1613 Thunk_statement::is_simple(Function_type* fntype) const
1614 {
1615   // We need a thunk to call a method, or to pass a variable number of
1616   // arguments.
1617   if (fntype->is_method() || fntype->is_varargs())
1618     return false;
1619
1620   // A defer statement requires a thunk to set up for whether the
1621   // function can call recover.
1622   if (this->classification() == STATEMENT_DEFER)
1623     return false;
1624
1625   // We can only permit a single parameter of pointer type.
1626   const Typed_identifier_list* parameters = fntype->parameters();
1627   if (parameters != NULL
1628       && (parameters->size() > 1
1629           || (parameters->size() == 1
1630               && parameters->begin()->type()->points_to() == NULL)))
1631     return false;
1632
1633   // If the function returns multiple values, or returns a type other
1634   // than integer, floating point, or pointer, then it may get a
1635   // hidden first parameter, in which case we need the more
1636   // complicated approach.  This is true even though we are going to
1637   // ignore the return value.
1638   const Typed_identifier_list* results = fntype->results();
1639   if (results != NULL
1640       && (results->size() > 1
1641           || (results->size() == 1
1642               && !results->begin()->type()->is_basic_type()
1643               && results->begin()->type()->points_to() == NULL)))
1644     return false;
1645
1646   // If this calls something which is not a simple function, then we
1647   // need a thunk.
1648   Expression* fn = this->call_->call_expression()->fn();
1649   if (fn->bound_method_expression() != NULL
1650       || fn->interface_field_reference_expression() != NULL)
1651     return false;
1652
1653   return true;
1654 }
1655
1656 // Traverse a thunk statement.
1657
1658 int
1659 Thunk_statement::do_traverse(Traverse* traverse)
1660 {
1661   return this->traverse_expression(traverse, &this->call_);
1662 }
1663
1664 // We implement traverse_assignment for a thunk statement because it
1665 // effectively copies the function call.
1666
1667 bool
1668 Thunk_statement::do_traverse_assignments(Traverse_assignments* tassign)
1669 {
1670   Expression* fn = this->call_->call_expression()->fn();
1671   Expression* fn2 = fn;
1672   tassign->value(&fn2, true, false);
1673   return true;
1674 }
1675
1676 // Determine types in a thunk statement.
1677
1678 void
1679 Thunk_statement::do_determine_types()
1680 {
1681   this->call_->determine_type_no_context();
1682
1683   // Now that we know the types of the call, build the struct used to
1684   // pass parameters.
1685   Call_expression* ce = this->call_->call_expression();
1686   if (ce == NULL)
1687     return;
1688   Function_type* fntype = ce->get_function_type();
1689   if (fntype != NULL && !this->is_simple(fntype))
1690     this->struct_type_ = this->build_struct(fntype);
1691 }
1692
1693 // Check types in a thunk statement.
1694
1695 void
1696 Thunk_statement::do_check_types(Gogo*)
1697 {
1698   Call_expression* ce = this->call_->call_expression();
1699   if (ce == NULL)
1700     {
1701       if (!this->call_->is_error_expression())
1702         this->report_error("expected call expression");
1703       return;
1704     }
1705   Function_type* fntype = ce->get_function_type();
1706   if (fntype != NULL && fntype->is_method())
1707     {
1708       Expression* fn = ce->fn();
1709       if (fn->bound_method_expression() == NULL
1710           && fn->interface_field_reference_expression() == NULL)
1711         this->report_error(_("no object for method call"));
1712     }
1713 }
1714
1715 // The Traverse class used to find and simplify thunk statements.
1716
1717 class Simplify_thunk_traverse : public Traverse
1718 {
1719  public:
1720   Simplify_thunk_traverse(Gogo* gogo)
1721     : Traverse(traverse_blocks),
1722       gogo_(gogo)
1723   { }
1724
1725   int
1726   block(Block*);
1727
1728  private:
1729   Gogo* gogo_;
1730 };
1731
1732 int
1733 Simplify_thunk_traverse::block(Block* b)
1734 {
1735   // The parser ensures that thunk statements always appear at the end
1736   // of a block.
1737   if (b->statements()->size() < 1)
1738     return TRAVERSE_CONTINUE;
1739   Thunk_statement* stat = b->statements()->back()->thunk_statement();
1740   if (stat == NULL)
1741     return TRAVERSE_CONTINUE;
1742   if (stat->simplify_statement(this->gogo_, b))
1743     return TRAVERSE_SKIP_COMPONENTS;
1744   return TRAVERSE_CONTINUE;
1745 }
1746
1747 // Simplify all thunk statements.
1748
1749 void
1750 Gogo::simplify_thunk_statements()
1751 {
1752   Simplify_thunk_traverse thunk_traverse(this);
1753   this->traverse(&thunk_traverse);
1754 }
1755
1756 // Simplify complex thunk statements into simple ones.  A complicated
1757 // thunk statement is one which takes anything other than zero
1758 // parameters or a single pointer parameter.  We rewrite it into code
1759 // which allocates a struct, stores the parameter values into the
1760 // struct, and does a simple go or defer statement which passes the
1761 // struct to a thunk.  The thunk does the real call.
1762
1763 bool
1764 Thunk_statement::simplify_statement(Gogo* gogo, Block* block)
1765 {
1766   if (this->classification() == STATEMENT_ERROR)
1767     return false;
1768   if (this->call_->is_error_expression())
1769     return false;
1770
1771   Call_expression* ce = this->call_->call_expression();
1772   Function_type* fntype = ce->get_function_type();
1773   if (fntype == NULL)
1774     {
1775       gcc_assert(saw_errors());
1776       this->set_is_error();
1777       return false;
1778     }
1779   if (this->is_simple(fntype))
1780     return false;
1781
1782   Expression* fn = ce->fn();
1783   Bound_method_expression* bound_method = fn->bound_method_expression();
1784   Interface_field_reference_expression* interface_method =
1785     fn->interface_field_reference_expression();
1786   const bool is_method = bound_method != NULL || interface_method != NULL;
1787
1788   source_location location = this->location();
1789
1790   std::string thunk_name = Gogo::thunk_name();
1791
1792   // Build the thunk.
1793   this->build_thunk(gogo, thunk_name, fntype);
1794
1795   // Generate code to call the thunk.
1796
1797   // Get the values to store into the struct which is the single
1798   // argument to the thunk.
1799
1800   Expression_list* vals = new Expression_list();
1801   if (fntype->is_builtin())
1802     ;
1803   else if (!is_method)
1804     vals->push_back(fn);
1805   else if (interface_method != NULL)
1806     vals->push_back(interface_method->expr());
1807   else if (bound_method != NULL)
1808     {
1809       vals->push_back(bound_method->method());
1810       Expression* first_arg = bound_method->first_argument();
1811
1812       // We always pass a pointer when calling a method.
1813       if (first_arg->type()->points_to() == NULL)
1814         first_arg = Expression::make_unary(OPERATOR_AND, first_arg, location);
1815
1816       // If we are calling a method which was inherited from an
1817       // embedded struct, and the method did not get a stub, then the
1818       // first type may be wrong.
1819       Type* fatype = bound_method->first_argument_type();
1820       if (fatype != NULL)
1821         {
1822           if (fatype->points_to() == NULL)
1823             fatype = Type::make_pointer_type(fatype);
1824           Type* unsafe = Type::make_pointer_type(Type::make_void_type());
1825           first_arg = Expression::make_cast(unsafe, first_arg, location);
1826           first_arg = Expression::make_cast(fatype, first_arg, location);
1827         }
1828
1829       vals->push_back(first_arg);
1830     }
1831   else
1832     gcc_unreachable();
1833
1834   if (ce->args() != NULL)
1835     {
1836       for (Expression_list::const_iterator p = ce->args()->begin();
1837            p != ce->args()->end();
1838            ++p)
1839         vals->push_back(*p);
1840     }
1841
1842   // Build the struct.
1843   Expression* constructor =
1844     Expression::make_struct_composite_literal(this->struct_type_, vals,
1845                                               location);
1846
1847   // Allocate the initialized struct on the heap.
1848   constructor = Expression::make_heap_composite(constructor, location);
1849
1850   // Look up the thunk.
1851   Named_object* named_thunk = gogo->lookup(thunk_name, NULL);
1852   gcc_assert(named_thunk != NULL && named_thunk->is_function());
1853
1854   // Build the call.
1855   Expression* func = Expression::make_func_reference(named_thunk, NULL,
1856                                                      location);
1857   Expression_list* params = new Expression_list();
1858   params->push_back(constructor);
1859   Call_expression* call = Expression::make_call(func, params, false, location);
1860
1861   // Build the simple go or defer statement.
1862   Statement* s;
1863   if (this->classification() == STATEMENT_GO)
1864     s = Statement::make_go_statement(call, location);
1865   else if (this->classification() == STATEMENT_DEFER)
1866     s = Statement::make_defer_statement(call, location);
1867   else
1868     gcc_unreachable();
1869
1870   // The current block should end with the go statement.
1871   gcc_assert(block->statements()->size() >= 1);
1872   gcc_assert(block->statements()->back() == this);
1873   block->replace_statement(block->statements()->size() - 1, s);
1874
1875   // We already ran the determine_types pass, so we need to run it now
1876   // for the new statement.
1877   s->determine_types();
1878
1879   // Sanity check.
1880   gogo->check_types_in_block(block);
1881
1882   // Return true to tell the block not to keep looking at statements.
1883   return true;
1884 }
1885
1886 // Set the name to use for thunk parameter N.
1887
1888 void
1889 Thunk_statement::thunk_field_param(int n, char* buf, size_t buflen)
1890 {
1891   snprintf(buf, buflen, "a%d", n);
1892 }
1893
1894 // Build a new struct type to hold the parameters for a complicated
1895 // thunk statement.  FNTYPE is the type of the function call.
1896
1897 Struct_type*
1898 Thunk_statement::build_struct(Function_type* fntype)
1899 {
1900   source_location location = this->location();
1901
1902   Struct_field_list* fields = new Struct_field_list();
1903
1904   Call_expression* ce = this->call_->call_expression();
1905   Expression* fn = ce->fn();
1906
1907   Interface_field_reference_expression* interface_method =
1908     fn->interface_field_reference_expression();
1909   if (interface_method != NULL)
1910     {
1911       // If this thunk statement calls a method on an interface, we
1912       // pass the interface object to the thunk.
1913       Typed_identifier tid(Thunk_statement::thunk_field_fn,
1914                            interface_method->expr()->type(),
1915                            location);
1916       fields->push_back(Struct_field(tid));
1917     }
1918   else if (!fntype->is_builtin())
1919     {
1920       // The function to call.
1921       Typed_identifier tid(Go_statement::thunk_field_fn, fntype, location);
1922       fields->push_back(Struct_field(tid));
1923     }
1924   else if (ce->is_recover_call())
1925     {
1926       // The predeclared recover function has no argument.  However,
1927       // we add an argument when building recover thunks.  Handle that
1928       // here.
1929       fields->push_back(Struct_field(Typed_identifier("can_recover",
1930                                                       Type::lookup_bool_type(),
1931                                                       location)));
1932     }
1933
1934   if (fn->bound_method_expression() != NULL)
1935     {
1936       gcc_assert(fntype->is_method());
1937       Type* rtype = fntype->receiver()->type();
1938       // We always pass the receiver as a pointer.
1939       if (rtype->points_to() == NULL)
1940         rtype = Type::make_pointer_type(rtype);
1941       Typed_identifier tid(Thunk_statement::thunk_field_receiver, rtype,
1942                            location);
1943       fields->push_back(Struct_field(tid));
1944     }
1945
1946   const Expression_list* args = ce->args();
1947   if (args != NULL)
1948     {
1949       int i = 0;
1950       for (Expression_list::const_iterator p = args->begin();
1951            p != args->end();
1952            ++p, ++i)
1953         {
1954           char buf[50];
1955           this->thunk_field_param(i, buf, sizeof buf);
1956           fields->push_back(Struct_field(Typed_identifier(buf, (*p)->type(),
1957                                                           location)));
1958         }
1959     }
1960
1961   return Type::make_struct_type(fields, location);
1962 }
1963
1964 // Build the thunk we are going to call.  This is a brand new, albeit
1965 // artificial, function.
1966
1967 void
1968 Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
1969                              Function_type* fntype)
1970 {
1971   source_location location = this->location();
1972
1973   Call_expression* ce = this->call_->call_expression();
1974
1975   bool may_call_recover = false;
1976   if (this->classification() == STATEMENT_DEFER)
1977     {
1978       Func_expression* fn = ce->fn()->func_expression();
1979       if (fn == NULL)
1980         may_call_recover = true;
1981       else
1982         {
1983           const Named_object* no = fn->named_object();
1984           if (!no->is_function())
1985             may_call_recover = true;
1986           else
1987             may_call_recover = no->func_value()->calls_recover();
1988         }
1989     }
1990
1991   // Build the type of the thunk.  The thunk takes a single parameter,
1992   // which is a pointer to the special structure we build.
1993   const char* const parameter_name = "__go_thunk_parameter";
1994   Typed_identifier_list* thunk_parameters = new Typed_identifier_list();
1995   Type* pointer_to_struct_type = Type::make_pointer_type(this->struct_type_);
1996   thunk_parameters->push_back(Typed_identifier(parameter_name,
1997                                                pointer_to_struct_type,
1998                                                location));
1999
2000   Typed_identifier_list* thunk_results = NULL;
2001   if (may_call_recover)
2002     {
2003       // When deferring a function which may call recover, add a
2004       // return value, to disable tail call optimizations which will
2005       // break the way we check whether recover is permitted.
2006       thunk_results = new Typed_identifier_list();
2007       thunk_results->push_back(Typed_identifier("", Type::lookup_bool_type(),
2008                                                 location));
2009     }
2010
2011   Function_type* thunk_type = Type::make_function_type(NULL, thunk_parameters,
2012                                                        thunk_results,
2013                                                        location);
2014
2015   // Start building the thunk.
2016   Named_object* function = gogo->start_function(thunk_name, thunk_type, true,
2017                                                 location);
2018
2019   // For a defer statement, start with a call to
2020   // __go_set_defer_retaddr.  */
2021   Label* retaddr_label = NULL; 
2022   if (may_call_recover)
2023     {
2024       retaddr_label = gogo->add_label_reference("retaddr");
2025       Expression* arg = Expression::make_label_addr(retaddr_label, location);
2026       Expression* call = Runtime::make_call(Runtime::SET_DEFER_RETADDR,
2027                                             location, 1, arg);
2028
2029       // This is a hack to prevent the middle-end from deleting the
2030       // label.
2031       gogo->start_block(location);
2032       gogo->add_statement(Statement::make_goto_statement(retaddr_label,
2033                                                          location));
2034       Block* then_block = gogo->finish_block(location);
2035       then_block->determine_types();
2036
2037       Statement* s = Statement::make_if_statement(call, then_block, NULL,
2038                                                   location);
2039       s->determine_types();
2040       gogo->add_statement(s);
2041     }
2042
2043   // Get a reference to the parameter.
2044   Named_object* named_parameter = gogo->lookup(parameter_name, NULL);
2045   gcc_assert(named_parameter != NULL && named_parameter->is_variable());
2046
2047   // Build the call.  Note that the field names are the same as the
2048   // ones used in build_struct.
2049   Expression* thunk_parameter = Expression::make_var_reference(named_parameter,
2050                                                                location);
2051   thunk_parameter = Expression::make_unary(OPERATOR_MULT, thunk_parameter,
2052                                            location);
2053
2054   Bound_method_expression* bound_method = ce->fn()->bound_method_expression();
2055   Interface_field_reference_expression* interface_method =
2056     ce->fn()->interface_field_reference_expression();
2057
2058   Expression* func_to_call;
2059   unsigned int next_index;
2060   if (!fntype->is_builtin())
2061     {
2062       func_to_call = Expression::make_field_reference(thunk_parameter,
2063                                                       0, location);
2064       next_index = 1;
2065     }
2066   else
2067     {
2068       gcc_assert(bound_method == NULL && interface_method == NULL);
2069       func_to_call = ce->fn();
2070       next_index = 0;
2071     }
2072
2073   if (bound_method != NULL)
2074     {
2075       Expression* r = Expression::make_field_reference(thunk_parameter, 1,
2076                                                        location);
2077       // The main program passes in a function pointer from the
2078       // interface expression, so here we can make a bound method in
2079       // all cases.
2080       func_to_call = Expression::make_bound_method(r, func_to_call,
2081                                                    location);
2082       next_index = 2;
2083     }
2084   else if (interface_method != NULL)
2085     {
2086       // The main program passes the interface object.
2087       const std::string& name(interface_method->name());
2088       func_to_call = Expression::make_interface_field_reference(func_to_call,
2089                                                                 name,
2090                                                                 location);
2091     }
2092
2093   Expression_list* call_params = new Expression_list();
2094   const Struct_field_list* fields = this->struct_type_->fields();
2095   Struct_field_list::const_iterator p = fields->begin();
2096   for (unsigned int i = 0; i < next_index; ++i)
2097     ++p;
2098   bool is_recover_call = ce->is_recover_call();
2099   Expression* recover_arg = NULL;
2100   for (; p != fields->end(); ++p, ++next_index)
2101     {
2102       Expression* thunk_param = Expression::make_var_reference(named_parameter,
2103                                                                location);
2104       thunk_param = Expression::make_unary(OPERATOR_MULT, thunk_param,
2105                                            location);
2106       Expression* param = Expression::make_field_reference(thunk_param,
2107                                                            next_index,
2108                                                            location);
2109       if (!is_recover_call)
2110         call_params->push_back(param);
2111       else
2112         {
2113           gcc_assert(call_params->empty());
2114           recover_arg = param;
2115         }
2116     }
2117
2118   if (call_params->empty())
2119     {
2120       delete call_params;
2121       call_params = NULL;
2122     }
2123
2124   Expression* call = Expression::make_call(func_to_call, call_params, false,
2125                                            location);
2126   // We need to lower in case this is a builtin function.
2127   call = call->lower(gogo, function, -1);
2128   Call_expression* call_ce = call->call_expression();
2129   if (call_ce != NULL && may_call_recover)
2130     call_ce->set_is_deferred();
2131
2132   Statement* call_statement = Statement::make_statement(call);
2133
2134   // We already ran the determine_types pass, so we need to run it
2135   // just for this statement now.
2136   call_statement->determine_types();
2137
2138   // Sanity check.
2139   call->check_types(gogo);
2140
2141   if (call_ce != NULL && recover_arg != NULL)
2142     call_ce->set_recover_arg(recover_arg);
2143
2144   gogo->add_statement(call_statement);
2145
2146   // If this is a defer statement, the label comes immediately after
2147   // the call.
2148   if (may_call_recover)
2149     {
2150       gogo->add_label_definition("retaddr", location);
2151
2152       Expression_list* vals = new Expression_list();
2153       vals->push_back(Expression::make_boolean(false, location));
2154       gogo->add_statement(Statement::make_return_statement(vals, location));
2155     }
2156
2157   // That is all the thunk has to do.
2158   gogo->finish_function(location);
2159 }
2160
2161 // Get the function and argument trees.
2162
2163 void
2164 Thunk_statement::get_fn_and_arg(Translate_context* context, tree* pfn,
2165                                 tree* parg)
2166 {
2167   if (this->call_->is_error_expression())
2168     {
2169       *pfn = error_mark_node;
2170       *parg = error_mark_node;
2171       return;
2172     }
2173
2174   Call_expression* ce = this->call_->call_expression();
2175
2176   Expression* fn = ce->fn();
2177   *pfn = fn->get_tree(context);
2178
2179   const Expression_list* args = ce->args();
2180   if (args == NULL || args->empty())
2181     *parg = null_pointer_node;
2182   else
2183     {
2184       gcc_assert(args->size() == 1);
2185       *parg = args->front()->get_tree(context);
2186     }
2187 }
2188
2189 // Class Go_statement.
2190
2191 tree
2192 Go_statement::do_get_tree(Translate_context* context)
2193 {
2194   tree fn_tree;
2195   tree arg_tree;
2196   this->get_fn_and_arg(context, &fn_tree, &arg_tree);
2197
2198   static tree go_fndecl;
2199
2200   tree fn_arg_type = NULL_TREE;
2201   if (go_fndecl == NULL_TREE)
2202     {
2203       // Only build FN_ARG_TYPE if we need it.
2204       tree subargtypes = tree_cons(NULL_TREE, ptr_type_node, void_list_node);
2205       tree subfntype = build_function_type(ptr_type_node, subargtypes);
2206       fn_arg_type = build_pointer_type(subfntype);
2207     }
2208
2209   return Gogo::call_builtin(&go_fndecl,
2210                             this->location(),
2211                             "__go_go",
2212                             2,
2213                             void_type_node,
2214                             fn_arg_type,
2215                             fn_tree,
2216                             ptr_type_node,
2217                             arg_tree);
2218 }
2219
2220 // Make a go statement.
2221
2222 Statement*
2223 Statement::make_go_statement(Call_expression* call, source_location location)
2224 {
2225   return new Go_statement(call, location);
2226 }
2227
2228 // Class Defer_statement.
2229
2230 tree
2231 Defer_statement::do_get_tree(Translate_context* context)
2232 {
2233   source_location loc = this->location();
2234
2235   tree fn_tree;
2236   tree arg_tree;
2237   this->get_fn_and_arg(context, &fn_tree, &arg_tree);
2238   if (fn_tree == error_mark_node || arg_tree == error_mark_node)
2239     return error_mark_node;
2240
2241   static tree defer_fndecl;
2242
2243   tree fn_arg_type = NULL_TREE;
2244   if (defer_fndecl == NULL_TREE)
2245     {
2246       // Only build FN_ARG_TYPE if we need it.
2247       tree subargtypes = tree_cons(NULL_TREE, ptr_type_node, void_list_node);
2248       tree subfntype = build_function_type(ptr_type_node, subargtypes);
2249       fn_arg_type = build_pointer_type(subfntype);
2250     }
2251
2252   tree defer_stack = context->function()->func_value()->defer_stack(loc);
2253
2254   return Gogo::call_builtin(&defer_fndecl,
2255                             loc,
2256                             "__go_defer",
2257                             3,
2258                             void_type_node,
2259                             ptr_type_node,
2260                             defer_stack,
2261                             fn_arg_type,
2262                             fn_tree,
2263                             ptr_type_node,
2264                             arg_tree);
2265 }
2266
2267 // Make a defer statement.
2268
2269 Statement*
2270 Statement::make_defer_statement(Call_expression* call,
2271                                 source_location location)
2272 {
2273   return new Defer_statement(call, location);
2274 }
2275
2276 // Class Return_statement.
2277
2278 // Traverse assignments.  We treat each return value as a top level
2279 // RHS in an expression.
2280
2281 bool
2282 Return_statement::do_traverse_assignments(Traverse_assignments* tassign)
2283 {
2284   Expression_list* vals = this->vals_;
2285   if (vals != NULL)
2286     {
2287       for (Expression_list::iterator p = vals->begin();
2288            p != vals->end();
2289            ++p)
2290         tassign->value(&*p, true, true);
2291     }
2292   return true;
2293 }
2294
2295 // Lower a return statement.  If we are returning a function call
2296 // which returns multiple values which match the current function,
2297 // split up the call's results.  If the function has named result
2298 // variables, and the return statement lists explicit values, then
2299 // implement it by assigning the values to the result variables and
2300 // changing the statement to not list any values.  This lets
2301 // panic/recover work correctly.
2302
2303 Statement*
2304 Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing)
2305 {
2306   if (this->is_lowered_)
2307     return this;
2308
2309   Expression_list* vals = this->vals_;
2310   this->vals_ = NULL;
2311   this->is_lowered_ = true;
2312
2313   source_location loc = this->location();
2314
2315   size_t vals_count = vals == NULL ? 0 : vals->size();
2316   Function::Results* results = function->func_value()->result_variables();
2317   size_t results_count = results == NULL ? 0 : results->size();
2318
2319   if (vals_count == 0)
2320     {
2321       if (results_count > 0 && !function->func_value()->results_are_named())
2322         {
2323           this->report_error(_("not enough arguments to return"));
2324           return this;
2325         }
2326       return this;
2327     }
2328
2329   if (results_count == 0)
2330     {
2331       this->report_error(_("return with value in function "
2332                            "with no return type"));
2333       return this;
2334     }
2335
2336   // If the current function has multiple return values, and we are
2337   // returning a single call expression, split up the call expression.
2338   if (results_count > 1
2339       && vals->size() == 1
2340       && vals->front()->call_expression() != NULL)
2341     {
2342       Call_expression* call = vals->front()->call_expression();
2343       delete vals;
2344       vals = new Expression_list;
2345       for (size_t i = 0; i < results_count; ++i)
2346         vals->push_back(Expression::make_call_result(call, i));
2347       vals_count = results_count;
2348     }
2349
2350   if (vals_count < results_count)
2351     {
2352       this->report_error(_("not enough arguments to return"));
2353       return this;
2354     }
2355
2356   if (vals_count > results_count)
2357     {
2358       this->report_error(_("too many values in return statement"));
2359       return this;
2360     }
2361
2362   Block* b = new Block(enclosing, loc);
2363
2364   Expression_list* lhs = new Expression_list();
2365   Expression_list* rhs = new Expression_list();
2366
2367   Expression_list::const_iterator pe = vals->begin();
2368   int i = 1;
2369   for (Function::Results::const_iterator pr = results->begin();
2370        pr != results->end();
2371        ++pr, ++pe, ++i)
2372     {
2373       Named_object* rv = *pr;
2374       Expression* e = *pe;
2375
2376       // Check types now so that we give a good error message.  The
2377       // result type is known.  We determine the expression type
2378       // early.
2379
2380       Type *rvtype = rv->result_var_value()->type();
2381       Type_context type_context(rvtype, false);
2382       e->determine_type(&type_context);
2383
2384       std::string reason;
2385       if (Type::are_assignable(rvtype, e->type(), &reason))
2386         {
2387           Expression* ve = Expression::make_var_reference(rv, e->location());
2388           lhs->push_back(ve);
2389           rhs->push_back(e);
2390         }
2391       else
2392         {
2393           if (reason.empty())
2394             error_at(e->location(), "incompatible type for return value %d", i);
2395           else
2396             error_at(e->location(),
2397                      "incompatible type for return value %d (%s)",
2398                      i, reason.c_str());
2399         }
2400     }
2401   gcc_assert(lhs->size() == rhs->size());
2402
2403   if (lhs->empty())
2404     ;
2405   else if (lhs->size() == 1)
2406     {
2407       b->add_statement(Statement::make_assignment(lhs->front(), rhs->front(),
2408                                                   loc));
2409       delete lhs;
2410       delete rhs;
2411     }
2412   else
2413     b->add_statement(Statement::make_tuple_assignment(lhs, rhs, loc));
2414
2415   b->add_statement(this);
2416
2417   delete vals;
2418
2419   return Statement::make_block_statement(b, loc);
2420 }
2421
2422 // Convert a return statement to the backend representation.
2423
2424 tree
2425 Return_statement::do_get_tree(Translate_context* context)
2426 {
2427   Function* function = context->function()->func_value();
2428   tree fndecl = function->get_decl();
2429
2430   Function::Results* results = function->result_variables();
2431   std::vector<Bexpression*> retvals;
2432   if (results != NULL && !results->empty())
2433     {
2434       retvals.reserve(results->size());
2435       for (Function::Results::const_iterator p = results->begin();
2436            p != results->end();
2437            p++)
2438         {
2439           tree rv = (*p)->get_tree(context->gogo(), context->function());
2440           retvals.push_back(tree_to_expr(rv));
2441         }
2442     }
2443
2444   Bstatement* ret;
2445   ret = context->backend()->return_statement(tree_to_function(fndecl),
2446                                              retvals, this->location());
2447   return stat_to_tree(ret);
2448 }
2449
2450 // Make a return statement.
2451
2452 Statement*
2453 Statement::make_return_statement(Expression_list* vals,
2454                                  source_location location)
2455 {
2456   return new Return_statement(vals, location);
2457 }
2458
2459 // A break or continue statement.
2460
2461 class Bc_statement : public Statement
2462 {
2463  public:
2464   Bc_statement(bool is_break, Unnamed_label* label, source_location location)
2465     : Statement(STATEMENT_BREAK_OR_CONTINUE, location),
2466       label_(label), is_break_(is_break)
2467   { }
2468
2469   bool
2470   is_break() const
2471   { return this->is_break_; }
2472
2473  protected:
2474   int
2475   do_traverse(Traverse*)
2476   { return TRAVERSE_CONTINUE; }
2477
2478   bool
2479   do_may_fall_through() const
2480   { return false; }
2481
2482   tree
2483   do_get_tree(Translate_context* context)
2484   {
2485     return stat_to_tree(this->label_->get_goto(context, this->location()));
2486   }
2487
2488  private:
2489   // The label that this branches to.
2490   Unnamed_label* label_;
2491   // True if this is "break", false if it is "continue".
2492   bool is_break_;
2493 };
2494
2495 // Make a break statement.
2496
2497 Statement*
2498 Statement::make_break_statement(Unnamed_label* label, source_location location)
2499 {
2500   return new Bc_statement(true, label, location);
2501 }
2502
2503 // Make a continue statement.
2504
2505 Statement*
2506 Statement::make_continue_statement(Unnamed_label* label,
2507                                    source_location location)
2508 {
2509   return new Bc_statement(false, label, location);
2510 }
2511
2512 // A goto statement.
2513
2514 class Goto_statement : public Statement
2515 {
2516  public:
2517   Goto_statement(Label* label, source_location location)
2518     : Statement(STATEMENT_GOTO, location),
2519       label_(label)
2520   { }
2521
2522  protected:
2523   int
2524   do_traverse(Traverse*)
2525   { return TRAVERSE_CONTINUE; }
2526
2527   void
2528   do_check_types(Gogo*);
2529
2530   bool
2531   do_may_fall_through() const
2532   { return false; }
2533
2534   tree
2535   do_get_tree(Translate_context*);
2536
2537  private:
2538   Label* label_;
2539 };
2540
2541 // Check types for a label.  There aren't any types per se, but we use
2542 // this to give an error if the label was never defined.
2543
2544 void
2545 Goto_statement::do_check_types(Gogo*)
2546 {
2547   if (!this->label_->is_defined())
2548     {
2549       error_at(this->location(), "reference to undefined label %qs",
2550                Gogo::message_name(this->label_->name()).c_str());
2551       this->set_is_error();
2552     }
2553 }
2554
2555 // Return the tree for the goto statement.
2556
2557 tree
2558 Goto_statement::do_get_tree(Translate_context* context)
2559 {
2560   Blabel* blabel = this->label_->get_backend_label(context);
2561   Bstatement* statement = context->backend()->goto_statement(blabel,
2562                                                              this->location());
2563   return stat_to_tree(statement);
2564 }
2565
2566 // Make a goto statement.
2567
2568 Statement*
2569 Statement::make_goto_statement(Label* label, source_location location)
2570 {
2571   return new Goto_statement(label, location);
2572 }
2573
2574 // A goto statement to an unnamed label.
2575
2576 class Goto_unnamed_statement : public Statement
2577 {
2578  public:
2579   Goto_unnamed_statement(Unnamed_label* label, source_location location)
2580     : Statement(STATEMENT_GOTO_UNNAMED, location),
2581       label_(label)
2582   { }
2583
2584  protected:
2585   int
2586   do_traverse(Traverse*)
2587   { return TRAVERSE_CONTINUE; }
2588
2589   bool
2590   do_may_fall_through() const
2591   { return false; }
2592
2593   tree
2594   do_get_tree(Translate_context* context)
2595   {
2596     return stat_to_tree(this->label_->get_goto(context, this->location()));
2597   }
2598
2599  private:
2600   Unnamed_label* label_;
2601 };
2602
2603 // Make a goto statement to an unnamed label.
2604
2605 Statement*
2606 Statement::make_goto_unnamed_statement(Unnamed_label* label,
2607                                        source_location location)
2608 {
2609   return new Goto_unnamed_statement(label, location);
2610 }
2611
2612 // Class Label_statement.
2613
2614 // Traversal.
2615
2616 int
2617 Label_statement::do_traverse(Traverse*)
2618 {
2619   return TRAVERSE_CONTINUE;
2620 }
2621
2622 // Return a tree defining this label.
2623
2624 tree
2625 Label_statement::do_get_tree(Translate_context* context)
2626 {
2627   Blabel* blabel = this->label_->get_backend_label(context);
2628   Bstatement* statement;
2629   statement = context->backend()->label_definition_statement(blabel);
2630   return stat_to_tree(statement);
2631 }
2632
2633 // Make a label statement.
2634
2635 Statement*
2636 Statement::make_label_statement(Label* label, source_location location)
2637 {
2638   return new Label_statement(label, location);
2639 }
2640
2641 // An unnamed label statement.
2642
2643 class Unnamed_label_statement : public Statement
2644 {
2645  public:
2646   Unnamed_label_statement(Unnamed_label* label)
2647     : Statement(STATEMENT_UNNAMED_LABEL, label->location()),
2648       label_(label)
2649   { }
2650
2651  protected:
2652   int
2653   do_traverse(Traverse*)
2654   { return TRAVERSE_CONTINUE; }
2655
2656   tree
2657   do_get_tree(Translate_context* context)
2658   { return stat_to_tree(this->label_->get_definition(context)); }
2659
2660  private:
2661   // The label.
2662   Unnamed_label* label_;
2663 };
2664
2665 // Make an unnamed label statement.
2666
2667 Statement*
2668 Statement::make_unnamed_label_statement(Unnamed_label* label)
2669 {
2670   return new Unnamed_label_statement(label);
2671 }
2672
2673 // An if statement.
2674
2675 class If_statement : public Statement
2676 {
2677  public:
2678   If_statement(Expression* cond, Block* then_block, Block* else_block,
2679                source_location location)
2680     : Statement(STATEMENT_IF, location),
2681       cond_(cond), then_block_(then_block), else_block_(else_block)
2682   { }
2683
2684  protected:
2685   int
2686   do_traverse(Traverse*);
2687
2688   void
2689   do_determine_types();
2690
2691   void
2692   do_check_types(Gogo*);
2693
2694   bool
2695   do_may_fall_through() const;
2696
2697   tree
2698   do_get_tree(Translate_context*);
2699
2700  private:
2701   Expression* cond_;
2702   Block* then_block_;
2703   Block* else_block_;
2704 };
2705
2706 // Traversal.
2707
2708 int
2709 If_statement::do_traverse(Traverse* traverse)
2710 {
2711   if (this->traverse_expression(traverse, &this->cond_) == TRAVERSE_EXIT
2712       || this->then_block_->traverse(traverse) == TRAVERSE_EXIT)
2713     return TRAVERSE_EXIT;
2714   if (this->else_block_ != NULL)
2715     {
2716       if (this->else_block_->traverse(traverse) == TRAVERSE_EXIT)
2717         return TRAVERSE_EXIT;
2718     }
2719   return TRAVERSE_CONTINUE;
2720 }
2721
2722 void
2723 If_statement::do_determine_types()
2724 {
2725   Type_context context(Type::lookup_bool_type(), false);
2726   this->cond_->determine_type(&context);
2727   this->then_block_->determine_types();
2728   if (this->else_block_ != NULL)
2729     this->else_block_->determine_types();
2730 }
2731
2732 // Check types.
2733
2734 void
2735 If_statement::do_check_types(Gogo*)
2736 {
2737   Type* type = this->cond_->type();
2738   if (type->is_error())
2739     this->set_is_error();
2740   else if (!type->is_boolean_type())
2741     this->report_error(_("expected boolean expression"));
2742 }
2743
2744 // Whether the overall statement may fall through.
2745
2746 bool
2747 If_statement::do_may_fall_through() const
2748 {
2749   return (this->else_block_ == NULL
2750           || this->then_block_->may_fall_through()
2751           || this->else_block_->may_fall_through());
2752 }
2753
2754 // Get tree.
2755
2756 tree
2757 If_statement::do_get_tree(Translate_context* context)
2758 {
2759   gcc_assert(this->cond_->type()->is_boolean_type()
2760              || this->cond_->type()->is_error());
2761   tree cond_tree = this->cond_->get_tree(context);
2762   tree then_tree = this->then_block_->get_tree(context);
2763   tree else_tree = (this->else_block_ == NULL
2764                     ? NULL_TREE
2765                     : this->else_block_->get_tree(context));
2766
2767   Bexpression* cond_expr = tree_to_expr(cond_tree);
2768   Bstatement* then_stat = tree_to_stat(then_tree);
2769   Bstatement* else_stat = (else_tree == NULL_TREE
2770                            ? NULL
2771                            : tree_to_stat(else_tree));
2772   
2773   Bstatement* ret = context->backend()->if_statement(cond_expr, then_stat,
2774                                                      else_stat,
2775                                                      this->location());
2776   return stat_to_tree(ret);
2777 }
2778
2779 // Make an if statement.
2780
2781 Statement*
2782 Statement::make_if_statement(Expression* cond, Block* then_block,
2783                              Block* else_block, source_location location)
2784 {
2785   return new If_statement(cond, then_block, else_block, location);
2786 }
2787
2788 // Class Case_clauses::Hash_integer_value.
2789
2790 class Case_clauses::Hash_integer_value
2791 {
2792  public:
2793   size_t
2794   operator()(Expression*) const;
2795 };
2796
2797 size_t
2798 Case_clauses::Hash_integer_value::operator()(Expression* pe) const
2799 {
2800   Type* itype;
2801   mpz_t ival;
2802   mpz_init(ival);
2803   if (!pe->integer_constant_value(true, ival, &itype))
2804     gcc_unreachable();
2805   size_t ret = mpz_get_ui(ival);
2806   mpz_clear(ival);
2807   return ret;
2808 }
2809
2810 // Class Case_clauses::Eq_integer_value.
2811
2812 class Case_clauses::Eq_integer_value
2813 {
2814  public:
2815   bool
2816   operator()(Expression*, Expression*) const;
2817 };
2818
2819 bool
2820 Case_clauses::Eq_integer_value::operator()(Expression* a, Expression* b) const
2821 {
2822   Type* atype;
2823   Type* btype;
2824   mpz_t aval;
2825   mpz_t bval;
2826   mpz_init(aval);
2827   mpz_init(bval);
2828   if (!a->integer_constant_value(true, aval, &atype)
2829       || !b->integer_constant_value(true, bval, &btype))
2830     gcc_unreachable();
2831   bool ret = mpz_cmp(aval, bval) == 0;
2832   mpz_clear(aval);
2833   mpz_clear(bval);
2834   return ret;
2835 }
2836
2837 // Class Case_clauses::Case_clause.
2838
2839 // Traversal.
2840
2841 int
2842 Case_clauses::Case_clause::traverse(Traverse* traverse)
2843 {
2844   if (this->cases_ != NULL
2845       && (traverse->traverse_mask()
2846           & (Traverse::traverse_types | Traverse::traverse_expressions)) != 0)
2847     {
2848       if (this->cases_->traverse(traverse) == TRAVERSE_EXIT)
2849         return TRAVERSE_EXIT;
2850     }
2851   if (this->statements_ != NULL)
2852     {
2853       if (this->statements_->traverse(traverse) == TRAVERSE_EXIT)
2854         return TRAVERSE_EXIT;
2855     }
2856   return TRAVERSE_CONTINUE;
2857 }
2858
2859 // Check whether all the case expressions are integer constants.
2860
2861 bool
2862 Case_clauses::Case_clause::is_constant() const
2863 {
2864   if (this->cases_ != NULL)
2865     {
2866       for (Expression_list::const_iterator p = this->cases_->begin();
2867            p != this->cases_->end();
2868            ++p)
2869         if (!(*p)->is_constant() || (*p)->type()->integer_type() == NULL)
2870           return false;
2871     }
2872   return true;
2873 }
2874
2875 // Lower a case clause for a nonconstant switch.  VAL_TEMP is the
2876 // value we are switching on; it may be NULL.  If START_LABEL is not
2877 // NULL, it goes at the start of the statements, after the condition
2878 // test.  We branch to FINISH_LABEL at the end of the statements.
2879
2880 void
2881 Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
2882                                  Unnamed_label* start_label,
2883                                  Unnamed_label* finish_label) const
2884 {
2885   source_location loc = this->location_;
2886   Unnamed_label* next_case_label;
2887   if (this->cases_ == NULL || this->cases_->empty())
2888     {
2889       gcc_assert(this->is_default_);
2890       next_case_label = NULL;
2891     }
2892   else
2893     {
2894       Expression* cond = NULL;
2895
2896       for (Expression_list::const_iterator p = this->cases_->begin();
2897            p != this->cases_->end();
2898            ++p)
2899         {
2900           Expression* this_cond;
2901           if (val_temp == NULL)
2902             this_cond = *p;
2903           else
2904             {
2905               Expression* ref = Expression::make_temporary_reference(val_temp,
2906                                                                      loc);
2907               this_cond = Expression::make_binary(OPERATOR_EQEQ, ref, *p, loc);
2908             }
2909
2910           if (cond == NULL)
2911             cond = this_cond;
2912           else
2913             cond = Expression::make_binary(OPERATOR_OROR, cond, this_cond, loc);
2914         }
2915
2916       Block* then_block = new Block(b, loc);
2917       next_case_label = new Unnamed_label(UNKNOWN_LOCATION);
2918       Statement* s = Statement::make_goto_unnamed_statement(next_case_label,
2919                                                             loc);
2920       then_block->add_statement(s);
2921
2922       // if !COND { goto NEXT_CASE_LABEL }
2923       cond = Expression::make_unary(OPERATOR_NOT, cond, loc);
2924       s = Statement::make_if_statement(cond, then_block, NULL, loc);
2925       b->add_statement(s);
2926     }
2927
2928   if (start_label != NULL)
2929     b->add_statement(Statement::make_unnamed_label_statement(start_label));
2930
2931   if (this->statements_ != NULL)
2932     b->add_statement(Statement::make_block_statement(this->statements_, loc));
2933
2934   Statement* s = Statement::make_goto_unnamed_statement(finish_label, loc);
2935   b->add_statement(s);
2936
2937   if (next_case_label != NULL)
2938     b->add_statement(Statement::make_unnamed_label_statement(next_case_label));
2939 }
2940
2941 // Determine types.
2942
2943 void
2944 Case_clauses::Case_clause::determine_types(Type* type)
2945 {
2946   if (this->cases_ != NULL)
2947     {
2948       Type_context case_context(type, false);
2949       for (Expression_list::iterator p = this->cases_->begin();
2950            p != this->cases_->end();
2951            ++p)
2952         (*p)->determine_type(&case_context);
2953     }
2954   if (this->statements_ != NULL)
2955     this->statements_->determine_types();
2956 }
2957
2958 // Check types.  Returns false if there was an error.
2959
2960 bool
2961 Case_clauses::Case_clause::check_types(Type* type)
2962 {
2963   if (this->cases_ != NULL)
2964     {
2965       for (Expression_list::iterator p = this->cases_->begin();
2966            p != this->cases_->end();
2967            ++p)
2968         {
2969           if (!Type::are_assignable(type, (*p)->type(), NULL)
2970               && !Type::are_assignable((*p)->type(), type, NULL))
2971             {
2972               error_at((*p)->location(),
2973                        "type mismatch between switch value and case clause");
2974               return false;
2975             }
2976         }
2977     }
2978   return true;
2979 }
2980
2981 // Return true if this clause may fall through to the following
2982 // statements.  Note that this is not the same as whether the case
2983 // uses the "fallthrough" keyword.
2984
2985 bool
2986 Case_clauses::Case_clause::may_fall_through() const
2987 {
2988   if (this->statements_ == NULL)
2989     return true;
2990   return this->statements_->may_fall_through();
2991 }
2992
2993 // Convert the case values and statements to the backend
2994 // representation.  BREAK_LABEL is the label which break statements
2995 // should branch to.  CASE_CONSTANTS is used to detect duplicate
2996 // constants.  *CASES should be passed as an empty vector; the values
2997 // for this case will be added to it.  If this is the default case,
2998 // *CASES will remain empty.  This returns the statement to execute if
2999 // one of these cases is selected.
3000
3001 Bstatement*
3002 Case_clauses::Case_clause::get_backend(Translate_context* context,
3003                                        Unnamed_label* break_label,
3004                                        Case_constants* case_constants,
3005                                        std::vector<Bexpression*>* cases) const
3006 {
3007   if (this->cases_ != NULL)
3008     {
3009       gcc_assert(!this->is_default_);
3010       for (Expression_list::const_iterator p = this->cases_->begin();
3011            p != this->cases_->end();
3012            ++p)
3013         {
3014           Expression* e = *p;
3015           if (e->classification() != Expression::EXPRESSION_INTEGER)
3016             {
3017               Type* itype;
3018               mpz_t ival;
3019               mpz_init(ival);
3020               if (!(*p)->integer_constant_value(true, ival, &itype))
3021                 {
3022                   // Something went wrong.  This can happen with a
3023                   // negative constant and an unsigned switch value.
3024                   gcc_assert(saw_errors());
3025                   continue;
3026                 }
3027               gcc_assert(itype != NULL);
3028               e = Expression::make_integer(&ival, itype, e->location());
3029               mpz_clear(ival);
3030             }
3031
3032           std::pair<Case_constants::iterator, bool> ins =
3033             case_constants->insert(e);
3034           if (!ins.second)
3035             {
3036               // Value was already present.
3037               error_at(this->location_, "duplicate case in switch");
3038               continue;
3039             }
3040
3041           tree case_tree = e->get_tree(context);
3042           Bexpression* case_expr = tree_to_expr(case_tree);
3043           cases->push_back(case_expr);
3044         }
3045     }
3046
3047   Bstatement* statements;
3048   if (this->statements_ == NULL)
3049     statements = NULL;
3050   else
3051     statements = tree_to_stat(this->statements_->get_tree(context));
3052
3053   Bstatement* break_stat;
3054   if (this->is_fallthrough_)
3055     break_stat = NULL;
3056   else
3057     break_stat = break_label->get_goto(context, this->location_);
3058
3059   if (statements == NULL)
3060     return break_stat;
3061   else if (break_stat == NULL)
3062     return statements;
3063   else
3064     {
3065       std::vector<Bstatement*> list(2);
3066       list[0] = statements;
3067       list[1] = break_stat;
3068       return context->backend()->statement_list(list);
3069     }
3070 }
3071
3072 // Class Case_clauses.
3073
3074 // Traversal.
3075
3076 int
3077 Case_clauses::traverse(Traverse* traverse)
3078 {
3079   for (Clauses::iterator p = this->clauses_.begin();
3080        p != this->clauses_.end();
3081        ++p)
3082     {
3083       if (p->traverse(traverse) == TRAVERSE_EXIT)
3084         return TRAVERSE_EXIT;
3085     }
3086   return TRAVERSE_CONTINUE;
3087 }
3088
3089 // Check whether all the case expressions are constant.
3090
3091 bool
3092 Case_clauses::is_constant() const
3093 {
3094   for (Clauses::const_iterator p = this->clauses_.begin();
3095        p != this->clauses_.end();
3096        ++p)
3097     if (!p->is_constant())
3098       return false;
3099   return true;
3100 }
3101
3102 // Lower case clauses for a nonconstant switch.
3103
3104 void
3105 Case_clauses::lower(Block* b, Temporary_statement* val_temp,
3106                     Unnamed_label* break_label) const
3107 {
3108   // The default case.
3109   const Case_clause* default_case = NULL;
3110
3111   // The label for the fallthrough of the previous case.
3112   Unnamed_label* last_fallthrough_label = NULL;
3113
3114   // The label for the start of the default case.  This is used if the
3115   // case before the default case falls through.
3116   Unnamed_label* default_start_label = NULL;
3117
3118   // The label for the end of the default case.  This normally winds
3119   // up as BREAK_LABEL, but it will be different if the default case
3120   // falls through.
3121   Unnamed_label* default_finish_label = NULL;
3122
3123   for (Clauses::const_iterator p = this->clauses_.begin();
3124        p != this->clauses_.end();
3125        ++p)
3126     {
3127       // The label to use for the start of the statements for this
3128       // case.  This is NULL unless the previous case falls through.
3129       Unnamed_label* start_label = last_fallthrough_label;
3130
3131       // The label to jump to after the end of the statements for this
3132       // case.
3133       Unnamed_label* finish_label = break_label;
3134
3135       last_fallthrough_label = NULL;
3136       if (p->is_fallthrough() && p + 1 != this->clauses_.end())
3137         {
3138           finish_label = new Unnamed_label(p->location());
3139           last_fallthrough_label = finish_label;
3140         }
3141
3142       if (!p->is_default())
3143         p->lower(b, val_temp, start_label, finish_label);
3144       else
3145         {
3146           // We have to move the default case to the end, so that we
3147           // only use it if all the other tests fail.
3148           default_case = &*p;
3149           default_start_label = start_label;
3150           default_finish_label = finish_label;
3151         }
3152     }
3153
3154   if (default_case != NULL)
3155     default_case->lower(b, val_temp, default_start_label,
3156                         default_finish_label);
3157       
3158 }
3159
3160 // Determine types.
3161
3162 void
3163 Case_clauses::determine_types(Type* type)
3164 {
3165   for (Clauses::iterator p = this->clauses_.begin();
3166        p != this->clauses_.end();
3167        ++p)
3168     p->determine_types(type);
3169 }
3170
3171 // Check types.  Returns false if there was an error.
3172
3173 bool
3174 Case_clauses::check_types(Type* type)
3175 {
3176   bool ret = true;
3177   for (Clauses::iterator p = this->clauses_.begin();
3178        p != this->clauses_.end();
3179        ++p)
3180     {
3181       if (!p->check_types(type))
3182         ret = false;
3183     }
3184   return ret;
3185 }
3186
3187 // Return true if these clauses may fall through to the statements
3188 // following the switch statement.
3189
3190 bool
3191 Case_clauses::may_fall_through() const
3192 {
3193   bool found_default = false;
3194   for (Clauses::const_iterator p = this->clauses_.begin();
3195        p != this->clauses_.end();
3196        ++p)
3197     {
3198       if (p->may_fall_through() && !p->is_fallthrough())
3199         return true;
3200       if (p->is_default())
3201         found_default = true;
3202     }
3203   return !found_default;
3204 }
3205
3206 // Convert the cases to the backend representation.  This sets
3207 // *ALL_CASES and *ALL_STATEMENTS.
3208
3209 void
3210 Case_clauses::get_backend(Translate_context* context,
3211                           Unnamed_label* break_label,
3212                           std::vector<std::vector<Bexpression*> >* all_cases,
3213                           std::vector<Bstatement*>* all_statements) const
3214 {
3215   Case_constants case_constants;
3216
3217   size_t c = this->clauses_.size();
3218   all_cases->resize(c);
3219   all_statements->resize(c);
3220
3221   size_t i = 0;
3222   for (Clauses::const_iterator p = this->clauses_.begin();
3223        p != this->clauses_.end();
3224        ++p, ++i)
3225     {
3226       std::vector<Bexpression*> cases;
3227       Bstatement* stat = p->get_backend(context, break_label, &case_constants,
3228                                         &cases);
3229       (*all_cases)[i].swap(cases);
3230       (*all_statements)[i] = stat;
3231     }
3232 }
3233
3234 // A constant switch statement.  A Switch_statement is lowered to this
3235 // when all the cases are constants.
3236
3237 class Constant_switch_statement : public Statement
3238 {
3239  public:
3240   Constant_switch_statement(Expression* val, Case_clauses* clauses,
3241                             Unnamed_label* break_label,
3242                             source_location location)
3243     : Statement(STATEMENT_CONSTANT_SWITCH, location),
3244       val_(val), clauses_(clauses), break_label_(break_label)
3245   { }
3246
3247  protected:
3248   int
3249   do_traverse(Traverse*);
3250
3251   void
3252   do_determine_types();
3253
3254   void
3255   do_check_types(Gogo*);
3256
3257   bool
3258   do_may_fall_through() const;
3259
3260   tree
3261   do_get_tree(Translate_context*);
3262
3263  private:
3264   // The value to switch on.
3265   Expression* val_;
3266   // The case clauses.
3267   Case_clauses* clauses_;
3268   // The break label, if needed.
3269   Unnamed_label* break_label_;
3270 };
3271
3272 // Traversal.
3273
3274 int
3275 Constant_switch_statement::do_traverse(Traverse* traverse)
3276 {
3277   if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT)
3278     return TRAVERSE_EXIT;
3279   return this->clauses_->traverse(traverse);
3280 }
3281
3282 // Determine types.
3283
3284 void
3285 Constant_switch_statement::do_determine_types()
3286 {
3287   this->val_->determine_type_no_context();
3288   this->clauses_->determine_types(this->val_->type());
3289 }
3290
3291 // Check types.
3292
3293 void
3294 Constant_switch_statement::do_check_types(Gogo*)
3295 {
3296   if (!this->clauses_->check_types(this->val_->type()))
3297     this->set_is_error();
3298 }
3299
3300 // Return whether this switch may fall through.
3301
3302 bool
3303 Constant_switch_statement::do_may_fall_through() const
3304 {
3305   if (this->clauses_ == NULL)
3306     return true;
3307
3308   // If we have a break label, then some case needed it.  That implies
3309   // that the switch statement as a whole can fall through.
3310   if (this->break_label_ != NULL)
3311     return true;
3312
3313   return this->clauses_->may_fall_through();
3314 }
3315
3316 // Convert to GENERIC.
3317
3318 tree
3319 Constant_switch_statement::do_get_tree(Translate_context* context)
3320 {
3321   tree switch_val_tree = this->val_->get_tree(context);
3322   Bexpression* switch_val_expr = tree_to_expr(switch_val_tree);
3323
3324   Unnamed_label* break_label = this->break_label_;
3325   if (break_label == NULL)
3326     break_label = new Unnamed_label(this->location());
3327
3328   std::vector<std::vector<Bexpression*> > all_cases;
3329   std::vector<Bstatement*> all_statements;
3330   this->clauses_->get_backend(context, break_label, &all_cases,
3331                               &all_statements);
3332
3333   Bstatement* switch_statement;
3334   switch_statement = context->backend()->switch_statement(switch_val_expr,
3335                                                           all_cases,
3336                                                           all_statements,
3337                                                           this->location());
3338
3339   std::vector<Bstatement*> stats(2);
3340   stats[0] = switch_statement;
3341   stats[1] = break_label->get_definition(context);
3342   Bstatement* ret = context->backend()->statement_list(stats);
3343   return stat_to_tree(ret);
3344 }
3345
3346 // Class Switch_statement.
3347
3348 // Traversal.
3349
3350 int
3351 Switch_statement::do_traverse(Traverse* traverse)
3352 {
3353   if (this->val_ != NULL)
3354     {
3355       if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT)
3356         return TRAVERSE_EXIT;
3357     }
3358   return this->clauses_->traverse(traverse);
3359 }
3360
3361 // Lower a Switch_statement to a Constant_switch_statement or a series
3362 // of if statements.
3363
3364 Statement*
3365 Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
3366 {
3367   source_location loc = this->location();
3368
3369   if (this->val_ != NULL
3370       && (this->val_->is_error_expression()
3371           || this->val_->type()->is_error()))
3372     return Statement::make_error_statement(loc);
3373
3374   if (this->val_ != NULL
3375       && this->val_->type()->integer_type() != NULL
3376       && !this->clauses_->empty()
3377       && this->clauses_->is_constant())
3378     return new Constant_switch_statement(this->val_, this->clauses_,
3379                                          this->break_label_, loc);
3380
3381   Block* b = new Block(enclosing, loc);
3382
3383   if (this->clauses_->empty())
3384     {
3385       Expression* val = this->val_;
3386       if (val == NULL)
3387         val = Expression::make_boolean(true, loc);
3388       return Statement::make_statement(val);
3389     }
3390
3391   Temporary_statement* val_temp;
3392   if (this->val_ == NULL)
3393     val_temp = NULL;
3394   else
3395     {
3396       // var val_temp VAL_TYPE = VAL
3397       val_temp = Statement::make_temporary(NULL, this->val_, loc);
3398       b->add_statement(val_temp);
3399     }
3400
3401   this->clauses_->lower(b, val_temp, this->break_label());
3402
3403   Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
3404   b->add_statement(s);
3405
3406   return Statement::make_block_statement(b, loc);
3407 }
3408
3409 // Return the break label for this switch statement, creating it if
3410 // necessary.
3411
3412 Unnamed_label*
3413 Switch_statement::break_label()
3414 {
3415   if (this->break_label_ == NULL)
3416     this->break_label_ = new Unnamed_label(this->location());
3417   return this->break_label_;
3418 }
3419
3420 // Make a switch statement.
3421
3422 Switch_statement*
3423 Statement::make_switch_statement(Expression* val, source_location location)
3424 {
3425   return new Switch_statement(val, location);
3426 }
3427
3428 // Class Type_case_clauses::Type_case_clause.
3429
3430 // Traversal.
3431
3432 int
3433 Type_case_clauses::Type_case_clause::traverse(Traverse* traverse)
3434 {
3435   if (!this->is_default_
3436       && ((traverse->traverse_mask()
3437            & (Traverse::traverse_types | Traverse::traverse_expressions)) != 0)
3438       && Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
3439     return TRAVERSE_EXIT;
3440   if (this->statements_ != NULL)
3441     return this->statements_->traverse(traverse);
3442   return TRAVERSE_CONTINUE;
3443 }
3444
3445 // Lower one clause in a type switch.  Add statements to the block B.
3446 // The type descriptor we are switching on is in DESCRIPTOR_TEMP.
3447 // BREAK_LABEL is the label at the end of the type switch.
3448 // *STMTS_LABEL, if not NULL, is a label to put at the start of the
3449 // statements.
3450
3451 void
3452 Type_case_clauses::Type_case_clause::lower(Block* b,
3453                                            Temporary_statement* descriptor_temp,
3454                                            Unnamed_label* break_label,
3455                                            Unnamed_label** stmts_label) const
3456 {
3457   source_location loc = this->location_;
3458
3459   Unnamed_label* next_case_label = NULL;
3460   if (!this->is_default_)
3461     {
3462       Type* type = this->type_;
3463
3464       Expression* ref = Expression::make_temporary_reference(descriptor_temp,
3465                                                              loc);
3466
3467       Expression* cond;
3468       // The language permits case nil, which is of course a constant
3469       // rather than a type.  It will appear here as an invalid
3470       // forwarding type.
3471       if (type->is_nil_constant_as_type())
3472         cond = Expression::make_binary(OPERATOR_EQEQ, ref,
3473                                        Expression::make_nil(loc),
3474                                        loc);
3475       else
3476         cond = Runtime::make_call((type->interface_type() == NULL
3477                                    ? Runtime::IFACETYPEEQ
3478                                    : Runtime::IFACEI2TP),
3479                                   loc, 2,
3480                                   Expression::make_type_descriptor(type, loc),
3481                                   ref);
3482
3483       Unnamed_label* dest;
3484       if (!this->is_fallthrough_)
3485         {
3486           // if !COND { goto NEXT_CASE_LABEL }
3487           next_case_label = new Unnamed_label(UNKNOWN_LOCATION);
3488           dest = next_case_label;
3489           cond = Expression::make_unary(OPERATOR_NOT, cond, loc);
3490         }
3491       else
3492         {
3493           // if COND { goto STMTS_LABEL }
3494           gcc_assert(stmts_label != NULL);
3495           if (*stmts_label == NULL)
3496             *stmts_label = new Unnamed_label(UNKNOWN_LOCATION);
3497           dest = *stmts_label;
3498         }
3499       Block* then_block = new Block(b, loc);
3500       Statement* s = Statement::make_goto_unnamed_statement(dest, loc);
3501       then_block->add_statement(s);
3502       s = Statement::make_if_statement(cond, then_block, NULL, loc);
3503       b->add_statement(s);
3504     }
3505
3506   if (this->statements_ != NULL
3507       || (!this->is_fallthrough_
3508           && stmts_label != NULL
3509           && *stmts_label != NULL))
3510     {
3511       gcc_assert(!this->is_fallthrough_);
3512       if (stmts_label != NULL && *stmts_label != NULL)
3513         {
3514           gcc_assert(!this->is_default_);
3515           if (this->statements_ != NULL)
3516             (*stmts_label)->set_location(this->statements_->start_location());
3517           Statement* s = Statement::make_unnamed_label_statement(*stmts_label);
3518           b->add_statement(s);
3519           *stmts_label = NULL;
3520         }
3521       if (this->statements_ != NULL)
3522         b->add_statement(Statement::make_block_statement(this->statements_,
3523                                                          loc));
3524     }
3525
3526   if (this->is_fallthrough_)
3527     gcc_assert(next_case_label == NULL);
3528   else
3529     {
3530       source_location gloc = (this->statements_ == NULL
3531                               ? loc
3532                               : this->statements_->end_location());
3533       b->add_statement(Statement::make_goto_unnamed_statement(break_label,
3534                                                               gloc));
3535       if (next_case_label != NULL)
3536         {
3537           Statement* s =
3538             Statement::make_unnamed_label_statement(next_case_label);
3539           b->add_statement(s);
3540         }
3541     }
3542 }
3543
3544 // Class Type_case_clauses.
3545
3546 // Traversal.
3547
3548 int
3549 Type_case_clauses::traverse(Traverse* traverse)
3550 {
3551   for (Type_clauses::iterator p = this->clauses_.begin();
3552        p != this->clauses_.end();
3553        ++p)
3554     {
3555       if (p->traverse(traverse) == TRAVERSE_EXIT)
3556         return TRAVERSE_EXIT;
3557     }
3558   return TRAVERSE_CONTINUE;
3559 }
3560
3561 // Check for duplicate types.
3562
3563 void
3564 Type_case_clauses::check_duplicates() const
3565 {
3566   typedef Unordered_set_hash(const Type*, Type_hash_identical,
3567                              Type_identical) Types_seen;
3568   Types_seen types_seen;
3569   for (Type_clauses::const_iterator p = this->clauses_.begin();
3570        p != this->clauses_.end();
3571        ++p)
3572     {
3573       Type* t = p->type();
3574       if (t == NULL)
3575         continue;
3576       if (t->is_nil_constant_as_type())
3577         t = Type::make_nil_type();
3578       std::pair<Types_seen::iterator, bool> ins = types_seen.insert(t);
3579       if (!ins.second)
3580         error_at(p->location(), "duplicate type in switch");
3581     }
3582 }
3583
3584 // Lower the clauses in a type switch.  Add statements to the block B.
3585 // The type descriptor we are switching on is in DESCRIPTOR_TEMP.
3586 // BREAK_LABEL is the label at the end of the type switch.
3587
3588 void
3589 Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
3590                          Unnamed_label* break_label) const
3591 {
3592   const Type_case_clause* default_case = NULL;
3593
3594   Unnamed_label* stmts_label = NULL;
3595   for (Type_clauses::const_iterator p = this->clauses_.begin();
3596        p != this->clauses_.end();
3597        ++p)
3598     {
3599       if (!p->is_default())
3600         p->lower(b, descriptor_temp, break_label, &stmts_label);
3601       else
3602         {
3603           // We are generating a series of tests, which means that we
3604           // need to move the default case to the end.
3605           default_case = &*p;
3606         }
3607     }
3608   gcc_assert(stmts_label == NULL);
3609
3610   if (default_case != NULL)
3611     default_case->lower(b, descriptor_temp, break_label, NULL);
3612 }
3613
3614 // Class Type_switch_statement.
3615
3616 // Traversal.
3617
3618 int
3619 Type_switch_statement::do_traverse(Traverse* traverse)
3620 {
3621   if (this->var_ == NULL)
3622     {
3623       if (this->traverse_expression(traverse, &this->expr_) == TRAVERSE_EXIT)
3624         return TRAVERSE_EXIT;
3625     }
3626   if (this->clauses_ != NULL)
3627     return this->clauses_->traverse(traverse);
3628   return TRAVERSE_CONTINUE;
3629 }
3630
3631 // Lower a type switch statement to a series of if statements.  The gc
3632 // compiler is able to generate a table in some cases.  However, that
3633 // does not work for us because we may have type descriptors in
3634 // different shared libraries, so we can't compare them with simple
3635 // equality testing.
3636
3637 Statement*
3638 Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
3639 {
3640   const source_location loc = this->location();
3641
3642   if (this->clauses_ != NULL)
3643     this->clauses_->check_duplicates();
3644
3645   Block* b = new Block(enclosing, loc);
3646
3647   Type* val_type = (this->var_ != NULL
3648                     ? this->var_->var_value()->type()
3649                     : this->expr_->type());
3650
3651   // var descriptor_temp DESCRIPTOR_TYPE
3652   Type* descriptor_type = Type::make_type_descriptor_ptr_type();
3653   Temporary_statement* descriptor_temp =
3654     Statement::make_temporary(descriptor_type, NULL, loc);
3655   b->add_statement(descriptor_temp);
3656
3657   if (val_type->interface_type() == NULL)
3658     {
3659       // Doing a type switch on a non-interface type.  Should we issue
3660       // a warning for this case?
3661       Expression* lhs = Expression::make_temporary_reference(descriptor_temp,
3662                                                              loc);
3663       Expression* rhs;
3664       if (val_type->is_nil_type())
3665         rhs = Expression::make_nil(loc);
3666       else
3667         {
3668           if (val_type->is_abstract())
3669             val_type = val_type->make_non_abstract_type();
3670           rhs = Expression::make_type_descriptor(val_type, loc);
3671         }
3672       Statement* s = Statement::make_assignment(lhs, rhs, loc);
3673       b->add_statement(s);
3674     }
3675   else
3676     {
3677       // descriptor_temp = ifacetype(val_temp)
3678       // FIXME: This should be inlined.
3679       bool is_empty = val_type->interface_type()->is_empty();
3680       Expression* ref;
3681       if (this->var_ == NULL)
3682         ref = this->expr_;
3683       else
3684         ref = Expression::make_var_reference(this->var_, loc);
3685       Expression* call = Runtime::make_call((is_empty
3686                                              ? Runtime::EFACETYPE
3687                                              : Runtime::IFACETYPE),
3688                                             loc, 1, ref);
3689       Expression* lhs = Expression::make_temporary_reference(descriptor_temp,
3690                                                              loc);
3691       Statement* s = Statement::make_assignment(lhs, call, loc);
3692       b->add_statement(s);
3693     }
3694
3695   if (this->clauses_ != NULL)
3696     this->clauses_->lower(b, descriptor_temp, this->break_label());
3697
3698   Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
3699   b->add_statement(s);
3700
3701   return Statement::make_block_statement(b, loc);
3702 }
3703
3704 // Return the break label for this type switch statement, creating it
3705 // if necessary.
3706
3707 Unnamed_label*
3708 Type_switch_statement::break_label()
3709 {
3710   if (this->break_label_ == NULL)
3711     this->break_label_ = new Unnamed_label(this->location());
3712   return this->break_label_;
3713 }
3714
3715 // Make a type switch statement.
3716
3717 Type_switch_statement*
3718 Statement::make_type_switch_statement(Named_object* var, Expression* expr,
3719                                       source_location location)
3720 {
3721   return new Type_switch_statement(var, expr, location);
3722 }
3723
3724 // Class Send_statement.
3725
3726 // Traversal.
3727
3728 int
3729 Send_statement::do_traverse(Traverse* traverse)
3730 {
3731   if (this->traverse_expression(traverse, &this->channel_) == TRAVERSE_EXIT)
3732     return TRAVERSE_EXIT;
3733   return this->traverse_expression(traverse, &this->val_);
3734 }
3735
3736 // Determine types.
3737
3738 void
3739 Send_statement::do_determine_types()
3740 {
3741   this->channel_->determine_type_no_context();
3742   Type* type = this->channel_->type();
3743   Type_context context;
3744   if (type->channel_type() != NULL)
3745     context.type = type->channel_type()->element_type();
3746   this->val_->determine_type(&context);
3747 }
3748
3749 // Check types.
3750
3751 void
3752 Send_statement::do_check_types(Gogo*)
3753 {
3754   Type* type = this->channel_->type();
3755   if (type->is_error())
3756     {
3757       this->set_is_error();
3758       return;
3759     }
3760   Channel_type* channel_type = type->channel_type();
3761   if (channel_type == NULL)
3762     {
3763       error_at(this->location(), "left operand of %<<-%> must be channel");
3764       this->set_is_error();
3765       return;
3766     }
3767   Type* element_type = channel_type->element_type();
3768   if (!Type::are_assignable(element_type, this->val_->type(), NULL))
3769     {
3770       this->report_error(_("incompatible types in send"));
3771       return;
3772     }
3773   if (!channel_type->may_send())
3774     {
3775       this->report_error(_("invalid send on receive-only channel"));
3776       return;
3777     }
3778 }
3779
3780 // Get a tree for a send statement.
3781
3782 tree
3783 Send_statement::do_get_tree(Translate_context* context)
3784 {
3785   tree channel = this->channel_->get_tree(context);
3786   tree val = this->val_->get_tree(context);
3787   if (channel == error_mark_node || val == error_mark_node)
3788     return error_mark_node;
3789   Channel_type* channel_type = this->channel_->type()->channel_type();
3790   val = Expression::convert_for_assignment(context,
3791                                            channel_type->element_type(),
3792                                            this->val_->type(),
3793                                            val,
3794                                            this->location());
3795   return Gogo::send_on_channel(channel, val, true, this->for_select_,
3796                                this->location());
3797 }
3798
3799 // Make a send statement.
3800
3801 Send_statement*
3802 Statement::make_send_statement(Expression* channel, Expression* val,
3803                                source_location location)
3804 {
3805   return new Send_statement(channel, val, location);
3806 }
3807
3808 // Class Select_clauses::Select_clause.
3809
3810 // Traversal.
3811
3812 int
3813 Select_clauses::Select_clause::traverse(Traverse* traverse)
3814 {
3815   if (!this->is_lowered_
3816       && (traverse->traverse_mask()
3817           & (Traverse::traverse_types | Traverse::traverse_expressions)) != 0)
3818     {
3819       if (this->channel_ != NULL)
3820         {
3821           if (Expression::traverse(&this->channel_, traverse) == TRAVERSE_EXIT)
3822             return TRAVERSE_EXIT;
3823         }
3824       if (this->val_ != NULL)
3825         {
3826           if (Expression::traverse(&this->val_, traverse) == TRAVERSE_EXIT)
3827             return TRAVERSE_EXIT;
3828         }
3829       if (this->closed_ != NULL)
3830         {
3831           if (Expression::traverse(&this->closed_, traverse) == TRAVERSE_EXIT)
3832             return TRAVERSE_EXIT;
3833         }
3834     }
3835   if (this->statements_ != NULL)
3836     {
3837       if (this->statements_->traverse(traverse) == TRAVERSE_EXIT)
3838         return TRAVERSE_EXIT;
3839     }
3840   return TRAVERSE_CONTINUE;
3841 }
3842
3843 // Lowering.  Here we pull out the channel and the send values, to
3844 // enforce the order of evaluation.  We also add explicit send and
3845 // receive statements to the clauses.
3846
3847 void
3848 Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function,
3849                                      Block* b)
3850 {
3851   if (this->is_default_)
3852     {
3853       gcc_assert(this->channel_ == NULL && this->val_ == NULL);
3854       this->is_lowered_ = true;
3855       return;
3856     }
3857
3858   source_location loc = this->location_;
3859
3860   // Evaluate the channel before the select statement.
3861   Temporary_statement* channel_temp = Statement::make_temporary(NULL,
3862                                                                 this->channel_,
3863                                                                 loc);
3864   b->add_statement(channel_temp);
3865   this->channel_ = Expression::make_temporary_reference(channel_temp, loc);
3866
3867   // If this is a send clause, evaluate the value to send before the
3868   // select statement.
3869   Temporary_statement* val_temp = NULL;
3870   if (this->is_send_ && !this->val_->is_constant())
3871     {
3872       val_temp = Statement::make_temporary(NULL, this->val_, loc);
3873       b->add_statement(val_temp);
3874     }
3875
3876   // Add the send or receive before the rest of the statements if any.
3877   Block *init = new Block(b, loc);
3878   Expression* ref = Expression::make_temporary_reference(channel_temp, loc);
3879   if (this->is_send_)
3880     {
3881       Expression* ref2;
3882       if (val_temp == NULL)
3883         ref2 = this->val_;
3884       else
3885         ref2 = Expression::make_temporary_reference(val_temp, loc);
3886       Send_statement* send = Statement::make_send_statement(ref, ref2, loc);
3887       send->set_for_select();
3888       init->add_statement(send);
3889     }
3890   else if (this->closed_ != NULL && !this->closed_->is_sink_expression())
3891     {
3892       gcc_assert(this->var_ == NULL && this->closedvar_ == NULL);
3893       if (this->val_ == NULL)
3894         this->val_ = Expression::make_sink(loc);
3895       Statement* s = Statement::make_tuple_receive_assignment(this->val_,
3896                                                               this->closed_,
3897                                                               ref, true, loc);
3898       init->add_statement(s);
3899     }
3900   else if (this->closedvar_ != NULL)
3901     {
3902       gcc_assert(this->val_ == NULL);
3903       Expression* val;
3904       if (this->var_ == NULL)
3905         val = Expression::make_sink(loc);
3906       else
3907         val = Expression::make_var_reference(this->var_, loc);
3908       Expression* closed = Expression::make_var_reference(this->closedvar_,
3909                                                           loc);
3910       Statement* s = Statement::make_tuple_receive_assignment(val, closed, ref,
3911                                                               true, loc);
3912       // We have to put S in STATEMENTS_, because that is where the
3913       // variables are declared.
3914       gcc_assert(this->statements_ != NULL);
3915       this->statements_->add_statement_at_front(s);
3916       // We have to lower STATEMENTS_ again, to lower the tuple
3917       // receive assignment we just added.
3918       gogo->lower_block(function, this->statements_);
3919     }
3920   else
3921     {
3922       Receive_expression* recv = Expression::make_receive(ref, loc);
3923       recv->set_for_select();
3924       if (this->val_ != NULL)
3925         {
3926           gcc_assert(this->var_ == NULL);
3927           init->add_statement(Statement::make_assignment(this->val_, recv,
3928                                                          loc));
3929         }
3930       else if (this->var_ != NULL)
3931         {
3932           this->var_->var_value()->set_init(recv);
3933           this->var_->var_value()->clear_type_from_chan_element();
3934         }
3935       else
3936         {
3937           init->add_statement(Statement::make_statement(recv));
3938         }
3939     }
3940
3941   // Lower any statements we just created.
3942   gogo->lower_block(function, init);
3943
3944   if (this->statements_ != NULL)
3945     init->add_statement(Statement::make_block_statement(this->statements_,
3946                                                         loc));
3947
3948   this->statements_ = init;
3949
3950   // Now all references should be handled through the statements, not
3951   // through here.
3952   this->is_lowered_ = true;
3953   this->val_ = NULL;
3954   this->var_ = NULL;
3955 }
3956
3957 // Determine types.
3958
3959 void
3960 Select_clauses::Select_clause::determine_types()
3961 {
3962   gcc_assert(this->is_lowered_);
3963   if (this->statements_ != NULL)
3964     this->statements_->determine_types();
3965 }
3966
3967 // Whether this clause may fall through to the statement which follows
3968 // the overall select statement.
3969
3970 bool
3971 Select_clauses::Select_clause::may_fall_through() const
3972 {
3973   if (this->statements_ == NULL)
3974     return true;
3975   return this->statements_->may_fall_through();
3976 }
3977
3978 // Return a tree for the statements to execute.
3979
3980 tree
3981 Select_clauses::Select_clause::get_statements_tree(Translate_context* context)
3982 {
3983   if (this->statements_ == NULL)
3984     return NULL_TREE;
3985   return this->statements_->get_tree(context);
3986 }
3987
3988 // Class Select_clauses.
3989
3990 // Traversal.
3991
3992 int
3993 Select_clauses::traverse(Traverse* traverse)
3994 {
3995   for (Clauses::iterator p = this->clauses_.begin();
3996        p != this->clauses_.end();
3997        ++p)
3998     {
3999       if (p->traverse(traverse) == TRAVERSE_EXIT)
4000         return TRAVERSE_EXIT;
4001     }
4002   return TRAVERSE_CONTINUE;
4003 }
4004
4005 // Lowering.  Here we pull out the channel and the send values, to
4006 // enforce the order of evaluation.  We also add explicit send and
4007 // receive statements to the clauses.
4008
4009 void
4010 Select_clauses::lower(Gogo* gogo, Named_object* function, Block* b)
4011 {
4012   for (Clauses::iterator p = this->clauses_.begin();
4013        p != this->clauses_.end();
4014        ++p)
4015     p->lower(gogo, function, b);
4016 }
4017
4018 // Determine types.
4019
4020 void
4021 Select_clauses::determine_types()
4022 {
4023   for (Clauses::iterator p = this->clauses_.begin();
4024        p != this->clauses_.end();
4025        ++p)
4026     p->determine_types();
4027 }
4028
4029 // Return whether these select clauses fall through to the statement
4030 // following the overall select statement.
4031
4032 bool
4033 Select_clauses::may_fall_through() const
4034 {
4035   for (Clauses::const_iterator p = this->clauses_.begin();
4036        p != this->clauses_.end();
4037        ++p)
4038     if (p->may_fall_through())
4039       return true;
4040   return false;
4041 }
4042
4043 // Return a tree.  We build a call to
4044 //   size_t __go_select(size_t count, _Bool has_default,
4045 //                      channel* channels, _Bool* is_send)
4046 //
4047 // There are COUNT entries in the CHANNELS and IS_SEND arrays.  The
4048 // value in the IS_SEND array is true for send, false for receive.
4049 // __go_select returns an integer from 0 to COUNT, inclusive.  A
4050 // return of 0 means that the default case should be run; this only
4051 // happens if HAS_DEFAULT is non-zero.  Otherwise the number indicates
4052 // the case to run.
4053
4054 // FIXME: This doesn't handle channels which send interface types
4055 // where the receiver has a static type which matches that interface.
4056
4057 tree
4058 Select_clauses::get_tree(Translate_context* context,
4059                          Unnamed_label *break_label,
4060                          source_location location)
4061 {
4062   size_t count = this->clauses_.size();
4063   VEC(constructor_elt, gc)* chan_init = VEC_alloc(constructor_elt, gc, count);
4064   VEC(constructor_elt, gc)* is_send_init = VEC_alloc(constructor_elt, gc,
4065                                                      count);
4066   Select_clause* default_clause = NULL;
4067   tree final_stmt_list = NULL_TREE;
4068   tree channel_type_tree = NULL_TREE;
4069
4070   size_t i = 0;
4071   for (Clauses::iterator p = this->clauses_.begin();
4072        p != this->clauses_.end();
4073        ++p)
4074     {
4075       if (p->is_default())
4076         {
4077           default_clause = &*p;
4078           --count;
4079           continue;
4080         }
4081
4082       if (p->channel()->type()->channel_type() == NULL)
4083         {
4084           // We should have given an error in the send or receive
4085           // statement we created via lowering.
4086           gcc_assert(saw_errors());
4087           return error_mark_node;
4088         }
4089
4090       tree channel_tree = p->channel()->get_tree(context);
4091       if (channel_tree == error_mark_node)
4092         return error_mark_node;
4093       channel_type_tree = TREE_TYPE(channel_tree);
4094
4095       constructor_elt* elt = VEC_quick_push(constructor_elt, chan_init, NULL);
4096       elt->index = build_int_cstu(sizetype, i);
4097       elt->value = channel_tree;
4098
4099       elt = VEC_quick_push(constructor_elt, is_send_init, NULL);
4100       elt->index = build_int_cstu(sizetype, i);
4101       elt->value = p->is_send() ? boolean_true_node : boolean_false_node;
4102
4103       ++i;
4104     }
4105   gcc_assert(i == count);
4106
4107   if (i == 0 && default_clause != NULL)
4108     {
4109       // There is only a default clause.
4110       gcc_assert(final_stmt_list == NULL_TREE);
4111       tree stmt_list = NULL_TREE;
4112       append_to_statement_list(default_clause->get_statements_tree(context),
4113                                &stmt_list);
4114       Bstatement* ldef = break_label->get_definition(context);
4115       append_to_statement_list(stat_to_tree(ldef), &stmt_list);
4116       return stmt_list;
4117     }
4118
4119   tree pointer_chan_type_tree = (channel_type_tree == NULL_TREE
4120                                  ? ptr_type_node
4121                                  : build_pointer_type(channel_type_tree));
4122   tree chans_arg;
4123   tree pointer_boolean_type_tree = build_pointer_type(boolean_type_node);
4124   tree is_sends_arg;
4125
4126   if (i == 0)
4127     {
4128       chans_arg = fold_convert_loc(location, pointer_chan_type_tree,
4129                                    null_pointer_node);
4130       is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree,
4131                                       null_pointer_node);
4132     }
4133   else
4134     {
4135       tree index_type_tree = build_index_type(size_int(count - 1));
4136       tree chan_array_type_tree = build_array_type(channel_type_tree,
4137                                                    index_type_tree);
4138       tree chan_constructor = build_constructor(chan_array_type_tree,
4139                                                 chan_init);
4140       tree chan_var = create_tmp_var(chan_array_type_tree, "CHAN");
4141       DECL_IGNORED_P(chan_var) = 0;
4142       DECL_INITIAL(chan_var) = chan_constructor;
4143       DECL_SOURCE_LOCATION(chan_var) = location;
4144       TREE_ADDRESSABLE(chan_var) = 1;
4145       tree decl_expr = build1(DECL_EXPR, void_type_node, chan_var);
4146       SET_EXPR_LOCATION(decl_expr, location);
4147       append_to_statement_list(decl_expr, &final_stmt_list);
4148
4149       tree is_send_array_type_tree = build_array_type(boolean_type_node,
4150                                                       index_type_tree);
4151       tree is_send_constructor = build_constructor(is_send_array_type_tree,
4152                                                    is_send_init);
4153       tree is_send_var = create_tmp_var(is_send_array_type_tree, "ISSEND");
4154       DECL_IGNORED_P(is_send_var) = 0;
4155       DECL_INITIAL(is_send_var) = is_send_constructor;
4156       DECL_SOURCE_LOCATION(is_send_var) = location;
4157       TREE_ADDRESSABLE(is_send_var) = 1;
4158       decl_expr = build1(DECL_EXPR, void_type_node, is_send_var);
4159       SET_EXPR_LOCATION(decl_expr, location);
4160       append_to_statement_list(decl_expr, &final_stmt_list);
4161
4162       chans_arg = fold_convert_loc(location, pointer_chan_type_tree,
4163                                    build_fold_addr_expr_loc(location,
4164                                                             chan_var));
4165       is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree,
4166                                       build_fold_addr_expr_loc(location,
4167                                                                is_send_var));
4168     }
4169
4170   static tree select_fndecl;
4171   tree call = Gogo::call_builtin(&select_fndecl,
4172                                  location,
4173                                  "__go_select",
4174                                  4,
4175                                  sizetype,
4176                                  sizetype,
4177                                  size_int(count),
4178                                  boolean_type_node,
4179                                  (default_clause == NULL
4180                                   ? boolean_false_node
4181                                   : boolean_true_node),
4182                                  pointer_chan_type_tree,
4183                                  chans_arg,
4184                                  pointer_boolean_type_tree,
4185                                  is_sends_arg);
4186   if (call == error_mark_node)
4187     return error_mark_node;
4188
4189   tree stmt_list = NULL_TREE;
4190
4191   if (default_clause != NULL)
4192     this->add_clause_tree(context, 0, default_clause, break_label, &stmt_list);
4193
4194   i = 1;
4195   for (Clauses::iterator p = this->clauses_.begin();
4196        p != this->clauses_.end();
4197        ++p)
4198     {
4199       if (!p->is_default())
4200         {
4201           this->add_clause_tree(context, i, &*p, break_label, &stmt_list);
4202           ++i;
4203         }
4204     }
4205
4206   Bstatement* ldef = break_label->get_definition(context);
4207   append_to_statement_list(stat_to_tree(ldef), &stmt_list);
4208
4209   tree switch_stmt = build3(SWITCH_EXPR, sizetype, call, stmt_list, NULL_TREE);
4210   SET_EXPR_LOCATION(switch_stmt, location);
4211   append_to_statement_list(switch_stmt, &final_stmt_list);
4212
4213   return final_stmt_list;
4214 }
4215
4216 // Add the tree for CLAUSE to STMT_LIST.
4217
4218 void
4219 Select_clauses::add_clause_tree(Translate_context* context, int case_index,
4220                                 Select_clause* clause,
4221                                 Unnamed_label* bottom_label, tree* stmt_list)
4222 {
4223   tree label = create_artificial_label(clause->location());
4224   append_to_statement_list(build3(CASE_LABEL_EXPR, void_type_node,
4225                                   build_int_cst(sizetype, case_index),
4226                                   NULL_TREE, label),
4227                            stmt_list);
4228   append_to_statement_list(clause->get_statements_tree(context), stmt_list);
4229   source_location gloc = (clause->statements() == NULL
4230                           ? clause->location()
4231                           : clause->statements()->end_location());
4232   Bstatement* g = bottom_label->get_goto(context, gloc);
4233   append_to_statement_list(stat_to_tree(g), stmt_list);
4234 }
4235
4236 // Class Select_statement.
4237
4238 // Return the break label for this switch statement, creating it if
4239 // necessary.
4240
4241 Unnamed_label*
4242 Select_statement::break_label()
4243 {
4244   if (this->break_label_ == NULL)
4245     this->break_label_ = new Unnamed_label(this->location());
4246   return this->break_label_;
4247 }
4248
4249 // Lower a select statement.  This will still return a select
4250 // statement, but it will be modified to implement the order of
4251 // evaluation rules, and to include the send and receive statements as
4252 // explicit statements in the clauses.
4253
4254 Statement*
4255 Select_statement::do_lower(Gogo* gogo, Named_object* function,
4256                            Block* enclosing)
4257 {
4258   if (this->is_lowered_)
4259     return this;
4260   Block* b = new Block(enclosing, this->location());
4261   this->clauses_->lower(gogo, function, b);
4262   this->is_lowered_ = true;
4263   b->add_statement(this);
4264   return Statement::make_block_statement(b, this->location());
4265 }
4266
4267 // Return the tree for a select statement.
4268
4269 tree
4270 Select_statement::do_get_tree(Translate_context* context)
4271 {
4272   return this->clauses_->get_tree(context, this->break_label(),
4273                                   this->location());
4274 }
4275
4276 // Make a select statement.
4277
4278 Select_statement*
4279 Statement::make_select_statement(source_location location)
4280 {
4281   return new Select_statement(location);
4282 }
4283
4284 // Class For_statement.
4285
4286 // Traversal.
4287
4288 int
4289 For_statement::do_traverse(Traverse* traverse)
4290 {
4291   if (this->init_ != NULL)
4292     {
4293       if (this->init_->traverse(traverse) == TRAVERSE_EXIT)
4294         return TRAVERSE_EXIT;
4295     }
4296   if (this->cond_ != NULL)
4297     {
4298       if (this->traverse_expression(traverse, &this->cond_) == TRAVERSE_EXIT)
4299         return TRAVERSE_EXIT;
4300     }
4301   if (this->post_ != NULL)
4302     {
4303       if (this->post_->traverse(traverse) == TRAVERSE_EXIT)
4304         return TRAVERSE_EXIT;
4305     }
4306   return this->statements_->traverse(traverse);
4307 }
4308
4309 // Lower a For_statement into if statements and gotos.  Getting rid of
4310 // complex statements make it easier to handle garbage collection.
4311
4312 Statement*
4313 For_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
4314 {
4315   Statement* s;
4316   source_location loc = this->location();
4317
4318   Block* b = new Block(enclosing, this->location());
4319   if (this->init_ != NULL)
4320     {
4321       s = Statement::make_block_statement(this->init_,
4322                                           this->init_->start_location());
4323       b->add_statement(s);
4324     }
4325
4326   Unnamed_label* entry = NULL;
4327   if (this->cond_ != NULL)
4328     {
4329       entry = new Unnamed_label(this->location());
4330       b->add_statement(Statement::make_goto_unnamed_statement(entry, loc));
4331     }
4332
4333   Unnamed_label* top = new Unnamed_label(this->location());
4334   b->add_statement(Statement::make_unnamed_label_statement(top));
4335
4336   s = Statement::make_block_statement(this->statements_,
4337                                       this->statements_->start_location());
4338   b->add_statement(s);
4339
4340   source_location end_loc = this->statements_->end_location();
4341
4342   Unnamed_label* cont = this->continue_label_;
4343   if (cont != NULL)
4344     b->add_statement(Statement::make_unnamed_label_statement(cont));
4345
4346   if (this->post_ != NULL)
4347     {
4348       s = Statement::make_block_statement(this->post_,
4349                                           this->post_->start_location());
4350       b->add_statement(s);
4351       end_loc = this->post_->end_location();
4352     }
4353
4354   if (this->cond_ == NULL)
4355     b->add_statement(Statement::make_goto_unnamed_statement(top, end_loc));
4356   else
4357     {
4358       b->add_statement(Statement::make_unnamed_label_statement(entry));
4359
4360       source_location cond_loc = this->cond_->location();
4361       Block* then_block = new Block(b, cond_loc);
4362       s = Statement::make_goto_unnamed_statement(top, cond_loc);
4363       then_block->add_statement(s);
4364
4365       s = Statement::make_if_statement(this->cond_, then_block, NULL, cond_loc);
4366       b->add_statement(s);
4367     }
4368
4369   Unnamed_label* brk = this->break_label_;
4370   if (brk != NULL)
4371     b->add_statement(Statement::make_unnamed_label_statement(brk));
4372
4373   b->set_end_location(end_loc);
4374
4375   return Statement::make_block_statement(b, loc);
4376 }
4377
4378 // Return the break label, creating it if necessary.
4379
4380 Unnamed_label*
4381 For_statement::break_label()
4382 {
4383   if (this->break_label_ == NULL)
4384     this->break_label_ = new Unnamed_label(this->location());
4385   return this->break_label_;
4386 }
4387
4388 // Return the continue LABEL_EXPR.
4389
4390 Unnamed_label*
4391 For_statement::continue_label()
4392 {
4393   if (this->continue_label_ == NULL)
4394     this->continue_label_ = new Unnamed_label(this->location());
4395   return this->continue_label_;
4396 }
4397
4398 // Set the break and continue labels a for statement.  This is used
4399 // when lowering a for range statement.
4400
4401 void
4402 For_statement::set_break_continue_labels(Unnamed_label* break_label,
4403                                          Unnamed_label* continue_label)
4404 {
4405   gcc_assert(this->break_label_ == NULL && this->continue_label_ == NULL);
4406   this->break_label_ = break_label;
4407   this->continue_label_ = continue_label;
4408 }
4409
4410 // Make a for statement.
4411
4412 For_statement*
4413 Statement::make_for_statement(Block* init, Expression* cond, Block* post,
4414                               source_location location)
4415 {
4416   return new For_statement(init, cond, post, location);
4417 }
4418
4419 // Class For_range_statement.
4420
4421 // Traversal.
4422
4423 int
4424 For_range_statement::do_traverse(Traverse* traverse)
4425 {
4426   if (this->traverse_expression(traverse, &this->index_var_) == TRAVERSE_EXIT)
4427     return TRAVERSE_EXIT;
4428   if (this->value_var_ != NULL)
4429     {
4430       if (this->traverse_expression(traverse, &this->value_var_)
4431           == TRAVERSE_EXIT)
4432         return TRAVERSE_EXIT;
4433     }
4434   if (this->traverse_expression(traverse, &this->range_) == TRAVERSE_EXIT)
4435     return TRAVERSE_EXIT;
4436   return this->statements_->traverse(traverse);
4437 }
4438
4439 // Lower a for range statement.  For simplicity we lower this into a
4440 // for statement, which will then be lowered in turn to goto
4441 // statements.
4442
4443 Statement*
4444 For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing)
4445 {
4446   Type* range_type = this->range_->type();
4447   if (range_type->points_to() != NULL
4448       && range_type->points_to()->array_type() != NULL
4449       && !range_type->points_to()->is_open_array_type())
4450     range_type = range_type->points_to();
4451
4452   Type* index_type;
4453   Type* value_type = NULL;
4454   if (range_type->array_type() != NULL)
4455     {
4456       index_type = Type::lookup_integer_type("int");
4457       value_type = range_type->array_type()->element_type();
4458     }
4459   else if (range_type->is_string_type())
4460     {
4461       index_type = Type::lookup_integer_type("int");
4462       value_type = index_type;
4463     }
4464   else if (range_type->map_type() != NULL)
4465     {
4466       index_type = range_type->map_type()->key_type();
4467       value_type = range_type->map_type()->val_type();
4468     }
4469   else if (range_type->channel_type() != NULL)
4470     {
4471       index_type = range_type->channel_type()->element_type();
4472       if (this->value_var_ != NULL)
4473         {
4474           if (!this->value_var_->type()->is_error())
4475             this->report_error(_("too many variables for range clause "
4476                                  "with channel"));
4477           return Statement::make_error_statement(this->location());
4478         }
4479     }
4480   else
4481     {
4482       this->report_error(_("range clause must have "
4483                            "array, slice, setring, map, or channel type"));
4484       return Statement::make_error_statement(this->location());
4485     }
4486
4487   source_location loc = this->location();
4488   Block* temp_block = new Block(enclosing, loc);
4489
4490   Named_object* range_object = NULL;
4491   Temporary_statement* range_temp = NULL;
4492   Var_expression* ve = this->range_->var_expression();
4493   if (ve != NULL)
4494     range_object = ve->named_object();
4495   else
4496     {
4497       range_temp = Statement::make_temporary(NULL, this->range_, loc);
4498       temp_block->add_statement(range_temp);
4499     }
4500
4501   Temporary_statement* index_temp = Statement::make_temporary(index_type,
4502                                                               NULL, loc);
4503   temp_block->add_statement(index_temp);
4504
4505   Temporary_statement* value_temp = NULL;
4506   if (this->value_var_ != NULL)
4507     {
4508       value_temp = Statement::make_temporary(value_type, NULL, loc);
4509       temp_block->add_statement(value_temp);
4510     }
4511
4512   Block* body = new Block(temp_block, loc);
4513
4514   Block* init;
4515   Expression* cond;
4516   Block* iter_init;
4517   Block* post;
4518
4519   // Arrange to do a loop appropriate for the type.  We will produce
4520   //   for INIT ; COND ; POST {
4521   //           ITER_INIT
4522   //           INDEX = INDEX_TEMP
4523   //           VALUE = VALUE_TEMP // If there is a value
4524   //           original statements
4525   //   }
4526
4527   if (range_type->array_type() != NULL)
4528     this->lower_range_array(gogo, temp_block, body, range_object, range_temp,
4529                             index_temp, value_temp, &init, &cond, &iter_init,
4530                             &post);
4531   else if (range_type->is_string_type())
4532     this->lower_range_string(gogo, temp_block, body, range_object, range_temp,
4533                              index_temp, value_temp, &init, &cond, &iter_init,
4534                              &post);
4535   else if (range_type->map_type() != NULL)
4536     this->lower_range_map(gogo, temp_block, body, range_object, range_temp,
4537                           index_temp, value_temp, &init, &cond, &iter_init,
4538                           &post);
4539   else if (range_type->channel_type() != NULL)
4540     this->lower_range_channel(gogo, temp_block, body, range_object, range_temp,
4541                               index_temp, value_temp, &init, &cond, &iter_init,
4542                               &post);
4543   else
4544     gcc_unreachable();
4545
4546   if (iter_init != NULL)
4547     body->add_statement(Statement::make_block_statement(iter_init, loc));
4548
4549   Statement* assign;
4550   Expression* index_ref = Expression::make_temporary_reference(index_temp, loc);
4551   if (this->value_var_ == NULL)
4552     {
4553       assign = Statement::make_assignment(this->index_var_, index_ref, loc);
4554     }
4555   else
4556     {
4557       Expression_list* lhs = new Expression_list();
4558       lhs->push_back(this->index_var_);
4559       lhs->push_back(this->value_var_);
4560
4561       Expression_list* rhs = new Expression_list();
4562       rhs->push_back(index_ref);
4563       rhs->push_back(Expression::make_temporary_reference(value_temp, loc));
4564
4565       assign = Statement::make_tuple_assignment(lhs, rhs, loc);
4566     }
4567   body->add_statement(assign);
4568
4569   body->add_statement(Statement::make_block_statement(this->statements_, loc));
4570
4571   body->set_end_location(this->statements_->end_location());
4572
4573   For_statement* loop = Statement::make_for_statement(init, cond, post,
4574                                                       this->location());
4575   loop->add_statements(body);
4576   loop->set_break_continue_labels(this->break_label_, this->continue_label_);
4577
4578   temp_block->add_statement(loop);
4579
4580   return Statement::make_block_statement(temp_block, loc);
4581 }
4582
4583 // Return a reference to the range, which may be in RANGE_OBJECT or in
4584 // RANGE_TEMP.
4585
4586 Expression*
4587 For_range_statement::make_range_ref(Named_object* range_object,
4588                                     Temporary_statement* range_temp,
4589                                     source_location loc)
4590 {
4591   if (range_object != NULL)
4592     return Expression::make_var_reference(range_object, loc);
4593   else
4594     return Expression::make_temporary_reference(range_temp, loc);
4595 }
4596
4597 // Return a call to the predeclared function FUNCNAME passing a
4598 // reference to the temporary variable ARG.
4599
4600 Expression*
4601 For_range_statement::call_builtin(Gogo* gogo, const char* funcname,
4602                                   Expression* arg,
4603                                   source_location loc)
4604 {
4605   Named_object* no = gogo->lookup_global(funcname);
4606   gcc_assert(no != NULL && no->is_function_declaration());
4607   Expression* func = Expression::make_func_reference(no, NULL, loc);
4608   Expression_list* params = new Expression_list();
4609   params->push_back(arg);
4610   return Expression::make_call(func, params, false, loc);
4611 }
4612
4613 // Lower a for range over an array or slice.
4614
4615 void
4616 For_range_statement::lower_range_array(Gogo* gogo,
4617                                        Block* enclosing,
4618                                        Block* body_block,
4619                                        Named_object* range_object,
4620                                        Temporary_statement* range_temp,
4621                                        Temporary_statement* index_temp,
4622                                        Temporary_statement* value_temp,
4623                                        Block** pinit,
4624                                        Expression** pcond,
4625                                        Block** piter_init,
4626                                        Block** ppost)
4627 {
4628   source_location loc = this->location();
4629
4630   // The loop we generate:
4631   //   len_temp := len(range)
4632   //   for index_temp = 0; index_temp < len_temp; index_temp++ {
4633   //           value_temp = range[index_temp]
4634   //           index = index_temp
4635   //           value = value_temp
4636   //           original body
4637   //   }
4638
4639   // Set *PINIT to
4640   //   var len_temp int
4641   //   len_temp = len(range)
4642   //   index_temp = 0
4643
4644   Block* init = new Block(enclosing, loc);
4645
4646   Expression* ref = this->make_range_ref(range_object, range_temp, loc);
4647   Expression* len_call = this->call_builtin(gogo, "len", ref, loc);
4648   Temporary_statement* len_temp = Statement::make_temporary(index_temp->type(),
4649                                                             len_call, loc);
4650   init->add_statement(len_temp);
4651
4652   mpz_t zval;
4653   mpz_init_set_ui(zval, 0UL);
4654   Expression* zexpr = Expression::make_integer(&zval, NULL, loc);
4655   mpz_clear(zval);
4656
4657   ref = Expression::make_temporary_reference(index_temp, loc);
4658   Statement* s = Statement::make_assignment(ref, zexpr, loc);
4659   init->add_statement(s);
4660
4661   *pinit = init;
4662
4663   // Set *PCOND to
4664   //   index_temp < len_temp
4665
4666   ref = Expression::make_temporary_reference(index_temp, loc);
4667   Expression* ref2 = Expression::make_temporary_reference(len_temp, loc);
4668   Expression* lt = Expression::make_binary(OPERATOR_LT, ref, ref2, loc);
4669
4670   *pcond = lt;
4671
4672   // Set *PITER_INIT to
4673   //   value_temp = range[index_temp]
4674
4675   Block* iter_init = NULL;
4676   if (value_temp != NULL)
4677     {
4678       iter_init = new Block(body_block, loc);
4679
4680       ref = this->make_range_ref(range_object, range_temp, loc);
4681       Expression* ref2 = Expression::make_temporary_reference(index_temp, loc);
4682       Expression* index = Expression::make_index(ref, ref2, NULL, loc);
4683
4684       ref = Expression::make_temporary_reference(value_temp, loc);
4685       s = Statement::make_assignment(ref, index, loc);
4686
4687       iter_init->add_statement(s);
4688     }
4689   *piter_init = iter_init;
4690
4691   // Set *PPOST to
4692   //   index_temp++
4693
4694   Block* post = new Block(enclosing, loc);
4695   ref = Expression::make_temporary_reference(index_temp, loc);
4696   s = Statement::make_inc_statement(ref);
4697   post->add_statement(s);
4698   *ppost = post;
4699 }
4700
4701 // Lower a for range over a string.
4702
4703 void
4704 For_range_statement::lower_range_string(Gogo*,
4705                                         Block* enclosing,
4706                                         Block* body_block,
4707                                         Named_object* range_object,
4708                                         Temporary_statement* range_temp,
4709                                         Temporary_statement* index_temp,
4710                                         Temporary_statement* value_temp,
4711                                         Block** pinit,
4712                                         Expression** pcond,
4713                                         Block** piter_init,
4714                                         Block** ppost)
4715 {
4716   source_location loc = this->location();
4717
4718   // The loop we generate:
4719   //   var next_index_temp int
4720   //   for index_temp = 0; ; index_temp = next_index_temp {
4721   //           next_index_temp, value_temp = stringiter2(range, index_temp)
4722   //           if next_index_temp == 0 {
4723   //                   break
4724   //           }
4725   //           index = index_temp
4726   //           value = value_temp
4727   //           original body
4728   //   }
4729
4730   // Set *PINIT to
4731   //   var next_index_temp int
4732   //   index_temp = 0
4733
4734   Block* init = new Block(enclosing, loc);
4735
4736   Temporary_statement* next_index_temp =
4737     Statement::make_temporary(index_temp->type(), NULL, loc);
4738   init->add_statement(next_index_temp);
4739
4740   mpz_t zval;
4741   mpz_init_set_ui(zval, 0UL);
4742   Expression* zexpr = Expression::make_integer(&zval, NULL, loc);
4743
4744   Expression* ref = Expression::make_temporary_reference(index_temp, loc);
4745   Statement* s = Statement::make_assignment(ref, zexpr, loc);
4746
4747   init->add_statement(s);
4748   *pinit = init;
4749
4750   // The loop has no condition.
4751
4752   *pcond = NULL;
4753
4754   // Set *PITER_INIT to
4755   //   next_index_temp = runtime.stringiter(range, index_temp)
4756   // or
4757   //   next_index_temp, value_temp = runtime.stringiter2(range, index_temp)
4758   // followed by
4759   //   if next_index_temp == 0 {
4760   //           break
4761   //   }
4762
4763   Block* iter_init = new Block(body_block, loc);
4764
4765   Expression* p1 = this->make_range_ref(range_object, range_temp, loc);
4766   Expression* p2 = Expression::make_temporary_reference(index_temp, loc);
4767   Call_expression* call = Runtime::make_call((value_temp == NULL
4768                                               ? Runtime::STRINGITER
4769                                               : Runtime::STRINGITER2),
4770                                              loc, 2, p1, p2);
4771
4772   if (value_temp == NULL)
4773     {
4774       ref = Expression::make_temporary_reference(next_index_temp, loc);
4775       s = Statement::make_assignment(ref, call, loc);
4776     }
4777   else
4778     {
4779       Expression_list* lhs = new Expression_list();
4780       lhs->push_back(Expression::make_temporary_reference(next_index_temp,
4781                                                           loc));
4782       lhs->push_back(Expression::make_temporary_reference(value_temp, loc));
4783
4784       Expression_list* rhs = new Expression_list();
4785       rhs->push_back(Expression::make_call_result(call, 0));
4786       rhs->push_back(Expression::make_call_result(call, 1));
4787
4788       s = Statement::make_tuple_assignment(lhs, rhs, loc);
4789     }
4790   iter_init->add_statement(s);
4791
4792   ref = Expression::make_temporary_reference(next_index_temp, loc);
4793   zexpr = Expression::make_integer(&zval, NULL, loc);
4794   mpz_clear(zval);
4795   Expression* equals = Expression::make_binary(OPERATOR_EQEQ, ref, zexpr, loc);
4796
4797   Block* then_block = new Block(iter_init, loc);
4798   s = Statement::make_break_statement(this->break_label(), loc);
4799   then_block->add_statement(s);
4800
4801   s = Statement::make_if_statement(equals, then_block, NULL, loc);
4802   iter_init->add_statement(s);
4803
4804   *piter_init = iter_init;
4805
4806   // Set *PPOST to
4807   //   index_temp = next_index_temp
4808
4809   Block* post = new Block(enclosing, loc);
4810
4811   Expression* lhs = Expression::make_temporary_reference(index_temp, loc);
4812   Expression* rhs = Expression::make_temporary_reference(next_index_temp, loc);
4813   s = Statement::make_assignment(lhs, rhs, loc);
4814
4815   post->add_statement(s);
4816   *ppost = post;
4817 }
4818
4819 // Lower a for range over a map.
4820
4821 void
4822 For_range_statement::lower_range_map(Gogo*,
4823                                      Block* enclosing,
4824                                      Block* body_block,
4825                                      Named_object* range_object,
4826                                      Temporary_statement* range_temp,
4827                                      Temporary_statement* index_temp,
4828                                      Temporary_statement* value_temp,
4829                                      Block** pinit,
4830                                      Expression** pcond,
4831                                      Block** piter_init,
4832                                      Block** ppost)
4833 {
4834   source_location loc = this->location();
4835
4836   // The runtime uses a struct to handle ranges over a map.  The
4837   // struct is four pointers long.  The first pointer is NULL when we
4838   // have completed the iteration.
4839
4840   // The loop we generate:
4841   //   var hiter map_iteration_struct
4842   //   for mapiterinit(range, &hiter); hiter[0] != nil; mapiternext(&hiter) {
4843   //           mapiter2(hiter, &index_temp, &value_temp)
4844   //           index = index_temp
4845   //           value = value_temp
4846   //           original body
4847   //   }
4848
4849   // Set *PINIT to
4850   //   var hiter map_iteration_struct
4851   //   runtime.mapiterinit(range, &hiter)
4852
4853   Block* init = new Block(enclosing, loc);
4854
4855   Type* map_iteration_type = Runtime::map_iteration_type();
4856   Temporary_statement* hiter = Statement::make_temporary(map_iteration_type,
4857                                                          NULL, loc);
4858   init->add_statement(hiter);
4859
4860   Expression* p1 = this->make_range_ref(range_object, range_temp, loc);
4861   Expression* ref = Expression::make_temporary_reference(hiter, loc);
4862   Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc);
4863   Expression* call = Runtime::make_call(Runtime::MAPITERINIT, loc, 2, p1, p2);
4864   init->add_statement(Statement::make_statement(call));
4865
4866   *pinit = init;
4867
4868   // Set *PCOND to
4869   //   hiter[0] != nil
4870
4871   ref = Expression::make_temporary_reference(hiter, loc);
4872
4873   mpz_t zval;
4874   mpz_init_set_ui(zval, 0UL);
4875   Expression* zexpr = Expression::make_integer(&zval, NULL, loc);
4876   mpz_clear(zval);
4877
4878   Expression* index = Expression::make_index(ref, zexpr, NULL, loc);
4879
4880   Expression* ne = Expression::make_binary(OPERATOR_NOTEQ, index,
4881                                            Expression::make_nil(loc),
4882                                            loc);
4883
4884   *pcond = ne;
4885
4886   // Set *PITER_INIT to
4887   //   mapiter1(hiter, &index_temp)
4888   // or
4889   //   mapiter2(hiter, &index_temp, &value_temp)
4890
4891   Block* iter_init = new Block(body_block, loc);
4892
4893   ref = Expression::make_temporary_reference(hiter, loc);
4894   p1 = Expression::make_unary(OPERATOR_AND, ref, loc);
4895   ref = Expression::make_temporary_reference(index_temp, loc);
4896   p2 = Expression::make_unary(OPERATOR_AND, ref, loc);
4897   if (value_temp == NULL)
4898     call = Runtime::make_call(Runtime::MAPITER1, loc, 2, p1, p2);
4899   else
4900     {
4901       ref = Expression::make_temporary_reference(value_temp, loc);
4902       Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc);
4903       call = Runtime::make_call(Runtime::MAPITER2, loc, 3, p1, p2, p3);
4904     }
4905   iter_init->add_statement(Statement::make_statement(call));
4906
4907   *piter_init = iter_init;
4908
4909   // Set *PPOST to
4910   //   mapiternext(&hiter)
4911
4912   Block* post = new Block(enclosing, loc);
4913
4914   ref = Expression::make_temporary_reference(hiter, loc);
4915   p1 = Expression::make_unary(OPERATOR_AND, ref, loc);
4916   call = Runtime::make_call(Runtime::MAPITERNEXT, loc, 1, p1);
4917   post->add_statement(Statement::make_statement(call));
4918
4919   *ppost = post;
4920 }
4921
4922 // Lower a for range over a channel.
4923
4924 void
4925 For_range_statement::lower_range_channel(Gogo*,
4926                                          Block*,
4927                                          Block* body_block,
4928                                          Named_object* range_object,
4929                                          Temporary_statement* range_temp,
4930                                          Temporary_statement* index_temp,
4931                                          Temporary_statement* value_temp,
4932                                          Block** pinit,
4933                                          Expression** pcond,
4934                                          Block** piter_init,
4935                                          Block** ppost)
4936 {
4937   gcc_assert(value_temp == NULL);
4938
4939   source_location loc = this->location();
4940
4941   // The loop we generate:
4942   //   for {
4943   //           index_temp, ok_temp = <-range
4944   //           if !ok_temp {
4945   //                   break
4946   //           }
4947   //           index = index_temp
4948   //           original body
4949   //   }
4950
4951   // We have no initialization code, no condition, and no post code.
4952
4953   *pinit = NULL;
4954   *pcond = NULL;
4955   *ppost = NULL;
4956
4957   // Set *PITER_INIT to
4958   //   index_temp, ok_temp = <-range
4959   //   if !ok_temp {
4960   //           break
4961   //   }
4962
4963   Block* iter_init = new Block(body_block, loc);
4964
4965   Temporary_statement* ok_temp =
4966     Statement::make_temporary(Type::lookup_bool_type(), NULL, loc);
4967   iter_init->add_statement(ok_temp);
4968
4969   Expression* cref = this->make_range_ref(range_object, range_temp, loc);
4970   Expression* iref = Expression::make_temporary_reference(index_temp, loc);
4971   Expression* oref = Expression::make_temporary_reference(ok_temp, loc);
4972   Statement* s = Statement::make_tuple_receive_assignment(iref, oref, cref,
4973                                                           false, loc);
4974   iter_init->add_statement(s);
4975
4976   Block* then_block = new Block(iter_init, loc);
4977   s = Statement::make_break_statement(this->break_label(), loc);
4978   then_block->add_statement(s);
4979
4980   oref = Expression::make_temporary_reference(ok_temp, loc);
4981   Expression* cond = Expression::make_unary(OPERATOR_NOT, oref, loc);
4982   s = Statement::make_if_statement(cond, then_block, NULL, loc);
4983   iter_init->add_statement(s);
4984
4985   *piter_init = iter_init;
4986 }
4987
4988 // Return the break LABEL_EXPR.
4989
4990 Unnamed_label*
4991 For_range_statement::break_label()
4992 {
4993   if (this->break_label_ == NULL)
4994     this->break_label_ = new Unnamed_label(this->location());
4995   return this->break_label_;
4996 }
4997
4998 // Return the continue LABEL_EXPR.
4999
5000 Unnamed_label*
5001 For_range_statement::continue_label()
5002 {
5003   if (this->continue_label_ == NULL)
5004     this->continue_label_ = new Unnamed_label(this->location());
5005   return this->continue_label_;
5006 }
5007
5008 // Make a for statement with a range clause.
5009
5010 For_range_statement*
5011 Statement::make_for_range_statement(Expression* index_var,
5012                                     Expression* value_var,
5013                                     Expression* range,
5014                                     source_location location)
5015 {
5016   return new For_range_statement(index_var, value_var, range, location);
5017 }