LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - statements.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 296 320 92.5 %
Date: 2020-07-04 13:15:35 Functions: 38 47 80.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.