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

Reply via email to