Branch data 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 : 12706 : Parse::Parse(Lex* lex, Gogo* gogo)
45 : 12706 : : lex_(lex),
46 : 12706 : token_(Token::make_invalid_token(Linemap::unknown_location())),
47 : 12706 : unget_token_(Token::make_invalid_token(Linemap::unknown_location())),
48 : 12706 : unget_token_valid_(false),
49 : 12706 : is_erroneous_function_(false),
50 : 12706 : gogo_(gogo),
51 : 12706 : break_stack_(NULL),
52 : 12706 : continue_stack_(NULL),
53 : 12706 : enclosing_vars_()
54 : : {
55 : 12706 : }
56 : :
57 : : // Return the current token.
58 : :
59 : : const Token*
60 : 60180382 : Parse::peek_token()
61 : : {
62 : 60180382 : if (this->unget_token_valid_)
63 : 4355638 : return &this->unget_token_;
64 : 55824744 : if (this->token_.is_invalid())
65 : 12706 : this->token_ = this->lex_->next_token();
66 : 55824744 : return &this->token_;
67 : : }
68 : :
69 : : // Advance to the next token and return it.
70 : :
71 : : const Token*
72 : 21714152 : Parse::advance_token()
73 : : {
74 : 21714152 : if (this->unget_token_valid_)
75 : : {
76 : 1999935 : this->unget_token_valid_ = false;
77 : 1999935 : if (!this->token_.is_invalid())
78 : 1999935 : return &this->token_;
79 : : }
80 : 19714217 : this->token_ = this->lex_->next_token();
81 : 19714217 : return &this->token_;
82 : : }
83 : :
84 : : // Push a token back on the input stream.
85 : :
86 : : void
87 : 1999935 : Parse::unget_token(const Token& token)
88 : : {
89 : 1999935 : go_assert(!this->unget_token_valid_);
90 : 1999935 : this->unget_token_ = token;
91 : 1999935 : this->unget_token_valid_ = true;
92 : 1999935 : }
93 : :
94 : : // The location of the current token.
95 : :
96 : : Location
97 : 9322350 : Parse::location()
98 : : {
99 : 9322350 : return this->peek_token()->location();
100 : : }
101 : :
102 : : // IdentifierList = identifier { "," identifier } .
103 : :
104 : : void
105 : 446656 : Parse::identifier_list(Typed_identifier_list* til)
106 : : {
107 : 446656 : const Token* token = this->peek_token();
108 : 463566 : while (true)
109 : : {
110 : 455111 : if (!token->is_identifier())
111 : : {
112 : 1 : go_error_at(this->location(), "expected identifier");
113 : 1 : return;
114 : : }
115 : 455110 : std::string name =
116 : 455110 : this->gogo_->pack_hidden_name(token->identifier(),
117 : 455110 : token->is_identifier_exported());
118 : 455110 : til->push_back(Typed_identifier(name, NULL, token->location()));
119 : 455110 : token = this->advance_token();
120 : 455110 : if (!token->is_op(OPERATOR_COMMA))
121 : 446655 : return;
122 : 8455 : token = this->advance_token();
123 : 455110 : }
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 : 1554026 : Parse::expression_list(Expression* first, bool may_be_sink,
135 : : bool may_be_composite_lit)
136 : : {
137 : 1554026 : Expression_list* ret = new Expression_list();
138 : 1554026 : if (first != NULL)
139 : 3094 : ret->push_back(first);
140 : 2134939 : while (true)
141 : : {
142 : 2134939 : ret->push_back(this->expression(PRECEDENCE_NORMAL, may_be_sink,
143 : : may_be_composite_lit, NULL, NULL));
144 : :
145 : 2134939 : const Token* token = this->peek_token();
146 : 2134939 : if (!token->is_op(OPERATOR_COMMA))
147 : 1554026 : 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 : 575398 : Parse::qualified_ident(std::string* pname, Named_object** ppackage)
171 : : {
172 : 575398 : const Token* token = this->peek_token();
173 : 575398 : if (!token->is_identifier())
174 : : {
175 : 0 : go_error_at(this->location(), "expected identifier");
176 : 0 : return false;
177 : : }
178 : :
179 : 575398 : std::string name = token->identifier();
180 : 575398 : bool is_exported = token->is_identifier_exported();
181 : 575398 : name = this->gogo_->pack_hidden_name(name, is_exported);
182 : :
183 : 575398 : token = this->advance_token();
184 : 575398 : if (!token->is_op(OPERATOR_DOT))
185 : : {
186 : 493390 : *pname = name;
187 : 493390 : *ppackage = NULL;
188 : 493390 : 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 : 575398 : }
233 : :
234 : : // Type = TypeName | TypeLit | "(" Type ")" .
235 : : // TypeLit =
236 : : // ArrayType | StructType | PointerType | FunctionType | InterfaceType |
237 : : // SliceType | MapType | ChannelType .
238 : :
239 : : Type*
240 : 804148 : Parse::type()
241 : : {
242 : 804148 : const Token* token = this->peek_token();
243 : 804148 : if (token->is_identifier())
244 : 558178 : return this->type_name(true);
245 : 245970 : else if (token->is_op(OPERATOR_LSQUARE))
246 : 57496 : return this->array_type(false);
247 : 232258 : else if (token->is_keyword(KEYWORD_CHAN)
248 : 188474 : || token->is_op(OPERATOR_CHANOP))
249 : 4761 : return this->channel_type();
250 : 183713 : else if (token->is_keyword(KEYWORD_INTERFACE))
251 : 3139 : return this->interface_type(true);
252 : 180574 : 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 : 174959 : else if (token->is_keyword(KEYWORD_MAP))
262 : 9939 : return this->map_type();
263 : 165020 : else if (token->is_keyword(KEYWORD_STRUCT))
264 : 25090 : 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 : 296361 : Parse::type_may_start_here()
289 : : {
290 : 296361 : const Token* token = this->peek_token();
291 : 296361 : return (token->is_identifier()
292 : 213839 : || token->is_op(OPERATOR_LSQUARE)
293 : 213733 : || token->is_op(OPERATOR_CHANOP)
294 : 213608 : || token->is_keyword(KEYWORD_CHAN)
295 : 213428 : || token->is_keyword(KEYWORD_INTERFACE)
296 : 213130 : || token->is_keyword(KEYWORD_FUNC)
297 : 212940 : || token->is_keyword(KEYWORD_MAP)
298 : 211892 : || token->is_keyword(KEYWORD_STRUCT)
299 : 204524 : || token->is_op(OPERATOR_MULT)
300 : 296361 : || 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 : 575398 : Parse::type_name(bool issue_error)
310 : : {
311 : 575398 : Location location = this->location();
312 : :
313 : 575398 : std::string name;
314 : 575398 : Named_object* package;
315 : 575398 : if (!this->qualified_ident(&name, &package))
316 : 5 : return Type::make_error_type();
317 : :
318 : 575393 : Named_object* named_object;
319 : 575393 : if (package == NULL)
320 : 493390 : 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 : 575393 : bool ok = true;
346 : 575393 : 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 : 555199 : else if (named_object->is_type())
361 : : {
362 : 216933 : if (!named_object->type_value()->is_visible())
363 : : ok = false;
364 : : }
365 : 338266 : 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 : 575385 : if (named_object->is_type())
378 : 216932 : return named_object->type_value();
379 : 358453 : else if (named_object->is_unknown() || named_object->is_type_declaration())
380 : 358453 : return Type::make_forward_declaration(named_object);
381 : : else
382 : 0 : go_unreachable();
383 : 575398 : }
384 : :
385 : : // ArrayType = "[" [ ArrayLength ] "]" ElementType .
386 : : // ArrayLength = Expression .
387 : : // ElementType = CompleteType .
388 : :
389 : : Type*
390 : 106345 : Parse::array_type(bool may_use_ellipsis)
391 : : {
392 : 106345 : go_assert(this->peek_token()->is_op(OPERATOR_LSQUARE));
393 : 106345 : const Token* token = this->advance_token();
394 : :
395 : 106345 : Expression* length = NULL;
396 : 106345 : if (token->is_op(OPERATOR_RSQUARE))
397 : 87091 : this->advance_token();
398 : : else
399 : : {
400 : 19254 : if (!token->is_op(OPERATOR_ELLIPSIS))
401 : 18379 : 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 : 19254 : 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 : 19254 : this->advance_token();
424 : : }
425 : :
426 : 106345 : Type* element_type = this->type();
427 : 106345 : if (element_type->is_error_type())
428 : 0 : return Type::make_error_type();
429 : :
430 : 106345 : 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 : 25090 : Parse::struct_type()
470 : : {
471 : 25090 : go_assert(this->peek_token()->is_keyword(KEYWORD_STRUCT));
472 : 25090 : Location location = this->location();
473 : 25090 : 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 : 25090 : this->advance_token();
486 : :
487 : 25090 : Struct_field_list* sfl = new Struct_field_list;
488 : 137688 : while (!this->peek_token()->is_op(OPERATOR_RCURLY))
489 : : {
490 : 87508 : this->field_decl(sfl);
491 : 87508 : if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
492 : 86485 : this->advance_token();
493 : 113621 : 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 : 25090 : this->advance_token();
501 : :
502 : 25090 : for (Struct_field_list::const_iterator pi = sfl->begin();
503 : 115636 : pi != sfl->end();
504 : : ++pi)
505 : : {
506 : 90549 : if (pi->type()->is_error_type())
507 : 3 : return pi->type();
508 : 495229 : for (Struct_field_list::const_iterator pj = pi + 1;
509 : 495229 : pj != sfl->end();
510 : 404683 : ++pj)
511 : : {
512 : 404683 : if (pi->field_name() == pj->field_name()
513 : 404683 : && !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 : 25087 : return Type::make_struct_type(sfl, location);
520 : : }
521 : :
522 : : // FieldDecl = (IdentifierList CompleteType | TypeName) [ Tag ] .
523 : : // Tag = string_lit .
524 : :
525 : : void
526 : 87508 : Parse::field_decl(Struct_field_list* sfl)
527 : : {
528 : 87508 : const Token* token = this->peek_token();
529 : 87508 : Location location = token->location();
530 : 87508 : bool is_anonymous;
531 : 87508 : bool is_anonymous_pointer;
532 : 87508 : if (token->is_op(OPERATOR_MULT))
533 : : {
534 : : is_anonymous = true;
535 : : is_anonymous_pointer = true;
536 : : }
537 : 86884 : else if (token->is_identifier())
538 : : {
539 : 86882 : std::string id = token->identifier();
540 : 86882 : bool is_id_exported = token->is_identifier_exported();
541 : 86882 : Location id_location = token->location();
542 : 86882 : token = this->advance_token();
543 : 108563 : is_anonymous = (token->is_op(OPERATOR_SEMICOLON)
544 : 84775 : || token->is_op(OPERATOR_RCURLY)
545 : 171013 : || token->is_op(OPERATOR_DOT)
546 : 84131 : || token->is_string());
547 : 86882 : is_anonymous_pointer = false;
548 : 86882 : this->unget_token(Token::make_identifier_token(id, is_id_exported,
549 : : id_location));
550 : 86882 : }
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 : 87515 : && !token->is_op(OPERATOR_RCURLY)
557 : 16 : && !token->is_eof())
558 : 7 : token = this->advance_token();
559 : 87508 : return;
560 : : }
561 : :
562 : 87506 : 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 : 3388 : 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 : 84115 : Typed_identifier_list til;
599 : 90209 : while (true)
600 : : {
601 : 87162 : token = this->peek_token();
602 : 87162 : if (!token->is_identifier())
603 : : {
604 : 0 : go_error_at(this->location(), "expected identifier");
605 : 0 : return;
606 : : }
607 : 87162 : std::string name =
608 : 87162 : this->gogo_->pack_hidden_name(token->identifier(),
609 : 87162 : token->is_identifier_exported());
610 : 87162 : til.push_back(Typed_identifier(name, NULL, token->location()));
611 : 106186 : if (!this->advance_token()->is_op(OPERATOR_COMMA))
612 : : break;
613 : 3047 : this->advance_token();
614 : 3047 : }
615 : :
616 : 84115 : Type* type = this->type();
617 : :
618 : 84115 : std::string tag;
619 : 84115 : if (this->peek_token()->is_string())
620 : : {
621 : 1743 : tag = this->peek_token()->string_value();
622 : 1743 : this->advance_token();
623 : : }
624 : :
625 : 171277 : for (Typed_identifier_list::iterator p = til.begin();
626 : 171277 : p != til.end();
627 : 87162 : ++p)
628 : : {
629 : 87162 : p->set_type(type);
630 : 87162 : sfl->push_back(Struct_field(*p));
631 : 87162 : if (!tag.empty())
632 : 1742 : sfl->back().set_tag(tag);
633 : : }
634 : 84115 : }
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(¶ms, &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 : 18447 : 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 : 22276 : 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 : 18730 : 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 : 12429 : 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 : 11342 : 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 : 22956 : 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 : 72353 : 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 : 3948 : 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 : 631 : methods->push_back(Typed_identifier("", type, location));
1305 : : }
1306 : 4586 : }
1307 : :
1308 : : // Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
1309 : :
1310 : : void
1311 : 350220 : Parse::declaration()
1312 : : {
1313 : 350220 : const Token* token = this->peek_token();
1314 : 350220 : if (token->is_keyword(KEYWORD_CONST))
1315 : 117685 : this->const_decl();
1316 : 232535 : else if (token->is_keyword(KEYWORD_TYPE))
1317 : 31323 : 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 : 350220 : }
1328 : :
1329 : : bool
1330 : 291460 : Parse::declaration_may_start_here()
1331 : : {
1332 : 291460 : const Token* token = this->peek_token();
1333 : 469157 : return (token->is_keyword(KEYWORD_CONST)
1334 : 147593 : || token->is_keyword(KEYWORD_TYPE)
1335 : 128976 : || token->is_keyword(KEYWORD_VAR)
1336 : 291460 : || token->is_keyword(KEYWORD_FUNC));
1337 : : }
1338 : :
1339 : : // Decl<P> = P | "(" [ List<P> ] ")" .
1340 : :
1341 : : void
1342 : 114257 : Parse::decl(void (Parse::*pfn)())
1343 : : {
1344 : 114257 : 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 : 114255 : if (!this->peek_token()->is_op(OPERATOR_LPAREN))
1352 : 105006 : (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 : 57158 : 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 : 117685 : Parse::const_decl()
1406 : : {
1407 : 117685 : go_assert(this->peek_token()->is_keyword(KEYWORD_CONST));
1408 : 117685 : this->advance_token();
1409 : :
1410 : 117685 : int iota = 0;
1411 : 117685 : Type* last_type = NULL;
1412 : 117685 : Expression_list* last_expr_list = NULL;
1413 : :
1414 : 117685 : if (!this->peek_token()->is_op(OPERATOR_LPAREN))
1415 : 113690 : 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 : 117685 : if (last_expr_list != NULL)
1437 : 117682 : delete last_expr_list;
1438 : : }
1439 : :
1440 : : // ConstSpec = IdentifierList [ [ CompleteType ] "=" ExpressionList ] .
1441 : :
1442 : : void
1443 : 152150 : Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list)
1444 : : {
1445 : 152150 : this->check_directives();
1446 : :
1447 : 152150 : Location loc = this->location();
1448 : 152150 : Typed_identifier_list til;
1449 : 152150 : this->identifier_list(&til);
1450 : :
1451 : 152150 : Type* type = NULL;
1452 : 152150 : 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 : 152150 : Expression_list *expr_list;
1460 : 152150 : 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(©);
1476 : 9085 : expr_list->push_back(copy);
1477 : : }
1478 : : }
1479 : : else
1480 : : {
1481 : 143065 : this->advance_token();
1482 : 143065 : expr_list = this->expression_list(NULL, false, true);
1483 : 143065 : *last_type = type;
1484 : 143065 : if (*last_expr_list != NULL)
1485 : 12399 : delete *last_expr_list;
1486 : 143065 : *last_expr_list = expr_list;
1487 : : }
1488 : :
1489 : 152149 : Expression_list::const_iterator pe = expr_list->begin();
1490 : 152149 : for (Typed_identifier_list::iterator pi = til.begin();
1491 : 304359 : pi != til.end();
1492 : 152210 : ++pi, ++pe)
1493 : : {
1494 : 152210 : if (pe == expr_list->end())
1495 : : {
1496 : 0 : go_error_at(this->location(), "not enough initializers");
1497 : 0 : return;
1498 : : }
1499 : 152210 : if (type != NULL)
1500 : 22007 : pi->set_type(type);
1501 : :
1502 : 152210 : if (!Gogo::is_sink_name(pi->name()))
1503 : 151001 : 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 : 1209 : 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 : 152149 : if (pe != expr_list->end())
1516 : 0 : go_error_at(this->location(), "too many initializers");
1517 : :
1518 : : return;
1519 : 152150 : }
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 : 31323 : Parse::type_decl()
1613 : : {
1614 : 31323 : go_assert(this->peek_token()->is_keyword(KEYWORD_TYPE));
1615 : 31323 : this->advance_token();
1616 : 31323 : this->decl(&Parse::type_spec);
1617 : 31323 : }
1618 : :
1619 : : // TypeSpec = identifier ["="] Type .
1620 : :
1621 : : void
1622 : 32015 : Parse::type_spec()
1623 : : {
1624 : 32015 : unsigned int pragmas = this->lex_->get_and_clear_pragmas();
1625 : 32015 : this->check_directives();
1626 : :
1627 : 32015 : const Token* token = this->peek_token();
1628 : 32015 : if (!token->is_identifier())
1629 : : {
1630 : 0 : go_error_at(this->location(), "expected identifier");
1631 : 0 : return;
1632 : : }
1633 : 32015 : std::string name = token->identifier();
1634 : 32015 : bool is_exported = token->is_identifier_exported();
1635 : 32015 : Location location = token->location();
1636 : 32015 : token = this->advance_token();
1637 : :
1638 : 32015 : bool is_alias = false;
1639 : 32015 : 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 : 32015 : Named_object* named_type = NULL;
1649 : 32015 : if (name != "_")
1650 : : {
1651 : 31951 : name = this->gogo_->pack_hidden_name(name, is_exported);
1652 : 31951 : named_type = this->gogo_->declare_type(name, location);
1653 : : }
1654 : :
1655 : 32015 : Type* type;
1656 : 32015 : 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 : 32012 : else if (!token->is_op(OPERATOR_SEMICOLON))
1663 : 32010 : 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 : 32015 : 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 : 32015 : if (name != "_")
1680 : : {
1681 : 31951 : if (named_type->is_type_declaration())
1682 : : {
1683 : 31951 : Type* ftype = type->forwarded();
1684 : 31951 : if (ftype->forward_declaration_type() != NULL
1685 : 6760 : && (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 : 31951 : Named_type* nt = Type::make_named_type(named_type, type, location);
1693 : 31951 : if (is_alias)
1694 : 301 : nt->set_is_alias();
1695 : :
1696 : 31951 : this->gogo_->define_type(named_type, nt);
1697 : 31951 : go_assert(named_type->package() == NULL);
1698 : :
1699 : 31951 : if ((pragmas & GOPRAGMA_NOTINHEAP) != 0)
1700 : : {
1701 : 203 : nt->set_not_in_heap();
1702 : 203 : pragmas &= ~GOPRAGMA_NOTINHEAP;
1703 : : }
1704 : 31951 : 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 : 32015 : }
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 : 309872 : 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 : 264867 : 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 : 281931 : 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 : 72487 : 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 : 11807 : 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 : 4921700 : Parse::operand(bool may_be_sink, bool* is_parenthesized)
2669 : : {
2670 : 4921700 : const Token* token = this->peek_token();
2671 : 4921700 : Expression* ret;
2672 : 4921700 : switch (token->classification())
2673 : : {
2674 : 3044653 : case Token::TOKEN_IDENTIFIER:
2675 : 3044653 : {
2676 : 3044653 : Location location = token->location();
2677 : 3044653 : std::string id = token->identifier();
2678 : 3044653 : bool is_exported = token->is_identifier_exported();
2679 : 3044653 : std::string packed = this->gogo_->pack_hidden_name(id, is_exported);
2680 : :
2681 : 3044653 : Named_object* in_function;
2682 : 3044653 : Named_object* named_object = this->gogo_->lookup(packed, &in_function);
2683 : :
2684 : 3044653 : Package* package = NULL;
2685 : 3044653 : 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 : 3044651 : this->advance_token();
2704 : :
2705 : 3044651 : if (named_object != NULL
2706 : 2979971 : && named_object->is_type()
2707 : 3115036 : && !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 : 3044651 : if (named_object == NULL)
2718 : : {
2719 : 64680 : 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 : 64668 : named_object = this->gogo_->add_unknown_name(packed, location);
2736 : : }
2737 : :
2738 : 3044639 : if (in_function != NULL
2739 : 1830525 : && in_function != this->gogo_->current_function()
2740 : 3086956 : && (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 : 3003449 : switch (named_object->classification())
2746 : : {
2747 : 165519 : case Named_object::NAMED_OBJECT_CONST:
2748 : 165519 : 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 : 586311 : case Named_object::NAMED_OBJECT_UNKNOWN:
2776 : 586311 : {
2777 : 586311 : Unknown_expression* ue =
2778 : 586311 : Expression::make_unknown_reference(named_object, location);
2779 : 586311 : 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 : 3044653 : }
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 : 1259798 : case Token::TOKEN_INTEGER:
2803 : 1259798 : ret = Expression::make_integer_z(token->integer_value(), NULL,
2804 : : token->location());
2805 : 1259798 : this->advance_token();
2806 : 1259798 : 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 : 93994 : case Token::TOKEN_OPERATOR:
2847 : 93994 : if (token->is_op(OPERATOR_LPAREN))
2848 : : {
2849 : 45137 : this->advance_token();
2850 : 45137 : ret = this->expression(PRECEDENCE_NORMAL, may_be_sink, true, NULL,
2851 : : NULL);
2852 : 45137 : if (!this->peek_token()->is_op(OPERATOR_RPAREN))
2853 : 0 : go_error_at(this->location(), "missing %<)%>");
2854 : : else
2855 : 45137 : this->advance_token();
2856 : 45137 : if (is_parenthesized != NULL)
2857 : 45137 : *is_parenthesized = true;
2858 : 45137 : 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 : 4921700 : Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
3241 : : bool* is_type_switch, bool* is_parenthesized)
3242 : : {
3243 : 4921700 : Location start_loc = this->location();
3244 : 4921700 : bool operand_is_parenthesized = false;
3245 : 4921700 : bool whole_is_parenthesized = false;
3246 : :
3247 : 4921700 : Expression* ret = this->operand(may_be_sink, &operand_is_parenthesized);
3248 : :
3249 : 4921700 : 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 : 4921700 : if (may_be_composite_lit
3254 : 4238464 : && !operand_is_parenthesized
3255 : 5386149 : && ret->unknown_expression() != NULL
3256 : 10307849 : && 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 : 4921700 : 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 : 6615103 : while (true)
3324 : : {
3325 : 6615103 : const Token* token = this->peek_token();
3326 : 6615103 : 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 : 5790538 : 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 : 5076445 : 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 : 4921700 : if (whole_is_parenthesized && is_parenthesized != NULL)
3348 : 4 : *is_parenthesized = true;
3349 : :
3350 : 4921700 : 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 : 4921700 : Parse::expression(Precedence precedence, bool may_be_sink,
3593 : : bool may_be_composite_lit, bool* is_type_switch,
3594 : : bool *is_parenthesized)
3595 : : {
3596 : 4921700 : Expression* left = this->unary_expr(may_be_sink, may_be_composite_lit,
3597 : : is_type_switch, is_parenthesized);
3598 : :
3599 : 6102310 : while (true)
3600 : : {
3601 : 5512005 : if (is_type_switch != NULL && *is_type_switch)
3602 : 4921700 : return left;
3603 : :
3604 : 5509612 : const Token* token = this->peek_token();
3605 : 5509612 : if (token->classification() != Token::TOKEN_OPERATOR)
3606 : : {
3607 : : // Not a binary_op.
3608 : : return left;
3609 : : }
3610 : :
3611 : 5509607 : Precedence right_precedence;
3612 : 5509607 : 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 : 96321 : case OPERATOR_MULT:
3635 : 96321 : case OPERATOR_DIV:
3636 : 96321 : case OPERATOR_MOD:
3637 : 96321 : case OPERATOR_LSHIFT:
3638 : 96321 : case OPERATOR_RSHIFT:
3639 : 96321 : case OPERATOR_AND:
3640 : 96321 : case OPERATOR_BITCLEAR:
3641 : 96321 : right_precedence = PRECEDENCE_MULOP;
3642 : 96321 : break;
3643 : : default:
3644 : 4921700 : right_precedence = PRECEDENCE_INVALID;
3645 : : break;
3646 : : }
3647 : :
3648 : 687235 : if (right_precedence == PRECEDENCE_INVALID)
3649 : : {
3650 : : // Not a binary_op.
3651 : : return left;
3652 : : }
3653 : :
3654 : 740482 : if (is_parenthesized != NULL)
3655 : 0 : *is_parenthesized = false;
3656 : :
3657 : 740482 : Operator op = token->op();
3658 : 740482 : Location binop_location = token->location();
3659 : :
3660 : 740482 : 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 : 590305 : this->advance_token();
3668 : :
3669 : 590305 : left = this->verify_not_sink(left);
3670 : 590305 : Expression* right = this->expression(right_precedence, false,
3671 : : may_be_composite_lit,
3672 : : NULL, NULL);
3673 : 590305 : left = Expression::make_binary(op, left, right, binop_location);
3674 : 590305 : }
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 : 5106233 : Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
3743 : : bool* is_type_switch, bool* is_parenthesized)
3744 : : {
3745 : 5106233 : 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 : 5106233 : 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 : 5383928 : if (token->is_op(OPERATOR_PLUS)
3802 : 5044513 : || token->is_op(OPERATOR_MINUS)
3803 : 5012328 : || token->is_op(OPERATOR_NOT)
3804 : 5009746 : || token->is_op(OPERATOR_XOR)
3805 : 5005659 : || token->is_op(OPERATOR_CHANOP)
3806 : 4981288 : || token->is_op(OPERATOR_MULT)
3807 : 5106172 : || token->is_op(OPERATOR_AND))
3808 : : {
3809 : 184533 : Location location = token->location();
3810 : 184533 : Operator op = token->op();
3811 : 184533 : this->advance_token();
3812 : :
3813 : 184533 : Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL,
3814 : : NULL);
3815 : 184533 : if (expr->is_error_expression())
3816 : : ;
3817 : 184533 : else if (op == OPERATOR_MULT && expr->is_type_expression())
3818 : 4954 : expr = Expression::make_type(Type::make_pointer_type(expr->type()),
3819 : : location);
3820 : 179579 : else if (op == OPERATOR_AND && expr->is_composite_literal())
3821 : 19145 : expr = Expression::make_heap_expression(expr, location);
3822 : 160434 : else if (op != OPERATOR_CHANOP)
3823 : 156347 : expr = Expression::make_unary(op, expr, location);
3824 : : else
3825 : 4087 : expr = Expression::make_receive(expr, location);
3826 : 184533 : return expr;
3827 : : }
3828 : : else
3829 : 4921639 : return this->primary_expr(may_be_sink, may_be_composite_lit,
3830 : 4921639 : 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 "<-" 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 : 12706 : Parse::package_clause()
5877 : : {
5878 : 12706 : const Token* token = this->peek_token();
5879 : 12706 : Location location = token->location();
5880 : 12706 : std::string name;
5881 : 12706 : 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 : 12704 : token = this->advance_token();
5889 : 12704 : if (token->is_identifier())
5890 : : {
5891 : 12703 : name = token->identifier();
5892 : 12703 : if (name == "_")
5893 : : {
5894 : 1 : go_error_at(this->location(), "invalid package name %<_%>");
5895 : 1 : name = Gogo::erroneous_name();
5896 : : }
5897 : 12703 : 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 : 12706 : this->gogo_->set_package_name(name, location);
5906 : 12706 : }
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 : 12706 : Parse::program()
5960 : : {
5961 : 12706 : this->package_clause();
5962 : :
5963 : 12706 : const Token* token = this->peek_token();
5964 : 12706 : if (token->is_op(OPERATOR_SEMICOLON))
5965 : 12703 : token = this->advance_token();
5966 : : else
5967 : 3 : go_error_at(this->location(),
5968 : : "expected %<;%> or newline after package clause");
5969 : :
5970 : 23392 : 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 : 304166 : while (!token->is_eof())
5982 : : {
5983 : 291460 : if (this->declaration_may_start_here())
5984 : 291448 : 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 : 291460 : token = this->peek_token();
5999 : 291460 : if (token->is_op(OPERATOR_SEMICOLON))
6000 : 291443 : 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 : 12706 : this->check_directives();
6016 : 12706 : }
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 : 446741 : Parse::check_directives()
6023 : : {
6024 : 446741 : if (this->lex_->get_and_clear_pragmas() != 0)
6025 : 0 : go_error_at(this->location(), "misplaced compiler directive");
6026 : 446741 : 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 : 446741 : }
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 : 2827406 : Parse::verify_not_sink(Expression* expr)
6061 : : {
6062 : 2827406 : 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 : 2827406 : if (expr->var_expression() != NULL)
6071 : 1002913 : this->mark_var_used(expr->var_expression()->named_object());
6072 : 1824493 : else if (expr->enclosed_var_expression() != NULL)
6073 : 26154 : this->mark_var_used(expr->enclosed_var_expression()->variable());
6074 : 2827406 : 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 : }
|