From 7d4845bc958712b3a437ad636d64fc241610fbc0 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 24 Feb 2022 11:49:51 +0000 Subject: Add code generation for range expressions --- gcc/rust/backend/rust-compile-expr.cc | 107 ++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'gcc/rust/backend/rust-compile-expr.cc') diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 65f159e..e2d1138 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -1377,5 +1377,112 @@ CompileExpr::visit (HIR::IdentifierExpr &expr) } } +void +CompileExpr::visit (HIR::RangeFromToExpr &expr) +{ + tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx); + tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx); + if (from == error_mark_node || to == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {from, to}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeFromExpr &expr) +{ + tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx); + if (from == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {from}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeToExpr &expr) +{ + tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx); + if (to == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {to}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeFullExpr &expr) +{ + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + translated = ctx->get_backend ()->constructor_expression (adt, false, {}, -1, + expr.get_locus ()); +} + +void +CompileExpr::visit (HIR::RangeFromToInclExpr &expr) +{ + tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx); + tree to = CompileExpr::Compile (expr.get_to_expr ().get (), ctx); + if (from == error_mark_node || to == error_mark_node) + { + translated = error_mark_node; + return; + } + + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), &tyty); + rust_assert (ok); + + tree adt = TyTyResolveCompile::compile (ctx, tyty); + + // make the constructor + translated + = ctx->get_backend ()->constructor_expression (adt, false, {from, to}, -1, + expr.get_locus ()); +} + } // namespace Compile } // namespace Rust -- cgit v1.1 From a6dd242845303f44f38035189fd9360c7f572dfc Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 24 Feb 2022 11:59:16 +0000 Subject: Refactor ArrayIndexExpr code into implementation cc file --- gcc/rust/backend/rust-compile-expr.cc | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'gcc/rust/backend/rust-compile-expr.cc') diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index e2d1138..6849471 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -1484,5 +1484,36 @@ CompileExpr::visit (HIR::RangeFromToInclExpr &expr) expr.get_locus ()); } +void +CompileExpr::visit (HIR::ArrayIndexExpr &expr) +{ + tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx); + tree index = CompileExpr::Compile (expr.get_index_expr (), ctx); + + // lets check if the array is a reference type then we can add an + // indirection if required + TyTy::BaseType *array_expr_ty = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + expr.get_array_expr ()->get_mappings ().get_hirid (), &array_expr_ty); + rust_assert (ok); + + // do we need to add an indirect reference + if (array_expr_ty->get_kind () == TyTy::TypeKind::REF) + { + TyTy::ReferenceType *r + = static_cast (array_expr_ty); + TyTy::BaseType *tuple_type = r->get_base (); + tree array_tyty = TyTyResolveCompile::compile (ctx, tuple_type); + + array_reference + = ctx->get_backend ()->indirect_expression (array_tyty, array_reference, + true, expr.get_locus ()); + } + + translated + = ctx->get_backend ()->array_index_expression (array_reference, index, + expr.get_locus ()); +} + } // namespace Compile } // namespace Rust -- cgit v1.1 From d8351d9168f92c997858fdb25942c05dc832f330 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 24 Feb 2022 16:22:29 +0000 Subject: Decouple the HIR::OperatorExpr from resolving operator overloads This means we can reuse the same code for operations that are not HIR::OperatorExpr's such as ArrayIndexExpr which can resolve to core::ops::index lang items. --- gcc/rust/backend/rust-compile-expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/rust/backend/rust-compile-expr.cc') diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 6849471..dfe5231 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -790,7 +790,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref, tree CompileExpr::resolve_operator_overload ( - Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExpr &expr, + Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExprMeta expr, tree lhs, tree rhs, HIR::Expr *lhs_expr, HIR::Expr *rhs_expr) { TyTy::FnType *fntype; -- cgit v1.1 From 22c6bca60a9bc80c043e4da9a94cb80023dde04c Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 24 Feb 2022 16:59:05 +0000 Subject: Add support for index lang item overloads This reuses our code to resolve operator overloads to call into the index lang item for the array-index-expression this serves as a basis for supporting slices. Fixes #975 --- gcc/rust/backend/rust-compile-expr.cc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'gcc/rust/backend/rust-compile-expr.cc') diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index dfe5231..bf47661 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -1490,6 +1490,35 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr) tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx); tree index = CompileExpr::Compile (expr.get_index_expr (), ctx); + // this might be an core::ops::index lang item situation + TyTy::FnType *fntype; + bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload ( + expr.get_mappings ().get_hirid (), &fntype); + if (is_op_overload) + { + auto lang_item_type = Analysis::RustLangItem::ItemType::INDEX; + tree operator_overload_call + = resolve_operator_overload (lang_item_type, expr, array_reference, + index, expr.get_array_expr (), + expr.get_index_expr ()); + + // lookup the expected type for this expression + TyTy::BaseType *tyty = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), + &tyty); + rust_assert (ok); + tree expected_type = TyTyResolveCompile::compile (ctx, tyty); + + // rust deref always returns a reference from this overload then we can + // actually do the indirection + translated + = ctx->get_backend ()->indirect_expression (expected_type, + operator_overload_call, + true, expr.get_locus ()); + return; + } + // lets check if the array is a reference type then we can add an // indirection if required TyTy::BaseType *array_expr_ty = nullptr; -- cgit v1.1