diff options
Diffstat (limited to 'gcc/rust/rust-gcc.cc')
-rw-r--r-- | gcc/rust/rust-gcc.cc | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 23a91ad..44617a6 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -256,6 +256,11 @@ public: const std::vector<Btyped_identifier> &, Btype *, const Location); + Btype *function_type_varadic (const Btyped_identifier &, + const std::vector<Btyped_identifier> &, + const std::vector<Btyped_identifier> &, Btype *, + const Location); + Btype *function_ptr_type (Btype *, const std::vector<Btype *> &, Location); Btype *struct_type (const std::vector<Btyped_identifier> &); @@ -1049,6 +1054,62 @@ Gcc_backend::function_type (const Btyped_identifier &receiver, } Btype * +Gcc_backend::function_type_varadic ( + const Btyped_identifier &receiver, + const std::vector<Btyped_identifier> ¶meters, + const std::vector<Btyped_identifier> &results, Btype *result_struct, Location) +{ + size_t n = parameters.size () + (receiver.btype != NULL ? 1 : 0); + tree *args = XALLOCAVEC (tree, n); + size_t offs = 0; + + if (receiver.btype != NULL) + { + tree t = receiver.btype->get_tree (); + if (t == error_mark_node) + return this->error_type (); + + args[offs++] = t; + } + + for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin (); + p != parameters.end (); ++p) + { + tree t = p->btype->get_tree (); + if (t == error_mark_node) + return this->error_type (); + args[offs++] = t; + } + + tree result; + if (results.empty ()) + result = void_type_node; + else if (results.size () == 1) + result = results.front ().btype->get_tree (); + else + { + gcc_assert (result_struct != NULL); + result = result_struct->get_tree (); + } + if (result == error_mark_node) + return this->error_type (); + + // 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 this->error_type (); + + return this->make_type (build_pointer_type (fntype)); +} + +Btype * Gcc_backend::function_ptr_type (Btype *result_type, const std::vector<Btype *> ¶meters, Location /* locus */) |