OSDN Git Service

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