diff options
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 71 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.def | 31 |
3 files changed, 61 insertions, 43 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e22f79e..c987dc9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -f3658aea2493c7f1c4a72502f9e7da562c7764c4 +ecf9b645cefc5c3b4e6339adeb452b2d8642cf3e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 36000ea..4f8a519 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7018,6 +7018,26 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, } } break; + + case BUILTIN_PRINT: + case BUILTIN_PRINTLN: + // Force all the arguments into temporary variables, so that we + // don't try to evaluate something while holding the print lock. + if (this->args() == NULL) + break; + for (Expression_list::iterator pa = this->args()->begin(); + pa != this->args()->end(); + ++pa) + { + if (!(*pa)->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, *pa, loc); + inserter->insert(temp); + *pa = Expression::make_temporary_reference(temp, loc); + } + } + break; } return this; @@ -8336,7 +8356,9 @@ Builtin_call_expression::do_get_backend(Translate_context* context) case BUILTIN_PRINTLN: { const bool is_ln = this->code_ == BUILTIN_PRINTLN; - Expression* print_stmts = NULL; + + Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK, + location, 0); const Expression_list* call_args = this->args(); if (call_args != NULL) @@ -8348,8 +8370,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context) if (is_ln && p != call_args->begin()) { Expression* print_space = - Runtime::make_call(Runtime::PRINT_SPACE, - this->location(), 0); + Runtime::make_call(Runtime::PRINTSP, location, 0); print_stmts = Expression::make_compound(print_stmts, print_space, @@ -8360,51 +8381,51 @@ Builtin_call_expression::do_get_backend(Translate_context* context) Type* type = arg->type(); Runtime::Function code; if (type->is_string_type()) - code = Runtime::PRINT_STRING; + code = Runtime::PRINTSTRING; else if (type->integer_type() != NULL && type->integer_type()->is_unsigned()) { Type* itype = Type::lookup_integer_type("uint64"); arg = Expression::make_cast(itype, arg, location); - code = Runtime::PRINT_UINT64; + code = Runtime::PRINTUINT; } else if (type->integer_type() != NULL) { Type* itype = Type::lookup_integer_type("int64"); arg = Expression::make_cast(itype, arg, location); - code = Runtime::PRINT_INT64; + code = Runtime::PRINTINT; } else if (type->float_type() != NULL) { Type* dtype = Type::lookup_float_type("float64"); arg = Expression::make_cast(dtype, arg, location); - code = Runtime::PRINT_DOUBLE; + code = Runtime::PRINTFLOAT; } else if (type->complex_type() != NULL) { Type* ctype = Type::lookup_complex_type("complex128"); arg = Expression::make_cast(ctype, arg, location); - code = Runtime::PRINT_COMPLEX; + code = Runtime::PRINTCOMPLEX; } else if (type->is_boolean_type()) - code = Runtime::PRINT_BOOL; + code = Runtime::PRINTBOOL; else if (type->points_to() != NULL || type->channel_type() != NULL || type->map_type() != NULL || type->function_type() != NULL) { arg = Expression::make_cast(type, arg, location); - code = Runtime::PRINT_POINTER; + code = Runtime::PRINTPOINTER; } else if (type->interface_type() != NULL) { if (type->interface_type()->is_empty()) - code = Runtime::PRINT_EMPTY_INTERFACE; + code = Runtime::PRINTEFACE; else - code = Runtime::PRINT_INTERFACE; + code = Runtime::PRINTIFACE; } else if (type->is_slice_type()) - code = Runtime::PRINT_SLICE; + code = Runtime::PRINTSLICE; else { go_assert(saw_errors()); @@ -8412,30 +8433,22 @@ Builtin_call_expression::do_get_backend(Translate_context* context) } Expression* call = Runtime::make_call(code, location, 1, arg); - if (print_stmts == NULL) - print_stmts = call; - else - print_stmts = Expression::make_compound(print_stmts, call, - location); + print_stmts = Expression::make_compound(print_stmts, call, + location); } } if (is_ln) { Expression* print_nl = - Runtime::make_call(Runtime::PRINT_NL, location, 0); - if (print_stmts == NULL) - print_stmts = print_nl; - else - print_stmts = Expression::make_compound(print_stmts, print_nl, - location); + Runtime::make_call(Runtime::PRINTNL, location, 0); + print_stmts = Expression::make_compound(print_stmts, print_nl, + location); } - // There aren't any arguments to the print builtin. The compiler - // issues a warning for this so we should avoid getting the backend - // representation for this call. Instead, perform a no-op. - if (print_stmts == NULL) - return context->backend()->boolean_constant_expression(false); + Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK, + location, 0); + print_stmts = Expression::make_compound(print_stmts, unlock, location); return print_stmts->get_backend(context); } diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 168f473..e7edfa6 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -299,42 +299,47 @@ DEF_GO_RUNTIME(INTERFACE_EMPTY_COMPARE, "__go_interface_empty_compare", P2(IFACE, EFACE), R1(INT)) +// Lock the printer (for print/println). +DEF_GO_RUNTIME(PRINTLOCK, "runtime.printlock", P0(), R0()) + +// Unlock the printer (for print/println). +DEF_GO_RUNTIME(PRINTUNLOCK, "runtime.printunlock", P0(), R0()) + // Print a string (for print/println). -DEF_GO_RUNTIME(PRINT_STRING, "__go_print_string", P1(STRING), R0()) +DEF_GO_RUNTIME(PRINTSTRING, "runtime.printstring", P1(STRING), R0()) // Print a uint64 (for print/println). -DEF_GO_RUNTIME(PRINT_UINT64, "__go_print_uint64", P1(UINT64), R0()) +DEF_GO_RUNTIME(PRINTUINT, "runtime.printuint", P1(UINT64), R0()) // Print a int64 (for print/println). -DEF_GO_RUNTIME(PRINT_INT64, "__go_print_int64", P1(INT64), R0()) +DEF_GO_RUNTIME(PRINTINT, "runtime.printint", P1(INT64), R0()) // Print a float64 (for print/println). -DEF_GO_RUNTIME(PRINT_DOUBLE, "__go_print_double", P1(FLOAT64), R0()) +DEF_GO_RUNTIME(PRINTFLOAT, "runtime.printfloat", P1(FLOAT64), R0()) // Print a complex128 (for print/println). -DEF_GO_RUNTIME(PRINT_COMPLEX, "__go_print_complex", P1(COMPLEX128), R0()) +DEF_GO_RUNTIME(PRINTCOMPLEX, "runtime.printcomplex", P1(COMPLEX128), R0()) // Print a bool (for print/println). -DEF_GO_RUNTIME(PRINT_BOOL, "__go_print_bool", P1(BOOL), R0()) +DEF_GO_RUNTIME(PRINTBOOL, "runtime.printbool", P1(BOOL), R0()) // Print a pointer/map/channel/function (for print/println). -DEF_GO_RUNTIME(PRINT_POINTER, "__go_print_pointer", P1(POINTER), R0()) +DEF_GO_RUNTIME(PRINTPOINTER, "runtime.printpointer", P1(POINTER), R0()) // Print an empty interface (for print/println). -DEF_GO_RUNTIME(PRINT_EMPTY_INTERFACE, "__go_print_empty_interface", - P1(EFACE), R0()) +DEF_GO_RUNTIME(PRINTEFACE, "runtime.printeface", P1(EFACE), R0()) // Print a non-empty interface (for print/println). -DEF_GO_RUNTIME(PRINT_INTERFACE, "__go_print_interface", P1(IFACE), R0()) +DEF_GO_RUNTIME(PRINTIFACE, "runtime.printiface", P1(IFACE), R0()) // Print a slice (for print/println). -DEF_GO_RUNTIME(PRINT_SLICE, "__go_print_slice", P1(SLICE), R0()) +DEF_GO_RUNTIME(PRINTSLICE, "runtime.printslice", P1(SLICE), R0()) // Print a space (for println). -DEF_GO_RUNTIME(PRINT_SPACE, "__go_print_space", P0(), R0()) +DEF_GO_RUNTIME(PRINTSP, "runtime.printsp", P0(), R0()) // Print a newline (for println). -DEF_GO_RUNTIME(PRINT_NL, "__go_print_nl", P0(), R0()) +DEF_GO_RUNTIME(PRINTNL, "runtime.printnl", P0(), R0()) // Used for field tracking for data analysis. |