Mercurial > hg > CbC > CbC_gcc
diff gcc/go/gofrontend/parse.cc @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/go/gofrontend/parse.cc Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/go/gofrontend/parse.cc Thu Oct 25 07:37:49 2018 +0900 @@ -20,7 +20,7 @@ bool Parse::Enclosing_var_comparison::operator()(const Enclosing_var& v1, - const Enclosing_var& v2) + const Enclosing_var& v2) const { if (v1.var() == v2.var()) return false; @@ -50,7 +50,6 @@ gogo_(gogo), break_stack_(NULL), continue_stack_(NULL), - iota_(0), enclosing_vars_() { } @@ -1407,19 +1406,20 @@ { go_assert(this->peek_token()->is_keyword(KEYWORD_CONST)); this->advance_token(); - this->reset_iota(); - + + int iota = 0; Type* last_type = NULL; Expression_list* last_expr_list = NULL; if (!this->peek_token()->is_op(OPERATOR_LPAREN)) - this->const_spec(&last_type, &last_expr_list); + this->const_spec(iota, &last_type, &last_expr_list); else { this->advance_token(); while (!this->peek_token()->is_op(OPERATOR_RPAREN)) { - this->const_spec(&last_type, &last_expr_list); + this->const_spec(iota, &last_type, &last_expr_list); + ++iota; if (this->peek_token()->is_op(OPERATOR_SEMICOLON)) this->advance_token(); else if (!this->peek_token()->is_op(OPERATOR_RPAREN)) @@ -1440,7 +1440,7 @@ // ConstSpec = IdentifierList [ [ CompleteType ] "=" ExpressionList ] . void -Parse::const_spec(Type** last_type, Expression_list** last_expr_list) +Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list) { Typed_identifier_list til; this->identifier_list(&til); @@ -1492,7 +1492,7 @@ pi->set_type(type); if (!Gogo::is_sink_name(pi->name())) - this->gogo_->add_constant(*pi, *pe, this->iota_value()); + this->gogo_->add_constant(*pi, *pe, iota); else { static int count; @@ -1500,15 +1500,13 @@ snprintf(buf, sizeof buf, ".$sinkconst%d", count); ++count; Typed_identifier ti(std::string(buf), type, pi->location()); - Named_object* no = this->gogo_->add_constant(ti, *pe, this->iota_value()); + Named_object* no = this->gogo_->add_constant(ti, *pe, iota); no->const_value()->set_is_sink(); } } if (pe != expr_list->end()) go_error_at(this->location(), "too many initializers"); - this->increment_iota(); - return; } @@ -2362,7 +2360,10 @@ { GOPRAGMA_NOINLINE, "noinline", false, true, true }, { GOPRAGMA_SYSTEMSTACK, "systemstack", false, true, true }, { GOPRAGMA_NOWRITEBARRIER, "nowritebarrier", false, true, true }, - { GOPRAGMA_NOWRITEBARRIERREC, "nowritebarrierrec", false, true, true }, + { GOPRAGMA_NOWRITEBARRIERREC, "nowritebarrierrec", false, true, + true }, + { GOPRAGMA_YESWRITEBARRIERREC, "yeswritebarrierrec", false, true, + true }, { GOPRAGMA_CGOUNSAFEARGS, "cgo_unsafe_args", false, true, true }, { GOPRAGMA_UINTPTRESCAPES, "uintptrescapes", true, true, true }, }; @@ -2745,14 +2746,18 @@ Expression* closure_ref = Expression::make_var_reference(closure, location); - closure_ref = Expression::make_unary(OPERATOR_MULT, closure_ref, location); + closure_ref = + Expression::make_dereference(closure_ref, + Expression::NIL_CHECK_NOT_NEEDED, + location); // The closure structure holds pointers to the variables, so we need // to introduce an indirection. Expression* e = Expression::make_field_reference(closure_ref, ins.first->index(), location); - e = Expression::make_unary(OPERATOR_MULT, e, location); + e = Expression::make_dereference(e, Expression::NIL_CHECK_NOT_NEEDED, + location); return Expression::make_enclosing_var_reference(e, var, location); } @@ -3055,21 +3060,6 @@ Struct_type* st = closure_var->var_value()->type()->deref()->struct_type(); Expression* cv = Expression::make_struct_composite_literal(st, initializer, location); - - // When compiling the runtime, closures do not escape. When escape - // analysis becomes the default, and applies to closures, this - // should be changed to make it an error if a closure escapes. - if (this->gogo_->compiling_runtime() - && this->gogo_->package_name() == "runtime") - { - Temporary_statement* ctemp = Statement::make_temporary(st, cv, location); - this->gogo_->add_statement(ctemp); - Expression* ref = Expression::make_temporary_reference(ctemp, location); - Expression* addr = Expression::make_unary(OPERATOR_AND, ref, location); - addr->unary_expression()->set_does_not_escape(); - return addr; - } - return Expression::make_heap_expression(cv, location); } @@ -4314,9 +4304,15 @@ this->gogo_->start_block(stat_location); Statement* stat; if (is_go) - stat = Statement::make_go_statement(call_expr, stat_location); + { + stat = Statement::make_go_statement(call_expr, stat_location); + call_expr->set_is_concurrent(); + } else - stat = Statement::make_defer_statement(call_expr, stat_location); + { + stat = Statement::make_defer_statement(call_expr, stat_location); + call_expr->set_is_deferred(); + } this->gogo_->add_statement(stat); this->gogo_->add_block(this->gogo_->finish_block(stat_location), stat_location); @@ -4678,11 +4674,26 @@ { Location fallthrough_loc = this->location(); is_fallthrough = true; - if (this->advance_token()->is_op(OPERATOR_SEMICOLON)) - this->advance_token(); + while (this->advance_token()->is_op(OPERATOR_SEMICOLON)) + ; if (this->peek_token()->is_op(OPERATOR_RCURLY)) go_error_at(fallthrough_loc, _("cannot fallthrough final case in switch")); + else if (!this->peek_token()->is_keyword(KEYWORD_CASE) + && !this->peek_token()->is_keyword(KEYWORD_DEFAULT)) + { + go_error_at(fallthrough_loc, "fallthrough statement out of place"); + while (!this->peek_token()->is_keyword(KEYWORD_CASE) + && !this->peek_token()->is_keyword(KEYWORD_DEFAULT) + && !this->peek_token()->is_op(OPERATOR_RCURLY) + && !this->peek_token()->is_eof()) + { + if (this->statement_may_start_here()) + this->statement_list(); + else + this->advance_token(); + } + } } if (is_default) @@ -5171,7 +5182,18 @@ Expression* e; if (saw_comma || !this->peek_token()->is_op(OPERATOR_CHANOP)) - e = this->expression(PRECEDENCE_NORMAL, true, true, NULL, NULL); + { + e = this->expression(PRECEDENCE_NORMAL, true, true, NULL, NULL); + if (e->receive_expression() != NULL) + { + *is_send = false; + *channel = e->receive_expression()->channel(); + // This is 'case (<-c):'. We now expect ':'. If we see + // '<-', then we have case (<-c)<-v: + if (!this->peek_token()->is_op(OPERATOR_CHANOP)) + return true; + } + } else { // case <-c: @@ -5200,14 +5222,17 @@ if (this->peek_token()->is_op(OPERATOR_EQ)) { - if (!this->advance_token()->is_op(OPERATOR_CHANOP)) + *is_send = false; + this->advance_token(); + Location recvloc = this->location(); + Expression* recvexpr = this->expression(PRECEDENCE_NORMAL, false, + true, NULL, NULL); + if (recvexpr->receive_expression() == NULL) { - go_error_at(this->location(), "missing %<<-%>"); + go_error_at(recvloc, "missing %<<-%>"); return false; } - *is_send = false; - this->advance_token(); - *channel = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL); + *channel = recvexpr->receive_expression()->channel(); if (saw_comma) { // case v, e = <-c: @@ -5456,8 +5481,7 @@ no->var_value()->set_type_from_range_value(); if (is_new) any_new = true; - if (!Gogo::is_sink_name(pti->name())) - p_range_clause->value = Expression::make_var_reference(no, location); + p_range_clause->value = Expression::make_var_reference(no, location); } if (!any_new) @@ -5821,30 +5845,6 @@ } } -// Reset the current iota value. - -void -Parse::reset_iota() -{ - this->iota_ = 0; -} - -// Return the current iota value. - -int -Parse::iota_value() -{ - return this->iota_; -} - -// Increment the current iota value. - -void -Parse::increment_iota() -{ - ++this->iota_; -} - // Skip forward to a semicolon or OP. OP will normally be // OPERATOR_RPAREN or OPERATOR_RCURLY. If we find a semicolon, move // past it and return. If we find OP, it will be the next token to