Binary_expression::do_flatten(Gogo* gogo, Named_object*,
Statement_inserter* inserter)
{
+ if (this->classification() == EXPRESSION_ERROR)
+ return this;
+
Location loc = this->location();
Temporary_statement* temp;
if (this->left_->type()->is_string_type()
Builtin_call_expression::do_flatten(Gogo*, Named_object*,
Statement_inserter* inserter)
{
- if (this->code_ == BUILTIN_APPEND
- || this->code_ == BUILTIN_COPY)
+ Location loc = this->location();
+
+ switch (this->code_)
{
- Location loc = this->location();
- Type* at = this->args()->front()->type();
+ default:
+ break;
+
+ case BUILTIN_APPEND:
+ case BUILTIN_COPY:
+ {
+ Type* at = this->args()->front()->type();
+ for (Expression_list::iterator pa = this->args()->begin();
+ pa != this->args()->end();
+ ++pa)
+ {
+ if ((*pa)->is_nil_expression())
+ {
+ Expression* nil = Expression::make_nil(loc);
+ Expression* zero = Expression::make_integer_ul(0, NULL, loc);
+ *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
+ }
+ if (!(*pa)->is_variable())
+ {
+ Temporary_statement* temp =
+ Statement::make_temporary(NULL, *pa, loc);
+ inserter->insert(temp);
+ *pa = Expression::make_temporary_reference(temp, loc);
+ }
+ }
+ }
+ break;
+
+ case BUILTIN_PANIC:
for (Expression_list::iterator pa = this->args()->begin();
- pa != this->args()->end();
- ++pa)
- {
- if ((*pa)->is_nil_expression())
+ pa != this->args()->end();
+ ++pa)
+ {
+ if (!(*pa)->is_variable() && (*pa)->type()->interface_type() != NULL)
{
- Expression* nil = Expression::make_nil(loc);
- Expression* zero = Expression::make_integer_ul(0, NULL, loc);
- *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
+ Temporary_statement* temp =
+ Statement::make_temporary(NULL, *pa, loc);
+ inserter->insert(temp);
+ *pa = Expression::make_temporary_reference(temp, loc);
}
- if (!(*pa)->is_variable())
- {
- Temporary_statement* temp =
- Statement::make_temporary(NULL, *pa, loc);
- inserter->insert(temp);
- *pa = Expression::make_temporary_reference(temp, loc);
- }
- }
+ }
}
+
return this;
}
}
}
+// Flatten a temporary statement: add another temporary when it might
+// be needed for interface conversion.
+
+Statement*
+Temporary_statement::do_flatten(Gogo*, Named_object*, Block*,
+ Statement_inserter* inserter)
+{
+ if (this->type_ != NULL
+ && this->init_ != NULL
+ && !Type::are_identical(this->type_, this->init_->type(), false, NULL)
+ && this->init_->type()->interface_type() != NULL
+ && !this->init_->is_variable())
+ {
+ Temporary_statement *temp =
+ Statement::make_temporary(NULL, this->init_, this->location());
+ inserter->insert(temp);
+ this->init_ = Expression::make_temporary_reference(temp,
+ this->location());
+ }
+ return this;
+}
+
// Convert to backend representation.
Bstatement*
binit = this->init_->get_backend(context);
else
{
- Expression* init = Expression::make_cast(this->type_, this->init_,
- this->location());
- context->gogo()->lower_expression(context->function(), NULL, &init);
+ Expression* init = Expression::convert_for_assignment(context->gogo(),
+ this->type_,
+ this->init_,
+ this->location());
binit = init->get_backend(context);
}