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