OSDN Git Service

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