LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - statements.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.7 % 322 305
Test Date: 2026-02-28 14:20:25 Functions: 86.7 % 45 39
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.