diff options
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r-- | gcc/go/go-gcc.cc | 44 |
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* |