https://gcc.gnu.org/g:32ccdf41a087e1027e4ba26cbe71c39d9e44b4d3
commit 32ccdf41a087e1027e4ba26cbe71c39d9e44b4d3 Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Date: Sat May 18 23:53:42 2024 +0200 Parse box expressions 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> Diff: --- 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 a2cb506805be..c0f4884f3c98 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 fdc99bb70860..2873053c5f52 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 de4242afeb55..c9ccbfc2ceff 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 622e7f766a38..2bc58d57a9c6 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 326379cf40c2..4e6e1668f5fe 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 015680b2af46..c3b93d4dc0d2 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 48f6594a636c..796c23f797e5 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 66cff8fdcaf7..fc37b50f9ae3 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 cacd8c159a24..d477739bbc70 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 35d542b49abe..3b462ee88a7d 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 ab3ae0a8b5fc..e145259ae8bc 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 263ca634ea5c..e22ad6d3c7c8 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 c00bf9c7e2e1..95c0a0b94289 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 fa1be1979411..dfb3bffd4d22 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 e61ccabb99e6..c2a478bd35c4 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 &);