OSDN Git Service

Don't crash on invalid return statement.
[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   if (fndecl == error_mark_node || DECL_RESULT(fndecl) == error_mark_node)
2571     return error_mark_node;
2572
2573   const Typed_identifier_list* results = this->results_;
2574
2575   if (this->vals_ == NULL)
2576     {
2577       tree stmt_list = NULL_TREE;
2578       tree retval = function->return_value(context->gogo(),
2579                                            context->function(),
2580                                            this->location(),
2581                                            &stmt_list);
2582       tree set;
2583       if (retval == NULL_TREE)
2584         set = NULL_TREE;
2585       else if (retval == error_mark_node)
2586         return error_mark_node;
2587       else
2588         set = fold_build2_loc(this->location(), MODIFY_EXPR, void_type_node,
2589                               DECL_RESULT(fndecl), retval);
2590       append_to_statement_list(this->build_stmt_1(RETURN_EXPR, set),
2591                                &stmt_list);
2592       return stmt_list;
2593     }
2594   else if (this->vals_->size() == 1)
2595     {
2596       gcc_assert(!VOID_TYPE_P(TREE_TYPE(TREE_TYPE(fndecl))));
2597       tree val = (*this->vals_->begin())->get_tree(context);
2598       gcc_assert(results != NULL && results->size() == 1);
2599       val = Expression::convert_for_assignment(context,
2600                                                results->begin()->type(),
2601                                                (*this->vals_->begin())->type(),
2602                                                val, this->location());
2603       if (val == error_mark_node)
2604         return error_mark_node;
2605       tree set = build2(MODIFY_EXPR, void_type_node,
2606                         DECL_RESULT(fndecl), val);
2607       SET_EXPR_LOCATION(set, this->location());
2608       return this->build_stmt_1(RETURN_EXPR, set);
2609     }
2610   else
2611     {
2612       gcc_assert(!VOID_TYPE_P(TREE_TYPE(TREE_TYPE(fndecl))));
2613       tree stmt_list = NULL_TREE;
2614       tree rettype = TREE_TYPE(DECL_RESULT(fndecl));
2615       tree retvar = create_tmp_var(rettype, "RESULT");
2616       gcc_assert(results != NULL && results->size() == this->vals_->size());
2617       Expression_list::const_iterator pv = this->vals_->begin();
2618       Typed_identifier_list::const_iterator pr = results->begin();
2619       for (tree field = TYPE_FIELDS(rettype);
2620            field != NULL_TREE;
2621            ++pv, ++pr, field = DECL_CHAIN(field))
2622         {
2623           gcc_assert(pv != this->vals_->end());
2624           tree val = (*pv)->get_tree(context);
2625           val = Expression::convert_for_assignment(context, pr->type(),
2626                                                    (*pv)->type(), val,
2627                                                    this->location());
2628           if (val == error_mark_node)
2629             return error_mark_node;
2630           tree set = build2(MODIFY_EXPR, void_type_node,
2631                             build3(COMPONENT_REF, TREE_TYPE(field),
2632                                    retvar, field, NULL_TREE),
2633                             val);
2634           SET_EXPR_LOCATION(set, this->location());
2635           append_to_statement_list(set, &stmt_list);
2636         }
2637       tree set = build2(MODIFY_EXPR, void_type_node, DECL_RESULT(fndecl),
2638                         retvar);
2639       append_to_statement_list(this->build_stmt_1(RETURN_EXPR, set),
2640                                &stmt_list);
2641       return stmt_list;
2642     }
2643 }
2644
2645 // Make a return statement.
2646
2647 Statement*
2648 Statement::make_return_statement(const Typed_identifier_list* results,
2649                                  Expression_list* vals,
2650                                  source_location location)
2651 {
2652   return new Return_statement(results, vals, location);
2653 }
2654
2655 // A break or continue statement.
2656
2657 class Bc_statement : public Statement
2658 {
2659  public:
2660   Bc_statement(bool is_break, Unnamed_label* label, source_location location)
2661     : Statement(STATEMENT_BREAK_OR_CONTINUE, location),
2662       label_(label), is_break_(is_break)
2663   { }
2664
2665   bool
2666   is_break() const
2667   { return this->is_break_; }
2668
2669  protected:
2670   int
2671   do_traverse(Traverse*)
2672   { return TRAVERSE_CONTINUE; }
2673
2674   bool
2675   do_may_fall_through() const
2676   { return false; }
2677
2678   tree
2679   do_get_tree(Translate_context*)
2680   { return this->label_->get_goto(this->location()); }
2681
2682  private:
2683   // The label that this branches to.
2684   Unnamed_label* label_;
2685   // True if this is "break", false if it is "continue".
2686   bool is_break_;
2687 };
2688
2689 // Make a break statement.
2690
2691 Statement*
2692 Statement::make_break_statement(Unnamed_label* label, source_location location)
2693 {
2694   return new Bc_statement(true, label, location);
2695 }
2696
2697 // Make a continue statement.
2698
2699 Statement*
2700 Statement::make_continue_statement(Unnamed_label* label,
2701                                    source_location location)
2702 {
2703   return new Bc_statement(false, label, location);
2704 }
2705
2706 // A goto statement.
2707
2708 class Goto_statement : public Statement
2709 {
2710  public:
2711   Goto_statement(Label* label, source_location location)
2712     : Statement(STATEMENT_GOTO, location),
2713       label_(label)
2714   { }
2715
2716  protected:
2717   int
2718   do_traverse(Traverse*)
2719   { return TRAVERSE_CONTINUE; }
2720
2721   void
2722   do_check_types(Gogo*);
2723
2724   bool
2725   do_may_fall_through() const
2726   { return false; }
2727
2728   tree
2729   do_get_tree(Translate_context*);
2730
2731  private:
2732   Label* label_;
2733 };
2734
2735 // Check types for a label.  There aren't any types per se, but we use
2736 // this to give an error if the label was never defined.
2737
2738 void
2739 Goto_statement::do_check_types(Gogo*)
2740 {
2741   if (!this->label_->is_defined())
2742     {
2743       error_at(this->location(), "reference to undefined label %qs",
2744                Gogo::message_name(this->label_->name()).c_str());
2745       this->set_is_error();
2746     }
2747 }
2748
2749 // Return the tree for the goto statement.
2750
2751 tree
2752 Goto_statement::do_get_tree(Translate_context*)
2753 {
2754   return this->build_stmt_1(GOTO_EXPR, this->label_->get_decl());
2755 }
2756
2757 // Make a goto statement.
2758
2759 Statement*
2760 Statement::make_goto_statement(Label* label, source_location location)
2761 {
2762   return new Goto_statement(label, location);
2763 }
2764
2765 // A goto statement to an unnamed label.
2766
2767 class Goto_unnamed_statement : public Statement
2768 {
2769  public:
2770   Goto_unnamed_statement(Unnamed_label* label, source_location location)
2771     : Statement(STATEMENT_GOTO_UNNAMED, location),
2772       label_(label)
2773   { }
2774
2775  protected:
2776   int
2777   do_traverse(Traverse*)
2778   { return TRAVERSE_CONTINUE; }
2779
2780   bool
2781   do_may_fall_through() const
2782   { return false; }
2783
2784   tree
2785   do_get_tree(Translate_context*)
2786   { return this->label_->get_goto(this->location()); }
2787
2788  private:
2789   Unnamed_label* label_;
2790 };
2791
2792 // Make a goto statement to an unnamed label.
2793
2794 Statement*
2795 Statement::make_goto_unnamed_statement(Unnamed_label* label,
2796                                        source_location location)
2797 {
2798   return new Goto_unnamed_statement(label, location);
2799 }
2800
2801 // Class Label_statement.
2802
2803 // Traversal.
2804
2805 int
2806 Label_statement::do_traverse(Traverse*)
2807 {
2808   return TRAVERSE_CONTINUE;
2809 }
2810
2811 // Return a tree defining this label.
2812
2813 tree
2814 Label_statement::do_get_tree(Translate_context*)
2815 {
2816   return this->build_stmt_1(LABEL_EXPR, this->label_->get_decl());
2817 }
2818
2819 // Make a label statement.
2820
2821 Statement*
2822 Statement::make_label_statement(Label* label, source_location location)
2823 {
2824   return new Label_statement(label, location);
2825 }
2826
2827 // An unnamed label statement.
2828
2829 class Unnamed_label_statement : public Statement
2830 {
2831  public:
2832   Unnamed_label_statement(Unnamed_label* label)
2833     : Statement(STATEMENT_UNNAMED_LABEL, label->location()),
2834       label_(label)
2835   { }
2836
2837  protected:
2838   int
2839   do_traverse(Traverse*)
2840   { return TRAVERSE_CONTINUE; }
2841
2842   tree
2843   do_get_tree(Translate_context*)
2844   { return this->label_->get_definition(); }
2845
2846  private:
2847   // The label.
2848   Unnamed_label* label_;
2849 };
2850
2851 // Make an unnamed label statement.
2852
2853 Statement*
2854 Statement::make_unnamed_label_statement(Unnamed_label* label)
2855 {
2856   return new Unnamed_label_statement(label);
2857 }
2858
2859 // An if statement.
2860
2861 class If_statement : public Statement
2862 {
2863  public:
2864   If_statement(Expression* cond, Block* then_block, Block* else_block,
2865                source_location location)
2866     : Statement(STATEMENT_IF, location),
2867       cond_(cond), then_block_(then_block), else_block_(else_block)
2868   { }
2869
2870  protected:
2871   int
2872   do_traverse(Traverse*);
2873
2874   void
2875   do_determine_types();
2876
2877   void
2878   do_check_types(Gogo*);
2879
2880   bool
2881   do_may_fall_through() const;
2882
2883   tree
2884   do_get_tree(Translate_context*);
2885
2886  private:
2887   Expression* cond_;
2888   Block* then_block_;
2889   Block* else_block_;
2890 };
2891
2892 // Traversal.
2893
2894 int
2895 If_statement::do_traverse(Traverse* traverse)
2896 {
2897   if (this->cond_ != NULL)
2898     {
2899       if (this->traverse_expression(traverse, &this->cond_) == TRAVERSE_EXIT)
2900         return TRAVERSE_EXIT;
2901     }
2902   if (this->then_block_->traverse(traverse) == TRAVERSE_EXIT)
2903     return TRAVERSE_EXIT;
2904   if (this->else_block_ != NULL)
2905     {
2906       if (this->else_block_->traverse(traverse) == TRAVERSE_EXIT)
2907         return TRAVERSE_EXIT;
2908     }
2909   return TRAVERSE_CONTINUE;
2910 }
2911
2912 void
2913 If_statement::do_determine_types()
2914 {
2915   if (this->cond_ != NULL)
2916     {
2917       Type_context context(Type::lookup_bool_type(), false);
2918       this->cond_->determine_type(&context);
2919     }
2920   this->then_block_->determine_types();
2921   if (this->else_block_ != NULL)
2922     this->else_block_->determine_types();
2923 }
2924
2925 // Check types.
2926
2927 void
2928 If_statement::do_check_types(Gogo*)
2929 {
2930   if (this->cond_ != NULL)
2931     {
2932       Type* type = this->cond_->type();
2933       if (type->is_error_type())
2934         this->set_is_error();
2935       else if (!type->is_boolean_type())
2936         this->report_error(_("expected boolean expression"));
2937     }
2938 }
2939
2940 // Whether the overall statement may fall through.
2941
2942 bool
2943 If_statement::do_may_fall_through() const
2944 {
2945   return (this->else_block_ == NULL
2946           || this->then_block_->may_fall_through()
2947           || this->else_block_->may_fall_through());
2948 }
2949
2950 // Get tree.
2951
2952 tree
2953 If_statement::do_get_tree(Translate_context* context)
2954 {
2955   gcc_assert(this->cond_ == NULL || this->cond_->type()->is_boolean_type());
2956   tree ret = build3(COND_EXPR, void_type_node,
2957                     (this->cond_ == NULL
2958                      ? boolean_true_node
2959                      : this->cond_->get_tree(context)),
2960                     this->then_block_->get_tree(context),
2961                     (this->else_block_ == NULL
2962                      ? NULL_TREE
2963                      : this->else_block_->get_tree(context)));
2964   SET_EXPR_LOCATION(ret, this->location());
2965   return ret;
2966 }
2967
2968 // Make an if statement.
2969
2970 Statement*
2971 Statement::make_if_statement(Expression* cond, Block* then_block,
2972                              Block* else_block, source_location location)
2973 {
2974   return new If_statement(cond, then_block, else_block, location);
2975 }
2976
2977 // Class Case_clauses::Case_clause.
2978
2979 // Traversal.
2980
2981 int
2982 Case_clauses::Case_clause::traverse(Traverse* traverse)
2983 {
2984   if (this->cases_ != NULL
2985       && (traverse->traverse_mask() & Traverse::traverse_expressions) != 0)
2986     {
2987       if (this->cases_->traverse(traverse) == TRAVERSE_EXIT)
2988         return TRAVERSE_EXIT;
2989     }
2990   if (this->statements_ != NULL)
2991     {
2992       if (this->statements_->traverse(traverse) == TRAVERSE_EXIT)
2993         return TRAVERSE_EXIT;
2994     }
2995   return TRAVERSE_CONTINUE;
2996 }
2997
2998 // Check whether all the case expressions are integer constants.
2999
3000 bool
3001 Case_clauses::Case_clause::is_constant() const
3002 {
3003   if (this->cases_ != NULL)
3004     {
3005       for (Expression_list::const_iterator p = this->cases_->begin();
3006            p != this->cases_->end();
3007            ++p)
3008         if (!(*p)->is_constant() || (*p)->type()->integer_type() == NULL)
3009           return false;
3010     }
3011   return true;
3012 }
3013
3014 // Lower a case clause for a nonconstant switch.  VAL_TEMP is the
3015 // value we are switching on; it may be NULL.  If START_LABEL is not
3016 // NULL, it goes at the start of the statements, after the condition
3017 // test.  We branch to FINISH_LABEL at the end of the statements.
3018
3019 void
3020 Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
3021                                  Unnamed_label* start_label,
3022                                  Unnamed_label* finish_label) const
3023 {
3024   source_location loc = this->location_;
3025   Unnamed_label* next_case_label;
3026   if (this->cases_ == NULL || this->cases_->empty())
3027     {
3028       gcc_assert(this->is_default_);
3029       next_case_label = NULL;
3030     }
3031   else
3032     {
3033       Expression* cond = NULL;
3034
3035       for (Expression_list::const_iterator p = this->cases_->begin();
3036            p != this->cases_->end();
3037            ++p)
3038         {
3039           Expression* this_cond;
3040           if (val_temp == NULL)
3041             this_cond = *p;
3042           else
3043             {
3044               Expression* ref = Expression::make_temporary_reference(val_temp,
3045                                                                      loc);
3046               this_cond = Expression::make_binary(OPERATOR_EQEQ, ref, *p, loc);
3047             }
3048
3049           if (cond == NULL)
3050             cond = this_cond;
3051           else
3052             cond = Expression::make_binary(OPERATOR_OROR, cond, this_cond, loc);
3053         }
3054
3055       Block* then_block = new Block(b, loc);
3056       next_case_label = new Unnamed_label(UNKNOWN_LOCATION);
3057       Statement* s = Statement::make_goto_unnamed_statement(next_case_label,
3058                                                             loc);
3059       then_block->add_statement(s);
3060
3061       // if !COND { goto NEXT_CASE_LABEL }
3062       cond = Expression::make_unary(OPERATOR_NOT, cond, loc);
3063       s = Statement::make_if_statement(cond, then_block, NULL, loc);
3064       b->add_statement(s);
3065     }
3066
3067   if (start_label != NULL)
3068     b->add_statement(Statement::make_unnamed_label_statement(start_label));
3069
3070   if (this->statements_ != NULL)
3071     b->add_statement(Statement::make_block_statement(this->statements_, loc));
3072
3073   Statement* s = Statement::make_goto_unnamed_statement(finish_label, loc);
3074   b->add_statement(s);
3075
3076   if (next_case_label != NULL)
3077     b->add_statement(Statement::make_unnamed_label_statement(next_case_label));
3078 }
3079
3080 // Determine types.
3081
3082 void
3083 Case_clauses::Case_clause::determine_types(Type* type)
3084 {
3085   if (this->cases_ != NULL)
3086     {
3087       Type_context case_context(type, false);
3088       for (Expression_list::iterator p = this->cases_->begin();
3089            p != this->cases_->end();
3090            ++p)
3091         (*p)->determine_type(&case_context);
3092     }
3093   if (this->statements_ != NULL)
3094     this->statements_->determine_types();
3095 }
3096
3097 // Check types.  Returns false if there was an error.
3098
3099 bool
3100 Case_clauses::Case_clause::check_types(Type* type)
3101 {
3102   if (this->cases_ != NULL)
3103     {
3104       for (Expression_list::iterator p = this->cases_->begin();
3105            p != this->cases_->end();
3106            ++p)
3107         {
3108           if (!Type::are_assignable(type, (*p)->type(), NULL)
3109               && !Type::are_assignable((*p)->type(), type, NULL))
3110             {
3111               error_at((*p)->location(),
3112                        "type mismatch between switch value and case clause");
3113               return false;
3114             }
3115         }
3116     }
3117   return true;
3118 }
3119
3120 // Return true if this clause may fall through to the following
3121 // statements.  Note that this is not the same as whether the case
3122 // uses the "fallthrough" keyword.
3123
3124 bool
3125 Case_clauses::Case_clause::may_fall_through() const
3126 {
3127   if (this->statements_ == NULL)
3128     return true;
3129   return this->statements_->may_fall_through();
3130 }
3131
3132 // Build up the body of a SWITCH_EXPR.
3133
3134 void
3135 Case_clauses::Case_clause::get_constant_tree(Translate_context* context,
3136                                              Unnamed_label* break_label,
3137                                              Case_constants* case_constants,
3138                                              tree* stmt_list) const
3139 {
3140   if (this->cases_ != NULL)
3141     {
3142       for (Expression_list::const_iterator p = this->cases_->begin();
3143            p != this->cases_->end();
3144            ++p)
3145         {
3146           Type* itype;
3147           mpz_t ival;
3148           mpz_init(ival);
3149           if (!(*p)->integer_constant_value(true, ival, &itype))
3150             gcc_unreachable();
3151           gcc_assert(itype != NULL);
3152           tree type_tree = itype->get_tree(context->gogo());
3153           tree val = Expression::integer_constant_tree(ival, type_tree);
3154           mpz_clear(ival);
3155
3156           if (val != error_mark_node)
3157             {
3158               gcc_assert(TREE_CODE(val) == INTEGER_CST);
3159
3160               std::pair<Case_constants::iterator, bool> ins =
3161                 case_constants->insert(val);
3162               if (!ins.second)
3163                 {
3164                   // Value was already present.
3165                   warning_at(this->location_, 0,
3166                              "duplicate case value will never match");
3167                   continue;
3168                 }
3169
3170               tree label = create_artificial_label(this->location_);
3171               append_to_statement_list(build3(CASE_LABEL_EXPR, void_type_node,
3172                                               val, NULL_TREE, label),
3173                                        stmt_list);
3174             }
3175         }
3176     }
3177
3178   if (this->is_default_)
3179     {
3180       tree label = create_artificial_label(this->location_);
3181       append_to_statement_list(build3(CASE_LABEL_EXPR, void_type_node,
3182                                       NULL_TREE, NULL_TREE, label),
3183                                stmt_list);
3184     }
3185
3186   if (this->statements_ != NULL)
3187     {
3188       tree block_tree = this->statements_->get_tree(context);
3189       if (block_tree != error_mark_node)
3190         append_to_statement_list(block_tree, stmt_list);
3191     }
3192
3193   if (!this->is_fallthrough_)
3194     append_to_statement_list(break_label->get_goto(this->location_), stmt_list);
3195 }
3196
3197 // Class Case_clauses.
3198
3199 // Traversal.
3200
3201 int
3202 Case_clauses::traverse(Traverse* traverse)
3203 {
3204   for (Clauses::iterator p = this->clauses_.begin();
3205        p != this->clauses_.end();
3206        ++p)
3207     {
3208       if (p->traverse(traverse) == TRAVERSE_EXIT)
3209         return TRAVERSE_EXIT;
3210     }
3211   return TRAVERSE_CONTINUE;
3212 }
3213
3214 // Check whether all the case expressions are constant.
3215
3216 bool
3217 Case_clauses::is_constant() const
3218 {
3219   for (Clauses::const_iterator p = this->clauses_.begin();
3220        p != this->clauses_.end();
3221        ++p)
3222     if (!p->is_constant())
3223       return false;
3224   return true;
3225 }
3226
3227 // Lower case clauses for a nonconstant switch.
3228
3229 void
3230 Case_clauses::lower(Block* b, Temporary_statement* val_temp,
3231                     Unnamed_label* break_label) const
3232 {
3233   // The default case.
3234   const Case_clause* default_case = NULL;
3235
3236   // The label for the fallthrough of the previous case.
3237   Unnamed_label* last_fallthrough_label = NULL;
3238
3239   // The label for the start of the default case.  This is used if the
3240   // case before the default case falls through.
3241   Unnamed_label* default_start_label = NULL;
3242
3243   // The label for the end of the default case.  This normally winds
3244   // up as BREAK_LABEL, but it will be different if the default case
3245   // falls through.
3246   Unnamed_label* default_finish_label = NULL;
3247
3248   for (Clauses::const_iterator p = this->clauses_.begin();
3249        p != this->clauses_.end();
3250        ++p)
3251     {
3252       // The label to use for the start of the statements for this
3253       // case.  This is NULL unless the previous case falls through.
3254       Unnamed_label* start_label = last_fallthrough_label;
3255
3256       // The label to jump to after the end of the statements for this
3257       // case.
3258       Unnamed_label* finish_label = break_label;
3259
3260       last_fallthrough_label = NULL;
3261       if (p->is_fallthrough() && p + 1 != this->clauses_.end())
3262         {
3263           finish_label = new Unnamed_label(p->location());
3264           last_fallthrough_label = finish_label;
3265         }
3266
3267       if (!p->is_default())
3268         p->lower(b, val_temp, start_label, finish_label);
3269       else
3270         {
3271           // We have to move the default case to the end, so that we
3272           // only use it if all the other tests fail.
3273           default_case = &*p;
3274           default_start_label = start_label;
3275           default_finish_label = finish_label;
3276         }
3277     }
3278
3279   if (default_case != NULL)
3280     default_case->lower(b, val_temp, default_start_label,
3281                         default_finish_label);
3282       
3283 }
3284
3285 // Determine types.
3286
3287 void
3288 Case_clauses::determine_types(Type* type)
3289 {
3290   for (Clauses::iterator p = this->clauses_.begin();
3291        p != this->clauses_.end();
3292        ++p)
3293     p->determine_types(type);
3294 }
3295
3296 // Check types.  Returns false if there was an error.
3297
3298 bool
3299 Case_clauses::check_types(Type* type)
3300 {
3301   bool ret = true;
3302   for (Clauses::iterator p = this->clauses_.begin();
3303        p != this->clauses_.end();
3304        ++p)
3305     {
3306       if (!p->check_types(type))
3307         ret = false;
3308     }
3309   return ret;
3310 }
3311
3312 // Return true if these clauses may fall through to the statements
3313 // following the switch statement.
3314
3315 bool
3316 Case_clauses::may_fall_through() const
3317 {
3318   bool found_default = false;
3319   for (Clauses::const_iterator p = this->clauses_.begin();
3320        p != this->clauses_.end();
3321        ++p)
3322     {
3323       if (p->may_fall_through() && !p->is_fallthrough())
3324         return true;
3325       if (p->is_default())
3326         found_default = true;
3327     }
3328   return !found_default;
3329 }
3330
3331 // Return a tree when all case expressions are constants.
3332
3333 tree
3334 Case_clauses::get_constant_tree(Translate_context* context,
3335                                 Unnamed_label* break_label) const
3336 {
3337   Case_constants case_constants;
3338   tree stmt_list = NULL_TREE;
3339   for (Clauses::const_iterator p = this->clauses_.begin();
3340        p != this->clauses_.end();
3341        ++p)
3342     p->get_constant_tree(context, break_label, &case_constants,
3343                          &stmt_list);
3344   return stmt_list;
3345 }
3346
3347 // A constant switch statement.  A Switch_statement is lowered to this
3348 // when all the cases are constants.
3349
3350 class Constant_switch_statement : public Statement
3351 {
3352  public:
3353   Constant_switch_statement(Expression* val, Case_clauses* clauses,
3354                             Unnamed_label* break_label,
3355                             source_location location)
3356     : Statement(STATEMENT_CONSTANT_SWITCH, location),
3357       val_(val), clauses_(clauses), break_label_(break_label)
3358   { }
3359
3360  protected:
3361   int
3362   do_traverse(Traverse*);
3363
3364   void
3365   do_determine_types();
3366
3367   void
3368   do_check_types(Gogo*);
3369
3370   bool
3371   do_may_fall_through() const;
3372
3373   tree
3374   do_get_tree(Translate_context*);
3375
3376  private:
3377   // The value to switch on.
3378   Expression* val_;
3379   // The case clauses.
3380   Case_clauses* clauses_;
3381   // The break label, if needed.
3382   Unnamed_label* break_label_;
3383 };
3384
3385 // Traversal.
3386
3387 int
3388 Constant_switch_statement::do_traverse(Traverse* traverse)
3389 {
3390   if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT)
3391     return TRAVERSE_EXIT;
3392   return this->clauses_->traverse(traverse);
3393 }
3394
3395 // Determine types.
3396
3397 void
3398 Constant_switch_statement::do_determine_types()
3399 {
3400   this->val_->determine_type_no_context();
3401   this->clauses_->determine_types(this->val_->type());
3402 }
3403
3404 // Check types.
3405
3406 void
3407 Constant_switch_statement::do_check_types(Gogo*)
3408 {
3409   if (!this->clauses_->check_types(this->val_->type()))
3410     this->set_is_error();
3411 }
3412
3413 // Return whether this switch may fall through.
3414
3415 bool
3416 Constant_switch_statement::do_may_fall_through() const
3417 {
3418   if (this->clauses_ == NULL)
3419     return true;
3420
3421   // If we have a break label, then some case needed it.  That implies
3422   // that the switch statement as a whole can fall through.
3423   if (this->break_label_ != NULL)
3424     return true;
3425
3426   return this->clauses_->may_fall_through();
3427 }
3428
3429 // Convert to GENERIC.
3430
3431 tree
3432 Constant_switch_statement::do_get_tree(Translate_context* context)
3433 {
3434   tree switch_val_tree = this->val_->get_tree(context);
3435
3436   Unnamed_label* break_label = this->break_label_;
3437   if (break_label == NULL)
3438     break_label = new Unnamed_label(this->location());
3439
3440   tree stmt_list = NULL_TREE;
3441   tree s = build3(SWITCH_EXPR, void_type_node, switch_val_tree,
3442                   this->clauses_->get_constant_tree(context, break_label),
3443                   NULL_TREE);
3444   SET_EXPR_LOCATION(s, this->location());
3445   append_to_statement_list(s, &stmt_list);
3446
3447   append_to_statement_list(break_label->get_definition(), &stmt_list);
3448
3449   return stmt_list;
3450 }
3451
3452 // Class Switch_statement.
3453
3454 // Traversal.
3455
3456 int
3457 Switch_statement::do_traverse(Traverse* traverse)
3458 {
3459   if (this->val_ != NULL)
3460     {
3461       if (this->traverse_expression(traverse, &this->val_) == TRAVERSE_EXIT)
3462         return TRAVERSE_EXIT;
3463     }
3464   return this->clauses_->traverse(traverse);
3465 }
3466
3467 // Lower a Switch_statement to a Constant_switch_statement or a series
3468 // of if statements.
3469
3470 Statement*
3471 Switch_statement::do_lower(Gogo*, Block* enclosing)
3472 {
3473   source_location loc = this->location();
3474
3475   if (this->val_ != NULL
3476       && (this->val_->is_error_expression()
3477           || this->val_->type()->is_error_type()))
3478     return Statement::make_error_statement(loc);
3479
3480   if (this->val_ != NULL
3481       && this->val_->type()->integer_type() != NULL
3482       && !this->clauses_->empty()
3483       && this->clauses_->is_constant())
3484     return new Constant_switch_statement(this->val_, this->clauses_,
3485                                          this->break_label_, loc);
3486
3487   Block* b = new Block(enclosing, loc);
3488
3489   if (this->clauses_->empty())
3490     {
3491       Expression* val = this->val_;
3492       if (val == NULL)
3493         val = Expression::make_boolean(true, loc);
3494       return Statement::make_statement(val);
3495     }
3496
3497   Temporary_statement* val_temp;
3498   if (this->val_ == NULL)
3499     val_temp = NULL;
3500   else
3501     {
3502       // var val_temp VAL_TYPE = VAL
3503       val_temp = Statement::make_temporary(NULL, this->val_, loc);
3504       b->add_statement(val_temp);
3505     }
3506
3507   this->clauses_->lower(b, val_temp, this->break_label());
3508
3509   Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
3510   b->add_statement(s);
3511
3512   return Statement::make_block_statement(b, loc);
3513 }
3514
3515 // Return the break label for this switch statement, creating it if
3516 // necessary.
3517
3518 Unnamed_label*
3519 Switch_statement::break_label()
3520 {
3521   if (this->break_label_ == NULL)
3522     this->break_label_ = new Unnamed_label(this->location());
3523   return this->break_label_;
3524 }
3525
3526 // Make a switch statement.
3527
3528 Switch_statement*
3529 Statement::make_switch_statement(Expression* val, source_location location)
3530 {
3531   return new Switch_statement(val, location);
3532 }
3533
3534 // Class Type_case_clauses::Type_case_clause.
3535
3536 // Traversal.
3537
3538 int
3539 Type_case_clauses::Type_case_clause::traverse(Traverse* traverse)
3540 {
3541   if (!this->is_default_
3542       && ((traverse->traverse_mask()
3543            & (Traverse::traverse_types | Traverse::traverse_expressions)) != 0)
3544       && Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
3545     return TRAVERSE_EXIT;
3546   if (this->statements_ != NULL)
3547     return this->statements_->traverse(traverse);
3548   return TRAVERSE_CONTINUE;
3549 }
3550
3551 // Lower one clause in a type switch.  Add statements to the block B.
3552 // The type descriptor we are switching on is in DESCRIPTOR_TEMP.
3553 // BREAK_LABEL is the label at the end of the type switch.
3554 // *STMTS_LABEL, if not NULL, is a label to put at the start of the
3555 // statements.
3556
3557 void
3558 Type_case_clauses::Type_case_clause::lower(Block* b,
3559                                            Temporary_statement* descriptor_temp,
3560                                            Unnamed_label* break_label,
3561                                            Unnamed_label** stmts_label) const
3562 {
3563   source_location loc = this->location_;
3564
3565   Unnamed_label* next_case_label = NULL;
3566   if (!this->is_default_)
3567     {
3568       Type* type = this->type_;
3569
3570       Expression* cond;
3571       // The language permits case nil, which is of course a constant
3572       // rather than a type.  It will appear here as an invalid
3573       // forwarding type.
3574       if (type->is_nil_constant_as_type())
3575         {
3576           Expression* ref =
3577             Expression::make_temporary_reference(descriptor_temp, loc);
3578           cond = Expression::make_binary(OPERATOR_EQEQ, ref,
3579                                          Expression::make_nil(loc),
3580                                          loc);
3581         }
3582       else
3583         {
3584           Expression* func;
3585           if (type->interface_type() == NULL)
3586             {
3587               // func ifacetypeeq(*descriptor, *descriptor) bool
3588               static Named_object* ifacetypeeq;
3589               if (ifacetypeeq == NULL)
3590                 {
3591                   const source_location bloc = BUILTINS_LOCATION;
3592                   Typed_identifier_list* param_types =
3593                     new Typed_identifier_list();
3594                   Type* descriptor_type = Type::make_type_descriptor_ptr_type();
3595                   param_types->push_back(Typed_identifier("a", descriptor_type,
3596                                                           bloc));
3597                   param_types->push_back(Typed_identifier("b", descriptor_type,
3598                                                           bloc));
3599                   Typed_identifier_list* ret_types =
3600                     new Typed_identifier_list();
3601                   Type* bool_type = Type::lookup_bool_type();
3602                   ret_types->push_back(Typed_identifier("", bool_type, bloc));
3603                   Function_type* fntype = Type::make_function_type(NULL,
3604                                                                    param_types,
3605                                                                    ret_types,
3606                                                                    bloc);
3607                   ifacetypeeq =
3608                     Named_object::make_function_declaration("ifacetypeeq", NULL,
3609                                                             fntype, bloc);
3610                   const char* n = "runtime.ifacetypeeq";
3611                   ifacetypeeq->func_declaration_value()->set_asm_name(n);
3612                 }
3613
3614               // ifacetypeeq(descriptor_temp, DESCRIPTOR)
3615               func = Expression::make_func_reference(ifacetypeeq, NULL, loc);
3616             }
3617           else
3618             {
3619               // func ifaceI2Tp(*descriptor, *descriptor) bool
3620               static Named_object* ifaceI2Tp;
3621               if (ifaceI2Tp == NULL)
3622                 {
3623                   const source_location bloc = BUILTINS_LOCATION;
3624                   Typed_identifier_list* param_types =
3625                     new Typed_identifier_list();
3626                   Type* descriptor_type = Type::make_type_descriptor_ptr_type();
3627                   param_types->push_back(Typed_identifier("a", descriptor_type,
3628                                                           bloc));
3629                   param_types->push_back(Typed_identifier("b", descriptor_type,
3630                                                           bloc));
3631                   Typed_identifier_list* ret_types =
3632                     new Typed_identifier_list();
3633                   Type* bool_type = Type::lookup_bool_type();
3634                   ret_types->push_back(Typed_identifier("", bool_type, bloc));
3635                   Function_type* fntype = Type::make_function_type(NULL,
3636                                                                    param_types,
3637                                                                    ret_types,
3638                                                                    bloc);
3639                   ifaceI2Tp =
3640                     Named_object::make_function_declaration("ifaceI2Tp", NULL,
3641                                                             fntype, bloc);
3642                   const char* n = "runtime.ifaceI2Tp";
3643                   ifaceI2Tp->func_declaration_value()->set_asm_name(n);
3644                 }
3645
3646               // ifaceI2Tp(descriptor_temp, DESCRIPTOR)
3647               func = Expression::make_func_reference(ifaceI2Tp, NULL, loc);
3648             }
3649           Expression_list* params = new Expression_list();
3650           params->push_back(Expression::make_type_descriptor(type, loc));
3651           Expression* ref =
3652             Expression::make_temporary_reference(descriptor_temp, loc);
3653           params->push_back(ref);
3654           cond = Expression::make_call(func, params, false, loc);
3655         }
3656
3657       Unnamed_label* dest;
3658       if (!this->is_fallthrough_)
3659         {
3660           // if !COND { goto NEXT_CASE_LABEL }
3661           next_case_label = new Unnamed_label(UNKNOWN_LOCATION);
3662           dest = next_case_label;
3663           cond = Expression::make_unary(OPERATOR_NOT, cond, loc);
3664         }
3665       else
3666         {
3667           // if COND { goto STMTS_LABEL }
3668           gcc_assert(stmts_label != NULL);
3669           if (*stmts_label == NULL)
3670             *stmts_label = new Unnamed_label(UNKNOWN_LOCATION);
3671           dest = *stmts_label;
3672         }
3673       Block* then_block = new Block(b, loc);
3674       Statement* s = Statement::make_goto_unnamed_statement(dest, loc);
3675       then_block->add_statement(s);
3676       s = Statement::make_if_statement(cond, then_block, NULL, loc);
3677       b->add_statement(s);
3678     }
3679
3680   if (this->statements_ != NULL
3681       || (!this->is_fallthrough_
3682           && stmts_label != NULL
3683           && *stmts_label != NULL))
3684     {
3685       gcc_assert(!this->is_fallthrough_);
3686       if (stmts_label != NULL && *stmts_label != NULL)
3687         {
3688           gcc_assert(!this->is_default_);
3689           if (this->statements_ != NULL)
3690             (*stmts_label)->set_location(this->statements_->start_location());
3691           Statement* s = Statement::make_unnamed_label_statement(*stmts_label);
3692           b->add_statement(s);
3693           *stmts_label = NULL;
3694         }
3695       if (this->statements_ != NULL)
3696         b->add_statement(Statement::make_block_statement(this->statements_,
3697                                                          loc));
3698     }
3699
3700   if (this->is_fallthrough_)
3701     gcc_assert(next_case_label == NULL);
3702   else
3703     {
3704       source_location gloc = (this->statements_ == NULL
3705                               ? loc
3706                               : this->statements_->end_location());
3707       b->add_statement(Statement::make_goto_unnamed_statement(break_label,
3708                                                               gloc));
3709       if (next_case_label != NULL)
3710         {
3711           Statement* s =
3712             Statement::make_unnamed_label_statement(next_case_label);
3713           b->add_statement(s);
3714         }
3715     }
3716 }
3717
3718 // Class Type_case_clauses.
3719
3720 // Traversal.
3721
3722 int
3723 Type_case_clauses::traverse(Traverse* traverse)
3724 {
3725   for (Type_clauses::iterator p = this->clauses_.begin();
3726        p != this->clauses_.end();
3727        ++p)
3728     {
3729       if (p->traverse(traverse) == TRAVERSE_EXIT)
3730         return TRAVERSE_EXIT;
3731     }
3732   return TRAVERSE_CONTINUE;
3733 }
3734
3735 // Check for duplicate types.
3736
3737 void
3738 Type_case_clauses::check_duplicates() const
3739 {
3740   typedef Unordered_set_hash(const Type*, Type_hash_identical,
3741                              Type_identical) Types_seen;
3742   Types_seen types_seen;
3743   for (Type_clauses::const_iterator p = this->clauses_.begin();
3744        p != this->clauses_.end();
3745        ++p)
3746     {
3747       Type* t = p->type();
3748       if (t == NULL)
3749         continue;
3750       if (t->is_nil_constant_as_type())
3751         t = Type::make_nil_type();
3752       std::pair<Types_seen::iterator, bool> ins = types_seen.insert(t);
3753       if (!ins.second)
3754         error_at(p->location(), "duplicate type in switch");
3755     }
3756 }
3757
3758 // Lower the clauses in a type switch.  Add statements to the block B.
3759 // The type descriptor we are switching on is in DESCRIPTOR_TEMP.
3760 // BREAK_LABEL is the label at the end of the type switch.
3761
3762 void
3763 Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
3764                          Unnamed_label* break_label) const
3765 {
3766   const Type_case_clause* default_case = NULL;
3767
3768   Unnamed_label* stmts_label = NULL;
3769   for (Type_clauses::const_iterator p = this->clauses_.begin();
3770        p != this->clauses_.end();
3771        ++p)
3772     {
3773       if (!p->is_default())
3774         p->lower(b, descriptor_temp, break_label, &stmts_label);
3775       else
3776         {
3777           // We are generating a series of tests, which means that we
3778           // need to move the default case to the end.
3779           default_case = &*p;
3780         }
3781     }
3782   gcc_assert(stmts_label == NULL);
3783
3784   if (default_case != NULL)
3785     default_case->lower(b, descriptor_temp, break_label, NULL);
3786 }
3787
3788 // Class Type_switch_statement.
3789
3790 // Traversal.
3791
3792 int
3793 Type_switch_statement::do_traverse(Traverse* traverse)
3794 {
3795   if (this->var_ == NULL)
3796     {
3797       if (this->traverse_expression(traverse, &this->expr_) == TRAVERSE_EXIT)
3798         return TRAVERSE_EXIT;
3799     }
3800   if (this->clauses_ != NULL)
3801     return this->clauses_->traverse(traverse);
3802   return TRAVERSE_CONTINUE;
3803 }
3804
3805 // Lower a type switch statement to a series of if statements.  The gc
3806 // compiler is able to generate a table in some cases.  However, that
3807 // does not work for us because we may have type descriptors in
3808 // different shared libraries, so we can't compare them with simple
3809 // equality testing.
3810
3811 Statement*
3812 Type_switch_statement::do_lower(Gogo*, Block* enclosing)
3813 {
3814   const source_location loc = this->location();
3815
3816   if (this->clauses_ != NULL)
3817     this->clauses_->check_duplicates();
3818
3819   Block* b = new Block(enclosing, loc);
3820
3821   Type* val_type = (this->var_ != NULL
3822                     ? this->var_->var_value()->type()
3823                     : this->expr_->type());
3824
3825   // var descriptor_temp DESCRIPTOR_TYPE
3826   Type* descriptor_type = Type::make_type_descriptor_ptr_type();
3827   Temporary_statement* descriptor_temp =
3828     Statement::make_temporary(descriptor_type, NULL, loc);
3829   b->add_statement(descriptor_temp);
3830
3831   if (val_type->interface_type() == NULL)
3832     {
3833       // Doing a type switch on a non-interface type.  Should we issue
3834       // a warning for this case?
3835       // descriptor_temp = DESCRIPTOR
3836       Expression* lhs = Expression::make_temporary_reference(descriptor_temp,
3837                                                              loc);
3838       Expression* rhs = Expression::make_type_descriptor(val_type, loc);
3839       Statement* s = Statement::make_assignment(lhs, rhs, loc);
3840       b->add_statement(s);
3841     }
3842   else
3843     {
3844       const source_location bloc = BUILTINS_LOCATION;
3845
3846       // func {efacetype,ifacetype}(*interface) *descriptor
3847       // FIXME: This should be inlined.
3848       Typed_identifier_list* param_types = new Typed_identifier_list();
3849       param_types->push_back(Typed_identifier("i", val_type, bloc));
3850       Typed_identifier_list* ret_types = new Typed_identifier_list();
3851       ret_types->push_back(Typed_identifier("", descriptor_type, bloc));
3852       Function_type* fntype = Type::make_function_type(NULL, param_types,
3853                                                        ret_types, bloc);
3854       bool is_empty = val_type->interface_type()->is_empty();
3855       const char* fnname = is_empty ? "efacetype" : "ifacetype";
3856       Named_object* fn =
3857         Named_object::make_function_declaration(fnname, NULL, fntype, bloc);
3858       const char* asm_name = (is_empty
3859                               ? "runtime.efacetype"
3860                               : "runtime.ifacetype");
3861       fn->func_declaration_value()->set_asm_name(asm_name);
3862
3863       // descriptor_temp = ifacetype(val_temp)
3864       Expression* func = Expression::make_func_reference(fn, NULL, loc);
3865       Expression_list* params = new Expression_list();
3866       Expression* ref;
3867       if (this->var_ == NULL)
3868         ref = this->expr_;
3869       else
3870         ref = Expression::make_var_reference(this->var_, loc);
3871       params->push_back(ref);
3872       Expression* call = Expression::make_call(func, params, false, loc);
3873       Expression* lhs = Expression::make_temporary_reference(descriptor_temp,
3874                                                              loc);
3875       Statement* s = Statement::make_assignment(lhs, call, loc);
3876       b->add_statement(s);
3877     }
3878
3879   if (this->clauses_ != NULL)
3880     this->clauses_->lower(b, descriptor_temp, this->break_label());
3881
3882   Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
3883   b->add_statement(s);
3884
3885   return Statement::make_block_statement(b, loc);
3886 }
3887
3888 // Return the break label for this type switch statement, creating it
3889 // if necessary.
3890
3891 Unnamed_label*
3892 Type_switch_statement::break_label()
3893 {
3894   if (this->break_label_ == NULL)
3895     this->break_label_ = new Unnamed_label(this->location());
3896   return this->break_label_;
3897 }
3898
3899 // Make a type switch statement.
3900
3901 Type_switch_statement*
3902 Statement::make_type_switch_statement(Named_object* var, Expression* expr,
3903                                       source_location location)
3904 {
3905   return new Type_switch_statement(var, expr, location);
3906 }
3907
3908 // Class Select_clauses::Select_clause.
3909
3910 // Traversal.
3911
3912 int
3913 Select_clauses::Select_clause::traverse(Traverse* traverse)
3914 {
3915   if (!this->is_lowered_
3916       && (traverse->traverse_mask() & Traverse::traverse_expressions) != 0)
3917     {
3918       if (this->channel_ != NULL)
3919         {
3920           if (Expression::traverse(&this->channel_, traverse) == TRAVERSE_EXIT)
3921             return TRAVERSE_EXIT;
3922         }
3923       if (this->val_ != NULL)
3924         {
3925           if (Expression::traverse(&this->val_, traverse) == TRAVERSE_EXIT)
3926             return TRAVERSE_EXIT;
3927         }
3928     }
3929   if (this->statements_ != NULL)
3930     {
3931       if (this->statements_->traverse(traverse) == TRAVERSE_EXIT)
3932         return TRAVERSE_EXIT;
3933     }
3934   return TRAVERSE_CONTINUE;
3935 }
3936
3937 // Lowering.  Here we pull out the channel and the send values, to
3938 // enforce the order of evaluation.  We also add explicit send and
3939 // receive statements to the clauses.
3940
3941 void
3942 Select_clauses::Select_clause::lower(Block* b)
3943 {
3944   if (this->is_default_)
3945     {
3946       gcc_assert(this->channel_ == NULL && this->val_ == NULL);
3947       this->is_lowered_ = true;
3948       return;
3949     }
3950
3951   source_location loc = this->location_;
3952
3953   // Evaluate the channel before the select statement.
3954   Temporary_statement* channel_temp = Statement::make_temporary(NULL,
3955                                                                 this->channel_,
3956                                                                 loc);
3957   b->add_statement(channel_temp);
3958   this->channel_ = Expression::make_temporary_reference(channel_temp, loc);
3959
3960   // If this is a send clause, evaluate the value to send before the
3961   // select statement.
3962   Temporary_statement* val_temp = NULL;
3963   if (this->is_send_)
3964     {
3965       val_temp = Statement::make_temporary(NULL, this->val_, loc);
3966       b->add_statement(val_temp);
3967     }
3968
3969   // Add the send or receive before the rest of the statements if any.
3970   Block *init = new Block(b, loc);
3971   Expression* ref = Expression::make_temporary_reference(channel_temp, loc);
3972   if (this->is_send_)
3973     {
3974       Expression* ref2 = Expression::make_temporary_reference(val_temp, loc);
3975       Send_expression* send = Expression::make_send(ref, ref2, loc);
3976       send->discarding_value();
3977       send->set_for_select();
3978       init->add_statement(Statement::make_statement(send));
3979     }
3980   else
3981     {
3982       Receive_expression* recv = Expression::make_receive(ref, loc);
3983       recv->set_for_select();
3984       if (this->val_ != NULL)
3985         {
3986           gcc_assert(this->var_ == NULL);
3987           init->add_statement(Statement::make_assignment(this->val_, recv,
3988                                                          loc));
3989         }
3990       else if (this->var_ != NULL)
3991         {
3992           this->var_->var_value()->set_init(recv);
3993           this->var_->var_value()->clear_type_from_chan_element();
3994         }
3995       else
3996         {
3997           recv->discarding_value();
3998           init->add_statement(Statement::make_statement(recv));
3999         }
4000     }
4001
4002   if (this->statements_ != NULL)
4003     init->add_statement(Statement::make_block_statement(this->statements_,
4004                                                         loc));
4005
4006   this->statements_ = init;
4007
4008   // Now all references should be handled through the statements, not
4009   // through here.
4010   this->is_lowered_ = true;
4011   this->val_ = NULL;
4012   this->var_ = NULL;
4013 }
4014
4015 // Determine types.
4016
4017 void
4018 Select_clauses::Select_clause::determine_types()
4019 {
4020   gcc_assert(this->is_lowered_);
4021   if (this->statements_ != NULL)
4022     this->statements_->determine_types();
4023 }
4024
4025 // Whether this clause may fall through to the statement which follows
4026 // the overall select statement.
4027
4028 bool
4029 Select_clauses::Select_clause::may_fall_through() const
4030 {
4031   if (this->statements_ == NULL)
4032     return true;
4033   return this->statements_->may_fall_through();
4034 }
4035
4036 // Return a tree for the statements to execute.
4037
4038 tree
4039 Select_clauses::Select_clause::get_statements_tree(Translate_context* context)
4040 {
4041   if (this->statements_ == NULL)
4042     return NULL_TREE;
4043   return this->statements_->get_tree(context);
4044 }
4045
4046 // Class Select_clauses.
4047
4048 // Traversal.
4049
4050 int
4051 Select_clauses::traverse(Traverse* traverse)
4052 {
4053   for (Clauses::iterator p = this->clauses_.begin();
4054        p != this->clauses_.end();
4055        ++p)
4056     {
4057       if (p->traverse(traverse) == TRAVERSE_EXIT)
4058         return TRAVERSE_EXIT;
4059     }
4060   return TRAVERSE_CONTINUE;
4061 }
4062
4063 // Lowering.  Here we pull out the channel and the send values, to
4064 // enforce the order of evaluation.  We also add explicit send and
4065 // receive statements to the clauses.
4066
4067 void
4068 Select_clauses::lower(Block* b)
4069 {
4070   for (Clauses::iterator p = this->clauses_.begin();
4071        p != this->clauses_.end();
4072        ++p)
4073     p->lower(b);
4074 }
4075
4076 // Determine types.
4077
4078 void
4079 Select_clauses::determine_types()
4080 {
4081   for (Clauses::iterator p = this->clauses_.begin();
4082        p != this->clauses_.end();
4083        ++p)
4084     p->determine_types();
4085 }
4086
4087 // Return whether these select clauses fall through to the statement
4088 // following the overall select statement.
4089
4090 bool
4091 Select_clauses::may_fall_through() const
4092 {
4093   for (Clauses::const_iterator p = this->clauses_.begin();
4094        p != this->clauses_.end();
4095        ++p)
4096     if (p->may_fall_through())
4097       return true;
4098   return false;
4099 }
4100
4101 // Return a tree.  We build a call to
4102 //   size_t __go_select(size_t count, _Bool has_default,
4103 //                      channel* channels, _Bool* is_send)
4104 //
4105 // There are COUNT entries in the CHANNELS and IS_SEND arrays.  The
4106 // value in the IS_SEND array is true for send, false for receive.
4107 // __go_select returns an integer from 0 to COUNT, inclusive.  A
4108 // return of 0 means that the default case should be run; this only
4109 // happens if HAS_DEFAULT is non-zero.  Otherwise the number indicates
4110 // the case to run.
4111
4112 // FIXME: This doesn't handle channels which send interface types
4113 // where the receiver has a static type which matches that interface.
4114
4115 tree
4116 Select_clauses::get_tree(Translate_context* context,
4117                          Unnamed_label *break_label,
4118                          source_location location)
4119 {
4120   size_t count = this->clauses_.size();
4121   VEC(constructor_elt, gc)* chan_init = VEC_alloc(constructor_elt, gc, count);
4122   VEC(constructor_elt, gc)* is_send_init = VEC_alloc(constructor_elt, gc,
4123                                                      count);
4124   Select_clause* default_clause = NULL;
4125   tree final_stmt_list = NULL_TREE;
4126   tree channel_type_tree = NULL_TREE;
4127
4128   size_t i = 0;
4129   for (Clauses::iterator p = this->clauses_.begin();
4130        p != this->clauses_.end();
4131        ++p)
4132     {
4133       if (p->is_default())
4134         {
4135           default_clause = &*p;
4136           --count;
4137           continue;
4138         }
4139
4140       tree channel_tree = p->channel()->get_tree(context);
4141       if (channel_tree == error_mark_node)
4142         return error_mark_node;
4143       channel_type_tree = TREE_TYPE(channel_tree);
4144
4145       constructor_elt* elt = VEC_quick_push(constructor_elt, chan_init, NULL);
4146       elt->index = build_int_cstu(sizetype, i);
4147       elt->value = channel_tree;
4148
4149       elt = VEC_quick_push(constructor_elt, is_send_init, NULL);
4150       elt->index = build_int_cstu(sizetype, i);
4151       elt->value = p->is_send() ? boolean_true_node : boolean_false_node;
4152
4153       ++i;
4154     }
4155   gcc_assert(i == count);
4156
4157   if (i == 0 && default_clause != NULL)
4158     {
4159       // There is only a default clause.
4160       gcc_assert(final_stmt_list == NULL_TREE);
4161       tree stmt_list = NULL_TREE;
4162       append_to_statement_list(default_clause->get_statements_tree(context),
4163                                &stmt_list);
4164       append_to_statement_list(break_label->get_definition(), &stmt_list);
4165       return stmt_list;
4166     }
4167
4168   tree pointer_chan_type_tree = (channel_type_tree == NULL_TREE
4169                                  ? ptr_type_node
4170                                  : build_pointer_type(channel_type_tree));
4171   tree chans_arg;
4172   tree pointer_boolean_type_tree = build_pointer_type(boolean_type_node);
4173   tree is_sends_arg;
4174
4175   if (i == 0)
4176     {
4177       chans_arg = fold_convert_loc(location, pointer_chan_type_tree,
4178                                    null_pointer_node);
4179       is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree,
4180                                       null_pointer_node);
4181     }
4182   else
4183     {
4184       tree index_type_tree = build_index_type(size_int(count - 1));
4185       tree chan_array_type_tree = build_array_type(channel_type_tree,
4186                                                    index_type_tree);
4187       tree chan_constructor = build_constructor(chan_array_type_tree,
4188                                                 chan_init);
4189       tree chan_var = create_tmp_var(chan_array_type_tree, "CHAN");
4190       DECL_IGNORED_P(chan_var) = 0;
4191       DECL_INITIAL(chan_var) = chan_constructor;
4192       DECL_SOURCE_LOCATION(chan_var) = location;
4193       TREE_ADDRESSABLE(chan_var) = 1;
4194       tree decl_expr = build1(DECL_EXPR, void_type_node, chan_var);
4195       SET_EXPR_LOCATION(decl_expr, location);
4196       append_to_statement_list(decl_expr, &final_stmt_list);
4197
4198       tree is_send_array_type_tree = build_array_type(boolean_type_node,
4199                                                       index_type_tree);
4200       tree is_send_constructor = build_constructor(is_send_array_type_tree,
4201                                                    is_send_init);
4202       tree is_send_var = create_tmp_var(is_send_array_type_tree, "ISSEND");
4203       DECL_IGNORED_P(is_send_var) = 0;
4204       DECL_INITIAL(is_send_var) = is_send_constructor;
4205       DECL_SOURCE_LOCATION(is_send_var) = location;
4206       TREE_ADDRESSABLE(is_send_var) = 1;
4207       decl_expr = build1(DECL_EXPR, void_type_node, is_send_var);
4208       SET_EXPR_LOCATION(decl_expr, location);
4209       append_to_statement_list(decl_expr, &final_stmt_list);
4210
4211       chans_arg = fold_convert_loc(location, pointer_chan_type_tree,
4212                                    build_fold_addr_expr_loc(location,
4213                                                             chan_var));
4214       is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree,
4215                                       build_fold_addr_expr_loc(location,
4216                                                                is_send_var));
4217     }
4218
4219   static tree select_fndecl;
4220   tree call = Gogo::call_builtin(&select_fndecl,
4221                                  location,
4222                                  "__go_select",
4223                                  4,
4224                                  sizetype,
4225                                  sizetype,
4226                                  size_int(count),
4227                                  boolean_type_node,
4228                                  (default_clause == NULL
4229                                   ? boolean_false_node
4230                                   : boolean_true_node),
4231                                  pointer_chan_type_tree,
4232                                  chans_arg,
4233                                  pointer_boolean_type_tree,
4234                                  is_sends_arg);
4235   if (call == error_mark_node)
4236     return error_mark_node;
4237
4238   tree stmt_list = NULL_TREE;
4239
4240   if (default_clause != NULL)
4241     this->add_clause_tree(context, 0, default_clause, break_label, &stmt_list);
4242
4243   i = 1;
4244   for (Clauses::iterator p = this->clauses_.begin();
4245        p != this->clauses_.end();
4246        ++p)
4247     {
4248       if (!p->is_default())
4249         {
4250           this->add_clause_tree(context, i, &*p, break_label, &stmt_list);
4251           ++i;
4252         }
4253     }
4254
4255   append_to_statement_list(break_label->get_definition(), &stmt_list);
4256
4257   tree switch_stmt = build3(SWITCH_EXPR, sizetype, call, stmt_list, NULL_TREE);
4258   SET_EXPR_LOCATION(switch_stmt, location);
4259   append_to_statement_list(switch_stmt, &final_stmt_list);
4260
4261   return final_stmt_list;
4262 }
4263
4264 // Add the tree for CLAUSE to STMT_LIST.
4265
4266 void
4267 Select_clauses::add_clause_tree(Translate_context* context, int case_index,
4268                                 Select_clause* clause,
4269                                 Unnamed_label* bottom_label, tree* stmt_list)
4270 {
4271   tree label = create_artificial_label(clause->location());
4272   append_to_statement_list(build3(CASE_LABEL_EXPR, void_type_node,
4273                                   build_int_cst(sizetype, case_index),
4274                                   NULL_TREE, label),
4275                            stmt_list);
4276   append_to_statement_list(clause->get_statements_tree(context), stmt_list);
4277   tree g = bottom_label->get_goto(clause->statements() == NULL
4278                                   ? clause->location()
4279                                   : clause->statements()->end_location());
4280   append_to_statement_list(g, stmt_list);
4281 }
4282
4283 // Class Select_statement.
4284
4285 // Return the break label for this switch statement, creating it if
4286 // necessary.
4287
4288 Unnamed_label*
4289 Select_statement::break_label()
4290 {
4291   if (this->break_label_ == NULL)
4292     this->break_label_ = new Unnamed_label(this->location());
4293   return this->break_label_;
4294 }
4295
4296 // Lower a select statement.  This will still return a select
4297 // statement, but it will be modified to implement the order of
4298 // evaluation rules, and to include the send and receive statements as
4299 // explicit statements in the clauses.
4300
4301 Statement*
4302 Select_statement::do_lower(Gogo*, Block* enclosing)
4303 {
4304   if (this->is_lowered_)
4305     return this;
4306   Block* b = new Block(enclosing, this->location());
4307   this->clauses_->lower(b);
4308   this->is_lowered_ = true;
4309   b->add_statement(this);
4310   return Statement::make_block_statement(b, this->location());
4311 }
4312
4313 // Return the tree for a select statement.
4314
4315 tree
4316 Select_statement::do_get_tree(Translate_context* context)
4317 {
4318   return this->clauses_->get_tree(context, this->break_label(),
4319                                   this->location());
4320 }
4321
4322 // Make a select statement.
4323
4324 Select_statement*
4325 Statement::make_select_statement(source_location location)
4326 {
4327   return new Select_statement(location);
4328 }
4329
4330 // Class For_statement.
4331
4332 // Traversal.
4333
4334 int
4335 For_statement::do_traverse(Traverse* traverse)
4336 {
4337   if (this->init_ != NULL)
4338     {
4339       if (this->init_->traverse(traverse) == TRAVERSE_EXIT)
4340         return TRAVERSE_EXIT;
4341     }
4342   if (this->cond_ != NULL)
4343     {
4344       if (this->traverse_expression(traverse, &this->cond_) == TRAVERSE_EXIT)
4345         return TRAVERSE_EXIT;
4346     }
4347   if (this->post_ != NULL)
4348     {
4349       if (this->post_->traverse(traverse) == TRAVERSE_EXIT)
4350         return TRAVERSE_EXIT;
4351     }
4352   return this->statements_->traverse(traverse);
4353 }
4354
4355 // Lower a For_statement into if statements and gotos.  Getting rid of
4356 // complex statements make it easier to handle garbage collection.
4357
4358 Statement*
4359 For_statement::do_lower(Gogo*, Block* enclosing)
4360 {
4361   Statement* s;
4362   source_location loc = this->location();
4363
4364   Block* b = new Block(enclosing, this->location());
4365   if (this->init_ != NULL)
4366     {
4367       s = Statement::make_block_statement(this->init_,
4368                                           this->init_->start_location());
4369       b->add_statement(s);
4370     }
4371
4372   Unnamed_label* entry = NULL;
4373   if (this->cond_ != NULL)
4374     {
4375       entry = new Unnamed_label(this->location());
4376       b->add_statement(Statement::make_goto_unnamed_statement(entry, loc));
4377     }
4378
4379   Unnamed_label* top = new Unnamed_label(this->location());
4380   b->add_statement(Statement::make_unnamed_label_statement(top));
4381
4382   s = Statement::make_block_statement(this->statements_,
4383                                       this->statements_->start_location());
4384   b->add_statement(s);
4385
4386   source_location end_loc = this->statements_->end_location();
4387
4388   Unnamed_label* cont = this->continue_label_;
4389   if (cont != NULL)
4390     b->add_statement(Statement::make_unnamed_label_statement(cont));
4391
4392   if (this->post_ != NULL)
4393     {
4394       s = Statement::make_block_statement(this->post_,
4395                                           this->post_->start_location());
4396       b->add_statement(s);
4397       end_loc = this->post_->end_location();
4398     }
4399
4400   if (this->cond_ == NULL)
4401     b->add_statement(Statement::make_goto_unnamed_statement(top, end_loc));
4402   else
4403     {
4404       b->add_statement(Statement::make_unnamed_label_statement(entry));
4405
4406       source_location cond_loc = this->cond_->location();
4407       Block* then_block = new Block(b, cond_loc);
4408       s = Statement::make_goto_unnamed_statement(top, cond_loc);
4409       then_block->add_statement(s);
4410
4411       s = Statement::make_if_statement(this->cond_, then_block, NULL, cond_loc);
4412       b->add_statement(s);
4413     }
4414
4415   Unnamed_label* brk = this->break_label_;
4416   if (brk != NULL)
4417     b->add_statement(Statement::make_unnamed_label_statement(brk));
4418
4419   b->set_end_location(end_loc);
4420
4421   return Statement::make_block_statement(b, loc);
4422 }
4423
4424 // Return the break label, creating it if necessary.
4425
4426 Unnamed_label*
4427 For_statement::break_label()
4428 {
4429   if (this->break_label_ == NULL)
4430     this->break_label_ = new Unnamed_label(this->location());
4431   return this->break_label_;
4432 }
4433
4434 // Return the continue LABEL_EXPR.
4435
4436 Unnamed_label*
4437 For_statement::continue_label()
4438 {
4439   if (this->continue_label_ == NULL)
4440     this->continue_label_ = new Unnamed_label(this->location());
4441   return this->continue_label_;
4442 }
4443
4444 // Set the break and continue labels a for statement.  This is used
4445 // when lowering a for range statement.
4446
4447 void
4448 For_statement::set_break_continue_labels(Unnamed_label* break_label,
4449                                          Unnamed_label* continue_label)
4450 {
4451   gcc_assert(this->break_label_ == NULL && this->continue_label_ == NULL);
4452   this->break_label_ = break_label;
4453   this->continue_label_ = continue_label;
4454 }
4455
4456 // Make a for statement.
4457
4458 For_statement*
4459 Statement::make_for_statement(Block* init, Expression* cond, Block* post,
4460                               source_location location)
4461 {
4462   return new For_statement(init, cond, post, location);
4463 }
4464
4465 // Class For_range_statement.
4466
4467 // Traversal.
4468
4469 int
4470 For_range_statement::do_traverse(Traverse* traverse)
4471 {
4472   if (this->traverse_expression(traverse, &this->index_var_) == TRAVERSE_EXIT)
4473     return TRAVERSE_EXIT;
4474   if (this->value_var_ != NULL)
4475     {
4476       if (this->traverse_expression(traverse, &this->value_var_)
4477           == TRAVERSE_EXIT)
4478         return TRAVERSE_EXIT;
4479     }
4480   if (this->traverse_expression(traverse, &this->range_) == TRAVERSE_EXIT)
4481     return TRAVERSE_EXIT;
4482   return this->statements_->traverse(traverse);
4483 }
4484
4485 // Lower a for range statement.  For simplicity we lower this into a
4486 // for statement, which will then be lowered in turn to goto
4487 // statements.
4488
4489 Statement*
4490 For_range_statement::do_lower(Gogo* gogo, Block* enclosing)
4491 {
4492   Type* range_type = this->range_->type();
4493   if (range_type->points_to() != NULL
4494       && range_type->points_to()->array_type() != NULL
4495       && !range_type->points_to()->is_open_array_type())
4496     range_type = range_type->points_to();
4497
4498   Type* index_type;
4499   Type* value_type = NULL;
4500   if (range_type->array_type() != NULL)
4501     {
4502       index_type = Type::lookup_integer_type("int");
4503       value_type = range_type->array_type()->element_type();
4504     }
4505   else if (range_type->is_string_type())
4506     {
4507       index_type = Type::lookup_integer_type("int");
4508       value_type = index_type;
4509     }
4510   else if (range_type->map_type() != NULL)
4511     {
4512       index_type = range_type->map_type()->key_type();
4513       value_type = range_type->map_type()->val_type();
4514     }
4515   else if (range_type->channel_type() != NULL)
4516     {
4517       index_type = range_type->channel_type()->element_type();
4518       if (this->value_var_ != NULL)
4519         {
4520           if (!this->value_var_->type()->is_error_type())
4521             this->report_error(_("too many variables for range clause "
4522                                  "with channel"));
4523           return Statement::make_error_statement(this->location());
4524         }
4525     }
4526   else
4527     {
4528       this->report_error(_("range clause must have "
4529                            "array, slice, setring, map, or channel type"));
4530       return Statement::make_error_statement(this->location());
4531     }
4532
4533   source_location loc = this->location();
4534   Block* temp_block = new Block(enclosing, loc);
4535
4536   Named_object* range_object = NULL;
4537   Temporary_statement* range_temp = NULL;
4538   Var_expression* ve = this->range_->var_expression();
4539   if (ve != NULL)
4540     range_object = ve->named_object();
4541   else
4542     {
4543       range_temp = Statement::make_temporary(NULL, this->range_, loc);
4544       temp_block->add_statement(range_temp);
4545     }
4546
4547   Temporary_statement* index_temp = Statement::make_temporary(index_type,
4548                                                               NULL, loc);
4549   temp_block->add_statement(index_temp);
4550
4551   Temporary_statement* value_temp = NULL;
4552   if (this->value_var_ != NULL)
4553     {
4554       value_temp = Statement::make_temporary(value_type, NULL, loc);
4555       temp_block->add_statement(value_temp);
4556     }
4557
4558   Block* body = new Block(temp_block, loc);
4559
4560   Block* init;
4561   Expression* cond;
4562   Block* iter_init;
4563   Block* post;
4564
4565   // Arrange to do a loop appropriate for the type.  We will produce
4566   //   for INIT ; COND ; POST {
4567   //           ITER_INIT
4568   //           INDEX = INDEX_TEMP
4569   //           VALUE = VALUE_TEMP // If there is a value
4570   //           original statements
4571   //   }
4572
4573   if (range_type->array_type() != NULL)
4574     this->lower_range_array(gogo, temp_block, body, range_object, range_temp,
4575                             index_temp, value_temp, &init, &cond, &iter_init,
4576                             &post);
4577   else if (range_type->is_string_type())
4578     this->lower_range_string(gogo, temp_block, body, range_object, range_temp,
4579                              index_temp, value_temp, &init, &cond, &iter_init,
4580                              &post);
4581   else if (range_type->map_type() != NULL)
4582     this->lower_range_map(gogo, temp_block, body, range_object, range_temp,
4583                           index_temp, value_temp, &init, &cond, &iter_init,
4584                           &post);
4585   else if (range_type->channel_type() != NULL)
4586     this->lower_range_channel(gogo, temp_block, body, range_object, range_temp,
4587                               index_temp, value_temp, &init, &cond, &iter_init,
4588                               &post);
4589   else
4590     gcc_unreachable();
4591
4592   if (iter_init != NULL)
4593     body->add_statement(Statement::make_block_statement(iter_init, loc));
4594
4595   Statement* assign;
4596   Expression* index_ref = Expression::make_temporary_reference(index_temp, loc);
4597   if (this->value_var_ == NULL)
4598     {
4599       assign = Statement::make_assignment(this->index_var_, index_ref, loc);
4600     }
4601   else
4602     {
4603       Expression_list* lhs = new Expression_list();
4604       lhs->push_back(this->index_var_);
4605       lhs->push_back(this->value_var_);
4606
4607       Expression_list* rhs = new Expression_list();
4608       rhs->push_back(index_ref);
4609       rhs->push_back(Expression::make_temporary_reference(value_temp, loc));
4610
4611       assign = Statement::make_tuple_assignment(lhs, rhs, loc);
4612     }
4613   body->add_statement(assign);
4614
4615   body->add_statement(Statement::make_block_statement(this->statements_, loc));
4616
4617   body->set_end_location(this->statements_->end_location());
4618
4619   For_statement* loop = Statement::make_for_statement(init, cond, post,
4620                                                       this->location());
4621   loop->add_statements(body);
4622   loop->set_break_continue_labels(this->break_label_, this->continue_label_);
4623
4624   temp_block->add_statement(loop);
4625
4626   return Statement::make_block_statement(temp_block, loc);
4627 }
4628
4629 // Return a reference to the range, which may be in RANGE_OBJECT or in
4630 // RANGE_TEMP.
4631
4632 Expression*
4633 For_range_statement::make_range_ref(Named_object* range_object,
4634                                     Temporary_statement* range_temp,
4635                                     source_location loc)
4636 {
4637   if (range_object != NULL)
4638     return Expression::make_var_reference(range_object, loc);
4639   else
4640     return Expression::make_temporary_reference(range_temp, loc);
4641 }
4642
4643 // Return a call to the predeclared function FUNCNAME passing a
4644 // reference to the temporary variable ARG.
4645
4646 Expression*
4647 For_range_statement::call_builtin(Gogo* gogo, const char* funcname,
4648                                   Expression* arg,
4649                                   source_location loc)
4650 {
4651   Named_object* no = gogo->lookup_global(funcname);
4652   gcc_assert(no != NULL && no->is_function_declaration());
4653   Expression* func = Expression::make_func_reference(no, NULL, loc);
4654   Expression_list* params = new Expression_list();
4655   params->push_back(arg);
4656   return Expression::make_call(func, params, false, loc);
4657 }
4658
4659 // Lower a for range over an array or slice.
4660
4661 void
4662 For_range_statement::lower_range_array(Gogo* gogo,
4663                                        Block* enclosing,
4664                                        Block* body_block,
4665                                        Named_object* range_object,
4666                                        Temporary_statement* range_temp,
4667                                        Temporary_statement* index_temp,
4668                                        Temporary_statement* value_temp,
4669                                        Block** pinit,
4670                                        Expression** pcond,
4671                                        Block** piter_init,
4672                                        Block** ppost)
4673 {
4674   source_location loc = this->location();
4675
4676   // The loop we generate:
4677   //   len_temp := len(range)
4678   //   for index_temp = 0; index_temp < len_temp; index_temp++ {
4679   //           value_temp = range[index_temp]
4680   //           index = index_temp
4681   //           value = value_temp
4682   //           original body
4683   //   }
4684
4685   // Set *PINIT to
4686   //   var len_temp int
4687   //   len_temp = len(range)
4688   //   index_temp = 0
4689
4690   Block* init = new Block(enclosing, loc);
4691
4692   Expression* ref = this->make_range_ref(range_object, range_temp, loc);
4693   Expression* len_call = this->call_builtin(gogo, "len", ref, loc);
4694   Temporary_statement* len_temp = Statement::make_temporary(index_temp->type(),
4695                                                             len_call, loc);
4696   init->add_statement(len_temp);
4697
4698   mpz_t zval;
4699   mpz_init_set_ui(zval, 0UL);
4700   Expression* zexpr = Expression::make_integer(&zval, NULL, loc);
4701   mpz_clear(zval);
4702
4703   ref = Expression::make_temporary_reference(index_temp, loc);
4704   Statement* s = Statement::make_assignment(ref, zexpr, loc);
4705   init->add_statement(s);
4706
4707   *pinit = init;
4708
4709   // Set *PCOND to
4710   //   index_temp < len_temp
4711
4712   ref = Expression::make_temporary_reference(index_temp, loc);
4713   Expression* ref2 = Expression::make_temporary_reference(len_temp, loc);
4714   Expression* lt = Expression::make_binary(OPERATOR_LT, ref, ref2, loc);
4715
4716   *pcond = lt;
4717
4718   // Set *PITER_INIT to
4719   //   value_temp = range[index_temp]
4720
4721   Block* iter_init = NULL;
4722   if (value_temp != NULL)
4723     {
4724       iter_init = new Block(body_block, loc);
4725
4726       ref = this->make_range_ref(range_object, range_temp, loc);
4727       Expression* ref2 = Expression::make_temporary_reference(index_temp, loc);
4728       Expression* index = Expression::make_index(ref, ref2, NULL, loc);
4729
4730       ref = Expression::make_temporary_reference(value_temp, loc);
4731       s = Statement::make_assignment(ref, index, loc);
4732
4733       iter_init->add_statement(s);
4734     }
4735   *piter_init = iter_init;
4736
4737   // Set *PPOST to
4738   //   index_temp++
4739
4740   Block* post = new Block(enclosing, loc);
4741   ref = Expression::make_temporary_reference(index_temp, loc);
4742   s = Statement::make_inc_statement(ref);
4743   post->add_statement(s);
4744   *ppost = post;
4745 }
4746
4747 // Lower a for range over a string.
4748
4749 void
4750 For_range_statement::lower_range_string(Gogo* gogo,
4751                                         Block* enclosing,
4752                                         Block* body_block,
4753                                         Named_object* range_object,
4754                                         Temporary_statement* range_temp,
4755                                         Temporary_statement* index_temp,
4756                                         Temporary_statement* value_temp,
4757                                         Block** pinit,
4758                                         Expression** pcond,
4759                                         Block** piter_init,
4760                                         Block** ppost)
4761 {
4762   source_location loc = this->location();
4763
4764   // The loop we generate:
4765   //   var next_index_temp int
4766   //   for index_temp = 0; ; index_temp = next_index_temp {
4767   //           next_index_temp, value_temp = stringiter2(range, index_temp)
4768   //           if next_index_temp == 0 {
4769   //                   break
4770   //           }
4771   //           index = index_temp
4772   //           value = value_temp
4773   //           original body
4774   //   }
4775
4776   // Set *PINIT to
4777   //   var next_index_temp int
4778   //   index_temp = 0
4779
4780   Block* init = new Block(enclosing, loc);
4781
4782   Temporary_statement* next_index_temp =
4783     Statement::make_temporary(index_temp->type(), NULL, loc);
4784   init->add_statement(next_index_temp);
4785
4786   mpz_t zval;
4787   mpz_init_set_ui(zval, 0UL);
4788   Expression* zexpr = Expression::make_integer(&zval, NULL, loc);
4789
4790   Expression* ref = Expression::make_temporary_reference(index_temp, loc);
4791   Statement* s = Statement::make_assignment(ref, zexpr, loc);
4792
4793   init->add_statement(s);
4794   *pinit = init;
4795
4796   // The loop has no condition.
4797
4798   *pcond = NULL;
4799
4800   // Set *PITER_INIT to
4801   //   next_index_temp = runtime.stringiter(range, index_temp)
4802   // or
4803   //   next_index_temp, value_temp = runtime.stringiter2(range, index_temp)
4804   // followed by
4805   //   if next_index_temp == 0 {
4806   //           break
4807   //   }
4808
4809   Block* iter_init = new Block(body_block, loc);
4810
4811   Named_object* no;
4812   if (value_temp == NULL)
4813     {
4814       static Named_object* stringiter;
4815       if (stringiter == NULL)
4816         {
4817           source_location bloc = BUILTINS_LOCATION;
4818           Type* int_type = gogo->lookup_global("int")->type_value();
4819
4820           Typed_identifier_list* params = new Typed_identifier_list();
4821           params->push_back(Typed_identifier("s", Type::make_string_type(),
4822                                              bloc));
4823           params->push_back(Typed_identifier("k", int_type, bloc));
4824
4825           Typed_identifier_list* results = new Typed_identifier_list();
4826           results->push_back(Typed_identifier("", int_type, bloc));
4827
4828           Function_type* fntype = Type::make_function_type(NULL, params,
4829                                                            results, bloc);
4830           stringiter = Named_object::make_function_declaration("stringiter",
4831                                                                NULL, fntype,
4832                                                                bloc);
4833           const char* n = "runtime.stringiter";
4834           stringiter->func_declaration_value()->set_asm_name(n);
4835         }
4836       no = stringiter;
4837     }
4838   else
4839     {
4840       static Named_object* stringiter2;
4841       if (stringiter2 == NULL)
4842         {
4843           source_location bloc = BUILTINS_LOCATION;
4844           Type* int_type = gogo->lookup_global("int")->type_value();
4845
4846           Typed_identifier_list* params = new Typed_identifier_list();
4847           params->push_back(Typed_identifier("s", Type::make_string_type(),
4848                                              bloc));
4849           params->push_back(Typed_identifier("k", int_type, bloc));
4850
4851           Typed_identifier_list* results = new Typed_identifier_list();
4852           results->push_back(Typed_identifier("", int_type, bloc));
4853           results->push_back(Typed_identifier("", int_type, bloc));
4854
4855           Function_type* fntype = Type::make_function_type(NULL, params,
4856                                                            results, bloc);
4857           stringiter2 = Named_object::make_function_declaration("stringiter",
4858                                                                 NULL, fntype,
4859                                                                 bloc);
4860           const char* n = "runtime.stringiter2";
4861           stringiter2->func_declaration_value()->set_asm_name(n);
4862         }
4863       no = stringiter2;
4864     }
4865
4866   Expression* func = Expression::make_func_reference(no, NULL, loc);
4867   Expression_list* params = new Expression_list();
4868   params->push_back(this->make_range_ref(range_object, range_temp, loc));
4869   params->push_back(Expression::make_temporary_reference(index_temp, loc));
4870   Call_expression* call = Expression::make_call(func, params, false, loc);
4871
4872   if (value_temp == NULL)
4873     {
4874       ref = Expression::make_temporary_reference(next_index_temp, loc);
4875       s = Statement::make_assignment(ref, call, loc);
4876     }
4877   else
4878     {
4879       Expression_list* lhs = new Expression_list();
4880       lhs->push_back(Expression::make_temporary_reference(next_index_temp,
4881                                                           loc));
4882       lhs->push_back(Expression::make_temporary_reference(value_temp, loc));
4883
4884       Expression_list* rhs = new Expression_list();
4885       rhs->push_back(Expression::make_call_result(call, 0));
4886       rhs->push_back(Expression::make_call_result(call, 1));
4887
4888       s = Statement::make_tuple_assignment(lhs, rhs, loc);
4889     }
4890   iter_init->add_statement(s);
4891
4892   ref = Expression::make_temporary_reference(next_index_temp, loc);
4893   zexpr = Expression::make_integer(&zval, NULL, loc);
4894   mpz_clear(zval);
4895   Expression* equals = Expression::make_binary(OPERATOR_EQEQ, ref, zexpr, loc);
4896
4897   Block* then_block = new Block(iter_init, loc);
4898   s = Statement::make_break_statement(this->break_label(), loc);
4899   then_block->add_statement(s);
4900
4901   s = Statement::make_if_statement(equals, then_block, NULL, loc);
4902   iter_init->add_statement(s);
4903
4904   *piter_init = iter_init;
4905
4906   // Set *PPOST to
4907   //   index_temp = next_index_temp
4908
4909   Block* post = new Block(enclosing, loc);
4910
4911   Expression* lhs = Expression::make_temporary_reference(index_temp, loc);
4912   Expression* rhs = Expression::make_temporary_reference(next_index_temp, loc);
4913   s = Statement::make_assignment(lhs, rhs, loc);
4914
4915   post->add_statement(s);
4916   *ppost = post;
4917 }
4918
4919 // Lower a for range over a map.
4920
4921 void
4922 For_range_statement::lower_range_map(Gogo* gogo,
4923                                      Block* enclosing,
4924                                      Block* body_block,
4925                                      Named_object* range_object,
4926                                      Temporary_statement* range_temp,
4927                                      Temporary_statement* index_temp,
4928                                      Temporary_statement* value_temp,
4929                                      Block** pinit,
4930                                      Expression** pcond,
4931                                      Block** piter_init,
4932                                      Block** ppost)
4933 {
4934   source_location loc = this->location();
4935
4936   // The runtime uses a struct to handle ranges over a map.  The
4937   // struct is four pointers long.  The first pointer is NULL when we
4938   // have completed the iteration.
4939
4940   // The loop we generate:
4941   //   var hiter map_iteration_struct
4942   //   for mapiterinit(range, &hiter); hiter[0] != nil; mapiternext(&hiter) {
4943   //           mapiter2(hiter, &index_temp, &value_temp)
4944   //           index = index_temp
4945   //           value = value_temp
4946   //           original body
4947   //   }
4948
4949   // Set *PINIT to
4950   //   var hiter map_iteration_struct
4951   //   runtime.mapiterinit(range, &hiter)
4952
4953   Block* init = new Block(enclosing, loc);
4954
4955   const unsigned long map_iteration_size = 4;
4956
4957   mpz_t ival;
4958   mpz_init_set_ui(ival, map_iteration_size);
4959   Expression* iexpr = Expression::make_integer(&ival, NULL, loc);
4960   mpz_clear(ival);
4961
4962   Type* byte_type = gogo->lookup_global("byte")->type_value();
4963   Type* ptr_type = Type::make_pointer_type(byte_type);
4964
4965   Type* map_iteration_type = Type::make_array_type(ptr_type, iexpr);
4966   Type* map_iteration_ptr = Type::make_pointer_type(map_iteration_type);
4967
4968   Temporary_statement* hiter = Statement::make_temporary(map_iteration_type,
4969                                                          NULL, loc);
4970   init->add_statement(hiter);
4971
4972   source_location bloc = BUILTINS_LOCATION;
4973   Typed_identifier_list* param_types = new Typed_identifier_list();
4974   param_types->push_back(Typed_identifier("map", this->range_->type(), bloc));
4975   param_types->push_back(Typed_identifier("it", map_iteration_ptr, bloc));
4976   Function_type* fntype = Type::make_function_type(NULL, param_types, NULL,
4977                                                    bloc);
4978
4979   Named_object* mapiterinit =
4980     Named_object::make_function_declaration("mapiterinit", NULL, fntype, bloc);
4981   const char* n = "runtime.mapiterinit";
4982   mapiterinit->func_declaration_value()->set_asm_name(n);
4983
4984   Expression* func = Expression::make_func_reference(mapiterinit, NULL, loc);
4985   Expression_list* params = new Expression_list();
4986   params->push_back(this->make_range_ref(range_object, range_temp, loc));
4987   Expression* ref = Expression::make_temporary_reference(hiter, loc);
4988   params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc));
4989   Expression* call = Expression::make_call(func, params, false, loc);
4990   init->add_statement(Statement::make_statement(call));
4991
4992   *pinit = init;
4993
4994   // Set *PCOND to
4995   //   hiter[0] != nil
4996
4997   ref = Expression::make_temporary_reference(hiter, loc);
4998
4999   mpz_t zval;
5000   mpz_init_set_ui(zval, 0UL);
5001   Expression* zexpr = Expression::make_integer(&zval, NULL, loc);
5002   mpz_clear(zval);
5003
5004   Expression* index = Expression::make_index(ref, zexpr, NULL, loc);
5005
5006   Expression* ne = Expression::make_binary(OPERATOR_NOTEQ, index,
5007                                            Expression::make_nil(loc),
5008                                            loc);
5009
5010   *pcond = ne;
5011
5012   // Set *PITER_INIT to
5013   //   mapiter1(hiter, &index_temp)
5014   // or
5015   //   mapiter2(hiter, &index_temp, &value_temp)
5016
5017   Block* iter_init = new Block(body_block, loc);
5018
5019   param_types = new Typed_identifier_list();
5020   param_types->push_back(Typed_identifier("hiter", map_iteration_ptr, bloc));
5021   Type* pkey_type = Type::make_pointer_type(index_temp->type());
5022   param_types->push_back(Typed_identifier("key", pkey_type, bloc));
5023   if (value_temp != NULL)
5024     {
5025       Type* pval_type = Type::make_pointer_type(value_temp->type());
5026       param_types->push_back(Typed_identifier("val", pval_type, bloc));
5027     }
5028   fntype = Type::make_function_type(NULL, param_types, NULL, bloc);
5029   n = value_temp == NULL ? "mapiter1" : "mapiter2";
5030   Named_object* mapiter = Named_object::make_function_declaration(n, NULL,
5031                                                                   fntype, bloc);
5032   n = value_temp == NULL ? "runtime.mapiter1" : "runtime.mapiter2";
5033   mapiter->func_declaration_value()->set_asm_name(n);
5034
5035   func = Expression::make_func_reference(mapiter, NULL, loc);
5036   params = new Expression_list();
5037   ref = Expression::make_temporary_reference(hiter, loc);
5038   params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc));
5039   ref = Expression::make_temporary_reference(index_temp, loc);
5040   params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc));
5041   if (value_temp != NULL)
5042     {
5043       ref = Expression::make_temporary_reference(value_temp, loc);
5044       params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc));
5045     }
5046   call = Expression::make_call(func, params, false, loc);
5047   iter_init->add_statement(Statement::make_statement(call));
5048
5049   *piter_init = iter_init;
5050
5051   // Set *PPOST to
5052   //   mapiternext(&hiter)
5053
5054   Block* post = new Block(enclosing, loc);
5055
5056   static Named_object* mapiternext;
5057   if (mapiternext == NULL)
5058     {
5059       param_types = new Typed_identifier_list();
5060       param_types->push_back(Typed_identifier("it", map_iteration_ptr, bloc));
5061       fntype = Type::make_function_type(NULL, param_types, NULL, bloc);
5062       mapiternext = Named_object::make_function_declaration("mapiternext",
5063                                                             NULL, fntype,
5064                                                             bloc);
5065       const char* n = "runtime.mapiternext";
5066       mapiternext->func_declaration_value()->set_asm_name(n);
5067     }
5068
5069   func = Expression::make_func_reference(mapiternext, NULL, loc);
5070   params = new Expression_list();
5071   ref = Expression::make_temporary_reference(hiter, loc);
5072   params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc));
5073   call = Expression::make_call(func, params, false, loc);
5074   post->add_statement(Statement::make_statement(call));
5075
5076   *ppost = post;
5077 }
5078
5079 // Lower a for range over a channel.
5080
5081 void
5082 For_range_statement::lower_range_channel(Gogo* gogo,
5083                                          Block*,
5084                                          Block* body_block,
5085                                          Named_object* range_object,
5086                                          Temporary_statement* range_temp,
5087                                          Temporary_statement* index_temp,
5088                                          Temporary_statement* value_temp,
5089                                          Block** pinit,
5090                                          Expression** pcond,
5091                                          Block** piter_init,
5092                                          Block** ppost)
5093 {
5094   gcc_assert(value_temp == NULL);
5095
5096   source_location loc = this->location();
5097
5098   // The loop we generate:
5099   //   for {
5100   //           index_temp = <-range
5101   //           if closed(range) {
5102   //                   break
5103   //           }
5104   //           index = index_temp
5105   //           value = value_temp
5106   //           original body
5107   //   }
5108
5109   // We have no initialization code, no condition, and no post code.
5110
5111   *pinit = NULL;
5112   *pcond = NULL;
5113   *ppost = NULL;
5114
5115   // Set *PITER_INIT to
5116   //   index_temp = <-range
5117   //   if closed(range) {
5118   //           break
5119   //   }
5120
5121   Block* iter_init = new Block(body_block, loc);
5122
5123   Expression* ref = this->make_range_ref(range_object, range_temp, loc);
5124   Expression* cond = this->call_builtin(gogo, "closed", ref, loc);
5125
5126   ref = this->make_range_ref(range_object, range_temp, loc);
5127   Expression* recv = Expression::make_receive(ref, loc);
5128   ref = Expression::make_temporary_reference(index_temp, loc);
5129   Statement* s = Statement::make_assignment(ref, recv, loc);
5130   iter_init->add_statement(s);
5131
5132   Block* then_block = new Block(iter_init, loc);
5133   s = Statement::make_break_statement(this->break_label(), loc);
5134   then_block->add_statement(s);
5135
5136   s = Statement::make_if_statement(cond, then_block, NULL, loc);
5137   iter_init->add_statement(s);
5138
5139   *piter_init = iter_init;
5140 }
5141
5142 // Return the break LABEL_EXPR.
5143
5144 Unnamed_label*
5145 For_range_statement::break_label()
5146 {
5147   if (this->break_label_ == NULL)
5148     this->break_label_ = new Unnamed_label(this->location());
5149   return this->break_label_;
5150 }
5151
5152 // Return the continue LABEL_EXPR.
5153
5154 Unnamed_label*
5155 For_range_statement::continue_label()
5156 {
5157   if (this->continue_label_ == NULL)
5158     this->continue_label_ = new Unnamed_label(this->location());
5159   return this->continue_label_;
5160 }
5161
5162 // Make a for statement with a range clause.
5163
5164 For_range_statement*
5165 Statement::make_for_range_statement(Expression* index_var,
5166                                     Expression* value_var,
5167                                     Expression* range,
5168                                     source_location location)
5169 {
5170   return new For_range_statement(index_var, value_var, range, location);
5171 }