// Copyright (C) 2020-2025 Free Software Foundation, Inc. // This file is part of GCC. // GCC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 3, or (at your option) any later // version. // GCC is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // You should have received a copy of the GNU General Public License // along with GCC; see the file COPYING3. If not see // . #ifndef RUST_HIR_STATEMENT_H #define RUST_HIR_STATEMENT_H #include "rust-hir.h" #include "rust-hir-path.h" #include "rust-hir-expr.h" #include "rust-system.h" namespace Rust { namespace HIR { /* Base statement abstract class. Note that most "statements" are not allowed in * top-level module scope - only a subclass of statements called "items" are. */ class Stmt : public Node, public FullVisitable { public: using FullVisitable::accept_vis; // Unique pointer custom clone function std::unique_ptr clone_stmt () const { return std::unique_ptr (clone_stmt_impl ()); } BaseKind get_hir_kind () override { return STMT; } virtual ~Stmt () {} virtual std::string as_string () const = 0; virtual void accept_vis (HIRStmtVisitor &vis) = 0; virtual location_t get_locus () const = 0; virtual bool is_unit_check_needed () const { return false; } const Analysis::NodeMapping &get_mappings () const { return mappings; } virtual bool is_item () const = 0; protected: Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {} // Clone function implementation as pure virtual method virtual Stmt *clone_stmt_impl () const = 0; Analysis::NodeMapping mappings; }; // Just a semi-colon, which apparently is a statement. class EmptyStmt : public Stmt { location_t locus; public: std::string as_string () const override { return std::string (1, ';'); } EmptyStmt (Analysis::NodeMapping mappings, location_t locus) : Stmt (std::move (mappings)), locus (locus) {} location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; bool is_item () const override final { return false; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ EmptyStmt *clone_stmt_impl () const override { return new EmptyStmt (*this); } }; /* Variable assignment let statement - type of "declaration statement" as it * introduces new name into scope */ class LetStmt : public Stmt { // bool has_outer_attrs; AST::AttrVec outer_attrs; std::unique_ptr variables_pattern; tl::optional> type; tl::optional> init_expr; tl::optional> else_expr; location_t locus; public: // Returns whether let statement has outer attributes. bool has_outer_attrs () const { return !outer_attrs.empty (); } // Returns whether let statement has a given return type. bool has_type () const { return type.has_value (); } // Returns whether let statement has an initialisation expression. bool has_init_expr () const { return init_expr.has_value (); } // Returns whether let statement has a diverging else expression. bool has_else_expr () const { return else_expr.has_value (); } std::string as_string () const override; LetStmt (Analysis::NodeMapping mappings, std::unique_ptr variables_pattern, tl::optional> init_expr, tl::optional> else_expr, tl::optional> type, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone LetStmt (LetStmt const &other); // Overloaded assignment operator to clone LetStmt &operator= (LetStmt const &other); // move constructors LetStmt (LetStmt &&other) = default; LetStmt &operator= (LetStmt &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; const std::vector &get_outer_attrs () const { return outer_attrs; } std::vector &get_outer_attrs () { return outer_attrs; } HIR::Type &get_type () { rust_assert (*type); return *type.value (); } const HIR::Type &get_type () const { rust_assert (*type); return *type.value (); } HIR::Expr &get_init_expr () { rust_assert (*init_expr); return *init_expr.value (); } const HIR::Expr &get_init_expr () const { rust_assert (*init_expr); return *init_expr.value (); } HIR::Expr &get_else_expr () { rust_assert (*else_expr); return *else_expr.value (); } const HIR::Expr &get_else_expr () const { rust_assert (*else_expr); return *else_expr.value (); } HIR::Pattern &get_pattern () { return *variables_pattern; } bool is_item () const override final { return false; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ LetStmt *clone_stmt_impl () const override { return new LetStmt (*this); } }; /* class for expression statements (statements containing an expression) */ class ExprStmt : public Stmt { std::unique_ptr expr; location_t locus; bool must_be_unit; public: ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr expr, location_t locus, bool must_be_unit); ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr expr, location_t locus); std::string as_string () const override; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; bool is_item () const override final { return false; } Expr &get_expr () { return *expr; } // Copy constructor with clone ExprStmt (ExprStmt const &other); // Overloaded assignment operator to clone ExprStmt &operator= (ExprStmt const &other); // move constructors ExprStmt (ExprStmt &&other) = default; ExprStmt &operator= (ExprStmt &&other) = default; bool is_unit_check_needed () const override { return must_be_unit; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ ExprStmt *clone_stmt_impl () const override { return new ExprStmt (*this); } }; } // namespace HIR } // namespace Rust #endif