Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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_HIR_STATEMENT_H
20 : : #define RUST_HIR_STATEMENT_H
21 : :
22 : : #include "rust-hir.h"
23 : : #include "rust-hir-path.h"
24 : : #include "rust-hir-expr.h"
25 : : #include "rust-system.h"
26 : :
27 : : namespace Rust {
28 : : namespace HIR {
29 : : /* Base statement abstract class. Note that most "statements" are not allowed in
30 : : * top-level module scope - only a subclass of statements called "items" are. */
31 : 2 : class Stmt : public Node, public FullVisitable
32 : : {
33 : : public:
34 : : using FullVisitable::accept_vis;
35 : :
36 : : // Unique pointer custom clone function
37 : 6 : std::unique_ptr<Stmt> clone_stmt () const
38 : : {
39 : 6 : return std::unique_ptr<Stmt> (clone_stmt_impl ());
40 : : }
41 : :
42 : 0 : BaseKind get_hir_kind () override { return STMT; }
43 : :
44 : 42 : virtual ~Stmt () {}
45 : :
46 : : virtual std::string as_string () const = 0;
47 : :
48 : : virtual void accept_vis (HIRStmtVisitor &vis) = 0;
49 : :
50 : : virtual location_t get_locus () const = 0;
51 : :
52 : 12750 : virtual bool is_unit_check_needed () const { return false; }
53 : :
54 : 1130836 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
55 : :
56 : : virtual bool is_item () const = 0;
57 : :
58 : : protected:
59 : 46321 : Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {}
60 : :
61 : : // Clone function implementation as pure virtual method
62 : : virtual Stmt *clone_stmt_impl () const = 0;
63 : :
64 : : Analysis::NodeMapping mappings;
65 : : };
66 : :
67 : : // Just a semi-colon, which apparently is a statement.
68 : 0 : class EmptyStmt : public Stmt
69 : : {
70 : : location_t locus;
71 : :
72 : : public:
73 : 0 : std::string as_string () const override { return std::string (1, ';'); }
74 : :
75 : 54 : EmptyStmt (Analysis::NodeMapping mappings, location_t locus)
76 : 54 : : Stmt (std::move (mappings)), locus (locus)
77 : : {}
78 : :
79 : 54 : location_t get_locus () const override final { return locus; }
80 : :
81 : : void accept_vis (HIRFullVisitor &vis) override;
82 : : void accept_vis (HIRStmtVisitor &vis) override;
83 : :
84 : 108 : bool is_item () const override final { return false; }
85 : :
86 : : protected:
87 : : /* Use covariance to implement clone function as returning this object rather
88 : : * than base */
89 : 0 : EmptyStmt *clone_stmt_impl () const override { return new EmptyStmt (*this); }
90 : : };
91 : :
92 : : /* Variable assignment let statement - type of "declaration statement" as it
93 : : * introduces new name into scope */
94 : : class LetStmt : public Stmt
95 : : {
96 : : // bool has_outer_attrs;
97 : : AST::AttrVec outer_attrs;
98 : :
99 : : std::unique_ptr<Pattern> variables_pattern;
100 : :
101 : : tl::optional<std::unique_ptr<Type>> type;
102 : :
103 : : tl::optional<std::unique_ptr<Expr>> init_expr;
104 : : tl::optional<std::unique_ptr<Expr>> else_expr;
105 : :
106 : : location_t locus;
107 : :
108 : : public:
109 : : // Returns whether let statement has outer attributes.
110 : : bool has_outer_attrs () const { return !outer_attrs.empty (); }
111 : :
112 : : // Returns whether let statement has a given return type.
113 : 24294 : bool has_type () const { return type.has_value (); }
114 : :
115 : : // Returns whether let statement has an initialisation expression.
116 : 88688 : bool has_init_expr () const { return init_expr.has_value (); }
117 : : // Returns whether let statement has a diverging else expression.
118 : 4 : bool has_else_expr () const { return else_expr.has_value (); }
119 : :
120 : : std::string as_string () const override;
121 : :
122 : : LetStmt (Analysis::NodeMapping mappings,
123 : : std::unique_ptr<Pattern> variables_pattern,
124 : : tl::optional<std::unique_ptr<Expr>> init_expr,
125 : : tl::optional<std::unique_ptr<Expr>> else_expr,
126 : : tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs,
127 : : location_t locus);
128 : :
129 : : // Copy constructor with clone
130 : : LetStmt (LetStmt const &other);
131 : :
132 : : // Overloaded assignment operator to clone
133 : : LetStmt &operator= (LetStmt const &other);
134 : :
135 : : // move constructors
136 : : LetStmt (LetStmt &&other) = default;
137 : : LetStmt &operator= (LetStmt &&other) = default;
138 : :
139 : 15748 : location_t get_locus () const override final { return locus; }
140 : :
141 : : void accept_vis (HIRFullVisitor &vis) override;
142 : : void accept_vis (HIRStmtVisitor &vis) override;
143 : :
144 : : const std::vector<AST::Attribute> &get_outer_attrs () const
145 : : {
146 : : return outer_attrs;
147 : : }
148 : 0 : std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
149 : :
150 : 6711 : HIR::Type &get_type ()
151 : : {
152 : 6711 : rust_assert (*type);
153 : 6711 : return *type.value ();
154 : : }
155 : :
156 : 0 : const HIR::Type &get_type () const
157 : : {
158 : 0 : rust_assert (*type);
159 : 0 : return *type.value ();
160 : : }
161 : :
162 : 113450 : HIR::Expr &get_init_expr ()
163 : : {
164 : 113450 : rust_assert (*init_expr);
165 : 113450 : return *init_expr.value ();
166 : : }
167 : :
168 : 8 : const HIR::Expr &get_init_expr () const
169 : : {
170 : 8 : rust_assert (*init_expr);
171 : 8 : return *init_expr.value ();
172 : : }
173 : :
174 : : HIR::Expr &get_else_expr ()
175 : : {
176 : : rust_assert (*else_expr);
177 : : return *else_expr.value ();
178 : : }
179 : :
180 : 0 : const HIR::Expr &get_else_expr () const
181 : : {
182 : 0 : rust_assert (*else_expr);
183 : 0 : return *else_expr.value ();
184 : : }
185 : :
186 : 35694 : HIR::Pattern &get_pattern () { return *variables_pattern; }
187 : :
188 : 25392 : bool is_item () const override final { return false; }
189 : :
190 : : protected:
191 : : /* Use covariance to implement clone function as returning this object rather
192 : : * than base */
193 : 4 : LetStmt *clone_stmt_impl () const override { return new LetStmt (*this); }
194 : : };
195 : :
196 : : /* class for expression statements (statements containing an expression) */
197 : : class ExprStmt : public Stmt
198 : : {
199 : : std::unique_ptr<Expr> expr;
200 : : location_t locus;
201 : : bool must_be_unit;
202 : :
203 : : public:
204 : : ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr,
205 : : location_t locus, bool must_be_unit);
206 : :
207 : : ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr,
208 : : location_t locus);
209 : :
210 : : std::string as_string () const override;
211 : :
212 : 7689 : location_t get_locus () const override final { return locus; }
213 : :
214 : : void accept_vis (HIRFullVisitor &vis) override;
215 : : void accept_vis (HIRStmtVisitor &vis) override;
216 : :
217 : 15342 : bool is_item () const override final { return false; }
218 : :
219 : 54929 : Expr &get_expr () { return *expr; }
220 : :
221 : : // Copy constructor with clone
222 : : ExprStmt (ExprStmt const &other);
223 : :
224 : : // Overloaded assignment operator to clone
225 : : ExprStmt &operator= (ExprStmt const &other);
226 : :
227 : : // move constructors
228 : : ExprStmt (ExprStmt &&other) = default;
229 : : ExprStmt &operator= (ExprStmt &&other) = default;
230 : :
231 : 7671 : bool is_unit_check_needed () const override { return must_be_unit; }
232 : :
233 : : protected:
234 : : /* Use covariance to implement clone function as returning this object rather
235 : : * than base */
236 : 2 : ExprStmt *clone_stmt_impl () const override { return new ExprStmt (*this); }
237 : : };
238 : :
239 : : } // namespace HIR
240 : : } // namespace Rust
241 : :
242 : : #endif
|