OSDN Git Service

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