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

Generated by: LCOV version 2.1-beta

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