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