github.com/ronhuafeng/gofrontend@v0.0.0-20220715151246-ff23266b8bc5/go/statements.h (about) 1 // statements.h -- Go frontend statements. -*- C++ -*- 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 #ifndef GO_STATEMENTS_H 8 #define GO_STATEMENTS_H 9 10 #include "operator.h" 11 12 class Gogo; 13 class Traverse; 14 class Statement_inserter; 15 class Block; 16 class Function; 17 class Unnamed_label; 18 class Export_function_body; 19 class Import_function_body; 20 class Assignment_statement; 21 class Temporary_statement; 22 class Variable_declaration_statement; 23 class Expression_statement; 24 class Block_statement; 25 class Return_statement; 26 class Thunk_statement; 27 class Defer_statement; 28 class Goto_statement; 29 class Goto_unnamed_statement; 30 class Label_statement; 31 class Unnamed_label_statement; 32 class If_statement; 33 class For_statement; 34 class For_range_statement; 35 class Switch_statement; 36 class Type_switch_statement; 37 class Send_statement; 38 class Select_statement; 39 class Variable; 40 class Named_object; 41 class Label; 42 class Translate_context; 43 class Expression; 44 class Expression_list; 45 class Struct_type; 46 class Call_expression; 47 class Map_index_expression; 48 class Receive_expression; 49 class Case_clauses; 50 class Type_case_clauses; 51 class Select_clauses; 52 class Typed_identifier_list; 53 class Bexpression; 54 class Bstatement; 55 class Bvariable; 56 class Ast_dump_context; 57 58 // 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. 154 static Assignment_statement* 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. 191 static Block_statement* 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 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 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 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 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 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 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 548 // Implemented by child class: make implicit conversions explicit. 549 virtual void 550 do_add_conversions() 551 { } 552 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), 613 lhs_(lhs), rhs_(rhs), omit_write_barrier_(false) 614 { } 615 616 Expression* 617 lhs() const 618 { return this->lhs_; } 619 620 Expression* 621 rhs() const 622 { return this->rhs_; } 623 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 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 648 int 649 do_inlining_cost() 650 { return 1; } 651 652 void 653 do_export_statement(Export_function_body*); 654 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 664 void 665 do_add_conversions(); 666 667 private: 668 // Left hand side--the lvalue. 669 Expression* lhs_; 670 // Right hand side--the rvalue. 671 Expression* rhs_; 672 // True if we can omit a write barrier from this assignment. 673 bool omit_write_barrier_; 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), 683 type_(type), init_(init), bvariable_(NULL), is_address_taken_(false), 684 value_escapes_(false), assigned_(false), uses_(0) 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 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 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 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 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 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 748 // Import the declaration of a temporary. 749 static Statement* 750 do_import(Import_function_body*, Location); 751 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 765 int 766 do_inlining_cost() 767 { return 1; } 768 769 void 770 do_export_statement(Export_function_body*); 771 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 781 void 782 do_add_conversions(); 783 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_; 793 // True if the value assigned to this temporary variable escapes. 794 // This is used for select statements. 795 bool value_escapes_; 796 // True if this temporary variable is assigned (after initialization). 797 bool assigned_; 798 // Number of uses of this temporary variable. 799 int uses_; 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 815 // Import a variable declaration. 816 static Statement* 817 do_import(Import_function_body*, Location); 818 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 829 int 830 do_inlining_cost() 831 { return 1; } 832 833 void 834 do_export_statement(Export_function_body*); 835 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 845 void 846 do_add_conversions(); 847 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 882 int 883 do_inlining_cost() 884 { return 1; } 885 886 void 887 do_export_statement(Export_function_body*); 888 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 927 int 928 do_inlining_cost() 929 { return 0; } 930 931 void 932 do_export_statement(Export_function_body*); 933 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 957 // Return the actual block. 958 Block* 959 block() const 960 { return this->block_; } 961 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 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 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 989 int 990 do_inlining_cost() 991 { return 0; } 992 993 void 994 do_export_statement(Export_function_body*); 995 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() 1025 { return this->channel_; } 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 1050 void 1051 do_add_conversions(); 1052 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 1077 // received value, and CLOSEDVAR may be a variable to be initialized 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 bool 1096 has_default() const; 1097 1098 // Traverse the select clauses. 1099 int 1100 traverse(Traverse*); 1101 1102 // Lower statements. 1103 void 1104 lower(Gogo*, Named_object*, Block*, Temporary_statement*, 1105 Temporary_statement*, int* send_count, int* recv_count); 1106 1107 // Determine types. 1108 void 1109 determine_types(); 1110 1111 // Check types. 1112 void 1113 check_types(); 1114 1115 // Whether the select clauses may fall through to the statement 1116 // which follows the overall select statement. 1117 bool 1118 may_fall_through() const; 1119 1120 // Convert to the backend representation. 1121 Bstatement* 1122 get_backend(Translate_context*, Temporary_statement* index, 1123 Unnamed_label* break_label, Location); 1124 1125 // Dump AST representation. 1126 void 1127 dump_clauses(Ast_dump_context*) const; 1128 1129 // A single clause. 1130 class Select_clause 1131 { 1132 public: 1133 Select_clause() 1134 : channel_(NULL), val_(NULL), closed_(NULL), var_(NULL), 1135 closedvar_(NULL), statements_(NULL), is_send_(false), 1136 is_default_(false) 1137 { } 1138 1139 Select_clause(bool is_send, Expression* channel, Expression* val, 1140 Expression* closed, Named_object* var, 1141 Named_object* closedvar, bool is_default, Block* statements, 1142 Location location) 1143 : channel_(channel), val_(val), closed_(closed), var_(var), 1144 closedvar_(closedvar), statements_(statements), case_index_(0), 1145 location_(location), is_send_(is_send), is_default_(is_default), 1146 is_lowered_(false), is_case_index_set_(false) 1147 { go_assert(is_default ? channel == NULL : channel != NULL); } 1148 1149 // Traverse the select clause. 1150 int 1151 traverse(Traverse*); 1152 1153 // Lower statements. 1154 void 1155 lower(Gogo*, Named_object*, Block*, Temporary_statement*, int, 1156 Temporary_statement*); 1157 1158 // Determine types. 1159 void 1160 determine_types(); 1161 1162 // Check types. 1163 void 1164 check_types(); 1165 1166 // Return true if this is the default clause. 1167 bool 1168 is_default() const 1169 { return this->is_default_; } 1170 1171 // Return the channel. This will return NULL for the default 1172 // clause. 1173 Expression* 1174 channel() const 1175 { return this->channel_; } 1176 1177 // Return true for a send, false for a receive. 1178 bool 1179 is_send() const 1180 { 1181 go_assert(!this->is_default_); 1182 return this->is_send_; 1183 } 1184 1185 // Return the value to send or the lvalue to receive into. 1186 Expression* 1187 val() const 1188 { return this->val_; } 1189 1190 // Return the lvalue to set to whether the channel is closed 1191 // on a receive. 1192 Expression* 1193 closed() const 1194 { return this->closed_; } 1195 1196 // Return the variable to initialize, for "case a := <-ch". 1197 Named_object* 1198 var() const 1199 { return this->var_; } 1200 1201 // Return the variable to initialize to whether the channel 1202 // is closed, for "case a, c := <-ch". 1203 Named_object* 1204 closedvar() const 1205 { return this->closedvar_; } 1206 1207 // Return the statements. 1208 Block* 1209 statements() const 1210 { return this->statements_; } 1211 1212 // Return the location. 1213 Location 1214 location() const 1215 { return this->location_; } 1216 1217 // Return the case index for this clause. 1218 int 1219 case_index() const 1220 { 1221 go_assert(this->is_case_index_set_); 1222 return this->case_index_; 1223 } 1224 1225 // Set the case index. 1226 void 1227 set_case_index(int i) 1228 { 1229 go_assert(!this->is_case_index_set_); 1230 this->case_index_ = i; 1231 this->is_case_index_set_ = true; 1232 } 1233 1234 // Whether this clause may fall through to the statement which 1235 // follows the overall select statement. 1236 bool 1237 may_fall_through() const; 1238 1239 // Convert the statements to the backend representation. 1240 Bstatement* 1241 get_statements_backend(Translate_context*); 1242 1243 // Dump AST representation. 1244 void 1245 dump_clause(Ast_dump_context*) const; 1246 1247 private: 1248 void 1249 lower_send(Block*, Expression*, Expression*); 1250 1251 void 1252 lower_recv(Gogo*, Named_object*, Block*, Expression*, Expression*, 1253 Temporary_statement*); 1254 1255 void 1256 set_case(Block*, Expression*, Expression*, Expression*); 1257 1258 // The channel. 1259 Expression* channel_; 1260 // The value to send or the lvalue to receive into. 1261 Expression* val_; 1262 // The lvalue to set to whether the channel is closed on a 1263 // receive. 1264 Expression* closed_; 1265 // The variable to initialize, for "case a := <-ch". 1266 Named_object* var_; 1267 // The variable to initialize to whether the channel is closed, 1268 // for "case a, c := <-ch". 1269 Named_object* closedvar_; 1270 // The statements to execute. 1271 Block* statements_; 1272 // The index of this clause in the switch statement. If 1273 // runtime.selectgo returns this index, this clause has been 1274 // chosen. 1275 int case_index_; 1276 // The location of this clause. 1277 Location location_; 1278 // Whether this is a send or a receive. 1279 bool is_send_; 1280 // Whether this is the default. 1281 bool is_default_; 1282 // Whether this has been lowered. 1283 bool is_lowered_; 1284 // Whether the case index has been set. 1285 bool is_case_index_set_; 1286 }; 1287 1288 Select_clause& 1289 at(size_t i) 1290 { return this->clauses_.at(i); } 1291 1292 private: 1293 typedef std::vector<Select_clause> Clauses; 1294 1295 Clauses clauses_; 1296 }; 1297 1298 // A select statement. 1299 1300 class Select_statement : public Statement 1301 { 1302 public: 1303 Select_statement(Location location) 1304 : Statement(STATEMENT_SELECT, location), 1305 clauses_(NULL), index_(NULL), break_label_(NULL), is_lowered_(false) 1306 { } 1307 1308 // Add the clauses. 1309 void 1310 add_clauses(Select_clauses* clauses) 1311 { 1312 go_assert(this->clauses_ == NULL); 1313 this->clauses_ = clauses; 1314 } 1315 1316 // Return the break label for this select statement. 1317 Unnamed_label* 1318 break_label(); 1319 1320 protected: 1321 int 1322 do_traverse(Traverse* traverse) 1323 { return this->clauses_->traverse(traverse); } 1324 1325 Statement* 1326 do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); 1327 1328 void 1329 do_determine_types() 1330 { this->clauses_->determine_types(); } 1331 1332 void 1333 do_check_types(Gogo*) 1334 { this->clauses_->check_types(); } 1335 1336 bool 1337 do_may_fall_through() const; 1338 1339 Bstatement* 1340 do_get_backend(Translate_context*); 1341 1342 void 1343 do_dump_statement(Ast_dump_context*) const; 1344 1345 private: 1346 // Lower a one-case select statement. 1347 Statement* 1348 lower_one_case(Block*); 1349 1350 // Lower a two-case select statement with one defualt case. 1351 Statement* 1352 lower_two_case(Block*); 1353 1354 // The select clauses. 1355 Select_clauses* clauses_; 1356 // A temporary that holds the index value returned by selectgo. 1357 Temporary_statement* index_; 1358 // The break label. 1359 Unnamed_label* break_label_; 1360 // Whether this statement has been lowered. 1361 bool is_lowered_; 1362 }; 1363 1364 // A statement which requires a thunk: go or defer. 1365 1366 class Thunk_statement : public Statement 1367 { 1368 public: 1369 Thunk_statement(Statement_classification, Call_expression*, 1370 Location); 1371 1372 // Return the call expression. 1373 Expression* 1374 call() const 1375 { return this->call_; } 1376 1377 // Simplify a go or defer statement so that it only uses a single 1378 // parameter. 1379 bool 1380 simplify_statement(Gogo*, Named_object*, Block*); 1381 1382 protected: 1383 int 1384 do_traverse(Traverse* traverse); 1385 1386 bool 1387 do_traverse_assignments(Traverse_assignments*); 1388 1389 void 1390 do_determine_types(); 1391 1392 void 1393 do_check_types(Gogo*); 1394 1395 // Return the function and argument for the call. 1396 bool 1397 get_fn_and_arg(Expression** pfn, Expression** parg); 1398 1399 private: 1400 // Return whether this is a simple go statement. 1401 bool 1402 is_simple(Function_type*) const; 1403 1404 // Return whether the thunk function is a constant. 1405 bool 1406 is_constant_function() const; 1407 1408 // Build the struct to use for a complex case. 1409 Struct_type* 1410 build_struct(Function_type* fntype); 1411 1412 // Build the thunk. 1413 void 1414 build_thunk(Gogo*, const std::string&); 1415 1416 // Set the name to use for thunk field N. 1417 void 1418 thunk_field_param(int n, char* buf, size_t buflen); 1419 1420 // The function call to be executed in a separate thread (go) or 1421 // later (defer). 1422 Expression* call_; 1423 // The type used for a struct to pass to a thunk, if this is not a 1424 // simple call. 1425 Struct_type* struct_type_; 1426 }; 1427 1428 // A go statement. 1429 1430 class Go_statement : public Thunk_statement 1431 { 1432 public: 1433 Go_statement(Call_expression* call, Location location) 1434 : Thunk_statement(STATEMENT_GO, call, location) 1435 { } 1436 1437 protected: 1438 Bstatement* 1439 do_get_backend(Translate_context*); 1440 1441 void 1442 do_dump_statement(Ast_dump_context*) const; 1443 }; 1444 1445 // A defer statement. 1446 1447 class Defer_statement : public Thunk_statement 1448 { 1449 public: 1450 Defer_statement(Call_expression* call, Location location) 1451 : Thunk_statement(STATEMENT_DEFER, call, location), 1452 on_stack_(false) 1453 { } 1454 1455 void 1456 set_on_stack() 1457 { this->on_stack_ = true; } 1458 1459 protected: 1460 Bstatement* 1461 do_get_backend(Translate_context*); 1462 1463 void 1464 do_dump_statement(Ast_dump_context*) const; 1465 1466 private: 1467 static Type* 1468 defer_struct_type(); 1469 1470 bool on_stack_; 1471 }; 1472 1473 // A goto statement. 1474 1475 class Goto_statement : public Statement 1476 { 1477 public: 1478 Goto_statement(Label* label, Location location) 1479 : Statement(STATEMENT_GOTO, location), 1480 label_(label) 1481 { } 1482 1483 // Return the label being jumped to. 1484 Label* 1485 label() const 1486 { return this->label_; } 1487 1488 // Import a goto statement. 1489 static Statement* 1490 do_import(Import_function_body*, Location); 1491 1492 protected: 1493 int 1494 do_traverse(Traverse*); 1495 1496 void 1497 do_check_types(Gogo*); 1498 1499 bool 1500 do_may_fall_through() const 1501 { return false; } 1502 1503 Bstatement* 1504 do_get_backend(Translate_context*); 1505 1506 int 1507 do_inlining_cost() 1508 { return 5; } 1509 1510 void 1511 do_export_statement(Export_function_body*); 1512 1513 void 1514 do_dump_statement(Ast_dump_context*) const; 1515 1516 private: 1517 Label* label_; 1518 }; 1519 1520 // A goto statement to an unnamed label. 1521 1522 class Goto_unnamed_statement : public Statement 1523 { 1524 public: 1525 Goto_unnamed_statement(Unnamed_label* label, Location location) 1526 : Statement(STATEMENT_GOTO_UNNAMED, location), 1527 label_(label) 1528 { } 1529 1530 Unnamed_label* 1531 unnamed_label() const 1532 { return this->label_; } 1533 1534 protected: 1535 int 1536 do_traverse(Traverse*); 1537 1538 bool 1539 do_may_fall_through() const 1540 { return false; } 1541 1542 Bstatement* 1543 do_get_backend(Translate_context* context); 1544 1545 int 1546 do_inlining_cost() 1547 { return 5; } 1548 1549 void 1550 do_export_statement(Export_function_body*); 1551 1552 void 1553 do_dump_statement(Ast_dump_context*) const; 1554 1555 private: 1556 Unnamed_label* label_; 1557 }; 1558 1559 // A label statement. 1560 1561 class Label_statement : public Statement 1562 { 1563 public: 1564 Label_statement(Label* label, Location location) 1565 : Statement(STATEMENT_LABEL, location), 1566 label_(label) 1567 { } 1568 1569 // Return the label itself. 1570 Label* 1571 label() const 1572 { return this->label_; } 1573 1574 // Import a label or unnamed label. 1575 static Statement* 1576 do_import(Import_function_body*, Location); 1577 1578 protected: 1579 int 1580 do_traverse(Traverse*); 1581 1582 Bstatement* 1583 do_get_backend(Translate_context*); 1584 1585 int 1586 do_inlining_cost() 1587 { return 1; } 1588 1589 void 1590 do_export_statement(Export_function_body*); 1591 1592 void 1593 do_dump_statement(Ast_dump_context*) const; 1594 1595 private: 1596 // The label. 1597 Label* label_; 1598 }; 1599 1600 // An unnamed label statement. 1601 1602 class Unnamed_label_statement : public Statement 1603 { 1604 public: 1605 Unnamed_label_statement(Unnamed_label* label); 1606 1607 protected: 1608 int 1609 do_traverse(Traverse*); 1610 1611 Bstatement* 1612 do_get_backend(Translate_context* context); 1613 1614 int 1615 do_inlining_cost() 1616 { return 1; } 1617 1618 void 1619 do_export_statement(Export_function_body*); 1620 1621 void 1622 do_dump_statement(Ast_dump_context*) const; 1623 1624 private: 1625 // The label. 1626 Unnamed_label* label_; 1627 }; 1628 1629 // An if statement. 1630 1631 class If_statement : public Statement 1632 { 1633 public: 1634 If_statement(Expression* cond, Block* then_block, Block* else_block, 1635 Location location) 1636 : Statement(STATEMENT_IF, location), 1637 cond_(cond), then_block_(then_block), else_block_(else_block) 1638 { } 1639 1640 Expression* 1641 condition() const 1642 { return this->cond_; } 1643 1644 Block* 1645 then_block() const 1646 { return this->then_block_; } 1647 1648 Block* 1649 else_block() const 1650 { return this->else_block_; } 1651 1652 // Import an if statement. 1653 static Statement* 1654 do_import(Import_function_body*, Location); 1655 1656 protected: 1657 int 1658 do_traverse(Traverse*); 1659 1660 void 1661 do_determine_types(); 1662 1663 void 1664 do_check_types(Gogo*); 1665 1666 int 1667 do_inlining_cost() 1668 { return 5; } 1669 1670 void 1671 do_export_statement(Export_function_body*); 1672 1673 bool 1674 do_may_fall_through() const; 1675 1676 Bstatement* 1677 do_get_backend(Translate_context*); 1678 1679 void 1680 do_dump_statement(Ast_dump_context*) const; 1681 1682 private: 1683 Expression* cond_; 1684 Block* then_block_; 1685 Block* else_block_; 1686 }; 1687 1688 // A for statement. 1689 1690 class For_statement : public Statement 1691 { 1692 public: 1693 For_statement(Block* init, Expression* cond, Block* post, 1694 Location location) 1695 : Statement(STATEMENT_FOR, location), 1696 init_(init), cond_(cond), post_(post), statements_(NULL), 1697 break_label_(NULL), continue_label_(NULL) 1698 { } 1699 1700 // Add the statements. 1701 void 1702 add_statements(Block* statements) 1703 { 1704 go_assert(this->statements_ == NULL); 1705 this->statements_ = statements; 1706 } 1707 1708 // Return the break label for this for statement. 1709 Unnamed_label* 1710 break_label(); 1711 1712 // Return the continue label for this for statement. 1713 Unnamed_label* 1714 continue_label(); 1715 1716 // Set the break and continue labels for this statement. 1717 void 1718 set_break_continue_labels(Unnamed_label* break_label, 1719 Unnamed_label* continue_label); 1720 1721 protected: 1722 int 1723 do_traverse(Traverse*); 1724 1725 bool 1726 do_traverse_assignments(Traverse_assignments*) 1727 { go_unreachable(); } 1728 1729 Statement* 1730 do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); 1731 1732 bool 1733 do_may_fall_through() const; 1734 1735 Bstatement* 1736 do_get_backend(Translate_context*) 1737 { go_unreachable(); } 1738 1739 void 1740 do_dump_statement(Ast_dump_context*) const; 1741 1742 private: 1743 // The initialization statements. This may be NULL. 1744 Block* init_; 1745 // The condition. This may be NULL. 1746 Expression* cond_; 1747 // The statements to run after each iteration. This may be NULL. 1748 Block* post_; 1749 // The statements in the loop itself. 1750 Block* statements_; 1751 // The break label, if needed. 1752 Unnamed_label* break_label_; 1753 // The continue label, if needed. 1754 Unnamed_label* continue_label_; 1755 }; 1756 1757 // A for statement over a range clause. 1758 1759 class For_range_statement : public Statement 1760 { 1761 public: 1762 For_range_statement(Expression* index_var, Expression* value_var, 1763 Expression* range, Location location) 1764 : Statement(STATEMENT_FOR_RANGE, location), 1765 index_var_(index_var), value_var_(value_var), range_(range), 1766 statements_(NULL), break_label_(NULL), continue_label_(NULL) 1767 { } 1768 1769 // Add the statements. 1770 void 1771 add_statements(Block* statements) 1772 { 1773 go_assert(this->statements_ == NULL); 1774 this->statements_ = statements; 1775 } 1776 1777 // Return the break label for this for statement. 1778 Unnamed_label* 1779 break_label(); 1780 1781 // Return the continue label for this for statement. 1782 Unnamed_label* 1783 continue_label(); 1784 1785 protected: 1786 int 1787 do_traverse(Traverse*); 1788 1789 bool 1790 do_traverse_assignments(Traverse_assignments*) 1791 { go_unreachable(); } 1792 1793 Statement* 1794 do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); 1795 1796 Bstatement* 1797 do_get_backend(Translate_context*) 1798 { go_unreachable(); } 1799 1800 void 1801 do_dump_statement(Ast_dump_context*) const; 1802 1803 private: 1804 Expression* 1805 make_range_ref(Named_object*, Temporary_statement*, Location); 1806 1807 Call_expression* 1808 call_builtin(Gogo*, const char* funcname, Expression* arg, Location); 1809 1810 void 1811 lower_range_array(Gogo*, Block*, Block*, Named_object*, Temporary_statement*, 1812 Temporary_statement*, Temporary_statement*, 1813 Block**, Expression**, Block**, Block**); 1814 1815 void 1816 lower_range_slice(Gogo*, Block*, Block*, Named_object*, Temporary_statement*, 1817 Temporary_statement*, Temporary_statement*, 1818 Block**, Expression**, Block**, Block**); 1819 1820 void 1821 lower_range_string(Gogo*, Block*, Block*, Named_object*, Temporary_statement*, 1822 Temporary_statement*, Temporary_statement*, 1823 Block**, Expression**, Block**, Block**); 1824 1825 void 1826 lower_range_map(Gogo*, Map_type*, Block*, Block*, Named_object*, 1827 Temporary_statement*, Temporary_statement*, 1828 Temporary_statement*, Block**, Expression**, Block**, 1829 Block**); 1830 1831 void 1832 lower_range_channel(Gogo*, Block*, Block*, Named_object*, 1833 Temporary_statement*, Temporary_statement*, 1834 Temporary_statement*, Block**, Expression**, Block**, 1835 Block**); 1836 1837 Statement* 1838 lower_map_range_clear(Type*, Block*, Expression*, Named_object*, 1839 Temporary_statement*, Location); 1840 1841 Statement* 1842 lower_array_range_clear(Gogo*, Type*, Expression*, Block*, 1843 Named_object*, Temporary_statement*, 1844 Location); 1845 1846 // The variable which is set to the index value. 1847 Expression* index_var_; 1848 // The variable which is set to the element value. This may be 1849 // NULL. 1850 Expression* value_var_; 1851 // The expression we are ranging over. 1852 Expression* range_; 1853 // The statements in the block. 1854 Block* statements_; 1855 // The break label, if needed. 1856 Unnamed_label* break_label_; 1857 // The continue label, if needed. 1858 Unnamed_label* continue_label_; 1859 }; 1860 1861 // Class Case_clauses holds the clauses of a switch statement. This 1862 // is built by the parser. 1863 1864 class Case_clauses 1865 { 1866 public: 1867 Case_clauses() 1868 : clauses_() 1869 { } 1870 1871 // Add a new clause. CASES is a list of case expressions; it may be 1872 // NULL. IS_DEFAULT is true if this is the default case. 1873 // STATEMENTS is a block of statements. IS_FALLTHROUGH is true if 1874 // after the statements the case clause should fall through to the 1875 // next clause. 1876 void 1877 add(Expression_list* cases, bool is_default, Block* statements, 1878 bool is_fallthrough, Location location) 1879 { 1880 this->clauses_.push_back(Case_clause(cases, is_default, statements, 1881 is_fallthrough, location)); 1882 } 1883 1884 // Return whether there are no clauses. 1885 bool 1886 empty() const 1887 { return this->clauses_.empty(); } 1888 1889 // Traverse the case clauses. 1890 int 1891 traverse(Traverse*); 1892 1893 // Lower for a nonconstant switch. 1894 void 1895 lower(Block*, Temporary_statement*, Unnamed_label*) const; 1896 1897 // Determine types of expressions. The Type parameter is the type 1898 // of the switch value. 1899 void 1900 determine_types(Type*); 1901 1902 // Check types. The Type parameter is the type of the switch value. 1903 bool 1904 check_types(Type*); 1905 1906 // Return true if all the clauses are constant values. 1907 bool 1908 is_constant() const; 1909 1910 // Return true if these clauses may fall through to the statements 1911 // following the switch statement. 1912 bool 1913 may_fall_through() const; 1914 1915 // Return the body of a SWITCH_EXPR when all the clauses are 1916 // constants. 1917 void 1918 get_backend(Translate_context*, Unnamed_label* break_label, 1919 std::vector<std::vector<Bexpression*> >* all_cases, 1920 std::vector<Bstatement*>* all_statements) const; 1921 1922 // Dump the AST representation to a dump context. 1923 void 1924 dump_clauses(Ast_dump_context*) const; 1925 1926 private: 1927 // For a constant switch we need to keep a record of constants we 1928 // have already seen. 1929 class Hash_integer_value; 1930 class Eq_integer_value; 1931 typedef Unordered_set_hash(Expression*, Hash_integer_value, 1932 Eq_integer_value) Case_constants; 1933 1934 // One case clause. 1935 class Case_clause 1936 { 1937 public: 1938 Case_clause() 1939 : cases_(NULL), statements_(NULL), is_default_(false), 1940 is_fallthrough_(false), location_(Linemap::unknown_location()) 1941 { } 1942 1943 Case_clause(Expression_list* cases, bool is_default, Block* statements, 1944 bool is_fallthrough, Location location) 1945 : cases_(cases), statements_(statements), is_default_(is_default), 1946 is_fallthrough_(is_fallthrough), location_(location) 1947 { } 1948 1949 // Whether this clause falls through to the next clause. 1950 bool 1951 is_fallthrough() const 1952 { return this->is_fallthrough_; } 1953 1954 // Whether this is the default. 1955 bool 1956 is_default() const 1957 { return this->is_default_; } 1958 1959 // The location of this clause. 1960 Location 1961 location() const 1962 { return this->location_; } 1963 1964 // Traversal. 1965 int 1966 traverse(Traverse*); 1967 1968 // Lower for a nonconstant switch. 1969 void 1970 lower(Block*, Temporary_statement*, Unnamed_label*, Unnamed_label*) const; 1971 1972 // Determine types. 1973 void 1974 determine_types(Type*); 1975 1976 // Check types. 1977 bool 1978 check_types(Type*); 1979 1980 // Return true if all the case expressions are constant. 1981 bool 1982 is_constant() const; 1983 1984 // Return true if this clause may fall through to execute the 1985 // statements following the switch statement. This is not the 1986 // same as whether this clause falls through to the next clause. 1987 bool 1988 may_fall_through() const; 1989 1990 // Convert the case values and statements to the backend 1991 // representation. 1992 Bstatement* 1993 get_backend(Translate_context*, Unnamed_label* break_label, 1994 Case_constants*, std::vector<Bexpression*>* cases) const; 1995 1996 // Dump the AST representation to a dump context. 1997 void 1998 dump_clause(Ast_dump_context*) const; 1999 2000 private: 2001 // The list of case expressions. 2002 Expression_list* cases_; 2003 // The statements to execute. 2004 Block* statements_; 2005 // Whether this is the default case. 2006 bool is_default_; 2007 // Whether this falls through after the statements. 2008 bool is_fallthrough_; 2009 // The location of this case clause. 2010 Location location_; 2011 }; 2012 2013 friend class Case_clause; 2014 2015 // The type of the list of clauses. 2016 typedef std::vector<Case_clause> Clauses; 2017 2018 // All the case clauses. 2019 Clauses clauses_; 2020 }; 2021 2022 // A switch statement. 2023 2024 class Switch_statement : public Statement 2025 { 2026 public: 2027 Switch_statement(Expression* val, Location location) 2028 : Statement(STATEMENT_SWITCH, location), 2029 val_(val), clauses_(NULL), break_label_(NULL) 2030 { } 2031 2032 // Add the clauses. 2033 void 2034 add_clauses(Case_clauses* clauses) 2035 { 2036 go_assert(this->clauses_ == NULL); 2037 this->clauses_ = clauses; 2038 } 2039 2040 // Return the break label for this switch statement. 2041 Unnamed_label* 2042 break_label(); 2043 2044 protected: 2045 int 2046 do_traverse(Traverse*); 2047 2048 Statement* 2049 do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); 2050 2051 Bstatement* 2052 do_get_backend(Translate_context*) 2053 { go_unreachable(); } 2054 2055 void 2056 do_dump_statement(Ast_dump_context*) const; 2057 2058 bool 2059 do_may_fall_through() const; 2060 2061 private: 2062 // The value to switch on. This may be NULL. 2063 Expression* val_; 2064 // The case clauses. 2065 Case_clauses* clauses_; 2066 // The break label, if needed. 2067 Unnamed_label* break_label_; 2068 }; 2069 2070 // Class Type_case_clauses holds the clauses of a type switch 2071 // statement. This is built by the parser. 2072 2073 class Type_case_clauses 2074 { 2075 public: 2076 Type_case_clauses() 2077 : clauses_() 2078 { } 2079 2080 // Add a new clause. TYPE is the type for this clause; it may be 2081 // NULL. IS_FALLTHROUGH is true if this falls through to the next 2082 // clause; in this case STATEMENTS will be NULL. IS_DEFAULT is true 2083 // if this is the default case. STATEMENTS is a block of 2084 // statements; it may be NULL. 2085 void 2086 add(Type* type, bool is_fallthrough, bool is_default, Block* statements, 2087 Location location) 2088 { 2089 this->clauses_.push_back(Type_case_clause(type, is_fallthrough, is_default, 2090 statements, location)); 2091 } 2092 2093 // Return whether there are no clauses. 2094 bool 2095 empty() const 2096 { return this->clauses_.empty(); } 2097 2098 // Traverse the type case clauses. 2099 int 2100 traverse(Traverse*); 2101 2102 // Check for duplicates. 2103 void 2104 check_duplicates() const; 2105 2106 // Lower to if and goto statements. 2107 void 2108 lower(Gogo*, Type*, Block*, Temporary_statement* descriptor_temp, 2109 Unnamed_label* break_label) const; 2110 2111 // Return true if these clauses may fall through to the statements 2112 // following the switch statement. 2113 bool 2114 may_fall_through() const; 2115 2116 // Dump the AST representation to a dump context. 2117 void 2118 dump_clauses(Ast_dump_context*) const; 2119 2120 private: 2121 // One type case clause. 2122 class Type_case_clause 2123 { 2124 public: 2125 Type_case_clause() 2126 : type_(NULL), statements_(NULL), is_default_(false), 2127 location_(Linemap::unknown_location()) 2128 { } 2129 2130 Type_case_clause(Type* type, bool is_fallthrough, bool is_default, 2131 Block* statements, Location location) 2132 : type_(type), statements_(statements), is_fallthrough_(is_fallthrough), 2133 is_default_(is_default), location_(location) 2134 { } 2135 2136 // The type. 2137 Type* 2138 type() const 2139 { return this->type_; } 2140 2141 // Whether this is the default. 2142 bool 2143 is_default() const 2144 { return this->is_default_; } 2145 2146 // The location of this type clause. 2147 Location 2148 location() const 2149 { return this->location_; } 2150 2151 // Traversal. 2152 int 2153 traverse(Traverse*); 2154 2155 // Lower to if and goto statements. 2156 void 2157 lower(Gogo*, Type*, Block*, Temporary_statement* descriptor_temp, 2158 Unnamed_label* break_label, Unnamed_label** stmts_label) const; 2159 2160 // Return true if this clause may fall through to execute the 2161 // statements following the switch statement. This is not the 2162 // same as whether this clause falls through to the next clause. 2163 bool 2164 may_fall_through() const; 2165 2166 // Dump the AST representation to a dump context. 2167 void 2168 dump_clause(Ast_dump_context*) const; 2169 2170 private: 2171 // The type for this type clause. 2172 Type* type_; 2173 // The statements to execute. 2174 Block* statements_; 2175 // Whether this falls through--this is true for "case T1, T2". 2176 bool is_fallthrough_; 2177 // Whether this is the default case. 2178 bool is_default_; 2179 // The location of this type case clause. 2180 Location location_; 2181 }; 2182 2183 friend class Type_case_clause; 2184 2185 // The type of the list of type clauses. 2186 typedef std::vector<Type_case_clause> Type_clauses; 2187 2188 // All the type case clauses. 2189 Type_clauses clauses_; 2190 }; 2191 2192 // A type switch statement. 2193 2194 class Type_switch_statement : public Statement 2195 { 2196 public: 2197 Type_switch_statement(const std::string& name, Expression* expr, 2198 Location location) 2199 : Statement(STATEMENT_TYPE_SWITCH, location), 2200 name_(name), expr_(expr), clauses_(NULL), break_label_(NULL) 2201 { } 2202 2203 // Add the clauses. 2204 void 2205 add_clauses(Type_case_clauses* clauses) 2206 { 2207 go_assert(this->clauses_ == NULL); 2208 this->clauses_ = clauses; 2209 } 2210 2211 // Return the break label for this type switch statement. 2212 Unnamed_label* 2213 break_label(); 2214 2215 protected: 2216 int 2217 do_traverse(Traverse*); 2218 2219 Statement* 2220 do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); 2221 2222 Bstatement* 2223 do_get_backend(Translate_context*) 2224 { go_unreachable(); } 2225 2226 void 2227 do_dump_statement(Ast_dump_context*) const; 2228 2229 bool 2230 do_may_fall_through() const; 2231 2232 private: 2233 // The name of the variable declared in the type switch guard. Empty if there 2234 // is no variable declared. 2235 std::string name_; 2236 // The expression we are switching on if there is no variable. 2237 Expression* expr_; 2238 // The type case clauses. 2239 Type_case_clauses* clauses_; 2240 // The break label, if needed. 2241 Unnamed_label* break_label_; 2242 }; 2243 2244 #endif // !defined(GO_STATEMENTS_H)