From: Owen Avery <[email protected]>
This doesn't do anything beyond creating TryExpr and parsing them, so
try expressions shouldn't be able to make it past AST lowering yet.
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc (TokenCollector::visit): Add visitor
for TryExpr.
* ast/rust-ast-collector.h (TokenCollector::visit): Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h (ASTVisitor::visit): Likewise.
(DefaultASTVisitor::visit): Likewise.
* expand/rust-derive.h (DeriveVisitor::visit): Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
* hir/rust-ast-lower-base.h (ASTLoweringBase::visit): Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit):
Likewise.
* resolve/rust-ast-resolve-base.h (ResolverBase::visit):
Likewise.
* ast/rust-ast-full-decls.h (class TryExpr): New forward class
declaration.
* ast/rust-ast.cc (TryExpr::as_string): New function.
(TryExpr::accept_vis): Likewise.
* ast/rust-expr.h (class TryExpr): New class.
* parse/rust-parse.h (Parser::parse_try_expr): New function.
* parse/rust-parse-impl.h (Parser::parse_try_expr): Likewise.
(Parser::null_denotation_not_path): Use parse_try_expr to parse
try expressions.
Signed-off-by: Owen Avery <[email protected]>
---
gcc/rust/ast/rust-ast-collector.cc | 7 +++
gcc/rust/ast/rust-ast-collector.h | 1 +
gcc/rust/ast/rust-ast-full-decls.h | 1 +
gcc/rust/ast/rust-ast-visitor.cc | 7 +++
gcc/rust/ast/rust-ast-visitor.h | 2 +
gcc/rust/ast/rust-ast.cc | 19 ++++++
gcc/rust/ast/rust-expr.h | 76 +++++++++++++++++++++++
gcc/rust/expand/rust-derive.h | 1 +
gcc/rust/hir/rust-ast-lower-base.cc | 3 +
gcc/rust/hir/rust-ast-lower-base.h | 1 +
gcc/rust/parse/rust-parse-impl.h | 31 +++++++++
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 +
14 files changed, 157 insertions(+)
diff --git a/gcc/rust/ast/rust-ast-collector.cc
b/gcc/rust/ast/rust-ast-collector.cc
index 5a8d462dbd7..0b5f27d36d2 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1370,6 +1370,13 @@ TokenCollector::visit (ReturnExpr &expr)
visit (expr.get_returned_expr ());
}
+void
+TokenCollector::visit (TryExpr &expr)
+{
+ push (Rust::Token::make (TRY, expr.get_locus ()));
+ visit (expr.get_block_expr ());
+}
+
void
TokenCollector::visit (UnsafeBlockExpr &expr)
{
diff --git a/gcc/rust/ast/rust-ast-collector.h
b/gcc/rust/ast/rust-ast-collector.h
index cec2365892e..e8af5878a2c 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -289,6 +289,7 @@ public:
void visit (RangeFromToInclExpr &expr);
void visit (RangeToInclExpr &expr);
void visit (ReturnExpr &expr);
+ void visit (TryExpr &expr);
void visit (BoxExpr &expr);
void visit (UnsafeBlockExpr &expr);
void visit (LoopExpr &expr);
diff --git a/gcc/rust/ast/rust-ast-full-decls.h
b/gcc/rust/ast/rust-ast-full-decls.h
index b410f3ad006..eb1f3ea890c 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -128,6 +128,7 @@ class RangeFullExpr;
class RangeFromToInclExpr;
class RangeToInclExpr;
class ReturnExpr;
+class TryExpr;
class UnsafeBlockExpr;
class LoopLabel;
class BaseLoopExpr;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index c24425bbb38..fd45fb1060d 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -549,6 +549,13 @@ DefaultASTVisitor::visit (AST::ReturnExpr &expr)
visit (expr.get_returned_expr ());
}
+void
+DefaultASTVisitor::visit (AST::TryExpr &expr)
+{
+ visit_outer_attrs (expr);
+ visit (expr.get_block_expr ());
+}
+
void
DefaultASTVisitor::visit (AST::BoxExpr &expr)
{
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 22fd98b6ea8..6111b0548ed 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -116,6 +116,7 @@ public:
virtual void visit (RangeFromToInclExpr &expr) = 0;
virtual void visit (RangeToInclExpr &expr) = 0;
virtual void visit (ReturnExpr &expr) = 0;
+ virtual void visit (TryExpr &expr) = 0;
virtual void visit (BoxExpr &expr) = 0;
virtual void visit (UnsafeBlockExpr &expr) = 0;
virtual void visit (LoopExpr &expr) = 0;
@@ -307,6 +308,7 @@ public:
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::TryExpr &expr) override;
virtual void visit (AST::BoxExpr &expr) override;
virtual void visit (AST::UnsafeBlockExpr &expr) override;
virtual void visit (AST::LoopExpr &expr) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 916829fe95c..4d928ca7a2d 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1636,6 +1636,19 @@ ReturnExpr::as_string () const
return str;
}
+std::string
+TryExpr::as_string () const
+{
+ /* TODO: find way to incorporate outer attrs - may have to represent in
+ * different style (i.e. something more like BorrowExpr: \n outer attrs) */
+
+ std::string str ("try ");
+
+ str += block_expr->as_string ();
+
+ return str;
+}
+
std::string
RangeToExpr::as_string () const
{
@@ -4604,6 +4617,12 @@ ReturnExpr::accept_vis (ASTVisitor &vis)
vis.visit (*this);
}
+void
+TryExpr::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
void
UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
{
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 21e856bb1d0..3e50c46e58d 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -3700,6 +3700,82 @@ protected:
}
};
+// Try expression AST node representation
+class TryExpr : public ExprWithBlock
+{
+ std::vector<Attribute> outer_attrs;
+ std::unique_ptr<BlockExpr> block_expr;
+ location_t locus;
+
+ // TODO: find another way to store this to save memory?
+ bool marked_for_strip = false;
+
+public:
+ std::string as_string () const override;
+
+ // Constructor for ReturnExpr.
+ TryExpr (std::unique_ptr<BlockExpr> block_expr,
+ std::vector<Attribute> outer_attribs, location_t locus)
+ : outer_attrs (std::move (outer_attribs)),
+ block_expr (std::move (block_expr)), locus (locus)
+ {
+ rust_assert (this->block_expr);
+ }
+
+ // Copy constructor with clone
+ TryExpr (TryExpr const &other)
+ : ExprWithBlock (other), outer_attrs (other.outer_attrs),
+ block_expr (other.block_expr->clone_block_expr ()), locus (other.locus),
+ marked_for_strip (other.marked_for_strip)
+ {}
+
+ // Overloaded assignment operator to clone return_expr pointer
+ TryExpr &operator= (TryExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ locus = other.locus;
+ marked_for_strip = other.marked_for_strip;
+ outer_attrs = other.outer_attrs;
+
+ block_expr = other.block_expr->clone_block_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ TryExpr (TryExpr &&other) = default;
+ TryExpr &operator= (TryExpr &&other) = default;
+
+ location_t get_locus () const override final { return locus; }
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ // Can't think of any invalid invariants, so store boolean.
+ void mark_for_strip () override { marked_for_strip = true; }
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ BlockExpr &get_block_expr () { return *block_expr; }
+
+ 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);
+ }
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::Return; }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ TryExpr *clone_expr_with_block_impl () const override
+ {
+ return new TryExpr (*this);
+ }
+};
+
// Forward decl - defined in rust-macro.h
class MacroInvocation;
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index ff4f427695a..61c7355e7ab 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -159,6 +159,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 (TryExpr &expr) override final{};
virtual void visit (BoxExpr &expr) override final{};
virtual void visit (UnsafeBlockExpr &expr) override final{};
virtual void visit (LoopExpr &expr) override final{};
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc
b/gcc/rust/hir/rust-ast-lower-base.cc
index 5b35052b665..b07ac0c0750 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -242,6 +242,9 @@ void
ASTLoweringBase::visit (AST::ReturnExpr &)
{}
void
+ASTLoweringBase::visit (AST::TryExpr &)
+{}
+void
ASTLoweringBase::visit (AST::UnsafeBlockExpr &)
{}
void
diff --git a/gcc/rust/hir/rust-ast-lower-base.h
b/gcc/rust/hir/rust-ast-lower-base.h
index 51912be66b4..0284ff0c82b 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -144,6 +144,7 @@ public:
virtual void visit (AST::RangeToInclExpr &expr) override;
virtual void visit (AST::BoxExpr &expr) override;
virtual void visit (AST::ReturnExpr &expr) override;
+ virtual void visit (AST::TryExpr &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/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 120817b88b8..9608cd885f4 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -7570,6 +7570,34 @@ Parser<ManagedTokenSource>::parse_return_expr
(AST::AttrVec outer_attrs,
locus));
}
+// Parses a try expression.
+template <typename ManagedTokenSource>
+std::unique_ptr<AST::TryExpr>
+Parser<ManagedTokenSource>::parse_try_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 (TRY);
+ }
+
+ std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
+
+ if (!block_expr)
+ {
+ Error error (lexer.peek_token ()->get_locus (),
+ "failed to parse try block expression");
+ add_error (std::move (error));
+
+ return nullptr;
+ }
+
+ return std::unique_ptr<AST::TryExpr> (
+ new AST::TryExpr (std::move (block_expr), std::move (outer_attrs), locus));
+}
+
/* Parses a break expression (including any label to break to AND any return
* expression). */
template <typename ManagedTokenSource>
@@ -12508,6 +12536,9 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
case RETURN_KW:
// FIXME: is this really a null denotation expression?
return parse_return_expr (std::move (outer_attrs), tok->get_locus ());
+ case TRY:
+ // FIXME: is this really a null denotation expression?
+ return parse_try_expr (std::move (outer_attrs), tok->get_locus ());
case BREAK:
// FIXME: is this really a null denotation expression?
return parse_break_expr (std::move (outer_attrs), tok->get_locus ());
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index c9b6edb60e9..36426d56f8d 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -649,6 +649,9 @@ private:
std::unique_ptr<AST::ReturnExpr>
parse_return_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
+ std::unique_ptr<AST::TryExpr>
+ parse_try_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
+ location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::BreakExpr>
parse_break_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc
b/gcc/rust/resolve/rust-ast-resolve-base.cc
index 71c4c4834db..05f34bc3f87 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -283,6 +283,10 @@ void
ResolverBase::visit (AST::ReturnExpr &)
{}
+void
+ResolverBase::visit (AST::TryExpr &)
+{}
+
void
ResolverBase::visit (AST::UnsafeBlockExpr &)
{}
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h
b/gcc/rust/resolve/rust-ast-resolve-base.h
index e17bdcb5eaa..0cbf78e39ab 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -99,6 +99,7 @@ public:
void visit (AST::RangeToInclExpr &);
void visit (AST::BoxExpr &);
void visit (AST::ReturnExpr &);
+ void visit (AST::TryExpr &);
void visit (AST::UnsafeBlockExpr &);
void visit (AST::LoopExpr &);
void visit (AST::WhileLoopExpr &);
--
2.49.0