diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-01-19 20:37:50 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-01-19 20:37:50 +0000 |
commit | 5ee9259f75c8d3f90b4860ee7cd40e253de8856b (patch) | |
tree | 285525af646b8fd9037c502e76778000afdb2b48 /gcc | |
parent | e9dd48d91da11d1af1e61f773a060a44fd9e457e (diff) | |
download | gcc-5ee9259f75c8d3f90b4860ee7cd40e253de8856b.zip gcc-5ee9259f75c8d3f90b4860ee7cd40e253de8856b.tar.gz gcc-5ee9259f75c8d3f90b4860ee7cd40e253de8856b.tar.bz2 |
Generate an init function if any global variable needs a preinit.
From-SVN: r169023
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 40 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 9 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 18 |
3 files changed, 42 insertions, 25 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index b12eeb7..8e67074 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -1395,8 +1395,6 @@ Gogo::determine_types() // 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) @@ -1604,9 +1602,10 @@ Find_shortcut::expression(Expression** pexpr) class Shortcuts : public Traverse { public: - Shortcuts() + Shortcuts(Gogo* gogo) : Traverse(traverse_variables - | traverse_statements) + | traverse_statements), + gogo_(gogo) { } protected: @@ -1620,6 +1619,9 @@ class Shortcuts : public Traverse // Convert a shortcut operator. Statement* convert_shortcut(Block* enclosing, Expression** pshortcut); + + // The IR. + Gogo* gogo_; }; // Remove shortcut operators in a single statement. @@ -1687,7 +1689,7 @@ Shortcuts::variable(Named_object* no) 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); } @@ -1730,7 +1732,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut) 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); @@ -1742,7 +1744,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut) void Gogo::remove_shortcuts() { - Shortcuts shortcuts; + Shortcuts shortcuts(this); this->traverse(&shortcuts); } @@ -1812,9 +1814,10 @@ Find_eval_ordering::expression(Expression** expression_pointer) class Order_eval : public Traverse { public: - Order_eval() + Order_eval(Gogo* gogo) : Traverse(traverse_variables - | traverse_statements) + | traverse_statements), + gogo_(gogo) { } int @@ -1822,6 +1825,10 @@ class Order_eval : public Traverse int statement(Block*, size_t*, Statement*); + + private: + // The IR. + Gogo* gogo_; }; // Implement the order of evaluation rules for a statement. @@ -1942,7 +1949,7 @@ Order_eval::variable(Named_object* no) 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); } @@ -1954,7 +1961,7 @@ Order_eval::variable(Named_object* no) void Gogo::order_evaluations() { - Order_eval order_eval; + Order_eval order_eval(this); this->traverse(&order_eval); } @@ -3155,20 +3162,25 @@ Variable::lower_init_expression(Gogo* gogo, Named_object* function) // 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()); } diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index dd7afc8..0a822c5 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -318,6 +318,11 @@ class Gogo 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 @@ -1143,12 +1148,12 @@ class Variable // 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 diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index b91e2c7..53414eb 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -1657,12 +1657,12 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type, 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 { @@ -1670,7 +1670,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type, // 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; @@ -1724,18 +1724,18 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type, 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; @@ -1790,17 +1790,17 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars, 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; |