}
// The cost to inline a variable reference. We currently only support
-// references to parameters.
+// references to parameters and local variables.
int
Var_expression::do_inlining_cost() const
{
if (this->variable_->is_variable())
{
- if (this->variable_->var_value()->is_parameter())
+ if (!this->variable_->var_value()->is_global())
return 1;
}
else if (this->variable_->is_result_variable())
ifb->advance(6);
return Statement::make_return_statement(NULL, loc);
}
+ else if (ifb->match_c_string("var "))
+ return Variable_declaration_statement::do_import(ifb, loc);
Expression* lhs = Expression::import_expression(ifb, loc);
ifb->require_c_string(" = ");
return new Variable_declaration_statement(var);
}
+// Export a variable declaration.
+
+void
+Variable_declaration_statement::do_export_statement(Export_function_body* efb)
+{
+ efb->write_c_string("var ");
+ efb->write_string(Gogo::unpack_hidden_name(this->var_->name()));
+ efb->write_c_string(" ");
+ Variable* var = this->var_->var_value();
+ Type* type = var->type();
+ efb->write_type(type);
+ Expression* init = var->init();
+ if (init != NULL)
+ {
+ efb->write_c_string(" = ");
+
+ go_assert(efb->type_context() == NULL);
+ efb->set_type_context(type);
+
+ init->export_expression(efb);
+
+ efb->set_type_context(NULL);
+ }
+}
+
+// Import a variable declaration.
+
+Statement*
+Variable_declaration_statement::do_import(Import_function_body* ifb,
+ Location loc)
+{
+ ifb->require_c_string("var ");
+ std::string id = ifb->read_identifier();
+ ifb->require_c_string(" ");
+ Type* type = ifb->read_type();
+ Expression* init = NULL;
+ if (ifb->match_c_string(" = "))
+ {
+ ifb->advance(3);
+ init = Expression::import_expression(ifb, loc);
+ Type_context context(type, false);
+ init->determine_type(&context);
+ }
+ Variable* var = new Variable(type, init, false, false, false, loc);
+ var->set_is_used();
+ // FIXME: The package we are importing does not yet exist, so we
+ // can't pass the correct package here. It probably doesn't matter.
+ Named_object* no = ifb->block()->bindings()->add_variable(id, NULL, var);
+ return Statement::make_variable_declaration(no);
+}
+
// Class Temporary_statement.
// Return the type of the temporary variable.
class Function;
class Unnamed_label;
class Export_function_body;
+class Import_function_body;
class Assignment_statement;
class Temporary_statement;
class Variable_declaration_statement;
inlining_cost()
{ return this->do_inlining_cost(); }
- // Export data for this statement to BODY. INDENT is an indentation
- // level used if the export data requires multiple lines.
+ // Export data for this statement to BODY.
void
export_statement(Export_function_body* efb)
{ this->do_export_statement(efb); }
{ return 0x100000; }
// Implemented by child class: write export data for this statement
- // to the string. The integer is an indentation level used if the
- // export data requires multiple lines. This need only be
- // implemented by classes that implement do_inlining_cost with a
- // reasonable value.
+ // to the string. This need only be implemented by classes that
+ // implement do_inlining_cost with a reasonable value.
virtual void
do_export_statement(Export_function_body*)
{ go_unreachable(); }
var()
{ return this->var_; }
+ // Import a variable declaration.
+ static Statement*
+ do_import(Import_function_body*, Location);
+
protected:
int
do_traverse(Traverse*);
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
+ int
+ do_inlining_cost()
+ { return 1; }
+
+ void
+ do_export_statement(Export_function_body*);
+
Statement*
do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);