aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/go-gcc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r--gcc/go/go-gcc.cc44
1 files changed, 42 insertions, 2 deletions
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index d8b80b6..1ce1ff2 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -322,7 +322,7 @@ class Gcc_backend : public Backend
Bexpression*
call_expression(Bexpression* fn, const std::vector<Bexpression*>& args,
- Location);
+ Bexpression* static_chain, Location);
// Statements.
@@ -403,6 +403,9 @@ class Gcc_backend : public Backend
Location);
Bvariable*
+ static_chain_variable(Bfunction*, const std::string&, Btype*, Location);
+
+ Bvariable*
temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
Location, Bstatement**);
@@ -1808,7 +1811,7 @@ Gcc_backend::array_index_expression(Bexpression* array, Bexpression* index,
Bexpression*
Gcc_backend::call_expression(Bexpression* fn_expr,
const std::vector<Bexpression*>& fn_args,
- Location location)
+ Bexpression* chain_expr, Location location)
{
tree fn = fn_expr->get_tree();
if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node)
@@ -1868,6 +1871,9 @@ Gcc_backend::call_expression(Bexpression* fn_expr,
excess_type != NULL_TREE ? excess_type : rettype,
fn, nargs, args);
+ if (chain_expr)
+ CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree();
+
if (excess_type != NULL_TREE)
{
// Calling convert here can undo our excess precision change.
@@ -2489,6 +2495,40 @@ Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
return new Bvariable(decl);
}
+// Make a static chain variable.
+
+Bvariable*
+Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
+ Btype* btype, Location location)
+{
+ tree type_tree = btype->get_tree();
+ if (type_tree == error_mark_node)
+ return this->error_variable();
+ tree decl = build_decl(location.gcc_location(), PARM_DECL,
+ get_identifier_from_string(name), type_tree);
+ tree fndecl = function->get_tree();
+ DECL_CONTEXT(decl) = fndecl;
+ DECL_ARG_TYPE(decl) = type_tree;
+ TREE_USED(decl) = 1;
+ DECL_ARTIFICIAL(decl) = 1;
+ DECL_IGNORED_P(decl) = 1;
+ TREE_READONLY(decl) = 1;
+
+ struct function *f = DECL_STRUCT_FUNCTION(fndecl);
+ if (f == NULL)
+ {
+ push_struct_function(fndecl);
+ pop_cfun();
+ f = DECL_STRUCT_FUNCTION(fndecl);
+ }
+ gcc_assert(f->static_chain_decl == NULL);
+ f->static_chain_decl = decl;
+ DECL_STATIC_CHAIN(fndecl) = 1;
+
+ go_preserve_from_gc(decl);
+ return new Bvariable(decl);
+}
+
// Make a temporary variable.
Bvariable*