From: Pierre-Emmanuel Patry <[email protected]>
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 <[email protected]>
---
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