aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc19
-rw-r--r--gcc/rust/backend/rust-compile-type.cc54
-rw-r--r--gcc/rust/backend/rust-compile-type.h1
-rw-r--r--gcc/rust/backend/rust-compile.cc31
4 files changed, 86 insertions, 19 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index b176ed2..4168bb8 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1014,13 +1014,28 @@ tree
CompileExpr::compile_string_literal (const HIR::LiteralExpr &expr,
const TyTy::BaseType *tyty)
{
+ tree fat_pointer = TyTyResolveCompile::compile (ctx, tyty);
+
rust_assert (expr.get_lit_type () == HIR::Literal::STRING);
const auto literal_value = expr.get_literal ();
auto base = ctx->get_backend ()->string_constant_expression (
literal_value.as_string ());
- return address_expression (base, build_pointer_type (TREE_TYPE (base)),
- expr.get_locus ());
+ tree data = address_expression (base, build_pointer_type (TREE_TYPE (base)),
+ expr.get_locus ());
+
+ TyTy::BaseType *usize = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
+ rust_assert (ok);
+ tree type = TyTyResolveCompile::compile (ctx, usize);
+
+ mpz_t ival;
+ mpz_init_set_ui (ival, literal_value.as_string ().size ());
+ tree size = double_int_to_tree (type, mpz_get_double_int (type, ival, true));
+
+ return ctx->get_backend ()->constructor_expression (fat_pointer, false,
+ {data, size}, -1,
+ expr.get_locus ());
}
tree
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index 707b2af..6068e0d 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -525,6 +525,7 @@ void
TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
{
const TyTy::SliceType *slice = nullptr;
+ const TyTy::StrType *str = nullptr;
if (type.is_dyn_slice_type (&slice))
{
tree type_record = create_slice_type_record (*slice);
@@ -538,6 +539,18 @@ TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
return;
}
+ else if (type.is_dyn_str_type (&str))
+ {
+ tree type_record = create_str_type_record (*str);
+ std::string dyn_str_type_str
+ = std::string (type.is_mutable () ? "&mut " : "&") + "str";
+
+ translated
+ = ctx->get_backend ()->named_type (dyn_str_type_str, type_record,
+ str->get_locus ());
+
+ return;
+ }
tree base_compiled_type
= TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
@@ -556,6 +569,7 @@ void
TyTyResolveCompile::visit (const TyTy::PointerType &type)
{
const TyTy::SliceType *slice = nullptr;
+ const TyTy::StrType *str = nullptr;
if (type.is_dyn_slice_type (&slice))
{
tree type_record = create_slice_type_record (*slice);
@@ -569,6 +583,18 @@ TyTyResolveCompile::visit (const TyTy::PointerType &type)
return;
}
+ else if (type.is_dyn_str_type (&str))
+ {
+ tree type_record = create_str_type_record (*str);
+ std::string dyn_str_type_str
+ = std::string (type.is_mutable () ? "*mut " : "*const ") + "str";
+
+ translated
+ = ctx->get_backend ()->named_type (dyn_str_type_str, type_record,
+ str->get_locus ());
+
+ return;
+ }
tree base_compiled_type
= TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
@@ -586,7 +612,7 @@ TyTyResolveCompile::visit (const TyTy::PointerType &type)
void
TyTyResolveCompile::visit (const TyTy::StrType &type)
{
- tree raw_str = ctx->get_backend ()->raw_str_type ();
+ tree raw_str = create_str_type_record (type);
translated
= ctx->get_backend ()->named_type ("str", raw_str,
Linemap::predeclared_location ());
@@ -657,5 +683,31 @@ TyTyResolveCompile::create_slice_type_record (const TyTy::SliceType &type)
return record;
}
+tree
+TyTyResolveCompile::create_str_type_record (const TyTy::StrType &type)
+{
+ // lookup usize
+ TyTy::BaseType *usize = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
+ rust_assert (ok);
+
+ tree char_ptr = build_pointer_type (char_type_node);
+ tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
+
+ tree element_type = const_char_type;
+ tree data_field_ty = build_pointer_type (element_type);
+ Backend::typed_identifier data_field ("data", data_field_ty,
+ type.get_locus ());
+
+ tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
+ Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
+
+ tree record = ctx->get_backend ()->struct_type ({data_field, len_field});
+ SLICE_FLAG (record) = 1;
+ TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
+
+ return record;
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index aefacea..c9b6b62 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -62,6 +62,7 @@ public:
protected:
tree create_slice_type_record (const TyTy::SliceType &type);
+ tree create_str_type_record (const TyTy::StrType &type);
private:
TyTyResolveCompile (Context *ctx, bool trait_object_mode);
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 18a2df6..9bcd01c 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -210,6 +210,12 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
if (expected->get_kind () == TyTy::TypeKind::REF)
{
+ // this is a dyn object
+ if (SLICE_TYPE_P (TREE_TYPE (rvalue)))
+ {
+ return rvalue;
+ }
+
// bad coercion... of something to a reference
if (actual->get_kind () != TyTy::TypeKind::REF)
return error_mark_node;
@@ -218,11 +224,6 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
= static_cast<const TyTy::ReferenceType *> (expected);
const TyTy::ReferenceType *act
= static_cast<const TyTy::ReferenceType *> (actual);
- if (act->is_dyn_slice_type ())
- {
- // nothing to do
- return rvalue;
- }
tree expected_type = TyTyResolveCompile::compile (ctx, act->get_base ());
tree deref_rvalue
@@ -232,7 +233,7 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
tree coerced
= coercion_site (deref_rvalue, act->get_base (), exp->get_base (),
lvalue_locus, rvalue_locus);
- if (exp->is_dyn_slice_type () && SLICE_TYPE_P (TREE_TYPE (coerced)))
+ if (exp->is_dyn_object () && SLICE_TYPE_P (TREE_TYPE (coerced)))
return coerced;
return address_expression (coerced,
@@ -241,6 +242,12 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
}
else if (expected->get_kind () == TyTy::TypeKind::POINTER)
{
+ // this is a dyn object
+ if (SLICE_TYPE_P (TREE_TYPE (rvalue)))
+ {
+ return rvalue;
+ }
+
// bad coercion... of something to a reference
bool valid_coercion = actual->get_kind () == TyTy::TypeKind::REF
|| actual->get_kind () == TyTy::TypeKind::POINTER;
@@ -256,11 +263,6 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
{
const TyTy::ReferenceType *act
= static_cast<const TyTy::ReferenceType *> (actual);
- if (act->is_dyn_slice_type ())
- {
- // nothing to do
- return rvalue;
- }
actual_base = act->get_base ();
expected_type = TyTyResolveCompile::compile (ctx, act->get_base ());
@@ -269,11 +271,6 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
{
const TyTy::PointerType *act
= static_cast<const TyTy::PointerType *> (actual);
- if (act->is_dyn_slice_type ())
- {
- // nothing to do
- return rvalue;
- }
actual_base = act->get_base ();
expected_type = TyTyResolveCompile::compile (ctx, act->get_base ());
@@ -286,6 +283,8 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
rvalue_locus);
tree coerced = coercion_site (deref_rvalue, actual_base, exp->get_base (),
lvalue_locus, rvalue_locus);
+ if (exp->is_dyn_object () && SLICE_TYPE_P (TREE_TYPE (coerced)))
+ return coerced;
return address_expression (coerced,
build_pointer_type (TREE_TYPE (coerced)),