aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/rust-gcc.cc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-07-27 13:36:51 +0000
committerGitHub <noreply@github.com>2021-07-27 13:36:51 +0000
commitf76ddb42f82c04baf6b14aef1b532ccb5a0425bb (patch)
tree5b2ddeb0e2c1839ff97d7aa78886345295ef607a /gcc/rust/rust-gcc.cc
parent9526e6d62167ff824814c7ac8c09b36316029262 (diff)
parent7f8adccb5056152edc4aacf08ce2ed040f076171 (diff)
downloadgcc-f76ddb42f82c04baf6b14aef1b532ccb5a0425bb.zip
gcc-f76ddb42f82c04baf6b14aef1b532ccb5a0425bb.tar.gz
gcc-f76ddb42f82c04baf6b14aef1b532ccb5a0425bb.tar.bz2
Merge #598
598: Hello world r=philberty a=philberty ```rust extern "C" { fn puts(s: *const i8); } fn main() { unsafe { let a = "Hello World\0"; let b = a as *const str; let c = b as *const i8; puts(c); } } ``` Fixes #421 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/rust-gcc.cc')
-rw-r--r--gcc/rust/rust-gcc.cc61
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> &parameters,
+ 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 *> &parameters,
Location /* locus */)