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