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