aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/rust-gcc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/rust-gcc.cc')
-rw-r--r--gcc/rust/rust-gcc.cc116
1 files changed, 8 insertions, 108 deletions
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index d406b59..c86804e 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -98,19 +98,6 @@ public:
// Types.
- tree unit_type ()
- {
- static tree unit_type;
- if (unit_type == nullptr)
- {
- auto unit_type_node = struct_type ({});
- unit_type = named_type ("()", unit_type_node,
- ::Linemap::predeclared_location ());
- }
-
- return unit_type;
- }
-
tree bool_type () { return boolean_type_node; }
tree char_type () { return char_type_node; }
@@ -170,8 +157,6 @@ public:
tree zero_expression (tree);
- tree unit_expression () { return integer_zero_node; }
-
tree var_expression (Bvariable *var, Location);
tree integer_constant_expression (tree type, mpz_t val);
@@ -236,7 +221,7 @@ public:
tree assignment_statement (tree lhs, tree rhs, Location);
- tree return_statement (tree, const std::vector<tree> &, Location);
+ tree return_statement (tree fndecl, tree val, Location locus);
tree if_statement (tree, tree condition, tree then_block, tree else_block,
Location);
@@ -720,14 +705,6 @@ Gcc_backend::function_type (const typed_identifier &receiver,
if (result == error_mark_node)
return error_mark_node;
- // The libffi library cannot represent a zero-sized object. To
- // avoid causing confusion on 32-bit SPARC, we treat a function that
- // returns a zero-sized value as returning void. That should do no
- // harm since there is no actual value to be returned. See
- // https://gcc.gnu.org/PR72814 for details.
- if (result != void_type_node && int_size_in_bytes (result) == 0)
- result = void_type_node;
-
tree fntype = build_function_type (result, args);
if (fntype == error_mark_node)
return error_mark_node;
@@ -776,14 +753,6 @@ Gcc_backend::function_type_varadic (
if (result == error_mark_node)
return error_mark_node;
- // The libffi library cannot represent a zero-sized object. To
- // avoid causing confusion on 32-bit SPARC, we treat a function that
- // returns a zero-sized value as returning void. That should do no
- // harm since there is no actual value to be returned. See
- // https://gcc.gnu.org/PR72814 for details.
- if (result != void_type_node && int_size_in_bytes (result) == 0)
- result = void_type_node;
-
tree fntype = build_varargs_function_type_array (result, n, args);
if (fntype == error_mark_node)
return error_mark_node;
@@ -1988,90 +1957,21 @@ Gcc_backend::assignment_statement (tree lhs, tree rhs, Location location)
// Return.
tree
-Gcc_backend::return_statement (tree fntree, const std::vector<tree> &vals,
- Location location)
+Gcc_backend::return_statement (tree fntree, tree val, Location location)
{
if (fntree == error_mark_node)
return error_mark_node;
+
tree result = DECL_RESULT (fntree);
if (result == error_mark_node)
return error_mark_node;
- // If the result size is zero bytes, we have set the function type
- // to have a result type of void, so don't return anything.
- // See the function_type method.
- tree res_type = TREE_TYPE (result);
- if (res_type == void_type_node || int_size_in_bytes (res_type) == 0)
- {
- tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = vals.begin ();
- p != vals.end (); p++)
- {
- tree val = (*p);
- if (val == error_mark_node)
- return error_mark_node;
- append_to_statement_list (val, &stmt_list);
- }
- tree ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, NULL_TREE);
- append_to_statement_list (ret, &stmt_list);
- return stmt_list;
- }
-
- tree ret;
- if (vals.empty ())
- ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, NULL_TREE);
- else if (vals.size () == 1)
- {
- tree val = vals.front ();
- if (val == error_mark_node)
- return error_mark_node;
- tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, result, vals.front ());
- ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, set);
- }
- else
- {
- // To return multiple values, copy the values into a temporary
- // variable of the right structure type, and then assign the
- // temporary variable to the DECL_RESULT in the return
- // statement.
- tree stmt_list = NULL_TREE;
- tree rettype = TREE_TYPE (result);
-
- if (DECL_STRUCT_FUNCTION (fntree) == NULL)
- push_struct_function (fntree);
- else
- push_cfun (DECL_STRUCT_FUNCTION (fntree));
- tree rettmp = create_tmp_var (rettype, "RESULT");
- pop_cfun ();
+ if (val == error_mark_node)
+ return error_mark_node;
- tree field = TYPE_FIELDS (rettype);
- for (std::vector<tree>::const_iterator p = vals.begin ();
- p != vals.end (); p++, field = DECL_CHAIN (field))
- {
- gcc_assert (field != NULL_TREE);
- tree ref
- = fold_build3_loc (location.gcc_location (), COMPONENT_REF,
- TREE_TYPE (field), rettmp, field, NULL_TREE);
- tree val = (*p);
- if (val == error_mark_node)
- return error_mark_node;
- tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, ref, (*p));
- append_to_statement_list (set, &stmt_list);
- }
- gcc_assert (field == NULL_TREE);
- tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, result, rettmp);
- tree ret_expr = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, set);
- append_to_statement_list (ret_expr, &stmt_list);
- ret = stmt_list;
- }
- return ret;
+ auto locus = location.gcc_location ();
+ tree set = fold_build2_loc (locus, MODIFY_EXPR, void_type_node, result, val);
+ return fold_build1_loc (locus, RETURN_EXPR, void_type_node, set);
}
// Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an