diff options
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 19 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-type.cc | 54 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-type.h | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 31 |
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)), |