OSDN Git Service

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