diff options
Diffstat (limited to 'gcc/go/gofrontend/parse.cc')
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 9d112850fee..6e56f835699 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -213,7 +213,7 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage) if (name == "_") { error_at(this->location(), "invalid use of %<_%>"); - name = "blank"; + name = Gogo::erroneous_name(); } if (package->name() == this->gogo_->package_name()) @@ -744,6 +744,8 @@ Parse::signature(Typed_identifier* receiver, Location location) return NULL; Parse::Names names; + if (receiver != NULL) + names[receiver->name()] = receiver; if (params != NULL) this->check_signature_names(params, &names); if (results != NULL) @@ -1940,12 +1942,9 @@ Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init, { if (this->gogo_->in_global_scope()) return this->create_dummy_global(type, init, location); - else if (type == NULL) - this->gogo_->add_statement(Statement::make_statement(init, true)); else { - // With both a type and an initializer, create a dummy - // variable so that we will check whether the + // Create a dummy variable so that we will check whether the // initializer can be assigned to the type. Variable* var = new Variable(type, init, false, false, false, location); @@ -2693,15 +2692,17 @@ Parse::composite_lit(Type* type, int depth, Location location) { this->advance_token(); return Expression::make_composite_literal(type, depth, false, NULL, - location); + false, location); } bool has_keys = false; + bool all_are_names = true; Expression_list* vals = new Expression_list; while (true) { Expression* val; bool is_type_omitted = false; + bool is_name = false; const Token* token = this->peek_token(); @@ -2722,6 +2723,7 @@ Parse::composite_lit(Type* type, int depth, Location location) val = this->id_to_expression(gogo->pack_hidden_name(identifier, is_exported), location); + is_name = true; } else { @@ -2747,6 +2749,7 @@ Parse::composite_lit(Type* type, int depth, Location location) { if (has_keys) vals->push_back(NULL); + is_name = false; } else { @@ -2793,6 +2796,9 @@ Parse::composite_lit(Type* type, int depth, Location location) vals->push_back(val); + if (!is_name) + all_are_names = false; + if (token->is_op(OPERATOR_COMMA)) { if (this->advance_token()->is_op(OPERATOR_RCURLY)) @@ -2833,7 +2839,7 @@ Parse::composite_lit(Type* type, int depth, Location location) } return Expression::make_composite_literal(type, depth, has_keys, vals, - location); + all_are_names, location); } // FunctionLit = "func" Signature Block . @@ -3107,7 +3113,7 @@ Parse::selector(Expression* left, bool* is_type_switch) if (token->identifier() == "_") { error_at(this->location(), "invalid use of %<_%>"); - name = this->gogo_->pack_hidden_name("blank", false); + name = Gogo::erroneous_name(); } this->advance_token(); return Expression::make_selector(left, name, location); @@ -3146,7 +3152,7 @@ Parse::selector(Expression* left, bool* is_type_switch) } // Index = "[" Expression "]" . -// Slice = "[" Expression ":" [ Expression ] "]" . +// Slice = "[" Expression ":" [ Expression ] [ ":" Expression ] "]" . Expression* Parse::index(Expression* expr) @@ -3172,14 +3178,31 @@ Parse::index(Expression* expr) // We use nil to indicate a missing high expression. if (this->advance_token()->is_op(OPERATOR_RSQUARE)) end = Expression::make_nil(this->location()); + else if (this->peek_token()->is_op(OPERATOR_COLON)) + { + error_at(this->location(), "middle index required in 3-index slice"); + end = Expression::make_error(this->location()); + } else end = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL); } + + Expression* cap = NULL; + if (this->peek_token()->is_op(OPERATOR_COLON)) + { + if (this->advance_token()->is_op(OPERATOR_RSQUARE)) + { + error_at(this->location(), "final index required in 3-index slice"); + cap = Expression::make_error(this->location()); + } + else + cap = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL); + } if (!this->peek_token()->is_op(OPERATOR_RSQUARE)) error_at(this->location(), "missing %<]%>"); else this->advance_token(); - return Expression::make_index(expr, start, end, location); + return Expression::make_index(expr, start, end, cap, location); } // Call = "(" [ ArgumentList [ "," ] ] ")" . @@ -4932,7 +4955,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val, { error_at(recv_var_loc, "no new variables on left side of %<:=%>"); - recv_var = "blank"; + recv_var = Gogo::erroneous_name(); } *is_send = false; *varname = gogo->pack_hidden_name(recv_var, is_rv_exported); @@ -4968,7 +4991,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val, { error_at(recv_var_loc, "no new variables on left side of %<:=%>"); - recv_var = "blank"; + recv_var = Gogo::erroneous_name(); } *is_send = false; if (recv_var != "_") @@ -5505,7 +5528,7 @@ Parse::package_clause() if (name == "_") { error_at(this->location(), "invalid package name _"); - name = "blank"; + name = Gogo::erroneous_name(); } this->advance_token(); } |