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