From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Add support for old box expression syntax.
gcc/rust/ChangeLog: * ast/rust-ast-collector.cc (TokenCollector::visit): Add visit member function for BoxExpr nodes. * ast/rust-ast-collector.h: Add visit function prototype. * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add visit member function to default ast visitor. * ast/rust-ast-visitor.h: Add visit function's prototype. * ast/rust-ast.cc (BoxExpr::as_string): Add as_string function implementation for BoxExpr. (BoxExpr::accept_vis): Add accept_vis implementation to BoxExpr. * ast/rust-expr.h (class BoxExpr): Add BoxExpr class to represent boxed expressions. * expand/rust-derive.h: Add BoxExpr visit function prototype. * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add BoxExpr visitor implementation. * hir/rust-ast-lower-base.h: Add visit function's prototype. * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Add BoxExpr visitor implementation. * hir/rust-ast-lower-expr.h: Add visit function's prototype. * parse/rust-parse-impl.h (Parser::parse_box_expr): Add parse_box_expr function's implementation. * parse/rust-parse.h: Add parse_box_expr function's prototype. * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Add resolver visit implementation. * resolve/rust-ast-resolve-base.h: Add resolver's visit function prototype. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> --- gcc/rust/ast/rust-ast-collector.cc | 8 +++ gcc/rust/ast/rust-ast-collector.h | 1 + gcc/rust/ast/rust-ast-visitor.cc | 7 +++ gcc/rust/ast/rust-ast-visitor.h | 2 + gcc/rust/ast/rust-ast.cc | 12 ++++ gcc/rust/ast/rust-expr.h | 73 +++++++++++++++++++++++ gcc/rust/expand/rust-derive.h | 1 + gcc/rust/hir/rust-ast-lower-base.cc | 5 ++ gcc/rust/hir/rust-ast-lower-base.h | 1 + gcc/rust/hir/rust-ast-lower-expr.cc | 8 +++ gcc/rust/hir/rust-ast-lower-expr.h | 1 + gcc/rust/parse/rust-parse-impl.h | 23 +++++++ gcc/rust/parse/rust-parse.h | 3 + gcc/rust/resolve/rust-ast-resolve-base.cc | 4 ++ gcc/rust/resolve/rust-ast-resolve-base.h | 1 + 15 files changed, 150 insertions(+) diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 5c44d3dc1cb..a7f6ed57623 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -20,6 +20,7 @@ #include "rust-diagnostics.h" #include "rust-item.h" #include "rust-keyword-values.h" +#include "rust-token.h" namespace Rust { namespace AST { @@ -1315,6 +1316,13 @@ TokenCollector::visit (RangeToInclExpr &expr) visit (expr.get_to_expr ()); } +void +TokenCollector::visit (BoxExpr &expr) +{ + push (Rust::Token::make (BOX, expr.get_locus ())); + visit (expr.get_boxed_expr ()); +} + void TokenCollector::visit (ReturnExpr &expr) { diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h index def95516945..7b418bb6d31 100644 --- a/gcc/rust/ast/rust-ast-collector.h +++ b/gcc/rust/ast/rust-ast-collector.h @@ -288,6 +288,7 @@ public: void visit (RangeFromToInclExpr &expr); void visit (RangeToInclExpr &expr); void visit (ReturnExpr &expr); + void visit (BoxExpr &expr); void visit (UnsafeBlockExpr &expr); void visit (LoopExpr &expr); void visit (WhileLoopExpr &expr); diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index 2021012a693..ba3eb67cbe7 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -531,6 +531,13 @@ DefaultASTVisitor::visit (AST::ReturnExpr &expr) visit (expr.get_returned_expr ()); } +void +DefaultASTVisitor::visit (AST::BoxExpr &expr) +{ + visit_outer_attrs (expr); + visit (expr.get_boxed_expr ()); +} + void DefaultASTVisitor::visit (AST::UnsafeBlockExpr &expr) { diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index 5da8a7b27e5..1d96304f188 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -112,6 +112,7 @@ public: virtual void visit (RangeFromToInclExpr &expr) = 0; virtual void visit (RangeToInclExpr &expr) = 0; virtual void visit (ReturnExpr &expr) = 0; + virtual void visit (BoxExpr &expr) = 0; virtual void visit (UnsafeBlockExpr &expr) = 0; virtual void visit (LoopExpr &expr) = 0; virtual void visit (WhileLoopExpr &expr) = 0; @@ -297,6 +298,7 @@ protected: virtual void visit (AST::RangeFromToInclExpr &expr) override; virtual void visit (AST::RangeToInclExpr &expr) override; virtual void visit (AST::ReturnExpr &expr) override; + virtual void visit (AST::BoxExpr &expr) override; virtual void visit (AST::UnsafeBlockExpr &expr) override; virtual void visit (AST::LoopExpr &expr) override; virtual void visit (AST::WhileLoopExpr &expr) override; diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 6da0d827670..bc896928ce6 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1581,6 +1581,18 @@ BorrowExpr::as_string () const return str; } +std::string +BoxExpr::as_string () const +{ + return "box " + expr->as_string (); +} + +void +BoxExpr::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + std::string ReturnExpr::as_string () const { diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 015680b2af4..c3b93d4dc0d 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -3310,6 +3310,79 @@ protected: } }; +class BoxExpr : public ExprWithoutBlock +{ + std::unique_ptr<Expr> expr; + std::vector<Attribute> outer_attrs; + location_t locus; + +public: + BoxExpr (std::unique_ptr<Expr> expr, std::vector<Attribute> outer_attrs, + location_t locus) + : expr (std::move (expr)), outer_attrs (outer_attrs), locus (locus) + {} + + // Copy constructor with clone + BoxExpr (BoxExpr const &other) + : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), + locus (other.locus) + { + // guard to protect from null pointer dereference + if (other.expr != nullptr) + expr = other.expr->clone_expr (); + } + + BoxExpr &operator= (BoxExpr const &other) + { + ExprWithoutBlock::operator= (other); + locus = other.locus; + outer_attrs = other.outer_attrs; + + // guard to protect from null pointer dereference + if (other.expr != nullptr) + expr = other.expr->clone_expr (); + else + expr = nullptr; + + return *this; + } + + // move constructors + BoxExpr (BoxExpr &&other) = default; + BoxExpr &operator= (BoxExpr &&other) = default; + + location_t get_locus () const override final { return locus; } + + void accept_vis (ASTVisitor &vis) override; + + void mark_for_strip () override { expr = nullptr; } + bool is_marked_for_strip () const override { return expr == nullptr; } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override + { + outer_attrs = std::move (new_attrs); + } + + std::string as_string () const override; + + Expr &get_boxed_expr () + { + rust_assert (expr != nullptr); + return *expr; + } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + BoxExpr *clone_expr_without_block_impl () const override + { + return new BoxExpr (*this); + } +}; + // Return expression AST node representation class ReturnExpr : public ExprWithoutBlock { diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h index 0faf4f07de0..c92f9c07f28 100644 --- a/gcc/rust/expand/rust-derive.h +++ b/gcc/rust/expand/rust-derive.h @@ -130,6 +130,7 @@ private: virtual void visit (RangeFromToInclExpr &expr) override final{}; virtual void visit (RangeToInclExpr &expr) override final{}; virtual void visit (ReturnExpr &expr) override final{}; + virtual void visit (BoxExpr &expr) override final{}; virtual void visit (UnsafeBlockExpr &expr) override final{}; virtual void visit (LoopExpr &expr) override final{}; virtual void visit (WhileLoopExpr &expr) override final{}; diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index 6803ad4132d..96969782c98 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -213,6 +213,11 @@ ASTLoweringBase::visit (AST::RangeFromToInclExpr &) void ASTLoweringBase::visit (AST::RangeToInclExpr &) {} + +void +ASTLoweringBase::visit (AST::BoxExpr &) +{} + void ASTLoweringBase::visit (AST::ReturnExpr &) {} diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index 2987bb19121..94e0e48968c 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -137,6 +137,7 @@ public: virtual void visit (AST::RangeFullExpr &expr); virtual void visit (AST::RangeFromToInclExpr &expr); virtual void visit (AST::RangeToInclExpr &expr); + virtual void visit (AST::BoxExpr &expr); virtual void visit (AST::ReturnExpr &expr); virtual void visit (AST::UnsafeBlockExpr &expr); virtual void visit (AST::LoopExpr &expr); diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index 6927139e48c..515d36a839f 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -24,6 +24,7 @@ #include "rust-ast-lower-type.h" #include "rust-ast.h" #include "rust-diagnostics.h" +#include "rust-system.h" namespace Rust { namespace HIR { @@ -141,6 +142,13 @@ ASTLoweringExpr::visit (AST::QualifiedPathInExpression &expr) translated = ASTLowerQualPathInExpression::translate (expr); } +void +ASTLoweringExpr::visit (AST::BoxExpr &expr) +{ + // Not implemented + rust_unreachable (); +} + void ASTLoweringExpr::visit (AST::ReturnExpr &expr) { diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 52caa4de294..cd7b74aa7f2 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -85,6 +85,7 @@ public: void visit (AST::UnsafeBlockExpr &expr) override; void visit (AST::PathInExpression &expr) override; void visit (AST::QualifiedPathInExpression &expr) override; + void visit (AST::BoxExpr &expr) override; void visit (AST::ReturnExpr &expr) override; void visit (AST::CallExpr &expr) override; void visit (AST::MethodCallExpr &expr) override; diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 9e186ccfd22..d1f5b6bbf0a 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -7550,6 +7550,27 @@ Parser<ManagedTokenSource>::parse_literal_expr (AST::AttrVec outer_attrs) t->get_locus ())); } +template <typename ManagedTokenSource> +std::unique_ptr<AST::BoxExpr> +Parser<ManagedTokenSource>::parse_box_expr (AST::AttrVec outer_attrs, + location_t pratt_parsed_loc) +{ + location_t locus = pratt_parsed_loc; + if (locus == UNKNOWN_LOCATION) + { + locus = lexer.peek_token ()->get_locus (); + skip_token (BOX); + } + + ParseRestrictions restrictions; + restrictions.expr_can_be_null = false; + + std::unique_ptr<AST::Expr> expr = parse_expr (AST::AttrVec (), restrictions); + + return std::unique_ptr<AST::BoxExpr> ( + new AST::BoxExpr (std::move (expr), std::move (outer_attrs), locus)); +} + // Parses a return expression (including any expression to return). template <typename ManagedTokenSource> std::unique_ptr<AST::ReturnExpr> @@ -12461,6 +12482,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path ( case UNSAFE: return parse_unsafe_block_expr (std::move (outer_attrs), tok->get_locus ()); + case BOX: + return parse_box_expr (std::move (outer_attrs), tok->get_locus ()); case UNDERSCORE: add_error ( Error (tok->get_locus (), diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index c00bf9c7e2e..95c0a0b9428 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -622,6 +622,9 @@ private: = AST::AttrVec ()); AST::ClosureParam parse_closure_param (); + std::unique_ptr<AST::BoxExpr> parse_box_expr (AST::AttrVec outer_attrs, + location_t pratt_parsed_loc + = UNKNOWN_LOCATION); // When given a pratt_parsed_loc, use it as the location of the // first token parsed in the expression (the parsing of that first // token should be skipped). diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc index 22c04a343ca..66ce5bfa35a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc @@ -266,6 +266,10 @@ void ResolverBase::visit (AST::RangeToInclExpr &) {} +void +ResolverBase::visit (AST::BoxExpr &) +{} + void ResolverBase::visit (AST::ReturnExpr &) {} diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 93d75aa109d..46bcac6ec8e 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -89,6 +89,7 @@ public: void visit (AST::RangeFullExpr &); void visit (AST::RangeFromToInclExpr &); void visit (AST::RangeToInclExpr &); + void visit (AST::BoxExpr &); void visit (AST::ReturnExpr &); void visit (AST::UnsafeBlockExpr &); void visit (AST::LoopExpr &); -- 2.45.2