// initialization, we need an initialization function.
if (!variable->is_global())
;
- else if (variable->has_pre_init())
- this->need_init_fn_ = true;
else if (variable->init() == NULL)
;
else if (variable->type()->interface_type() != NULL)
class Shortcuts : public Traverse
{
public:
- Shortcuts()
+ Shortcuts(Gogo* gogo)
: Traverse(traverse_variables
- | traverse_statements)
+ | traverse_statements),
+ gogo_(gogo)
{ }
protected:
// Convert a shortcut operator.
Statement*
convert_shortcut(Block* enclosing, Expression** pshortcut);
+
+ // The IR.
+ Gogo* gogo_;
};
// Remove shortcut operators in a single statement.
return TRAVERSE_CONTINUE;
Statement* snew = this->convert_shortcut(NULL, pshortcut);
- var->add_preinit_statement(snew);
+ var->add_preinit_statement(this->gogo_, snew);
if (pshortcut == &init)
var->set_init(init);
}
delete shortcut;
// Now convert any shortcut operators in LEFT and RIGHT.
- Shortcuts shortcuts;
+ Shortcuts shortcuts(this->gogo_);
retblock->traverse(&shortcuts);
return Statement::make_block_statement(retblock, loc);
void
Gogo::remove_shortcuts()
{
- Shortcuts shortcuts;
+ Shortcuts shortcuts(this);
this->traverse(&shortcuts);
}
class Order_eval : public Traverse
{
public:
- Order_eval()
+ Order_eval(Gogo* gogo)
: Traverse(traverse_variables
- | traverse_statements)
+ | traverse_statements),
+ gogo_(gogo)
{ }
int
int
statement(Block*, size_t*, Statement*);
+
+ private:
+ // The IR.
+ Gogo* gogo_;
};
// Implement the order of evaluation rules for a statement.
Expression** pexpr = *p;
source_location loc = (*pexpr)->location();
Temporary_statement* ts = Statement::make_temporary(NULL, *pexpr, loc);
- var->add_preinit_statement(ts);
+ var->add_preinit_statement(this->gogo_, ts);
*pexpr = Expression::make_temporary_reference(ts, loc);
}
void
Gogo::order_evaluations()
{
- Order_eval order_eval;
+ Order_eval order_eval(this);
this->traverse(&order_eval);
}
// Get the preinit block.
Block*
-Variable::preinit_block()
+Variable::preinit_block(Gogo* gogo)
{
gcc_assert(this->is_global_);
if (this->preinit_ == NULL)
this->preinit_ = new Block(NULL, this->location());
+
+ // If a global variable has a preinitialization statement, then we
+ // need to have an initialization function.
+ gogo->set_need_init_fn();
+
return this->preinit_;
}
// Add a statement to be run before the initialization expression.
void
-Variable::add_preinit_statement(Statement* s)
+Variable::add_preinit_statement(Gogo* gogo, Statement* s)
{
- Block* b = this->preinit_block();
+ Block* b = this->preinit_block(gogo);
b->add_statement(s);
b->set_end_location(s->location());
}
void
record_interface_type(Interface_type*);
+ // Note that we need an initialization function.
+ void
+ set_need_init_fn()
+ { this->need_init_fn_ = true; }
+
// Clear out all names in file scope. This is called when we start
// parsing a new file.
void
// Get the preinit block, a block of statements to be run before the
// initialization expression.
Block*
- preinit_block();
+ preinit_block(Gogo*);
// Add a statement to be run before the initialization expression.
// This is only used for global variables.
void
- add_preinit_statement(Statement*);
+ add_preinit_statement(Gogo*, Statement*);
// Lower the initialization expression after parsing is complete.
void
else if (!val_no->is_sink())
{
if (val_no->is_variable())
- val_no->var_value()->add_preinit_statement(s);
+ val_no->var_value()->add_preinit_statement(this->gogo_, s);
}
else if (!no->is_sink())
{
if (no->is_variable())
- no->var_value()->add_preinit_statement(s);
+ no->var_value()->add_preinit_statement(this->gogo_, s);
}
else
{
// the map is nil.
Named_object* dummy = this->create_dummy_global(Type::lookup_bool_type(),
NULL, location);
- dummy->var_value()->add_preinit_statement(s);
+ dummy->var_value()->add_preinit_statement(this->gogo_, s);
}
return true;
else if (!val_no->is_sink())
{
if (val_no->is_variable())
- val_no->var_value()->add_preinit_statement(s);
+ val_no->var_value()->add_preinit_statement(this->gogo_, s);
}
else if (!no->is_sink())
{
if (no->is_variable())
- no->var_value()->add_preinit_statement(s);
+ no->var_value()->add_preinit_statement(this->gogo_, s);
}
else
{
Named_object* dummy = this->create_dummy_global(Type::lookup_bool_type(),
NULL, location);
- dummy->var_value()->add_preinit_statement(s);
+ dummy->var_value()->add_preinit_statement(this->gogo_, s);
}
return true;
else if (!val_no->is_sink())
{
if (val_no->is_variable())
- val_no->var_value()->add_preinit_statement(s);
+ val_no->var_value()->add_preinit_statement(this->gogo_, s);
}
else if (!no->is_sink())
{
if (no->is_variable())
- no->var_value()->add_preinit_statement(s);
+ no->var_value()->add_preinit_statement(this->gogo_, s);
}
else
{
Named_object* dummy = this->create_dummy_global(type, NULL, location);
- dummy->var_value()->add_preinit_statement(s);
+ dummy->var_value()->add_preinit_statement(this->gogo_, s);
}
return true;