(root)/
gcc-13.2.0/
gcc/
rust/
hir/
rust-ast-lower-block.h
       1  // Copyright (C) 2020-2023 Free Software Foundation, Inc.
       2  
       3  // This file is part of GCC.
       4  
       5  // GCC is free software; you can redistribute it and/or modify it under
       6  // the terms of the GNU General Public License as published by the Free
       7  // Software Foundation; either version 3, or (at your option) any later
       8  // version.
       9  
      10  // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11  // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13  // for more details.
      14  
      15  // You should have received a copy of the GNU General Public License
      16  // along with GCC; see the file COPYING3.  If not see
      17  // <http://www.gnu.org/licenses/>.
      18  
      19  #ifndef RUST_AST_LOWER_BLOCK
      20  #define RUST_AST_LOWER_BLOCK
      21  
      22  #include "rust-diagnostics.h"
      23  #include "rust-ast-lower-base.h"
      24  
      25  namespace Rust {
      26  namespace HIR {
      27  
      28  class ASTLoweringBlock : public ASTLoweringBase
      29  {
      30    using Rust::HIR::ASTLoweringBase::visit;
      31  
      32  public:
      33    static HIR::BlockExpr *translate (AST::BlockExpr *expr, bool *terminated)
      34    {
      35      ASTLoweringBlock resolver;
      36      expr->accept_vis (resolver);
      37      if (resolver.translated != nullptr)
      38        {
      39  	resolver.mappings->insert_hir_expr (resolver.translated);
      40        }
      41  
      42      *terminated = resolver.terminated;
      43      return resolver.translated;
      44    }
      45  
      46    static HIR::UnsafeBlockExpr *translate (AST::UnsafeBlockExpr *expr,
      47  					  bool *terminated)
      48    {
      49      ASTLoweringBlock resolver;
      50  
      51      HIR::BlockExpr *block
      52        = ASTLoweringBlock::translate (expr->get_block_expr ().get (),
      53  				     terminated);
      54      auto crate_num = resolver.mappings->get_current_crate ();
      55      Analysis::NodeMapping mapping (crate_num, expr->get_node_id (),
      56  				   resolver.mappings->get_next_hir_id (
      57  				     crate_num),
      58  				   UNKNOWN_LOCAL_DEFID);
      59  
      60      HIR::UnsafeBlockExpr *translated
      61        = new HIR::UnsafeBlockExpr (mapping,
      62  				  std::unique_ptr<HIR::BlockExpr> (block),
      63  				  expr->get_outer_attrs (), expr->get_locus ());
      64  
      65      resolver.mappings->insert_hir_expr (translated);
      66  
      67      return translated;
      68    }
      69  
      70    void visit (AST::BlockExpr &expr) override;
      71  
      72  private:
      73    ASTLoweringBlock ()
      74      : ASTLoweringBase (), translated (nullptr), terminated (false)
      75    {}
      76  
      77    HIR::BlockExpr *translated;
      78    bool terminated;
      79  };
      80  
      81  class ASTLoweringIfBlock : public ASTLoweringBase
      82  {
      83    using Rust::HIR::ASTLoweringBase::visit;
      84  
      85  public:
      86    static HIR::IfExpr *translate (AST::IfExpr *expr, bool *terminated)
      87    {
      88      ASTLoweringIfBlock resolver;
      89      expr->accept_vis (resolver);
      90      if (resolver.translated != nullptr)
      91        {
      92  	resolver.mappings->insert_hir_expr (resolver.translated);
      93        }
      94      *terminated = resolver.terminated;
      95      return resolver.translated;
      96    }
      97  
      98    ~ASTLoweringIfBlock () {}
      99  
     100    void visit (AST::IfExpr &expr) override;
     101  
     102    void visit (AST::IfExprConseqElse &expr) override;
     103  
     104    void visit (AST::IfExprConseqIf &expr) override;
     105  
     106  private:
     107    ASTLoweringIfBlock ()
     108      : ASTLoweringBase (), translated (nullptr), terminated (false)
     109    {}
     110  
     111    HIR::IfExpr *translated;
     112    bool terminated;
     113  };
     114  
     115  class ASTLoweringIfLetBlock : public ASTLoweringBase
     116  {
     117    using Rust::HIR::ASTLoweringBase::visit;
     118  
     119  public:
     120    static HIR::IfLetExpr *translate (AST::IfLetExpr *expr)
     121    {
     122      ASTLoweringIfLetBlock resolver;
     123      expr->accept_vis (resolver);
     124      if (resolver.translated != nullptr)
     125        {
     126  	resolver.mappings->insert_hir_expr (resolver.translated);
     127        }
     128      return resolver.translated;
     129    }
     130  
     131    ~ASTLoweringIfLetBlock () {}
     132  
     133    void visit (AST::IfLetExpr &expr) override;
     134  
     135  private:
     136    ASTLoweringIfLetBlock () : ASTLoweringBase (), translated (nullptr) {}
     137  
     138    HIR::IfLetExpr *translated;
     139  };
     140  
     141  class ASTLoweringExprWithBlock : public ASTLoweringBase
     142  {
     143    using Rust::HIR::ASTLoweringBase::visit;
     144  
     145  public:
     146    static HIR::ExprWithBlock *translate (AST::ExprWithBlock *expr,
     147  					bool *terminated)
     148    {
     149      ASTLoweringExprWithBlock resolver;
     150      expr->accept_vis (resolver);
     151      if (resolver.translated != nullptr)
     152        {
     153  	resolver.mappings->insert_hir_expr (resolver.translated);
     154        }
     155  
     156      *terminated = resolver.terminated;
     157      return resolver.translated;
     158    }
     159  
     160    ~ASTLoweringExprWithBlock () {}
     161  
     162    void visit (AST::IfExpr &expr) override
     163    {
     164      translated = ASTLoweringIfBlock::translate (&expr, &terminated);
     165    }
     166  
     167    void visit (AST::IfExprConseqElse &expr) override
     168    {
     169      translated = ASTLoweringIfBlock::translate (&expr, &terminated);
     170    }
     171  
     172    void visit (AST::IfExprConseqIf &expr) override
     173    {
     174      translated = ASTLoweringIfBlock::translate (&expr, &terminated);
     175    }
     176  
     177    void visit (AST::IfLetExpr &expr) override
     178    {
     179      translated = ASTLoweringIfLetBlock::translate (&expr);
     180    }
     181  
     182    void visit (AST::BlockExpr &expr) override
     183    {
     184      translated = ASTLoweringBlock::translate (&expr, &terminated);
     185    }
     186  
     187    void visit (AST::UnsafeBlockExpr &expr) override
     188    {
     189      translated = ASTLoweringBlock::translate (&expr, &terminated);
     190    }
     191  
     192    void visit (AST::LoopExpr &expr) override
     193    {
     194      HIR::BlockExpr *loop_block
     195        = ASTLoweringBlock::translate (expr.get_loop_block ().get (),
     196  				     &terminated);
     197  
     198      HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
     199  
     200      auto crate_num = mappings->get_current_crate ();
     201      Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     202  				   mappings->get_next_hir_id (crate_num),
     203  				   UNKNOWN_LOCAL_DEFID);
     204  
     205      translated
     206        = new HIR::LoopExpr (mapping,
     207  			   std::unique_ptr<HIR::BlockExpr> (loop_block),
     208  			   expr.get_locus (), std::move (loop_label),
     209  			   expr.get_outer_attrs ());
     210    }
     211  
     212    void visit (AST::WhileLoopExpr &expr) override;
     213  
     214    void visit (AST::ForLoopExpr &expr) override;
     215  
     216    void visit (AST::MatchExpr &expr) override;
     217  
     218  private:
     219    ASTLoweringExprWithBlock ()
     220      : ASTLoweringBase (), translated (nullptr), terminated (false)
     221    {}
     222  
     223    HIR::ExprWithBlock *translated;
     224    bool terminated;
     225  };
     226  
     227  } // namespace HIR
     228  } // namespace Rust
     229  
     230  #endif // RUST_AST_LOWER_BLOCK