aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Manghane <cmang@google.com>2014-04-22 23:46:30 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2014-04-22 23:46:30 +0000
commitaa4929209a17cc4070b900d9bd2947b50c6f83d1 (patch)
tree4a57f96317acc5e134415f90f182cd3b815dc14b
parent2195867f1d6cdc9e8d36aeeefc3c0f000bccbda3 (diff)
downloadgcc-aa4929209a17cc4070b900d9bd2947b50c6f83d1.zip
gcc-aa4929209a17cc4070b900d9bd2947b50c6f83d1.tar.gz
gcc-aa4929209a17cc4070b900d9bd2947b50c6f83d1.tar.bz2
compiler: Use backend interface for initialization functions.
* go-gcc.cc (Gcc_backend::temporary_variable): Push cfun around call to create_tmp_var. Require that function be non-NULL. From-SVN: r209665
-rw-r--r--gcc/go/ChangeLog5
-rw-r--r--gcc/go/go-gcc.cc24
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc103
-rw-r--r--gcc/go/gofrontend/gogo.cc56
-rw-r--r--gcc/go/gofrontend/gogo.h12
5 files changed, 91 insertions, 109 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index c8beaec..966fd42 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-22 Chris Manghane <cmang@google.com>
+
+ * go-gcc.cc (Gcc_backend::temporary_variable): Push cfun around
+ call to create_tmp_var. Require that function be non-NULL.
+
2014-04-17 Chris Manghane <cmang@google.com>
* go-gcc.cc (Gcc_backend::named_constant_expression): New
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 1af639e..376e4dc 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -2214,10 +2214,21 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
return this->error_variable();
}
+ go_assert(function != NULL);
+ tree decl = function->get_tree();
+
tree var;
// We can only use create_tmp_var if the type is not addressable.
if (!TREE_ADDRESSABLE(type_tree))
- var = create_tmp_var(type_tree, "GOTMP");
+ {
+ if (DECL_STRUCT_FUNCTION(decl) == NULL)
+ push_struct_function(decl);
+ else
+ push_cfun(DECL_STRUCT_FUNCTION(decl));
+
+ var = create_tmp_var(type_tree, "GOTMP");
+ pop_cfun();
+ }
else
{
gcc_assert(bblock != NULL);
@@ -2227,16 +2238,7 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
DECL_ARTIFICIAL(var) = 1;
DECL_IGNORED_P(var) = 1;
TREE_USED(var) = 1;
- // FIXME: Permitting function to be NULL here is a temporary
- // measure until we have a proper representation of the init
- // function.
- if (function != NULL)
- DECL_CONTEXT(var) = function->get_tree();
- else
- {
- gcc_assert(current_function_decl != NULL_TREE);
- DECL_CONTEXT(var) = current_function_decl;
- }
+ DECL_CONTEXT(var) = decl;
// We have to add this variable to the BLOCK and the BIND_EXPR.
tree bind_tree = bblock->get_tree();
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index 32a7f38..c00e7d1 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -236,32 +236,6 @@ Gogo::define_builtin_function_trees()
false);
}
-// Get the name to use for the import control function. If there is a
-// global function or variable, then we know that that name must be
-// unique in the link, and we use it as the basis for our name.
-
-const std::string&
-Gogo::get_init_fn_name()
-{
- if (this->init_fn_name_.empty())
- {
- go_assert(this->package_ != NULL);
- if (this->is_main_package())
- {
- // Use a name which the runtime knows.
- this->init_fn_name_ = "__go_init_main";
- }
- else
- {
- std::string s = this->pkgpath_symbol();
- s.append("..import");
- this->init_fn_name_ = s;
- }
- }
-
- return this->init_fn_name_;
-}
-
// Add statements to INIT_STMT_LIST which run the initialization
// functions for imported packages. This is only used for the "main"
// package.
@@ -434,65 +408,31 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
append_to_statement_list(call, init_stmt_list);
}
-// Build the decl for the initialization function.
-
-tree
-Gogo::initialization_function_decl()
-{
- // The tedious details of building your own function. There doesn't
- // seem to be a helper function for this.
- std::string name = this->package_name() + ".init";
- tree fndecl = build_decl(this->package_->location().gcc_location(),
- FUNCTION_DECL, get_identifier_from_string(name),
- build_function_type(void_type_node,
- void_list_node));
- const std::string& asm_name(this->get_init_fn_name());
- SET_DECL_ASSEMBLER_NAME(fndecl, get_identifier_from_string(asm_name));
-
- tree resdecl = build_decl(this->package_->location().gcc_location(),
- RESULT_DECL, NULL_TREE, void_type_node);
- DECL_ARTIFICIAL(resdecl) = 1;
- DECL_CONTEXT(resdecl) = fndecl;
- DECL_RESULT(fndecl) = resdecl;
-
- TREE_STATIC(fndecl) = 1;
- TREE_USED(fndecl) = 1;
- DECL_ARTIFICIAL(fndecl) = 1;
- TREE_PUBLIC(fndecl) = 1;
-
- DECL_INITIAL(fndecl) = make_node(BLOCK);
- TREE_USED(DECL_INITIAL(fndecl)) = 1;
-
- return fndecl;
-}
-
// Create the magic initialization function. INIT_STMT_LIST is the
// code that it needs to run.
void
-Gogo::write_initialization_function(tree fndecl, tree init_stmt_list)
+Gogo::write_initialization_function(Named_object* initfn, tree init_stmt_list)
{
// Make sure that we thought we needed an initialization function,
// as otherwise we will not have reported it in the export data.
go_assert(this->is_main_package() || this->need_init_fn_);
- if (fndecl == NULL_TREE)
- fndecl = this->initialization_function_decl();
+ if (initfn == NULL)
+ initfn = this->initialization_function_decl();
- DECL_SAVED_TREE(fndecl) = init_stmt_list;
-
- if (DECL_STRUCT_FUNCTION(fndecl) == NULL)
- push_struct_function(fndecl);
- else
- push_cfun(DECL_STRUCT_FUNCTION(fndecl));
- cfun->function_start_locus = this->package_->location().gcc_location();
- cfun->function_end_locus = cfun->function_start_locus;
+ Bfunction* fndecl = initfn->func_value()->get_or_make_decl(this, initfn);
+ Location loc = this->package_->location();
+ std::vector<Bvariable*> vars;
+ this->backend()->block(fndecl, NULL, vars, loc, loc);
- gimplify_function_tree(fndecl);
-
- cgraph_add_new_function(fndecl, false);
-
- pop_cfun();
+ if (!this->backend()->function_set_body(fndecl, tree_to_stat(init_stmt_list)))
+ {
+ go_assert(saw_errors());
+ return;
+ }
+ gimplify_function_tree(function_to_tree(fndecl));
+ cgraph_add_new_function(function_to_tree(fndecl), false);
}
// Search for references to VAR in any statements or called functions.
@@ -775,7 +715,7 @@ Gogo::write_globals()
tree* vec = new tree[count];
- tree init_fndecl = NULL_TREE;
+ Named_object* init_fndecl = NULL;
tree init_stmt_list = NULL_TREE;
if (this->is_main_package())
@@ -902,17 +842,12 @@ Gogo::write_globals()
{
// We are going to create temporary variables which
// means that we need an fndecl.
- if (init_fndecl == NULL_TREE)
+ if (init_fndecl == NULL)
init_fndecl = this->initialization_function_decl();
- if (DECL_STRUCT_FUNCTION(init_fndecl) == NULL)
- push_struct_function(init_fndecl);
- else
- push_cfun(DECL_STRUCT_FUNCTION(init_fndecl));
+
Bvariable* var_decl = is_sink ? NULL : var;
var_init_stmt =
- no->var_value()->get_init_block(this, NULL, var_decl);
-
- pop_cfun();
+ no->var_value()->get_init_block(this, init_fndecl, var_decl);
}
if (var_init_stmt != NULL)
@@ -975,7 +910,7 @@ Gogo::write_globals()
// Set up a magic function to do all the initialization actions.
// This will be called if this package is imported.
- if (init_stmt_list != NULL_TREE
+ if (init_stmt_list != NULL
|| this->need_init_fn_
|| this->is_main_package())
this->write_initialization_function(init_fndecl, init_stmt_list);
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 6df4b6b..ac9510e 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -575,6 +575,45 @@ Gogo::current_bindings() const
return this->globals_;
}
+// Get the name to use for the import control function. If there is a
+// global function or variable, then we know that that name must be
+// unique in the link, and we use it as the basis for our name.
+
+const std::string&
+Gogo::get_init_fn_name()
+{
+ if (this->init_fn_name_.empty())
+ {
+ go_assert(this->package_ != NULL);
+ if (this->is_main_package())
+ {
+ // Use a name which the runtime knows.
+ this->init_fn_name_ = "__go_init_main";
+ }
+ else
+ {
+ std::string s = this->pkgpath_symbol();
+ s.append("..import");
+ this->init_fn_name_ = s;
+ }
+ }
+
+ return this->init_fn_name_;
+}
+
+// Build the decl for the initialization function.
+
+Named_object*
+Gogo::initialization_function_decl()
+{
+ std::string name = this->get_init_fn_name();
+ Location loc = this->package_->location();
+
+ Function_type* fntype = Type::make_function_type(NULL, NULL, NULL, loc);
+ Function* initfn = new Function(fntype, NULL, NULL, loc);
+ return Named_object::make_function(name, NULL, initfn);
+}
+
// Return the current block.
Block*
@@ -4071,7 +4110,12 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
;
else if (Gogo::unpack_hidden_name(no->name()) == "init"
&& !this->type_->is_method())
- ;
+ ;
+ else if (no->name() == gogo->get_init_fn_name())
+ {
+ is_visible = true;
+ asm_name = no->name();
+ }
else if (Gogo::unpack_hidden_name(no->name()) == "main"
&& gogo->is_main_package())
is_visible = true;
@@ -4647,13 +4691,9 @@ Block::get_backend(Translate_context* context)
vars.push_back((*pv)->get_backend_variable(gogo, function));
}
- // FIXME: Permitting FUNCTION to be NULL here is a temporary measure
- // until we have a proper representation of the init function.
- Bfunction* bfunction;
- if (function == NULL)
- bfunction = NULL;
- else
- bfunction = tree_to_function(function->func_value()->get_decl());
+ go_assert(function != NULL);
+ Bfunction* bfunction =
+ function->func_value()->get_or_make_decl(gogo, function);
Bblock* ret = context->backend()->block(bfunction, context->bblock(),
vars, this->start_location_,
this->end_location_);
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 3dc401d..dd43d26 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -616,6 +616,10 @@ class Gogo
Expression*
allocate_memory(Type *type, Location);
+ // Get the name of the magic initialization function.
+ const std::string&
+ get_init_fn_name();
+
private:
// During parsing, we keep a stack of functions. Each function on
// the stack is one that we are currently parsing. For each
@@ -642,17 +646,13 @@ class Gogo
const Bindings*
current_bindings() const;
- // Get the name of the magic initialization function.
- const std::string&
- get_init_fn_name();
-
// Get the decl for the magic initialization function.
- tree
+ Named_object*
initialization_function_decl();
// Write the magic initialization function.
void
- write_initialization_function(tree fndecl, tree init_stmt_list);
+ write_initialization_function(Named_object* fndecl, tree init_stmt_list);
// Initialize imported packages.
void