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-block.h3
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc120
-rw-r--r--gcc/rust/backend/rust-compile-expr.h2
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc69
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc15
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.h1
-rw-r--r--gcc/rust/backend/rust-compile.cc15
7 files changed, 94 insertions, 131 deletions
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index 0595ee9..e3c7399 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -46,7 +46,6 @@ public:
void visit (HIR::StructExprFieldIndexValue &) override {}
void visit (HIR::StructExprStruct &) override {}
void visit (HIR::StructExprStructFields &) override {}
- void visit (HIR::IdentifierExpr &) override {}
void visit (HIR::LiteralExpr &) override {}
void visit (HIR::BorrowExpr &) override {}
void visit (HIR::DereferenceExpr &) override {}
@@ -126,7 +125,6 @@ public:
void visit (HIR::StructExprFieldIndexValue &) override {}
void visit (HIR::StructExprStruct &) override {}
void visit (HIR::StructExprStructFields &) override {}
- void visit (HIR::IdentifierExpr &) override {}
void visit (HIR::LiteralExpr &) override {}
void visit (HIR::BorrowExpr &) override {}
void visit (HIR::DereferenceExpr &) override {}
@@ -216,7 +214,6 @@ public:
void visit (HIR::StructExprFieldIndexValue &) override {}
void visit (HIR::StructExprStruct &) override {}
void visit (HIR::StructExprStructFields &) override {}
- void visit (HIR::IdentifierExpr &) override {}
void visit (HIR::LiteralExpr &) override {}
void visit (HIR::BorrowExpr &) override {}
void visit (HIR::DereferenceExpr &) override {}
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 38d10d2..bfaa7fc 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -692,12 +692,6 @@ CompileExpr::visit (HIR::MatchExpr &expr)
}
break;
- case HIR::Expr::ExprType::Ident: {
- // FIXME
- gcc_unreachable ();
- }
- break;
-
case HIR::Expr::ExprType::Path: {
// FIXME
gcc_unreachable ();
@@ -1809,120 +1803,6 @@ HIRCompileBase::resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
}
void
-CompileExpr::visit (HIR::IdentifierExpr &expr)
-{
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
-
- bool is_value = false;
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (ctx->get_resolver ()->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- is_value = true;
- }
- else if (!ctx->get_resolver ()->lookup_resolved_type (ast_node_id,
- &ref_node_id))
- {
- rust_error_at (expr.get_locus (),
- "Failed to lookup type reference for node: %s",
- expr.as_string ().c_str ());
- return;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- {
- rust_fatal_error (expr.get_locus (), "unresolved IdentifierExpr: %s",
- expr.as_string ().c_str ());
- return;
- }
-
- // node back to HIR
- HirId ref;
- if (!ctx->get_mappings ()->lookup_node_to_hir (ref_node_id, &ref))
- {
- rust_error_at (expr.get_locus (), "reverse lookup failure");
- return;
- }
-
- TyTy::BaseType *lookup = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (ref, &lookup))
- {
- rust_fatal_error (expr.get_locus (),
- "failed to find type relevant to this context: %s",
- expr.get_mappings ().as_string ().c_str ());
- return;
- }
-
- bool is_type_ref = !is_value;
- if (is_type_ref)
- {
- // this might be a case for
- //
- // struct S;
- //
- // fn main() {
- // let s = S;
- // }
-
- if (lookup->is_unit ())
- {
- translated = ctx->get_backend ()->unit_expression ();
- return;
- }
-
- // rust actually treats like this an fn call or structs with fields but
- // unit structs are just the struct name lets catch it with an is-unit
- // check
- gcc_unreachable ();
- }
-
- tree fn = NULL_TREE;
- Bvariable *var = nullptr;
- if (ctx->lookup_const_decl (ref, &translated))
- {
- TREE_USED (translated) = 1;
- return;
- }
- else if (ctx->lookup_function_decl (ref, &fn))
- {
- TREE_USED (fn) = 1;
- translated = address_expression (fn, expr.get_locus ());
- }
- else if (ctx->lookup_var_decl (ref, &var))
- {
- // TREE_USED is setup in the gcc abstraction here
- translated = ctx->get_backend ()->var_expression (var, expr.get_locus ());
- }
- else if (ctx->lookup_pattern_binding (ref, &translated))
- {
- TREE_USED (translated) = 1;
- return;
- }
- else
- {
- // lets try and query compile it to an item/impl item
- HIR::Item *resolved_item = ctx->get_mappings ()->lookup_hir_item (ref);
- bool is_hir_item = resolved_item != nullptr;
- if (!is_hir_item)
- {
- translated = error_mark_node;
- return;
- }
-
- if (!lookup->has_subsititions_defined ())
- translated = CompileItem::compile (resolved_item, ctx, nullptr, true,
- expr.get_locus ());
- else
- translated = CompileItem::compile (resolved_item, ctx, lookup, true,
- expr.get_locus ());
-
- if (translated != error_mark_node)
- {
- TREE_USED (translated) = 1;
- }
- }
-}
-
-void
CompileExpr::visit (HIR::RangeFromToExpr &expr)
{
tree from = CompileExpr::Compile (expr.get_from_expr ().get (), ctx);
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 9b8976d..69f9492 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -118,8 +118,6 @@ public:
void visit (HIR::MethodCallExpr &expr) override;
- void visit (HIR::IdentifierExpr &expr) override;
-
void visit (HIR::LiteralExpr &expr) override
{
TyTy::BaseType *tyty = nullptr;
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 67e38c3..06dc457 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -37,6 +37,8 @@ static tree
transmute_handler (Context *ctx, TyTy::FnType *fntype);
static tree
rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
+static tree
+wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
static inline tree
rotate_left_handler (Context *ctx, TyTy::FnType *fntype)
@@ -49,13 +51,32 @@ rotate_right_handler (Context *ctx, TyTy::FnType *fntype)
return rotate_handler (ctx, fntype, RROTATE_EXPR);
}
+static inline tree
+wrapping_add_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ return wrapping_op_handler (ctx, fntype, PLUS_EXPR);
+}
+static inline tree
+wrapping_sub_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ return wrapping_op_handler (ctx, fntype, MINUS_EXPR);
+}
+static inline tree
+wrapping_mul_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ return wrapping_op_handler (ctx, fntype, MULT_EXPR);
+}
+
static const std::map<std::string,
std::function<tree (Context *, TyTy::FnType *)>>
generic_intrinsics = {{"offset", &offset_handler},
{"size_of", &sizeof_handler},
{"transmute", &transmute_handler},
{"rotate_left", &rotate_left_handler},
- {"rotate_right", &rotate_right_handler}};
+ {"rotate_right", &rotate_right_handler},
+ {"wrapping_add", &wrapping_add_handler},
+ {"wrapping_sub", &wrapping_sub_handler},
+ {"wrapping_mul", &wrapping_mul_handler}};
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -373,5 +394,51 @@ rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
return fndecl;
}
+/**
+ * pub fn wrapping_{add, sub, mul}<T>(lhs: T, rhs: T) -> T;
+ */
+static tree
+wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
+{
+ // wrapping_<op> intrinsics have two parameter
+ rust_assert (fntype->get_params ().size () == 2);
+
+ tree lookup = NULL_TREE;
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+ return lookup;
+
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+ // setup the params
+ std::vector<Bvariable *> param_vars;
+ compile_fn_params (ctx, fntype, fndecl, &param_vars);
+
+ auto &lhs_param = param_vars.at (0);
+ auto &rhs_param = param_vars.at (1);
+ if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+ return error_mark_node;
+
+ enter_intrinsic_block (ctx, fndecl);
+
+ // BUILTIN wrapping_<op> FN BODY BEGIN
+ auto lhs = ctx->get_backend ()->var_expression (lhs_param, Location ());
+ auto rhs = ctx->get_backend ()->var_expression (rhs_param, Location ());
+
+ // Operations are always wrapping in Rust, as we have -fwrapv enabled by
+ // default. The difference between a wrapping_{add, sub, mul} and a regular
+ // arithmetic operation is that these intrinsics do not panic - they always
+ // carry over.
+ auto wrap_expr = build2 (op, TREE_TYPE (lhs), lhs, rhs);
+
+ auto return_statement
+ = ctx->get_backend ()->return_statement (fndecl, {wrap_expr}, Location ());
+ ctx->add_statement (return_statement);
+ // BUILTIN wrapping_<op> FN BODY END
+
+ finalize_intrinsic_block (ctx, fndecl);
+
+ return fndecl;
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 8c1b7ef..f799445 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -64,6 +64,13 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
return error_mark_node;
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup);
+
+ // it might be a unit-struct
+ if (adt->is_unit ())
+ {
+ return ctx->get_backend ()->unit_expression ();
+ }
+
if (!adt->is_enum ())
return error_mark_node;
@@ -121,6 +128,14 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
return ctx->get_backend ()->var_expression (var, expr_locus);
}
+ // might be a match pattern binding
+ tree binding = error_mark_node;
+ if (ctx->lookup_pattern_binding (ref, &binding))
+ {
+ TREE_USED (binding) = 1;
+ return binding;
+ }
+
// it might be a function call
if (lookup->get_kind () == TyTy::TypeKind::FNDEF)
{
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h
index 6968c06..90c3140 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.h
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.h
@@ -47,7 +47,6 @@ public:
void visit (HIR::ClosureExprInnerTyped &) override {}
void visit (HIR::StructExprStruct &) override {}
void visit (HIR::StructExprStructFields &) override {}
- void visit (HIR::IdentifierExpr &) override {}
void visit (HIR::LiteralExpr &) override {}
void visit (HIR::BorrowExpr &) override {}
void visit (HIR::DereferenceExpr &) override {}
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 8a614f2..c4100c4 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -188,10 +188,17 @@ CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field)
void
CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
{
- // we can make the field look like an identifier expr to take advantage of
- // existing code
- HIR::IdentifierExpr expr (field.get_mappings (), field.get_field_name (),
- field.get_locus ());
+ // we can make the field look like a path expr to take advantage of existing
+ // code
+
+ Analysis::NodeMapping mappings_copy1 = field.get_mappings ();
+ Analysis::NodeMapping mappings_copy2 = field.get_mappings ();
+
+ HIR::PathIdentSegment ident_seg (field.get_field_name ());
+ HIR::PathExprSegment seg (mappings_copy1, ident_seg, field.get_locus (),
+ HIR::GenericArgs::create_empty ());
+ HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false,
+ {});
translated = CompileExpr::Compile (&expr, ctx);
}