aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-03-11 11:22:07 +0000
committerPhilip Herron <philip.herron@embecosm.com>2022-03-11 13:54:21 +0000
commit040b2ec9a6b20aa2441951e47f344d303dd61d7e (patch)
tree031aecbdcf83d4a96ffe751238266a192de83b66
parente076823eda8f11425a705a191d686e9e48be2fc4 (diff)
downloadgcc-040b2ec9a6b20aa2441951e47f344d303dd61d7e.zip
gcc-040b2ec9a6b20aa2441951e47f344d303dd61d7e.tar.gz
gcc-040b2ec9a6b20aa2441951e47f344d303dd61d7e.tar.bz2
Add code generation for the slice type
This type must respect the layout of the FatPtr type in libcore. Rust implements slices using Rustc types in libcore and uses a neat trick. The slice is generated into the FatPtr which contains the pointer and length of the slice. This is then placed into a union called Repr which has 3 variants a mutable and immutable pointer to the FatPtr and a final variant which is the raw FatPtr. This means we can use unsafe access to the union to gain a pointer to the FatPtr. Addresses #849
-rw-r--r--gcc/rust/backend/rust-compile-type.cc34
-rw-r--r--gcc/testsuite/rust/execute/torture/slice1.rs27
2 files changed, 59 insertions, 2 deletions
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index ba6a206..07b95c7 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -349,8 +349,38 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
void
TyTyResolveCompile::visit (const TyTy::SliceType &type)
{
- // TODO
- gcc_unreachable ();
+ if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type))
+ return;
+
+ std::vector<Backend::typed_identifier> fields;
+
+ tree element_type
+ = TyTyResolveCompile::compile (ctx, type.get_element_type ());
+ tree data_field_ty = build_pointer_type (element_type);
+ Backend::typed_identifier data_field ("data", data_field_ty, Location ());
+ fields.push_back (std::move (data_field));
+
+ // lookup usize
+ TyTy::BaseType *usize = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
+ rust_assert (ok);
+
+ tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
+ Backend::typed_identifier len_field ("len", len_field_ty, Location ());
+ fields.push_back (std::move (len_field));
+
+ tree type_record = ctx->get_backend ()->struct_type (fields);
+
+ std::string named_struct_str
+ = std::string ("[") + type.get_element_type ()->get_name () + "]";
+ tree named_struct
+ = ctx->get_backend ()->named_type (named_struct_str, type_record,
+ type.get_ident ().locus);
+
+ ctx->push_type (named_struct);
+ translated = named_struct;
+
+ ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
}
void
diff --git a/gcc/testsuite/rust/execute/torture/slice1.rs b/gcc/testsuite/rust/execute/torture/slice1.rs
new file mode 100644
index 0000000..a0488b3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/slice1.rs
@@ -0,0 +1,27 @@
+// { dg-additional-options "-w" }
+struct FatPtr<T> {
+ data: *const T,
+ len: usize,
+}
+
+union Repr<T> {
+ rust: *const [T],
+ rust_mut: *mut [T],
+ raw: FatPtr<T>,
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+ unsafe {
+ let a = FatPtr { data, len };
+ let b = Repr { raw: a };
+ b.rust
+ }
+}
+
+fn main() -> i32 {
+ let a = 123;
+ let b: *const i32 = &a;
+ let c = slice_from_raw_parts(b, 1);
+
+ 0
+}