1 // statements.h -- Go frontend statements.     -*- C++ -*-
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 #ifndef GO_STATEMENTS_H
8 #define GO_STATEMENTS_H
9 
10 #include "operator.h"
11 
12 class Gogo;
13 class Traverse;
14 class Statement_inserter;
15 class Block;
16 class Function;
17 class Unnamed_label;
18 class Assignment_statement;
19 class Temporary_statement;
20 class Variable_declaration_statement;
21 class Expression_statement;
22 class Block_statement;
23 class Return_statement;
24 class Thunk_statement;
25 class Goto_statement;
26 class Goto_unnamed_statement;
27 class Label_statement;
28 class Unnamed_label_statement;
29 class If_statement;
30 class For_statement;
31 class For_range_statement;
32 class Switch_statement;
33 class Type_switch_statement;
34 class Send_statement;
35 class Select_statement;
36 class Variable;
37 class Named_object;
38 class Label;
39 class Translate_context;
40 class Expression;
41 class Expression_list;
42 class Struct_type;
43 class Call_expression;
44 class Map_index_expression;
45 class Receive_expression;
46 class Case_clauses;
47 class Type_case_clauses;
48 class Select_clauses;
49 class Typed_identifier_list;
50 class Bexpression;
51 class Bstatement;
52 class Bvariable;
53 class Ast_dump_context;
54 
55 // This class is used to traverse assignments made by a statement
56 // which makes assignments.
57 
58 class Traverse_assignments
59 {
60  public:
Traverse_assignments()61   Traverse_assignments()
62   { }
63 
~Traverse_assignments()64   virtual ~Traverse_assignments()
65   { }
66 
67   // This is called for a variable initialization.
68   virtual void
69   initialize_variable(Named_object*) = 0;
70 
71   // This is called for each assignment made by the statement.  PLHS
72   // points to the left hand side, and PRHS points to the right hand
73   // side.  PRHS may be NULL if there is no associated expression, as
74   // in the bool set by a non-blocking receive.
75   virtual void
76   assignment(Expression** plhs, Expression** prhs) = 0;
77 
78   // This is called for each expression which is not passed to the
79   // assignment function.  This is used for some of the statements
80   // which assign two values, for which there is no expression which
81   // describes the value.  For ++ and -- the value is passed to both
82   // the assignment method and the rhs method.  IS_STORED is true if
83   // this value is being stored directly.  It is false if the value is
84   // computed but not stored.  IS_LOCAL is true if the value is being
85   // stored in a local variable or this is being called by a return
86   // statement.
87   virtual void
88   value(Expression**, bool is_stored, bool is_local) = 0;
89 };
90 
91 // A single statement.
92 
93 class Statement
94 {
95  public:
96   // The types of statements.
97   enum Statement_classification
98   {
99     STATEMENT_ERROR,
100     STATEMENT_VARIABLE_DECLARATION,
101     STATEMENT_TEMPORARY,
102     STATEMENT_ASSIGNMENT,
103     STATEMENT_EXPRESSION,
104     STATEMENT_BLOCK,
105     STATEMENT_GO,
106     STATEMENT_DEFER,
107     STATEMENT_RETURN,
108     STATEMENT_BREAK_OR_CONTINUE,
109     STATEMENT_GOTO,
110     STATEMENT_GOTO_UNNAMED,
111     STATEMENT_LABEL,
112     STATEMENT_UNNAMED_LABEL,
113     STATEMENT_IF,
114     STATEMENT_CONSTANT_SWITCH,
115     STATEMENT_SEND,
116     STATEMENT_SELECT,
117 
118     // These statements types are created by the parser, but they
119     // disappear during the lowering pass.
120     STATEMENT_ASSIGNMENT_OPERATION,
121     STATEMENT_TUPLE_ASSIGNMENT,
122     STATEMENT_TUPLE_MAP_ASSIGNMENT,
123     STATEMENT_TUPLE_RECEIVE_ASSIGNMENT,
124     STATEMENT_TUPLE_TYPE_GUARD_ASSIGNMENT,
125     STATEMENT_INCDEC,
126     STATEMENT_FOR,
127     STATEMENT_FOR_RANGE,
128     STATEMENT_SWITCH,
129     STATEMENT_TYPE_SWITCH
130   };
131 
132   Statement(Statement_classification, Location);
133 
134   virtual ~Statement();
135 
136   // Make a variable declaration.
137   static Statement*
138   make_variable_declaration(Named_object*);
139 
140   // Make a statement which creates a temporary variable and
141   // initializes it to an expression.  The block is used if the
142   // temporary variable has to be explicitly destroyed; the variable
143   // must still be added to the block.  References to the temporary
144   // variable may be constructed using make_temporary_reference.
145   // Either the type or the initialization expression may be NULL, but
146   // not both.
147   static Temporary_statement*
148   make_temporary(Type*, Expression*, Location);
149 
150   // Make an assignment statement.
151   static Statement*
152   make_assignment(Expression*, Expression*, Location);
153 
154   // Make an assignment operation (+=, etc.).
155   static Statement*
156   make_assignment_operation(Operator, Expression*, Expression*,
157 			    Location);
158 
159   // Make a tuple assignment statement.
160   static Statement*
161   make_tuple_assignment(Expression_list*, Expression_list*, Location);
162 
163   // Make an assignment from a map index to a pair of variables.
164   static Statement*
165   make_tuple_map_assignment(Expression* val, Expression* present,
166 			    Expression*, Location);
167 
168   // Make an assignment from a nonblocking receive to a pair of
169   // variables.
170   static Statement*
171   make_tuple_receive_assignment(Expression* val, Expression* closed,
172 				Expression* channel, Location);
173 
174   // Make an assignment from a type guard to a pair of variables.
175   static Statement*
176   make_tuple_type_guard_assignment(Expression* val, Expression* ok,
177 				   Expression* expr, Type* type,
178 				   Location);
179 
180   // Make an expression statement from an Expression.  IS_IGNORED is
181   // true if the value is being explicitly ignored, as in an
182   // assignment to _.
183   static Statement*
184   make_statement(Expression*, bool is_ignored);
185 
186   // Make a block statement from a Block.  This is an embedded list of
187   // statements which may also include variable definitions.
188   static Statement*
189   make_block_statement(Block*, Location);
190 
191   // Make an increment statement.
192   static Statement*
193   make_inc_statement(Expression*);
194 
195   // Make a decrement statement.
196   static Statement*
197   make_dec_statement(Expression*);
198 
199   // Make a go statement.
200   static Statement*
201   make_go_statement(Call_expression* call, Location);
202 
203   // Make a defer statement.
204   static Statement*
205   make_defer_statement(Call_expression* call, Location);
206 
207   // Make a return statement.
208   static Return_statement*
209   make_return_statement(Expression_list*, Location);
210 
211   // Make a statement that returns the result of a call expression.
212   // If the call does not return any results, this just returns the
213   // call expression as a statement, assuming that the function will
214   // end immediately afterward.
215   static Statement*
216   make_return_from_call(Call_expression*, Location);
217 
218   // Make a break statement.
219   static Statement*
220   make_break_statement(Unnamed_label* label, Location);
221 
222   // Make a continue statement.
223   static Statement*
224   make_continue_statement(Unnamed_label* label, Location);
225 
226   // Make a goto statement.
227   static Statement*
228   make_goto_statement(Label* label, Location);
229 
230   // Make a goto statement to an unnamed label.
231   static Statement*
232   make_goto_unnamed_statement(Unnamed_label* label, Location);
233 
234   // Make a label statement--where the label is defined.
235   static Statement*
236   make_label_statement(Label* label, Location);
237 
238   // Make an unnamed label statement--where the label is defined.
239   static Statement*
240   make_unnamed_label_statement(Unnamed_label* label);
241 
242   // Make an if statement.
243   static Statement*
244   make_if_statement(Expression* cond, Block* then_block, Block* else_block,
245 		    Location);
246 
247   // Make a switch statement.
248   static Switch_statement*
249   make_switch_statement(Expression* switch_val, Location);
250 
251   // Make a type switch statement.
252   static Type_switch_statement*
253   make_type_switch_statement(const std::string&, Expression*, Location);
254 
255   // Make a send statement.
256   static Send_statement*
257   make_send_statement(Expression* channel, Expression* val, Location);
258 
259   // Make a select statement.
260   static Select_statement*
261   make_select_statement(Location);
262 
263   // Make a for statement.
264   static For_statement*
265   make_for_statement(Block* init, Expression* cond, Block* post,
266 		     Location location);
267 
268   // Make a for statement with a range clause.
269   static For_range_statement*
270   make_for_range_statement(Expression* index_var, Expression* value_var,
271 			   Expression* range, Location);
272 
273   // Return the statement classification.
274   Statement_classification
classification()275   classification() const
276   { return this->classification_; }
277 
278   // Get the statement location.
279   Location
location()280   location() const
281   { return this->location_; }
282 
283   // Traverse the tree.
284   int
285   traverse(Block*, size_t* index, Traverse*);
286 
287   // Traverse the contents of this statement--the expressions and
288   // statements which it contains.
289   int
290   traverse_contents(Traverse*);
291 
292   // If this statement assigns some values, it calls a function for
293   // each value to which this statement assigns a value, and returns
294   // true.  If this statement does not assign any values, it returns
295   // false.
296   bool
297   traverse_assignments(Traverse_assignments* tassign);
298 
299   // Lower a statement.  This is called immediately after parsing to
300   // simplify statements for further processing.  It returns the same
301   // Statement or a new one.  FUNCTION is the function containing this
302   // statement.  BLOCK is the block containing this statement.
303   // INSERTER can be used to insert new statements before this one.
304   Statement*
lower(Gogo * gogo,Named_object * function,Block * block,Statement_inserter * inserter)305   lower(Gogo* gogo, Named_object* function, Block* block,
306 	Statement_inserter* inserter)
307   { return this->do_lower(gogo, function, block, inserter); }
308 
309   // Flatten a statement.  This is called immediately after the order of
310   // evaluation rules are applied to statements.  It returns the same
311   // Statement or a new one.  FUNCTION is the function containing this
312   // statement.  BLOCK is the block containing this statement.
313   // INSERTER can be used to insert new statements before this one.
314   Statement*
flatten(Gogo * gogo,Named_object * function,Block * block,Statement_inserter * inserter)315   flatten(Gogo* gogo, Named_object* function, Block* block,
316           Statement_inserter* inserter)
317   { return this->do_flatten(gogo, function, block, inserter); }
318 
319   // Set type information for unnamed constants.
320   void
321   determine_types();
322 
323   // Check types in a statement.  This simply checks that any
324   // expressions used by the statement have the right type.
325   void
check_types(Gogo * gogo)326   check_types(Gogo* gogo)
327   { this->do_check_types(gogo); }
328 
329   // Return whether this is a block statement.
330   bool
is_block_statement()331   is_block_statement() const
332   { return this->classification_ == STATEMENT_BLOCK; }
333 
334   // If this is an assignment statement, return it.  Otherwise return
335   // NULL.
336   Assignment_statement*
assignment_statement()337   assignment_statement()
338   {
339     return this->convert<Assignment_statement, STATEMENT_ASSIGNMENT>();
340   }
341 
342   // If this is an temporary statement, return it.  Otherwise return
343   // NULL.
344   Temporary_statement*
temporary_statement()345   temporary_statement()
346   {
347     return this->convert<Temporary_statement, STATEMENT_TEMPORARY>();
348   }
349 
350   // If this is a variable declaration statement, return it.
351   // Otherwise return NULL.
352   Variable_declaration_statement*
variable_declaration_statement()353   variable_declaration_statement()
354   {
355     return this->convert<Variable_declaration_statement,
356 			 STATEMENT_VARIABLE_DECLARATION>();
357   }
358 
359   // If this is an expression statement, return it.  Otherwise return
360   // NULL.
361   Expression_statement*
expression_statement()362   expression_statement()
363   {
364     return this->convert<Expression_statement, STATEMENT_EXPRESSION>();
365   }
366 
367   // If this is an block statement, return it.  Otherwise return
368   // NULL.
369   Block_statement*
block_statement()370   block_statement()
371   { return this->convert<Block_statement, STATEMENT_BLOCK>(); }
372 
373   // If this is a return statement, return it.  Otherwise return NULL.
374   Return_statement*
return_statement()375   return_statement()
376   { return this->convert<Return_statement, STATEMENT_RETURN>(); }
377 
378   // If this is a thunk statement (a go or defer statement), return
379   // it.  Otherwise return NULL.
380   Thunk_statement*
381   thunk_statement();
382 
383   // If this is a goto statement, return it.  Otherwise return NULL.
384   Goto_statement*
goto_statement()385   goto_statement()
386   { return this->convert<Goto_statement, STATEMENT_GOTO>(); }
387 
388   // If this is a goto_unnamed statement, return it.  Otherwise return NULL.
389   Goto_unnamed_statement*
goto_unnamed_statement()390   goto_unnamed_statement()
391   { return this->convert<Goto_unnamed_statement, STATEMENT_GOTO_UNNAMED>(); }
392 
393   // If this is a label statement, return it.  Otherwise return NULL.
394   Label_statement*
label_statement()395   label_statement()
396   { return this->convert<Label_statement, STATEMENT_LABEL>(); }
397 
398   // If this is an unnamed_label statement, return it.  Otherwise return NULL.
399   Unnamed_label_statement*
unnamed_label_statement()400   unnamed_label_statement()
401   { return this->convert<Unnamed_label_statement, STATEMENT_UNNAMED_LABEL>(); }
402 
403   // If this is an if statement, return it.  Otherwise return NULL.
404   If_statement*
if_statement()405   if_statement()
406   { return this->convert<If_statement, STATEMENT_IF>(); }
407 
408   // If this is a for statement, return it.  Otherwise return NULL.
409   For_statement*
for_statement()410   for_statement()
411   { return this->convert<For_statement, STATEMENT_FOR>(); }
412 
413   // If this is a for statement over a range clause, return it.
414   // Otherwise return NULL.
415   For_range_statement*
for_range_statement()416   for_range_statement()
417   { return this->convert<For_range_statement, STATEMENT_FOR_RANGE>(); }
418 
419   // If this is a switch statement, return it.  Otherwise return NULL.
420   Switch_statement*
switch_statement()421   switch_statement()
422   { return this->convert<Switch_statement, STATEMENT_SWITCH>(); }
423 
424   // If this is a type switch statement, return it.  Otherwise return
425   // NULL.
426   Type_switch_statement*
type_switch_statement()427   type_switch_statement()
428   { return this->convert<Type_switch_statement, STATEMENT_TYPE_SWITCH>(); }
429 
430   // If this is a send statement, return it.  Otherwise return NULL.
431   Send_statement*
send_statement()432   send_statement()
433   { return this->convert<Send_statement, STATEMENT_SEND>(); }
434 
435   // If this is a select statement, return it.  Otherwise return NULL.
436   Select_statement*
select_statement()437   select_statement()
438   { return this->convert<Select_statement, STATEMENT_SELECT>(); }
439 
440   // Return true if this statement may fall through--if after
441   // executing this statement we may go on to execute the following
442   // statement, if any.
443   bool
may_fall_through()444   may_fall_through() const
445   { return this->do_may_fall_through(); }
446 
447   // Convert the statement to the backend representation.
448   Bstatement*
449   get_backend(Translate_context*);
450 
451   // Dump AST representation of a statement to a dump context.
452   void
453   dump_statement(Ast_dump_context*) const;
454 
455  protected:
456   // Implemented by child class: traverse the tree.
457   virtual int
458   do_traverse(Traverse*) = 0;
459 
460   // Implemented by child class: traverse assignments.  Any statement
461   // which includes an assignment should implement this.
462   virtual bool
do_traverse_assignments(Traverse_assignments *)463   do_traverse_assignments(Traverse_assignments*)
464   { return false; }
465 
466   // Implemented by the child class: lower this statement to a simpler
467   // one.
468   virtual Statement*
do_lower(Gogo *,Named_object *,Block *,Statement_inserter *)469   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
470   { return this; }
471 
472   // Implemented by the child class: lower this statement to a simpler
473   // one.
474   virtual Statement*
do_flatten(Gogo *,Named_object *,Block *,Statement_inserter *)475   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*)
476   { return this; }
477 
478   // Implemented by child class: set type information for unnamed
479   // constants.  Any statement which includes an expression needs to
480   // implement this.
481   virtual void
do_determine_types()482   do_determine_types()
483   { }
484 
485   // Implemented by child class: check types of expressions used in a
486   // statement.
487   virtual void
do_check_types(Gogo *)488   do_check_types(Gogo*)
489   { }
490 
491   // Implemented by child class: return true if this statement may
492   // fall through.
493   virtual bool
do_may_fall_through()494   do_may_fall_through() const
495   { return true; }
496 
497   // Implemented by child class: convert to backend representation.
498   virtual Bstatement*
499   do_get_backend(Translate_context*) = 0;
500 
501   // Implemented by child class: dump ast representation.
502   virtual void
503   do_dump_statement(Ast_dump_context*) const = 0;
504 
505   // Traverse an expression in a statement.
506   int
507   traverse_expression(Traverse*, Expression**);
508 
509   // Traverse an expression list in a statement.  The Expression_list
510   // may be NULL.
511   int
512   traverse_expression_list(Traverse*, Expression_list*);
513 
514   // Traverse a type in a statement.
515   int
516   traverse_type(Traverse*, Type*);
517 
518   // For children to call when they detect that they are in error.
519   void
520   set_is_error();
521 
522   // For children to call to report an error conveniently.
523   void
524   report_error(const char*);
525 
526   // For children to return an error statement from lower().
527   static Statement*
528   make_error_statement(Location);
529 
530  private:
531   // Convert to the desired statement classification, or return NULL.
532   // This is a controlled dynamic cast.
533   template<typename Statement_class, Statement_classification sc>
534   Statement_class*
convert()535   convert()
536   {
537     return (this->classification_ == sc
538 	    ? static_cast<Statement_class*>(this)
539 	    : NULL);
540   }
541 
542   template<typename Statement_class, Statement_classification sc>
543   const Statement_class*
convert()544   convert() const
545   {
546     return (this->classification_ == sc
547 	    ? static_cast<const Statement_class*>(this)
548 	    : NULL);
549   }
550 
551   // The statement classification.
552   Statement_classification classification_;
553   // The location in the input file of the start of this statement.
554   Location location_;
555 };
556 
557 // An assignment statement.
558 
559 class Assignment_statement : public Statement
560 {
561  public:
Assignment_statement(Expression * lhs,Expression * rhs,Location location)562   Assignment_statement(Expression* lhs, Expression* rhs,
563 		       Location location)
564     : Statement(STATEMENT_ASSIGNMENT, location),
565       lhs_(lhs), rhs_(rhs)
566   { }
567 
568   Expression*
lhs()569   lhs() const
570   { return this->lhs_; }
571 
572   Expression*
rhs()573   rhs() const
574   { return this->rhs_; }
575 
576  protected:
577   int
578   do_traverse(Traverse* traverse);
579 
580   bool
581   do_traverse_assignments(Traverse_assignments*);
582 
583   virtual Statement*
584   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
585 
586   void
587   do_determine_types();
588 
589   void
590   do_check_types(Gogo*);
591 
592   Statement*
593   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
594 
595   Bstatement*
596   do_get_backend(Translate_context*);
597 
598   void
599   do_dump_statement(Ast_dump_context*) const;
600 
601  private:
602   // Left hand side--the lvalue.
603   Expression* lhs_;
604   // Right hand side--the rvalue.
605   Expression* rhs_;
606 };
607 
608 // A statement which creates and initializes a temporary variable.
609 
610 class Temporary_statement : public Statement
611 {
612  public:
Temporary_statement(Type * type,Expression * init,Location location)613   Temporary_statement(Type* type, Expression* init, Location location)
614     : Statement(STATEMENT_TEMPORARY, location),
615       type_(type), init_(init), bvariable_(NULL), is_address_taken_(false)
616   { }
617 
618   // Return the type of the temporary variable.
619   Type*
620   type() const;
621 
622   // Return the initializer if there is one.
623   Expression*
init()624   init() const
625   { return this->init_; }
626 
627   // Record that something takes the address of this temporary
628   // variable.
629   void
set_is_address_taken()630   set_is_address_taken()
631   { this->is_address_taken_ = true; }
632 
633   // Return the temporary variable.  This should not be called until
634   // after the statement itself has been converted.
635   Bvariable*
636   get_backend_variable(Translate_context*) const;
637 
638  protected:
639   int
640   do_traverse(Traverse*);
641 
642   bool
643   do_traverse_assignments(Traverse_assignments*);
644 
645   void
646   do_determine_types();
647 
648   void
649   do_check_types(Gogo*);
650 
651   Statement*
652   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
653 
654   Bstatement*
655   do_get_backend(Translate_context*);
656 
657   void
658   do_dump_statement(Ast_dump_context*) const;
659 
660  private:
661   // The type of the temporary variable.
662   Type* type_;
663   // The initial value of the temporary variable.  This may be NULL.
664   Expression* init_;
665   // The backend representation of the temporary variable.
666   Bvariable* bvariable_;
667   // True if something takes the address of this temporary variable.
668   bool is_address_taken_;
669 };
670 
671 // A variable declaration.  This marks the point in the code where a
672 // variable is declared.  The Variable is also attached to a Block.
673 
674 class Variable_declaration_statement : public Statement
675 {
676  public:
677   Variable_declaration_statement(Named_object* var);
678 
679   // The variable being declared.
680   Named_object*
var()681   var()
682   { return this->var_; }
683 
684  protected:
685   int
686   do_traverse(Traverse*);
687 
688   bool
689   do_traverse_assignments(Traverse_assignments*);
690 
691   Statement*
692   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
693 
694   Statement*
695   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
696 
697   Bstatement*
698   do_get_backend(Translate_context*);
699 
700   void
701   do_dump_statement(Ast_dump_context*) const;
702 
703  private:
704   Named_object* var_;
705 };
706 
707 // A return statement.
708 
709 class Return_statement : public Statement
710 {
711  public:
Return_statement(Expression_list * vals,Location location)712   Return_statement(Expression_list* vals, Location location)
713     : Statement(STATEMENT_RETURN, location),
714       vals_(vals), is_lowered_(false)
715   { }
716 
717   // The list of values being returned.  This may be NULL.
718   const Expression_list*
vals()719   vals() const
720   { return this->vals_; }
721 
722  protected:
723   int
do_traverse(Traverse * traverse)724   do_traverse(Traverse* traverse)
725   { return this->traverse_expression_list(traverse, this->vals_); }
726 
727   bool
728   do_traverse_assignments(Traverse_assignments*);
729 
730   Statement*
731   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
732 
733   bool
do_may_fall_through()734   do_may_fall_through() const
735   { return false; }
736 
737   Bstatement*
738   do_get_backend(Translate_context*);
739 
740   void
741   do_dump_statement(Ast_dump_context*) const;
742 
743  private:
744   // Return values.  This may be NULL.
745   Expression_list* vals_;
746   // True if this statement has been lowered.
747   bool is_lowered_;
748 };
749 
750 // An expression statement.
751 
752 class Expression_statement : public Statement
753 {
754  public:
755   Expression_statement(Expression* expr, bool is_ignored);
756 
757   Expression*
expr()758   expr()
759   { return this->expr_; }
760 
761  protected:
762   int
do_traverse(Traverse * traverse)763   do_traverse(Traverse* traverse)
764   { return this->traverse_expression(traverse, &this->expr_); }
765 
766   void
767   do_determine_types();
768 
769   void
770   do_check_types(Gogo*);
771 
772   bool
773   do_may_fall_through() const;
774 
775   Bstatement*
776   do_get_backend(Translate_context* context);
777 
778   void
779   do_dump_statement(Ast_dump_context*) const;
780 
781  private:
782   Expression* expr_;
783   // Whether the value of this expression is being explicitly ignored.
784   bool is_ignored_;
785 };
786 
787 // A block statement--a list of statements which may include variable
788 // definitions.
789 
790 class Block_statement : public Statement
791 {
792  public:
Block_statement(Block * block,Location location)793   Block_statement(Block* block, Location location)
794     : Statement(STATEMENT_BLOCK, location),
795       block_(block), is_lowered_for_statement_(false)
796   { }
797 
798   void
set_is_lowered_for_statement()799   set_is_lowered_for_statement()
800   { this->is_lowered_for_statement_ = true; }
801 
802   bool
is_lowered_for_statement()803   is_lowered_for_statement()
804   { return this->is_lowered_for_statement_; }
805 
806  protected:
807   int
do_traverse(Traverse * traverse)808   do_traverse(Traverse* traverse)
809   { return this->block_->traverse(traverse); }
810 
811   void
do_determine_types()812   do_determine_types()
813   { this->block_->determine_types(); }
814 
815   bool
do_may_fall_through()816   do_may_fall_through() const
817   { return this->block_->may_fall_through(); }
818 
819   Bstatement*
820   do_get_backend(Translate_context* context);
821 
822   void
823   do_dump_statement(Ast_dump_context*) const;
824 
825  private:
826   Block* block_;
827   // True if this block statement represents a lowered for statement.
828   bool is_lowered_for_statement_;
829 };
830 
831 // A send statement.
832 
833 class Send_statement : public Statement
834 {
835  public:
Send_statement(Expression * channel,Expression * val,Location location)836   Send_statement(Expression* channel, Expression* val,
837 		 Location location)
838     : Statement(STATEMENT_SEND, location),
839       channel_(channel), val_(val)
840   { }
841 
842   Expression*
channel()843   channel()
844   { return this->channel_; }
845 
846   Expression*
val()847   val()
848   { return this->val_; }
849 
850  protected:
851   int
852   do_traverse(Traverse* traverse);
853 
854   void
855   do_determine_types();
856 
857   void
858   do_check_types(Gogo*);
859 
860   Statement*
861   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
862 
863   Bstatement*
864   do_get_backend(Translate_context*);
865 
866   void
867   do_dump_statement(Ast_dump_context*) const;
868 
869  private:
870   // The channel on which to send the value.
871   Expression* channel_;
872   // The value to send.
873   Expression* val_;
874 };
875 
876 // Select_clauses holds the clauses of a select statement.  This is
877 // built by the parser.
878 
879 class Select_clauses
880 {
881  public:
Select_clauses()882   Select_clauses()
883     : clauses_()
884   { }
885 
886   // Add a new clause.  IS_SEND is true if this is a send clause,
887   // false for a receive clause.  For a send clause CHANNEL is the
888   // channel and VAL is the value to send.  For a receive clause
889   // CHANNEL is the channel, VAL is either NULL or a Var_expression
890   // for the variable to set, and CLOSED is either NULL or a
891   // Var_expression to set to whether the channel is closed.  If VAL
892   // is NULL, VAR may be a variable to be initialized with the
893   // received value, and CLOSEDVAR ma be a variable to be initialized
894   // with whether the channel is closed.  IS_DEFAULT is true if this
895   // is the default clause.  STATEMENTS is the list of statements to
896   // execute.
897   void
add(bool is_send,Expression * channel,Expression * val,Expression * closed,Named_object * var,Named_object * closedvar,bool is_default,Block * statements,Location location)898   add(bool is_send, Expression* channel, Expression* val, Expression* closed,
899       Named_object* var, Named_object* closedvar, bool is_default,
900       Block* statements, Location location)
901   {
902     this->clauses_.push_back(Select_clause(is_send, channel, val, closed, var,
903 					   closedvar, is_default, statements,
904 					   location));
905   }
906 
907   size_t
size()908   size() const
909   { return this->clauses_.size(); }
910 
911   // Traverse the select clauses.
912   int
913   traverse(Traverse*);
914 
915   // Lower statements.
916   void
917   lower(Gogo*, Named_object*, Block*, Temporary_statement*);
918 
919   // Determine types.
920   void
921   determine_types();
922 
923   // Check types.
924   void
925   check_types();
926 
927   // Whether the select clauses may fall through to the statement
928   // which follows the overall select statement.
929   bool
930   may_fall_through() const;
931 
932   // Convert to the backend representation.
933   Bstatement*
934   get_backend(Translate_context*, Temporary_statement* sel,
935 	      Unnamed_label* break_label, Location);
936 
937   // Dump AST representation.
938   void
939   dump_clauses(Ast_dump_context*) const;
940 
941  private:
942   // A single clause.
943   class Select_clause
944   {
945    public:
Select_clause()946     Select_clause()
947       : channel_(NULL), val_(NULL), closed_(NULL), var_(NULL),
948 	closedvar_(NULL), statements_(NULL), is_send_(false),
949 	is_default_(false)
950     { }
951 
Select_clause(bool is_send,Expression * channel,Expression * val,Expression * closed,Named_object * var,Named_object * closedvar,bool is_default,Block * statements,Location location)952     Select_clause(bool is_send, Expression* channel, Expression* val,
953 		  Expression* closed, Named_object* var,
954 		  Named_object* closedvar, bool is_default, Block* statements,
955 		  Location location)
956       : channel_(channel), val_(val), closed_(closed), var_(var),
957 	closedvar_(closedvar), statements_(statements), location_(location),
958 	is_send_(is_send), is_default_(is_default), is_lowered_(false)
959     { go_assert(is_default ? channel == NULL : channel != NULL); }
960 
961     // Traverse the select clause.
962     int
963     traverse(Traverse*);
964 
965     // Lower statements.
966     void
967     lower(Gogo*, Named_object*, Block*, Temporary_statement*);
968 
969     // Determine types.
970     void
971     determine_types();
972 
973     // Check types.
974     void
975     check_types();
976 
977     // Return true if this is the default clause.
978     bool
is_default()979     is_default() const
980     { return this->is_default_; }
981 
982     // Return the channel.  This will return NULL for the default
983     // clause.
984     Expression*
channel()985     channel() const
986     { return this->channel_; }
987 
988     // Return true for a send, false for a receive.
989     bool
is_send()990     is_send() const
991     {
992       go_assert(!this->is_default_);
993       return this->is_send_;
994     }
995 
996     // Return the statements.
997     const Block*
statements()998     statements() const
999     { return this->statements_; }
1000 
1001     // Return the location.
1002     Location
location()1003     location() const
1004     { return this->location_; }
1005 
1006     // Whether this clause may fall through to the statement which
1007     // follows the overall select statement.
1008     bool
1009     may_fall_through() const;
1010 
1011     // Convert the statements to the backend representation.
1012     Bstatement*
1013     get_statements_backend(Translate_context*);
1014 
1015     // Dump AST representation.
1016     void
1017     dump_clause(Ast_dump_context*) const;
1018 
1019    private:
1020     void
1021     lower_default(Block*, Expression*);
1022 
1023     void
1024     lower_send(Block*, Expression*, Expression*);
1025 
1026     void
1027     lower_recv(Gogo*, Named_object*, Block*, Expression*, Expression*);
1028 
1029     // The channel.
1030     Expression* channel_;
1031     // The value to send or the lvalue to receive into.
1032     Expression* val_;
1033     // The lvalue to set to whether the channel is closed on a
1034     // receive.
1035     Expression* closed_;
1036     // The variable to initialize, for "case a := <-ch".
1037     Named_object* var_;
1038     // The variable to initialize to whether the channel is closed,
1039     // for "case a, c := <-ch".
1040     Named_object* closedvar_;
1041     // The statements to execute.
1042     Block* statements_;
1043     // The location of this clause.
1044     Location location_;
1045     // Whether this is a send or a receive.
1046     bool is_send_;
1047     // Whether this is the default.
1048     bool is_default_;
1049     // Whether this has been lowered.
1050     bool is_lowered_;
1051   };
1052 
1053   typedef std::vector<Select_clause> Clauses;
1054 
1055   Clauses clauses_;
1056 };
1057 
1058 // A select statement.
1059 
1060 class Select_statement : public Statement
1061 {
1062  public:
Select_statement(Location location)1063   Select_statement(Location location)
1064     : Statement(STATEMENT_SELECT, location),
1065       clauses_(NULL), sel_(NULL), break_label_(NULL), is_lowered_(false)
1066   { }
1067 
1068   // Add the clauses.
1069   void
add_clauses(Select_clauses * clauses)1070   add_clauses(Select_clauses* clauses)
1071   {
1072     go_assert(this->clauses_ == NULL);
1073     this->clauses_ = clauses;
1074   }
1075 
1076   // Return the break label for this select statement.
1077   Unnamed_label*
1078   break_label();
1079 
1080  protected:
1081   int
do_traverse(Traverse * traverse)1082   do_traverse(Traverse* traverse)
1083   { return this->clauses_->traverse(traverse); }
1084 
1085   Statement*
1086   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
1087 
1088   void
do_determine_types()1089   do_determine_types()
1090   { this->clauses_->determine_types(); }
1091 
1092   void
do_check_types(Gogo *)1093   do_check_types(Gogo*)
1094   { this->clauses_->check_types(); }
1095 
1096   bool
1097   do_may_fall_through() const;
1098 
1099   Bstatement*
1100   do_get_backend(Translate_context*);
1101 
1102   void
1103   do_dump_statement(Ast_dump_context*) const;
1104 
1105  private:
1106   // The select clauses.
1107   Select_clauses* clauses_;
1108   // A temporary which holds the select structure we build up at runtime.
1109   Temporary_statement* sel_;
1110   // The break label.
1111   Unnamed_label* break_label_;
1112   // Whether this statement has been lowered.
1113   bool is_lowered_;
1114 };
1115 
1116 // A statement which requires a thunk: go or defer.
1117 
1118 class Thunk_statement : public Statement
1119 {
1120  public:
1121   Thunk_statement(Statement_classification, Call_expression*,
1122 		  Location);
1123 
1124   // Return the call expression.
1125   Expression*
call()1126   call() const
1127   { return this->call_; }
1128 
1129   // Simplify a go or defer statement so that it only uses a single
1130   // parameter.
1131   bool
1132   simplify_statement(Gogo*, Named_object*, Block*);
1133 
1134  protected:
1135   int
1136   do_traverse(Traverse* traverse);
1137 
1138   bool
1139   do_traverse_assignments(Traverse_assignments*);
1140 
1141   void
1142   do_determine_types();
1143 
1144   void
1145   do_check_types(Gogo*);
1146 
1147   // Return the function and argument for the call.
1148   bool
1149   get_fn_and_arg(Expression** pfn, Expression** parg);
1150 
1151  private:
1152   // Return whether this is a simple go statement.
1153   bool
1154   is_simple(Function_type*) const;
1155 
1156   // Return whether the thunk function is a constant.
1157   bool
1158   is_constant_function() const;
1159 
1160   // Build the struct to use for a complex case.
1161   Struct_type*
1162   build_struct(Function_type* fntype);
1163 
1164   // Build the thunk.
1165   void
1166   build_thunk(Gogo*, const std::string&);
1167 
1168   // Set the name to use for thunk field N.
1169   void
1170   thunk_field_param(int n, char* buf, size_t buflen);
1171 
1172   // The function call to be executed in a separate thread (go) or
1173   // later (defer).
1174   Expression* call_;
1175   // The type used for a struct to pass to a thunk, if this is not a
1176   // simple call.
1177   Struct_type* struct_type_;
1178 };
1179 
1180 // A go statement.
1181 
1182 class Go_statement : public Thunk_statement
1183 {
1184  public:
Go_statement(Call_expression * call,Location location)1185   Go_statement(Call_expression* call, Location location)
1186     : Thunk_statement(STATEMENT_GO, call, location)
1187   { }
1188 
1189  protected:
1190   Bstatement*
1191   do_get_backend(Translate_context*);
1192 
1193   void
1194   do_dump_statement(Ast_dump_context*) const;
1195 };
1196 
1197 // A defer statement.
1198 
1199 class Defer_statement : public Thunk_statement
1200 {
1201  public:
Defer_statement(Call_expression * call,Location location)1202   Defer_statement(Call_expression* call, Location location)
1203     : Thunk_statement(STATEMENT_DEFER, call, location)
1204   { }
1205 
1206  protected:
1207   Bstatement*
1208   do_get_backend(Translate_context*);
1209 
1210   void
1211   do_dump_statement(Ast_dump_context*) const;
1212 };
1213 
1214 // A goto statement.
1215 
1216 class Goto_statement : public Statement
1217 {
1218  public:
Goto_statement(Label * label,Location location)1219   Goto_statement(Label* label, Location location)
1220     : Statement(STATEMENT_GOTO, location),
1221       label_(label)
1222   { }
1223 
1224   // Return the label being jumped to.
1225   Label*
label()1226   label() const
1227   { return this->label_; }
1228 
1229  protected:
1230   int
1231   do_traverse(Traverse*);
1232 
1233   void
1234   do_check_types(Gogo*);
1235 
1236   bool
do_may_fall_through()1237   do_may_fall_through() const
1238   { return false; }
1239 
1240   Bstatement*
1241   do_get_backend(Translate_context*);
1242 
1243   void
1244   do_dump_statement(Ast_dump_context*) const;
1245 
1246  private:
1247   Label* label_;
1248 };
1249 
1250 // A goto statement to an unnamed label.
1251 
1252 class Goto_unnamed_statement : public Statement
1253 {
1254  public:
Goto_unnamed_statement(Unnamed_label * label,Location location)1255   Goto_unnamed_statement(Unnamed_label* label, Location location)
1256     : Statement(STATEMENT_GOTO_UNNAMED, location),
1257       label_(label)
1258   { }
1259 
1260   Unnamed_label*
unnamed_label()1261   unnamed_label() const
1262   { return this->label_; }
1263 
1264  protected:
1265   int
1266   do_traverse(Traverse*);
1267 
1268   bool
do_may_fall_through()1269   do_may_fall_through() const
1270   { return false; }
1271 
1272   Bstatement*
1273   do_get_backend(Translate_context* context);
1274 
1275   void
1276   do_dump_statement(Ast_dump_context*) const;
1277 
1278  private:
1279   Unnamed_label* label_;
1280 };
1281 
1282 // A label statement.
1283 
1284 class Label_statement : public Statement
1285 {
1286  public:
Label_statement(Label * label,Location location)1287   Label_statement(Label* label, Location location)
1288     : Statement(STATEMENT_LABEL, location),
1289       label_(label)
1290   { }
1291 
1292   // Return the label itself.
1293   Label*
label()1294   label() const
1295   { return this->label_; }
1296 
1297  protected:
1298   int
1299   do_traverse(Traverse*);
1300 
1301   Bstatement*
1302   do_get_backend(Translate_context*);
1303 
1304   void
1305   do_dump_statement(Ast_dump_context*) const;
1306 
1307  private:
1308   // The label.
1309   Label* label_;
1310 };
1311 
1312 // An unnamed label statement.
1313 
1314 class Unnamed_label_statement : public Statement
1315 {
1316  public:
1317   Unnamed_label_statement(Unnamed_label* label);
1318 
1319  protected:
1320   int
1321   do_traverse(Traverse*);
1322 
1323   Bstatement*
1324   do_get_backend(Translate_context* context);
1325 
1326   void
1327   do_dump_statement(Ast_dump_context*) const;
1328 
1329  private:
1330   // The label.
1331   Unnamed_label* label_;
1332 };
1333 
1334 // An if statement.
1335 
1336 class If_statement : public Statement
1337 {
1338  public:
If_statement(Expression * cond,Block * then_block,Block * else_block,Location location)1339   If_statement(Expression* cond, Block* then_block, Block* else_block,
1340 	       Location location)
1341     : Statement(STATEMENT_IF, location),
1342       cond_(cond), then_block_(then_block), else_block_(else_block)
1343   { }
1344 
1345   Expression*
condition()1346   condition() const
1347   { return this->cond_; }
1348 
1349  protected:
1350   int
1351   do_traverse(Traverse*);
1352 
1353   void
1354   do_determine_types();
1355 
1356   void
1357   do_check_types(Gogo*);
1358 
1359   bool
1360   do_may_fall_through() const;
1361 
1362   Bstatement*
1363   do_get_backend(Translate_context*);
1364 
1365   void
1366   do_dump_statement(Ast_dump_context*) const;
1367 
1368  private:
1369   Expression* cond_;
1370   Block* then_block_;
1371   Block* else_block_;
1372 };
1373 
1374 // A for statement.
1375 
1376 class For_statement : public Statement
1377 {
1378  public:
For_statement(Block * init,Expression * cond,Block * post,Location location)1379   For_statement(Block* init, Expression* cond, Block* post,
1380 		Location location)
1381     : Statement(STATEMENT_FOR, location),
1382       init_(init), cond_(cond), post_(post), statements_(NULL),
1383       break_label_(NULL), continue_label_(NULL)
1384   { }
1385 
1386   // Add the statements.
1387   void
add_statements(Block * statements)1388   add_statements(Block* statements)
1389   {
1390     go_assert(this->statements_ == NULL);
1391     this->statements_ = statements;
1392   }
1393 
1394   // Return the break label for this for statement.
1395   Unnamed_label*
1396   break_label();
1397 
1398   // Return the continue label for this for statement.
1399   Unnamed_label*
1400   continue_label();
1401 
1402   // Set the break and continue labels for this statement.
1403   void
1404   set_break_continue_labels(Unnamed_label* break_label,
1405 			    Unnamed_label* continue_label);
1406 
1407  protected:
1408   int
1409   do_traverse(Traverse*);
1410 
1411   bool
do_traverse_assignments(Traverse_assignments *)1412   do_traverse_assignments(Traverse_assignments*)
1413   { go_unreachable(); }
1414 
1415   Statement*
1416   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
1417 
1418   bool
1419   do_may_fall_through() const;
1420 
1421   Bstatement*
do_get_backend(Translate_context *)1422   do_get_backend(Translate_context*)
1423   { go_unreachable(); }
1424 
1425   void
1426   do_dump_statement(Ast_dump_context*) const;
1427 
1428  private:
1429   // The initialization statements.  This may be NULL.
1430   Block* init_;
1431   // The condition.  This may be NULL.
1432   Expression* cond_;
1433   // The statements to run after each iteration.  This may be NULL.
1434   Block* post_;
1435   // The statements in the loop itself.
1436   Block* statements_;
1437   // The break label, if needed.
1438   Unnamed_label* break_label_;
1439   // The continue label, if needed.
1440   Unnamed_label* continue_label_;
1441 };
1442 
1443 // A for statement over a range clause.
1444 
1445 class For_range_statement : public Statement
1446 {
1447  public:
For_range_statement(Expression * index_var,Expression * value_var,Expression * range,Location location)1448   For_range_statement(Expression* index_var, Expression* value_var,
1449 		      Expression* range, Location location)
1450     : Statement(STATEMENT_FOR_RANGE, location),
1451       index_var_(index_var), value_var_(value_var), range_(range),
1452       statements_(NULL), break_label_(NULL), continue_label_(NULL)
1453   { }
1454 
1455   // Add the statements.
1456   void
add_statements(Block * statements)1457   add_statements(Block* statements)
1458   {
1459     go_assert(this->statements_ == NULL);
1460     this->statements_ = statements;
1461   }
1462 
1463   // Return the break label for this for statement.
1464   Unnamed_label*
1465   break_label();
1466 
1467   // Return the continue label for this for statement.
1468   Unnamed_label*
1469   continue_label();
1470 
1471  protected:
1472   int
1473   do_traverse(Traverse*);
1474 
1475   bool
do_traverse_assignments(Traverse_assignments *)1476   do_traverse_assignments(Traverse_assignments*)
1477   { go_unreachable(); }
1478 
1479   Statement*
1480   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
1481 
1482   Bstatement*
do_get_backend(Translate_context *)1483   do_get_backend(Translate_context*)
1484   { go_unreachable(); }
1485 
1486   void
1487   do_dump_statement(Ast_dump_context*) const;
1488 
1489  private:
1490   Expression*
1491   make_range_ref(Named_object*, Temporary_statement*, Location);
1492 
1493   Call_expression*
1494   call_builtin(Gogo*, const char* funcname, Expression* arg, Location);
1495 
1496   void
1497   lower_range_array(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
1498 		    Temporary_statement*, Temporary_statement*,
1499 		    Block**, Expression**, Block**, Block**);
1500 
1501   void
1502   lower_range_slice(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
1503 		    Temporary_statement*, Temporary_statement*,
1504 		    Block**, Expression**, Block**, Block**);
1505 
1506   void
1507   lower_range_string(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
1508 		     Temporary_statement*, Temporary_statement*,
1509 		     Block**, Expression**, Block**, Block**);
1510 
1511   void
1512   lower_range_map(Gogo*, Map_type*, Block*, Block*, Named_object*,
1513 		  Temporary_statement*, Temporary_statement*,
1514 		  Temporary_statement*, Block**, Expression**, Block**,
1515 		  Block**);
1516 
1517   void
1518   lower_range_channel(Gogo*, Block*, Block*, Named_object*,
1519 		      Temporary_statement*, Temporary_statement*,
1520 		      Temporary_statement*, Block**, Expression**, Block**,
1521 		      Block**);
1522 
1523   // The variable which is set to the index value.
1524   Expression* index_var_;
1525   // The variable which is set to the element value.  This may be
1526   // NULL.
1527   Expression* value_var_;
1528   // The expression we are ranging over.
1529   Expression* range_;
1530   // The statements in the block.
1531   Block* statements_;
1532   // The break label, if needed.
1533   Unnamed_label* break_label_;
1534   // The continue label, if needed.
1535   Unnamed_label* continue_label_;
1536 };
1537 
1538 // Class Case_clauses holds the clauses of a switch statement.  This
1539 // is built by the parser.
1540 
1541 class Case_clauses
1542 {
1543  public:
Case_clauses()1544   Case_clauses()
1545     : clauses_()
1546   { }
1547 
1548   // Add a new clause.  CASES is a list of case expressions; it may be
1549   // NULL.  IS_DEFAULT is true if this is the default case.
1550   // STATEMENTS is a block of statements.  IS_FALLTHROUGH is true if
1551   // after the statements the case clause should fall through to the
1552   // next clause.
1553   void
add(Expression_list * cases,bool is_default,Block * statements,bool is_fallthrough,Location location)1554   add(Expression_list* cases, bool is_default, Block* statements,
1555       bool is_fallthrough, Location location)
1556   {
1557     this->clauses_.push_back(Case_clause(cases, is_default, statements,
1558 					 is_fallthrough, location));
1559   }
1560 
1561   // Return whether there are no clauses.
1562   bool
empty()1563   empty() const
1564   { return this->clauses_.empty(); }
1565 
1566   // Traverse the case clauses.
1567   int
1568   traverse(Traverse*);
1569 
1570   // Lower for a nonconstant switch.
1571   void
1572   lower(Block*, Temporary_statement*, Unnamed_label*) const;
1573 
1574   // Determine types of expressions.  The Type parameter is the type
1575   // of the switch value.
1576   void
1577   determine_types(Type*);
1578 
1579   // Check types.  The Type parameter is the type of the switch value.
1580   bool
1581   check_types(Type*);
1582 
1583   // Return true if all the clauses are constant values.
1584   bool
1585   is_constant() const;
1586 
1587   // Return true if these clauses may fall through to the statements
1588   // following the switch statement.
1589   bool
1590   may_fall_through() const;
1591 
1592   // Return the body of a SWITCH_EXPR when all the clauses are
1593   // constants.
1594   void
1595   get_backend(Translate_context*, Unnamed_label* break_label,
1596 	      std::vector<std::vector<Bexpression*> >* all_cases,
1597 	      std::vector<Bstatement*>* all_statements) const;
1598 
1599   // Dump the AST representation to a dump context.
1600   void
1601   dump_clauses(Ast_dump_context*) const;
1602 
1603  private:
1604   // For a constant switch we need to keep a record of constants we
1605   // have already seen.
1606   class Hash_integer_value;
1607   class Eq_integer_value;
1608   typedef Unordered_set_hash(Expression*, Hash_integer_value,
1609 			     Eq_integer_value) Case_constants;
1610 
1611   // One case clause.
1612   class Case_clause
1613   {
1614    public:
Case_clause()1615     Case_clause()
1616       : cases_(NULL), statements_(NULL), is_default_(false),
1617 	is_fallthrough_(false), location_(Linemap::unknown_location())
1618     { }
1619 
Case_clause(Expression_list * cases,bool is_default,Block * statements,bool is_fallthrough,Location location)1620     Case_clause(Expression_list* cases, bool is_default, Block* statements,
1621 		bool is_fallthrough, Location location)
1622       : cases_(cases), statements_(statements), is_default_(is_default),
1623 	is_fallthrough_(is_fallthrough), location_(location)
1624     { }
1625 
1626     // Whether this clause falls through to the next clause.
1627     bool
is_fallthrough()1628     is_fallthrough() const
1629     { return this->is_fallthrough_; }
1630 
1631     // Whether this is the default.
1632     bool
is_default()1633     is_default() const
1634     { return this->is_default_; }
1635 
1636     // The location of this clause.
1637     Location
location()1638     location() const
1639     { return this->location_; }
1640 
1641     // Traversal.
1642     int
1643     traverse(Traverse*);
1644 
1645     // Lower for a nonconstant switch.
1646     void
1647     lower(Block*, Temporary_statement*, Unnamed_label*, Unnamed_label*) const;
1648 
1649     // Determine types.
1650     void
1651     determine_types(Type*);
1652 
1653     // Check types.
1654     bool
1655     check_types(Type*);
1656 
1657     // Return true if all the case expressions are constant.
1658     bool
1659     is_constant() const;
1660 
1661     // Return true if this clause may fall through to execute the
1662     // statements following the switch statement.  This is not the
1663     // same as whether this clause falls through to the next clause.
1664     bool
1665     may_fall_through() const;
1666 
1667     // Convert the case values and statements to the backend
1668     // representation.
1669     Bstatement*
1670     get_backend(Translate_context*, Unnamed_label* break_label,
1671 		Case_constants*, std::vector<Bexpression*>* cases) const;
1672 
1673     // Dump the AST representation to a dump context.
1674     void
1675     dump_clause(Ast_dump_context*) const;
1676 
1677    private:
1678     // The list of case expressions.
1679     Expression_list* cases_;
1680     // The statements to execute.
1681     Block* statements_;
1682     // Whether this is the default case.
1683     bool is_default_;
1684     // Whether this falls through after the statements.
1685     bool is_fallthrough_;
1686     // The location of this case clause.
1687     Location location_;
1688   };
1689 
1690   friend class Case_clause;
1691 
1692   // The type of the list of clauses.
1693   typedef std::vector<Case_clause> Clauses;
1694 
1695   // All the case clauses.
1696   Clauses clauses_;
1697 };
1698 
1699 // A switch statement.
1700 
1701 class Switch_statement : public Statement
1702 {
1703  public:
Switch_statement(Expression * val,Location location)1704   Switch_statement(Expression* val, Location location)
1705     : Statement(STATEMENT_SWITCH, location),
1706       val_(val), clauses_(NULL), break_label_(NULL)
1707   { }
1708 
1709   // Add the clauses.
1710   void
add_clauses(Case_clauses * clauses)1711   add_clauses(Case_clauses* clauses)
1712   {
1713     go_assert(this->clauses_ == NULL);
1714     this->clauses_ = clauses;
1715   }
1716 
1717   // Return the break label for this switch statement.
1718   Unnamed_label*
1719   break_label();
1720 
1721  protected:
1722   int
1723   do_traverse(Traverse*);
1724 
1725   Statement*
1726   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
1727 
1728   Bstatement*
do_get_backend(Translate_context *)1729   do_get_backend(Translate_context*)
1730   { go_unreachable(); }
1731 
1732   void
1733   do_dump_statement(Ast_dump_context*) const;
1734 
1735   bool
1736   do_may_fall_through() const;
1737 
1738  private:
1739   // The value to switch on.  This may be NULL.
1740   Expression* val_;
1741   // The case clauses.
1742   Case_clauses* clauses_;
1743   // The break label, if needed.
1744   Unnamed_label* break_label_;
1745 };
1746 
1747 // Class Type_case_clauses holds the clauses of a type switch
1748 // statement.  This is built by the parser.
1749 
1750 class Type_case_clauses
1751 {
1752  public:
Type_case_clauses()1753   Type_case_clauses()
1754     : clauses_()
1755   { }
1756 
1757   // Add a new clause.  TYPE is the type for this clause; it may be
1758   // NULL.  IS_FALLTHROUGH is true if this falls through to the next
1759   // clause; in this case STATEMENTS will be NULL.  IS_DEFAULT is true
1760   // if this is the default case.  STATEMENTS is a block of
1761   // statements; it may be NULL.
1762   void
add(Type * type,bool is_fallthrough,bool is_default,Block * statements,Location location)1763   add(Type* type, bool is_fallthrough, bool is_default, Block* statements,
1764       Location location)
1765   {
1766     this->clauses_.push_back(Type_case_clause(type, is_fallthrough, is_default,
1767 					      statements, location));
1768   }
1769 
1770   // Return whether there are no clauses.
1771   bool
empty()1772   empty() const
1773   { return this->clauses_.empty(); }
1774 
1775   // Traverse the type case clauses.
1776   int
1777   traverse(Traverse*);
1778 
1779   // Check for duplicates.
1780   void
1781   check_duplicates() const;
1782 
1783   // Lower to if and goto statements.
1784   void
1785   lower(Type*, Block*, Temporary_statement* descriptor_temp,
1786 	Unnamed_label* break_label) const;
1787 
1788   // Return true if these clauses may fall through to the statements
1789   // following the switch statement.
1790   bool
1791   may_fall_through() const;
1792 
1793   // Dump the AST representation to a dump context.
1794   void
1795   dump_clauses(Ast_dump_context*) const;
1796 
1797  private:
1798   // One type case clause.
1799   class Type_case_clause
1800   {
1801    public:
Type_case_clause()1802     Type_case_clause()
1803       : type_(NULL), statements_(NULL), is_default_(false),
1804 	location_(Linemap::unknown_location())
1805     { }
1806 
Type_case_clause(Type * type,bool is_fallthrough,bool is_default,Block * statements,Location location)1807     Type_case_clause(Type* type, bool is_fallthrough, bool is_default,
1808 		     Block* statements, Location location)
1809       : type_(type), statements_(statements), is_fallthrough_(is_fallthrough),
1810 	is_default_(is_default), location_(location)
1811     { }
1812 
1813     // The type.
1814     Type*
type()1815     type() const
1816     { return this->type_; }
1817 
1818     // Whether this is the default.
1819     bool
is_default()1820     is_default() const
1821     { return this->is_default_; }
1822 
1823     // The location of this type clause.
1824     Location
location()1825     location() const
1826     { return this->location_; }
1827 
1828     // Traversal.
1829     int
1830     traverse(Traverse*);
1831 
1832     // Lower to if and goto statements.
1833     void
1834     lower(Type*, Block*, Temporary_statement* descriptor_temp,
1835 	  Unnamed_label* break_label, Unnamed_label** stmts_label) const;
1836 
1837     // Return true if this clause may fall through to execute the
1838     // statements following the switch statement.  This is not the
1839     // same as whether this clause falls through to the next clause.
1840     bool
1841     may_fall_through() const;
1842 
1843     // Dump the AST representation to a dump context.
1844     void
1845     dump_clause(Ast_dump_context*) const;
1846 
1847    private:
1848     // The type for this type clause.
1849     Type* type_;
1850     // The statements to execute.
1851     Block* statements_;
1852     // Whether this falls through--this is true for "case T1, T2".
1853     bool is_fallthrough_;
1854     // Whether this is the default case.
1855     bool is_default_;
1856     // The location of this type case clause.
1857     Location location_;
1858   };
1859 
1860   friend class Type_case_clause;
1861 
1862   // The type of the list of type clauses.
1863   typedef std::vector<Type_case_clause> Type_clauses;
1864 
1865   // All the type case clauses.
1866   Type_clauses clauses_;
1867 };
1868 
1869 // A type switch statement.
1870 
1871 class Type_switch_statement : public Statement
1872 {
1873  public:
Type_switch_statement(const std::string & name,Expression * expr,Location location)1874   Type_switch_statement(const std::string& name, Expression* expr,
1875 			Location location)
1876     : Statement(STATEMENT_TYPE_SWITCH, location),
1877       name_(name), expr_(expr), clauses_(NULL), break_label_(NULL)
1878   { }
1879 
1880   // Add the clauses.
1881   void
add_clauses(Type_case_clauses * clauses)1882   add_clauses(Type_case_clauses* clauses)
1883   {
1884     go_assert(this->clauses_ == NULL);
1885     this->clauses_ = clauses;
1886   }
1887 
1888   // Return the break label for this type switch statement.
1889   Unnamed_label*
1890   break_label();
1891 
1892  protected:
1893   int
1894   do_traverse(Traverse*);
1895 
1896   Statement*
1897   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
1898 
1899   Bstatement*
do_get_backend(Translate_context *)1900   do_get_backend(Translate_context*)
1901   { go_unreachable(); }
1902 
1903   void
1904   do_dump_statement(Ast_dump_context*) const;
1905 
1906   bool
1907   do_may_fall_through() const;
1908 
1909  private:
1910   // The name of the variable declared in the type switch guard.  Empty if there
1911   // is no variable declared.
1912   std::string name_;
1913   // The expression we are switching on if there is no variable.
1914   Expression* expr_;
1915   // The type case clauses.
1916   Type_case_clauses* clauses_;
1917   // The break label, if needed.
1918   Unnamed_label* break_label_;
1919 };
1920 
1921 #endif // !defined(GO_STATEMENTS_H)
1922