Commit c6d2bfbb by Chris Manghane Committed by Ian Lance Taylor

compiler: Use backend interface for temporary reference expressions.

	* go-gcc.cc (Backend::convert_expression): New function.

From-SVN: r203209
parent 7c327f7b
2013-10-04 Chris Manghane <cmang@google.com>
* go-gcc.cc (Backend::convert_expression): New function.
2013-10-02 Chris Manghane <cmang@google.com>
* go-gcc.cc: Include "real.h" and "realmpfr.h".
......
......@@ -229,6 +229,9 @@ class Gcc_backend : public Backend
Bexpression*
complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag);
Bexpression*
convert_expression(Btype* type, Bexpression* expr, Location);
// Statements.
Bstatement*
......@@ -949,6 +952,20 @@ Gcc_backend::complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag)
return tree_to_expr(ret);
}
// An expression that converts an expression to a different type.
Bexpression*
Gcc_backend::convert_expression(Btype* type, Bexpression* expr, Location)
{
tree type_tree = type->get_tree();
tree expr_tree = expr->get_tree();
if (type_tree == error_mark_node || expr_tree == error_mark_node)
return this->error_expression();
tree ret = fold_convert(type_tree, expr_tree);
return tree_to_expr(ret);
}
// An expression as a statement.
Bstatement*
......
......@@ -262,6 +262,10 @@ class Backend
virtual Bexpression*
complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag) = 0;
// Return an expression that converts EXPR to TYPE.
virtual Bexpression*
convert_expression(Btype* type, Bexpression* expr, Location) = 0;
// Statements.
// Create an error statement. This is used for cases which should
......
......@@ -995,23 +995,24 @@ Temporary_reference_expression::do_address_taken(bool)
tree
Temporary_reference_expression::do_get_tree(Translate_context* context)
{
Gogo* gogo = context->gogo();
Bvariable* bvar = this->statement_->get_backend_variable(context);
Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
// The gcc backend can't represent the same set of recursive types
// The backend can't always represent the same set of recursive types
// that the Go frontend can. In some cases this means that a
// temporary variable won't have the right backend type. Correct
// that here by adding a type cast. We need to use base() to push
// the circularity down one level.
tree ret = var_to_tree(bvar);
Type* stype = this->statement_->type();
if (!this->is_lvalue_
&& POINTER_TYPE_P(TREE_TYPE(ret))
&& VOID_TYPE_P(TREE_TYPE(TREE_TYPE(ret))))
&& stype->has_pointer()
&& stype->deref()->is_void_type())
{
Btype* type_btype = this->type()->base()->get_backend(context->gogo());
tree type_tree = type_to_tree(type_btype);
ret = fold_convert_loc(this->location().gcc_location(), type_tree, ret);
Btype* btype = this->type()->base()->get_backend(gogo);
ret = gogo->backend()->convert_expression(btype, ret, this->location());
}
return ret;
return expr_to_tree(ret);
}
// Ast dump for temporary reference.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment