OSDN Git Service

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