diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-11-16 15:18:49 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-16 15:18:49 +0000 |
commit | 5514d9cec51d5ec7cc30dd6cdbfadfdddbe0aab3 (patch) | |
tree | 55051cad7f474f411d79ca1e86cc23d63138716d /gcc/rust/hir | |
parent | dcd758595f646a480947265ccc9833fdd3976b75 (diff) | |
parent | 6d1333ef46cba6ed9e1ace817f9cc649b7f7a1df (diff) | |
download | gcc-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.h | 16 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.h | 23 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 79 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-full-test.cc | 67 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-visitor.h | 1 |
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; |