LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - parse.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.4 % 3062 2767
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 110 110
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // parse.cc -- Go frontend parser.
       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              : #include "go-system.h"
       8              : 
       9              : #include "lex.h"
      10              : #include "gogo.h"
      11              : #include "go-diagnostics.h"
      12              : #include "types.h"
      13              : #include "statements.h"
      14              : #include "expressions.h"
      15              : #include "parse.h"
      16              : 
      17              : // Struct Parse::Enclosing_var_comparison.
      18              : 
      19              : // Return true if v1 should be considered to be less than v2.
      20              : 
      21              : bool
      22        85922 : Parse::Enclosing_var_comparison::operator()(const Enclosing_var& v1,
      23              :                                             const Enclosing_var& v2) const
      24              : {
      25        85922 :   if (v1.var() == v2.var())
      26              :     return false;
      27              : 
      28        50604 :   const std::string& n1(v1.var()->name());
      29        50604 :   const std::string& n2(v2.var()->name());
      30        50604 :   int i = n1.compare(n2);
      31        50604 :   if (i < 0)
      32              :     return true;
      33        20357 :   else if (i > 0)
      34              :     return false;
      35              : 
      36              :   // If we get here it means that a single nested function refers to
      37              :   // two different variables defined in enclosing functions, and both
      38              :   // variables have the same name.  I think this is impossible.
      39            0 :   go_unreachable();
      40              : }
      41              : 
      42              : // Class Parse.
      43              : 
      44        12707 : Parse::Parse(Lex* lex, Gogo* gogo)
      45        12707 :   : lex_(lex),
      46        12707 :     token_(Token::make_invalid_token(Linemap::unknown_location())),
      47        12707 :     unget_token_(Token::make_invalid_token(Linemap::unknown_location())),
      48        12707 :     unget_token_valid_(false),
      49        12707 :     is_erroneous_function_(false),
      50        12707 :     gogo_(gogo),
      51        12707 :     break_stack_(NULL),
      52        12707 :     continue_stack_(NULL),
      53        12707 :     enclosing_vars_()
      54              : {
      55        12707 : }
      56              : 
      57              : // Return the current token.
      58              : 
      59              : const Token*
      60     60221866 : Parse::peek_token()
      61              : {
      62     60221866 :   if (this->unget_token_valid_)
      63      4355881 :     return &this->unget_token_;
      64     55865985 :   if (this->token_.is_invalid())
      65        12707 :     this->token_ = this->lex_->next_token();
      66     55865985 :   return &this->token_;
      67              : }
      68              : 
      69              : // Advance to the next token and return it.
      70              : 
      71              : const Token*
      72     21728318 : Parse::advance_token()
      73              : {
      74     21728318 :   if (this->unget_token_valid_)
      75              :     {
      76      2000178 :       this->unget_token_valid_ = false;
      77      2000178 :       if (!this->token_.is_invalid())
      78      2000178 :         return &this->token_;
      79              :     }
      80     19728140 :   this->token_ = this->lex_->next_token();
      81     19728140 :   return &this->token_;
      82              : }
      83              : 
      84              : // Push a token back on the input stream.
      85              : 
      86              : void
      87      2000178 : Parse::unget_token(const Token& token)
      88              : {
      89      2000178 :   go_assert(!this->unget_token_valid_);
      90      2000178 :   this->unget_token_ = token;
      91      2000178 :   this->unget_token_valid_ = true;
      92      2000178 : }
      93              : 
      94              : // The location of the current token.
      95              : 
      96              : Location
      97      9327865 : Parse::location()
      98              : {
      99      9327865 :   return this->peek_token()->location();
     100              : }
     101              : 
     102              : // IdentifierList = identifier { "," identifier } .
     103              : 
     104              : void
     105       449223 : Parse::identifier_list(Typed_identifier_list* til)
     106              : {
     107       449223 :   const Token* token = this->peek_token();
     108       466133 :   while (true)
     109              :     {
     110       457678 :       if (!token->is_identifier())
     111              :         {
     112            1 :           go_error_at(this->location(), "expected identifier");
     113            1 :           return;
     114              :         }
     115       457677 :       std::string name =
     116       457677 :         this->gogo_->pack_hidden_name(token->identifier(),
     117       457677 :                                       token->is_identifier_exported());
     118       915354 :       til->push_back(Typed_identifier(name, NULL, token->location()));
     119       457677 :       token = this->advance_token();
     120       457677 :       if (!token->is_op(OPERATOR_COMMA))
     121       449222 :         return;
     122         8455 :       token = this->advance_token();
     123       457677 :     }
     124              : }
     125              : 
     126              : // ExpressionList = Expression { "," Expression } .
     127              : 
     128              : // If MAY_BE_COMPOSITE_LIT is true, an expression may be a composite
     129              : // literal.
     130              : 
     131              : // If MAY_BE_SINK is true, the expressions in the list may be "_".
     132              : 
     133              : Expression_list*
     134      1556593 : Parse::expression_list(Expression* first, bool may_be_sink,
     135              :                        bool may_be_composite_lit)
     136              : {
     137      1556593 :   Expression_list* ret = new Expression_list();
     138      1556593 :   if (first != NULL)
     139         3094 :     ret->push_back(first);
     140      2137506 :   while (true)
     141              :     {
     142      2137506 :       ret->push_back(this->expression(PRECEDENCE_NORMAL, may_be_sink,
     143              :                                       may_be_composite_lit, NULL, NULL));
     144              : 
     145      2137506 :       const Token* token = this->peek_token();
     146      2137506 :       if (!token->is_op(OPERATOR_COMMA))
     147      1556593 :         return ret;
     148              : 
     149              :       // Most expression lists permit a trailing comma.
     150       581328 :       Location location = token->location();
     151       581328 :       this->advance_token();
     152       581328 :       if (!this->expression_may_start_here())
     153              :         {
     154          415 :           this->unget_token(Token::make_operator_token(OPERATOR_COMMA,
     155              :                                                        location));
     156          415 :           return ret;
     157              :         }
     158              :     }
     159              : }
     160              : 
     161              : // QualifiedIdent = [ PackageName "." ] identifier .
     162              : // PackageName = identifier .
     163              : 
     164              : // This sets *PNAME to the identifier and sets *PPACKAGE to the
     165              : // package or NULL if there isn't one.  This returns true on success,
     166              : // false on failure in which case it will have emitted an error
     167              : // message.
     168              : 
     169              : bool
     170       575667 : Parse::qualified_ident(std::string* pname, Named_object** ppackage)
     171              : {
     172       575667 :   const Token* token = this->peek_token();
     173       575667 :   if (!token->is_identifier())
     174              :     {
     175            0 :       go_error_at(this->location(), "expected identifier");
     176            0 :       return false;
     177              :     }
     178              : 
     179       575667 :   std::string name = token->identifier();
     180       575667 :   bool is_exported = token->is_identifier_exported();
     181       575667 :   name = this->gogo_->pack_hidden_name(name, is_exported);
     182              : 
     183       575667 :   token = this->advance_token();
     184       575667 :   if (!token->is_op(OPERATOR_DOT))
     185              :     {
     186       493659 :       *pname = name;
     187       493659 :       *ppackage = NULL;
     188       493659 :       return true;
     189              :     }
     190              : 
     191        82008 :   Named_object* package = this->gogo_->lookup(name, NULL);
     192        82008 :   if (package == NULL || !package->is_package())
     193              :     {
     194            5 :       if (package == NULL)
     195            5 :         go_error_at(this->location(), "reference to undefined name %qs",
     196           10 :                     Gogo::message_name(name).c_str());
     197              :       else
     198            0 :         go_error_at(this->location(), "expected package");
     199              :       // We expect . IDENTIFIER; skip both.
     200            5 :       if (this->advance_token()->is_identifier())
     201            5 :         this->advance_token();
     202            5 :       return false;
     203              :     }
     204              : 
     205        82003 :   package->package_value()->note_usage(Gogo::unpack_hidden_name(name));
     206              : 
     207        82003 :   token = this->advance_token();
     208        82003 :   if (!token->is_identifier())
     209              :     {
     210            0 :       go_error_at(this->location(), "expected identifier");
     211            0 :       return false;
     212              :     }
     213              : 
     214        82003 :   name = token->identifier();
     215              : 
     216        82003 :   if (name == "_")
     217              :     {
     218            0 :       go_error_at(this->location(), "invalid use of %<_%>");
     219            0 :       name = Gogo::erroneous_name();
     220              :     }
     221              : 
     222        82003 :   if (package->name() == this->gogo_->package_name())
     223            0 :     name = this->gogo_->pack_hidden_name(name,
     224            0 :                                          token->is_identifier_exported());
     225              : 
     226        82003 :   *pname = name;
     227        82003 :   *ppackage = package;
     228              : 
     229        82003 :   this->advance_token();
     230              : 
     231        82003 :   return true;
     232       575667 : }
     233              : 
     234              : // Type = TypeName | TypeLit | "(" Type ")" .
     235              : // TypeLit =
     236              : //      ArrayType | StructType | PointerType | FunctionType | InterfaceType |
     237              : //      SliceType | MapType | ChannelType .
     238              : 
     239              : Type*
     240       804425 : Parse::type()
     241              : {
     242       804425 :   const Token* token = this->peek_token();
     243       804425 :   if (token->is_identifier())
     244       558447 :     return this->type_name(true);
     245       245978 :   else if (token->is_op(OPERATOR_LSQUARE))
     246        57491 :     return this->array_type(false);
     247       232284 :   else if (token->is_keyword(KEYWORD_CHAN)
     248       188487 :            || token->is_op(OPERATOR_CHANOP))
     249         4761 :     return this->channel_type();
     250       183726 :   else if (token->is_keyword(KEYWORD_INTERFACE))
     251         3139 :     return this->interface_type(true);
     252       180587 :   else if (token->is_keyword(KEYWORD_FUNC))
     253              :     {
     254         5615 :       Location location = token->location();
     255         5615 :       this->advance_token();
     256         5615 :       Type* type = this->signature(NULL, location);
     257         5615 :       if (type == NULL)
     258            1 :         return Type::make_error_type();
     259              :       return type;
     260              :     }
     261       174972 :   else if (token->is_keyword(KEYWORD_MAP))
     262         9939 :     return this->map_type();
     263       165033 :   else if (token->is_keyword(KEYWORD_STRUCT))
     264        25103 :     return this->struct_type();
     265       139930 :   else if (token->is_op(OPERATOR_MULT))
     266       139774 :     return this->pointer_type();
     267          156 :   else if (token->is_op(OPERATOR_LPAREN))
     268              :     {
     269          148 :       this->advance_token();
     270          148 :       Type* ret = this->type();
     271          148 :       if (this->peek_token()->is_op(OPERATOR_RPAREN))
     272          148 :         this->advance_token();
     273              :       else
     274              :         {
     275            0 :           if (!ret->is_error_type())
     276            0 :             go_error_at(this->location(), "expected %<)%>");
     277              :         }
     278          148 :       return ret;
     279              :     }
     280              :   else
     281              :     {
     282            8 :       go_error_at(token->location(), "expected type");
     283            8 :       return Type::make_error_type();
     284              :     }
     285              : }
     286              : 
     287              : bool
     288       298928 : Parse::type_may_start_here()
     289              : {
     290       298928 :   const Token* token = this->peek_token();
     291       298928 :   return (token->is_identifier()
     292       216406 :           || token->is_op(OPERATOR_LSQUARE)
     293       216300 :           || token->is_op(OPERATOR_CHANOP)
     294       216175 :           || token->is_keyword(KEYWORD_CHAN)
     295       215995 :           || token->is_keyword(KEYWORD_INTERFACE)
     296       215697 :           || token->is_keyword(KEYWORD_FUNC)
     297       215507 :           || token->is_keyword(KEYWORD_MAP)
     298       214459 :           || token->is_keyword(KEYWORD_STRUCT)
     299       207091 :           || token->is_op(OPERATOR_MULT)
     300       298928 :           || token->is_op(OPERATOR_LPAREN));
     301              : }
     302              : 
     303              : // TypeName = QualifiedIdent .
     304              : 
     305              : // If MAY_BE_NIL is true, then an identifier with the value of the
     306              : // predefined constant nil is accepted, returning the nil type.
     307              : 
     308              : Type*
     309       575667 : Parse::type_name(bool issue_error)
     310              : {
     311       575667 :   Location location = this->location();
     312              : 
     313       575667 :   std::string name;
     314       575667 :   Named_object* package;
     315       575667 :   if (!this->qualified_ident(&name, &package))
     316            5 :     return Type::make_error_type();
     317              : 
     318       575662 :   Named_object* named_object;
     319       575662 :   if (package == NULL)
     320       493659 :     named_object = this->gogo_->lookup(name, NULL);
     321              :   else
     322              :     {
     323        82003 :       named_object = package->package_value()->lookup(name);
     324        82003 :       if (named_object == NULL
     325        82003 :           && issue_error
     326        82003 :           && package->name() != this->gogo_->package_name())
     327              :         {
     328              :           // Check whether the name is there but hidden.
     329            4 :           std::string s = ('.' + package->package_value()->pkgpath()
     330            4 :                            + '.' + name);
     331            4 :           named_object = package->package_value()->lookup(s);
     332            4 :           if (named_object != NULL)
     333              :             {
     334            1 :               Package* p = package->package_value();
     335            1 :               const std::string& packname(p->package_name());
     336            1 :               go_error_at(location,
     337              :                           "invalid reference to hidden type %<%s.%s%>",
     338            2 :                           Gogo::message_name(packname).c_str(),
     339            1 :                           Gogo::message_name(name).c_str());
     340            1 :               issue_error = false;
     341              :             }
     342            4 :         }
     343              :     }
     344              : 
     345       575662 :   bool ok = true;
     346       575662 :   if (named_object == NULL)
     347              :     {
     348        20194 :       if (package == NULL)
     349        20189 :         named_object = this->gogo_->add_unknown_name(name, location);
     350              :       else
     351              :         {
     352            5 :           const std::string& packname(package->package_value()->package_name());
     353            5 :           go_error_at(location, "reference to undefined identifier %<%s.%s%>",
     354           10 :                       Gogo::message_name(packname).c_str(),
     355            5 :                       Gogo::message_name(name).c_str());
     356            5 :           issue_error = false;
     357            5 :           ok = false;
     358              :         }
     359              :     }
     360       555468 :   else if (named_object->is_type())
     361              :     {
     362       216935 :       if (!named_object->type_value()->is_visible())
     363              :         ok = false;
     364              :     }
     365       338533 :   else if (named_object->is_unknown() || named_object->is_type_declaration())
     366              :     ;
     367              :   else
     368              :     ok = false;
     369              : 
     370        20194 :   if (!ok)
     371              :     {
     372            8 :       if (issue_error)
     373            2 :         go_error_at(location, "expected type");
     374            8 :       return Type::make_error_type();
     375              :     }
     376              : 
     377       575654 :   if (named_object->is_type())
     378       216934 :     return named_object->type_value();
     379       358720 :   else if (named_object->is_unknown() || named_object->is_type_declaration())
     380       358720 :     return Type::make_forward_declaration(named_object);
     381              :   else
     382            0 :     go_unreachable();
     383       575667 : }
     384              : 
     385              : // ArrayType = "[" [ ArrayLength ] "]" ElementType .
     386              : // ArrayLength = Expression .
     387              : // ElementType = CompleteType .
     388              : 
     389              : Type*
     390       106340 : Parse::array_type(bool may_use_ellipsis)
     391              : {
     392       106340 :   go_assert(this->peek_token()->is_op(OPERATOR_LSQUARE));
     393       106340 :   const Token* token = this->advance_token();
     394              : 
     395       106340 :   Expression* length = NULL;
     396       106340 :   if (token->is_op(OPERATOR_RSQUARE))
     397        87091 :     this->advance_token();
     398              :   else
     399              :     {
     400        19249 :       if (!token->is_op(OPERATOR_ELLIPSIS))
     401        18374 :         length = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
     402          875 :       else if (may_use_ellipsis)
     403              :         {
     404              :           // An ellipsis is used in composite literals to represent a
     405              :           // fixed array of the size of the number of elements.  We
     406              :           // use a length of nil to represent this, and change the
     407              :           // length when parsing the composite literal.
     408          872 :           length = Expression::make_nil(this->location());
     409          872 :           this->advance_token();
     410              :         }
     411              :       else
     412              :         {
     413            3 :           go_error_at(this->location(),
     414              :                       "use of %<[...]%> outside of array literal");
     415            3 :           length = Expression::make_error(this->location());
     416            3 :           this->advance_token();
     417              :         }
     418        19249 :       if (!this->peek_token()->is_op(OPERATOR_RSQUARE))
     419              :         {
     420            0 :           go_error_at(this->location(), "expected %<]%>");
     421            0 :           return Type::make_error_type();
     422              :         }
     423        19249 :       this->advance_token();
     424              :     }
     425              : 
     426       106340 :   Type* element_type = this->type();
     427       106340 :   if (element_type->is_error_type())
     428            0 :     return Type::make_error_type();
     429              : 
     430       106340 :   return Type::make_array_type(element_type, length);
     431              : }
     432              : 
     433              : // MapType = "map" "[" KeyType "]" ValueType .
     434              : // KeyType = CompleteType .
     435              : // ValueType = CompleteType .
     436              : 
     437              : Type*
     438         9939 : Parse::map_type()
     439              : {
     440         9939 :   Location location = this->location();
     441         9939 :   go_assert(this->peek_token()->is_keyword(KEYWORD_MAP));
     442         9939 :   if (!this->advance_token()->is_op(OPERATOR_LSQUARE))
     443              :     {
     444            0 :       go_error_at(this->location(), "expected %<[%>");
     445            0 :       return Type::make_error_type();
     446              :     }
     447         9939 :   this->advance_token();
     448              : 
     449         9939 :   Type* key_type = this->type();
     450              : 
     451         9939 :   if (!this->peek_token()->is_op(OPERATOR_RSQUARE))
     452              :     {
     453            0 :       go_error_at(this->location(), "expected %<]%>");
     454            0 :       return Type::make_error_type();
     455              :     }
     456         9939 :   this->advance_token();
     457              : 
     458         9939 :   Type* value_type = this->type();
     459              : 
     460         9939 :   if (key_type->is_error_type() || value_type->is_error_type())
     461            2 :     return Type::make_error_type();
     462              : 
     463         9937 :   return Type::make_map_type(key_type, value_type, location);
     464              : }
     465              : 
     466              : // StructType     = "struct" "{" { FieldDecl ";" } "}" .
     467              : 
     468              : Type*
     469        25103 : Parse::struct_type()
     470              : {
     471        25103 :   go_assert(this->peek_token()->is_keyword(KEYWORD_STRUCT));
     472        25103 :   Location location = this->location();
     473        25103 :   if (!this->advance_token()->is_op(OPERATOR_LCURLY))
     474              :     {
     475            0 :       Location token_loc = this->location();
     476            0 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
     477            0 :           && this->advance_token()->is_op(OPERATOR_LCURLY))
     478            0 :         go_error_at(token_loc, "unexpected semicolon or newline before %<{%>");
     479              :       else
     480              :         {
     481            0 :           go_error_at(this->location(), "expected %<{%>");
     482            0 :           return Type::make_error_type();
     483              :         }
     484              :     }
     485        25103 :   this->advance_token();
     486              : 
     487        25103 :   Struct_field_list* sfl = new Struct_field_list;
     488       137957 :   while (!this->peek_token()->is_op(OPERATOR_RCURLY))
     489              :     {
     490        87751 :       this->field_decl(sfl);
     491        87751 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
     492        86728 :         this->advance_token();
     493       113877 :       else if (!this->peek_token()->is_op(OPERATOR_RCURLY))
     494              :         {
     495            0 :           go_error_at(this->location(), "expected %<;%> or %<}%> or newline");
     496            0 :           if (!this->skip_past_error(OPERATOR_RCURLY))
     497            0 :             return Type::make_error_type();
     498              :         }
     499              :     }
     500        25103 :   this->advance_token();
     501              : 
     502        25103 :   for (Struct_field_list::const_iterator pi = sfl->begin();
     503       115892 :        pi != sfl->end();
     504              :        ++pi)
     505              :     {
     506        90792 :       if (pi->type()->is_error_type())
     507            3 :         return pi->type();
     508       500108 :       for (Struct_field_list::const_iterator pj = pi + 1;
     509       500108 :            pj != sfl->end();
     510       409319 :            ++pj)
     511              :         {
     512       409319 :           if (pi->field_name() == pj->field_name()
     513       409319 :               && !Gogo::is_sink_name(pi->field_name()))
     514            2 :             go_error_at(pi->location(), "duplicate field name %qs",
     515            4 :                         Gogo::message_name(pi->field_name()).c_str());
     516              :         }
     517              :     }
     518              : 
     519        25100 :   return Type::make_struct_type(sfl, location);
     520              : }
     521              : 
     522              : // FieldDecl = (IdentifierList CompleteType | TypeName) [ Tag ] .
     523              : // Tag = string_lit .
     524              : 
     525              : void
     526        87751 : Parse::field_decl(Struct_field_list* sfl)
     527              : {
     528        87751 :   const Token* token = this->peek_token();
     529        87751 :   Location location = token->location();
     530        87751 :   bool is_anonymous;
     531        87751 :   bool is_anonymous_pointer;
     532        87751 :   if (token->is_op(OPERATOR_MULT))
     533              :     {
     534              :       is_anonymous = true;
     535              :       is_anonymous_pointer = true;
     536              :     }
     537        87127 :   else if (token->is_identifier())
     538              :     {
     539        87125 :       std::string id = token->identifier();
     540        87125 :       bool is_id_exported = token->is_identifier_exported();
     541        87125 :       Location id_location = token->location();
     542        87125 :       token = this->advance_token();
     543       108801 :       is_anonymous = (token->is_op(OPERATOR_SEMICOLON)
     544        85018 :                       || token->is_op(OPERATOR_RCURLY)
     545       171499 :                       || token->is_op(OPERATOR_DOT)
     546        84374 :                       || token->is_string());
     547        87125 :       is_anonymous_pointer = false;
     548        87125 :       this->unget_token(Token::make_identifier_token(id, is_id_exported,
     549              :                                                      id_location));
     550        87125 :     }
     551              :   else
     552              :     {
     553            2 :       go_error_at(this->location(), "expected field name");
     554            2 :       this->gogo_->mark_locals_used();
     555            9 :       while (!token->is_op(OPERATOR_SEMICOLON)
     556        87758 :              && !token->is_op(OPERATOR_RCURLY)
     557           16 :              && !token->is_eof())
     558            7 :         token = this->advance_token();
     559        87751 :       return;
     560              :     }
     561              : 
     562        87749 :   if (is_anonymous)
     563              :     {
     564         3391 :       if (is_anonymous_pointer)
     565              :         {
     566          624 :           this->advance_token();
     567          624 :           if (!this->peek_token()->is_identifier())
     568              :             {
     569            1 :               go_error_at(this->location(), "expected field name");
     570            1 :               this->gogo_->mark_locals_used();
     571            4 :               while (!token->is_op(OPERATOR_SEMICOLON)
     572            4 :                      && !token->is_op(OPERATOR_RCURLY)
     573            7 :                      && !token->is_eof())
     574            3 :                 token = this->advance_token();
     575            1 :               return;
     576              :             }
     577              :         }
     578         3390 :       Type* type = this->type_name(true);
     579              : 
     580         3390 :       std::string tag;
     581         3390 :       if (this->peek_token()->is_string())
     582              :         {
     583           20 :           tag = this->peek_token()->string_value();
     584           20 :           this->advance_token();
     585              :         }
     586              : 
     587         3390 :       if (!type->is_error_type())
     588              :         {
     589         3388 :           if (is_anonymous_pointer)
     590          623 :             type = Type::make_pointer_type(type);
     591         6776 :           sfl->push_back(Struct_field(Typed_identifier("", type, location)));
     592         3388 :           if (!tag.empty())
     593           20 :             sfl->back().set_tag(tag);
     594              :         }
     595         3390 :     }
     596              :   else
     597              :     {
     598        84358 :       Typed_identifier_list til;
     599        90452 :       while (true)
     600              :         {
     601        87405 :           token = this->peek_token();
     602        87405 :           if (!token->is_identifier())
     603              :             {
     604            0 :               go_error_at(this->location(), "expected identifier");
     605            0 :               return;
     606              :             }
     607        87405 :           std::string name =
     608        87405 :             this->gogo_->pack_hidden_name(token->identifier(),
     609        87405 :                                           token->is_identifier_exported());
     610       174810 :           til.push_back(Typed_identifier(name, NULL, token->location()));
     611       106424 :           if (!this->advance_token()->is_op(OPERATOR_COMMA))
     612              :             break;
     613         3047 :           this->advance_token();
     614         3047 :         }
     615              : 
     616        84358 :       Type* type = this->type();
     617              : 
     618        84358 :       std::string tag;
     619        84358 :       if (this->peek_token()->is_string())
     620              :         {
     621         1743 :           tag = this->peek_token()->string_value();
     622         1743 :           this->advance_token();
     623              :         }
     624              : 
     625       171763 :       for (Typed_identifier_list::iterator p = til.begin();
     626       171763 :            p != til.end();
     627        87405 :            ++p)
     628              :         {
     629        87405 :           p->set_type(type);
     630        87405 :           sfl->push_back(Struct_field(*p));
     631        87405 :           if (!tag.empty())
     632         1742 :             sfl->back().set_tag(tag);
     633              :         }
     634        84358 :     }
     635              : }
     636              : 
     637              : // PointerType = "*" Type .
     638              : 
     639              : Type*
     640       139774 : Parse::pointer_type()
     641              : {
     642       139774 :   go_assert(this->peek_token()->is_op(OPERATOR_MULT));
     643       139774 :   this->advance_token();
     644       139774 :   Type* type = this->type();
     645       139774 :   if (type->is_error_type())
     646              :     return type;
     647       139773 :   return Type::make_pointer_type(type);
     648              : }
     649              : 
     650              : // ChannelType   = Channel | SendChannel | RecvChannel .
     651              : // Channel       = "chan" ElementType .
     652              : // SendChannel   = "chan" "<-" ElementType .
     653              : // RecvChannel   = "<-" "chan" ElementType .
     654              : 
     655              : Type*
     656         4761 : Parse::channel_type()
     657              : {
     658         4761 :   const Token* token = this->peek_token();
     659         4761 :   bool send = true;
     660         4761 :   bool receive = true;
     661         4761 :   if (token->is_op(OPERATOR_CHANOP))
     662              :     {
     663          333 :       if (!this->advance_token()->is_keyword(KEYWORD_CHAN))
     664              :         {
     665            0 :           go_error_at(this->location(), "expected %<chan%>");
     666            0 :           return Type::make_error_type();
     667              :         }
     668          333 :       send = false;
     669          333 :       this->advance_token();
     670              :     }
     671              :   else
     672              :     {
     673         4428 :       go_assert(token->is_keyword(KEYWORD_CHAN));
     674         4428 :       if (this->advance_token()->is_op(OPERATOR_CHANOP))
     675              :         {
     676          389 :           receive = false;
     677          389 :           this->advance_token();
     678              :         }
     679              :     }
     680              : 
     681              :   // Better error messages for the common error of omitting the
     682              :   // channel element type.
     683         4761 :   if (!this->type_may_start_here())
     684              :     {
     685            3 :       token = this->peek_token();
     686            3 :       if (token->is_op(OPERATOR_RCURLY))
     687            1 :         go_error_at(this->location(), "unexpected %<}%> in channel type");
     688            2 :       else if (token->is_op(OPERATOR_RPAREN))
     689            1 :         go_error_at(this->location(), "unexpected %<)%> in channel type");
     690            1 :       else if (token->is_op(OPERATOR_COMMA))
     691            1 :         go_error_at(this->location(), "unexpected comma in channel type");
     692              :       else
     693            0 :         go_error_at(this->location(), "expected channel element type");
     694            3 :       return Type::make_error_type();
     695              :     }
     696              : 
     697         4758 :   Type* element_type = this->type();
     698         4758 :   return Type::make_channel_type(send, receive, element_type);
     699              : }
     700              : 
     701              : // Give an error for a duplicate parameter or receiver name.
     702              : 
     703              : void
     704       204161 : Parse::check_signature_names(const Typed_identifier_list* params,
     705              :                              Parse::Names* names)
     706              : {
     707       505555 :   for (Typed_identifier_list::const_iterator p = params->begin();
     708       505555 :        p != params->end();
     709       301394 :        ++p)
     710              :     {
     711       301394 :       if (p->name().empty() || Gogo::is_sink_name(p->name()))
     712       106356 :         continue;
     713       195038 :       std::pair<std::string, const Typed_identifier*> val =
     714       195038 :         std::make_pair(p->name(), &*p);
     715       195038 :       std::pair<Parse::Names::iterator, bool> ins = names->insert(val);
     716       195038 :       if (!ins.second)
     717              :         {
     718           21 :           go_error_at(p->location(), "redefinition of %qs",
     719           21 :                       Gogo::message_name(p->name()).c_str());
     720           21 :           go_inform(ins.first->second->location(),
     721              :                     "previous definition of %qs was here",
     722           42 :                     Gogo::message_name(p->name()).c_str());
     723              :         }
     724       195038 :     }
     725       204161 : }
     726              : 
     727              : // Signature      = Parameters [ Result ] .
     728              : 
     729              : // RECEIVER is the receiver if there is one, or NULL.  LOCATION is the
     730              : // location of the start of the type.
     731              : 
     732              : // This returns NULL on a parse error.
     733              : 
     734              : Function_type*
     735       164221 : Parse::signature(Typed_identifier* receiver, Location location)
     736              : {
     737       164221 :   bool is_varargs = false;
     738       164221 :   Typed_identifier_list* params;
     739       164221 :   bool params_ok = this->parameters(&params, &is_varargs);
     740              : 
     741       164221 :   Typed_identifier_list* results = NULL;
     742       164221 :   if (this->peek_token()->is_op(OPERATOR_LPAREN)
     743       139450 :       || this->type_may_start_here())
     744              :     {
     745        97124 :       if (!this->result(&results))
     746              :         return NULL;
     747              :     }
     748              : 
     749       164219 :   if (!params_ok)
     750              :     return NULL;
     751              : 
     752       164207 :   Parse::Names names;
     753       164207 :   if (receiver != NULL)
     754        53258 :     names[receiver->name()] = receiver;
     755       164207 :   if (params != NULL)
     756       107039 :     this->check_signature_names(params, &names);
     757       164207 :   if (results != NULL)
     758        97122 :     this->check_signature_names(results, &names);
     759              : 
     760       164207 :   Function_type* ret = Type::make_function_type(receiver, params, results,
     761              :                                                 location);
     762       164207 :   if (is_varargs)
     763         1978 :     ret->set_is_varargs();
     764       164207 :   return ret;
     765       164207 : }
     766              : 
     767              : // Parameters     = "(" [ ParameterList [ "," ] ] ")" .
     768              : 
     769              : // This returns false on a parse error.
     770              : 
     771              : bool
     772       242253 : Parse::parameters(Typed_identifier_list** pparams, bool* is_varargs)
     773              : {
     774       242253 :   *pparams = NULL;
     775              : 
     776       242253 :   if (!this->peek_token()->is_op(OPERATOR_LPAREN))
     777              :     {
     778            0 :       go_error_at(this->location(), "expected %<(%>");
     779            0 :       return false;
     780              :     }
     781              : 
     782       242253 :   Typed_identifier_list* params = NULL;
     783       242253 :   bool saw_error = false;
     784              : 
     785       242253 :   const Token* token = this->advance_token();
     786       242253 :   if (!token->is_op(OPERATOR_RPAREN))
     787              :     {
     788       185083 :       params = this->parameter_list(is_varargs);
     789       185083 :       if (params == NULL)
     790           14 :         saw_error = true;
     791       185083 :       token = this->peek_token();
     792              :     }
     793              : 
     794              :   // The optional trailing comma is picked up in parameter_list.
     795              : 
     796       242253 :   if (!token->is_op(OPERATOR_RPAREN))
     797              :     {
     798            1 :       go_error_at(this->location(), "expected %<)%>");
     799            1 :       return false;
     800              :     }
     801       242252 :   this->advance_token();
     802              : 
     803       242252 :   if (saw_error)
     804              :     return false;
     805              : 
     806       242238 :   *pparams = params;
     807       242238 :   return true;
     808              : }
     809              : 
     810              : // ParameterList  = ParameterDecl { "," ParameterDecl } .
     811              : 
     812              : // This sets *IS_VARARGS if the list ends with an ellipsis.
     813              : // IS_VARARGS will be NULL if varargs are not permitted.
     814              : 
     815              : // We pick up an optional trailing comma.
     816              : 
     817              : // This returns NULL if some error is seen.
     818              : 
     819              : Typed_identifier_list*
     820       185083 : Parse::parameter_list(bool* is_varargs)
     821              : {
     822       185083 :   Location location = this->location();
     823       185083 :   Typed_identifier_list* ret = new Typed_identifier_list();
     824              : 
     825       185083 :   bool saw_error = false;
     826              : 
     827              :   // If we see an identifier and then a comma, then we don't know
     828              :   // whether we are looking at a list of identifiers followed by a
     829              :   // type, or a list of types given by name.  We have to do an
     830              :   // arbitrary lookahead to figure it out.
     831              : 
     832       185083 :   bool parameters_have_names;
     833       185083 :   const Token* token = this->peek_token();
     834       185083 :   if (!token->is_identifier())
     835              :     {
     836              :       // This must be a type which starts with something like '*'.
     837              :       parameters_have_names = false;
     838              :     }
     839              :   else
     840              :     {
     841       176922 :       std::string name = token->identifier();
     842       176922 :       bool is_exported = token->is_identifier_exported();
     843       176922 :       Location id_location = token->location();
     844       176922 :       token = this->advance_token();
     845       176922 :       if (!token->is_op(OPERATOR_COMMA))
     846              :         {
     847       158475 :           if (token->is_op(OPERATOR_DOT))
     848              :             {
     849              :               // This is a qualified identifier, which must turn out
     850              :               // to be a type.
     851              :               parameters_have_names = false;
     852              :             }
     853       156421 :           else if (token->is_op(OPERATOR_RPAREN))
     854              :             {
     855              :               // A single identifier followed by a parenthesis must be
     856              :               // a type name.
     857              :               parameters_have_names = false;
     858              :             }
     859              :           else
     860              :             {
     861              :               // An identifier followed by something other than a
     862              :               // comma or a dot or a right parenthesis must be a
     863              :               // parameter name followed by a type.
     864              :               parameters_have_names = true;
     865              :             }
     866              : 
     867       158475 :           this->unget_token(Token::make_identifier_token(name, is_exported,
     868              :                                                          id_location));
     869              :         }
     870              :       else
     871              :         {
     872              :           // An identifier followed by a comma may be the first in a
     873              :           // list of parameter names followed by a type, or it may be
     874              :           // the first in a list of types without parameter names.  To
     875              :           // find out we gather as many identifiers separated by
     876              :           // commas as we can.
     877        18447 :           std::string id_name = this->gogo_->pack_hidden_name(name,
     878        18447 :                                                               is_exported);
     879        36894 :           ret->push_back(Typed_identifier(id_name, NULL, id_location));
     880        18447 :           bool just_saw_comma = true;
     881        22708 :           while (this->advance_token()->is_identifier())
     882              :             {
     883        22276 :               name = this->peek_token()->identifier();
     884        22276 :               is_exported = this->peek_token()->is_identifier_exported();
     885        22276 :               id_location = this->peek_token()->location();
     886        22276 :               id_name = this->gogo_->pack_hidden_name(name, is_exported);
     887        44552 :               ret->push_back(Typed_identifier(id_name, NULL, id_location));
     888        44552 :               if (!this->advance_token()->is_op(OPERATOR_COMMA))
     889              :                 {
     890              :                   just_saw_comma = false;
     891              :                   break;
     892              :                 }
     893              :             }
     894              : 
     895        18447 :           if (just_saw_comma)
     896              :             {
     897              :               // We saw ID1 "," ID2 "," followed by something which
     898              :               // was not an identifier.  We must be seeing the start
     899              :               // of a type, and ID1 and ID2 must be types, and the
     900              :               // parameters don't have names.
     901              :               parameters_have_names = false;
     902              :             }
     903        18015 :           else if (this->peek_token()->is_op(OPERATOR_RPAREN))
     904              :             {
     905              :               // We saw ID1 "," ID2 ")".  ID1 and ID2 must be types,
     906              :               // and the parameters don't have names.
     907              :               parameters_have_names = false;
     908              :             }
     909        12344 :           else if (this->peek_token()->is_op(OPERATOR_DOT))
     910              :             {
     911              :               // We saw ID1 "," ID2 ".".  ID2 must be a package name,
     912              :               // ID1 must be a type, and the parameters don't have
     913              :               // names.
     914          135 :               parameters_have_names = false;
     915          135 :               this->unget_token(Token::make_identifier_token(name, is_exported,
     916              :                                                              id_location));
     917          135 :               ret->pop_back();
     918          135 :               just_saw_comma = true;
     919              :             }
     920              :           else
     921              :             {
     922              :               // We saw ID1 "," ID2 followed by something other than
     923              :               // ",", ".", or ")".  We must be looking at the start of
     924              :               // a type, and ID1 and ID2 must be parameter names.
     925              :               parameters_have_names = true;
     926              :             }
     927              : 
     928          135 :           if (parameters_have_names)
     929              :             {
     930        12209 :               go_assert(!just_saw_comma);
     931              :               // We have just seen ID1, ID2 xxx.
     932        12209 :               Type* type;
     933        12209 :               if (!this->peek_token()->is_op(OPERATOR_ELLIPSIS))
     934        12207 :                 type = this->type();
     935              :               else
     936              :                 {
     937            2 :                   go_error_at(this->location(),
     938              :                               "%<...%> only permits one name");
     939            2 :                   saw_error = true;
     940            2 :                   this->advance_token();
     941            2 :                   type = this->type();
     942              :                 }
     943        40368 :               for (size_t i = 0; i < ret->size(); ++i)
     944        28159 :                 ret->set_type(i, type);
     945        12209 :               if (!this->peek_token()->is_op(OPERATOR_COMMA))
     946         9366 :                 return saw_error ? NULL : ret;
     947         2843 :               if (this->advance_token()->is_op(OPERATOR_RPAREN))
     948            0 :                 return saw_error ? NULL : ret;
     949              :             }
     950              :           else
     951              :             {
     952         6238 :               Typed_identifier_list* tret = new Typed_identifier_list();
     953         6238 :               for (Typed_identifier_list::const_iterator p = ret->begin();
     954        18667 :                    p != ret->end();
     955        12429 :                    ++p)
     956              :                 {
     957        12429 :                   Named_object* no = this->gogo_->lookup(p->name(), NULL);
     958        12429 :                   Type* type;
     959        12429 :                   if (no == NULL)
     960          655 :                     no = this->gogo_->add_unknown_name(p->name(),
     961              :                                                        p->location());
     962              : 
     963        12429 :                   if (no->is_type())
     964         1269 :                     type = no->type_value();
     965        11160 :                   else if (no->is_unknown() || no->is_type_declaration())
     966        11160 :                     type = Type::make_forward_declaration(no);
     967              :                   else
     968              :                     {
     969            0 :                       go_error_at(p->location(), "expected %qs to be a type",
     970            0 :                                   Gogo::message_name(p->name()).c_str());
     971            0 :                       saw_error = true;
     972            0 :                       type = Type::make_error_type();
     973              :                     }
     974        24858 :                   tret->push_back(Typed_identifier("", type, p->location()));
     975              :                 }
     976         6238 :               delete ret;
     977         6238 :               ret = tret;
     978         6238 :               if (!just_saw_comma
     979         9499 :                   || this->peek_token()->is_op(OPERATOR_RPAREN))
     980         5671 :                 return saw_error ? NULL : ret;
     981              :             }
     982        18447 :         }
     983       176922 :     }
     984              : 
     985       170046 :   bool mix_error = false;
     986       170046 :   this->parameter_decl(parameters_have_names, ret, is_varargs, &mix_error,
     987              :                        &saw_error);
     988       406964 :   while (this->peek_token()->is_op(OPERATOR_COMMA))
     989              :     {
     990        66905 :       if (this->advance_token()->is_op(OPERATOR_RPAREN))
     991              :         break;
     992        66872 :       if (is_varargs != NULL && *is_varargs)
     993              :         {
     994            8 :           go_error_at(this->location(), "%<...%> must be last parameter");
     995            8 :           saw_error = true;
     996              :         }
     997        66872 :       this->parameter_decl(parameters_have_names, ret, is_varargs, &mix_error,
     998              :                            &saw_error);
     999              :     }
    1000       170046 :   if (mix_error)
    1001              :     {
    1002            4 :       go_error_at(location, "mixed named and unnamed function parameters");
    1003            4 :       saw_error = true;
    1004              :     }
    1005       170046 :   if (saw_error)
    1006              :     {
    1007           12 :       delete ret;
    1008           12 :       return NULL;
    1009              :     }
    1010              :   return ret;
    1011              : }
    1012              : 
    1013              : // ParameterDecl  = [ IdentifierList ] [ "..." ] Type .
    1014              : 
    1015              : void
    1016       236918 : Parse::parameter_decl(bool parameters_have_names,
    1017              :                       Typed_identifier_list* til,
    1018              :                       bool* is_varargs,
    1019              :                       bool* mix_error,
    1020              :                       bool* saw_error)
    1021              : {
    1022       236918 :   if (!parameters_have_names)
    1023              :     {
    1024        22959 :       Type* type;
    1025        22959 :       Location location = this->location();
    1026        22959 :       if (!this->peek_token()->is_identifier())
    1027              :         {
    1028         9765 :           if (!this->peek_token()->is_op(OPERATOR_ELLIPSIS))
    1029         9678 :             type = this->type();
    1030              :           else
    1031              :             {
    1032           87 :               if (is_varargs == NULL)
    1033            1 :                 go_error_at(this->location(), "invalid use of %<...%>");
    1034              :               else
    1035           86 :                 *is_varargs = true;
    1036           87 :               this->advance_token();
    1037           87 :               if (is_varargs == NULL
    1038           87 :                   && this->peek_token()->is_op(OPERATOR_RPAREN))
    1039            1 :                 type = Type::make_error_type();
    1040              :               else
    1041              :                 {
    1042           86 :                   Type* element_type = this->type();
    1043           86 :                   type = Type::make_array_type(element_type, NULL);
    1044              :                 }
    1045              :             }
    1046              :         }
    1047              :       else
    1048              :         {
    1049        13194 :           type = this->type_name(false);
    1050        13194 :           if (type->is_error_type()
    1051        13194 :               || (!this->peek_token()->is_op(OPERATOR_COMMA)
    1052        10966 :                   && !this->peek_token()->is_op(OPERATOR_RPAREN)))
    1053              :             {
    1054            4 :               *mix_error = true;
    1055           11 :               while (!this->peek_token()->is_op(OPERATOR_COMMA)
    1056            6 :                      && !this->peek_token()->is_op(OPERATOR_RPAREN)
    1057           10 :                      && !this->peek_token()->is_eof())
    1058            3 :                 this->advance_token();
    1059              :             }
    1060              :         }
    1061        22959 :       if (!type->is_error_type())
    1062        45912 :         til->push_back(Typed_identifier("", type, location));
    1063              :       else
    1064            3 :         *saw_error = true;
    1065              :     }
    1066              :   else
    1067              :     {
    1068       213959 :       size_t orig_count = til->size();
    1069       213959 :       if (this->peek_token()->is_identifier())
    1070       213958 :         this->identifier_list(til);
    1071              :       else
    1072            1 :         *mix_error = true;
    1073       213959 :       size_t new_count = til->size();
    1074              : 
    1075       213959 :       Type* type;
    1076       213959 :       if (!this->peek_token()->is_op(OPERATOR_ELLIPSIS))
    1077       212056 :         type = this->type();
    1078              :       else
    1079              :         {
    1080         1903 :           if (is_varargs == NULL)
    1081              :             {
    1082            0 :               go_error_at(this->location(), "invalid use of %<...%>");
    1083            0 :               *saw_error = true;
    1084              :             }
    1085         1903 :           else if (new_count > orig_count + 1)
    1086              :             {
    1087            0 :               go_error_at(this->location(), "%<...%> only permits one name");
    1088            0 :               *saw_error = true;
    1089              :             }
    1090              :           else
    1091         1903 :             *is_varargs = true;
    1092         1903 :           this->advance_token();
    1093         1903 :           Type* element_type = this->type();
    1094         1903 :           type = Type::make_array_type(element_type, NULL);
    1095              :         }
    1096       432747 :       for (size_t i = orig_count; i < new_count; ++i)
    1097       218788 :         til->set_type(i, type);
    1098              :     }
    1099       236918 : }
    1100              : 
    1101              : // Result         = Parameters | Type .
    1102              : 
    1103              : // This returns false on a parse error.
    1104              : 
    1105              : bool
    1106        97124 : Parse::result(Typed_identifier_list** presults)
    1107              : {
    1108        97124 :   if (this->peek_token()->is_op(OPERATOR_LPAREN))
    1109        24771 :     return this->parameters(presults, NULL);
    1110              :   else
    1111              :     {
    1112        72353 :       Location location = this->location();
    1113        72353 :       Type* type = this->type();
    1114        72353 :       if (type->is_error_type())
    1115              :         {
    1116            0 :           *presults = NULL;
    1117            0 :           return false;
    1118              :         }
    1119        72353 :       Typed_identifier_list* til = new Typed_identifier_list();
    1120       144706 :       til->push_back(Typed_identifier("", type, location));
    1121        72353 :       *presults = til;
    1122        72353 :       return true;
    1123              :     }
    1124              : }
    1125              : 
    1126              : // Block = "{" [ StatementList ] "}" .
    1127              : 
    1128              : // Returns the location of the closing brace.
    1129              : 
    1130              : Location
    1131       473146 : Parse::block()
    1132              : {
    1133       473146 :   if (!this->peek_token()->is_op(OPERATOR_LCURLY))
    1134              :     {
    1135            2 :       Location loc = this->location();
    1136            2 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
    1137            0 :           && this->advance_token()->is_op(OPERATOR_LCURLY))
    1138            0 :         go_error_at(loc, "unexpected semicolon or newline before %<{%>");
    1139              :       else
    1140              :         {
    1141            2 :           go_error_at(this->location(), "expected %<{%>");
    1142            2 :           return Linemap::unknown_location();
    1143              :         }
    1144              :     }
    1145              : 
    1146       473144 :   const Token* token = this->advance_token();
    1147              : 
    1148       473144 :   if (!token->is_op(OPERATOR_RCURLY))
    1149              :     {
    1150       470580 :       this->statement_list();
    1151       470580 :       token = this->peek_token();
    1152       470580 :       if (!token->is_op(OPERATOR_RCURLY))
    1153              :         {
    1154           13 :           if (!token->is_eof() || !saw_errors())
    1155            1 :             go_error_at(this->location(), "expected %<}%>");
    1156              : 
    1157           13 :           this->gogo_->mark_locals_used();
    1158              : 
    1159              :           // Skip ahead to the end of the block, in hopes of avoiding
    1160              :           // lots of meaningless errors.
    1161           13 :           Location ret = token->location();
    1162           13 :           int nest = 0;
    1163           13 :           while (!token->is_eof())
    1164              :             {
    1165            0 :               if (token->is_op(OPERATOR_LCURLY))
    1166            0 :                 ++nest;
    1167            0 :               else if (token->is_op(OPERATOR_RCURLY))
    1168              :                 {
    1169            0 :                   --nest;
    1170            0 :                   if (nest < 0)
    1171              :                     {
    1172            0 :                       this->advance_token();
    1173            0 :                       break;
    1174              :                     }
    1175              :                 }
    1176            0 :               token = this->advance_token();
    1177            0 :               ret = token->location();
    1178              :             }
    1179           13 :           return ret;
    1180              :         }
    1181              :     }
    1182              : 
    1183       473131 :   Location ret = token->location();
    1184       473131 :   this->advance_token();
    1185       473131 :   return ret;
    1186              : }
    1187              : 
    1188              : // InterfaceType      = "interface" "{" [ MethodSpecList ] "}" .
    1189              : // MethodSpecList     = MethodSpec { ";" MethodSpec } [ ";" ] .
    1190              : 
    1191              : Type*
    1192         3142 : Parse::interface_type(bool record)
    1193              : {
    1194         3142 :   go_assert(this->peek_token()->is_keyword(KEYWORD_INTERFACE));
    1195         3142 :   Location location = this->location();
    1196              : 
    1197         3142 :   if (!this->advance_token()->is_op(OPERATOR_LCURLY))
    1198              :     {
    1199            0 :       Location token_loc = this->location();
    1200            0 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
    1201            0 :           && this->advance_token()->is_op(OPERATOR_LCURLY))
    1202            0 :         go_error_at(token_loc, "unexpected semicolon or newline before %<{%>");
    1203              :       else
    1204              :         {
    1205            0 :           go_error_at(this->location(), "expected %<{%>");
    1206            0 :           return Type::make_error_type();
    1207              :         }
    1208              :     }
    1209         3142 :   this->advance_token();
    1210              : 
    1211         3142 :   Typed_identifier_list* methods = new Typed_identifier_list();
    1212         3142 :   if (!this->peek_token()->is_op(OPERATOR_RCURLY))
    1213              :     {
    1214         2142 :       this->method_spec(methods);
    1215         6728 :       while (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    1216              :         {
    1217         4451 :           if (this->advance_token()->is_op(OPERATOR_RCURLY))
    1218              :             break;
    1219         2444 :           this->method_spec(methods);
    1220              :         }
    1221         2142 :       if (!this->peek_token()->is_op(OPERATOR_RCURLY))
    1222              :         {
    1223            0 :           go_error_at(this->location(), "expected %<}%>");
    1224            0 :           while (!this->advance_token()->is_op(OPERATOR_RCURLY))
    1225              :             {
    1226            0 :               if (this->peek_token()->is_eof())
    1227            0 :                 return Type::make_error_type();
    1228              :             }
    1229              :         }
    1230              :     }
    1231         3142 :   this->advance_token();
    1232              : 
    1233         3142 :   if (methods->empty())
    1234              :     {
    1235         1005 :       delete methods;
    1236         1005 :       methods = NULL;
    1237              :     }
    1238              : 
    1239         3142 :   Interface_type* ret;
    1240         3142 :   if (methods == NULL)
    1241         1005 :     ret = Type::make_empty_interface_type(location);
    1242              :   else
    1243         2137 :     ret = Type::make_interface_type(methods, location);
    1244         3142 :   if (record)
    1245         3139 :     this->gogo_->record_interface_type(ret);
    1246              :   return ret;
    1247              : }
    1248              : 
    1249              : // MethodSpec         = MethodName Signature | InterfaceTypeName .
    1250              : // MethodName         = identifier .
    1251              : // InterfaceTypeName  = TypeName .
    1252              : 
    1253              : void
    1254         4586 : Parse::method_spec(Typed_identifier_list* methods)
    1255              : {
    1256         4586 :   const Token* token = this->peek_token();
    1257         4586 :   if (!token->is_identifier())
    1258              :     {
    1259            0 :       go_error_at(this->location(), "expected identifier");
    1260            7 :       return;
    1261              :     }
    1262              : 
    1263         4586 :   std::string name = token->identifier();
    1264         4586 :   bool is_exported = token->is_identifier_exported();
    1265         4586 :   Location location = token->location();
    1266              : 
    1267         4586 :   if (this->advance_token()->is_op(OPERATOR_LPAREN))
    1268              :     {
    1269              :       // This is a MethodName.
    1270         3950 :       if (name == "_")
    1271            2 :         go_error_at(this->location(),
    1272              :                     "methods must have a unique non-blank name");
    1273         3950 :       name = this->gogo_->pack_hidden_name(name, is_exported);
    1274         3950 :       Type* type = this->signature(NULL, location);
    1275         3950 :       if (type == NULL)
    1276              :         return;
    1277         7896 :       methods->push_back(Typed_identifier(name, type, location));
    1278              :     }
    1279              :   else
    1280              :     {
    1281          636 :       this->unget_token(Token::make_identifier_token(name, is_exported,
    1282              :                                                      location));
    1283          636 :       Type* type = this->type_name(false);
    1284          636 :       if (type->is_error_type()
    1285          636 :           || (!this->peek_token()->is_op(OPERATOR_SEMICOLON)
    1286           22 :               && !this->peek_token()->is_op(OPERATOR_RCURLY)))
    1287              :         {
    1288            5 :           if (this->peek_token()->is_op(OPERATOR_COMMA))
    1289            2 :             go_error_at(this->location(),
    1290              :                         "name list not allowed in interface type");
    1291              :           else
    1292            3 :             go_error_at(location, "expected signature or type name");
    1293            5 :           this->gogo_->mark_locals_used();
    1294            5 :           token = this->peek_token();
    1295           19 :           while (!token->is_eof()
    1296           10 :                  && !token->is_op(OPERATOR_SEMICOLON)
    1297           21 :                  && !token->is_op(OPERATOR_RCURLY))
    1298            9 :             token = this->advance_token();
    1299              :           return;
    1300              :         }
    1301              :       // This must be an interface type, but we can't check that now.
    1302              :       // We check it and pull out the methods in
    1303              :       // Interface_type::do_verify.
    1304         1262 :       methods->push_back(Typed_identifier("", type, location));
    1305              :     }
    1306         4586 : }
    1307              : 
    1308              : // Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
    1309              : 
    1310              : void
    1311       352826 : Parse::declaration()
    1312              : {
    1313       352826 :   const Token* token = this->peek_token();
    1314       352826 :   if (token->is_keyword(KEYWORD_CONST))
    1315       120252 :     this->const_decl();
    1316       232574 :   else if (token->is_keyword(KEYWORD_TYPE))
    1317        31362 :     this->type_decl();
    1318       201212 :   else if (token->is_keyword(KEYWORD_VAR))
    1319        72248 :     this->var_decl();
    1320       128964 :   else if (token->is_keyword(KEYWORD_FUNC))
    1321       128964 :     this->function_decl();
    1322              :   else
    1323              :     {
    1324            0 :       go_error_at(this->location(), "expected declaration");
    1325            0 :       this->advance_token();
    1326              :     }
    1327       352826 : }
    1328              : 
    1329              : bool
    1330       294066 : Parse::declaration_may_start_here()
    1331              : {
    1332       294066 :   const Token* token = this->peek_token();
    1333       471802 :   return (token->is_keyword(KEYWORD_CONST)
    1334       147593 :           || token->is_keyword(KEYWORD_TYPE)
    1335       128976 :           || token->is_keyword(KEYWORD_VAR)
    1336       294066 :           || token->is_keyword(KEYWORD_FUNC));
    1337              : }
    1338              : 
    1339              : // Decl<P> = P | "(" [ List<P> ] ")" .
    1340              : 
    1341              : void
    1342       114296 : Parse::decl(void (Parse::*pfn)())
    1343              : {
    1344       114296 :   if (this->peek_token()->is_eof())
    1345              :     {
    1346            2 :       if (!saw_errors())
    1347            0 :         go_error_at(this->location(), "unexpected end of file");
    1348            2 :       return;
    1349              :     }
    1350              : 
    1351       114294 :   if (!this->peek_token()->is_op(OPERATOR_LPAREN))
    1352       105045 :     (this->*pfn)();
    1353              :   else
    1354              :     {
    1355         9249 :       if (this->lex_->get_and_clear_pragmas() != 0)
    1356            0 :         go_error_at(this->location(),
    1357              :                     "ignoring compiler directive before group");
    1358         9249 :       if (this->lex_->has_embeds())
    1359              :         {
    1360            0 :           this->lex_->clear_embeds();
    1361            0 :           go_error_at(this->location(),
    1362              :                       "ignoring %<//go:embed%> comment before group");
    1363              :         }
    1364         9249 :       if (!this->advance_token()->is_op(OPERATOR_RPAREN))
    1365              :         {
    1366         9243 :           this->list(pfn, true);
    1367         9243 :           if (!this->peek_token()->is_op(OPERATOR_RPAREN))
    1368              :             {
    1369            0 :               go_error_at(this->location(), "missing %<)%>");
    1370            0 :               while (!this->advance_token()->is_op(OPERATOR_RPAREN))
    1371              :                 {
    1372            0 :                   if (this->peek_token()->is_eof())
    1373              :                     return;
    1374              :                 }
    1375              :             }
    1376              :         }
    1377         9249 :       this->advance_token();
    1378              :     }
    1379              : }
    1380              : 
    1381              : // List<P> = P { ";" P } [ ";" ] .
    1382              : 
    1383              : // In order to pick up the trailing semicolon we need to know what
    1384              : // might follow.  This is either a '}' or a ')'.
    1385              : 
    1386              : void
    1387         9243 : Parse::list(void (Parse::*pfn)(), bool follow_is_paren)
    1388              : {
    1389         9243 :   (this->*pfn)();
    1390         9243 :   Operator follow = follow_is_paren ? OPERATOR_RPAREN : OPERATOR_RCURLY;
    1391        47915 :   while (this->peek_token()->is_op(OPERATOR_SEMICOLON)
    1392        47917 :          || this->peek_token()->is_op(OPERATOR_COMMA))
    1393              :     {
    1394        47914 :       if (this->peek_token()->is_op(OPERATOR_COMMA))
    1395            1 :         go_error_at(this->location(), "unexpected comma");
    1396        47914 :       if (this->advance_token()->is_op(follow))
    1397              :         break;
    1398        38672 :       (this->*pfn)();
    1399              :     }
    1400         9243 : }
    1401              : 
    1402              : // ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
    1403              : 
    1404              : void
    1405       120252 : Parse::const_decl()
    1406              : {
    1407       120252 :   go_assert(this->peek_token()->is_keyword(KEYWORD_CONST));
    1408       120252 :   this->advance_token();
    1409              : 
    1410       120252 :   int iota = 0;
    1411       120252 :   Type* last_type = NULL;
    1412       120252 :   Expression_list* last_expr_list = NULL;
    1413              : 
    1414       120252 :   if (!this->peek_token()->is_op(OPERATOR_LPAREN))
    1415       116257 :     this->const_spec(iota, &last_type, &last_expr_list);
    1416              :   else
    1417              :     {
    1418         3995 :       this->advance_token();
    1419        46450 :       while (!this->peek_token()->is_op(OPERATOR_RPAREN))
    1420              :         {
    1421        38460 :           this->const_spec(iota, &last_type, &last_expr_list);
    1422        38460 :           ++iota;
    1423        38460 :           if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    1424        38459 :             this->advance_token();
    1425        42456 :           else if (!this->peek_token()->is_op(OPERATOR_RPAREN))
    1426              :             {
    1427            0 :               go_error_at(this->location(),
    1428              :                           "expected %<;%> or %<)%> or newline");
    1429            0 :               if (!this->skip_past_error(OPERATOR_RPAREN))
    1430            0 :                 return;
    1431              :             }
    1432              :         }
    1433         3995 :       this->advance_token();
    1434              :     }
    1435              : 
    1436       120252 :   if (last_expr_list != NULL)
    1437       120249 :     delete last_expr_list;
    1438              : }
    1439              : 
    1440              : // ConstSpec = IdentifierList [ [ CompleteType ] "=" ExpressionList ] .
    1441              : 
    1442              : void
    1443       154717 : Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list)
    1444              : {
    1445       154717 :   this->check_directives();
    1446              : 
    1447       154717 :   Location loc = this->location();
    1448       154717 :   Typed_identifier_list til;
    1449       154717 :   this->identifier_list(&til);
    1450              : 
    1451       154717 :   Type* type = NULL;
    1452       154717 :   if (this->type_may_start_here())
    1453              :     {
    1454        14829 :       type = this->type();
    1455        14829 :       *last_type = NULL;
    1456        14829 :       *last_expr_list = NULL;
    1457              :     }
    1458              : 
    1459       154717 :   Expression_list *expr_list;
    1460       154717 :   if (!this->peek_token()->is_op(OPERATOR_EQ))
    1461              :     {
    1462         9085 :       if (*last_expr_list == NULL)
    1463              :         {
    1464            1 :           go_error_at(this->location(), "expected %<=%>");
    1465            1 :           return;
    1466              :         }
    1467         9084 :       type = *last_type;
    1468         9084 :       expr_list = new Expression_list;
    1469         9084 :       for (Expression_list::const_iterator p = (*last_expr_list)->begin();
    1470        18169 :            p != (*last_expr_list)->end();
    1471         9085 :            ++p)
    1472              :         {
    1473         9085 :           Expression* copy = (*p)->copy();
    1474         9085 :           copy->set_location(loc);
    1475         9085 :           this->update_references(&copy);
    1476         9085 :           expr_list->push_back(copy);
    1477              :         }
    1478              :     }
    1479              :   else
    1480              :     {
    1481       145632 :       this->advance_token();
    1482       145632 :       expr_list = this->expression_list(NULL, false, true);
    1483       145632 :       *last_type = type;
    1484       145632 :       if (*last_expr_list != NULL)
    1485        12399 :         delete *last_expr_list;
    1486       145632 :       *last_expr_list = expr_list;
    1487              :     }
    1488              : 
    1489       154716 :   Expression_list::const_iterator pe = expr_list->begin();
    1490       154716 :   for (Typed_identifier_list::iterator pi = til.begin();
    1491       309493 :        pi != til.end();
    1492       154777 :        ++pi, ++pe)
    1493              :     {
    1494       154777 :       if (pe == expr_list->end())
    1495              :         {
    1496            0 :           go_error_at(this->location(), "not enough initializers");
    1497            0 :           return;
    1498              :         }
    1499       154777 :       if (type != NULL)
    1500        22007 :         pi->set_type(type);
    1501              : 
    1502       154777 :       if (!Gogo::is_sink_name(pi->name()))
    1503       153568 :         this->gogo_->add_constant(*pi, *pe, iota);
    1504              :       else
    1505              :         {
    1506         1209 :           static int count;
    1507         1209 :           char buf[30];
    1508         1209 :           snprintf(buf, sizeof buf, ".$sinkconst%d", count);
    1509         1209 :           ++count;
    1510         2418 :           Typed_identifier ti(std::string(buf), type, pi->location());
    1511         1209 :           Named_object* no = this->gogo_->add_constant(ti, *pe, iota);
    1512         1209 :           no->const_value()->set_is_sink();
    1513         1209 :         }
    1514              :     }
    1515       154716 :   if (pe != expr_list->end())
    1516            0 :     go_error_at(this->location(), "too many initializers");
    1517              : 
    1518              :   return;
    1519       154717 : }
    1520              : 
    1521              : // Update any references to names to refer to the current names,
    1522              : // for weird cases like
    1523              : //
    1524              : // const X = 1
    1525              : // func F() {
    1526              : //      const (
    1527              : //              X = X + X
    1528              : //              Y
    1529              : //      )
    1530              : // }
    1531              : //
    1532              : // where the X + X for the first X is the outer X, but the X + X
    1533              : // copied for Y is the inner X.
    1534              : 
    1535        18170 : class Update_references : public Traverse
    1536              : {
    1537              :  public:
    1538         9085 :   Update_references(Gogo* gogo)
    1539         9085 :     : Traverse(traverse_expressions),
    1540         9085 :       gogo_(gogo)
    1541              :   { }
    1542              : 
    1543              :   int
    1544              :   expression(Expression**);
    1545              : 
    1546              :  private:
    1547              :   Gogo* gogo_;
    1548              : };
    1549              : 
    1550              : int
    1551        14699 : Update_references::expression(Expression** pexpr)
    1552              : {
    1553        14699 :   Named_object* old_no;
    1554        14699 :   switch ((*pexpr)->classification())
    1555              :     {
    1556            7 :     case Expression::EXPRESSION_CONST_REFERENCE:
    1557            7 :       old_no = (*pexpr)->const_expression()->named_object();
    1558            7 :       break;
    1559            0 :     case Expression::EXPRESSION_VAR_REFERENCE:
    1560            0 :       old_no = (*pexpr)->var_expression()->named_object();
    1561            0 :       break;
    1562            0 :     case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
    1563            0 :       old_no = (*pexpr)->enclosed_var_expression()->variable();
    1564            0 :       break;
    1565            4 :     case Expression::EXPRESSION_FUNC_REFERENCE:
    1566            4 :       old_no = (*pexpr)->func_expression()->named_object();
    1567            4 :       break;
    1568         9207 :     case Expression::EXPRESSION_UNKNOWN_REFERENCE:
    1569         9207 :       old_no = (*pexpr)->unknown_expression()->named_object();
    1570         9207 :       break;
    1571              :     default:
    1572              :       return TRAVERSE_CONTINUE;
    1573              :     }
    1574              : 
    1575         9218 :   if (old_no->package() != NULL)
    1576              :     {
    1577              :       // This is a qualified reference, so it can't have changed in
    1578              :       // scope.  FIXME: This probably doesn't handle dot imports
    1579              :       // correctly.
    1580              :       return TRAVERSE_CONTINUE;
    1581              :     }
    1582              : 
    1583         9216 :   Named_object* in_function;
    1584         9216 :   Named_object* new_no = this->gogo_->lookup(old_no->name(), &in_function);
    1585         9216 :   if (new_no == old_no)
    1586              :     return TRAVERSE_CONTINUE;
    1587              : 
    1588              :   // The new name must be a constant, since that is all we have
    1589              :   // introduced into scope.
    1590            0 :   if (!new_no->is_const())
    1591              :     {
    1592            0 :       go_assert(saw_errors());
    1593              :       return TRAVERSE_CONTINUE;
    1594              :     }
    1595              : 
    1596            0 :   *pexpr = Expression::make_const_reference(new_no, (*pexpr)->location());
    1597              : 
    1598            0 :   return TRAVERSE_CONTINUE;
    1599              : }
    1600              : 
    1601              : void
    1602         9085 : Parse::update_references(Expression** pexpr)
    1603              : {
    1604         9085 :   Update_references ur(this->gogo_);
    1605         9085 :   ur.expression(pexpr);
    1606         9085 :   (*pexpr)->traverse_subexpressions(&ur);
    1607         9085 : }
    1608              : 
    1609              : // TypeDecl = "type" Decl<TypeSpec> .
    1610              : 
    1611              : void
    1612        31362 : Parse::type_decl()
    1613              : {
    1614        31362 :   go_assert(this->peek_token()->is_keyword(KEYWORD_TYPE));
    1615        31362 :   this->advance_token();
    1616        31362 :   this->decl(&Parse::type_spec);
    1617        31362 : }
    1618              : 
    1619              : // TypeSpec = identifier ["="] Type .
    1620              : 
    1621              : void
    1622        32054 : Parse::type_spec()
    1623              : {
    1624        32054 :   unsigned int pragmas = this->lex_->get_and_clear_pragmas();
    1625        32054 :   this->check_directives();
    1626              : 
    1627        32054 :   const Token* token = this->peek_token();
    1628        32054 :   if (!token->is_identifier())
    1629              :     {
    1630            0 :       go_error_at(this->location(), "expected identifier");
    1631            0 :       return;
    1632              :     }
    1633        32054 :   std::string name = token->identifier();
    1634        32054 :   bool is_exported = token->is_identifier_exported();
    1635        32054 :   Location location = token->location();
    1636        32054 :   token = this->advance_token();
    1637              : 
    1638        32054 :   bool is_alias = false;
    1639        32054 :   if (token->is_op(OPERATOR_EQ))
    1640              :     {
    1641          312 :       is_alias = true;
    1642          312 :       token = this->advance_token();
    1643              :     }
    1644              : 
    1645              :   // The scope of the type name starts at the point where the
    1646              :   // identifier appears in the source code.  We implement this by
    1647              :   // declaring the type before we read the type definition.
    1648        32054 :   Named_object* named_type = NULL;
    1649        32054 :   if (name != "_")
    1650              :     {
    1651        31990 :       name = this->gogo_->pack_hidden_name(name, is_exported);
    1652        31990 :       named_type = this->gogo_->declare_type(name, location);
    1653              :     }
    1654              : 
    1655        32054 :   Type* type;
    1656        32054 :   if (name == "_" && token->is_keyword(KEYWORD_INTERFACE))
    1657              :     {
    1658              :       // We call Parse::interface_type explicity here because we do not want
    1659              :       // to record an interface with a blank type name.
    1660            3 :       type = this->interface_type(false);
    1661              :     }
    1662        32051 :   else if (!token->is_op(OPERATOR_SEMICOLON))
    1663        32049 :     type = this->type();
    1664              :   else
    1665              :     {
    1666            2 :       go_error_at(this->location(),
    1667              :                   "unexpected semicolon or newline in type declaration");
    1668            2 :       type = Type::make_error_type();
    1669              :     }
    1670              : 
    1671        32054 :   if (type->is_error_type())
    1672              :     {
    1673           11 :       this->gogo_->mark_locals_used();
    1674           24 :       while (!this->peek_token()->is_op(OPERATOR_SEMICOLON)
    1675           15 :              && !this->peek_token()->is_eof())
    1676            2 :         this->advance_token();
    1677              :     }
    1678              : 
    1679        32054 :   if (name != "_")
    1680              :     {
    1681        31990 :       if (named_type->is_type_declaration())
    1682              :         {
    1683        31990 :           Type* ftype = type->forwarded();
    1684        31990 :           if (ftype->forward_declaration_type() != NULL
    1685         6786 :               && (ftype->forward_declaration_type()->named_object()
    1686              :                   == named_type))
    1687              :             {
    1688            5 :               go_error_at(location, "invalid recursive type");
    1689            5 :               type = Type::make_error_type();
    1690              :             }
    1691              : 
    1692        31990 :           Named_type* nt = Type::make_named_type(named_type, type, location);
    1693        31990 :           if (is_alias)
    1694          301 :             nt->set_is_alias();
    1695              : 
    1696        31990 :           this->gogo_->define_type(named_type, nt);
    1697        31990 :           go_assert(named_type->package() == NULL);
    1698              : 
    1699        31990 :           if ((pragmas & GOPRAGMA_NOTINHEAP) != 0)
    1700              :             {
    1701          203 :               nt->set_not_in_heap();
    1702          203 :               pragmas &= ~GOPRAGMA_NOTINHEAP;
    1703              :             }
    1704        31990 :           if (pragmas != 0)
    1705            0 :             go_warning_at(location, 0,
    1706              :                           "ignoring magic %<//go:...%> comment before type");
    1707              :         }
    1708              :       else
    1709              :         {
    1710              :           // This will probably give a redefinition error.
    1711            0 :           this->gogo_->add_type(name, type, location);
    1712              :         }
    1713              :     }
    1714        32054 : }
    1715              : 
    1716              : // VarDecl = "var" Decl<VarSpec> .
    1717              : 
    1718              : void
    1719        72248 : Parse::var_decl()
    1720              : {
    1721        72248 :   go_assert(this->peek_token()->is_keyword(KEYWORD_VAR));
    1722        72248 :   this->advance_token();
    1723        72248 :   this->decl(&Parse::var_spec);
    1724        72248 : }
    1725              : 
    1726              : // VarSpec = IdentifierList
    1727              : //             ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
    1728              : 
    1729              : void
    1730        80548 : Parse::var_spec()
    1731              : {
    1732        80548 :   Location loc = this->location();
    1733              : 
    1734        80548 :   std::vector<std::string>* embeds = NULL;
    1735        80548 :   if (this->lex_->has_embeds())
    1736              :     {
    1737           22 :       if (!this->gogo_->current_file_imported_embed())
    1738            0 :         go_error_at(loc, "invalid go:embed: missing import %<embed%>");
    1739              :       else
    1740              :         {
    1741           22 :           embeds = new(std::vector<std::string>);
    1742           22 :           this->lex_->get_and_clear_embeds(embeds);
    1743              :         }
    1744              :     }
    1745              : 
    1746        80548 :   this->check_directives();
    1747              : 
    1748              :   // Get the variable names.
    1749        80548 :   Typed_identifier_list til;
    1750        80548 :   this->identifier_list(&til);
    1751              : 
    1752        80548 :   if (embeds != NULL)
    1753              :     {
    1754           22 :       if (!this->gogo_->in_global_scope())
    1755              :         {
    1756            0 :           go_error_at(loc, "go:embed only permitted at package scope");
    1757            0 :           embeds = NULL;
    1758              :         }
    1759           22 :       if (til.size() > 1)
    1760              :         {
    1761            0 :           go_error_at(loc, "go:embed cannot apply to multiple vars");
    1762            0 :           embeds = NULL;
    1763              :         }
    1764              :     }
    1765              : 
    1766        80548 :   Location location = this->location();
    1767              : 
    1768        80548 :   Type* type = NULL;
    1769        80548 :   Expression_list* init = NULL;
    1770        80548 :   if (!this->peek_token()->is_op(OPERATOR_EQ))
    1771              :     {
    1772        60382 :       type = this->type();
    1773        60382 :       if (type->is_error_type())
    1774              :         {
    1775            8 :           this->gogo_->mark_locals_used();
    1776           26 :           while (!this->peek_token()->is_op(OPERATOR_EQ)
    1777           18 :                  && !this->peek_token()->is_op(OPERATOR_SEMICOLON)
    1778           28 :                  && !this->peek_token()->is_eof())
    1779           10 :             this->advance_token();
    1780              :         }
    1781        60382 :       if (this->peek_token()->is_op(OPERATOR_EQ))
    1782              :         {
    1783         2525 :           this->advance_token();
    1784         2525 :           init = this->expression_list(NULL, false, true);
    1785              :         }
    1786              :     }
    1787              :   else
    1788              :     {
    1789        20166 :       this->advance_token();
    1790        20166 :       init = this->expression_list(NULL, false, true);
    1791              :     }
    1792              : 
    1793        80548 :   if (embeds != NULL && init != NULL)
    1794              :     {
    1795            0 :       go_error_at(loc, "go:embed cannot apply to var with initializer");
    1796            0 :       embeds = NULL;
    1797              :     }
    1798              : 
    1799        80548 :   this->init_vars(&til, type, init, false, embeds, location);
    1800              : 
    1801        80548 :   if (init != NULL)
    1802        22691 :     delete init;
    1803        80548 : }
    1804              : 
    1805              : // Create variables.  TIL is a list of variable names.  If TYPE is not
    1806              : // NULL, it is the type of all the variables.  If INIT is not NULL, it
    1807              : // is an initializer list for the variables.
    1808              : 
    1809              : void
    1810       309872 : Parse::init_vars(const Typed_identifier_list* til, Type* type,
    1811              :                  Expression_list* init, bool is_coloneq,
    1812              :                  std::vector<std::string>* embeds, Location location)
    1813              : {
    1814              :   // Check for an initialization which can yield multiple values.
    1815       808405 :   if (init != NULL && init->size() == 1 && til->size() > 1)
    1816              :     {
    1817        45007 :       go_assert(embeds == NULL);
    1818        45007 :       if (this->init_vars_from_call(til, type, *init->begin(), is_coloneq,
    1819              :                                     location))
    1820        45005 :         return;
    1821         8584 :       if (this->init_vars_from_map(til, type, *init->begin(), is_coloneq,
    1822              :                                    location))
    1823              :         return;
    1824         6414 :       if (this->init_vars_from_receive(til, type, *init->begin(), is_coloneq,
    1825              :                                        location))
    1826              :         return;
    1827         6368 :       if (this->init_vars_from_type_guard(til, type, *init->begin(),
    1828              :                                           is_coloneq, location))
    1829              :         return;
    1830              :     }
    1831              : 
    1832       471875 :   if (init != NULL && init->size() != til->size())
    1833              :     {
    1834            5 :       if (init->empty() || !init->front()->is_error_expression())
    1835            5 :         go_error_at(location, "wrong number of initializations");
    1836            5 :       init = NULL;
    1837            5 :       if (type == NULL)
    1838            5 :         type = Type::make_error_type();
    1839              :     }
    1840              : 
    1841              :   // Note that INIT was already parsed with the old name bindings, so
    1842              :   // we don't have to worry that it will accidentally refer to the
    1843              :   // newly declared variables.  But we do have to worry about a mix of
    1844              :   // newly declared variables and old variables if the old variables
    1845              :   // appear in the initializations.
    1846              : 
    1847       264867 :   Expression_list::const_iterator pexpr;
    1848       264867 :   if (init != NULL)
    1849       207005 :     pexpr = init->begin();
    1850       264867 :   bool any_new = false;
    1851       264867 :   Expression_list* vars = new Expression_list();
    1852       264867 :   Expression_list* vals = new Expression_list();
    1853       541252 :   for (Typed_identifier_list::const_iterator p = til->begin();
    1854       541252 :        p != til->end();
    1855       276385 :        ++p)
    1856              :     {
    1857       276385 :       if (init != NULL)
    1858       215247 :         go_assert(pexpr != init->end());
    1859       276385 :       Named_object* no = this->init_var(*p, type,
    1860       215247 :                                         init == NULL ? NULL : *pexpr,
    1861              :                                         is_coloneq, false, &any_new,
    1862              :                                         vars, vals);
    1863       276385 :       if (embeds != NULL && no->is_variable())
    1864           22 :         no->var_value()->set_embeds(embeds);
    1865       276385 :       if (init != NULL)
    1866       215247 :         ++pexpr;
    1867              :     }
    1868       264867 :   if (init != NULL)
    1869       207005 :     go_assert(pexpr == init->end());
    1870       264867 :   if (is_coloneq && !any_new)
    1871            6 :     go_error_at(location, "variables redeclared but no variable is new");
    1872       264867 :   this->finish_init_vars(vars, vals, location);
    1873              : }
    1874              : 
    1875              : // See if we need to initialize a list of variables from a function
    1876              : // call.  This returns true if we have set up the variables and the
    1877              : // initialization.
    1878              : 
    1879              : bool
    1880        45007 : Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
    1881              :                            Expression* expr, bool is_coloneq,
    1882              :                            Location location)
    1883              : {
    1884        45007 :   Call_expression* call = expr->call_expression();
    1885        36423 :   if (call == NULL)
    1886              :     return false;
    1887              : 
    1888              :   // This is a function call.  We can't check here whether it returns
    1889              :   // the right number of values, but it might.  Declare the variables,
    1890              :   // and then assign the results of the call to them.
    1891              : 
    1892        36423 :   call->set_expected_result_count(vars->size());
    1893              : 
    1894        36423 :   Named_object* first_var = NULL;
    1895        36423 :   unsigned int index = 0;
    1896        36423 :   bool any_new = false;
    1897        36423 :   Expression_list* ivars = new Expression_list();
    1898        36423 :   Expression_list* ivals = new Expression_list();
    1899        36423 :   for (Typed_identifier_list::const_iterator pv = vars->begin();
    1900       115571 :        pv != vars->end();
    1901        79148 :        ++pv, ++index)
    1902              :     {
    1903        79148 :       Expression* init = Expression::make_call_result(call, index);
    1904        79148 :       Named_object* no = this->init_var(*pv, type, init, is_coloneq, false,
    1905              :                                         &any_new, ivars, ivals);
    1906              : 
    1907        79148 :       if (this->gogo_->in_global_scope() && no->is_variable())
    1908              :         {
    1909          181 :           if (first_var == NULL)
    1910              :             first_var = no;
    1911              :           else
    1912              :             {
    1913              :               // If the current object is a redefinition of another object, we
    1914              :               // might have already recorded the dependency relationship between
    1915              :               // it and the first variable.  Either way, an error will be
    1916              :               // reported for the redefinition and we don't need to properly
    1917              :               // record dependency information for an invalid program.
    1918           95 :               if (no->is_redefinition())
    1919            0 :                 continue;
    1920              : 
    1921              :               // The subsequent vars have an implicit dependency on
    1922              :               // the first one, so that everything gets initialized in
    1923              :               // the right order and so that we detect cycles
    1924              :               // correctly.
    1925           95 :               this->gogo_->record_var_depends_on(no->var_value(), first_var);
    1926              :             }
    1927              :         }
    1928              :     }
    1929              : 
    1930        36423 :   if (is_coloneq && !any_new)
    1931            3 :     go_error_at(location, "variables redeclared but no variable is new");
    1932              : 
    1933        36423 :   this->finish_init_vars(ivars, ivals, location);
    1934              : 
    1935        36423 :   return true;
    1936              : }
    1937              : 
    1938              : // See if we need to initialize a pair of values from a map index
    1939              : // expression.  This returns true if we have set up the variables and
    1940              : // the initialization.
    1941              : 
    1942              : bool
    1943         8584 : Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
    1944              :                           Expression* expr, bool is_coloneq,
    1945              :                           Location location)
    1946              : {
    1947         8584 :   Index_expression* index = expr->index_expression();
    1948         2170 :   if (index == NULL)
    1949              :     return false;
    1950         2170 :   if (vars->size() != 2)
    1951              :     return false;
    1952              : 
    1953              :   // This is an index which is being assigned to two variables.  It
    1954              :   // must be a map index.  Declare the variables, and then assign the
    1955              :   // results of the map index.
    1956         2170 :   bool any_new = false;
    1957         2170 :   Typed_identifier_list::const_iterator p = vars->begin();
    1958         2170 :   Expression* init = type == NULL ? index : NULL;
    1959         2170 :   Named_object* val_no = this->init_var(*p, type, init, is_coloneq,
    1960              :                                         type == NULL, &any_new, NULL, NULL);
    1961         2170 :   if (type == NULL && any_new && val_no->is_variable())
    1962         1553 :     val_no->var_value()->set_type_from_init_tuple();
    1963         2170 :   Expression* val_var = Expression::make_var_reference(val_no, location);
    1964              : 
    1965         2170 :   ++p;
    1966         2170 :   Type* var_type = type;
    1967         2170 :   if (var_type == NULL)
    1968         2170 :     var_type = Type::lookup_bool_type();
    1969         2170 :   Named_object* no = this->init_var(*p, var_type, NULL, is_coloneq, false,
    1970              :                                     &any_new, NULL, NULL);
    1971         2170 :   Expression* present_var = Expression::make_var_reference(no, location);
    1972              : 
    1973         2170 :   if (is_coloneq && !any_new)
    1974            0 :     go_error_at(location, "variables redeclared but no variable is new");
    1975              : 
    1976         2170 :   Statement* s = Statement::make_tuple_map_assignment(val_var, present_var,
    1977              :                                                       index, location);
    1978              : 
    1979         2170 :   if (!this->gogo_->in_global_scope())
    1980         2167 :     this->gogo_->add_statement(s);
    1981            3 :   else if (!val_no->is_sink())
    1982              :     {
    1983            3 :       if (val_no->is_variable())
    1984              :         {
    1985            3 :           val_no->var_value()->add_preinit_statement(this->gogo_, s);
    1986            3 :           if (no->is_variable())
    1987            3 :             this->gogo_->record_var_depends_on(no->var_value(), val_no);
    1988              :         }
    1989              :     }
    1990            0 :   else if (!no->is_sink())
    1991              :     {
    1992            0 :       if (no->is_variable())
    1993            0 :         no->var_value()->add_preinit_statement(this->gogo_, s);
    1994              :     }
    1995              :   else
    1996              :     {
    1997              :       // Execute the map index expression just so that we can fail if
    1998              :       // the map is nil.
    1999            0 :       Named_object* dummy = this->create_dummy_global(Type::lookup_bool_type(),
    2000              :                                                       NULL, location);
    2001            0 :       dummy->var_value()->add_preinit_statement(this->gogo_, s);
    2002              :     }
    2003              : 
    2004              :   return true;
    2005              : }
    2006              : 
    2007              : // See if we need to initialize a pair of values from a receive
    2008              : // expression.  This returns true if we have set up the variables and
    2009              : // the initialization.
    2010              : 
    2011              : bool
    2012         6414 : Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
    2013              :                               Expression* expr, bool is_coloneq,
    2014              :                               Location location)
    2015              : {
    2016         6414 :   Receive_expression* receive = expr->receive_expression();
    2017           46 :   if (receive == NULL)
    2018              :     return false;
    2019           46 :   if (vars->size() != 2)
    2020              :     return false;
    2021              : 
    2022              :   // This is a receive expression which is being assigned to two
    2023              :   // variables.  Declare the variables, and then assign the results of
    2024              :   // the receive.
    2025           46 :   bool any_new = false;
    2026           46 :   Typed_identifier_list::const_iterator p = vars->begin();
    2027           46 :   Expression* init = type == NULL ? receive : NULL;
    2028           46 :   Named_object* val_no = this->init_var(*p, type, init, is_coloneq,
    2029              :                                         type == NULL, &any_new, NULL, NULL);
    2030           46 :   if (type == NULL && any_new && val_no->is_variable())
    2031           41 :     val_no->var_value()->set_type_from_init_tuple();
    2032           46 :   Expression* val_var = Expression::make_var_reference(val_no, location);
    2033              : 
    2034           46 :   ++p;
    2035           46 :   Type* var_type = type;
    2036           46 :   if (var_type == NULL)
    2037           46 :     var_type = Type::lookup_bool_type();
    2038           46 :   Named_object* no = this->init_var(*p, var_type, NULL, is_coloneq, false,
    2039              :                                     &any_new, NULL, NULL);
    2040           46 :   Expression* received_var = Expression::make_var_reference(no, location);
    2041              : 
    2042           46 :   if (is_coloneq && !any_new)
    2043            0 :     go_error_at(location, "variables redeclared but no variable is new");
    2044              : 
    2045           46 :   Statement* s = Statement::make_tuple_receive_assignment(val_var,
    2046              :                                                           received_var,
    2047              :                                                           receive->channel(),
    2048              :                                                           location);
    2049              : 
    2050           46 :   if (!this->gogo_->in_global_scope())
    2051           46 :     this->gogo_->add_statement(s);
    2052            0 :   else if (!val_no->is_sink())
    2053              :     {
    2054            0 :       if (val_no->is_variable())
    2055              :         {
    2056            0 :           val_no->var_value()->add_preinit_statement(this->gogo_, s);
    2057            0 :           if (no->is_variable())
    2058            0 :             this->gogo_->record_var_depends_on(no->var_value(), val_no);
    2059              :         }
    2060              :     }
    2061            0 :   else if (!no->is_sink())
    2062              :     {
    2063            0 :       if (no->is_variable())
    2064            0 :         no->var_value()->add_preinit_statement(this->gogo_, s);
    2065              :     }
    2066              :   else
    2067              :     {
    2068            0 :       Named_object* dummy = this->create_dummy_global(Type::lookup_bool_type(),
    2069              :                                                       NULL, location);
    2070            0 :       dummy->var_value()->add_preinit_statement(this->gogo_, s);
    2071              :     }
    2072              : 
    2073              :   return true;
    2074              : }
    2075              : 
    2076              : // See if we need to initialize a pair of values from a type guard
    2077              : // expression.  This returns true if we have set up the variables and
    2078              : // the initialization.
    2079              : 
    2080              : bool
    2081         6368 : Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
    2082              :                                  Type* type, Expression* expr,
    2083              :                                  bool is_coloneq, Location location)
    2084              : {
    2085         6368 :   Type_guard_expression* type_guard = expr->type_guard_expression();
    2086         6366 :   if (type_guard == NULL)
    2087              :     return false;
    2088         6366 :   if (vars->size() != 2)
    2089              :     return false;
    2090              : 
    2091              :   // This is a type guard expression which is being assigned to two
    2092              :   // variables.  Declare the variables, and then assign the results of
    2093              :   // the type guard.
    2094         6366 :   bool any_new = false;
    2095         6366 :   Typed_identifier_list::const_iterator p = vars->begin();
    2096         6366 :   Type* var_type = type;
    2097         6366 :   if (var_type == NULL)
    2098         6366 :     var_type = type_guard->type();
    2099         6366 :   Named_object* val_no = this->init_var(*p, var_type, NULL, is_coloneq, false,
    2100              :                                         &any_new, NULL, NULL);
    2101         6366 :   Expression* val_var = Expression::make_var_reference(val_no, location);
    2102              : 
    2103         6366 :   ++p;
    2104         6366 :   var_type = type;
    2105         6366 :   if (var_type == NULL)
    2106         6366 :     var_type = Type::lookup_bool_type();
    2107         6366 :   Named_object* no = this->init_var(*p, var_type, NULL, is_coloneq, false,
    2108              :                                     &any_new, NULL, NULL);
    2109         6366 :   Expression* ok_var = Expression::make_var_reference(no, location);
    2110              : 
    2111         6366 :   Expression* texpr = type_guard->expr();
    2112         6366 :   Type* t = type_guard->type();
    2113         6366 :   Statement* s = Statement::make_tuple_type_guard_assignment(val_var, ok_var,
    2114              :                                                              texpr, t,
    2115              :                                                              location);
    2116              : 
    2117         6366 :   if (is_coloneq && !any_new)
    2118            0 :     go_error_at(location, "variables redeclared but no variable is new");
    2119              : 
    2120         6366 :   if (!this->gogo_->in_global_scope())
    2121         6365 :     this->gogo_->add_statement(s);
    2122            1 :   else if (!val_no->is_sink())
    2123              :     {
    2124            1 :       if (val_no->is_variable())
    2125              :         {
    2126            1 :           val_no->var_value()->add_preinit_statement(this->gogo_, s);
    2127            1 :           if (no->is_variable())
    2128            1 :             this->gogo_->record_var_depends_on(no->var_value(), val_no);
    2129              :         }
    2130              :     }
    2131            0 :   else if (!no->is_sink())
    2132              :     {
    2133            0 :       if (no->is_variable())
    2134            0 :         no->var_value()->add_preinit_statement(this->gogo_, s);
    2135              :     }
    2136              :   else
    2137              :     {
    2138            0 :       Named_object* dummy = this->create_dummy_global(type, NULL, location);
    2139            0 :       dummy->var_value()->add_preinit_statement(this->gogo_, s);
    2140              :     }
    2141              : 
    2142              :   return true;
    2143              : }
    2144              : 
    2145              : // Create a single variable.  If IS_COLONEQ is true, we permit
    2146              : // redeclarations in the same block, and we set *IS_NEW when we find a
    2147              : // new variable which is not a redeclaration.
    2148              : 
    2149              : Named_object*
    2150       420439 : Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
    2151              :                 bool is_coloneq, bool type_from_init, bool* is_new,
    2152              :                 Expression_list* vars, Expression_list* vals)
    2153              : {
    2154       420439 :   Location location = tid.location();
    2155              : 
    2156       420439 :   if (Gogo::is_sink_name(tid.name()))
    2157              :     {
    2158        30881 :       if (!type_from_init && init != NULL)
    2159              :         {
    2160        11580 :           if (this->gogo_->in_global_scope())
    2161         1114 :             return this->create_dummy_global(type, init, location);
    2162              :           else
    2163              :             {
    2164              :               // Create a dummy variable so that we will check whether the
    2165              :               // initializer can be assigned to the type.
    2166        10466 :               Variable* var = new Variable(type, init, false, false, false,
    2167        10466 :                                            location);
    2168        10466 :               var->set_is_used();
    2169        10466 :               static int count;
    2170        10466 :               char buf[30];
    2171        10466 :               snprintf(buf, sizeof buf, "sink$%d", count);
    2172        10466 :               ++count;
    2173        10466 :               return this->gogo_->add_variable(buf, var);
    2174              :             }
    2175              :         }
    2176        19301 :       if (type != NULL)
    2177         2352 :         this->gogo_->add_type_to_verify(type);
    2178        19301 :       return this->gogo_->add_sink();
    2179              :     }
    2180              : 
    2181       389558 :   if (is_coloneq)
    2182              :     {
    2183       306705 :       Named_object* no = this->gogo_->lookup_in_block(tid.name());
    2184       306705 :       if (no != NULL
    2185       306705 :           && (no->is_variable() || no->is_result_variable()))
    2186              :         {
    2187              :           // INIT may be NULL even when IS_COLONEQ is true for cases
    2188              :           // like v, ok := x.(int).
    2189         5666 :           if (!type_from_init && init != NULL)
    2190              :             {
    2191         5497 :               go_assert(vars != NULL && vals != NULL);
    2192         5497 :               vars->push_back(Expression::make_var_reference(no, location));
    2193         5497 :               vals->push_back(init);
    2194              :             }
    2195         5666 :           return no;
    2196              :         }
    2197              :     }
    2198       383892 :   *is_new = true;
    2199       383892 :   Variable* var = new Variable(type, init, this->gogo_->in_global_scope(),
    2200       767784 :                                false, false, location);
    2201       383892 :   Named_object* no = this->gogo_->add_variable(tid.name(), var);
    2202       383892 :   if (!no->is_variable())
    2203              :     {
    2204              :       // The name is already defined, so we just gave an error.
    2205            2 :       return this->gogo_->add_sink();
    2206              :     }
    2207              :   return no;
    2208              : }
    2209              : 
    2210              : // Create a dummy global variable to force an initializer to be run in
    2211              : // the right place.  This is used when a sink variable is initialized
    2212              : // at global scope.
    2213              : 
    2214              : Named_object*
    2215         1114 : Parse::create_dummy_global(Type* type, Expression* init,
    2216              :                            Location location)
    2217              : {
    2218         1114 :   if (type == NULL && init == NULL)
    2219            0 :     type = Type::lookup_bool_type();
    2220         1114 :   Variable* var = new Variable(type, init, true, false, false, location);
    2221         1114 :   var->set_is_global_sink();
    2222         1114 :   static int count;
    2223         1114 :   char buf[30];
    2224         1114 :   snprintf(buf, sizeof buf, "_.%d", count);
    2225         1114 :   ++count;
    2226         1114 :   return this->gogo_->add_variable(buf, var);
    2227              : }
    2228              : 
    2229              : // Finish the variable initialization by executing any assignments to
    2230              : // existing variables when using :=.  These must be done as a tuple
    2231              : // assignment in case of something like n, a, b := 1, b, a.
    2232              : 
    2233              : void
    2234       301290 : Parse::finish_init_vars(Expression_list* vars, Expression_list* vals,
    2235              :                         Location location)
    2236              : {
    2237       301290 :   if (vars->empty())
    2238              :     {
    2239       295967 :       delete vars;
    2240       591934 :       delete vals;
    2241              :     }
    2242         5323 :   else if (vars->size() == 1)
    2243              :     {
    2244         5168 :       go_assert(!this->gogo_->in_global_scope());
    2245         5168 :       this->gogo_->add_statement(Statement::make_assignment(vars->front(),
    2246         5168 :                                                             vals->front(),
    2247              :                                                             location));
    2248         5168 :       delete vars;
    2249         5168 :       delete vals;
    2250              :     }
    2251              :   else
    2252              :     {
    2253          155 :       go_assert(!this->gogo_->in_global_scope());
    2254          155 :       this->gogo_->add_statement(Statement::make_tuple_assignment(vars, vals,
    2255              :                                                                   location));
    2256              :     }
    2257       301290 : }
    2258              : 
    2259              : // SimpleVarDecl = identifier ":=" Expression .
    2260              : 
    2261              : // We've already seen the identifier.
    2262              : 
    2263              : // FIXME: We also have to implement
    2264              : //  IdentifierList ":=" ExpressionList
    2265              : // In order to support both "a, b := 1, 0" and "a, b = 1, 0" we accept
    2266              : // tuple assignments here as well.
    2267              : 
    2268              : // If MAY_BE_COMPOSITE_LIT is true, the expression on the right hand
    2269              : // side may be a composite literal.
    2270              : 
    2271              : // If P_RANGE_CLAUSE is not NULL, then this will recognize a
    2272              : // RangeClause.
    2273              : 
    2274              : // If P_TYPE_SWITCH is not NULL, this will recognize a type switch
    2275              : // guard (var := expr.("type") using the literal keyword "type").
    2276              : 
    2277              : void
    2278       281931 : Parse::simple_var_decl_or_assignment(const std::string& name,
    2279              :                                      Location location,
    2280              :                                      bool may_be_composite_lit,
    2281              :                                      Range_clause* p_range_clause,
    2282              :                                      Type_switch* p_type_switch)
    2283              : {
    2284       281931 :   Typed_identifier_list til;
    2285       563862 :   til.push_back(Typed_identifier(name, NULL, location));
    2286              : 
    2287       281931 :   std::set<std::string> uniq_idents;
    2288       281931 :   uniq_idents.insert(name);
    2289       281931 :   std::string dup_name;
    2290       281931 :   Location dup_loc;
    2291              : 
    2292              :   // We've seen one identifier.  If we see a comma now, this could be
    2293              :   // "a, *p = 1, 2".
    2294       281931 :   if (this->peek_token()->is_op(OPERATOR_COMMA))
    2295              :     {
    2296        97533 :       go_assert(p_type_switch == NULL);
    2297       121147 :       while (true)
    2298              :         {
    2299       109340 :           const Token* token = this->advance_token();
    2300       109340 :           if (!token->is_identifier())
    2301              :             break;
    2302              : 
    2303       109340 :           std::string id = token->identifier();
    2304       109340 :           bool is_id_exported = token->is_identifier_exported();
    2305       109340 :           Location id_location = token->location();
    2306       109340 :           std::pair<std::set<std::string>::iterator, bool> ins;
    2307              : 
    2308       109340 :           token = this->advance_token();
    2309       109340 :           if (!token->is_op(OPERATOR_COMMA))
    2310              :             {
    2311        97533 :               if (token->is_op(OPERATOR_COLONEQ))
    2312              :                 {
    2313        72487 :                   id = this->gogo_->pack_hidden_name(id, is_id_exported);
    2314        72487 :                   ins = uniq_idents.insert(id);
    2315        72487 :                   if (!ins.second && !Gogo::is_sink_name(id))
    2316              :                     {
    2317              :                       // Use %s to print := to avoid -Wformat-diag warning.
    2318            4 :                       go_error_at(id_location,
    2319              :                                   "%qs repeated on left side of %s",
    2320            4 :                                   Gogo::message_name(id).c_str(), ":=");
    2321            4 :                       id = this->gogo_->pack_hidden_name("_", false);
    2322              :                     }
    2323       144974 :                   til.push_back(Typed_identifier(id, NULL, location));
    2324              :                 }
    2325              :               else
    2326        25046 :                 this->unget_token(Token::make_identifier_token(id,
    2327              :                                                                is_id_exported,
    2328              :                                                                id_location));
    2329        97533 :               break;
    2330              :             }
    2331              : 
    2332        11807 :           id = this->gogo_->pack_hidden_name(id, is_id_exported);
    2333        11807 :           ins = uniq_idents.insert(id);
    2334        11807 :           std::string name = id;
    2335        11807 :           if (!ins.second && !Gogo::is_sink_name(id))
    2336              :             {
    2337           37 :               dup_name = Gogo::message_name(id);
    2338           37 :               dup_loc = id_location;
    2339           37 :               id = this->gogo_->pack_hidden_name("_", false);
    2340              :             }
    2341        23614 :           til.push_back(Typed_identifier(id, NULL, location));
    2342       109340 :         }
    2343              : 
    2344              :       // We have a comma separated list of identifiers in TIL.  If the
    2345              :       // next token is COLONEQ, then this is a simple var decl, and we
    2346              :       // have the complete list of identifiers.  If the next token is
    2347              :       // not COLONEQ, then the only valid parse is a tuple assignment.
    2348              :       // The list of identifiers we have so far is really a list of
    2349              :       // expressions.  There are more expressions following.
    2350              : 
    2351        97533 :       if (!this->peek_token()->is_op(OPERATOR_COLONEQ))
    2352              :         {
    2353        25046 :           Expression_list* exprs = new Expression_list;
    2354        25046 :           for (Typed_identifier_list::const_iterator p = til.begin();
    2355        52930 :                p != til.end();
    2356        27884 :                ++p)
    2357        27884 :             exprs->push_back(this->id_to_expression(p->name(), p->location(),
    2358              :                                                     true, false));
    2359              : 
    2360        25046 :           Expression_list* more_exprs =
    2361        25046 :             this->expression_list(NULL, true, may_be_composite_lit);
    2362        25046 :           for (Expression_list::const_iterator p = more_exprs->begin();
    2363        50150 :                p != more_exprs->end();
    2364        25104 :                ++p)
    2365        25104 :             exprs->push_back(*p);
    2366        25046 :           delete more_exprs;
    2367              : 
    2368        25046 :           this->tuple_assignment(exprs, may_be_composite_lit, p_range_clause);
    2369        25046 :           return;
    2370              :         }
    2371              :     }
    2372              : 
    2373       256885 :   go_assert(this->peek_token()->is_op(OPERATOR_COLONEQ));
    2374       256885 :   const Token* token = this->advance_token();
    2375              : 
    2376       256885 :   if (!dup_name.empty())
    2377              :     {
    2378              :       // Use %s to print := to avoid -Wformat-diag warning.
    2379            0 :       go_error_at(dup_loc, "%qs repeated on left side of %s",
    2380              :                   dup_name.c_str(), ":=");
    2381              :     }
    2382              : 
    2383       256885 :   if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
    2384              :     {
    2385        25548 :       this->range_clause_decl(&til, p_range_clause);
    2386        25548 :       return;
    2387              :     }
    2388              : 
    2389       231337 :   Expression_list* init;
    2390       231337 :   if (p_type_switch == NULL)
    2391       228697 :     init = this->expression_list(NULL, false, may_be_composite_lit);
    2392              :   else
    2393              :     {
    2394         2640 :       bool is_type_switch = false;
    2395         2640 :       Expression* expr = this->expression(PRECEDENCE_NORMAL, false,
    2396              :                                           may_be_composite_lit,
    2397              :                                           &is_type_switch, NULL);
    2398         2640 :       if (is_type_switch)
    2399              :         {
    2400         2013 :           p_type_switch->found = true;
    2401         2013 :           p_type_switch->name = name;
    2402         2013 :           p_type_switch->location = location;
    2403         2013 :           p_type_switch->expr = expr;
    2404         2013 :           return;
    2405              :         }
    2406              : 
    2407          627 :       if (!this->peek_token()->is_op(OPERATOR_COMMA))
    2408              :         {
    2409          627 :           init = new Expression_list();
    2410          627 :           init->push_back(expr);
    2411              :         }
    2412              :       else
    2413              :         {
    2414            0 :           this->advance_token();
    2415            0 :           init = this->expression_list(expr, false, may_be_composite_lit);
    2416              :         }
    2417              :     }
    2418              : 
    2419       229324 :   this->init_vars(&til, NULL, init, true, NULL, location);
    2420       281931 : }
    2421              : 
    2422              : // FunctionDecl = "func" identifier Signature [ Block ] .
    2423              : // MethodDecl = "func" Receiver identifier Signature [ Block ] .
    2424              : 
    2425              : // Deprecated gcc extension:
    2426              : //   FunctionDecl = "func" identifier Signature
    2427              : //                    __asm__ "(" string_lit ")" .
    2428              : // This extension means a function whose real name is the identifier
    2429              : // inside the asm.  This extension will be removed at some future
    2430              : // date.  It has been replaced with //extern or //go:linkname comments.
    2431              : //
    2432              : // PRAGMAS is a bitset of magic comments.
    2433              : 
    2434              : void
    2435       128964 : Parse::function_decl()
    2436              : {
    2437       128964 :   go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC));
    2438              : 
    2439       128964 :   unsigned int pragmas = this->lex_->get_and_clear_pragmas();
    2440       128964 :   this->check_directives();
    2441              : 
    2442       128964 :   Location location = this->location();
    2443       128964 :   std::string extern_name = this->lex_->extern_name();
    2444       128964 :   const Token* token = this->advance_token();
    2445              : 
    2446       128964 :   bool expected_receiver = false;
    2447       128964 :   Typed_identifier* rec = NULL;
    2448       128964 :   if (token->is_op(OPERATOR_LPAREN))
    2449              :     {
    2450        53261 :       expected_receiver = true;
    2451        53261 :       rec = this->receiver();
    2452        53261 :       token = this->peek_token();
    2453              :     }
    2454              : 
    2455       128964 :   if (!token->is_identifier())
    2456              :     {
    2457            0 :       go_error_at(this->location(), "expected function name");
    2458            0 :       return;
    2459              :     }
    2460              : 
    2461       128964 :   std::string name =
    2462       128964 :     this->gogo_->pack_hidden_name(token->identifier(),
    2463       128964 :                                   token->is_identifier_exported());
    2464              : 
    2465       128964 :   this->advance_token();
    2466              : 
    2467       128964 :   Function_type* fntype = this->signature(rec, this->location());
    2468              : 
    2469       128964 :   Named_object* named_object = NULL;
    2470              : 
    2471       128964 :   if (this->peek_token()->is_keyword(KEYWORD_ASM))
    2472              :     {
    2473            0 :       if (!this->advance_token()->is_op(OPERATOR_LPAREN))
    2474              :         {
    2475            0 :           go_error_at(this->location(), "expected %<(%>");
    2476            0 :           return;
    2477              :         }
    2478            0 :       token = this->advance_token();
    2479            0 :       if (!token->is_string())
    2480              :         {
    2481            0 :           go_error_at(this->location(), "expected string");
    2482            0 :           return;
    2483              :         }
    2484            0 :       std::string asm_name = token->string_value();
    2485            0 :       if (!this->advance_token()->is_op(OPERATOR_RPAREN))
    2486              :         {
    2487            0 :           go_error_at(this->location(), "expected %<)%>");
    2488            0 :           return;
    2489              :         }
    2490            0 :       this->advance_token();
    2491            0 :       if (!Gogo::is_sink_name(name))
    2492              :         {
    2493            0 :           named_object = this->gogo_->declare_function(name, fntype, location);
    2494            0 :           if (named_object->is_function_declaration())
    2495            0 :             named_object->func_declaration_value()->set_asm_name(asm_name);
    2496              :         }
    2497            0 :     }
    2498              : 
    2499              :   // Check for the easy error of a newline before the opening brace.
    2500       128964 :   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    2501              :     {
    2502         3854 :       Location semi_loc = this->location();
    2503         3854 :       if (this->advance_token()->is_op(OPERATOR_LCURLY))
    2504            1 :         go_error_at(this->location(),
    2505              :                     "unexpected semicolon or newline before %<{%>");
    2506              :       else
    2507         3853 :         this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
    2508              :                                                      semi_loc));
    2509              :     }
    2510              : 
    2511       128964 :   static struct {
    2512              :     unsigned int bit;
    2513              :     const char* name;
    2514              :     bool decl_ok;
    2515              :     bool func_ok;
    2516              :     bool method_ok;
    2517              :   } pragma_check[] =
    2518              :       {
    2519              :         { GOPRAGMA_NOINTERFACE, "nointerface", false, false, true },
    2520              :         { GOPRAGMA_NOESCAPE, "noescape", true, false, false },
    2521              :         { GOPRAGMA_NORACE, "norace", false, true, true },
    2522              :         { GOPRAGMA_NOSPLIT, "nosplit", false, true, true },
    2523              :         { GOPRAGMA_NOINLINE, "noinline", false, true, true },
    2524              :         { GOPRAGMA_SYSTEMSTACK, "systemstack", false, true, true },
    2525              :         { GOPRAGMA_NOWRITEBARRIER, "nowritebarrier", false, true, true },
    2526              :         { GOPRAGMA_NOWRITEBARRIERREC, "nowritebarrierrec", false, true,
    2527              :           true },
    2528              :         { GOPRAGMA_YESWRITEBARRIERREC, "yeswritebarrierrec", false, true,
    2529              :           true },
    2530              :         { GOPRAGMA_CGOUNSAFEARGS, "cgo_unsafe_args", false, true, true },
    2531              :         { GOPRAGMA_UINTPTRESCAPES, "uintptrescapes", true, true, true },
    2532              :       };
    2533              : 
    2534       128964 :   bool is_decl = !this->peek_token()->is_op(OPERATOR_LCURLY);
    2535       128964 :   if (pragmas != 0)
    2536              :     {
    2537        44242 :       for (size_t i = 0;
    2538        48264 :            i < sizeof(pragma_check) / sizeof(pragma_check[0]);
    2539              :            ++i)
    2540              :         {
    2541        44242 :           if ((pragmas & pragma_check[i].bit) == 0)
    2542        39830 :             continue;
    2543              : 
    2544         4412 :           if (is_decl)
    2545              :             {
    2546         1608 :               if (pragma_check[i].decl_ok)
    2547         1608 :                 continue;
    2548            0 :               go_warning_at(location, 0,
    2549              :                             ("ignoring magic %<//go:%s%> comment "
    2550              :                              "before declaration"),
    2551              :                             pragma_check[i].name);
    2552              :             }
    2553         2804 :           else if (rec == NULL)
    2554              :             {
    2555         2199 :               if (pragma_check[i].func_ok)
    2556         2199 :                 continue;
    2557            0 :               go_warning_at(location, 0,
    2558              :                             ("ignoring magic %<//go:%s%> comment "
    2559              :                              "before function definition"),
    2560              :                             pragma_check[i].name);
    2561              :             }
    2562              :           else
    2563              :             {
    2564          605 :               if (pragma_check[i].method_ok)
    2565          605 :                 continue;
    2566            0 :               go_warning_at(location, 0,
    2567              :                             ("ignoring magic %<//go:%s%> comment "
    2568              :                              "before method definition"),
    2569              :                             pragma_check[i].name);
    2570              :             }
    2571              : 
    2572            0 :           pragmas &= ~ pragma_check[i].bit;
    2573              :         }
    2574              :     }
    2575              : 
    2576       128964 :   if (is_decl)
    2577              :     {
    2578         3853 :       if (named_object == NULL)
    2579              :         {
    2580              :           // Function declarations with the blank identifier as a name are
    2581              :           // mostly ignored since they cannot be called.  We make an object
    2582              :           // for this declaration for type-checking purposes.
    2583         3853 :           if (Gogo::is_sink_name(name))
    2584              :             {
    2585            2 :               static int count;
    2586            2 :               char buf[30];
    2587            2 :               snprintf(buf, sizeof buf, ".$sinkfndecl%d", count);
    2588            2 :               ++count;
    2589            2 :               name = std::string(buf);
    2590              :             }
    2591              : 
    2592         3853 :           if (fntype == NULL
    2593         3846 :               || (expected_receiver && rec == NULL))
    2594           10 :             this->gogo_->add_erroneous_name(name);
    2595              :           else
    2596              :             {
    2597         3843 :               named_object = this->gogo_->declare_function(name, fntype,
    2598              :                                                            location);
    2599         3843 :               if (!extern_name.empty()
    2600         3843 :                   && named_object->is_function_declaration())
    2601              :                 {
    2602          613 :                   Function_declaration* fd =
    2603          613 :                     named_object->func_declaration_value();
    2604          613 :                   fd->set_asm_name(extern_name);
    2605              :                 }
    2606              :             }
    2607              :         }
    2608              : 
    2609         3853 :       if (pragmas != 0 && named_object->is_function_declaration())
    2610         1608 :         named_object->func_declaration_value()->set_pragmas(pragmas);
    2611              :     }
    2612              :   else
    2613              :     {
    2614       125111 :       bool hold_is_erroneous_function = this->is_erroneous_function_;
    2615       125111 :       if (fntype == NULL)
    2616              :         {
    2617            4 :           fntype = Type::make_function_type(NULL, NULL, NULL, location);
    2618            4 :           this->is_erroneous_function_ = true;
    2619            4 :           if (!Gogo::is_sink_name(name))
    2620            4 :             this->gogo_->add_erroneous_name(name);
    2621            4 :           name = this->gogo_->pack_hidden_name("_", false);
    2622              :         }
    2623       125111 :       named_object = this->gogo_->start_function(name, fntype, true, location);
    2624       125111 :       Location end_loc = this->block();
    2625       125111 :       this->gogo_->finish_function(end_loc);
    2626              : 
    2627       125111 :       if (pragmas != 0
    2628         2414 :           && !this->is_erroneous_function_
    2629       127525 :           && named_object->is_function())
    2630         2414 :         named_object->func_value()->set_pragmas(pragmas);
    2631       125111 :       this->is_erroneous_function_ = hold_is_erroneous_function;
    2632              :     }
    2633       128964 : }
    2634              : 
    2635              : // Receiver = Parameters .
    2636              : 
    2637              : Typed_identifier*
    2638        53261 : Parse::receiver()
    2639              : {
    2640        53261 :   Location location = this->location();
    2641        53261 :   Typed_identifier_list* til;
    2642        53261 :   if (!this->parameters(&til, NULL))
    2643              :     return NULL;
    2644        53260 :   else if (til == NULL || til->empty())
    2645              :     {
    2646            1 :       go_error_at(location, "method has no receiver");
    2647            1 :       return NULL;
    2648              :     }
    2649        53259 :   else if (til->size() > 1)
    2650              :     {
    2651            1 :       go_error_at(location, "method has multiple receivers");
    2652            1 :       return NULL;
    2653              :     }
    2654              :   else
    2655              :     return &til->front();
    2656              : }
    2657              : 
    2658              : // Operand    = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" .
    2659              : // Literal    = BasicLit | CompositeLit | FunctionLit .
    2660              : // BasicLit   = int_lit | float_lit | imaginary_lit | char_lit | string_lit .
    2661              : 
    2662              : // If MAY_BE_SINK is true, this operand may be "_".
    2663              : 
    2664              : // If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
    2665              : // if the entire expression is in parentheses.
    2666              : 
    2667              : Expression*
    2668      4924366 : Parse::operand(bool may_be_sink, bool* is_parenthesized)
    2669              : {
    2670      4924366 :   const Token* token = this->peek_token();
    2671      4924366 :   Expression* ret;
    2672      4924366 :   switch (token->classification())
    2673              :     {
    2674      3045393 :     case Token::TOKEN_IDENTIFIER:
    2675      3045393 :       {
    2676      3045393 :         Location location = token->location();
    2677      3045393 :         std::string id = token->identifier();
    2678      3045393 :         bool is_exported = token->is_identifier_exported();
    2679      3045393 :         std::string packed = this->gogo_->pack_hidden_name(id, is_exported);
    2680              : 
    2681      3045393 :         Named_object* in_function;
    2682      3045393 :         Named_object* named_object = this->gogo_->lookup(packed, &in_function);
    2683              : 
    2684      3045393 :         Package* package = NULL;
    2685      3045393 :         if (named_object != NULL && named_object->is_package())
    2686              :           {
    2687       214174 :             if (!this->advance_token()->is_op(OPERATOR_DOT)
    2688       214172 :                 || !this->advance_token()->is_identifier())
    2689              :               {
    2690            2 :                 go_error_at(location, "unexpected reference to package");
    2691            2 :                 return Expression::make_error(location);
    2692              :               }
    2693       214172 :             package = named_object->package_value();
    2694       214172 :             package->note_usage(id);
    2695       214172 :             id = this->peek_token()->identifier();
    2696       214172 :             is_exported = this->peek_token()->is_identifier_exported();
    2697       214172 :             packed = this->gogo_->pack_hidden_name(id, is_exported);
    2698       214172 :             named_object = package->lookup(packed);
    2699       214172 :             location = this->location();
    2700       214172 :             go_assert(in_function == NULL);
    2701              :           }
    2702              : 
    2703      3045391 :         this->advance_token();
    2704              : 
    2705      3045391 :         if (named_object != NULL
    2706      2980653 :             && named_object->is_type()
    2707      3115776 :             && !named_object->type_value()->is_visible())
    2708              :           {
    2709            0 :             go_assert(package != NULL);
    2710            0 :             go_error_at(location, "invalid reference to hidden type %<%s.%s%>",
    2711            0 :                         Gogo::message_name(package->package_name()).c_str(),
    2712            0 :                         Gogo::message_name(id).c_str());
    2713            0 :             return Expression::make_error(location);
    2714              :           }
    2715              : 
    2716              : 
    2717      3045391 :         if (named_object == NULL)
    2718              :           {
    2719        64738 :             if (package != NULL)
    2720              :               {
    2721           12 :                 std::string n1 = Gogo::message_name(package->package_name());
    2722           12 :                 std::string n2 = Gogo::message_name(id);
    2723           12 :                 if (!is_exported)
    2724            2 :                   go_error_at(location,
    2725              :                               ("invalid reference to unexported identifier "
    2726              :                                "%<%s.%s%>"),
    2727              :                               n1.c_str(), n2.c_str());
    2728              :                 else
    2729           10 :                   go_error_at(location,
    2730              :                               "reference to undefined identifier %<%s.%s%>",
    2731              :                               n1.c_str(), n2.c_str());
    2732           12 :                 return Expression::make_error(location);
    2733           12 :               }
    2734              : 
    2735        64726 :             named_object = this->gogo_->add_unknown_name(packed, location);
    2736              :           }
    2737              : 
    2738      3045379 :         if (in_function != NULL
    2739      1830525 :             && in_function != this->gogo_->current_function()
    2740      3087696 :             && (named_object->is_variable()
    2741         2613 :                 || named_object->is_result_variable()))
    2742        41190 :           return this->enclosing_var_reference(in_function, named_object,
    2743        41190 :                                                may_be_sink, location);
    2744              : 
    2745      3004189 :         switch (named_object->classification())
    2746              :           {
    2747       166194 :           case Named_object::NAMED_OBJECT_CONST:
    2748       166194 :             return Expression::make_const_reference(named_object, location);
    2749        70385 :           case Named_object::NAMED_OBJECT_TYPE:
    2750        70385 :             return Expression::make_type(named_object->type_value(), location);
    2751         1085 :           case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
    2752         1085 :             {
    2753         1085 :               Type* t = Type::make_forward_declaration(named_object);
    2754         1085 :               return Expression::make_type(t, location);
    2755              :             }
    2756      1918937 :           case Named_object::NAMED_OBJECT_VAR:
    2757      1918937 :           case Named_object::NAMED_OBJECT_RESULT_VAR:
    2758              :             // Any left-hand-side can be a sink, so if this can not be
    2759              :             // a sink, then it must be a use of the variable.
    2760      1918937 :             if (!may_be_sink)
    2761      1375308 :               this->mark_var_used(named_object);
    2762      1918937 :             return Expression::make_var_reference(named_object, location);
    2763         5131 :           case Named_object::NAMED_OBJECT_SINK:
    2764         5131 :             if (may_be_sink)
    2765         5116 :               return Expression::make_sink(location);
    2766              :             else
    2767              :               {
    2768           15 :                 go_error_at(location, "cannot use %<_%> as value");
    2769           15 :                 return Expression::make_error(location);
    2770              :               }
    2771       256080 :           case Named_object::NAMED_OBJECT_FUNC:
    2772       256080 :           case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
    2773       256080 :             return Expression::make_func_reference(named_object, NULL,
    2774       256080 :                                                    location);
    2775       586376 :           case Named_object::NAMED_OBJECT_UNKNOWN:
    2776       586376 :             {
    2777       586376 :               Unknown_expression* ue =
    2778       586376 :                 Expression::make_unknown_reference(named_object, location);
    2779       586376 :               if (this->is_erroneous_function_)
    2780            2 :                 ue->set_no_error_message();
    2781              :               return ue;
    2782              :             }
    2783            1 :           case Named_object::NAMED_OBJECT_ERRONEOUS:
    2784            1 :             return Expression::make_error(location);
    2785            0 :           default:
    2786            0 :             go_unreachable();
    2787              :           }
    2788      3045393 :       }
    2789              :       go_unreachable();
    2790              : 
    2791       418373 :     case Token::TOKEN_STRING:
    2792       418373 :       ret = Expression::make_string(token->string_value(), token->location());
    2793       418373 :       this->advance_token();
    2794       418373 :       return ret;
    2795              : 
    2796        49035 :     case Token::TOKEN_CHARACTER:
    2797        49035 :       ret = Expression::make_character(token->character_value(), NULL,
    2798              :                                        token->location());
    2799        49035 :       this->advance_token();
    2800        49035 :       return ret;
    2801              : 
    2802      1261659 :     case Token::TOKEN_INTEGER:
    2803      1261659 :       ret = Expression::make_integer_z(token->integer_value(), NULL,
    2804              :                                        token->location());
    2805      1261659 :       this->advance_token();
    2806      1261659 :       return ret;
    2807              : 
    2808        18712 :     case Token::TOKEN_FLOAT:
    2809        18712 :       ret = Expression::make_float(token->float_value(), NULL,
    2810              :                                    token->location());
    2811        18712 :       this->advance_token();
    2812        18712 :       return ret;
    2813              : 
    2814          992 :     case Token::TOKEN_IMAGINARY:
    2815          992 :       {
    2816          992 :         mpfr_t zero;
    2817          992 :         mpfr_init_set_ui(zero, 0, MPFR_RNDN);
    2818          992 :         mpc_t val;
    2819          992 :         mpc_init2(val, mpc_precision);
    2820          992 :         mpc_set_fr_fr(val, zero, *token->imaginary_value(), MPC_RNDNN);
    2821          992 :         mpfr_clear(zero);
    2822          992 :         ret = Expression::make_complex(&val, NULL, token->location());
    2823          992 :         mpc_clear(val);
    2824          992 :         this->advance_token();
    2825          992 :         return ret;
    2826              :       }
    2827              : 
    2828        36143 :     case Token::TOKEN_KEYWORD:
    2829        36143 :       switch (token->keyword())
    2830              :         {
    2831        25692 :         case KEYWORD_FUNC:
    2832        25692 :           return this->function_lit();
    2833        10451 :         case KEYWORD_CHAN:
    2834        10451 :         case KEYWORD_INTERFACE:
    2835        10451 :         case KEYWORD_MAP:
    2836        10451 :         case KEYWORD_STRUCT:
    2837        10451 :           {
    2838        10451 :             Location location = token->location();
    2839        10451 :             return Expression::make_type(this->type(), location);
    2840              :           }
    2841              :         default:
    2842              :           break;
    2843              :         }
    2844              :       break;
    2845              : 
    2846        94059 :     case Token::TOKEN_OPERATOR:
    2847        94059 :       if (token->is_op(OPERATOR_LPAREN))
    2848              :         {
    2849        45202 :           this->advance_token();
    2850        45202 :           ret = this->expression(PRECEDENCE_NORMAL, may_be_sink, true, NULL,
    2851              :                                  NULL);
    2852        45202 :           if (!this->peek_token()->is_op(OPERATOR_RPAREN))
    2853            0 :             go_error_at(this->location(), "missing %<)%>");
    2854              :           else
    2855        45202 :             this->advance_token();
    2856        45202 :           if (is_parenthesized != NULL)
    2857        45202 :             *is_parenthesized = true;
    2858        45202 :           return ret;
    2859              :         }
    2860        48857 :       else if (token->is_op(OPERATOR_LSQUARE))
    2861              :         {
    2862              :           // Here we call array_type directly, as this is the only
    2863              :           // case where an ellipsis is permitted for an array type.
    2864        48849 :           Location location = token->location();
    2865        48849 :           return Expression::make_type(this->array_type(true), location);
    2866              :         }
    2867              :       break;
    2868              : 
    2869              :     default:
    2870              :       break;
    2871              :     }
    2872              : 
    2873            8 :   go_error_at(this->location(), "expected operand");
    2874            8 :   return Expression::make_error(this->location());
    2875              : }
    2876              : 
    2877              : // Handle a reference to a variable in an enclosing function.  We add
    2878              : // it to a list of such variables.  We return a reference to a field
    2879              : // in a struct which will be passed on the static chain when calling
    2880              : // the current function.
    2881              : 
    2882              : Expression*
    2883        43132 : Parse::enclosing_var_reference(Named_object* in_function, Named_object* var,
    2884              :                                bool may_be_sink, Location location)
    2885              : {
    2886        43132 :   go_assert(var->is_variable() || var->is_result_variable());
    2887              : 
    2888              :   // Any left-hand-side can be a sink, so if this can not be
    2889              :   // a sink, then it must be a use of the variable.
    2890        43132 :   if (!may_be_sink)
    2891        25799 :     this->mark_var_used(var);
    2892              : 
    2893        43132 :   Named_object* this_function = this->gogo_->current_function();
    2894        43132 :   Named_object* closure = this_function->func_value()->closure_var();
    2895              : 
    2896              :   // The last argument to the Enclosing_var constructor is the index
    2897              :   // of this variable in the closure.  We add 1 to the current number
    2898              :   // of enclosed variables, because the first field in the closure
    2899              :   // points to the function code.
    2900        43132 :   Enclosing_var ev(var, in_function, this->enclosing_vars_.size() + 1);
    2901        43132 :   std::pair<Enclosing_vars::iterator, bool> ins =
    2902        43132 :     this->enclosing_vars_.insert(ev);
    2903        43132 :   if (ins.second)
    2904              :     {
    2905              :       // This is a variable we have not seen before.  Add a new field
    2906              :       // to the closure type.
    2907        25473 :       this_function->func_value()->add_closure_field(var, location);
    2908              :     }
    2909              : 
    2910        43132 :   Expression* closure_ref = Expression::make_var_reference(closure,
    2911              :                                                            location);
    2912        43132 :   closure_ref =
    2913        43132 :       Expression::make_dereference(closure_ref,
    2914              :                                    Expression::NIL_CHECK_NOT_NEEDED,
    2915              :                                    location);
    2916              : 
    2917              :   // The closure structure holds pointers to the variables, so we need
    2918              :   // to introduce an indirection.
    2919        43132 :   Expression* e = Expression::make_field_reference(closure_ref,
    2920              :                                                    ins.first->index(),
    2921              :                                                    location);
    2922        43132 :   e = Expression::make_dereference(e, Expression::NIL_CHECK_NOT_NEEDED,
    2923              :                                    location);
    2924        43132 :   return Expression::make_enclosing_var_reference(e, var, location);
    2925              : }
    2926              : 
    2927              : // CompositeLit  = LiteralType LiteralValue .
    2928              : // LiteralType   = StructType | ArrayType | "[" "..." "]" ElementType |
    2929              : //                 SliceType | MapType | TypeName .
    2930              : // LiteralValue  = "{" [ ElementList [ "," ] ] "}" .
    2931              : // ElementList   = Element { "," Element } .
    2932              : // Element       = [ Key ":" ] Value .
    2933              : // Key           = FieldName | ElementIndex .
    2934              : // FieldName     = identifier .
    2935              : // ElementIndex  = Expression .
    2936              : // Value         = Expression | LiteralValue .
    2937              : 
    2938              : // We have already seen the type if there is one, and we are now
    2939              : // looking at the LiteralValue.  The case "[" "..."  "]" ElementType
    2940              : // will be seen here as an array type whose length is "nil".  The
    2941              : // DEPTH parameter is non-zero if this is an embedded composite
    2942              : // literal and the type was omitted.  It gives the number of steps up
    2943              : // to the type which was provided.  E.g., in [][]int{{1}} it will be
    2944              : // 1.  In [][][]int{{{1}}} it will be 2.
    2945              : 
    2946              : Expression*
    2947       226855 : Parse::composite_lit(Type* type, int depth, Location location)
    2948              : {
    2949       226855 :   go_assert(this->peek_token()->is_op(OPERATOR_LCURLY));
    2950       226855 :   this->advance_token();
    2951              : 
    2952       226855 :   if (this->peek_token()->is_op(OPERATOR_RCURLY))
    2953              :     {
    2954        12904 :       this->advance_token();
    2955        12904 :       return Expression::make_composite_literal(type, depth, false, NULL,
    2956        12904 :                                                 false, location);
    2957              :     }
    2958              : 
    2959       213951 :   bool has_keys = false;
    2960       213951 :   bool all_are_names = true;
    2961       213951 :   Expression_list* vals = new Expression_list;
    2962      1091305 :   while (true)
    2963              :     {
    2964      1091305 :       Expression* val;
    2965      1091305 :       bool is_type_omitted = false;
    2966      1091305 :       bool is_name = false;
    2967              : 
    2968      1091305 :       const Token* token = this->peek_token();
    2969              : 
    2970      1091305 :       if (token->is_identifier())
    2971              :         {
    2972       243123 :           std::string identifier = token->identifier();
    2973       243123 :           bool is_exported = token->is_identifier_exported();
    2974       243123 :           Location id_location = token->location();
    2975              : 
    2976       243123 :           if (this->advance_token()->is_op(OPERATOR_COLON))
    2977              :             {
    2978              :               // This may be a field name.  We don't know for sure--it
    2979              :               // could also be an expression for an array index.  We
    2980              :               // don't want to parse it as an expression because may
    2981              :               // trigger various errors, e.g., if this identifier
    2982              :               // happens to be the name of a package.
    2983       132014 :               Gogo* gogo = this->gogo_;
    2984       132014 :               val = this->id_to_expression(gogo->pack_hidden_name(identifier,
    2985              :                                                                   is_exported),
    2986              :                                            id_location, false, true);
    2987       132014 :               is_name = true;
    2988              :             }
    2989              :           else
    2990              :             {
    2991       111109 :               this->unget_token(Token::make_identifier_token(identifier,
    2992              :                                                              is_exported,
    2993              :                                                              id_location));
    2994       111109 :               val = this->expression(PRECEDENCE_NORMAL, false, true, NULL,
    2995              :                                      NULL);
    2996              :             }
    2997       243123 :         }
    2998       848182 :       else if (!token->is_op(OPERATOR_LCURLY))
    2999       712672 :         val = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    3000              :       else
    3001              :         {
    3002              :           // This must be a composite literal inside another composite
    3003              :           // literal, with the type omitted for the inner one.
    3004       135510 :           val = this->composite_lit(type, depth + 1, token->location());
    3005       135510 :           is_type_omitted = true;
    3006              :         }
    3007              : 
    3008      1091305 :       token = this->peek_token();
    3009      1091305 :       if (!token->is_op(OPERATOR_COLON))
    3010              :         {
    3011       825052 :           if (has_keys)
    3012           19 :             vals->push_back(NULL);
    3013              :           is_name = false;
    3014              :         }
    3015              :       else
    3016              :         {
    3017       266253 :           if (is_type_omitted)
    3018              :             {
    3019              :               // VAL is a nested composite literal with an omitted type being
    3020              :               // used a key.  Record this information in VAL so that the correct
    3021              :               // type is associated with the literal value if VAL is a
    3022              :               // map literal.
    3023           35 :               val->complit()->update_key_path(depth);
    3024              :             }
    3025              : 
    3026       266253 :           this->advance_token();
    3027              : 
    3028       266253 :           if (!has_keys && !vals->empty())
    3029              :             {
    3030            5 :               Expression_list* newvals = new Expression_list;
    3031            5 :               for (Expression_list::const_iterator p = vals->begin();
    3032           12 :                    p != vals->end();
    3033            7 :                    ++p)
    3034              :                 {
    3035            7 :                   newvals->push_back(NULL);
    3036            7 :                   newvals->push_back(*p);
    3037              :                 }
    3038            5 :               delete vals;
    3039            5 :               vals = newvals;
    3040              :             }
    3041       266253 :           has_keys = true;
    3042              : 
    3043       266253 :           vals->push_back(val);
    3044              : 
    3045       266253 :           if (!token->is_op(OPERATOR_LCURLY))
    3046       261063 :             val = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    3047              :           else
    3048              :             {
    3049              :               // This must be a composite literal inside another
    3050              :               // composite literal, with the type omitted for the
    3051              :               // inner one.
    3052         5190 :               val = this->composite_lit(type, depth + 1, token->location());
    3053              :             }
    3054              : 
    3055       266253 :           token = this->peek_token();
    3056              :         }
    3057              : 
    3058      1091305 :       vals->push_back(val);
    3059              : 
    3060      1091305 :       if (!is_name)
    3061       959291 :         all_are_names = false;
    3062              : 
    3063      1091305 :       if (token->is_op(OPERATOR_COMMA))
    3064              :         {
    3065      1821734 :           if (this->advance_token()->is_op(OPERATOR_RCURLY))
    3066              :             {
    3067        33513 :               this->advance_token();
    3068        33513 :               break;
    3069              :             }
    3070              :         }
    3071       180438 :       else if (token->is_op(OPERATOR_RCURLY))
    3072              :         {
    3073       180437 :           this->advance_token();
    3074       180437 :           break;
    3075              :         }
    3076              :       else
    3077              :         {
    3078            1 :           if (token->is_op(OPERATOR_SEMICOLON))
    3079            1 :             go_error_at(this->location(),
    3080              :                         ("need trailing comma before newline "
    3081              :                          "in composite literal"));
    3082              :           else
    3083            0 :             go_error_at(this->location(), "expected %<,%> or %<}%>");
    3084              : 
    3085            1 :           this->gogo_->mark_locals_used();
    3086            1 :           int edepth = 0;
    3087            3 :           while (!token->is_eof()
    3088            2 :                  && (edepth > 0 || !token->is_op(OPERATOR_RCURLY)))
    3089              :             {
    3090            1 :               if (token->is_op(OPERATOR_LCURLY))
    3091            0 :                 ++edepth;
    3092            1 :               else if (token->is_op(OPERATOR_RCURLY))
    3093            0 :                 --edepth;
    3094            1 :               token = this->advance_token();
    3095              :             }
    3096            1 :           if (token->is_op(OPERATOR_RCURLY))
    3097            1 :             this->advance_token();
    3098              : 
    3099            1 :           return Expression::make_error(location);
    3100              :         }
    3101              :     }
    3102              : 
    3103       213950 :   return Expression::make_composite_literal(type, depth, has_keys, vals,
    3104       213950 :                                             all_are_names, location);
    3105              : }
    3106              : 
    3107              : // FunctionLit = "func" Signature Block .
    3108              : 
    3109              : Expression*
    3110        25692 : Parse::function_lit()
    3111              : {
    3112        25692 :   Location location = this->location();
    3113        25692 :   go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC));
    3114        25692 :   this->advance_token();
    3115              : 
    3116        25692 :   Enclosing_vars hold_enclosing_vars;
    3117        25692 :   hold_enclosing_vars.swap(this->enclosing_vars_);
    3118              : 
    3119        25692 :   Function_type* type = this->signature(NULL, location);
    3120        25692 :   bool fntype_is_error = false;
    3121        25692 :   if (type == NULL)
    3122              :     {
    3123            0 :       type = Type::make_function_type(NULL, NULL, NULL, location);
    3124            0 :       fntype_is_error = true;
    3125              :     }
    3126              : 
    3127              :   // For a function literal, the next token must be a '{'.  If we
    3128              :   // don't see that, then we may have a type expression.
    3129        25692 :   if (!this->peek_token()->is_op(OPERATOR_LCURLY))
    3130              :     {
    3131           83 :       hold_enclosing_vars.swap(this->enclosing_vars_);
    3132           83 :       return Expression::make_type(type, location);
    3133              :     }
    3134              : 
    3135        25609 :   bool hold_is_erroneous_function = this->is_erroneous_function_;
    3136        25609 :   if (fntype_is_error)
    3137            0 :     this->is_erroneous_function_ = true;
    3138              : 
    3139        25609 :   Bc_stack* hold_break_stack = this->break_stack_;
    3140        25609 :   Bc_stack* hold_continue_stack = this->continue_stack_;
    3141        25609 :   this->break_stack_ = NULL;
    3142        25609 :   this->continue_stack_ = NULL;
    3143              : 
    3144        25609 :   Named_object* no = this->gogo_->start_function("", type, true, location);
    3145              : 
    3146        25609 :   Location end_loc = this->block();
    3147              : 
    3148        25609 :   this->gogo_->finish_function(end_loc);
    3149              : 
    3150        25609 :   if (this->break_stack_ != NULL)
    3151         3834 :     delete this->break_stack_;
    3152        25609 :   if (this->continue_stack_ != NULL)
    3153         3165 :     delete this->continue_stack_;
    3154        25609 :   this->break_stack_ = hold_break_stack;
    3155        25609 :   this->continue_stack_ = hold_continue_stack;
    3156              : 
    3157        25609 :   this->is_erroneous_function_ = hold_is_erroneous_function;
    3158              : 
    3159        25609 :   hold_enclosing_vars.swap(this->enclosing_vars_);
    3160              : 
    3161        25609 :   Expression* closure = this->create_closure(no, &hold_enclosing_vars,
    3162              :                                              location);
    3163              : 
    3164        25609 :   return Expression::make_func_reference(no, closure, location);
    3165        25692 : }
    3166              : 
    3167              : // Create a closure for the nested function FUNCTION.  This is based
    3168              : // on ENCLOSING_VARS, which is a list of all variables defined in
    3169              : // enclosing functions and referenced from FUNCTION.  A closure is the
    3170              : // address of a struct which point to the real function code and
    3171              : // contains the addresses of all the referenced variables.  This
    3172              : // returns NULL if no closure is required.
    3173              : 
    3174              : Expression*
    3175        25609 : Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars,
    3176              :                       Location location)
    3177              : {
    3178        25609 :   if (enclosing_vars->empty())
    3179              :     return NULL;
    3180              : 
    3181              :   // Get the variables in order by their field index.
    3182              : 
    3183        13057 :   size_t enclosing_var_count = enclosing_vars->size();
    3184        13057 :   std::vector<Enclosing_var> ev(enclosing_var_count);
    3185        38530 :   for (Enclosing_vars::const_iterator p = enclosing_vars->begin();
    3186        38530 :        p != enclosing_vars->end();
    3187        25473 :        ++p)
    3188              :     {
    3189              :       // Subtract 1 because index 0 is the function code.
    3190        25473 :       ev[p->index() - 1] = *p;
    3191              :     }
    3192              : 
    3193              :   // Build an initializer for a composite literal of the closure's
    3194              :   // type.
    3195              : 
    3196        13057 :   Named_object* enclosing_function = this->gogo_->current_function();
    3197        13057 :   Expression_list* initializer = new Expression_list;
    3198              : 
    3199        13057 :   initializer->push_back(Expression::make_func_code_reference(function,
    3200              :                                                               location));
    3201              : 
    3202        38530 :   for (size_t i = 0; i < enclosing_var_count; ++i)
    3203              :     {
    3204              :       // Add 1 to i because the first field in the closure is a
    3205              :       // pointer to the function code.
    3206        25473 :       go_assert(ev[i].index() == i + 1);
    3207        25473 :       Named_object* var = ev[i].var();
    3208        25473 :       Expression* ref;
    3209        25473 :       if (ev[i].in_function() == enclosing_function)
    3210        23807 :         ref = Expression::make_var_reference(var, location);
    3211              :       else
    3212         1666 :         ref = this->enclosing_var_reference(ev[i].in_function(), var,
    3213              :                                             true, location);
    3214        25473 :       Expression* refaddr = Expression::make_unary(OPERATOR_AND, ref,
    3215              :                                                    location);
    3216        25473 :       initializer->push_back(refaddr);
    3217              :     }
    3218              : 
    3219        13057 :   Named_object* closure_var = function->func_value()->closure_var();
    3220        26114 :   Struct_type* st = closure_var->var_value()->type()->deref()->struct_type();
    3221        13057 :   Expression* cv = Expression::make_struct_composite_literal(st, initializer,
    3222              :                                                              location);
    3223        13057 :   return Expression::make_heap_expression(cv, location);
    3224        13057 : }
    3225              : 
    3226              : // PrimaryExpr = Operand { Selector | Index | Slice | TypeGuard | Call } .
    3227              : 
    3228              : // If MAY_BE_SINK is true, this expression may be "_".
    3229              : 
    3230              : // If MAY_BE_COMPOSITE_LIT is true, this expression may be a composite
    3231              : // literal.
    3232              : 
    3233              : // If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
    3234              : // guard (var := expr.("type") using the literal keyword "type").
    3235              : 
    3236              : // If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
    3237              : // if the entire expression is in parentheses.
    3238              : 
    3239              : Expression*
    3240      4924366 : Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
    3241              :                     bool* is_type_switch, bool* is_parenthesized)
    3242              : {
    3243      4924366 :   Location start_loc = this->location();
    3244      4924366 :   bool operand_is_parenthesized = false;
    3245      4924366 :   bool whole_is_parenthesized = false;
    3246              : 
    3247      4924366 :   Expression* ret = this->operand(may_be_sink, &operand_is_parenthesized);
    3248              : 
    3249      4924366 :   whole_is_parenthesized = operand_is_parenthesized;
    3250              : 
    3251              :   // An unknown name followed by a curly brace must be a composite
    3252              :   // literal, and the unknown name must be a type.
    3253      4924366 :   if (may_be_composite_lit
    3254      4241130 :       && !operand_is_parenthesized
    3255      5388880 :       && ret->unknown_expression() != NULL
    3256     10313246 :       && this->peek_token()->is_op(OPERATOR_LCURLY))
    3257              :     {
    3258        12477 :       Named_object* no = ret->unknown_expression()->named_object();
    3259        12477 :       Type* type = Type::make_forward_declaration(no);
    3260        12477 :       ret = Expression::make_type(type, ret->location());
    3261              :     }
    3262              : 
    3263              :   // We handle composite literals and type casts here, as it is the
    3264              :   // easiest way to handle types which are in parentheses, as in
    3265              :   // "((uint))(1)".
    3266      4924366 :   if (ret->is_type_expression())
    3267              :     {
    3268       148468 :       if (this->peek_token()->is_op(OPERATOR_LCURLY))
    3269              :         {
    3270        86155 :           whole_is_parenthesized = false;
    3271        86155 :           if (!may_be_composite_lit)
    3272              :             {
    3273         1033 :               Type* t = ret->type();
    3274         1033 :               if (t->named_type() != NULL
    3275         1033 :                   || t->forward_declaration_type() != NULL)
    3276            0 :                 go_error_at(start_loc,
    3277            0 :                             _("parentheses required around this composite "
    3278              :                               "literal to avoid parsing ambiguity"));
    3279              :             }
    3280        85122 :           else if (operand_is_parenthesized)
    3281            6 :             go_error_at(start_loc,
    3282              :                         "cannot parenthesize type in composite literal");
    3283        86155 :           ret = this->composite_lit(ret->type(), 0, ret->location());
    3284              :         }
    3285        62313 :       else if (this->peek_token()->is_op(OPERATOR_LPAREN))
    3286              :         {
    3287        36243 :           whole_is_parenthesized = false;
    3288        36243 :           Location loc = this->location();
    3289        36243 :           this->advance_token();
    3290        36243 :           Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true,
    3291              :                                               NULL, NULL);
    3292        36243 :           if (this->peek_token()->is_op(OPERATOR_COMMA))
    3293            3 :             this->advance_token();
    3294        36243 :           if (this->peek_token()->is_op(OPERATOR_ELLIPSIS))
    3295              :             {
    3296            1 :               go_error_at(this->location(),
    3297              :                           "invalid use of %<...%> in type conversion");
    3298            1 :               this->advance_token();
    3299              :             }
    3300        36243 :           if (!this->peek_token()->is_op(OPERATOR_RPAREN))
    3301            0 :             go_error_at(this->location(), "expected %<)%>");
    3302              :           else
    3303        36243 :             this->advance_token();
    3304        36243 :           if (expr->is_error_expression())
    3305              :             ret = expr;
    3306              :           else
    3307              :             {
    3308        36243 :               Type* t = ret->type();
    3309        36243 :               if (t->classification() == Type::TYPE_ARRAY
    3310         6585 :                   && t->array_type()->length() != NULL
    3311        36251 :                   && t->array_type()->length()->is_nil_expression())
    3312              :                 {
    3313            3 :                   go_error_at(ret->location(),
    3314              :                               "use of %<[...]%> outside of array literal");
    3315            3 :                   ret = Expression::make_error(loc);
    3316              :                 }
    3317              :               else
    3318        36240 :                 ret = Expression::make_cast(t, expr, loc);
    3319              :             }
    3320              :         }
    3321              :     }
    3322              : 
    3323      6617769 :   while (true)
    3324              :     {
    3325      6617769 :       const Token* token = this->peek_token();
    3326      6617769 :       if (token->is_op(OPERATOR_LPAREN))
    3327              :         {
    3328       824565 :           whole_is_parenthesized = false;
    3329       824565 :           ret = this->call(this->verify_not_sink(ret));
    3330              :         }
    3331      5793204 :       else if (token->is_op(OPERATOR_DOT))
    3332              :         {
    3333       714093 :           whole_is_parenthesized = false;
    3334       714093 :           ret = this->selector(this->verify_not_sink(ret), is_type_switch);
    3335       714093 :           if (is_type_switch != NULL && *is_type_switch)
    3336              :             break;
    3337              :         }
    3338      5079111 :       else if (token->is_op(OPERATOR_LSQUARE))
    3339              :         {
    3340       157138 :           whole_is_parenthesized = false;
    3341       157138 :           ret = this->index(this->verify_not_sink(ret));
    3342              :         }
    3343              :       else
    3344              :         break;
    3345              :     }
    3346              : 
    3347      4924366 :   if (whole_is_parenthesized && is_parenthesized != NULL)
    3348            4 :     *is_parenthesized = true;
    3349              : 
    3350      4924366 :   return ret;
    3351              : }
    3352              : 
    3353              : // Selector = "." identifier .
    3354              : // TypeGuard = "." "(" QualifiedIdent ")" .
    3355              : 
    3356              : // Note that Operand can expand to QualifiedIdent, which contains a
    3357              : // ".".  That is handled directly in operand when it sees a package
    3358              : // name.
    3359              : 
    3360              : // If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
    3361              : // guard (var := expr.("type") using the literal keyword "type").
    3362              : 
    3363              : Expression*
    3364       714093 : Parse::selector(Expression* left, bool* is_type_switch)
    3365              : {
    3366       714093 :   go_assert(this->peek_token()->is_op(OPERATOR_DOT));
    3367       714093 :   Location location = this->location();
    3368              : 
    3369       714093 :   const Token* token = this->advance_token();
    3370       714093 :   if (token->is_identifier())
    3371              :     {
    3372              :       // This could be a field in a struct, or a method in an
    3373              :       // interface, or a method associated with a type.  We can't know
    3374              :       // which until we have seen all the types.
    3375       700127 :       std::string name =
    3376       700127 :         this->gogo_->pack_hidden_name(token->identifier(),
    3377       700127 :                                       token->is_identifier_exported());
    3378       700127 :       if (token->identifier() == "_")
    3379              :         {
    3380            1 :           go_error_at(this->location(), "invalid use of %<_%>");
    3381            1 :           name = Gogo::erroneous_name();
    3382              :         }
    3383       700127 :       this->advance_token();
    3384       700127 :       return Expression::make_selector(left, name, location);
    3385       700127 :     }
    3386        13966 :   else if (token->is_op(OPERATOR_LPAREN))
    3387              :     {
    3388        13966 :       this->advance_token();
    3389        13966 :       Type* type = NULL;
    3390        13966 :       if (!this->peek_token()->is_keyword(KEYWORD_TYPE))
    3391        11571 :         type = this->type();
    3392              :       else
    3393              :         {
    3394         2395 :           if (is_type_switch != NULL)
    3395         2393 :             *is_type_switch = true;
    3396              :           else
    3397              :             {
    3398            2 :               go_error_at(this->location(),
    3399              :                           "use of %<.(type)%> outside type switch");
    3400            2 :               type = Type::make_error_type();
    3401              :             }
    3402         2395 :           this->advance_token();
    3403              :         }
    3404        13966 :       if (!this->peek_token()->is_op(OPERATOR_RPAREN))
    3405            0 :         go_error_at(this->location(), "missing %<)%>");
    3406              :       else
    3407        13966 :         this->advance_token();
    3408        13966 :       if (is_type_switch != NULL && *is_type_switch)
    3409              :         return left;
    3410        11573 :       return Expression::make_type_guard(left, type, location);
    3411              :     }
    3412              :   else
    3413              :     {
    3414            0 :       go_error_at(this->location(), "expected identifier or %<(%>");
    3415            0 :       return left;
    3416              :     }
    3417              : }
    3418              : 
    3419              : // Index          = "[" Expression "]" .
    3420              : // Slice          = "[" Expression ":" [ Expression ] [ ":" Expression ] "]" .
    3421              : 
    3422              : Expression*
    3423       157138 : Parse::index(Expression* expr)
    3424              : {
    3425       157138 :   Location location = this->location();
    3426       157138 :   go_assert(this->peek_token()->is_op(OPERATOR_LSQUARE));
    3427       157138 :   this->advance_token();
    3428              : 
    3429       157138 :   Expression* start;
    3430       157138 :   if (!this->peek_token()->is_op(OPERATOR_COLON))
    3431       141882 :     start = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    3432              :   else
    3433        15256 :     start = Expression::make_integer_ul(0, NULL, location);
    3434              : 
    3435       157138 :   Expression* end = NULL;
    3436       157138 :   if (this->peek_token()->is_op(OPERATOR_COLON))
    3437              :     {
    3438              :       // We use nil to indicate a missing high expression.
    3439        47053 :       if (this->advance_token()->is_op(OPERATOR_RSQUARE))
    3440        20468 :         end = Expression::make_nil(this->location());
    3441        26585 :       else if (this->peek_token()->is_op(OPERATOR_COLON))
    3442              :         {
    3443           12 :           go_error_at(this->location(),
    3444              :                       "middle index required in 3-index slice");
    3445           12 :           end = Expression::make_error(this->location());
    3446              :         }
    3447              :       else
    3448        26573 :         end = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    3449              :     }
    3450              : 
    3451       157138 :   Expression* cap = NULL;
    3452       157138 :   if (this->peek_token()->is_op(OPERATOR_COLON))
    3453              :     {
    3454         3809 :       if (this->advance_token()->is_op(OPERATOR_RSQUARE))
    3455              :         {
    3456           12 :           go_error_at(this->location(),
    3457              :                       "final index required in 3-index slice");
    3458           12 :           cap = Expression::make_error(this->location());
    3459              :         }
    3460              :       else
    3461         3797 :         cap = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    3462              :     }
    3463       157138 :   if (!this->peek_token()->is_op(OPERATOR_RSQUARE))
    3464            0 :     go_error_at(this->location(), "missing %<]%>");
    3465              :   else
    3466       157138 :     this->advance_token();
    3467       157138 :   return Expression::make_index(expr, start, end, cap, location);
    3468              : }
    3469              : 
    3470              : // Call           = "(" [ ArgumentList [ "," ] ] ")" .
    3471              : // ArgumentList   = ExpressionList [ "..." ] .
    3472              : 
    3473              : Expression*
    3474       824565 : Parse::call(Expression* func)
    3475              : {
    3476       824565 :   go_assert(this->peek_token()->is_op(OPERATOR_LPAREN));
    3477       824565 :   Expression_list* args = NULL;
    3478       824565 :   bool is_varargs = false;
    3479       824565 :   const Token* token = this->advance_token();
    3480       824565 :   if (!token->is_op(OPERATOR_RPAREN))
    3481              :     {
    3482       681160 :       args = this->expression_list(NULL, false, true);
    3483       681160 :       token = this->peek_token();
    3484       681160 :       if (token->is_op(OPERATOR_ELLIPSIS))
    3485              :         {
    3486         5345 :           is_varargs = true;
    3487         5345 :           token = this->advance_token();
    3488              :         }
    3489              :     }
    3490       824565 :   if (token->is_op(OPERATOR_COMMA))
    3491          415 :     token = this->advance_token();
    3492       824565 :   if (!token->is_op(OPERATOR_RPAREN))
    3493              :     {
    3494            3 :       go_error_at(this->location(), "missing %<)%>");
    3495            3 :       if (!this->skip_past_error(OPERATOR_RPAREN))
    3496            1 :         return Expression::make_error(this->location());
    3497              :     }
    3498       824564 :   this->advance_token();
    3499       824564 :   if (func->is_error_expression())
    3500              :     return func;
    3501       824558 :   return Expression::make_call(func, args, is_varargs, func->location());
    3502              : }
    3503              : 
    3504              : // Return an expression for a single unqualified identifier.
    3505              : 
    3506              : Expression*
    3507       159911 : Parse::id_to_expression(const std::string& name, Location location,
    3508              :                         bool is_lhs, bool is_composite_literal_key)
    3509              : {
    3510       159911 :   Named_object* in_function;
    3511       159911 :   Named_object* named_object = this->gogo_->lookup(name, &in_function);
    3512       159911 :   if (named_object == NULL)
    3513              :     {
    3514       115560 :       if (is_composite_literal_key)
    3515              :         {
    3516              :           // This is a composite literal key, which means that it
    3517              :           // could just be a struct field name, so avoid confusion by
    3518              :           // not adding it to the bindings.  We'll look up the name
    3519              :           // later during the determine types phase if necessary.
    3520       115537 :           return Expression::make_composite_literal_key(name, location);
    3521              :         }
    3522           23 :       named_object = this->gogo_->add_unknown_name(name, location);
    3523              :     }
    3524              : 
    3525        44374 :   if (in_function != NULL
    3526        29692 :       && in_function != this->gogo_->current_function()
    3527        44650 :       && (named_object->is_variable() || named_object->is_result_variable()))
    3528          276 :     return this->enclosing_var_reference(in_function, named_object, is_lhs,
    3529          276 :                                          location);
    3530              : 
    3531        44098 :   switch (named_object->classification())
    3532              :     {
    3533         5110 :     case Named_object::NAMED_OBJECT_CONST:
    3534         5110 :       return Expression::make_const_reference(named_object, location);
    3535        30013 :     case Named_object::NAMED_OBJECT_VAR:
    3536        30013 :     case Named_object::NAMED_OBJECT_RESULT_VAR:
    3537        30013 :       if (!is_lhs)
    3538         5627 :         this->mark_var_used(named_object);
    3539        30013 :       return Expression::make_var_reference(named_object, location);
    3540         3290 :     case Named_object::NAMED_OBJECT_SINK:
    3541         3290 :       return Expression::make_sink(location);
    3542          331 :     case Named_object::NAMED_OBJECT_FUNC:
    3543          331 :     case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
    3544          331 :       return Expression::make_func_reference(named_object, NULL, location);
    3545         2297 :     case Named_object::NAMED_OBJECT_UNKNOWN:
    3546         2297 :       {
    3547         2297 :         Unknown_expression* ue =
    3548         2297 :           Expression::make_unknown_reference(named_object, location);
    3549         2297 :         if (this->is_erroneous_function_)
    3550            0 :           ue->set_no_error_message();
    3551              :         return ue;
    3552              :       }
    3553         3057 :     case Named_object::NAMED_OBJECT_PACKAGE:
    3554         3057 :     case Named_object::NAMED_OBJECT_TYPE:
    3555         3057 :     case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
    3556         3057 :       {
    3557              :         // These cases can arise for a field name in a composite
    3558              :         // literal.  Keep track of these as they might be fake uses of
    3559              :         // the related package.
    3560         3057 :         Unknown_expression* ue =
    3561         3057 :           Expression::make_unknown_reference(named_object, location);
    3562         3057 :         if (named_object->package() != NULL)
    3563          377 :           named_object->package()->note_fake_usage(ue);
    3564         3057 :         if (this->is_erroneous_function_)
    3565            0 :           ue->set_no_error_message();
    3566              :         return ue;
    3567              :       }
    3568            0 :     case Named_object::NAMED_OBJECT_ERRONEOUS:
    3569            0 :       return Expression::make_error(location);
    3570            0 :     default:
    3571            0 :       go_error_at(this->location(), "unexpected type of identifier");
    3572            0 :       return Expression::make_error(location);
    3573              :     }
    3574              : }
    3575              : 
    3576              : // Expression = UnaryExpr { binary_op Expression } .
    3577              : 
    3578              : // PRECEDENCE is the precedence of the current operator.
    3579              : 
    3580              : // If MAY_BE_SINK is true, this expression may be "_".
    3581              : 
    3582              : // If MAY_BE_COMPOSITE_LIT is true, this expression may be a composite
    3583              : // literal.
    3584              : 
    3585              : // If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
    3586              : // guard (var := expr.("type") using the literal keyword "type").
    3587              : 
    3588              : // If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
    3589              : // if the entire expression is in parentheses.
    3590              : 
    3591              : Expression*
    3592      4924366 : Parse::expression(Precedence precedence, bool may_be_sink,
    3593              :                   bool may_be_composite_lit, bool* is_type_switch,
    3594              :                   bool *is_parenthesized)
    3595              : {
    3596      4924366 :   Expression* left = this->unary_expr(may_be_sink, may_be_composite_lit,
    3597              :                                       is_type_switch, is_parenthesized);
    3598              : 
    3599      6105054 :   while (true)
    3600              :     {
    3601      5514710 :       if (is_type_switch != NULL && *is_type_switch)
    3602      4924366 :         return left;
    3603              : 
    3604      5512317 :       const Token* token = this->peek_token();
    3605      5512317 :       if (token->classification() != Token::TOKEN_OPERATOR)
    3606              :         {
    3607              :           // Not a binary_op.
    3608              :           return left;
    3609              :         }
    3610              : 
    3611      5512312 :       Precedence right_precedence;
    3612      5512312 :       switch (token->op())
    3613              :         {
    3614              :         case OPERATOR_OROR:
    3615              :           right_precedence = PRECEDENCE_OROR;
    3616              :           break;
    3617        71011 :         case OPERATOR_ANDAND:
    3618        71011 :           right_precedence = PRECEDENCE_ANDAND;
    3619        71011 :           break;
    3620       301459 :         case OPERATOR_EQEQ:
    3621       301459 :         case OPERATOR_NOTEQ:
    3622       301459 :         case OPERATOR_LT:
    3623       301459 :         case OPERATOR_LE:
    3624       301459 :         case OPERATOR_GT:
    3625       301459 :         case OPERATOR_GE:
    3626       301459 :           right_precedence = PRECEDENCE_RELOP;
    3627       301459 :           break;
    3628       218444 :         case OPERATOR_PLUS:
    3629       218444 :         case OPERATOR_MINUS:
    3630       218444 :         case OPERATOR_OR:
    3631       218444 :         case OPERATOR_XOR:
    3632       218444 :           right_precedence = PRECEDENCE_ADDOP;
    3633       218444 :           break;
    3634        96360 :         case OPERATOR_MULT:
    3635        96360 :         case OPERATOR_DIV:
    3636        96360 :         case OPERATOR_MOD:
    3637        96360 :         case OPERATOR_LSHIFT:
    3638        96360 :         case OPERATOR_RSHIFT:
    3639        96360 :         case OPERATOR_AND:
    3640        96360 :         case OPERATOR_BITCLEAR:
    3641        96360 :           right_precedence = PRECEDENCE_MULOP;
    3642        96360 :           break;
    3643              :         default:
    3644              :           right_precedence = PRECEDENCE_INVALID;
    3645              :           break;
    3646              :         }
    3647              : 
    3648       687274 :       if (right_precedence == PRECEDENCE_INVALID)
    3649              :         {
    3650              :           // Not a binary_op.
    3651              :           return left;
    3652              :         }
    3653              : 
    3654       740521 :       if (is_parenthesized != NULL)
    3655            0 :         *is_parenthesized = false;
    3656              : 
    3657       740521 :       Operator op = token->op();
    3658       740521 :       Location binop_location = token->location();
    3659              : 
    3660       740521 :       if (precedence >= right_precedence)
    3661              :         {
    3662              :           // We've already seen A * B, and we see + C.  We want to
    3663              :           // return so that A * B becomes a group.
    3664              :           return left;
    3665              :         }
    3666              : 
    3667       590344 :       this->advance_token();
    3668              : 
    3669       590344 :       left = this->verify_not_sink(left);
    3670       590344 :       Expression* right = this->expression(right_precedence, false,
    3671              :                                            may_be_composite_lit,
    3672              :                                            NULL, NULL);
    3673       590344 :       left = Expression::make_binary(op, left, right, binop_location);
    3674       590344 :     }
    3675              : }
    3676              : 
    3677              : bool
    3678      1508531 : Parse::expression_may_start_here()
    3679              : {
    3680      1508531 :   const Token* token = this->peek_token();
    3681      1508531 :   switch (token->classification())
    3682              :     {
    3683              :     case Token::TOKEN_INVALID:
    3684              :     case Token::TOKEN_EOF:
    3685              :       return false;
    3686         8438 :     case Token::TOKEN_KEYWORD:
    3687         8438 :       switch (token->keyword())
    3688              :         {
    3689              :         case KEYWORD_CHAN:
    3690              :         case KEYWORD_FUNC:
    3691              :         case KEYWORD_MAP:
    3692              :         case KEYWORD_STRUCT:
    3693              :         case KEYWORD_INTERFACE:
    3694              :           return true;
    3695              :         default:
    3696              :           return false;
    3697              :         }
    3698              :     case Token::TOKEN_IDENTIFIER:
    3699              :       return true;
    3700              :     case Token::TOKEN_STRING:
    3701              :       return true;
    3702       565974 :     case Token::TOKEN_OPERATOR:
    3703       565974 :       switch (token->op())
    3704              :         {
    3705              :         case OPERATOR_PLUS:
    3706              :         case OPERATOR_MINUS:
    3707              :         case OPERATOR_NOT:
    3708              :         case OPERATOR_XOR:
    3709              :         case OPERATOR_MULT:
    3710              :         case OPERATOR_CHANOP:
    3711              :         case OPERATOR_AND:
    3712              :         case OPERATOR_LPAREN:
    3713              :         case OPERATOR_LSQUARE:
    3714              :           return true;
    3715              :         default:
    3716              :           return false;
    3717              :         }
    3718              :     case Token::TOKEN_CHARACTER:
    3719              :     case Token::TOKEN_INTEGER:
    3720              :     case Token::TOKEN_FLOAT:
    3721              :     case Token::TOKEN_IMAGINARY:
    3722              :       return true;
    3723            0 :     default:
    3724            0 :       go_unreachable();
    3725              :     }
    3726              : }
    3727              : 
    3728              : // UnaryExpr = unary_op UnaryExpr | PrimaryExpr .
    3729              : 
    3730              : // If MAY_BE_SINK is true, this expression may be "_".
    3731              : 
    3732              : // If MAY_BE_COMPOSITE_LIT is true, this expression may be a composite
    3733              : // literal.
    3734              : 
    3735              : // If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
    3736              : // guard (var := expr.("type") using the literal keyword "type").
    3737              : 
    3738              : // If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
    3739              : // if the entire expression is in parentheses.
    3740              : 
    3741              : Expression*
    3742      5108880 : Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
    3743              :                   bool* is_type_switch, bool* is_parenthesized)
    3744              : {
    3745      5108880 :   const Token* token = this->peek_token();
    3746              : 
    3747              :   // There is a complex parse for <- chan.  The choices are
    3748              :   // Convert x to type <- chan int:
    3749              :   //   (<- chan int)(x)
    3750              :   // Receive from (x converted to type chan <- chan int):
    3751              :   //   (<- chan <- chan int (x))
    3752              :   // Convert x to type <- chan (<- chan int).
    3753              :   //   (<- chan <- chan int)(x)
    3754      5108880 :   if (token->is_op(OPERATOR_CHANOP))
    3755              :     {
    3756         4148 :       Location location = token->location();
    3757         4148 :       if (this->advance_token()->is_keyword(KEYWORD_CHAN))
    3758              :         {
    3759           61 :           Expression* expr = this->primary_expr(false, may_be_composite_lit,
    3760              :                                                 NULL, NULL);
    3761           61 :           if (expr->is_error_expression())
    3762           61 :             return expr;
    3763           61 :           else if (!expr->is_type_expression())
    3764            0 :             return Expression::make_receive(expr, location);
    3765              :           else
    3766              :             {
    3767           61 :               if (expr->type()->is_error_type())
    3768              :                 return expr;
    3769              : 
    3770              :               // We picked up "chan TYPE", but it is not a type
    3771              :               // conversion.
    3772           61 :               Channel_type* ct = expr->type()->channel_type();
    3773           61 :               if (ct == NULL)
    3774              :                 {
    3775              :                   // This is probably impossible.
    3776            0 :                   go_error_at(location, "expected channel type");
    3777            0 :                   return Expression::make_error(location);
    3778              :                 }
    3779           61 :               else if (ct->may_receive())
    3780              :                 {
    3781              :                   // <- chan TYPE.
    3782           55 :                   Type* t = Type::make_channel_type(false, true,
    3783              :                                                     ct->element_type());
    3784           55 :                   return Expression::make_type(t, location);
    3785              :                 }
    3786              :               else
    3787              :                 {
    3788              :                   // <- chan <- TYPE.  Because we skipped the leading
    3789              :                   // <-, we parsed this as chan <- TYPE.  With the
    3790              :                   // leading <-, we parse it as <- chan (<- TYPE).
    3791            6 :                   Type *t = this->reassociate_chan_direction(ct, location);
    3792            6 :                   return Expression::make_type(t, location);
    3793              :                 }
    3794              :             }
    3795              :         }
    3796              : 
    3797         4087 :       this->unget_token(Token::make_operator_token(OPERATOR_CHANOP, location));
    3798         4087 :       token = this->peek_token();
    3799              :     }
    3800              : 
    3801      5386621 :   if (token->is_op(OPERATOR_PLUS)
    3802      5047173 :       || token->is_op(OPERATOR_MINUS)
    3803      5014988 :       || token->is_op(OPERATOR_NOT)
    3804      5012406 :       || token->is_op(OPERATOR_XOR)
    3805      5008319 :       || token->is_op(OPERATOR_CHANOP)
    3806      4983948 :       || token->is_op(OPERATOR_MULT)
    3807      5108819 :       || token->is_op(OPERATOR_AND))
    3808              :     {
    3809       184514 :       Location location = token->location();
    3810       184514 :       Operator op = token->op();
    3811       184514 :       this->advance_token();
    3812              : 
    3813       184514 :       Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL,
    3814              :                                           NULL);
    3815       184514 :       if (expr->is_error_expression())
    3816              :         ;
    3817       184514 :       else if (op == OPERATOR_MULT && expr->is_type_expression())
    3818         4954 :         expr = Expression::make_type(Type::make_pointer_type(expr->type()),
    3819              :                                      location);
    3820       179560 :       else if (op == OPERATOR_AND && expr->is_composite_literal())
    3821        19145 :         expr = Expression::make_heap_expression(expr, location);
    3822       160415 :       else if (op != OPERATOR_CHANOP)
    3823       156328 :         expr = Expression::make_unary(op, expr, location);
    3824              :       else
    3825         4087 :         expr = Expression::make_receive(expr, location);
    3826       184514 :       return expr;
    3827              :     }
    3828              :   else
    3829      4924305 :     return this->primary_expr(may_be_sink, may_be_composite_lit,
    3830      4924305 :                               is_type_switch, is_parenthesized);
    3831              : }
    3832              : 
    3833              : // This is called for the obscure case of
    3834              : //   (<- chan <- chan int)(x)
    3835              : // In unary_expr we remove the leading <- and parse the remainder,
    3836              : // which gives us
    3837              : //   chan <- (chan int)
    3838              : // When we add the leading <- back in, we really want
    3839              : //   <- chan (<- chan int)
    3840              : // This means that we need to reassociate.
    3841              : 
    3842              : Type*
    3843            6 : Parse::reassociate_chan_direction(Channel_type *ct, Location location)
    3844              : {
    3845            6 :   Channel_type* ele = ct->element_type()->channel_type();
    3846            6 :   if (ele == NULL)
    3847              :     {
    3848            0 :       go_error_at(location, "parse error");
    3849            0 :       return Type::make_error_type();
    3850              :     }
    3851            6 :   Type* sub = ele;
    3852            6 :   if (ele->may_send())
    3853            6 :     sub = Type::make_channel_type(false, true, ele->element_type());
    3854              :   else
    3855            0 :     sub = this->reassociate_chan_direction(ele, location);
    3856            6 :   return Type::make_channel_type(false, true, sub);
    3857              : }
    3858              : 
    3859              : // Statement =
    3860              : //      Declaration | LabeledStmt | SimpleStmt |
    3861              : //      GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
    3862              : //      FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
    3863              : //      DeferStmt .
    3864              : 
    3865              : // LABEL is the label of this statement if it has one.
    3866              : 
    3867              : void
    3868      1288681 : Parse::statement(Label* label)
    3869              : {
    3870      1288681 :   const Token* token = this->peek_token();
    3871      1288681 :   switch (token->classification())
    3872              :     {
    3873       605618 :     case Token::TOKEN_KEYWORD:
    3874       605618 :       {
    3875       605618 :         switch (token->keyword())
    3876              :           {
    3877        58772 :           case KEYWORD_CONST:
    3878        58772 :           case KEYWORD_TYPE:
    3879        58772 :           case KEYWORD_VAR:
    3880        58772 :             this->declaration();
    3881        58772 :             break;
    3882          163 :           case KEYWORD_FUNC:
    3883          163 :           case KEYWORD_MAP:
    3884          163 :           case KEYWORD_STRUCT:
    3885          163 :           case KEYWORD_INTERFACE:
    3886          163 :             this->simple_stat(true, NULL, NULL, NULL);
    3887          163 :             break;
    3888        13891 :           case KEYWORD_GO:
    3889        13891 :           case KEYWORD_DEFER:
    3890        13891 :             this->go_or_defer_stat();
    3891        13891 :             break;
    3892       192928 :           case KEYWORD_RETURN:
    3893       192928 :             this->return_stat();
    3894       192928 :             break;
    3895         8057 :           case KEYWORD_BREAK:
    3896         8057 :             this->break_stat();
    3897         8057 :             break;
    3898        10807 :           case KEYWORD_CONTINUE:
    3899        10807 :             this->continue_stat();
    3900        10807 :             break;
    3901         2101 :           case KEYWORD_GOTO:
    3902         2101 :             this->goto_stat();
    3903         2101 :             break;
    3904       248846 :           case KEYWORD_IF:
    3905       248846 :             this->if_stat();
    3906       248846 :             break;
    3907        13579 :           case KEYWORD_SWITCH:
    3908        13579 :             this->switch_stat(label);
    3909        13579 :             break;
    3910         2656 :           case KEYWORD_SELECT:
    3911         2656 :             this->select_stat(label);
    3912         2656 :             break;
    3913        53818 :           case KEYWORD_FOR:
    3914        53818 :             this->for_stat(label);
    3915        53818 :             break;
    3916            0 :           default:
    3917            0 :             go_error_at(this->location(), "expected statement");
    3918            0 :             this->advance_token();
    3919            0 :             break;
    3920              :           }
    3921              :       }
    3922              :       break;
    3923              : 
    3924       675066 :     case Token::TOKEN_IDENTIFIER:
    3925       675066 :       {
    3926       675066 :         std::string identifier = token->identifier();
    3927       675066 :         bool is_exported = token->is_identifier_exported();
    3928       675066 :         Location location = token->location();
    3929       675066 :         if (this->advance_token()->is_op(OPERATOR_COLON))
    3930              :           {
    3931         1685 :             this->advance_token();
    3932         1685 :             this->labeled_stmt(identifier, location);
    3933              :           }
    3934              :         else
    3935              :           {
    3936       673381 :             this->unget_token(Token::make_identifier_token(identifier,
    3937              :                                                            is_exported,
    3938              :                                                            location));
    3939       673381 :             this->simple_stat(true, NULL, NULL, NULL);
    3940              :           }
    3941       675066 :       }
    3942       675066 :       break;
    3943              : 
    3944         7990 :     case Token::TOKEN_OPERATOR:
    3945         7990 :       if (token->is_op(OPERATOR_LCURLY))
    3946              :         {
    3947          452 :           Location location = token->location();
    3948          452 :           this->gogo_->start_block(location);
    3949          452 :           Location end_loc = this->block();
    3950          452 :           this->gogo_->add_block(this->gogo_->finish_block(end_loc),
    3951              :                                  location);
    3952              :         }
    3953         7538 :       else if (!token->is_op(OPERATOR_SEMICOLON))
    3954         7525 :         this->simple_stat(true, NULL, NULL, NULL);
    3955              :       break;
    3956              : 
    3957            7 :     case Token::TOKEN_STRING:
    3958            7 :     case Token::TOKEN_CHARACTER:
    3959            7 :     case Token::TOKEN_INTEGER:
    3960            7 :     case Token::TOKEN_FLOAT:
    3961            7 :     case Token::TOKEN_IMAGINARY:
    3962            7 :       this->simple_stat(true, NULL, NULL, NULL);
    3963            7 :       break;
    3964              : 
    3965            0 :     default:
    3966            0 :       go_error_at(this->location(), "expected statement");
    3967            0 :       this->advance_token();
    3968            0 :       break;
    3969              :     }
    3970      1288681 : }
    3971              : 
    3972              : bool
    3973      1840576 : Parse::statement_may_start_here()
    3974              : {
    3975      1840576 :   const Token* token = this->peek_token();
    3976      1840576 :   switch (token->classification())
    3977              :     {
    3978       672338 :     case Token::TOKEN_KEYWORD:
    3979       672338 :       {
    3980       672338 :         switch (token->keyword())
    3981              :           {
    3982              :           case KEYWORD_CONST:
    3983              :           case KEYWORD_TYPE:
    3984              :           case KEYWORD_VAR:
    3985              :           case KEYWORD_FUNC:
    3986              :           case KEYWORD_MAP:
    3987              :           case KEYWORD_STRUCT:
    3988              :           case KEYWORD_INTERFACE:
    3989              :           case KEYWORD_GO:
    3990              :           case KEYWORD_DEFER:
    3991              :           case KEYWORD_RETURN:
    3992              :           case KEYWORD_BREAK:
    3993              :           case KEYWORD_CONTINUE:
    3994              :           case KEYWORD_GOTO:
    3995              :           case KEYWORD_IF:
    3996              :           case KEYWORD_SWITCH:
    3997              :           case KEYWORD_SELECT:
    3998              :           case KEYWORD_FOR:
    3999              :             return true;
    4000              : 
    4001              :           default:
    4002              :             return false;
    4003              :           }
    4004              :       }
    4005              :       break;
    4006              : 
    4007              :     case Token::TOKEN_IDENTIFIER:
    4008              :       return true;
    4009              : 
    4010       467137 :     case Token::TOKEN_OPERATOR:
    4011       467137 :       if (token->is_op(OPERATOR_LCURLY)
    4012      1330469 :           || token->is_op(OPERATOR_SEMICOLON))
    4013              :         return true;
    4014              :       else
    4015       466671 :         return this->expression_may_start_here();
    4016              : 
    4017              :     case Token::TOKEN_STRING:
    4018              :     case Token::TOKEN_CHARACTER:
    4019              :     case Token::TOKEN_INTEGER:
    4020              :     case Token::TOKEN_FLOAT:
    4021              :     case Token::TOKEN_IMAGINARY:
    4022              :       return true;
    4023              : 
    4024              :     default:
    4025              :       return false;
    4026              :     }
    4027              : }
    4028              : 
    4029              : // LabeledStmt = Label ":" Statement .
    4030              : // Label       = identifier .
    4031              : 
    4032              : void
    4033         1685 : Parse::labeled_stmt(const std::string& label_name, Location location)
    4034              : {
    4035         1685 :   Label* label = this->gogo_->add_label_definition(label_name, location);
    4036              : 
    4037         1685 :   if (this->peek_token()->is_op(OPERATOR_RCURLY))
    4038              :     {
    4039              :       // This is a label at the end of a block.  A program is
    4040              :       // permitted to omit a semicolon here.
    4041              :       return;
    4042              :     }
    4043              : 
    4044         1623 :   if (!this->statement_may_start_here())
    4045              :     {
    4046            4 :       if (this->peek_token()->is_keyword(KEYWORD_FALLTHROUGH))
    4047              :         {
    4048              :           // We don't treat the fallthrough keyword as a statement,
    4049              :           // because it can't appear most places where a statement is
    4050              :           // permitted, but it may have a label.  We introduce a
    4051              :           // semicolon because the caller expects to see a statement.
    4052            1 :           this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
    4053              :                                                        location));
    4054            1 :           return;
    4055              :         }
    4056              : 
    4057              :       // Mark the label as used to avoid a useless error about an
    4058              :       // unused label.
    4059            3 :       if (label != NULL)
    4060            3 :         label->set_is_used();
    4061              : 
    4062            3 :       go_error_at(location, "missing statement after label");
    4063            3 :       this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
    4064              :                                                    location));
    4065            3 :       return;
    4066              :     }
    4067              : 
    4068         1619 :   this->statement(label);
    4069              : }
    4070              : 
    4071              : // SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt |
    4072              : //      Assignment | ShortVarDecl .
    4073              : 
    4074              : // EmptyStmt was handled in Parse::statement.
    4075              : 
    4076              : // In order to make this work for if and switch statements, if
    4077              : // RETURN_EXP is not NULL, and we see an ExpressionStat, we return the
    4078              : // expression rather than adding an expression statement to the
    4079              : // current block.  If we see something other than an ExpressionStat,
    4080              : // we add the statement, set *RETURN_EXP to true if we saw a send
    4081              : // statement, and return NULL.  The handling of send statements is for
    4082              : // better error messages.
    4083              : 
    4084              : // If P_RANGE_CLAUSE is not NULL, then this will recognize a
    4085              : // RangeClause.
    4086              : 
    4087              : // If P_TYPE_SWITCH is not NULL, this will recognize a type switch
    4088              : // guard (var := expr.("type") using the literal keyword "type").
    4089              : 
    4090              : Expression*
    4091      1013052 : Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
    4092              :                    Range_clause* p_range_clause, Type_switch* p_type_switch)
    4093              : {
    4094      1013052 :   const Token* token = this->peek_token();
    4095              : 
    4096              :   // An identifier follow by := is a SimpleVarDecl.
    4097      1013052 :   if (token->is_identifier())
    4098              :     {
    4099       980280 :       std::string identifier = token->identifier();
    4100       980280 :       bool is_exported = token->is_identifier_exported();
    4101       980280 :       Location location = token->location();
    4102              : 
    4103       980280 :       token = this->advance_token();
    4104      1776162 :       if (token->is_op(OPERATOR_COLONEQ)
    4105       980280 :           || token->is_op(OPERATOR_COMMA))
    4106              :         {
    4107       281931 :           identifier = this->gogo_->pack_hidden_name(identifier, is_exported);
    4108       281931 :           this->simple_var_decl_or_assignment(identifier, location,
    4109              :                                               may_be_composite_lit,
    4110              :                                               p_range_clause,
    4111       281931 :                                               (token->is_op(OPERATOR_COLONEQ)
    4112              :                                                ? p_type_switch
    4113              :                                                : NULL));
    4114       281931 :           return NULL;
    4115              :         }
    4116              : 
    4117       698349 :       this->unget_token(Token::make_identifier_token(identifier, is_exported,
    4118              :                                                      location));
    4119       980280 :     }
    4120        32772 :   else if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
    4121              :     {
    4122           91 :       Typed_identifier_list til;
    4123           91 :       this->range_clause_decl(&til, p_range_clause);
    4124           91 :       return NULL;
    4125           91 :     }
    4126              : 
    4127       731030 :   Expression* exp = this->expression(PRECEDENCE_NORMAL, true,
    4128              :                                      may_be_composite_lit,
    4129              :                                      (p_type_switch == NULL
    4130              :                                       ? NULL
    4131              :                                       : &p_type_switch->found),
    4132              :                                      NULL);
    4133       731030 :   if (p_type_switch != NULL && p_type_switch->found)
    4134              :     {
    4135          378 :       p_type_switch->name.clear();
    4136          378 :       p_type_switch->location = exp->location();
    4137          378 :       p_type_switch->expr = this->verify_not_sink(exp);
    4138          378 :       return NULL;
    4139              :     }
    4140       730652 :   token = this->peek_token();
    4141       730652 :   if (token->is_op(OPERATOR_CHANOP))
    4142              :     {
    4143         2594 :       this->send_stmt(this->verify_not_sink(exp), may_be_composite_lit);
    4144         2594 :       if (return_exp != NULL)
    4145            1 :         *return_exp = true;
    4146              :     }
    4147      1432932 :   else if (token->is_op(OPERATOR_PLUSPLUS)
    4148       728058 :            || token->is_op(OPERATOR_MINUSMINUS))
    4149        27453 :     this->inc_dec_stat(this->verify_not_sink(exp));
    4150      1398114 :   else if (token->is_op(OPERATOR_COMMA)
    4151       700605 :            || token->is_op(OPERATOR_EQ))
    4152       191205 :     this->assignment(exp, may_be_composite_lit, p_range_clause);
    4153      1005191 :   else if (token->is_op(OPERATOR_PLUSEQ)
    4154       491921 :            || token->is_op(OPERATOR_MINUSEQ)
    4155       489157 :            || token->is_op(OPERATOR_OREQ)
    4156       488333 :            || token->is_op(OPERATOR_XOREQ)
    4157       487409 :            || token->is_op(OPERATOR_MULTEQ)
    4158       487002 :            || token->is_op(OPERATOR_DIVEQ)
    4159       486948 :            || token->is_op(OPERATOR_MODEQ)
    4160       486355 :            || token->is_op(OPERATOR_LSHIFTEQ)
    4161       485220 :            || token->is_op(OPERATOR_RSHIFTEQ)
    4162       484636 :            || token->is_op(OPERATOR_ANDEQ)
    4163       509400 :            || token->is_op(OPERATOR_BITCLEAREQ))
    4164        25309 :     this->assignment(this->verify_not_sink(exp), may_be_composite_lit,
    4165              :                      p_range_clause);
    4166       484091 :   else if (return_exp != NULL)
    4167       232354 :     return this->verify_not_sink(exp);
    4168              :   else
    4169              :     {
    4170       251737 :       exp = this->verify_not_sink(exp);
    4171              : 
    4172       251737 :       if (token->is_op(OPERATOR_COLONEQ))
    4173              :         {
    4174            3 :           if (!exp->is_error_expression())
    4175            2 :             go_error_at(token->location(), "non-name on left side of %<:=%>");
    4176            3 :           this->gogo_->mark_locals_used();
    4177       780701 :           while (!token->is_op(OPERATOR_SEMICOLON)
    4178           12 :                  && !token->is_eof())
    4179            6 :             token = this->advance_token();
    4180              :           return NULL;
    4181              :         }
    4182              : 
    4183       251734 :       this->expression_stat(exp);
    4184              :     }
    4185              : 
    4186              :   return NULL;
    4187              : }
    4188              : 
    4189              : bool
    4190       267601 : Parse::simple_stat_may_start_here()
    4191              : {
    4192       267601 :   return this->expression_may_start_here();
    4193              : }
    4194              : 
    4195              : // Parse { Statement ";" } which is used in a few places.  The list of
    4196              : // statements may end with a right curly brace, in which case the
    4197              : // semicolon may be omitted.
    4198              : 
    4199              : void
    4200       528447 : Parse::statement_list()
    4201              : {
    4202      1787360 :   while (this->statement_may_start_here())
    4203              :     {
    4204      1287061 :       this->statement(NULL);
    4205      1287061 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4206      1258905 :         this->advance_token();
    4207        28156 :       else if (this->peek_token()->is_op(OPERATOR_RCURLY))
    4208              :         break;
    4209              :       else
    4210              :         {
    4211           15 :           if (!this->peek_token()->is_eof() || !saw_errors())
    4212            8 :             go_error_at(this->location(), "expected %<;%> or %<}%> or newline");
    4213           15 :           if (!this->skip_past_error(OPERATOR_RCURLY))
    4214              :             return;
    4215              :         }
    4216              :     }
    4217              : }
    4218              : 
    4219              : bool
    4220        51592 : Parse::statement_list_may_start_here()
    4221              : {
    4222        51592 :   return this->statement_may_start_here();
    4223              : }
    4224              : 
    4225              : // ExpressionStat = Expression .
    4226              : 
    4227              : void
    4228       251819 : Parse::expression_stat(Expression* exp)
    4229              : {
    4230       251819 :   this->gogo_->add_statement(Statement::make_statement(exp, false));
    4231       251819 : }
    4232              : 
    4233              : // SendStmt = Channel "&lt;-" Expression .
    4234              : // Channel  = Expression .
    4235              : 
    4236              : void
    4237         2594 : Parse::send_stmt(Expression* channel, bool may_be_composite_lit)
    4238              : {
    4239         2594 :   go_assert(this->peek_token()->is_op(OPERATOR_CHANOP));
    4240         2594 :   Location loc = this->location();
    4241         2594 :   this->advance_token();
    4242         2594 :   Expression* val = this->expression(PRECEDENCE_NORMAL, false,
    4243              :                                      may_be_composite_lit, NULL, NULL);
    4244         2594 :   Statement* s = Statement::make_send_statement(channel, val, loc);
    4245         2594 :   this->gogo_->add_statement(s);
    4246         2594 : }
    4247              : 
    4248              : // IncDecStat = Expression ( "++" | "--" ) .
    4249              : 
    4250              : void
    4251        27453 : Parse::inc_dec_stat(Expression* exp)
    4252              : {
    4253        27453 :   const Token* token = this->peek_token();
    4254        27453 :   if (token->is_op(OPERATOR_PLUSPLUS))
    4255        23182 :     this->gogo_->add_statement(Statement::make_inc_statement(exp));
    4256         4271 :   else if (token->is_op(OPERATOR_MINUSMINUS))
    4257         4271 :     this->gogo_->add_statement(Statement::make_dec_statement(exp));
    4258              :   else
    4259            0 :     go_unreachable();
    4260        27453 :   this->advance_token();
    4261        27453 : }
    4262              : 
    4263              : // Assignment = ExpressionList assign_op ExpressionList .
    4264              : 
    4265              : // EXP is an expression that we have already parsed.
    4266              : 
    4267              : // If MAY_BE_COMPOSITE_LIT is true, an expression on the right hand
    4268              : // side may be a composite literal.
    4269              : 
    4270              : // If RANGE_CLAUSE is not NULL, then this will recognize a
    4271              : // RangeClause.
    4272              : 
    4273              : void
    4274       216514 : Parse::assignment(Expression* expr, bool may_be_composite_lit,
    4275              :                   Range_clause* p_range_clause)
    4276              : {
    4277       216514 :   Expression_list* vars;
    4278       216514 :   if (!this->peek_token()->is_op(OPERATOR_COMMA))
    4279              :     {
    4280       213420 :       vars = new Expression_list();
    4281       213420 :       vars->push_back(expr);
    4282              :     }
    4283              :   else
    4284              :     {
    4285         3094 :       this->advance_token();
    4286         3094 :       vars = this->expression_list(expr, true, may_be_composite_lit);
    4287              :     }
    4288              : 
    4289       216514 :   this->tuple_assignment(vars, may_be_composite_lit, p_range_clause);
    4290       216514 : }
    4291              : 
    4292              : // An assignment statement.  LHS is the list of expressions which
    4293              : // appear on the left hand side.
    4294              : 
    4295              : // If MAY_BE_COMPOSITE_LIT is true, an expression on the right hand
    4296              : // side may be a composite literal.
    4297              : 
    4298              : // If RANGE_CLAUSE is not NULL, then this will recognize a
    4299              : // RangeClause.
    4300              : 
    4301              : void
    4302       241560 : Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
    4303              :                         Range_clause* p_range_clause)
    4304              : {
    4305       241560 :   const Token* token = this->peek_token();
    4306       266869 :   if (!token->is_op(OPERATOR_EQ)
    4307        11702 :       && !token->is_op(OPERATOR_PLUSEQ)
    4308         7830 :       && !token->is_op(OPERATOR_MINUSEQ)
    4309         5066 :       && !token->is_op(OPERATOR_OREQ)
    4310         4242 :       && !token->is_op(OPERATOR_XOREQ)
    4311         3318 :       && !token->is_op(OPERATOR_MULTEQ)
    4312         2911 :       && !token->is_op(OPERATOR_DIVEQ)
    4313         2857 :       && !token->is_op(OPERATOR_MODEQ)
    4314         2264 :       && !token->is_op(OPERATOR_LSHIFTEQ)
    4315         1129 :       && !token->is_op(OPERATOR_RSHIFTEQ)
    4316          545 :       && !token->is_op(OPERATOR_ANDEQ)
    4317       241560 :       && !token->is_op(OPERATOR_BITCLEAREQ))
    4318              :     {
    4319            0 :       go_error_at(this->location(), "expected assignment operator");
    4320            0 :       return;
    4321              :     }
    4322       241560 :   Operator op = token->op();
    4323       241560 :   Location location = token->location();
    4324              : 
    4325       241560 :   token = this->advance_token();
    4326              : 
    4327       241560 :   if (lhs == NULL)
    4328              :     return;
    4329              : 
    4330       241560 :   if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
    4331              :     {
    4332          105 :       if (op != OPERATOR_EQ)
    4333            0 :         go_error_at(this->location(), "range clause requires %<=%>");
    4334          105 :       this->range_clause_expr(lhs, p_range_clause);
    4335          105 :       return;
    4336              :     }
    4337              : 
    4338       241455 :   Expression_list* vals = this->expression_list(NULL, false,
    4339              :                                                 may_be_composite_lit);
    4340              : 
    4341              :   // We've parsed everything; check for errors.
    4342       241455 :   if (vals == NULL)
    4343              :     return;
    4344       514506 :   for (Expression_list::const_iterator pe = lhs->begin();
    4345       514506 :        pe != lhs->end();
    4346       273051 :        ++pe)
    4347              :     {
    4348       273051 :       if ((*pe)->is_error_expression())
    4349          107 :         return;
    4350       273051 :       if (op != OPERATOR_EQ && (*pe)->is_sink_expression())
    4351            0 :         go_error_at((*pe)->location(), "cannot use %<_%> as value");
    4352              :     }
    4353       487805 :   for (Expression_list::const_iterator pe = vals->begin();
    4354       487805 :        pe != vals->end();
    4355       246350 :        ++pe)
    4356              :     {
    4357       246352 :       if ((*pe)->is_error_expression())
    4358          107 :         return;
    4359              :     }
    4360              : 
    4361       241453 :   Call_expression* call;
    4362       241453 :   Index_expression* map_index;
    4363       241453 :   Receive_expression* receive;
    4364       241453 :   Type_guard_expression* type_guard;
    4365       241453 :   if (lhs->size() == vals->size())
    4366              :     {
    4367       217320 :       Statement* s;
    4368       217320 :       if (lhs->size() > 1)
    4369              :         {
    4370         3922 :           if (op != OPERATOR_EQ)
    4371            0 :             go_error_at(location, "multiple values only permitted with %<=%>");
    4372         3922 :           s = Statement::make_tuple_assignment(lhs, vals, location);
    4373              :         }
    4374              :       else
    4375              :         {
    4376       213398 :           if (op == OPERATOR_EQ)
    4377       188089 :             s = Statement::make_assignment(lhs->front(), vals->front(),
    4378              :                                            location);
    4379              :           else
    4380        25309 :             s = Statement::make_assignment_operation(op, lhs->front(),
    4381        25309 :                                                      vals->front(), location);
    4382       426796 :           delete lhs;
    4383       213398 :           delete vals;
    4384              :         }
    4385       217320 :       this->gogo_->add_statement(s);
    4386              :     }
    4387        24133 :   else if (vals->size() == 1
    4388        24133 :            && (call = (*vals->begin())->call_expression()) != NULL)
    4389              :     {
    4390        23576 :       if (op != OPERATOR_EQ)
    4391            0 :         go_error_at(location, "multiple results only permitted with %<=%>");
    4392        23576 :       call->set_expected_result_count(lhs->size());
    4393        23576 :       delete vals;
    4394        23576 :       vals = new Expression_list;
    4395        73296 :       for (unsigned int i = 0; i < lhs->size(); ++i)
    4396        49720 :         vals->push_back(Expression::make_call_result(call, i));
    4397        23576 :       Statement* s = Statement::make_tuple_assignment(lhs, vals, location);
    4398        23576 :       this->gogo_->add_statement(s);
    4399              :     }
    4400          557 :   else if (lhs->size() == 2
    4401          556 :            && vals->size() == 1
    4402         1113 :            && (map_index = (*vals->begin())->index_expression()) != NULL)
    4403              :     {
    4404          195 :       if (op != OPERATOR_EQ)
    4405            0 :         go_error_at(location, "two values from map requires %<=%>");
    4406          195 :       Expression* val = lhs->front();
    4407          195 :       Expression* present = lhs->back();
    4408          195 :       Statement* s = Statement::make_tuple_map_assignment(val, present,
    4409              :                                                           map_index, location);
    4410          195 :       this->gogo_->add_statement(s);
    4411              :     }
    4412          362 :   else if (lhs->size() == 2
    4413          361 :            && vals->size() == 1
    4414          723 :            && (receive = (*vals->begin())->receive_expression()) != NULL)
    4415              :     {
    4416           34 :       if (op != OPERATOR_EQ)
    4417            0 :         go_error_at(location, "two values from receive requires %<=%>");
    4418           34 :       Expression* val = lhs->front();
    4419           34 :       Expression* success = lhs->back();
    4420           34 :       Expression* channel = receive->channel();
    4421           34 :       Statement* s = Statement::make_tuple_receive_assignment(val, success,
    4422              :                                                               channel,
    4423              :                                                               location);
    4424           34 :       this->gogo_->add_statement(s);
    4425              :     }
    4426          328 :   else if (lhs->size() == 2
    4427          327 :            && vals->size() == 1
    4428          655 :            && (type_guard = (*vals->begin())->type_guard_expression()) != NULL)
    4429              :     {
    4430          327 :       if (op != OPERATOR_EQ)
    4431            0 :         go_error_at(location, "two values from type guard requires %<=%>");
    4432          327 :       Expression* val = lhs->front();
    4433          327 :       Expression* ok = lhs->back();
    4434          327 :       Expression* expr = type_guard->expr();
    4435          327 :       Type* type = type_guard->type();
    4436          327 :       Statement* s = Statement::make_tuple_type_guard_assignment(val, ok,
    4437              :                                                                  expr, type,
    4438              :                                                                  location);
    4439          327 :       this->gogo_->add_statement(s);
    4440              :     }
    4441              :   else
    4442              :     {
    4443            1 :       go_error_at(location, ("number of variables does not "
    4444              :                              "match number of values"));
    4445              :     }
    4446              : }
    4447              : 
    4448              : // GoStat = "go" Expression .
    4449              : // DeferStat = "defer" Expression .
    4450              : 
    4451              : void
    4452        13891 : Parse::go_or_defer_stat()
    4453              : {
    4454        25247 :   go_assert(this->peek_token()->is_keyword(KEYWORD_GO)
    4455              :              || this->peek_token()->is_keyword(KEYWORD_DEFER));
    4456        13891 :   bool is_go = this->peek_token()->is_keyword(KEYWORD_GO);
    4457        13891 :   Location stat_location = this->location();
    4458              : 
    4459        13891 :   this->advance_token();
    4460        13891 :   Location expr_location = this->location();
    4461              : 
    4462        13891 :   bool is_parenthesized = false;
    4463        13891 :   Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true, NULL,
    4464              :                                       &is_parenthesized);
    4465        13891 :   Call_expression* call_expr = expr->call_expression();
    4466        13891 :   if (is_parenthesized || call_expr == NULL)
    4467              :     {
    4468            9 :       go_error_at(expr_location, "argument to go/defer must be function call");
    4469            9 :       return;
    4470              :     }
    4471              : 
    4472              :   // Make it easier to simplify go/defer statements by putting every
    4473              :   // statement in its own block.
    4474        13882 :   this->gogo_->start_block(stat_location);
    4475        13882 :   Statement* stat;
    4476        13882 :   if (is_go)
    4477              :     {
    4478         2530 :       stat = Statement::make_go_statement(call_expr, stat_location);
    4479         2530 :       call_expr->set_is_concurrent();
    4480              :     }
    4481              :   else
    4482              :     {
    4483        11352 :       stat = Statement::make_defer_statement(call_expr, stat_location);
    4484        11352 :       call_expr->set_is_deferred();
    4485              :     }
    4486        13882 :   this->gogo_->add_statement(stat);
    4487        13882 :   this->gogo_->add_block(this->gogo_->finish_block(stat_location),
    4488              :                          stat_location);
    4489              : }
    4490              : 
    4491              : // ReturnStat = "return" [ ExpressionList ] .
    4492              : 
    4493              : void
    4494       192928 : Parse::return_stat()
    4495              : {
    4496       192928 :   go_assert(this->peek_token()->is_keyword(KEYWORD_RETURN));
    4497       192928 :   Location location = this->location();
    4498       192928 :   this->advance_token();
    4499       192928 :   Expression_list* vals = NULL;
    4500       192928 :   if (this->expression_may_start_here())
    4501       173975 :     vals = this->expression_list(NULL, false, true);
    4502       192928 :   Named_object* function = this->gogo_->current_function();
    4503       192928 :   this->gogo_->add_statement(Statement::make_return_statement(function, vals,
    4504              :                                                               location));
    4505              : 
    4506       192928 :   if (vals == NULL && function->func_value()->results_are_named())
    4507              :     {
    4508         7903 :       Function::Results* results = function->func_value()->result_variables();
    4509        23848 :       for (Function::Results::const_iterator p = results->begin();
    4510        23848 :            p != results->end();
    4511        15945 :            ++p)
    4512              :         {
    4513        15945 :           Named_object* no = this->gogo_->lookup((*p)->name(), NULL);
    4514        15945 :           if (no == NULL)
    4515            0 :             go_assert(saw_errors());
    4516        15945 :           else if (!no->is_result_variable())
    4517            0 :             go_error_at(location, "%qs is shadowed during return",
    4518            0 :                         (*p)->message_name().c_str());
    4519              :         }
    4520              :     }
    4521       192928 : }
    4522              : 
    4523              : // IfStmt = "if" [ SimpleStmt ";" ] Expression Block
    4524              : //          [ "else" ( IfStmt | Block ) ] .
    4525              : 
    4526              : void
    4527       254022 : Parse::if_stat()
    4528              : {
    4529       254022 :   go_assert(this->peek_token()->is_keyword(KEYWORD_IF));
    4530       254022 :   Location location = this->location();
    4531       254022 :   this->advance_token();
    4532              : 
    4533       254022 :   this->gogo_->start_block(location);
    4534              : 
    4535       254022 :   bool saw_simple_stat = false;
    4536       254022 :   Expression* cond = NULL;
    4537       254022 :   bool saw_send_stmt = false;
    4538       254022 :   if (this->simple_stat_may_start_here())
    4539              :     {
    4540       254020 :       cond = this->simple_stat(false, &saw_send_stmt, NULL, NULL);
    4541       254020 :       saw_simple_stat = true;
    4542              :     }
    4543       254020 :   if (cond != NULL && this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4544              :     {
    4545              :       // The SimpleStat is an expression statement.
    4546           68 :       this->expression_stat(cond);
    4547           68 :       cond = NULL;
    4548              :     }
    4549       254022 :   if (cond == NULL)
    4550              :     {
    4551        35741 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4552        35737 :         this->advance_token();
    4553            4 :       else if (saw_simple_stat)
    4554              :         {
    4555            3 :           if (saw_send_stmt)
    4556            1 :             go_error_at(this->location(),
    4557              :                         ("send statement used as value; "
    4558              :                          "use select for non-blocking send"));
    4559              :           else
    4560            2 :             go_error_at(this->location(),
    4561              :                         "expected %<;%> after statement in if expression");
    4562            3 :           if (!this->expression_may_start_here())
    4563            3 :             cond = Expression::make_error(this->location());
    4564              :         }
    4565        35741 :       if (cond == NULL && this->peek_token()->is_op(OPERATOR_LCURLY))
    4566              :         {
    4567            2 :           go_error_at(this->location(),
    4568              :                       "missing condition in if statement");
    4569            2 :           cond = Expression::make_error(this->location());
    4570              :         }
    4571        35741 :       if (cond == NULL)
    4572        35736 :         cond = this->expression(PRECEDENCE_NORMAL, false, false, NULL, NULL);
    4573              :     }
    4574              : 
    4575              :   // Check for the easy error of a newline before starting the block.
    4576       254022 :   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4577              :     {
    4578            1 :       Location semi_loc = this->location();
    4579            2 :       if (this->advance_token()->is_op(OPERATOR_LCURLY))
    4580            1 :         go_error_at(semi_loc, "unexpected semicolon or newline, expecting %<{%> after if clause");
    4581              :       // Otherwise we will get an error when we call this->block
    4582              :       // below.
    4583              :     }
    4584              : 
    4585       254022 :   this->gogo_->start_block(this->location());
    4586       254022 :   Location end_loc = this->block();
    4587       254022 :   Block* then_block = this->gogo_->finish_block(end_loc);
    4588              : 
    4589              :   // Check for the easy error of a newline before "else".
    4590       254022 :   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4591              :     {
    4592       234707 :       Location semi_loc = this->location();
    4593       234707 :       if (this->advance_token()->is_keyword(KEYWORD_ELSE))
    4594            1 :         go_error_at(this->location(),
    4595              :                  "unexpected semicolon or newline before %<else%>");
    4596              :       else
    4597       234706 :         this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
    4598              :                                                      semi_loc));
    4599              :     }
    4600              : 
    4601       254022 :   Block* else_block = NULL;
    4602       254022 :   if (this->peek_token()->is_keyword(KEYWORD_ELSE))
    4603              :     {
    4604        19311 :       this->gogo_->start_block(this->location());
    4605        19311 :       const Token* token = this->advance_token();
    4606        19311 :       if (token->is_keyword(KEYWORD_IF))
    4607         5176 :         this->if_stat();
    4608        14135 :       else if (token->is_op(OPERATOR_LCURLY))
    4609        14134 :         this->block();
    4610              :       else
    4611              :         {
    4612            1 :           go_error_at(this->location(), "expected %<if%> or %<{%>");
    4613            1 :           this->statement(NULL);
    4614              :         }
    4615        19311 :       else_block = this->gogo_->finish_block(this->location());
    4616              :     }
    4617              : 
    4618       254022 :   this->gogo_->add_statement(Statement::make_if_statement(cond, then_block,
    4619              :                                                           else_block,
    4620              :                                                           location));
    4621              : 
    4622       254022 :   this->gogo_->add_block(this->gogo_->finish_block(this->location()),
    4623              :                          location);
    4624       254022 : }
    4625              : 
    4626              : // SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
    4627              : // ExprSwitchStmt = "switch" [ [ SimpleStat ] ";" ] [ Expression ]
    4628              : //                      "{" { ExprCaseClause } "}" .
    4629              : // TypeSwitchStmt  = "switch" [ [ SimpleStat ] ";" ] TypeSwitchGuard
    4630              : //                      "{" { TypeCaseClause } "}" .
    4631              : // TypeSwitchGuard = [ identifier ":=" ] Expression "." "(" "type" ")" .
    4632              : 
    4633              : void
    4634        13579 : Parse::switch_stat(Label* label)
    4635              : {
    4636        13579 :   go_assert(this->peek_token()->is_keyword(KEYWORD_SWITCH));
    4637        13579 :   Location location = this->location();
    4638        13579 :   this->advance_token();
    4639              : 
    4640        13579 :   this->gogo_->start_block(location);
    4641              : 
    4642        13579 :   bool saw_simple_stat = false;
    4643        13579 :   Expression* switch_val = NULL;
    4644        13579 :   bool saw_send_stmt = false;
    4645        13579 :   Type_switch type_switch;
    4646        13579 :   bool have_type_switch_block = false;
    4647        13579 :   if (this->simple_stat_may_start_here())
    4648              :     {
    4649        10800 :       switch_val = this->simple_stat(false, &saw_send_stmt, NULL,
    4650              :                                      &type_switch);
    4651        10800 :       saw_simple_stat = true;
    4652              :     }
    4653        10800 :   if (switch_val != NULL && this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4654              :     {
    4655              :       // The SimpleStat is an expression statement.
    4656            1 :       this->expression_stat(switch_val);
    4657            1 :       switch_val = NULL;
    4658              :     }
    4659        13579 :   if (switch_val == NULL && !type_switch.found)
    4660              :     {
    4661         3533 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4662          755 :         this->advance_token();
    4663         2778 :       else if (saw_simple_stat)
    4664              :         {
    4665            1 :           if (saw_send_stmt)
    4666            0 :             go_error_at(this->location(),
    4667              :                         ("send statement used as value; "
    4668              :                          "use select for non-blocking send"));
    4669              :           else
    4670            1 :             go_error_at(this->location(),
    4671              :                         "expected %<;%> after statement in switch expression");
    4672              :         }
    4673         3533 :       if (!this->peek_token()->is_op(OPERATOR_LCURLY))
    4674              :         {
    4675          508 :           if (this->peek_token()->is_identifier())
    4676              :             {
    4677          508 :               const Token* token = this->peek_token();
    4678          508 :               std::string identifier = token->identifier();
    4679          508 :               bool is_exported = token->is_identifier_exported();
    4680          508 :               Location id_loc = token->location();
    4681              : 
    4682          508 :               token = this->advance_token();
    4683          508 :               bool is_coloneq = token->is_op(OPERATOR_COLONEQ);
    4684          508 :               this->unget_token(Token::make_identifier_token(identifier,
    4685              :                                                              is_exported,
    4686              :                                                              id_loc));
    4687          508 :               if (is_coloneq)
    4688              :                 {
    4689              :                   // This must be a TypeSwitchGuard.  It is in a
    4690              :                   // different block from any initial SimpleStat.
    4691            0 :                   if (saw_simple_stat)
    4692              :                     {
    4693            0 :                       this->gogo_->start_block(id_loc);
    4694            0 :                       have_type_switch_block = true;
    4695              :                     }
    4696              : 
    4697            0 :                   switch_val = this->simple_stat(false, &saw_send_stmt, NULL,
    4698              :                                                  &type_switch);
    4699            0 :                   if (!type_switch.found)
    4700              :                     {
    4701            0 :                       if (switch_val == NULL
    4702            0 :                           || !switch_val->is_error_expression())
    4703              :                         {
    4704            0 :                           go_error_at(id_loc,
    4705              :                                       "expected type switch assignment");
    4706            0 :                           switch_val = Expression::make_error(id_loc);
    4707              :                         }
    4708              :                     }
    4709              :                 }
    4710          508 :             }
    4711          508 :           if (switch_val == NULL && !type_switch.found)
    4712              :             {
    4713          508 :               switch_val = this->expression(PRECEDENCE_NORMAL, false, false,
    4714              :                                             &type_switch.found, NULL);
    4715          508 :               if (type_switch.found)
    4716              :                 {
    4717            1 :                   type_switch.name.clear();
    4718            1 :                   type_switch.expr = switch_val;
    4719            1 :                   type_switch.location = switch_val->location();
    4720              :                 }
    4721              :             }
    4722              :         }
    4723              :     }
    4724              : 
    4725        13579 :   if (!this->peek_token()->is_op(OPERATOR_LCURLY))
    4726              :     {
    4727            2 :       Location token_loc = this->location();
    4728            2 :       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
    4729            1 :           && this->advance_token()->is_op(OPERATOR_LCURLY))
    4730            1 :         go_error_at(token_loc, "missing %<{%> after switch clause");
    4731            1 :       else if (this->peek_token()->is_op(OPERATOR_COLONEQ))
    4732              :         {
    4733            1 :           go_error_at(token_loc, "invalid variable name");
    4734            1 :           this->advance_token();
    4735            1 :           this->expression(PRECEDENCE_NORMAL, false, false,
    4736              :                            &type_switch.found, NULL);
    4737            1 :           if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    4738            0 :             this->advance_token();
    4739            1 :           if (!this->peek_token()->is_op(OPERATOR_LCURLY))
    4740              :             {
    4741            0 :               if (have_type_switch_block)
    4742            0 :                 this->gogo_->add_block(this->gogo_->finish_block(location),
    4743              :                                        location);
    4744            0 :               this->gogo_->add_block(this->gogo_->finish_block(location),
    4745              :                                      location);
    4746            0 :               return;
    4747              :             }
    4748            1 :           if (type_switch.found)
    4749            1 :             type_switch.expr = Expression::make_error(location);
    4750              :         }
    4751              :       else
    4752              :         {
    4753            0 :           go_error_at(this->location(), "expected %<{%>");
    4754            0 :           if (have_type_switch_block)
    4755            0 :             this->gogo_->add_block(this->gogo_->finish_block(this->location()),
    4756              :                                    location);
    4757            0 :           this->gogo_->add_block(this->gogo_->finish_block(this->location()),
    4758              :                                  location);
    4759            0 :           return;
    4760              :         }
    4761              :     }
    4762        13579 :   this->advance_token();
    4763              : 
    4764        13579 :   Statement* statement;
    4765        13579 :   if (type_switch.found)
    4766         2393 :     statement = this->type_switch_body(label, type_switch, location);
    4767              :   else
    4768        11186 :     statement = this->expr_switch_body(label, switch_val, location);
    4769              : 
    4770        13579 :   if (statement != NULL)
    4771        13578 :     this->gogo_->add_statement(statement);
    4772              : 
    4773        13579 :   if (have_type_switch_block)
    4774            0 :     this->gogo_->add_block(this->gogo_->finish_block(this->location()),
    4775              :                            location);
    4776              : 
    4777        13579 :   this->gogo_->add_block(this->gogo_->finish_block(this->location()),
    4778              :                          location);
    4779        13579 : }
    4780              : 
    4781              : // The body of an expression switch.
    4782              : //   "{" { ExprCaseClause } "}"
    4783              : 
    4784              : Statement*
    4785        11186 : Parse::expr_switch_body(Label* label, Expression* switch_val,
    4786              :                         Location location)
    4787              : {
    4788        11186 :   Switch_statement* statement = Statement::make_switch_statement(switch_val,
    4789              :                                                                  location);
    4790              : 
    4791        11186 :   this->push_break_statement(statement, label);
    4792              : 
    4793        11186 :   Case_clauses* case_clauses = new Case_clauses();
    4794        11186 :   bool saw_default = false;
    4795        51402 :   while (!this->peek_token()->is_op(OPERATOR_RCURLY))
    4796              :     {
    4797        40217 :       if (this->peek_token()->is_eof())
    4798              :         {
    4799            1 :           if (!saw_errors())
    4800            0 :             go_error_at(this->location(), "missing %<}%>");
    4801            1 :           return NULL;
    4802              :         }
    4803        40216 :       this->expr_case_clause(case_clauses, &saw_default);
    4804              :     }
    4805        11185 :   this->advance_token();
    4806              : 
    4807        11185 :   statement->add_clauses(case_clauses);
    4808              : 
    4809        11185 :   this->pop_break_statement();
    4810              : 
    4811        11185 :   return statement;
    4812              : }
    4813              : 
    4814              : // ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .
    4815              : // FallthroughStat = "fallthrough" .
    4816              : 
    4817              : void
    4818        40216 : Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default)
    4819              : {
    4820        40216 :   Location location = this->location();
    4821              : 
    4822        40216 :   bool is_default = false;
    4823        40216 :   Expression_list* vals = this->expr_switch_case(&is_default);
    4824              : 
    4825        40216 :   if (!this->peek_token()->is_op(OPERATOR_COLON))
    4826              :     {
    4827            2 :       if (!saw_errors())
    4828            0 :         go_error_at(this->location(), "expected %<:%>");
    4829            2 :       return;
    4830              :     }
    4831              :   else
    4832        40214 :     this->advance_token();
    4833              : 
    4834        40214 :   Block* statements = NULL;
    4835        40214 :   if (this->statement_list_may_start_here())
    4836              :     {
    4837        38955 :       this->gogo_->start_block(this->location());
    4838        38955 :       this->statement_list();
    4839        38955 :       statements = this->gogo_->finish_block(this->location());
    4840              :     }
    4841              : 
    4842        40214 :   bool is_fallthrough = false;
    4843        40214 :   if (this->peek_token()->is_keyword(KEYWORD_FALLTHROUGH))
    4844              :     {
    4845          476 :       Location fallthrough_loc = this->location();
    4846          476 :       is_fallthrough = true;
    4847         1905 :       while (this->advance_token()->is_op(OPERATOR_SEMICOLON))
    4848              :         ;
    4849          476 :       if (this->peek_token()->is_op(OPERATOR_RCURLY))
    4850            2 :         go_error_at(fallthrough_loc,
    4851            2 :                     _("cannot fallthrough final case in switch"));
    4852          474 :       else if (!this->peek_token()->is_keyword(KEYWORD_CASE)
    4853          106 :                && !this->peek_token()->is_keyword(KEYWORD_DEFAULT))
    4854              :         {
    4855            1 :           go_error_at(fallthrough_loc, "fallthrough statement out of place");
    4856            3 :           while (!this->peek_token()->is_keyword(KEYWORD_CASE)
    4857            1 :                  && !this->peek_token()->is_keyword(KEYWORD_DEFAULT)
    4858          477 :                  && !this->peek_token()->is_op(OPERATOR_RCURLY)
    4859            3 :                  && !this->peek_token()->is_eof())
    4860              :             {
    4861            1 :               if (this->statement_may_start_here())
    4862            1 :                 this->statement_list();
    4863              :               else
    4864            0 :                 this->advance_token();
    4865              :             }
    4866              :         }
    4867              :     }
    4868              : 
    4869        40214 :   if (is_default)
    4870              :     {
    4871         5371 :       if (*saw_default)
    4872              :         {
    4873            0 :           go_error_at(location, "multiple defaults in switch");
    4874            0 :           return;
    4875              :         }
    4876         5371 :       *saw_default = true;
    4877              :     }
    4878              : 
    4879        40214 :   if (is_default || vals != NULL)
    4880        40214 :     clauses->add(vals, is_default, statements, is_fallthrough, location);
    4881              : }
    4882              : 
    4883              : // ExprSwitchCase = "case" ExpressionList | "default" .
    4884              : 
    4885              : Expression_list*
    4886        40216 : Parse::expr_switch_case(bool* is_default)
    4887              : {
    4888        40216 :   const Token* token = this->peek_token();
    4889        40216 :   if (token->is_keyword(KEYWORD_CASE))
    4890              :     {
    4891        34843 :       this->advance_token();
    4892        34843 :       return this->expression_list(NULL, false, true);
    4893              :     }
    4894         5373 :   else if (token->is_keyword(KEYWORD_DEFAULT))
    4895              :     {
    4896         5371 :       this->advance_token();
    4897         5371 :       *is_default = true;
    4898         5371 :       return NULL;
    4899              :     }
    4900              :   else
    4901              :     {
    4902            2 :       if (!saw_errors())
    4903            0 :         go_error_at(this->location(), "expected %<case%> or %<default%>");
    4904            2 :       if (!token->is_op(OPERATOR_RCURLY))
    4905            2 :         this->advance_token();
    4906            2 :       return NULL;
    4907              :     }
    4908              : }
    4909              : 
    4910              : // The body of a type switch.
    4911              : //   "{" { TypeCaseClause } "}" .
    4912              : 
    4913              : Statement*
    4914         2393 : Parse::type_switch_body(Label* label, const Type_switch& type_switch,
    4915              :                         Location location)
    4916              : {
    4917         2393 :   Expression* init = type_switch.expr;
    4918         2393 :   std::string var_name = type_switch.name;
    4919         2393 :   if (!var_name.empty())
    4920              :     {
    4921         2013 :       if (Gogo::is_sink_name(var_name))
    4922              :         {
    4923            1 :           go_error_at(type_switch.location,
    4924              :                       "no new variables on left side of %<:=%>");
    4925            1 :           var_name.clear();
    4926              :         }
    4927              :       else
    4928              :         {
    4929         2012 :           Location loc = type_switch.location;
    4930         2012 :           Temporary_statement* switch_temp =
    4931         2012 :               Statement::make_temporary(NULL, init, loc);
    4932         2012 :           this->gogo_->add_statement(switch_temp);
    4933         2012 :           init = Expression::make_temporary_reference(switch_temp, loc);
    4934              :         }
    4935              :     }
    4936              : 
    4937         2393 :   Type_switch_statement* statement =
    4938         2393 :       Statement::make_type_switch_statement(init, location);
    4939         2393 :   this->push_break_statement(statement, label);
    4940              : 
    4941         2393 :   Type_case_clauses* case_clauses = new Type_case_clauses();
    4942         2393 :   bool saw_default = false;
    4943         2393 :   std::vector<Named_object*> implicit_vars;
    4944        13771 :   while (!this->peek_token()->is_op(OPERATOR_RCURLY))
    4945              :     {
    4946        11378 :       if (this->peek_token()->is_eof())
    4947              :         {
    4948            0 :           go_error_at(this->location(), "missing %<}%>");
    4949            0 :           return NULL;
    4950              :         }
    4951        11378 :       this->type_case_clause(var_name, init, case_clauses, &saw_default,
    4952              :                              &implicit_vars);
    4953              :     }
    4954         2393 :   this->advance_token();
    4955              : 
    4956         2393 :   statement->add_clauses(case_clauses);
    4957              : 
    4958         2393 :   this->pop_break_statement();
    4959              : 
    4960              :   // If there is a type switch variable implicitly declared in each case clause,
    4961              :   // check that it is used in at least one of the cases.
    4962         2393 :   if (!var_name.empty())
    4963              :     {
    4964         2012 :       bool used = false;
    4965         2012 :       for (std::vector<Named_object*>::iterator p = implicit_vars.begin();
    4966         2012 :            p != implicit_vars.end();
    4967            0 :            ++p)
    4968              :         {
    4969         2009 :           if ((*p)->var_value()->is_used())
    4970              :             {
    4971              :               used = true;
    4972              :               break;
    4973              :             }
    4974              :         }
    4975         2012 :       if (!used)
    4976            3 :         go_error_at(type_switch.location, "%qs declared but not used",
    4977            6 :                     Gogo::message_name(var_name).c_str());
    4978              :     }
    4979              :   return statement;
    4980         2393 : }
    4981              : 
    4982              : // TypeCaseClause  = TypeSwitchCase ":" [ StatementList ] .
    4983              : // IMPLICIT_VARS is the list of variables implicitly declared for each type
    4984              : // case if there is a type switch variable declared.
    4985              : 
    4986              : void
    4987        11378 : Parse::type_case_clause(const std::string& var_name, Expression* init,
    4988              :                         Type_case_clauses* clauses, bool* saw_default,
    4989              :                         std::vector<Named_object*>* implicit_vars)
    4990              : {
    4991        11378 :   Location location = this->location();
    4992              : 
    4993        11378 :   std::vector<Type*> types;
    4994        11378 :   bool is_default = false;
    4995        11378 :   this->type_switch_case(&types, &is_default);
    4996              : 
    4997        11378 :   if (!this->peek_token()->is_op(OPERATOR_COLON))
    4998            0 :     go_error_at(this->location(), "expected %<:%>");
    4999              :   else
    5000        11378 :     this->advance_token();
    5001              : 
    5002        11378 :   Block* statements = NULL;
    5003        11378 :   if (this->statement_list_may_start_here())
    5004              :     {
    5005        10919 :       this->gogo_->start_block(this->location());
    5006        10919 :       if (!var_name.empty())
    5007              :         {
    5008         9915 :           Type* type = NULL;
    5009         9915 :           Location var_loc = init->location();
    5010         9915 :           if (types.size() == 1)
    5011              :             {
    5012         8774 :               type = types.front();
    5013         8774 :               init = Expression::make_type_guard(init, type, location);
    5014              :             }
    5015              : 
    5016         9915 :           Variable* v = new Variable(type, init, false, false, false,
    5017         9915 :                                      var_loc);
    5018         9915 :           v->set_is_used();
    5019         9915 :           v->set_is_type_switch_var();
    5020         9915 :           implicit_vars->push_back(this->gogo_->add_variable(var_name, v));
    5021              :         }
    5022        10919 :       this->statement_list();
    5023        10919 :       statements = this->gogo_->finish_block(this->location());
    5024              :     }
    5025              : 
    5026        11378 :   if (this->peek_token()->is_keyword(KEYWORD_FALLTHROUGH))
    5027              :     {
    5028            1 :       go_error_at(this->location(),
    5029              :                   "fallthrough is not permitted in a type switch");
    5030            1 :       if (this->advance_token()->is_op(OPERATOR_SEMICOLON))
    5031            1 :         this->advance_token();
    5032              :     }
    5033              : 
    5034        11378 :   if (is_default)
    5035              :     {
    5036         1054 :       go_assert(types.empty());
    5037         1054 :       if (*saw_default)
    5038              :         {
    5039            0 :           go_error_at(location, "multiple defaults in type switch");
    5040            0 :           return;
    5041              :         }
    5042         1054 :       *saw_default = true;
    5043         1054 :       clauses->add(NULL, false, true, statements, location);
    5044              :     }
    5045        10324 :   else if (!types.empty())
    5046              :     {
    5047         1278 :       for (std::vector<Type*>::const_iterator p = types.begin();
    5048        11601 :            p + 1 != types.end();
    5049         1278 :            ++p)
    5050         1278 :         clauses->add(*p, true, false, NULL, location);
    5051        10323 :       clauses->add(types.back(), false, false, statements, location);
    5052              :     }
    5053              :   else
    5054            1 :     clauses->add(Type::make_error_type(), false, false, statements, location);
    5055        11378 : }
    5056              : 
    5057              : // TypeSwitchCase  = "case" type | "default"
    5058              : 
    5059              : // We accept a comma separated list of types.
    5060              : 
    5061              : void
    5062        11378 : Parse::type_switch_case(std::vector<Type*>* types, bool* is_default)
    5063              : {
    5064        11378 :   const Token* token = this->peek_token();
    5065        11378 :   if (token->is_keyword(KEYWORD_CASE))
    5066              :     {
    5067        10324 :       this->advance_token();
    5068        12880 :       while (true)
    5069              :         {
    5070        11602 :           Type* t = this->type();
    5071              : 
    5072        11602 :           if (!t->is_error_type())
    5073        11601 :             types->push_back(t);
    5074              :           else
    5075              :             {
    5076            1 :               this->gogo_->mark_locals_used();
    5077            1 :               token = this->peek_token();
    5078            2 :               while (!token->is_op(OPERATOR_COLON)
    5079            1 :                      && !token->is_op(OPERATOR_COMMA)
    5080        11603 :                      && !token->is_op(OPERATOR_RCURLY)
    5081            3 :                      && !token->is_eof())
    5082            1 :                 token = this->advance_token();
    5083              :             }
    5084              : 
    5085        21926 :           if (!this->peek_token()->is_op(OPERATOR_COMMA))
    5086              :             break;
    5087         1278 :           this->advance_token();
    5088         1278 :         }
    5089              :     }
    5090         1054 :   else if (token->is_keyword(KEYWORD_DEFAULT))
    5091              :     {
    5092         1054 :       this->advance_token();
    5093         1054 :       *is_default = true;
    5094              :     }
    5095              :   else
    5096              :     {
    5097            0 :       go_error_at(this->location(), "expected %<case%> or %<default%>");
    5098            0 :       if (!token->is_op(OPERATOR_RCURLY))
    5099            0 :         this->advance_token();
    5100              :     }
    5101        11378 : }
    5102              : 
    5103              : // SelectStat = "select" "{" { CommClause } "}" .
    5104              : 
    5105              : void
    5106         2656 : Parse::select_stat(Label* label)
    5107              : {
    5108         2656 :   go_assert(this->peek_token()->is_keyword(KEYWORD_SELECT));
    5109         2656 :   Location location = this->location();
    5110         2656 :   const Token* token = this->advance_token();
    5111              : 
    5112         2656 :   if (!token->is_op(OPERATOR_LCURLY))
    5113              :     {
    5114            0 :       Location token_loc = token->location();
    5115            0 :       if (token->is_op(OPERATOR_SEMICOLON)
    5116            0 :           && this->advance_token()->is_op(OPERATOR_LCURLY))
    5117            0 :         go_error_at(token_loc, "unexpected semicolon or newline before %<{%>");
    5118              :       else
    5119              :         {
    5120            0 :           go_error_at(this->location(), "expected %<{%>");
    5121            0 :           return;
    5122              :         }
    5123              :     }
    5124         2656 :   this->advance_token();
    5125              : 
    5126         2656 :   Select_statement* statement = Statement::make_select_statement(location);
    5127              : 
    5128         2656 :   this->push_break_statement(statement, label);
    5129              : 
    5130         2656 :   Select_clauses* select_clauses = new Select_clauses();
    5131         2656 :   bool saw_default = false;
    5132        10648 :   while (!this->peek_token()->is_op(OPERATOR_RCURLY))
    5133              :     {
    5134         7992 :       if (this->peek_token()->is_eof())
    5135              :         {
    5136            0 :           go_error_at(this->location(), "expected %<}%>");
    5137            0 :           return;
    5138              :         }
    5139         7992 :       this->comm_clause(select_clauses, &saw_default);
    5140              :     }
    5141              : 
    5142         2656 :   this->advance_token();
    5143              : 
    5144         2656 :   statement->add_clauses(select_clauses);
    5145              : 
    5146         2656 :   this->pop_break_statement();
    5147              : 
    5148         2656 :   this->gogo_->add_statement(statement);
    5149              : }
    5150              : 
    5151              : // CommClause = CommCase ":" { Statement ";" } .
    5152              : 
    5153              : void
    5154         7992 : Parse::comm_clause(Select_clauses* clauses, bool* saw_default)
    5155              : {
    5156         7992 :   Location location = this->location();
    5157         7992 :   bool is_send = false;
    5158         7992 :   Expression* channel = NULL;
    5159         7992 :   Expression* val = NULL;
    5160         7992 :   Expression* closed = NULL;
    5161         7992 :   std::string varname;
    5162         7992 :   std::string closedname;
    5163         7992 :   bool is_default = false;
    5164         7992 :   bool got_case = this->comm_case(&is_send, &channel, &val, &closed,
    5165              :                                   &varname, &closedname, &is_default);
    5166              : 
    5167         7992 :   if (this->peek_token()->is_op(OPERATOR_COLON))
    5168         7991 :     this->advance_token();
    5169              :   else
    5170            1 :     go_error_at(this->location(), "expected colon");
    5171              : 
    5172         7992 :   this->gogo_->start_block(this->location());
    5173              : 
    5174         7992 :   Named_object* var = NULL;
    5175         7992 :   if (!varname.empty())
    5176              :     {
    5177              :       // FIXME: LOCATION is slightly wrong here.
    5178          524 :       Variable* v = new Variable(NULL, channel, false, false, false,
    5179          524 :                                  location);
    5180          524 :       v->set_type_from_chan_element();
    5181          524 :       var = this->gogo_->add_variable(varname, v);
    5182              :     }
    5183              : 
    5184         7992 :   Named_object* closedvar = NULL;
    5185         7992 :   if (!closedname.empty())
    5186              :     {
    5187              :       // FIXME: LOCATION is slightly wrong here.
    5188           41 :       Variable* v = new Variable(Type::lookup_bool_type(), NULL,
    5189           82 :                                  false, false, false, location);
    5190           41 :       closedvar = this->gogo_->add_variable(closedname, v);
    5191              :     }
    5192              : 
    5193         7992 :   this->statement_list();
    5194              : 
    5195         7992 :   Block* statements = this->gogo_->finish_block(this->location());
    5196              : 
    5197         7992 :   if (is_default)
    5198              :     {
    5199         1464 :       if (*saw_default)
    5200              :         {
    5201            0 :           go_error_at(location, "multiple defaults in select");
    5202            0 :           return;
    5203              :         }
    5204         1464 :       *saw_default = true;
    5205              :     }
    5206              : 
    5207         7992 :   if (got_case)
    5208         7990 :     clauses->add(is_send, channel, val, closed, var, closedvar, is_default,
    5209              :                  statements, location);
    5210            2 :   else if (statements != NULL)
    5211              :     {
    5212              :       // Add the statements to make sure that any names they define
    5213              :       // are traversed.
    5214            2 :       this->gogo_->add_block(statements, location);
    5215              :     }
    5216         7992 : }
    5217              : 
    5218              : // CommCase   = "case" ( SendStmt | RecvStmt ) | "default" .
    5219              : 
    5220              : bool
    5221         7992 : Parse::comm_case(bool* is_send, Expression** channel, Expression** val,
    5222              :                  Expression** closed, std::string* varname,
    5223              :                  std::string* closedname, bool* is_default)
    5224              : {
    5225         7992 :   const Token* token = this->peek_token();
    5226         7992 :   if (token->is_keyword(KEYWORD_DEFAULT))
    5227              :     {
    5228         1464 :       this->advance_token();
    5229         1464 :       *is_default = true;
    5230              :     }
    5231         6528 :   else if (token->is_keyword(KEYWORD_CASE))
    5232              :     {
    5233         6528 :       this->advance_token();
    5234         6528 :       if (!this->send_or_recv_stmt(is_send, channel, val, closed, varname,
    5235              :                                    closedname))
    5236              :         return false;
    5237              :     }
    5238              :   else
    5239              :     {
    5240            0 :       go_error_at(this->location(), "expected %<case%> or %<default%>");
    5241            0 :       if (!token->is_op(OPERATOR_RCURLY))
    5242            0 :         this->advance_token();
    5243            0 :       return false;
    5244              :     }
    5245              : 
    5246              :   return true;
    5247              : }
    5248              : 
    5249              : // RecvStmt   = [ Expression [ "," Expression ] ( "=" | ":=" ) ] RecvExpr .
    5250              : // RecvExpr   = Expression .
    5251              : 
    5252              : bool
    5253         6528 : Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
    5254              :                          Expression** closed, std::string* varname,
    5255              :                          std::string* closedname)
    5256              : {
    5257         6528 :   const Token* token = this->peek_token();
    5258         6528 :   bool saw_comma = false;
    5259         6528 :   bool closed_is_id = false;
    5260         6528 :   if (token->is_identifier())
    5261              :     {
    5262         2889 :       Gogo* gogo = this->gogo_;
    5263         2889 :       std::string recv_var = token->identifier();
    5264         2889 :       bool is_rv_exported = token->is_identifier_exported();
    5265         2889 :       Location recv_var_loc = token->location();
    5266         2889 :       token = this->advance_token();
    5267         2889 :       if (token->is_op(OPERATOR_COLONEQ))
    5268              :         {
    5269              :           // case rv := <-c:
    5270          499 :           this->advance_token();
    5271          499 :           Expression* e = this->expression(PRECEDENCE_NORMAL, false, false,
    5272              :                                            NULL, NULL);
    5273          499 :           Receive_expression* re = e->receive_expression();
    5274          499 :           if (re == NULL)
    5275              :             {
    5276            0 :               if (!e->is_error_expression())
    5277            0 :                 go_error_at(this->location(), "expected receive expression");
    5278            0 :               return false;
    5279              :             }
    5280          499 :           if (recv_var == "_")
    5281              :             {
    5282            0 :               go_error_at(recv_var_loc,
    5283              :                           "no new variables on left side of %<:=%>");
    5284            0 :               recv_var = Gogo::erroneous_name();
    5285              :             }
    5286          499 :           *is_send = false;
    5287          499 :           *varname = gogo->pack_hidden_name(recv_var, is_rv_exported);
    5288          499 :           *channel = re->channel();
    5289          499 :           return true;
    5290              :         }
    5291         2390 :       else if (token->is_op(OPERATOR_COMMA))
    5292              :         {
    5293           54 :           token = this->advance_token();
    5294           54 :           if (token->is_identifier())
    5295              :             {
    5296           54 :               std::string recv_closed = token->identifier();
    5297           54 :               bool is_rc_exported = token->is_identifier_exported();
    5298           54 :               Location recv_closed_loc = token->location();
    5299           54 :               closed_is_id = true;
    5300              : 
    5301           54 :               token = this->advance_token();
    5302           54 :               if (token->is_op(OPERATOR_COLONEQ))
    5303              :                 {
    5304              :                   // case rv, rc := <-c:
    5305           41 :                   this->advance_token();
    5306           41 :                   Expression* e = this->expression(PRECEDENCE_NORMAL, false,
    5307              :                                                    false, NULL, NULL);
    5308           41 :                   Receive_expression* re = e->receive_expression();
    5309           41 :                   if (re == NULL)
    5310              :                     {
    5311            0 :                       if (!e->is_error_expression())
    5312            0 :                         go_error_at(this->location(),
    5313              :                                  "expected receive expression");
    5314            0 :                       return false;
    5315              :                     }
    5316           41 :                   if (recv_var == "_" && recv_closed == "_")
    5317              :                     {
    5318            0 :                       go_error_at(recv_var_loc,
    5319              :                                   "no new variables on left side of %<:=%>");
    5320            0 :                       recv_var = Gogo::erroneous_name();
    5321              :                     }
    5322           41 :                   *is_send = false;
    5323           41 :                   if (recv_var != "_")
    5324           50 :                     *varname = gogo->pack_hidden_name(recv_var,
    5325           25 :                                                       is_rv_exported);
    5326           41 :                   if (recv_closed != "_")
    5327           82 :                     *closedname = gogo->pack_hidden_name(recv_closed,
    5328           41 :                                                          is_rc_exported);
    5329           41 :                   *channel = re->channel();
    5330           41 :                   return true;
    5331              :                 }
    5332              : 
    5333           13 :               this->unget_token(Token::make_identifier_token(recv_closed,
    5334              :                                                              is_rc_exported,
    5335              :                                                              recv_closed_loc));
    5336           54 :             }
    5337              : 
    5338           13 :           *val = this->id_to_expression(gogo->pack_hidden_name(recv_var,
    5339              :                                                                is_rv_exported),
    5340              :                                         recv_var_loc, true, false);
    5341           13 :           saw_comma = true;
    5342              :         }
    5343              :       else
    5344         2336 :         this->unget_token(Token::make_identifier_token(recv_var,
    5345              :                                                        is_rv_exported,
    5346              :                                                        recv_var_loc));
    5347          540 :     }
    5348              : 
    5349              :   // If SAW_COMMA is false, then we are looking at the start of the
    5350              :   // send or receive expression.  If SAW_COMMA is true, then *VAL is
    5351              :   // set and we just read a comma.
    5352              : 
    5353         2349 :   Expression* e;
    5354         5988 :   if (saw_comma || !this->peek_token()->is_op(OPERATOR_CHANOP))
    5355              :     {
    5356         2962 :       e = this->expression(PRECEDENCE_NORMAL, true, true, NULL, NULL);
    5357         2962 :       if (e->receive_expression() != NULL)
    5358              :         {
    5359            1 :           *is_send = false;
    5360            1 :           *channel = e->receive_expression()->channel();
    5361              :           // This is 'case (<-c):'.  We now expect ':'.  If we see
    5362              :           // '<-', then we have case (<-c)<-v:
    5363         2963 :           if (!this->peek_token()->is_op(OPERATOR_CHANOP))
    5364              :             return true;
    5365              :         }
    5366              :     }
    5367              :   else
    5368              :     {
    5369              :       // case <-c:
    5370         3026 :       *is_send = false;
    5371         3026 :       this->advance_token();
    5372         3026 :       *channel = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    5373              : 
    5374              :       // The next token should be ':'.  If it is '<-', then we have
    5375              :       // case <-c <- v:
    5376              :       // which is to say, send on a channel received from a channel.
    5377         7532 :       if (!this->peek_token()->is_op(OPERATOR_CHANOP))
    5378              :         return true;
    5379              : 
    5380            1 :       e = Expression::make_receive(*channel, (*channel)->location());
    5381              :     }
    5382              : 
    5383         2962 :   if (!saw_comma && this->peek_token()->is_op(OPERATOR_COMMA))
    5384              :     {
    5385            1 :       this->advance_token();
    5386              :       // case v, e = <-c:
    5387            1 :       if (!e->is_sink_expression())
    5388            1 :         *val = e;
    5389            1 :       e = this->expression(PRECEDENCE_NORMAL, true, true, NULL, NULL);
    5390            1 :       saw_comma = true;
    5391              :     }
    5392              : 
    5393         2962 :   if (this->peek_token()->is_op(OPERATOR_EQ))
    5394              :     {
    5395         1480 :       *is_send = false;
    5396         1480 :       this->advance_token();
    5397         1480 :       Location recvloc = this->location();
    5398         1480 :       Expression* recvexpr = this->expression(PRECEDENCE_NORMAL, false,
    5399              :                                               true, NULL, NULL);
    5400         1480 :       if (recvexpr->receive_expression() == NULL)
    5401              :         {
    5402            0 :           go_error_at(recvloc, "missing %<<-%>");
    5403            0 :           return false;
    5404              :         }
    5405         1480 :       *channel = recvexpr->receive_expression()->channel();
    5406         1480 :       if (saw_comma)
    5407              :         {
    5408              :           // case v, e = <-c:
    5409              :           // *VAL is already set.
    5410           14 :           if (!e->is_sink_expression())
    5411            9 :             *closed = e;
    5412              :         }
    5413              :       else
    5414              :         {
    5415              :           // case v = <-c:
    5416         1466 :           if (!e->is_sink_expression())
    5417         1459 :             *val = e;
    5418              :         }
    5419         1480 :       return true;
    5420              :     }
    5421              : 
    5422         1482 :   if (saw_comma)
    5423              :     {
    5424            0 :       if (closed_is_id)
    5425            0 :         go_error_at(this->location(), "expected %<=%> or %<:=%>");
    5426              :       else
    5427            0 :         go_error_at(this->location(), "expected %<=%>");
    5428            0 :       return false;
    5429              :     }
    5430              : 
    5431         1482 :   if (this->peek_token()->is_op(OPERATOR_CHANOP))
    5432              :     {
    5433              :       // case c <- v:
    5434         1480 :       *is_send = true;
    5435         1480 :       *channel = this->verify_not_sink(e);
    5436         1480 :       this->advance_token();
    5437         1480 :       *val = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    5438         1480 :       return true;
    5439              :     }
    5440              : 
    5441            2 :   go_error_at(this->location(), "expected %<<-%> or %<=%>");
    5442            2 :   return false;
    5443              : }
    5444              : 
    5445              : // ForStat = "for" [ Condition | ForClause | RangeClause ] Block .
    5446              : // Condition = Expression .
    5447              : 
    5448              : void
    5449        53818 : Parse::for_stat(Label* label)
    5450              : {
    5451        53818 :   go_assert(this->peek_token()->is_keyword(KEYWORD_FOR));
    5452        53818 :   Location location = this->location();
    5453        53818 :   const Token* token = this->advance_token();
    5454              : 
    5455              :   // Open a block to hold any variables defined in the init statement
    5456              :   // of the for statement.
    5457        53818 :   this->gogo_->start_block(location);
    5458              : 
    5459        53818 :   Block* init = NULL;
    5460        53818 :   Expression* cond = NULL;
    5461        53818 :   Block* post = NULL;
    5462        53818 :   Range_clause range_clause;
    5463              : 
    5464        53818 :   if (!token->is_op(OPERATOR_LCURLY))
    5465              :     {
    5466        50378 :       if (token->is_keyword(KEYWORD_VAR))
    5467              :         {
    5468            0 :           go_error_at(this->location(),
    5469              :                       "var declaration not allowed in for initializer");
    5470            0 :           this->var_decl();
    5471              :         }
    5472              : 
    5473        50378 :       if (token->is_op(OPERATOR_SEMICOLON))
    5474         1069 :         this->for_clause(&cond, &post);
    5475              :       else
    5476              :         {
    5477              :           // We might be looking at a Condition, an InitStat, or a
    5478              :           // RangeClause.
    5479        49309 :           bool saw_send_stmt = false;
    5480        49309 :           cond = this->simple_stat(false, &saw_send_stmt, &range_clause, NULL);
    5481        49309 :           if (!this->peek_token()->is_op(OPERATOR_SEMICOLON))
    5482              :             {
    5483        32078 :               if (cond == NULL && !range_clause.found)
    5484              :                 {
    5485            1 :                   if (saw_send_stmt)
    5486            0 :                     go_error_at(this->location(),
    5487              :                                 ("send statement used as value; "
    5488              :                                  "use select for non-blocking send"));
    5489              :                   else
    5490            1 :                     go_error_at(this->location(),
    5491              :                                 "parse error in for statement");
    5492              :                 }
    5493              :             }
    5494              :           else
    5495              :             {
    5496        17231 :               if (range_clause.found)
    5497            0 :                 go_error_at(this->location(), "parse error after range clause");
    5498              : 
    5499        17231 :               if (cond != NULL)
    5500              :                 {
    5501              :                   // COND is actually an expression statement for
    5502              :                   // InitStat at the start of a ForClause.
    5503           16 :                   this->expression_stat(cond);
    5504           16 :                   cond = NULL;
    5505              :                 }
    5506              : 
    5507        17231 :               this->for_clause(&cond, &post);
    5508              :             }
    5509              :         }
    5510              :     }
    5511              : 
    5512              :   // Check for the easy error of a newline before starting the block.
    5513        53818 :   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    5514              :     {
    5515            1 :       Location semi_loc = this->location();
    5516            2 :       if (this->advance_token()->is_op(OPERATOR_LCURLY))
    5517            1 :         go_error_at(semi_loc, "unexpected semicolon or newline, expecting %<{%> after for clause");
    5518              :       // Otherwise we will get an error when we call this->block
    5519              :       // below.
    5520              :     }
    5521              : 
    5522              :   // Build the For_statement and note that it is the current target
    5523              :   // for break and continue statements.
    5524              : 
    5525        53818 :   For_statement* sfor;
    5526        53818 :   For_range_statement* srange;
    5527        53818 :   Statement* s;
    5528        53818 :   if (!range_clause.found)
    5529              :     {
    5530        28074 :       sfor = Statement::make_for_statement(init, cond, post, location);
    5531        28074 :       s = sfor;
    5532        28074 :       srange = NULL;
    5533              :     }
    5534              :   else
    5535              :     {
    5536        25744 :       srange = Statement::make_for_range_statement(range_clause.index,
    5537              :                                                    range_clause.value,
    5538              :                                                    range_clause.range,
    5539              :                                                    location);
    5540        25744 :       s = srange;
    5541        25744 :       sfor = NULL;
    5542              :     }
    5543              : 
    5544        53818 :   this->push_break_statement(s, label);
    5545        53818 :   this->push_continue_statement(s, label);
    5546              : 
    5547              :   // Gather the block of statements in the loop and add them to the
    5548              :   // For_statement.
    5549              : 
    5550        53818 :   this->gogo_->start_block(this->location());
    5551        53818 :   Location end_loc = this->block();
    5552        53818 :   Block* statements = this->gogo_->finish_block(end_loc);
    5553              : 
    5554        53818 :   if (sfor != NULL)
    5555        28074 :     sfor->add_statements(statements);
    5556              :   else
    5557        25744 :     srange->add_statements(statements);
    5558              : 
    5559              :   // This is no longer the break/continue target.
    5560        53818 :   this->pop_break_statement();
    5561        53818 :   this->pop_continue_statement();
    5562              : 
    5563              :   // Add the For_statement to the list of statements, and close out
    5564              :   // the block we started to hold any variables defined in the for
    5565              :   // statement.
    5566              : 
    5567        53818 :   this->gogo_->add_statement(s);
    5568              : 
    5569        53818 :   this->gogo_->add_block(this->gogo_->finish_block(this->location()),
    5570              :                          location);
    5571        53818 : }
    5572              : 
    5573              : // ForClause = [ InitStat ] ";" [ Condition ] ";" [ PostStat ] .
    5574              : // InitStat = SimpleStat .
    5575              : // PostStat = SimpleStat .
    5576              : 
    5577              : // We have already read InitStat at this point.
    5578              : 
    5579              : void
    5580        18300 : Parse::for_clause(Expression** cond, Block** post)
    5581              : {
    5582        18300 :   go_assert(this->peek_token()->is_op(OPERATOR_SEMICOLON));
    5583        18300 :   this->advance_token();
    5584        18300 :   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
    5585          331 :     *cond = NULL;
    5586        17969 :   else if (this->peek_token()->is_op(OPERATOR_LCURLY))
    5587              :     {
    5588            1 :       go_error_at(this->location(), "unexpected semicolon or newline, expecting %<{%> after for clause");
    5589            1 :       *cond = NULL;
    5590            1 :       *post = NULL;
    5591            1 :       return;
    5592              :     }
    5593              :   else
    5594        17968 :     *cond = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
    5595        18299 :   if (!this->peek_token()->is_op(OPERATOR_SEMICOLON))
    5596            0 :     go_error_at(this->location(), "expected semicolon");
    5597              :   else
    5598        18299 :     this->advance_token();
    5599              : 
    5600        18299 :   if (this->peek_token()->is_op(OPERATOR_LCURLY))
    5601          452 :     *post = NULL;
    5602              :   else
    5603              :     {
    5604        17847 :       this->gogo_->start_block(this->location());
    5605        17847 :       this->simple_stat(false, NULL, NULL, NULL);
    5606        17847 :       *post = this->gogo_->finish_block(this->location());
    5607              :     }
    5608              : }
    5609              : 
    5610              : // RangeClause = [ IdentifierList ( "=" | ":=" ) ] "range" Expression .
    5611              : 
    5612              : // This is the := version.  It is called with a list of identifiers.
    5613              : 
    5614              : void
    5615        25639 : Parse::range_clause_decl(const Typed_identifier_list* til,
    5616              :                          Range_clause* p_range_clause)
    5617              : {
    5618        25639 :   go_assert(this->peek_token()->is_keyword(KEYWORD_RANGE));
    5619        25639 :   Location location = this->location();
    5620              : 
    5621        25639 :   p_range_clause->found = true;
    5622              : 
    5623        25639 :   if (til->size() > 2)
    5624            0 :     go_error_at(this->location(), "too many variables for range clause");
    5625              : 
    5626        25639 :   this->advance_token();
    5627        25639 :   Expression* expr = this->expression(PRECEDENCE_NORMAL, false, false, NULL,
    5628              :                                       NULL);
    5629        25639 :   p_range_clause->range = expr;
    5630              : 
    5631        25639 :   if (til->empty())
    5632           91 :     return;
    5633              : 
    5634        25548 :   bool any_new = false;
    5635              : 
    5636        25548 :   const Typed_identifier* pti = &til->front();
    5637        25548 :   Named_object* no = this->init_var(*pti, NULL, expr, true, true, &any_new,
    5638              :                                     NULL, NULL);
    5639        25548 :   if (any_new && no->is_variable())
    5640         9240 :     no->var_value()->set_type_from_range_index();
    5641        25548 :   p_range_clause->index = Expression::make_var_reference(no, location);
    5642              : 
    5643        25548 :   if (til->size() == 1)
    5644         3354 :     p_range_clause->value = NULL;
    5645              :   else
    5646              :     {
    5647        22194 :       pti = &til->back();
    5648        22194 :       bool is_new = false;
    5649        22194 :       no = this->init_var(*pti, NULL, expr, true, true, &is_new, NULL, NULL);
    5650        22194 :       if (is_new && no->is_variable())
    5651        22169 :         no->var_value()->set_type_from_range_value();
    5652        22194 :       if (is_new)
    5653        22169 :         any_new = true;
    5654        22194 :       p_range_clause->value = Expression::make_var_reference(no, location);
    5655              :     }
    5656              : 
    5657        25548 :   if (!any_new)
    5658            0 :     go_error_at(location, "variables redeclared but no variable is new");
    5659              : }
    5660              : 
    5661              : // The = version of RangeClause.  This is called with a list of
    5662              : // expressions.
    5663              : 
    5664              : void
    5665          105 : Parse::range_clause_expr(const Expression_list* vals,
    5666              :                          Range_clause* p_range_clause)
    5667              : {
    5668          105 :   go_assert(this->peek_token()->is_keyword(KEYWORD_RANGE));
    5669              : 
    5670          105 :   p_range_clause->found = true;
    5671              : 
    5672          105 :   go_assert(vals->size() >= 1);
    5673          105 :   if (vals->size() > 2)
    5674            0 :     go_error_at(this->location(), "too many variables for range clause");
    5675              : 
    5676          105 :   this->advance_token();
    5677          105 :   p_range_clause->range = this->expression(PRECEDENCE_NORMAL, false, false,
    5678              :                                            NULL, NULL);
    5679              : 
    5680          105 :   if (vals->empty())
    5681              :     return;
    5682              : 
    5683          105 :   p_range_clause->index = vals->front();
    5684          105 :   if (vals->size() == 1)
    5685           19 :     p_range_clause->value = NULL;
    5686              :   else
    5687           86 :     p_range_clause->value = vals->back();
    5688              : }
    5689              : 
    5690              : // Push a statement on the break stack.
    5691              : 
    5692              : void
    5693        70053 : Parse::push_break_statement(Statement* enclosing, Label* label)
    5694              : {
    5695        70053 :   if (this->break_stack_ == NULL)
    5696        10774 :     this->break_stack_ = new Bc_stack();
    5697        70053 :   this->break_stack_->push_back(std::make_pair(enclosing, label));
    5698        70053 : }
    5699              : 
    5700              : // Push a statement on the continue stack.
    5701              : 
    5702              : void
    5703        53818 : Parse::push_continue_statement(Statement* enclosing, Label* label)
    5704              : {
    5705        53818 :   if (this->continue_stack_ == NULL)
    5706         9326 :     this->continue_stack_ = new Bc_stack();
    5707        53818 :   this->continue_stack_->push_back(std::make_pair(enclosing, label));
    5708        53818 : }
    5709              : 
    5710              : // Pop the break stack.
    5711              : 
    5712              : void
    5713        70052 : Parse::pop_break_statement()
    5714              : {
    5715        70052 :   this->break_stack_->pop_back();
    5716        70052 : }
    5717              : 
    5718              : // Pop the continue stack.
    5719              : 
    5720              : void
    5721        53818 : Parse::pop_continue_statement()
    5722              : {
    5723        53818 :   this->continue_stack_->pop_back();
    5724        53818 : }
    5725              : 
    5726              : // Find a break or continue statement given a label name.
    5727              : 
    5728              : Statement*
    5729         1363 : Parse::find_bc_statement(const Bc_stack* bc_stack, const std::string& label)
    5730              : {
    5731         1363 :   if (bc_stack == NULL)
    5732              :     return NULL;
    5733         2486 :   for (Bc_stack::const_reverse_iterator p = bc_stack->rbegin();
    5734         2486 :        p != bc_stack->rend();
    5735         1123 :        ++p)
    5736              :     {
    5737         2469 :       if (p->second != NULL && p->second->name() == label)
    5738              :         {
    5739         1346 :           p->second->set_is_used();
    5740         1346 :           return p->first;
    5741              :         }
    5742              :     }
    5743              :   return NULL;
    5744              : }
    5745              : 
    5746              : // BreakStat = "break" [ identifier ] .
    5747              : 
    5748              : void
    5749         8057 : Parse::break_stat()
    5750              : {
    5751         8057 :   go_assert(this->peek_token()->is_keyword(KEYWORD_BREAK));
    5752         8057 :   Location location = this->location();
    5753              : 
    5754         8057 :   const Token* token = this->advance_token();
    5755         8057 :   Statement* enclosing;
    5756         8057 :   if (!token->is_identifier())
    5757              :     {
    5758         7225 :       if (this->break_stack_ == NULL || this->break_stack_->empty())
    5759              :         {
    5760            1 :           go_error_at(this->location(),
    5761              :                       "break statement not within for or switch or select");
    5762           10 :           return;
    5763              :         }
    5764         7224 :       enclosing = this->break_stack_->back().first;
    5765              :     }
    5766              :   else
    5767              :     {
    5768          832 :       enclosing = this->find_bc_statement(this->break_stack_,
    5769              :                                           token->identifier());
    5770          832 :       if (enclosing == NULL)
    5771              :         {
    5772              :           // If there is a label with this name, mark it as used to
    5773              :           // avoid a useless error about an unused label.
    5774            8 :           this->gogo_->add_label_reference(token->identifier(),
    5775              :                                            Linemap::unknown_location(), false);
    5776              : 
    5777            8 :           go_error_at(token->location(), "invalid break label %qs",
    5778            8 :                       Gogo::message_name(token->identifier()).c_str());
    5779            8 :           this->advance_token();
    5780            8 :           return;
    5781              :         }
    5782          824 :       this->advance_token();
    5783              :     }
    5784              : 
    5785         8048 :   Unnamed_label* label;
    5786         8048 :   if (enclosing->classification() == Statement::STATEMENT_FOR)
    5787         5391 :     label = enclosing->for_statement()->break_label();
    5788              :   else if (enclosing->classification() == Statement::STATEMENT_FOR_RANGE)
    5789         1426 :     label = enclosing->for_range_statement()->break_label();
    5790              :   else if (enclosing->classification() == Statement::STATEMENT_SWITCH)
    5791          968 :     label = enclosing->switch_statement()->break_label();
    5792              :   else if (enclosing->classification() == Statement::STATEMENT_TYPE_SWITCH)
    5793          197 :     label = enclosing->type_switch_statement()->break_label();
    5794              :   else if (enclosing->classification() == Statement::STATEMENT_SELECT)
    5795           66 :     label = enclosing->select_statement()->break_label();
    5796              :   else
    5797            0 :     go_unreachable();
    5798              : 
    5799         8048 :   this->gogo_->add_statement(Statement::make_break_statement(label,
    5800              :                                                              location));
    5801              : }
    5802              : 
    5803              : // ContinueStat = "continue" [ identifier ] .
    5804              : 
    5805              : void
    5806        10807 : Parse::continue_stat()
    5807              : {
    5808        10807 :   go_assert(this->peek_token()->is_keyword(KEYWORD_CONTINUE));
    5809        10807 :   Location location = this->location();
    5810              : 
    5811        10807 :   const Token* token = this->advance_token();
    5812        10807 :   Statement* enclosing;
    5813        10807 :   if (!token->is_identifier())
    5814              :     {
    5815        10276 :       if (this->continue_stack_ == NULL || this->continue_stack_->empty())
    5816              :         {
    5817            3 :           go_error_at(this->location(), "continue statement not within for");
    5818           15 :           return;
    5819              :         }
    5820        10273 :       enclosing = this->continue_stack_->back().first;
    5821              :     }
    5822              :   else
    5823              :     {
    5824          531 :       enclosing = this->find_bc_statement(this->continue_stack_,
    5825              :                                           token->identifier());
    5826          531 :       if (enclosing == NULL)
    5827              :         {
    5828              :           // If there is a label with this name, mark it as used to
    5829              :           // avoid a useless error about an unused label.
    5830            9 :           this->gogo_->add_label_reference(token->identifier(),
    5831              :                                            Linemap::unknown_location(), false);
    5832              : 
    5833            9 :           go_error_at(token->location(), "invalid continue label %qs",
    5834            9 :                       Gogo::message_name(token->identifier()).c_str());
    5835            9 :           this->advance_token();
    5836            9 :           return;
    5837              :         }
    5838          522 :       this->advance_token();
    5839              :     }
    5840              : 
    5841        10795 :   Unnamed_label* label;
    5842        10795 :   if (enclosing->classification() == Statement::STATEMENT_FOR)
    5843         4887 :     label = enclosing->for_statement()->continue_label();
    5844         5908 :   else if (enclosing->classification() == Statement::STATEMENT_FOR_RANGE)
    5845         5908 :     label = enclosing->for_range_statement()->continue_label();
    5846              :   else
    5847            0 :     go_unreachable();
    5848              : 
    5849        10795 :   this->gogo_->add_statement(Statement::make_continue_statement(label,
    5850              :                                                                 location));
    5851              : }
    5852              : 
    5853              : // GotoStat = "goto" identifier .
    5854              : 
    5855              : void
    5856         2101 : Parse::goto_stat()
    5857              : {
    5858         2101 :   go_assert(this->peek_token()->is_keyword(KEYWORD_GOTO));
    5859         2101 :   Location location = this->location();
    5860         2101 :   const Token* token = this->advance_token();
    5861         2101 :   if (!token->is_identifier())
    5862            0 :     go_error_at(this->location(), "expected label for goto");
    5863              :   else
    5864              :     {
    5865         2101 :       Label* label = this->gogo_->add_label_reference(token->identifier(),
    5866              :                                                       location, true);
    5867         2101 :       Statement* s = Statement::make_goto_statement(label, location);
    5868         2101 :       this->gogo_->add_statement(s);
    5869         2101 :       this->advance_token();
    5870              :     }
    5871         2101 : }
    5872              : 
    5873              : // PackageClause = "package" PackageName .
    5874              : 
    5875              : void
    5876        12707 : Parse::package_clause()
    5877              : {
    5878        12707 :   const Token* token = this->peek_token();
    5879        12707 :   Location location = token->location();
    5880        12707 :   std::string name;
    5881        12707 :   if (!token->is_keyword(KEYWORD_PACKAGE))
    5882              :     {
    5883            2 :       go_error_at(this->location(), "program must start with package clause");
    5884            2 :       name = "ERROR";
    5885              :     }
    5886              :   else
    5887              :     {
    5888        12705 :       token = this->advance_token();
    5889        12705 :       if (token->is_identifier())
    5890              :         {
    5891        12704 :           name = token->identifier();
    5892        12704 :           if (name == "_")
    5893              :             {
    5894            1 :               go_error_at(this->location(), "invalid package name %<_%>");
    5895            1 :               name = Gogo::erroneous_name();
    5896              :             }
    5897        12704 :           this->advance_token();
    5898              :         }
    5899              :       else
    5900              :         {
    5901            1 :           go_error_at(this->location(), "package name must be an identifier");
    5902            1 :           name = "ERROR";
    5903              :         }
    5904              :     }
    5905        12707 :   this->gogo_->set_package_name(name, location);
    5906        12707 : }
    5907              : 
    5908              : // ImportDecl = "import" Decl<ImportSpec> .
    5909              : 
    5910              : void
    5911        10686 : Parse::import_decl()
    5912              : {
    5913        10686 :   go_assert(this->peek_token()->is_keyword(KEYWORD_IMPORT));
    5914        10686 :   this->advance_token();
    5915        10686 :   this->decl(&Parse::import_spec);
    5916        10686 : }
    5917              : 
    5918              : // ImportSpec = [ "." | PackageName ] PackageFileName .
    5919              : 
    5920              : void
    5921        40358 : Parse::import_spec()
    5922              : {
    5923        40358 :   this->check_directives();
    5924              : 
    5925        40358 :   const Token* token = this->peek_token();
    5926        40358 :   Location location = token->location();
    5927              : 
    5928        40358 :   std::string local_name;
    5929        40358 :   bool is_local_name_exported = false;
    5930        40358 :   if (token->is_op(OPERATOR_DOT))
    5931              :     {
    5932          339 :       local_name = ".";
    5933          339 :       token = this->advance_token();
    5934              :     }
    5935        40019 :   else if (token->is_identifier())
    5936              :     {
    5937         1289 :       local_name = token->identifier();
    5938         1289 :       is_local_name_exported = token->is_identifier_exported();
    5939         1289 :       token = this->advance_token();
    5940              :     }
    5941              : 
    5942        40358 :   if (!token->is_string())
    5943              :     {
    5944            5 :       go_error_at(this->location(), "import path must be a string");
    5945            5 :       this->advance_token();
    5946            5 :       return;
    5947              :     }
    5948              : 
    5949        40353 :   this->gogo_->import_package(token->string_value(), local_name,
    5950              :                               is_local_name_exported, true, location);
    5951              : 
    5952        40353 :   this->advance_token();
    5953        40358 : }
    5954              : 
    5955              : // SourceFile       = PackageClause ";" { ImportDecl ";" }
    5956              : //                      { TopLevelDecl ";" } .
    5957              : 
    5958              : void
    5959        12707 : Parse::program()
    5960              : {
    5961        12707 :   this->package_clause();
    5962              : 
    5963        12707 :   const Token* token = this->peek_token();
    5964        12707 :   if (token->is_op(OPERATOR_SEMICOLON))
    5965        12704 :     token = this->advance_token();
    5966              :   else
    5967            3 :     go_error_at(this->location(),
    5968              :                 "expected %<;%> or newline after package clause");
    5969              : 
    5970        23393 :   while (token->is_keyword(KEYWORD_IMPORT))
    5971              :     {
    5972        10686 :       this->import_decl();
    5973        10686 :       token = this->peek_token();
    5974        10686 :       if (token->is_op(OPERATOR_SEMICOLON))
    5975        10686 :         token = this->advance_token();
    5976              :       else
    5977            0 :         go_error_at(this->location(),
    5978              :                     "expected %<;%> or newline after import declaration");
    5979              :     }
    5980              : 
    5981       306773 :   while (!token->is_eof())
    5982              :     {
    5983       294066 :       if (this->declaration_may_start_here())
    5984       294054 :         this->declaration();
    5985              :       else
    5986              :         {
    5987           12 :           go_error_at(this->location(), "expected declaration");
    5988           12 :           this->gogo_->mark_locals_used();
    5989           35 :           do
    5990           35 :             this->advance_token();
    5991           35 :           while (!this->peek_token()->is_eof()
    5992           34 :                  && !this->peek_token()->is_op(OPERATOR_SEMICOLON)
    5993           82 :                  && !this->peek_token()->is_op(OPERATOR_RCURLY));
    5994           12 :           if (!this->peek_token()->is_eof()
    5995           12 :               && !this->peek_token()->is_op(OPERATOR_SEMICOLON))
    5996            1 :             this->advance_token();
    5997              :         }
    5998       294066 :       token = this->peek_token();
    5999       294066 :       if (token->is_op(OPERATOR_SEMICOLON))
    6000       294049 :         token = this->advance_token();
    6001           17 :       else if (!token->is_eof() || !saw_errors())
    6002              :         {
    6003            4 :           if (token->is_op(OPERATOR_CHANOP))
    6004            1 :             go_error_at(this->location(),
    6005              :                         ("send statement used as value; "
    6006              :                          "use select for non-blocking send"));
    6007              :           else
    6008            3 :             go_error_at(this->location(),
    6009              :                         ("expected %<;%> or newline after top "
    6010              :                          "level declaration"));
    6011            4 :           this->skip_past_error(OPERATOR_INVALID);
    6012              :         }
    6013              :     }
    6014              : 
    6015        12707 :   this->check_directives();
    6016        12707 : }
    6017              : 
    6018              : // If there are any pending compiler directives, clear them and give
    6019              : // an error.  This is called when directives are not permitted.
    6020              : 
    6021              : void
    6022       449348 : Parse::check_directives()
    6023              : {
    6024       449348 :   if (this->lex_->get_and_clear_pragmas() != 0)
    6025            0 :     go_error_at(this->location(), "misplaced compiler directive");
    6026       449348 :   if (this->lex_->has_embeds())
    6027              :     {
    6028            0 :       this->lex_->clear_embeds();
    6029            0 :       go_error_at(this->location(), "misplaced go:embed directive");
    6030              :     }
    6031       449348 : }
    6032              : 
    6033              : // Skip forward to a semicolon or OP.  OP will normally be
    6034              : // OPERATOR_RPAREN or OPERATOR_RCURLY.  If we find a semicolon, move
    6035              : // past it and return.  If we find OP, it will be the next token to
    6036              : // read.  Return true if we are OK, false if we found EOF.
    6037              : 
    6038              : bool
    6039           22 : Parse::skip_past_error(Operator op)
    6040              : {
    6041           22 :   this->gogo_->mark_locals_used();
    6042           22 :   const Token* token = this->peek_token();
    6043           77 :   while (!token->is_op(op))
    6044              :     {
    6045           50 :       if (token->is_eof())
    6046              :         return false;
    6047           41 :       if (token->is_op(OPERATOR_SEMICOLON))
    6048              :         {
    6049            8 :           this->advance_token();
    6050            8 :           return true;
    6051              :         }
    6052           33 :       token = this->advance_token();
    6053              :     }
    6054              :   return true;
    6055              : }
    6056              : 
    6057              : // Check that an expression is not a sink.
    6058              : 
    6059              : Expression*
    6060      2827445 : Parse::verify_not_sink(Expression* expr)
    6061              : {
    6062      2827445 :   if (expr->is_sink_expression())
    6063              :     {
    6064            1 :       go_error_at(expr->location(), "cannot use %<_%> as value");
    6065            1 :       expr = Expression::make_error(expr->location());
    6066              :     }
    6067              : 
    6068              :   // If this can not be a sink, and it is a variable, then we are
    6069              :   // using the variable, not just assigning to it.
    6070      2827445 :   if (expr->var_expression() != NULL)
    6071      1002913 :     this->mark_var_used(expr->var_expression()->named_object());
    6072      1824532 :   else if (expr->enclosed_var_expression() != NULL)
    6073        26154 :     this->mark_var_used(expr->enclosed_var_expression()->variable());
    6074      2827445 :   return expr;
    6075              : }
    6076              : 
    6077              : // Mark a variable as used.
    6078              : 
    6079              : void
    6080      2435801 : Parse::mark_var_used(Named_object* no)
    6081              : {
    6082      2435801 :   if (no->is_variable())
    6083      2403346 :     no->var_value()->set_is_used();
    6084      2435801 : }
        

Generated by: LCOV version 2.4-beta

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