aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h17
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h16
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h74
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc67
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h1
-rw-r--r--gcc/rust/lint/rust-lint-marklive-base.h2
-rw-r--r--gcc/rust/lint/rust-lint-marklive.h6
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold-base.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h23
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-util.h2
11 files changed, 196 insertions, 16 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index c9d3c30..8ed84c7 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -388,6 +388,23 @@ public:
ctx->add_statement (assignment);
}
+ void visit (HIR::CompoundAssignmentExpr &expr) override
+ {
+ fncontext fn = ctx->peek_fn ();
+ auto lvalue = CompileExpr::Compile (expr.get_left_expr ().get (), ctx);
+ auto rvalue = CompileExpr::Compile (expr.get_right_expr ().get (), ctx);
+
+ auto op = expr.get_expr_type ();
+ auto operator_expr = ctx->get_backend ()->arithmetic_or_logical_expression (
+ op, lvalue, rvalue, expr.get_locus ());
+
+ Bstatement *assignment
+ = ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue,
+ operator_expr,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
+
void visit (HIR::ArrayIndexExpr &expr) override
{
Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx);
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 54cb6113..f36096b 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -452,11 +452,8 @@ public:
expr.get_locus ());
}
- /* Compound assignment expression is compiled away. */
void visit (AST::CompoundAssignmentExpr &expr) override
{
- /* First we need to find the corresponding arithmetic or logical operator.
- */
ArithmeticOrLogicalOperator op;
switch (expr.get_expr_type ())
{
@@ -503,15 +500,10 @@ public:
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::Expr *operator_expr
- = new HIR::ArithmeticOrLogicalExpr (mapping, asignee_expr->clone_expr (),
- std::unique_ptr<HIR::Expr> (value),
- op, expr.get_locus ());
- translated
- = new HIR::AssignmentExpr (mapping,
- std::unique_ptr<HIR::Expr> (asignee_expr),
- std::unique_ptr<HIR::Expr> (operator_expr),
- expr.get_locus ());
+
+ translated = new HIR::CompoundAssignmentExpr (
+ mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
+ std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
}
void visit (AST::StructExprStruct &struct_expr) override
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 37ec15d..901feda 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -666,6 +666,80 @@ protected:
}
};
+class CompoundAssignmentExpr : public OperatorExpr
+{
+public:
+ using ExprType = ArithmeticOrLogicalOperator;
+
+private:
+ // Note: overloading trait specified in comments
+ ExprType expr_type;
+ std::unique_ptr<Expr> right_expr;
+
+public:
+ std::string as_string () const override;
+
+ ExprType get_expr_type () const { return expr_type; }
+
+ // Use pointers in constructor to enable polymorphism
+ CompoundAssignmentExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> value_to_assign_to,
+ std::unique_ptr<Expr> value_to_assign,
+ ExprType expr_kind, Location locus)
+ : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
+ AST::AttrVec (), locus),
+ expr_type (expr_kind), right_expr (std::move (value_to_assign))
+ {}
+ // outer attributes not allowed
+
+ // Have clone in copy constructor
+ CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+ {}
+
+ // Overload assignment operator to clone
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
+
+ void accept_vis (HIRVisitor &vis) override;
+
+ std::unique_ptr<Expr> &get_left_expr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
+ std::unique_ptr<Expr> &get_right_expr ()
+ {
+ rust_assert (right_expr != nullptr);
+ return right_expr;
+ }
+
+ void visit_lhs (HIRVisitor &vis) { main_or_left_expr->accept_vis (vis); }
+ void visit_rhs (HIRVisitor &vis) { right_expr->accept_vis (vis); }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ CompoundAssignmentExpr *clone_expr_without_block_impl () const override
+ {
+ return new CompoundAssignmentExpr (*this);
+ }
+};
+
// Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
class GroupedExpr : public ExprWithoutBlock
{
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index bacef82..843e32c 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -1316,6 +1316,67 @@ AssignmentExpr::as_string () const
}
std::string
+CompoundAssignmentExpr::as_string () const
+{
+ std::string operator_str;
+ operator_str.reserve (1);
+
+ // get operator string
+ switch (expr_type)
+ {
+ case ArithmeticOrLogicalOperator::ADD:
+ operator_str = "+";
+ break;
+ case ArithmeticOrLogicalOperator::SUBTRACT:
+ operator_str = "-";
+ break;
+ case ArithmeticOrLogicalOperator::MULTIPLY:
+ operator_str = "*";
+ break;
+ case ArithmeticOrLogicalOperator::DIVIDE:
+ operator_str = "/";
+ break;
+ case ArithmeticOrLogicalOperator::MODULUS:
+ operator_str = "%";
+ break;
+ case ArithmeticOrLogicalOperator::BITWISE_AND:
+ operator_str = "&";
+ break;
+ case ArithmeticOrLogicalOperator::BITWISE_OR:
+ operator_str = "|";
+ break;
+ case ArithmeticOrLogicalOperator::BITWISE_XOR:
+ operator_str = "^";
+ break;
+ case ArithmeticOrLogicalOperator::LEFT_SHIFT:
+ operator_str = "<<";
+ break;
+ case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
+ operator_str = ">>";
+ break;
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ operator_str += "=";
+
+ std::string str ("CompoundAssignmentExpr: ");
+ if (main_or_left_expr == nullptr || right_expr == nullptr)
+ {
+ str += "error. this is probably a parsing failure.";
+ }
+ else
+ {
+ str += "\n left: " + main_or_left_expr->as_string ();
+ str += "\n right: " + right_expr->as_string ();
+ str += "\n operator: " + operator_str;
+ }
+
+ return str;
+}
+
+std::string
AsyncBlockExpr::as_string () const
{
std::string str = "AsyncBlockExpr: ";
@@ -3819,6 +3880,12 @@ AssignmentExpr::accept_vis (HIRVisitor &vis)
}
void
+CompoundAssignmentExpr::accept_vis (HIRVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
GroupedExpr::accept_vis (HIRVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 0487446..ea125d9 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -47,6 +47,7 @@ public:
virtual void visit (LazyBooleanExpr &expr) = 0;
virtual void visit (TypeCastExpr &expr) = 0;
virtual void visit (AssignmentExpr &expr) = 0;
+ virtual void visit (CompoundAssignmentExpr &expr) = 0;
virtual void visit (GroupedExpr &expr) = 0;
virtual void visit (ArrayElemsValues &elems) = 0;
virtual void visit (ArrayElemsCopied &elems) = 0;
diff --git a/gcc/rust/lint/rust-lint-marklive-base.h b/gcc/rust/lint/rust-lint-marklive-base.h
index b67705b..e0494d7 100644
--- a/gcc/rust/lint/rust-lint-marklive-base.h
+++ b/gcc/rust/lint/rust-lint-marklive-base.h
@@ -53,7 +53,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index ca5d894..bcf792b 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -186,6 +186,12 @@ public:
expr.visit_rhs (*this);
}
+ void visit (HIR::CompoundAssignmentExpr &expr) override
+ {
+ expr.visit_lhs (*this);
+ expr.visit_rhs (*this);
+ }
+
void visit (HIR::IfExpr &expr) override
{
expr.get_if_condition ()->accept_vis (*this);
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-base.h b/gcc/rust/typecheck/rust-hir-const-fold-base.h
index 9cbf1ab..0b41053 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold-base.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold-base.h
@@ -56,7 +56,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index eb96fd1..52dea21 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -58,7 +58,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index b332a68..2594a41 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -470,6 +470,29 @@ public:
result->clone ());
}
+ void visit (HIR::CompoundAssignmentExpr &expr) override
+ {
+ infered = new TyTy::TupleType (expr.get_mappings ().get_hirid ());
+
+ auto lhs = TypeCheckExpr::Resolve (expr.get_left_expr ().get (), false);
+ auto rhs = TypeCheckExpr::Resolve (expr.get_right_expr ().get (), false);
+
+ bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
+ bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
+ bool valid = valid_lhs && valid_rhs;
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (),
+ "cannot apply this operator to types %s and %s",
+ lhs->as_string ().c_str (), rhs->as_string ().c_str ());
+ return;
+ }
+
+ auto result = lhs->unify (rhs);
+ if (result->get_kind () == TyTy::TypeKind::ERROR)
+ return;
+ }
+
void visit (HIR::IdentifierExpr &expr) override
{
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.h b/gcc/rust/typecheck/rust-hir-type-check-util.h
index 4595ca3..f078df6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-util.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-util.h
@@ -51,7 +51,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}