From: Owen Avery <powerboat9.ga...@gmail.com>

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 <powerboat9.ga...@gmail.com>
---
 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

Reply via email to