+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".
Bexpression*
complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag);
+ Bexpression*
+ convert_expression(Btype* type, Bexpression* expr, Location);
+
// Statements.
Bstatement*
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*
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
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.