aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/hir
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-11-16 15:18:49 +0000
committerGitHub <noreply@github.com>2021-11-16 15:18:49 +0000
commit5514d9cec51d5ec7cc30dd6cdbfadfdddbe0aab3 (patch)
tree55051cad7f474f411d79ca1e86cc23d63138716d /gcc/rust/hir
parentdcd758595f646a480947265ccc9833fdd3976b75 (diff)
parent6d1333ef46cba6ed9e1ace817f9cc649b7f7a1df (diff)
downloadgcc-5514d9cec51d5ec7cc30dd6cdbfadfdddbe0aab3.zip
gcc-5514d9cec51d5ec7cc30dd6cdbfadfdddbe0aab3.tar.gz
gcc-5514d9cec51d5ec7cc30dd6cdbfadfdddbe0aab3.tar.bz2
Merge #801
801: operator overloading r=philberty a=philberty This change adds operator overloading by following how the C++ front-end does it. We are relying on GCC to inline the operator overloads which does occur once optimizations are enabled. It also brings back the desurgared compound assignment expression (e2b761b13e6ccd3a7af4100183bb13e32b5b0da0) for lang_items such as add_assign. You can find more information on how the algorithm works in: - c47d5cbdee9b701fb7753b44530fcb51f80b20fa - a7fb60bb626f7b936bf117636db777a5f0df30c9 These were refactored in: 0f74fe23c6d602c257ba94b2522bd9d6a594609e Fixes #249 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/hir')
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h16
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h23
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h79
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc67
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h1
5 files changed, 146 insertions, 40 deletions
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/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index db0425f..65a4921 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -613,29 +613,6 @@ public:
if (trait.has_generics ())
{
generic_params = lower_generic_params (trait.get_generic_params ());
-
- for (auto &generic_param : generic_params)
- {
- switch (generic_param->get_kind ())
- {
- case HIR::GenericParam::GenericKind::TYPE: {
- const HIR::TypeParam &t
- = static_cast<const HIR::TypeParam &> (*generic_param);
-
- if (t.has_type ())
- {
- // see https://github.com/rust-lang/rust/issues/36887
- rust_error_at (
- t.get_locus (),
- "defaults for type parameters are not allowed here");
- }
- }
- break;
-
- default:
- break;
- }
- }
}
std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 575d1f6..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
{
@@ -1635,7 +1709,6 @@ class MethodCallExpr : public ExprWithoutBlock
{
std::unique_ptr<Expr> receiver;
PathExprSegment method_name;
- // inlined form of CallParams
std::vector<std::unique_ptr<Expr> > params;
Location locus;
@@ -1643,10 +1716,6 @@ class MethodCallExpr : public ExprWithoutBlock
public:
std::string as_string () const override;
- /*inline std::vector<std::unique_ptr<Expr>> get_params() const {
- return params;
- }*/
-
MethodCallExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> call_receiver,
PathExprSegment method_path,
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;