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