Branch data 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_EXPR_H
20 : : #define RUST_HIR_EXPR_H
21 : :
22 : : #include "rust-ast.h"
23 : : #include "rust-hir-expr-abstract.h"
24 : : #include "rust-hir-literal.h"
25 : : #include "rust-common.h"
26 : : #include "rust-hir-bound.h"
27 : : #include "rust-hir-attrs.h"
28 : : #include "rust-expr.h"
29 : : #include "rust-hir-map.h"
30 : : #include "rust-mapping-common.h"
31 : :
32 : : namespace Rust {
33 : : namespace HIR {
34 : :
35 : : // Loop label expression HIR node used with break and continue expressions
36 : : // TODO: inline?
37 : 288 : class LoopLabel /*: public Node*/
38 : : {
39 : : Lifetime label; // of type LIFETIME_OR_LABEL
40 : :
41 : : location_t locus;
42 : :
43 : : Analysis::NodeMapping mappings;
44 : :
45 : : public:
46 : : std::string to_string () const;
47 : :
48 : : LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label,
49 : : location_t locus);
50 : :
51 : 36 : location_t get_locus () const { return locus; }
52 : :
53 : : Analysis::NodeMapping &get_mappings () { return mappings; }
54 : :
55 : 43 : Lifetime &get_lifetime () { return label; }
56 : : };
57 : :
58 : : // HIR node for an expression with an accompanying block - abstract
59 : 0 : class ExprWithBlock : public Expr
60 : : {
61 : : // TODO: should this mean that a BlockExpr should be a member variable?
62 : : protected:
63 : : ExprWithBlock (Analysis::NodeMapping mappings,
64 : : AST::AttrVec outer_attrs = AST::AttrVec ());
65 : :
66 : : // pure virtual clone implementation
67 : : virtual ExprWithBlock *clone_expr_with_block_impl () const = 0;
68 : :
69 : : // prevent having to define multiple clone expressions
70 : 7 : ExprWithBlock *clone_expr_impl () const override
71 : : {
72 : 7 : return clone_expr_with_block_impl ();
73 : : }
74 : :
75 : : public:
76 : : // Unique pointer custom clone function
77 : 0 : std::unique_ptr<ExprWithBlock> clone_expr_with_block () const
78 : : {
79 : 0 : return std::unique_ptr<ExprWithBlock> (clone_expr_with_block_impl ());
80 : : }
81 : :
82 : 0 : BlockType get_block_expr_type () const final override
83 : : {
84 : 0 : return BlockType::WITH_BLOCK;
85 : : };
86 : : };
87 : :
88 : : // Literals? Or literal base?
89 : : class LiteralExpr : public ExprWithoutBlock
90 : : {
91 : : Literal literal;
92 : : location_t locus;
93 : : bool negative_number = false;
94 : :
95 : : public:
96 : 17361 : std::string to_string () const override { return literal.as_string (); }
97 : :
98 : 44262 : Literal::LitType get_lit_type () const { return literal.get_lit_type (); }
99 : :
100 : : LiteralExpr (Analysis::NodeMapping mappings, std::string value_as_string,
101 : : Literal::LitType type, PrimitiveCoreType type_hint,
102 : : location_t locus, AST::AttrVec outer_attrs);
103 : :
104 : : LiteralExpr (Analysis::NodeMapping mappings, Literal literal,
105 : : location_t locus, AST::AttrVec outer_attrs);
106 : :
107 : : // Unique pointer custom clone function
108 : : std::unique_ptr<LiteralExpr> clone_literal_expr () const
109 : : {
110 : : return std::unique_ptr<LiteralExpr> (clone_literal_expr_impl ());
111 : : }
112 : :
113 : 70595 : location_t get_locus () const override final { return locus; }
114 : :
115 : : void accept_vis (HIRFullVisitor &vis) override;
116 : : void accept_vis (HIRExpressionVisitor &vis) override;
117 : :
118 : 18456 : Literal &get_literal () { return literal; }
119 : 21854 : const Literal &get_literal () const { return literal; }
120 : :
121 : 1304 : ExprType get_expression_type () const override final { return ExprType::Lit; }
122 : :
123 : 18041 : bool is_negative () const { return negative_number; }
124 : 550 : void set_negative ()
125 : : {
126 : 550 : rust_assert (get_lit_type () == Literal::LitType::INT
127 : : || get_lit_type () == Literal::LitType::FLOAT);
128 : 550 : negative_number = true;
129 : 550 : }
130 : :
131 : : protected:
132 : : /* Use covariance to implement clone function as returning this object rather
133 : : * than base */
134 : 90371 : LiteralExpr *clone_expr_impl () const override
135 : : {
136 : 90371 : return new LiteralExpr (*this);
137 : : }
138 : :
139 : : /* Use covariance to implement clone function as returning this object rather
140 : : * than base */
141 : 0 : LiteralExpr *clone_expr_without_block_impl () const override
142 : : {
143 : 0 : return new LiteralExpr (*this);
144 : : }
145 : :
146 : : /* not virtual as currently no subclasses of LiteralExpr, but could be in
147 : : * future */
148 : : /*virtual*/ LiteralExpr *clone_literal_expr_impl () const
149 : : {
150 : : return new LiteralExpr (*this);
151 : : }
152 : : };
153 : :
154 : : /* Represents an expression using unary or binary operators as HIR node. Can be
155 : : * overloaded. */
156 : : class OperatorExpr : public ExprWithoutBlock
157 : : {
158 : : // TODO: create binary and unary operator subclasses?
159 : : private:
160 : : location_t locus;
161 : :
162 : : protected:
163 : : /* Variable must be protected to allow derived classes to use it as a first
164 : : * class citizen */
165 : : std::unique_ptr<Expr> main_or_left_expr;
166 : :
167 : : // Constructor (only for initialisation of expr purposes)
168 : : OperatorExpr (Analysis::NodeMapping mappings,
169 : : std::unique_ptr<Expr> main_or_left_expr,
170 : : AST::AttrVec outer_attribs, location_t locus);
171 : :
172 : : // Copy constructor (only for initialisation of expr purposes)
173 : : OperatorExpr (OperatorExpr const &other);
174 : :
175 : : // Overload assignment operator to deep copy expr
176 : : OperatorExpr &operator= (OperatorExpr const &other);
177 : :
178 : : // move constructors
179 : : OperatorExpr (OperatorExpr &&other) = default;
180 : : OperatorExpr &operator= (OperatorExpr &&other) = default;
181 : :
182 : : public:
183 : 93755 : location_t get_locus () const override final { return locus; }
184 : :
185 : 77122 : Expr &get_expr () { return *main_or_left_expr; }
186 : :
187 : 159 : ExprType get_expression_type () const override final
188 : : {
189 : 159 : return ExprType::Operator;
190 : : }
191 : : };
192 : :
193 : : /* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be
194 : : * overloaded. */
195 : : class BorrowExpr : public OperatorExpr
196 : : {
197 : : Mutability mut;
198 : : bool raw;
199 : :
200 : : public:
201 : : std::string to_string () const override;
202 : :
203 : : BorrowExpr (Analysis::NodeMapping mappings,
204 : : std::unique_ptr<Expr> borrow_lvalue, Mutability mut, bool raw,
205 : : AST::AttrVec outer_attribs, location_t locus);
206 : :
207 : : void accept_vis (HIRFullVisitor &vis) override;
208 : : void accept_vis (HIRExpressionVisitor &vis) override;
209 : :
210 : 1947 : Mutability get_mut () const { return mut; }
211 : 0 : bool is_mut () const { return mut == Mutability::Mut; }
212 : 1947 : bool is_raw_borrow () const { return raw; }
213 : :
214 : : protected:
215 : : /* Use covariance to implement clone function as returning this object rather
216 : : * than base */
217 : 4 : BorrowExpr *clone_expr_impl () const override
218 : : {
219 : 4 : return new BorrowExpr (*this);
220 : : }
221 : :
222 : : /* Use covariance to implement clone function as returning this object rather
223 : : * than base */
224 : 0 : BorrowExpr *clone_expr_without_block_impl () const override
225 : : {
226 : 0 : return new BorrowExpr (*this);
227 : : }
228 : : };
229 : :
230 : : // Unary prefix * deference operator
231 : 0 : class DereferenceExpr : public OperatorExpr
232 : : {
233 : : public:
234 : : std::string to_string () const override;
235 : :
236 : : // Constructor calls OperatorExpr's protected constructor
237 : : DereferenceExpr (Analysis::NodeMapping mappings,
238 : : std::unique_ptr<Expr> deref_lvalue,
239 : : AST::AttrVec outer_attribs, location_t locus);
240 : :
241 : : void accept_vis (HIRFullVisitor &vis) override;
242 : : void accept_vis (HIRExpressionVisitor &vis) override;
243 : :
244 : : protected:
245 : : /* Use covariance to implement clone function as returning this object rather
246 : : * than base */
247 : 0 : DereferenceExpr *clone_expr_impl () const override
248 : : {
249 : 0 : return new DereferenceExpr (*this);
250 : : }
251 : :
252 : : /* Use covariance to implement clone function as returning this object rather
253 : : * than base */
254 : 0 : DereferenceExpr *clone_expr_without_block_impl () const override
255 : : {
256 : 0 : return new DereferenceExpr (*this);
257 : : }
258 : : };
259 : :
260 : : // Unary postfix ? error propogation operator. Cannot be overloaded.
261 : 0 : class ErrorPropagationExpr : public OperatorExpr
262 : : {
263 : : public:
264 : : std::string to_string () const override;
265 : :
266 : : // Constructor calls OperatorExpr's protected constructor
267 : : ErrorPropagationExpr (Analysis::NodeMapping mappings,
268 : : std::unique_ptr<Expr> potential_error_value,
269 : : AST::AttrVec outer_attribs, location_t locus);
270 : :
271 : : void accept_vis (HIRFullVisitor &vis) override;
272 : : void accept_vis (HIRExpressionVisitor &vis) override;
273 : :
274 : : protected:
275 : : /* Use covariance to implement clone function as returning this object rather
276 : : * than base */
277 : 0 : ErrorPropagationExpr *clone_expr_impl () const override
278 : : {
279 : 0 : return new ErrorPropagationExpr (*this);
280 : : }
281 : :
282 : : /* Use covariance to implement clone function as returning this object rather
283 : : * than base */
284 : 0 : ErrorPropagationExpr *clone_expr_without_block_impl () const override
285 : : {
286 : 0 : return new ErrorPropagationExpr (*this);
287 : : }
288 : : };
289 : :
290 : : // Unary prefix - or ! negation or NOT operators.
291 : : class NegationExpr : public OperatorExpr
292 : : {
293 : : public:
294 : : using ExprType = NegationOperator;
295 : :
296 : : private:
297 : : /* Note: overload negation via std::ops::Neg and not via std::ops::Not
298 : : * Negation only works for signed integer and floating-point types, NOT only
299 : : * works for boolean and integer types (via bitwise NOT) */
300 : : ExprType expr_type;
301 : :
302 : : public:
303 : : std::string to_string () const override;
304 : :
305 : 1722 : ExprType get_expr_type () const { return expr_type; }
306 : :
307 : : // Constructor calls OperatorExpr's protected constructor
308 : : NegationExpr (Analysis::NodeMapping mappings,
309 : : std::unique_ptr<Expr> negated_value, ExprType expr_kind,
310 : : AST::AttrVec outer_attribs, location_t locus);
311 : :
312 : : void accept_vis (HIRFullVisitor &vis) override;
313 : : void accept_vis (HIRExpressionVisitor &vis) override;
314 : :
315 : : protected:
316 : : /* Use covariance to implement clone function as returning this object rather
317 : : * than base */
318 : 9183 : NegationExpr *clone_expr_impl () const override
319 : : {
320 : 9183 : return new NegationExpr (*this);
321 : : }
322 : :
323 : : /* Use covariance to implement clone function as returning this object rather
324 : : * than base */
325 : 0 : NegationExpr *clone_expr_without_block_impl () const override
326 : : {
327 : 0 : return new NegationExpr (*this);
328 : : }
329 : : };
330 : :
331 : : // Infix binary operators. +, -, *, /, %, &, |, ^, <<, >>
332 : : class ArithmeticOrLogicalExpr : public OperatorExpr
333 : : {
334 : : public:
335 : : using ExprType = ArithmeticOrLogicalOperator;
336 : :
337 : : private:
338 : : // Note: overloading trait specified in comments
339 : : ExprType expr_type;
340 : :
341 : : std::unique_ptr<Expr> right_expr;
342 : :
343 : : public:
344 : : std::string to_string () const override;
345 : :
346 : 13299 : ExprType get_expr_type () const { return expr_type; }
347 : :
348 : : // Constructor calls OperatorExpr's protected constructor
349 : : ArithmeticOrLogicalExpr (Analysis::NodeMapping mappings,
350 : : std::unique_ptr<Expr> left_value,
351 : : std::unique_ptr<Expr> right_value,
352 : : ExprType expr_kind, location_t locus);
353 : : // outer attributes not allowed
354 : :
355 : : // Copy constructor - probably required due to unique pointer
356 : : ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other);
357 : :
358 : : // Overload assignment operator
359 : : ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other);
360 : :
361 : : // move constructors
362 : : ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr &&other) = default;
363 : : ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr &&other)
364 : : = default;
365 : :
366 : : void accept_vis (HIRFullVisitor &vis) override;
367 : : void accept_vis (HIRExpressionVisitor &vis) override;
368 : :
369 : 2922 : void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
370 : 2922 : void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
371 : :
372 : 25093 : Expr &get_lhs () { return *main_or_left_expr; }
373 : 28617 : Expr &get_rhs () { return *right_expr; }
374 : :
375 : : std::string get_operator_str () const;
376 : :
377 : : protected:
378 : : /* Use covariance to implement clone function as returning this object rather
379 : : * than base */
380 : 34 : ArithmeticOrLogicalExpr *clone_expr_impl () const override
381 : : {
382 : 34 : return new ArithmeticOrLogicalExpr (*this);
383 : : }
384 : :
385 : : /* Use covariance to implement clone function as returning this object rather
386 : : * than base */
387 : 0 : ArithmeticOrLogicalExpr *clone_expr_without_block_impl () const override
388 : : {
389 : 0 : return new ArithmeticOrLogicalExpr (*this);
390 : : }
391 : : };
392 : :
393 : : // Infix binary comparison operators. ==, !=, <, <=, >, >=
394 : : class ComparisonExpr : public OperatorExpr
395 : : {
396 : : public:
397 : : using ExprType = ComparisonOperator;
398 : :
399 : : private:
400 : : // Note: overloading trait specified in comments
401 : : ExprType expr_type;
402 : :
403 : : std::unique_ptr<Expr> right_expr;
404 : :
405 : : public:
406 : : std::string to_string () const override;
407 : :
408 : 9648 : ExprType get_expr_type () const { return expr_type; }
409 : :
410 : : // Constructor requires pointers for polymorphism
411 : : ComparisonExpr (Analysis::NodeMapping mappings,
412 : : std::unique_ptr<Expr> left_value,
413 : : std::unique_ptr<Expr> right_value, ExprType comparison_kind,
414 : : location_t locus);
415 : : // outer attributes not allowed
416 : :
417 : : // Copy constructor also calls OperatorExpr's protected constructor
418 : : ComparisonExpr (ComparisonExpr const &other);
419 : :
420 : : // Overload assignment operator to deep copy
421 : : ComparisonExpr &operator= (ComparisonExpr const &other);
422 : :
423 : : // move constructors
424 : : ComparisonExpr (ComparisonExpr &&other) = default;
425 : : ComparisonExpr &operator= (ComparisonExpr &&other) = default;
426 : :
427 : : void accept_vis (HIRFullVisitor &vis) override;
428 : : void accept_vis (HIRExpressionVisitor &vis) override;
429 : :
430 : 20468 : Expr &get_lhs () { return *main_or_left_expr; }
431 : 24014 : Expr &get_rhs () { return *right_expr; }
432 : :
433 : : ExprType get_kind () { return expr_type; }
434 : :
435 : : /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
436 : : * maybe? */
437 : : protected:
438 : : /* Use covariance to implement clone function as returning this object rather
439 : : * than base */
440 : 0 : ComparisonExpr *clone_expr_impl () const override
441 : : {
442 : 0 : return new ComparisonExpr (*this);
443 : : }
444 : :
445 : : /* Use covariance to implement clone function as returning this object rather
446 : : * than base */
447 : 0 : ComparisonExpr *clone_expr_without_block_impl () const override
448 : : {
449 : 0 : return new ComparisonExpr (*this);
450 : : }
451 : : };
452 : :
453 : : // Infix binary lazy boolean logical operators && and ||.
454 : : class LazyBooleanExpr : public OperatorExpr
455 : : {
456 : : public:
457 : : using ExprType = LazyBooleanOperator;
458 : :
459 : : private:
460 : : ExprType expr_type;
461 : :
462 : : std::unique_ptr<Expr> right_expr;
463 : :
464 : : public:
465 : : // Constructor calls OperatorExpr's protected constructor
466 : : LazyBooleanExpr (Analysis::NodeMapping mappings,
467 : : std::unique_ptr<Expr> left_bool_expr,
468 : : std::unique_ptr<Expr> right_bool_expr, ExprType expr_kind,
469 : : location_t locus);
470 : : // outer attributes not allowed
471 : :
472 : : // Copy constructor also calls OperatorExpr's protected constructor
473 : : LazyBooleanExpr (LazyBooleanExpr const &other);
474 : :
475 : : // Overload assignment operator to deep copy
476 : : LazyBooleanExpr &operator= (LazyBooleanExpr const &other);
477 : :
478 : : // move constructors
479 : : LazyBooleanExpr (LazyBooleanExpr &&other) = default;
480 : : LazyBooleanExpr &operator= (LazyBooleanExpr &&other) = default;
481 : :
482 : : std::string to_string () const override;
483 : :
484 : 377 : ExprType get_expr_type () const { return expr_type; }
485 : :
486 : : void accept_vis (HIRFullVisitor &vis) override;
487 : : void accept_vis (HIRExpressionVisitor &vis) override;
488 : :
489 : 4646 : Expr &get_lhs () { return *main_or_left_expr; }
490 : 4646 : Expr &get_rhs () { return *right_expr; }
491 : :
492 : : protected:
493 : : /* Use covariance to implement clone function as returning this object rather
494 : : * than base */
495 : 0 : LazyBooleanExpr *clone_expr_impl () const override
496 : : {
497 : 0 : return new LazyBooleanExpr (*this);
498 : : }
499 : :
500 : : /* Use covariance to implement clone function as returning this object rather
501 : : * than base */
502 : 0 : LazyBooleanExpr *clone_expr_without_block_impl () const override
503 : : {
504 : 0 : return new LazyBooleanExpr (*this);
505 : : }
506 : : };
507 : :
508 : : // Binary infix "as" chir expression.
509 : : class TypeCastExpr : public OperatorExpr
510 : : {
511 : : std::unique_ptr<Type> type_to_convert_to;
512 : :
513 : : // Note: only certain type casts allowed, outlined in reference
514 : : public:
515 : : std::string to_string () const override;
516 : :
517 : : // Constructor requires calling protected constructor of OperatorExpr
518 : : TypeCastExpr (Analysis::NodeMapping mappings,
519 : : std::unique_ptr<Expr> expr_to_cast,
520 : : std::unique_ptr<Type> type_to_cast_to, location_t locus);
521 : : // outer attributes not allowed
522 : :
523 : : // Copy constructor also requires calling protected constructor
524 : : TypeCastExpr (TypeCastExpr const &other);
525 : :
526 : : // Overload assignment operator to deep copy
527 : : TypeCastExpr &operator= (TypeCastExpr const &other);
528 : :
529 : : // move constructors as not supported in c++03
530 : : TypeCastExpr (TypeCastExpr &&other) = default;
531 : : TypeCastExpr &operator= (TypeCastExpr &&other) = default;
532 : :
533 : : void accept_vis (HIRFullVisitor &vis) override;
534 : : void accept_vis (HIRExpressionVisitor &vis) override;
535 : :
536 : : // FIXME: isn't it the same as get_expr() from parent?
537 : 19912 : Expr &get_casted_expr () { return *main_or_left_expr; }
538 : :
539 : 12174 : Type &get_type_to_convert_to () { return *type_to_convert_to; }
540 : :
541 : : protected:
542 : : /* Use covariance to implement clone function as returning this object rather
543 : : * than base */
544 : 0 : TypeCastExpr *clone_expr_impl () const override
545 : : {
546 : 0 : return new TypeCastExpr (*this);
547 : : }
548 : :
549 : : /* Use covariance to implement clone function as returning this object rather
550 : : * than base */
551 : 0 : TypeCastExpr *clone_expr_without_block_impl () const override
552 : : {
553 : 0 : return new TypeCastExpr (*this);
554 : : }
555 : : };
556 : :
557 : : // Binary assignment expression.
558 : : class AssignmentExpr : public OperatorExpr
559 : : {
560 : : std::unique_ptr<Expr> right_expr;
561 : :
562 : : public:
563 : : std::string to_string () const override;
564 : :
565 : : // Call OperatorExpr constructor to initialise left_expr
566 : : AssignmentExpr (Analysis::NodeMapping mappings,
567 : : std::unique_ptr<Expr> value_to_assign_to,
568 : : std::unique_ptr<Expr> value_to_assign, location_t locus);
569 : : // outer attributes not allowed
570 : :
571 : : // Call OperatorExpr constructor in copy constructor, as well as clone
572 : : AssignmentExpr (AssignmentExpr const &other);
573 : :
574 : : // Overload assignment operator to clone unique_ptr right_expr
575 : : AssignmentExpr &operator= (AssignmentExpr const &other);
576 : :
577 : : // move constructors
578 : : AssignmentExpr (AssignmentExpr &&other) = default;
579 : : AssignmentExpr &operator= (AssignmentExpr &&other) = default;
580 : :
581 : : void accept_vis (HIRFullVisitor &vis) override;
582 : : void accept_vis (HIRExpressionVisitor &vis) override;
583 : :
584 : 2364 : void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
585 : 2364 : void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
586 : :
587 : 24427 : Expr &get_lhs () { return *main_or_left_expr; }
588 : 19527 : Expr &get_rhs () { return *right_expr; }
589 : :
590 : : protected:
591 : : /* Use covariance to implement clone function as returning this object rather
592 : : * than base */
593 : 0 : AssignmentExpr *clone_expr_impl () const override
594 : : {
595 : 0 : return new AssignmentExpr (*this);
596 : : }
597 : :
598 : : /* Use covariance to implement clone function as returning this object rather
599 : : * than base */
600 : 0 : AssignmentExpr *clone_expr_without_block_impl () const override
601 : : {
602 : 0 : return new AssignmentExpr (*this);
603 : : }
604 : : };
605 : :
606 : : class CompoundAssignmentExpr : public OperatorExpr
607 : : {
608 : : public:
609 : : using ExprType = ArithmeticOrLogicalOperator;
610 : :
611 : : private:
612 : : // Note: overloading trait specified in comments
613 : : ExprType expr_type;
614 : : std::unique_ptr<Expr> right_expr;
615 : :
616 : : public:
617 : : std::string to_string () const override;
618 : :
619 : 2077 : ExprType get_expr_type () const { return expr_type; }
620 : :
621 : : // Use pointers in constructor to enable polymorphism
622 : : CompoundAssignmentExpr (Analysis::NodeMapping mappings,
623 : : std::unique_ptr<Expr> value_to_assign_to,
624 : : std::unique_ptr<Expr> value_to_assign,
625 : : ExprType expr_kind, location_t locus);
626 : : // outer attributes not allowed
627 : :
628 : : // Have clone in copy constructor
629 : : CompoundAssignmentExpr (CompoundAssignmentExpr const &other);
630 : :
631 : : // Overload assignment operator to clone
632 : : CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other);
633 : :
634 : : // move constructors
635 : : CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
636 : : CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
637 : :
638 : : void accept_vis (HIRFullVisitor &vis) override;
639 : : void accept_vis (HIRExpressionVisitor &vis) override;
640 : :
641 : 5322 : Expr &get_lhs () { return *main_or_left_expr; }
642 : :
643 : 5336 : Expr &get_rhs () { return *right_expr; }
644 : :
645 : 522 : void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
646 : 522 : void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
647 : :
648 : : std::string get_operator_str () const;
649 : :
650 : : protected:
651 : : /* Use covariance to implement clone function as returning this object rather
652 : : * than base */
653 : 0 : CompoundAssignmentExpr *clone_expr_without_block_impl () const override
654 : : {
655 : 0 : return new CompoundAssignmentExpr (*this);
656 : : }
657 : : };
658 : :
659 : : // Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
660 : : class GroupedExpr : public ExprWithoutBlock, public WithInnerAttrs
661 : : {
662 : : std::unique_ptr<Expr> expr_in_parens;
663 : :
664 : : location_t locus;
665 : :
666 : : public:
667 : : std::string to_string () const override;
668 : :
669 : : GroupedExpr (Analysis::NodeMapping mappings,
670 : : std::unique_ptr<Expr> parenthesised_expr,
671 : : AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
672 : : location_t locus);
673 : :
674 : : // Copy constructor includes clone for expr_in_parens
675 : : GroupedExpr (GroupedExpr const &other);
676 : :
677 : : // Overloaded assignment operator to clone expr_in_parens
678 : : GroupedExpr &operator= (GroupedExpr const &other);
679 : :
680 : : // move constructors
681 : : GroupedExpr (GroupedExpr &&other) = default;
682 : : GroupedExpr &operator= (GroupedExpr &&other) = default;
683 : :
684 : 641 : location_t get_locus () const override final { return locus; }
685 : :
686 : : void accept_vis (HIRFullVisitor &vis) override;
687 : : void accept_vis (HIRExpressionVisitor &vis) override;
688 : :
689 : 2403 : Expr &get_expr_in_parens () { return *expr_in_parens; }
690 : :
691 : 1 : ExprType get_expression_type () const override final
692 : : {
693 : 1 : return ExprType::Grouped;
694 : : }
695 : :
696 : : protected:
697 : : /* Use covariance to implement clone function as returning this object rather
698 : : * than base */
699 : 0 : GroupedExpr *clone_expr_impl () const override
700 : : {
701 : 0 : return new GroupedExpr (*this);
702 : : }
703 : :
704 : : /* Use covariance to implement clone function as returning this object rather
705 : : * than base */
706 : 0 : GroupedExpr *clone_expr_without_block_impl () const override
707 : : {
708 : 0 : return new GroupedExpr (*this);
709 : : }
710 : : };
711 : :
712 : : // Base array initialisation internal element representation thing (abstract)
713 : : // aka ArrayElements
714 : 0 : class ArrayElems : public FullVisitable
715 : : {
716 : : public:
717 : : enum ArrayExprType
718 : : {
719 : : VALUES,
720 : : COPIED,
721 : : };
722 : :
723 : 427 : ArrayElems (Analysis::NodeMapping mappings) : mappings (mappings){};
724 : :
725 : : virtual ~ArrayElems () {}
726 : :
727 : : // Unique pointer custom clone ArrayElems function
728 : 0 : std::unique_ptr<ArrayElems> clone_array_elems () const
729 : : {
730 : 0 : return std::unique_ptr<ArrayElems> (clone_array_elems_impl ());
731 : : }
732 : :
733 : : virtual std::string to_string () const = 0;
734 : :
735 : : virtual void accept_vis (HIRFullVisitor &vis) = 0;
736 : :
737 : : virtual ArrayExprType get_array_expr_type () const = 0;
738 : :
739 : 113 : Analysis::NodeMapping &get_mappings () { return mappings; }
740 : :
741 : : protected:
742 : : // pure virtual clone implementation
743 : : virtual ArrayElems *clone_array_elems_impl () const = 0;
744 : :
745 : : Analysis::NodeMapping mappings;
746 : : };
747 : :
748 : : // Value array elements
749 : : class ArrayElemsValues : public ArrayElems
750 : : {
751 : : std::vector<std::unique_ptr<Expr>> values;
752 : :
753 : : // TODO: should this store location data?
754 : :
755 : : public:
756 : : ArrayElemsValues (Analysis::NodeMapping mappings,
757 : : std::vector<std::unique_ptr<Expr>> elems);
758 : :
759 : : // copy constructor with vector clone
760 : : ArrayElemsValues (ArrayElemsValues const &other);
761 : :
762 : : // overloaded assignment operator with vector clone
763 : : ArrayElemsValues &operator= (ArrayElemsValues const &other);
764 : :
765 : : // move constructors
766 : : ArrayElemsValues (ArrayElemsValues &&other) = default;
767 : : ArrayElemsValues &operator= (ArrayElemsValues &&other) = default;
768 : :
769 : : std::string to_string () const override;
770 : :
771 : : void accept_vis (HIRFullVisitor &vis) override;
772 : :
773 : 303 : size_t get_num_elements () const { return values.size (); }
774 : :
775 : 2012 : std::vector<std::unique_ptr<Expr>> &get_values () { return values; }
776 : :
777 : 862 : ArrayElems::ArrayExprType get_array_expr_type () const override final
778 : : {
779 : 862 : return ArrayElems::ArrayExprType::VALUES;
780 : : }
781 : :
782 : : protected:
783 : 0 : ArrayElemsValues *clone_array_elems_impl () const override
784 : : {
785 : 0 : return new ArrayElemsValues (*this);
786 : : }
787 : : };
788 : :
789 : : // Copied array element and number of copies
790 : : class ArrayElemsCopied : public ArrayElems
791 : : {
792 : : std::unique_ptr<Expr> elem_to_copy;
793 : : std::unique_ptr<Expr> num_copies;
794 : :
795 : : public:
796 : : // Constructor requires pointers for polymorphism
797 : : ArrayElemsCopied (Analysis::NodeMapping mappings,
798 : : std::unique_ptr<Expr> copied_elem,
799 : : std::unique_ptr<Expr> copy_amount);
800 : :
801 : : // Copy constructor required due to unique_ptr - uses custom clone
802 : : ArrayElemsCopied (ArrayElemsCopied const &other);
803 : :
804 : : // Overloaded assignment operator for deep copying
805 : : ArrayElemsCopied &operator= (ArrayElemsCopied const &other);
806 : :
807 : : // move constructors
808 : : ArrayElemsCopied (ArrayElemsCopied &&other) = default;
809 : : ArrayElemsCopied &operator= (ArrayElemsCopied &&other) = default;
810 : :
811 : : std::string to_string () const override;
812 : :
813 : : void accept_vis (HIRFullVisitor &vis) override;
814 : :
815 : 723 : Expr &get_elem_to_copy () { return *elem_to_copy; }
816 : :
817 : 509 : Expr &get_num_copies_expr () { return *num_copies; }
818 : :
819 : 347 : ArrayElems::ArrayExprType get_array_expr_type () const override final
820 : : {
821 : 347 : return ArrayElems::ArrayExprType::COPIED;
822 : : }
823 : :
824 : : protected:
825 : 0 : ArrayElemsCopied *clone_array_elems_impl () const override
826 : : {
827 : 0 : return new ArrayElemsCopied (*this);
828 : : }
829 : : };
830 : :
831 : : // Array definition-ish expression
832 : : class ArrayExpr : public ExprWithoutBlock, public WithInnerAttrs
833 : : {
834 : : std::unique_ptr<ArrayElems> internal_elements;
835 : :
836 : : location_t locus;
837 : :
838 : : public:
839 : : std::string to_string () const override;
840 : :
841 : : // Returns whether array expr has array elems or if it is just empty.
842 : 0 : bool has_array_elems () const { return internal_elements != nullptr; }
843 : :
844 : : // Constructor requires ArrayElems pointer
845 : : ArrayExpr (Analysis::NodeMapping mappings,
846 : : std::unique_ptr<ArrayElems> array_elems,
847 : : AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
848 : : location_t locus);
849 : :
850 : : // Copy constructor requires cloning ArrayElems for polymorphism to hold
851 : : ArrayExpr (ArrayExpr const &other);
852 : :
853 : : // Overload assignment operator to clone internal_elements
854 : : ArrayExpr &operator= (ArrayExpr const &other);
855 : :
856 : : // move constructors
857 : : ArrayExpr (ArrayExpr &&other) = default;
858 : : ArrayExpr &operator= (ArrayExpr &&other) = default;
859 : :
860 : 3881 : location_t get_locus () const override final { return locus; }
861 : :
862 : : void accept_vis (HIRFullVisitor &vis) override;
863 : : void accept_vis (HIRExpressionVisitor &vis) override;
864 : :
865 : 2823 : ArrayElems &get_internal_elements () { return *internal_elements; };
866 : :
867 : 32 : ExprType get_expression_type () const override final
868 : : {
869 : 32 : return ExprType::Array;
870 : : }
871 : :
872 : : protected:
873 : : /* Use covariance to implement clone function as returning this object rather
874 : : * than base */
875 : 0 : ArrayExpr *clone_expr_impl () const override { return new ArrayExpr (*this); }
876 : :
877 : : /* Use covariance to implement clone function as returning this object rather
878 : : * than base */
879 : 0 : ArrayExpr *clone_expr_without_block_impl () const override
880 : : {
881 : 0 : return new ArrayExpr (*this);
882 : : }
883 : : };
884 : :
885 : : class ArrayIndexExpr : public ExprWithoutBlock
886 : : {
887 : : std::unique_ptr<Expr> array_expr;
888 : : std::unique_ptr<Expr> index_expr;
889 : :
890 : : location_t locus;
891 : :
892 : : public:
893 : : std::string to_string () const override;
894 : :
895 : : ArrayIndexExpr (Analysis::NodeMapping mappings,
896 : : std::unique_ptr<Expr> array_expr,
897 : : std::unique_ptr<Expr> array_index_expr,
898 : : AST::AttrVec outer_attribs, location_t locus);
899 : :
900 : : // Copy constructor requires special cloning due to unique_ptr
901 : : ArrayIndexExpr (ArrayIndexExpr const &other);
902 : :
903 : : // Overload assignment operator to clone unique_ptrs
904 : : ArrayIndexExpr &operator= (ArrayIndexExpr const &other);
905 : :
906 : : // move constructors
907 : : ArrayIndexExpr (ArrayIndexExpr &&other) = default;
908 : : ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
909 : :
910 : 1185 : location_t get_locus () const override final { return locus; }
911 : :
912 : : void accept_vis (HIRFullVisitor &vis) override;
913 : : void accept_vis (HIRExpressionVisitor &vis) override;
914 : :
915 : 2112 : Expr &get_array_expr () { return *array_expr; }
916 : 2279 : Expr &get_index_expr () { return *index_expr; }
917 : :
918 : 9 : ExprType get_expression_type () const override final
919 : : {
920 : 9 : return ExprType::ArrayIndex;
921 : : }
922 : :
923 : : protected:
924 : : /* Use covariance to implement clone function as returning this object rather
925 : : * than base */
926 : 0 : ArrayIndexExpr *clone_expr_impl () const override
927 : : {
928 : 0 : return new ArrayIndexExpr (*this);
929 : : }
930 : :
931 : : /* Use covariance to implement clone function as returning this object rather
932 : : * than base */
933 : 0 : ArrayIndexExpr *clone_expr_without_block_impl () const override
934 : : {
935 : 0 : return new ArrayIndexExpr (*this);
936 : : }
937 : : };
938 : :
939 : : // HIR representation of a tuple
940 : : class TupleExpr : public ExprWithoutBlock, public WithInnerAttrs
941 : : {
942 : : std::vector<std::unique_ptr<Expr>> tuple_elems;
943 : : // replaces (inlined version of) TupleElements
944 : :
945 : : location_t locus;
946 : :
947 : : public:
948 : : std::string to_string () const override;
949 : :
950 : : TupleExpr (Analysis::NodeMapping mappings,
951 : : std::vector<std::unique_ptr<Expr>> tuple_elements,
952 : : AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
953 : : location_t locus);
954 : :
955 : : // copy constructor with vector clone
956 : : TupleExpr (TupleExpr const &other);
957 : :
958 : : // overloaded assignment operator to vector clone
959 : : TupleExpr &operator= (TupleExpr const &other);
960 : :
961 : : // move constructors
962 : : TupleExpr (TupleExpr &&other) = default;
963 : : TupleExpr &operator= (TupleExpr &&other) = default;
964 : :
965 : : /* Note: syntactically, can disambiguate single-element tuple from parens with
966 : : * comma, i.e. (0,) rather than (0) */
967 : :
968 : 2422 : location_t get_locus () const override final { return locus; }
969 : :
970 : : void accept_vis (HIRFullVisitor &vis) override;
971 : : void accept_vis (HIRExpressionVisitor &vis) override;
972 : :
973 : : const std::vector<std::unique_ptr<Expr>> &get_tuple_elems () const
974 : : {
975 : : return tuple_elems;
976 : : }
977 : 3410 : std::vector<std::unique_ptr<Expr>> &get_tuple_elems () { return tuple_elems; }
978 : :
979 : 1127 : bool is_unit () const { return tuple_elems.size () == 0; }
980 : :
981 : 0 : ExprType get_expression_type () const override final
982 : : {
983 : 0 : return ExprType::Tuple;
984 : : }
985 : :
986 : : protected:
987 : : /* Use covariance to implement clone function as returning this object rather
988 : : * than base */
989 : 0 : TupleExpr *clone_expr_impl () const override { return new TupleExpr (*this); }
990 : :
991 : : /* Use covariance to implement clone function as returning this object rather
992 : : * than base */
993 : 0 : TupleExpr *clone_expr_without_block_impl () const override
994 : : {
995 : 0 : return new TupleExpr (*this);
996 : : }
997 : : };
998 : :
999 : : class TupleIndexExpr : public ExprWithoutBlock
1000 : : {
1001 : : std::unique_ptr<Expr> tuple_expr;
1002 : : TupleIndex tuple_index;
1003 : : location_t locus;
1004 : :
1005 : : public:
1006 : : std::string to_string () const override;
1007 : :
1008 : 1774 : TupleIndex get_tuple_index () const { return tuple_index; }
1009 : :
1010 : : TupleIndexExpr (Analysis::NodeMapping mappings,
1011 : : std::unique_ptr<Expr> tuple_expr, TupleIndex index,
1012 : : AST::AttrVec outer_attribs, location_t locus);
1013 : :
1014 : : // Copy constructor requires a clone for tuple_expr
1015 : : TupleIndexExpr (TupleIndexExpr const &other);
1016 : :
1017 : : // Overload assignment operator in order to clone
1018 : : TupleIndexExpr &operator= (TupleIndexExpr const &other);
1019 : :
1020 : : // move constructors
1021 : : TupleIndexExpr (TupleIndexExpr &&other) = default;
1022 : : TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
1023 : :
1024 : 2856 : location_t get_locus () const override final { return locus; }
1025 : :
1026 : : void accept_vis (HIRFullVisitor &vis) override;
1027 : : void accept_vis (HIRExpressionVisitor &vis) override;
1028 : :
1029 : 5898 : Expr &get_tuple_expr () { return *tuple_expr; }
1030 : :
1031 : 2 : ExprType get_expression_type () const override final
1032 : : {
1033 : 2 : return ExprType::TupleIdx;
1034 : : }
1035 : :
1036 : : protected:
1037 : : /* Use covariance to implement clone function as returning this object rather
1038 : : * than base */
1039 : 0 : TupleIndexExpr *clone_expr_impl () const override
1040 : : {
1041 : 0 : return new TupleIndexExpr (*this);
1042 : : }
1043 : :
1044 : : /* Use covariance to implement clone function as returning this object rather
1045 : : * than base */
1046 : 0 : TupleIndexExpr *clone_expr_without_block_impl () const override
1047 : : {
1048 : 0 : return new TupleIndexExpr (*this);
1049 : : }
1050 : : };
1051 : :
1052 : : // Base struct/tuple/union value creator HIR node (abstract)
1053 : : class StructExpr : public ExprWithoutBlock
1054 : : {
1055 : : protected:
1056 : : PathInExpression struct_name;
1057 : :
1058 : : // Protected constructor to allow initialising struct_name
1059 : : StructExpr (Analysis::NodeMapping mappings, PathInExpression struct_path,
1060 : : AST::AttrVec outer_attribs);
1061 : :
1062 : : public:
1063 : 1604 : PathInExpression &get_struct_name () { return struct_name; }
1064 : :
1065 : : std::string to_string () const override;
1066 : :
1067 : 3 : ExprType get_expression_type () const override final
1068 : : {
1069 : 3 : return ExprType::Struct;
1070 : : }
1071 : : };
1072 : :
1073 : : // Actual HIR node of the struct creator (with no fields). Not abstract!
1074 : : class StructExprStruct : public StructExpr, public WithInnerAttrs
1075 : : {
1076 : : location_t locus;
1077 : :
1078 : : public:
1079 : : std::string to_string () const override;
1080 : :
1081 : : // Constructor has to call protected constructor of base class
1082 : : StructExprStruct (Analysis::NodeMapping mappings,
1083 : : PathInExpression struct_path, AST::AttrVec inner_attribs,
1084 : : AST::AttrVec outer_attribs, location_t locus);
1085 : :
1086 : 5001 : location_t get_locus () const override final { return locus; }
1087 : :
1088 : : void accept_vis (HIRFullVisitor &vis) override;
1089 : : void accept_vis (HIRExpressionVisitor &vis) override;
1090 : :
1091 : : protected:
1092 : : /* Use covariance to implement clone function as returning this object rather
1093 : : * than base */
1094 : 0 : StructExprStruct *clone_expr_impl () const override
1095 : : {
1096 : 0 : return new StructExprStruct (*this);
1097 : : }
1098 : :
1099 : : /* Use covariance to implement clone function as returning this object rather
1100 : : * than base */
1101 : 0 : StructExprStruct *clone_expr_without_block_impl () const override
1102 : : {
1103 : 0 : return new StructExprStruct (*this);
1104 : : }
1105 : : };
1106 : :
1107 : : /* HIR node representing expression used to fill a struct's fields from another
1108 : : * struct */
1109 : : struct StructBase
1110 : : {
1111 : : private:
1112 : : std::unique_ptr<Expr> base_struct;
1113 : :
1114 : : public:
1115 : : // TODO: should this store location data?
1116 : : StructBase (std::unique_ptr<Expr> base_struct_ptr);
1117 : :
1118 : : // Copy constructor requires clone
1119 : : StructBase (StructBase const &other);
1120 : :
1121 : : // Destructor
1122 : 0 : ~StructBase () = default;
1123 : :
1124 : : // Overload assignment operator to clone base_struct
1125 : : StructBase &operator= (StructBase const &other);
1126 : :
1127 : : // move constructors
1128 : 0 : StructBase (StructBase &&other) = default;
1129 : : StructBase &operator= (StructBase &&other) = default;
1130 : :
1131 : : // Returns a null expr-ed StructBase - error state
1132 : : static StructBase error () { return StructBase (nullptr); }
1133 : :
1134 : : // Returns whether StructBase is in error state
1135 : : bool is_invalid () const { return base_struct == nullptr; }
1136 : :
1137 : : std::string to_string () const;
1138 : :
1139 : 2716 : Expr &get_base () { return *base_struct; }
1140 : : };
1141 : :
1142 : : /* Base HIR node for a single struct expression field (in struct instance
1143 : : * creation) - abstract */
1144 : 0 : class StructExprField : public FullVisitable
1145 : : {
1146 : : public:
1147 : : enum StructExprFieldKind
1148 : : {
1149 : : IDENTIFIER_VALUE,
1150 : : IDENTIFIER,
1151 : : INDEX_VALUE,
1152 : : };
1153 : :
1154 : : virtual ~StructExprField () {}
1155 : :
1156 : : // Unique pointer custom clone function
1157 : 0 : std::unique_ptr<StructExprField> clone_struct_expr_field () const
1158 : : {
1159 : 0 : return std::unique_ptr<StructExprField> (clone_struct_expr_field_impl ());
1160 : : }
1161 : :
1162 : : virtual std::string to_string () const = 0;
1163 : :
1164 : : virtual void accept_vis (HIRFullVisitor &vis) = 0;
1165 : : virtual void accept_vis (HIRExpressionVisitor &vis) = 0;
1166 : :
1167 : 14228 : Analysis::NodeMapping &get_mappings () { return mappings; }
1168 : :
1169 : 5972 : location_t get_locus () { return locus; }
1170 : :
1171 : : virtual StructExprFieldKind get_kind () const = 0;
1172 : :
1173 : : protected:
1174 : : // pure virtual clone implementation
1175 : : virtual StructExprField *clone_struct_expr_field_impl () const = 0;
1176 : :
1177 : : StructExprField (Analysis::NodeMapping mapping, location_t locus);
1178 : :
1179 : : Analysis::NodeMapping mappings;
1180 : : location_t locus;
1181 : : };
1182 : :
1183 : : // Identifier-only variant of StructExprField HIR node
1184 : 0 : class StructExprFieldIdentifier : public StructExprField
1185 : : {
1186 : : private:
1187 : : Identifier field_name;
1188 : :
1189 : : // TODO: should this store location data?
1190 : : public:
1191 : : StructExprFieldIdentifier (Analysis::NodeMapping mapping,
1192 : : Identifier field_identifier, location_t locus);
1193 : :
1194 : 0 : std::string to_string () const override { return field_name.as_string (); }
1195 : :
1196 : : void accept_vis (HIRFullVisitor &vis) override;
1197 : : void accept_vis (HIRExpressionVisitor &vis) override;
1198 : :
1199 : 845 : Identifier get_field_name () const { return field_name; }
1200 : :
1201 : 413 : StructExprFieldKind get_kind () const override
1202 : : {
1203 : 413 : return StructExprFieldKind::IDENTIFIER;
1204 : : }
1205 : :
1206 : : protected:
1207 : : /* Use covariance to implement clone function as returning this object rather
1208 : : * than base */
1209 : 0 : StructExprFieldIdentifier *clone_struct_expr_field_impl () const override
1210 : : {
1211 : 0 : return new StructExprFieldIdentifier (*this);
1212 : : }
1213 : : };
1214 : :
1215 : : /* Base HIR node for a single struct expression field with an assigned value -
1216 : : * abstract */
1217 : : class StructExprFieldWithVal : public StructExprField
1218 : : {
1219 : : std::unique_ptr<Expr> value;
1220 : :
1221 : : protected:
1222 : : StructExprFieldWithVal (Analysis::NodeMapping mapping,
1223 : : std::unique_ptr<Expr> field_value, location_t locus);
1224 : :
1225 : : // Copy constructor requires clone
1226 : : StructExprFieldWithVal (StructExprFieldWithVal const &other);
1227 : :
1228 : : // Overload assignment operator to clone unique_ptr
1229 : : StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other);
1230 : :
1231 : : // move constructors
1232 : : StructExprFieldWithVal (StructExprFieldWithVal &&other) = default;
1233 : : StructExprFieldWithVal &operator= (StructExprFieldWithVal &&other) = default;
1234 : :
1235 : : public:
1236 : : std::string to_string () const override;
1237 : :
1238 : 18156 : Expr &get_value () { return *value; }
1239 : : };
1240 : :
1241 : : // Identifier and value variant of StructExprField HIR node
1242 : : class StructExprFieldIdentifierValue : public StructExprFieldWithVal
1243 : : {
1244 : : public:
1245 : : Identifier field_name;
1246 : :
1247 : : // TODO: should this store location data?
1248 : :
1249 : : StructExprFieldIdentifierValue (Analysis::NodeMapping mapping,
1250 : : Identifier field_identifier,
1251 : : std::unique_ptr<Expr> field_value,
1252 : : location_t locus);
1253 : :
1254 : : std::string to_string () const override;
1255 : :
1256 : : void accept_vis (HIRFullVisitor &vis) override;
1257 : : void accept_vis (HIRExpressionVisitor &vis) override;
1258 : :
1259 : 4 : Identifier get_field_name () const { return field_name; }
1260 : :
1261 : 4643 : StructExprFieldKind get_kind () const override
1262 : : {
1263 : 4643 : return StructExprFieldKind::IDENTIFIER_VALUE;
1264 : : }
1265 : :
1266 : : protected:
1267 : : /* Use covariance to implement clone function as returning this object rather
1268 : : * than base */
1269 : 0 : StructExprFieldIdentifierValue *clone_struct_expr_field_impl () const override
1270 : : {
1271 : 0 : return new StructExprFieldIdentifierValue (*this);
1272 : : }
1273 : : };
1274 : :
1275 : : // Tuple index and value variant of StructExprField HIR node
1276 : 0 : class StructExprFieldIndexValue : public StructExprFieldWithVal
1277 : : {
1278 : : public:
1279 : : TupleIndex index;
1280 : :
1281 : : // TODO: should this store location data?
1282 : :
1283 : : StructExprFieldIndexValue (Analysis::NodeMapping mapping,
1284 : : TupleIndex tuple_index,
1285 : : std::unique_ptr<Expr> field_value,
1286 : : location_t locus);
1287 : :
1288 : : std::string to_string () const override;
1289 : :
1290 : 44 : TupleIndex get_tuple_index () const { return index; };
1291 : :
1292 : : void accept_vis (HIRFullVisitor &vis) override;
1293 : : void accept_vis (HIRExpressionVisitor &vis) override;
1294 : :
1295 : 86 : StructExprFieldKind get_kind () const override
1296 : : {
1297 : 86 : return StructExprFieldKind::INDEX_VALUE;
1298 : : }
1299 : :
1300 : : protected:
1301 : : /* Use covariance to implement clone function as returning this object rather
1302 : : * than base */
1303 : 0 : StructExprFieldIndexValue *clone_struct_expr_field_impl () const override
1304 : : {
1305 : 0 : return new StructExprFieldIndexValue (*this);
1306 : : }
1307 : : };
1308 : :
1309 : : // HIR node of a struct creator with fields
1310 : : class StructExprStructFields : public StructExprStruct
1311 : : {
1312 : : // std::vector<StructExprField> fields;
1313 : : std::vector<std::unique_ptr<StructExprField>> fields;
1314 : : tl::optional<std::unique_ptr<StructBase>> struct_base;
1315 : :
1316 : : public:
1317 : : // For unions there is just one field, the index
1318 : : // is set when type checking
1319 : : int union_index = -1;
1320 : :
1321 : : std::string to_string () const override;
1322 : :
1323 : 2966 : bool has_struct_base () const { return struct_base.has_value (); }
1324 : :
1325 : : // Constructor for StructExprStructFields when no struct base is used
1326 : : StructExprStructFields (
1327 : : Analysis::NodeMapping mappings, PathInExpression struct_path,
1328 : : std::vector<std::unique_ptr<StructExprField>> expr_fields, location_t locus,
1329 : : tl::optional<std::unique_ptr<StructBase>> base_struct,
1330 : : AST::AttrVec inner_attribs, AST::AttrVec outer_attribs);
1331 : :
1332 : : // copy constructor with vector clone
1333 : : StructExprStructFields (StructExprStructFields const &other);
1334 : :
1335 : : // overloaded assignment operator with vector clone
1336 : : StructExprStructFields &operator= (StructExprStructFields const &other);
1337 : :
1338 : : // move constructors
1339 : : StructExprStructFields (StructExprStructFields &&other) = default;
1340 : : StructExprStructFields &operator= (StructExprStructFields &&other) = default;
1341 : :
1342 : : void accept_vis (HIRFullVisitor &vis) override;
1343 : : void accept_vis (HIRExpressionVisitor &vis) override;
1344 : :
1345 : 3476 : std::vector<std::unique_ptr<StructExprField>> &get_fields ()
1346 : : {
1347 : 12578 : return fields;
1348 : : };
1349 : :
1350 : : const std::vector<std::unique_ptr<StructExprField>> &get_fields () const
1351 : : {
1352 : : return fields;
1353 : : };
1354 : :
1355 : 2653 : StructBase &get_struct_base () { return *struct_base.value (); }
1356 : :
1357 : : void
1358 : 1159 : set_fields_as_owner (std::vector<std::unique_ptr<StructExprField>> new_fields)
1359 : : {
1360 : 1159 : fields = std::move (new_fields);
1361 : : }
1362 : :
1363 : : protected:
1364 : : /* Use covariance to implement clone function as returning this object rather
1365 : : * than base */
1366 : 0 : StructExprStructFields *clone_expr_impl () const override
1367 : : {
1368 : 0 : return new StructExprStructFields (*this);
1369 : : }
1370 : :
1371 : : /* Use covariance to implement clone function as returning this object rather
1372 : : * than base */
1373 : 0 : StructExprStructFields *clone_expr_without_block_impl () const override
1374 : : {
1375 : 0 : return new StructExprStructFields (*this);
1376 : : }
1377 : : };
1378 : :
1379 : : // HIR node of the functional update struct creator
1380 : : class StructExprStructBase : public StructExprStruct
1381 : : {
1382 : : StructBase struct_base;
1383 : :
1384 : : public:
1385 : : StructExprStructBase (Analysis::NodeMapping mappings,
1386 : : PathInExpression struct_path, StructBase base_struct,
1387 : : AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
1388 : : location_t locus);
1389 : :
1390 : : void accept_vis (HIRFullVisitor &vis) override;
1391 : : void accept_vis (HIRExpressionVisitor &vis) override;
1392 : :
1393 : 0 : StructBase &get_struct_base () { return struct_base; }
1394 : :
1395 : : protected:
1396 : : /* Use covariance to implement clone function as returning this object rather
1397 : : * than base */
1398 : 0 : StructExprStructBase *clone_expr_impl () const override
1399 : : {
1400 : 0 : return new StructExprStructBase (*this);
1401 : : }
1402 : :
1403 : : /* Use covariance to implement clone function as returning this object rather
1404 : : * than base */
1405 : 0 : StructExprStructBase *clone_expr_without_block_impl () const override
1406 : : {
1407 : 0 : return new StructExprStructBase (*this);
1408 : : }
1409 : : };
1410 : :
1411 : : // Function call expression HIR node
1412 : : class CallExpr : public ExprWithoutBlock
1413 : : {
1414 : : std::unique_ptr<Expr> function;
1415 : : std::vector<std::unique_ptr<Expr>> params;
1416 : : location_t locus;
1417 : :
1418 : : public:
1419 : : std::string to_string () const override;
1420 : :
1421 : : CallExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> function_expr,
1422 : : std::vector<std::unique_ptr<Expr>> function_params,
1423 : : AST::AttrVec outer_attribs, location_t locus);
1424 : :
1425 : : // copy constructor requires clone
1426 : : CallExpr (CallExpr const &other);
1427 : :
1428 : : // Overload assignment operator to clone
1429 : : CallExpr &operator= (CallExpr const &other);
1430 : :
1431 : : // move constructors
1432 : : CallExpr (CallExpr &&other) = default;
1433 : : CallExpr &operator= (CallExpr &&other) = default;
1434 : :
1435 : : // Returns whether function call has parameters.
1436 : 21137 : bool has_params () const { return !params.empty (); }
1437 : :
1438 : 76110 : location_t get_locus () const override final { return locus; }
1439 : :
1440 : : void accept_vis (HIRFullVisitor &vis) override;
1441 : : void accept_vis (HIRExpressionVisitor &vis) override;
1442 : :
1443 : 32058 : bool has_fnexpr () const { return function != nullptr; }
1444 : 94294 : Expr &get_fnexpr () { return *function; }
1445 : :
1446 : 26565 : size_t num_params () const { return params.size (); }
1447 : :
1448 : 55114 : std::vector<std::unique_ptr<Expr>> &get_arguments () { return params; }
1449 : :
1450 : : const std::vector<std::unique_ptr<Expr>> &get_arguments () const
1451 : : {
1452 : : return params;
1453 : : }
1454 : :
1455 : 36 : ExprType get_expression_type () const override final
1456 : : {
1457 : 36 : return ExprType::Call;
1458 : : }
1459 : :
1460 : : protected:
1461 : : /* Use covariance to implement clone function as returning this object rather
1462 : : * than base */
1463 : 8 : CallExpr *clone_expr_impl () const override { return new CallExpr (*this); }
1464 : :
1465 : : /* Use covariance to implement clone function as returning this object rather
1466 : : * than base */
1467 : 0 : CallExpr *clone_expr_without_block_impl () const override
1468 : : {
1469 : 0 : return new CallExpr (*this);
1470 : : }
1471 : : };
1472 : :
1473 : : // Method call expression HIR node
1474 : : class MethodCallExpr : public ExprWithoutBlock
1475 : : {
1476 : : std::unique_ptr<Expr> receiver;
1477 : : PathExprSegment method_name;
1478 : : std::vector<std::unique_ptr<Expr>> params;
1479 : : location_t locus;
1480 : :
1481 : : public:
1482 : : std::string to_string () const override;
1483 : :
1484 : : MethodCallExpr (Analysis::NodeMapping mappings,
1485 : : std::unique_ptr<Expr> call_receiver,
1486 : : PathExprSegment method_path,
1487 : : std::vector<std::unique_ptr<Expr>> method_params,
1488 : : AST::AttrVec outer_attribs, location_t locus);
1489 : :
1490 : : // copy constructor required due to cloning
1491 : : MethodCallExpr (MethodCallExpr const &other);
1492 : :
1493 : : // Overload assignment operator to clone receiver object
1494 : : MethodCallExpr &operator= (MethodCallExpr const &other);
1495 : :
1496 : : // move constructors
1497 : : MethodCallExpr (MethodCallExpr &&other) = default;
1498 : : MethodCallExpr &operator= (MethodCallExpr &&other) = default;
1499 : :
1500 : 25101 : location_t get_locus () const override final { return locus; }
1501 : :
1502 : : void accept_vis (HIRFullVisitor &vis) override;
1503 : : void accept_vis (HIRExpressionVisitor &vis) override;
1504 : :
1505 : 32931 : Expr &get_receiver () { return *receiver; }
1506 : :
1507 : 2857 : PathExprSegment &get_method_name () { return method_name; };
1508 : : const PathExprSegment &get_method_name () const { return method_name; };
1509 : :
1510 : : bool has_params () const { return !params.empty (); }
1511 : : size_t num_params () const { return params.size (); }
1512 : :
1513 : 18625 : std::vector<std::unique_ptr<Expr>> &get_arguments () { return params; }
1514 : :
1515 : : const std::vector<std::unique_ptr<Expr>> &get_arguments () const
1516 : : {
1517 : : return params;
1518 : : }
1519 : :
1520 : 0 : ExprType get_expression_type () const override final
1521 : : {
1522 : 0 : return ExprType::MethodCall;
1523 : : }
1524 : :
1525 : : protected:
1526 : : /* Use covariance to implement clone function as returning this object rather
1527 : : * than base */
1528 : 0 : MethodCallExpr *clone_expr_impl () const override
1529 : : {
1530 : 0 : return new MethodCallExpr (*this);
1531 : : }
1532 : :
1533 : : /* Use covariance to implement clone function as returning this object rather
1534 : : * than base */
1535 : 0 : MethodCallExpr *clone_expr_without_block_impl () const override
1536 : : {
1537 : 0 : return new MethodCallExpr (*this);
1538 : : }
1539 : : };
1540 : :
1541 : : // aka FieldExpression
1542 : : // Struct or union field access expression HIR node
1543 : : class FieldAccessExpr : public ExprWithoutBlock
1544 : : {
1545 : : std::unique_ptr<Expr> receiver;
1546 : : Identifier field;
1547 : :
1548 : : location_t locus;
1549 : :
1550 : : public:
1551 : : std::string to_string () const override;
1552 : :
1553 : : FieldAccessExpr (Analysis::NodeMapping mappings,
1554 : : std::unique_ptr<Expr> field_access_receiver,
1555 : : Identifier field_name, AST::AttrVec outer_attribs,
1556 : : location_t locus);
1557 : :
1558 : : // Copy constructor required due to unique_ptr cloning
1559 : : FieldAccessExpr (FieldAccessExpr const &other);
1560 : :
1561 : : // Overload assignment operator to clone unique_ptr
1562 : : FieldAccessExpr &operator= (FieldAccessExpr const &other);
1563 : :
1564 : : // move constructors
1565 : : FieldAccessExpr (FieldAccessExpr &&other) = default;
1566 : : FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
1567 : :
1568 : 16889 : location_t get_locus () const override final { return locus; }
1569 : :
1570 : : void accept_vis (HIRFullVisitor &vis) override;
1571 : : void accept_vis (HIRExpressionVisitor &vis) override;
1572 : :
1573 : 41613 : Expr &get_receiver_expr () { return *receiver; }
1574 : :
1575 : 13907 : Identifier get_field_name () const { return field; }
1576 : :
1577 : 0 : ExprType get_expression_type () const override final
1578 : : {
1579 : 0 : return ExprType::FieldAccess;
1580 : : }
1581 : :
1582 : : protected:
1583 : : /* Use covariance to implement clone function as returning this object rather
1584 : : * than base */
1585 : 0 : FieldAccessExpr *clone_expr_impl () const override
1586 : : {
1587 : 0 : return new FieldAccessExpr (*this);
1588 : : }
1589 : :
1590 : : /* Use covariance to implement clone function as returning this object rather
1591 : : * than base */
1592 : 0 : FieldAccessExpr *clone_expr_without_block_impl () const override
1593 : : {
1594 : 0 : return new FieldAccessExpr (*this);
1595 : : }
1596 : : };
1597 : :
1598 : : // Closure parameter data structure
1599 : : struct ClosureParam
1600 : : {
1601 : : private:
1602 : : std::vector<AST::Attribute> outer_attrs;
1603 : : std::unique_ptr<Pattern> pattern;
1604 : : std::unique_ptr<Type> type;
1605 : : location_t locus;
1606 : :
1607 : : public:
1608 : : // Returns whether the type of the parameter has been given.
1609 : 60 : bool has_type_given () const { return type != nullptr; }
1610 : :
1611 : : // Constructor for closure parameter
1612 : : ClosureParam (std::unique_ptr<Pattern> param_pattern, location_t locus,
1613 : : std::unique_ptr<Type> param_type = nullptr,
1614 : : std::vector<AST::Attribute> outer_attrs = {});
1615 : :
1616 : : // Copy constructor required due to cloning as a result of unique_ptrs
1617 : : ClosureParam (ClosureParam const &other);
1618 : :
1619 : 61 : ~ClosureParam () = default;
1620 : :
1621 : : // Assignment operator must be overloaded to clone as well
1622 : : ClosureParam &operator= (ClosureParam const &other);
1623 : :
1624 : : // move constructors
1625 : 61 : ClosureParam (ClosureParam &&other) = default;
1626 : : ClosureParam &operator= (ClosureParam &&other) = default;
1627 : :
1628 : : std::string to_string () const;
1629 : :
1630 : : const std::vector<AST::Attribute> &get_outer_attrs () const
1631 : : {
1632 : : return outer_attrs;
1633 : : }
1634 : 0 : std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
1635 : :
1636 : 121 : Pattern &get_pattern () { return *pattern; }
1637 : :
1638 : 58 : Type &get_type () { return *type; }
1639 : :
1640 : 59 : location_t get_locus () const { return locus; }
1641 : : };
1642 : :
1643 : : // Base closure definition expression HIR node - abstract
1644 : : class ClosureExpr : public ExprWithoutBlock
1645 : : {
1646 : : private:
1647 : : bool has_move;
1648 : : std::vector<ClosureParam> params;
1649 : : location_t locus;
1650 : : std::unique_ptr<Type> return_type;
1651 : : std::unique_ptr<Expr> expr;
1652 : :
1653 : : public:
1654 : : ClosureExpr (Analysis::NodeMapping mappings,
1655 : : std::vector<ClosureParam> closure_params,
1656 : : std::unique_ptr<Type> closure_return_type,
1657 : : std::unique_ptr<Expr> closure_expr, bool has_move,
1658 : : AST::AttrVec outer_attribs, location_t locus);
1659 : :
1660 : : // Copy constructor requires cloning
1661 : : ClosureExpr (ClosureExpr const &other);
1662 : :
1663 : : // Overload assignment operator to clone unique_ptrs
1664 : : ClosureExpr &operator= (ClosureExpr const &other);
1665 : :
1666 : : // move constructors
1667 : : ClosureExpr (ClosureExpr &&other) = default;
1668 : : ClosureExpr &operator= (ClosureExpr &&other) = default;
1669 : :
1670 : : std::string to_string () const override;
1671 : :
1672 : 1121 : location_t get_locus () const override final { return locus; }
1673 : :
1674 : 1 : ExprType get_expression_type () const override final
1675 : : {
1676 : 1 : return ExprType::Closure;
1677 : : }
1678 : :
1679 : : bool get_has_move () const { return has_move; }
1680 : :
1681 : 137 : bool has_return_type () const { return return_type != nullptr; }
1682 : :
1683 : 0 : Type &get_return_type () { return *return_type; };
1684 : 358 : Expr &get_expr () { return *expr; }
1685 : :
1686 : 0 : bool has_params () const { return !params.empty (); }
1687 : 133 : std::vector<ClosureParam> &get_params () { return params; }
1688 : :
1689 : : void accept_vis (HIRFullVisitor &vis) override;
1690 : : void accept_vis (HIRExpressionVisitor &vis) override;
1691 : :
1692 : : protected:
1693 : : /* Use covariance to implement clone function as returning this object rather
1694 : : * than base */
1695 : 0 : ClosureExpr *clone_expr_impl () const override
1696 : : {
1697 : 0 : return new ClosureExpr (*this);
1698 : : }
1699 : :
1700 : : /* Use covariance to implement clone function as returning this object rather
1701 : : * than base */
1702 : 0 : ClosureExpr *clone_expr_without_block_impl () const override
1703 : : {
1704 : 0 : return new ClosureExpr (*this);
1705 : : }
1706 : : };
1707 : :
1708 : : // A block HIR node
1709 : : class BlockExpr : public ExprWithBlock, public WithInnerAttrs
1710 : : {
1711 : : // FIXME this should be private + get/set
1712 : : public:
1713 : : std::vector<std::unique_ptr<Stmt>> statements;
1714 : : std::unique_ptr<Expr> expr;
1715 : : bool tail_reachable;
1716 : : tl::optional<LoopLabel> label;
1717 : : location_t start_locus;
1718 : : location_t end_locus;
1719 : :
1720 : : std::string to_string () const override;
1721 : :
1722 : 20382 : AST::AttrVec get_inner_attrs () const { return inner_attrs; }
1723 : :
1724 : : // Returns whether the block contains statements.
1725 : : bool has_statements () const { return !statements.empty (); }
1726 : :
1727 : : // Returns whether the block contains an expression
1728 : 147130 : bool has_expr () const { return expr != nullptr; }
1729 : :
1730 : 5893 : bool is_tail_reachable () const { return tail_reachable; }
1731 : :
1732 : : BlockExpr (Analysis::NodeMapping mappings,
1733 : : std::vector<std::unique_ptr<Stmt>> block_statements,
1734 : : std::unique_ptr<Expr> block_expr, bool tail_reachable,
1735 : : AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
1736 : : tl::optional<LoopLabel> label, location_t start_locus,
1737 : : location_t end_locus);
1738 : :
1739 : : // Copy constructor with clone
1740 : : BlockExpr (BlockExpr const &other);
1741 : :
1742 : : // Overloaded assignment operator to clone pointer
1743 : : BlockExpr &operator= (BlockExpr const &other);
1744 : :
1745 : : // move constructors
1746 : : BlockExpr (BlockExpr &&other) = default;
1747 : : BlockExpr &operator= (BlockExpr &&other) = default;
1748 : :
1749 : : // Unique pointer custom clone function
1750 : 0 : std::unique_ptr<BlockExpr> clone_block_expr () const
1751 : : {
1752 : 0 : return std::unique_ptr<BlockExpr> (clone_block_expr_impl ());
1753 : : }
1754 : :
1755 : 92206 : location_t get_locus () const override final { return start_locus; }
1756 : :
1757 : 0 : location_t get_start_locus () const { return start_locus; }
1758 : :
1759 : 20014 : location_t get_end_locus () const { return end_locus; }
1760 : :
1761 : : void accept_vis (HIRFullVisitor &vis) override;
1762 : : void accept_vis (HIRExpressionVisitor &vis) override;
1763 : :
1764 : : bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
1765 : :
1766 : 19222 : bool has_final_expr () { return expr != nullptr; }
1767 : 123110 : Expr &get_final_expr () { return *expr; }
1768 : :
1769 : 188125 : std::vector<std::unique_ptr<Stmt>> &get_statements () { return statements; }
1770 : :
1771 : 91 : ExprType get_expression_type () const final override
1772 : : {
1773 : 91 : return ExprType::Block;
1774 : : }
1775 : :
1776 : 26983 : bool has_label () const { return label.has_value (); }
1777 : 0 : LoopLabel &get_label () { return label.value (); }
1778 : :
1779 : : protected:
1780 : : /* Use covariance to implement clone function as returning this object rather
1781 : : * than base */
1782 : 37 : BlockExpr *clone_expr_impl () const override
1783 : : {
1784 : 37 : return clone_block_expr_impl ();
1785 : : }
1786 : :
1787 : : /* Use covariance to implement clone function as returning this object rather
1788 : : * than base */
1789 : 0 : BlockExpr *clone_expr_with_block_impl () const override
1790 : : {
1791 : 0 : return clone_block_expr_impl ();
1792 : : }
1793 : :
1794 : : /* This is the base method as not an abstract class - not virtual but could be
1795 : : * in future if required. */
1796 : 37 : /*virtual*/ BlockExpr *clone_block_expr_impl () const
1797 : : {
1798 : 37 : return new BlockExpr (*this);
1799 : : }
1800 : : };
1801 : :
1802 : : class AnonConst : public ExprWithBlock
1803 : : {
1804 : : public:
1805 : : enum class Kind
1806 : : {
1807 : : Explicit,
1808 : : DeferredInference
1809 : : };
1810 : :
1811 : : AnonConst (Analysis::NodeMapping mappings, std::unique_ptr<Expr> &&expr,
1812 : : location_t locus = UNKNOWN_LOCATION);
1813 : : AnonConst (Analysis::NodeMapping mappings,
1814 : : location_t locus = UNKNOWN_LOCATION);
1815 : : AnonConst (const AnonConst &other);
1816 : : AnonConst operator= (const AnonConst &other);
1817 : :
1818 : : std::string to_string () const override;
1819 : :
1820 : : void accept_vis (HIRFullVisitor &vis) override;
1821 : : void accept_vis (HIRExpressionVisitor &vis) override;
1822 : :
1823 : 641 : ExprType get_expression_type () const final override
1824 : : {
1825 : 641 : return ExprType::AnonConst;
1826 : : }
1827 : :
1828 : 4518 : location_t get_locus () const override { return locus; }
1829 : :
1830 : 2208 : Expr &get_inner_expr ()
1831 : : {
1832 : 2208 : rust_assert (kind == Kind::Explicit);
1833 : 2208 : return *expr.value ();
1834 : : }
1835 : :
1836 : 0 : const Expr &get_inner_expr () const
1837 : : {
1838 : 0 : rust_assert (kind == Kind::Explicit);
1839 : 0 : return *expr.value ();
1840 : : }
1841 : :
1842 : 1155 : bool is_deferred () const { return kind == Kind::DeferredInference; }
1843 : :
1844 : : private:
1845 : : location_t locus;
1846 : : Kind kind;
1847 : : tl::optional<std::unique_ptr<Expr>> expr;
1848 : :
1849 : 7 : AnonConst *clone_expr_with_block_impl () const override
1850 : : {
1851 : 7 : return new AnonConst (*this);
1852 : : }
1853 : : };
1854 : :
1855 : : class ConstBlock : public ExprWithBlock
1856 : : {
1857 : : public:
1858 : : ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr,
1859 : : location_t locus = UNKNOWN_LOCATION,
1860 : : AST::AttrVec outer_attrs = {});
1861 : : ConstBlock (const ConstBlock &other);
1862 : : ConstBlock operator= (const ConstBlock &other);
1863 : :
1864 : : void accept_vis (HIRFullVisitor &vis) override;
1865 : : void accept_vis (HIRExpressionVisitor &vis) override;
1866 : :
1867 : : std::string to_string () const override;
1868 : :
1869 : 8 : ExprType get_expression_type () const final override
1870 : : {
1871 : 8 : return ExprType::ConstBlock;
1872 : : }
1873 : :
1874 : 76 : location_t get_locus () const override { return locus; }
1875 : 82 : AnonConst &get_const_expr () { return expr; }
1876 : 0 : const AnonConst &get_const_expr () const { return expr; }
1877 : :
1878 : : private:
1879 : : AnonConst expr;
1880 : : location_t locus;
1881 : :
1882 : 0 : ConstBlock *clone_expr_with_block_impl () const override
1883 : : {
1884 : 0 : return new ConstBlock (*this);
1885 : : }
1886 : : };
1887 : :
1888 : : // HIR node representing continue expression within loops
1889 : : class ContinueExpr : public ExprWithoutBlock
1890 : : {
1891 : : tl::optional<Lifetime> label;
1892 : : location_t locus;
1893 : :
1894 : : public:
1895 : : std::string to_string () const override;
1896 : :
1897 : : // Returns true if the continue expr has a label.
1898 : 24 : bool has_label () const { return label.has_value (); }
1899 : :
1900 : : // Constructor for a ContinueExpr with a label.
1901 : : ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
1902 : : tl::optional<Lifetime> label,
1903 : : AST::AttrVec outer_attribs = AST::AttrVec ());
1904 : :
1905 : 33 : location_t get_locus () const override final { return locus; }
1906 : :
1907 : : void accept_vis (HIRFullVisitor &vis) override;
1908 : : void accept_vis (HIRExpressionVisitor &vis) override;
1909 : :
1910 : 7 : Lifetime &get_label () { return label.value (); }
1911 : 0 : const Lifetime &get_label () const { return label.value (); }
1912 : :
1913 : 0 : ExprType get_expression_type () const final override
1914 : : {
1915 : 0 : return ExprType::Continue;
1916 : : }
1917 : :
1918 : : protected:
1919 : : /* Use covariance to implement clone function as returning this object rather
1920 : : * than base */
1921 : 0 : ContinueExpr *clone_expr_impl () const override
1922 : : {
1923 : 0 : return new ContinueExpr (*this);
1924 : : }
1925 : :
1926 : : /* Use covariance to implement clone function as returning this object rather
1927 : : * than base */
1928 : 0 : ContinueExpr *clone_expr_without_block_impl () const override
1929 : : {
1930 : 0 : return new ContinueExpr (*this);
1931 : : }
1932 : : };
1933 : :
1934 : : // HIR node representing break expression within loops
1935 : : class BreakExpr : public ExprWithoutBlock
1936 : : {
1937 : : // bool has_label;
1938 : : tl::optional<Lifetime> label;
1939 : :
1940 : : // bool has_break_expr;
1941 : : std::unique_ptr<Expr> break_expr;
1942 : :
1943 : : location_t locus;
1944 : :
1945 : : public:
1946 : : std::string to_string () const override;
1947 : :
1948 : : // Returns whether the break expression has a label or not.
1949 : 135 : bool has_label () const { return label.has_value (); }
1950 : :
1951 : : /* Returns whether the break expression has an expression used in the break or
1952 : : * not. */
1953 : 590 : bool has_break_expr () const { return break_expr != nullptr; }
1954 : :
1955 : : // Constructor for a break expression
1956 : : BreakExpr (Analysis::NodeMapping mappings, location_t locus,
1957 : : tl::optional<Lifetime> break_label,
1958 : : std::unique_ptr<Expr> expr_in_break = nullptr,
1959 : : AST::AttrVec outer_attribs = AST::AttrVec ());
1960 : :
1961 : : // Copy constructor defined to use clone for unique pointer
1962 : : BreakExpr (BreakExpr const &other);
1963 : :
1964 : : // Overload assignment operator to clone unique pointer
1965 : : BreakExpr &operator= (BreakExpr const &other);
1966 : :
1967 : : // move constructors
1968 : : BreakExpr (BreakExpr &&other) = default;
1969 : : BreakExpr &operator= (BreakExpr &&other) = default;
1970 : :
1971 : 205 : location_t get_locus () const override final { return locus; }
1972 : :
1973 : : void accept_vis (HIRFullVisitor &vis) override;
1974 : : void accept_vis (HIRExpressionVisitor &vis) override;
1975 : :
1976 : 38 : Lifetime &get_label () { return label.value (); }
1977 : 0 : const Lifetime &get_label () const { return label.value (); }
1978 : :
1979 : 140 : Expr &get_expr () { return *break_expr; }
1980 : :
1981 : 0 : ExprType get_expression_type () const override final
1982 : : {
1983 : 0 : return ExprType::Break;
1984 : : }
1985 : :
1986 : : protected:
1987 : : /* Use covariance to implement clone function as returning this object rather
1988 : : * than base */
1989 : 0 : BreakExpr *clone_expr_impl () const override { return new BreakExpr (*this); }
1990 : :
1991 : : /* Use covariance to implement clone function as returning this object rather
1992 : : * than base */
1993 : 0 : BreakExpr *clone_expr_without_block_impl () const override
1994 : : {
1995 : 0 : return new BreakExpr (*this);
1996 : : }
1997 : : };
1998 : :
1999 : : // Base range expression HIR node object - abstract
2000 : 0 : class RangeExpr : public ExprWithoutBlock
2001 : : {
2002 : : location_t locus;
2003 : :
2004 : : protected:
2005 : : // outer attributes not allowed before range expressions
2006 : : RangeExpr (Analysis::NodeMapping mappings, location_t locus);
2007 : :
2008 : : public:
2009 : 366 : location_t get_locus () const override final { return locus; }
2010 : :
2011 : 0 : ExprType get_expression_type () const override final
2012 : : {
2013 : 0 : return ExprType::Range;
2014 : : }
2015 : : };
2016 : :
2017 : : // Range from (inclusive) and to (exclusive) expression HIR node object
2018 : : // aka RangeExpr; constructs a std::ops::Range object
2019 : : class RangeFromToExpr : public RangeExpr
2020 : : {
2021 : : std::unique_ptr<Expr> from;
2022 : : std::unique_ptr<Expr> to;
2023 : :
2024 : : public:
2025 : : std::string to_string () const override;
2026 : :
2027 : : RangeFromToExpr (Analysis::NodeMapping mappings,
2028 : : std::unique_ptr<Expr> range_from,
2029 : : std::unique_ptr<Expr> range_to, location_t locus);
2030 : :
2031 : : // Copy constructor with cloning
2032 : : RangeFromToExpr (RangeFromToExpr const &other);
2033 : :
2034 : : // Overload assignment operator to clone unique pointers
2035 : : RangeFromToExpr &operator= (RangeFromToExpr const &other);
2036 : :
2037 : : // move constructors
2038 : : RangeFromToExpr (RangeFromToExpr &&other) = default;
2039 : : RangeFromToExpr &operator= (RangeFromToExpr &&other) = default;
2040 : :
2041 : : void accept_vis (HIRFullVisitor &vis) override;
2042 : : void accept_vis (HIRExpressionVisitor &vis) override;
2043 : :
2044 : 462 : Expr &get_from_expr () { return *from; }
2045 : 396 : Expr &get_to_expr () { return *to; }
2046 : :
2047 : : protected:
2048 : : /* Use covariance to implement clone function as returning this object rather
2049 : : * than base */
2050 : 0 : RangeFromToExpr *clone_expr_impl () const override
2051 : : {
2052 : 0 : return new RangeFromToExpr (*this);
2053 : : }
2054 : :
2055 : : /* Use covariance to implement clone function as returning this object rather
2056 : : * than base */
2057 : 0 : RangeFromToExpr *clone_expr_without_block_impl () const override
2058 : : {
2059 : 0 : return new RangeFromToExpr (*this);
2060 : : }
2061 : : };
2062 : :
2063 : : // Range from (inclusive) expression HIR node object
2064 : : // constructs a std::ops::RangeFrom object
2065 : : class RangeFromExpr : public RangeExpr
2066 : : {
2067 : : std::unique_ptr<Expr> from;
2068 : :
2069 : : public:
2070 : : std::string to_string () const override;
2071 : :
2072 : : RangeFromExpr (Analysis::NodeMapping mappings,
2073 : : std::unique_ptr<Expr> range_from, location_t locus);
2074 : :
2075 : : // Copy constructor with clone
2076 : : RangeFromExpr (RangeFromExpr const &other);
2077 : :
2078 : : // Overload assignment operator to clone unique_ptr
2079 : : RangeFromExpr &operator= (RangeFromExpr const &other);
2080 : :
2081 : : // move constructors
2082 : : RangeFromExpr (RangeFromExpr &&other) = default;
2083 : : RangeFromExpr &operator= (RangeFromExpr &&other) = default;
2084 : :
2085 : : void accept_vis (HIRFullVisitor &vis) override;
2086 : : void accept_vis (HIRExpressionVisitor &vis) override;
2087 : :
2088 : 42 : Expr &get_from_expr () { return *from; }
2089 : :
2090 : : protected:
2091 : : /* Use covariance to implement clone function as returning this object rather
2092 : : * than base */
2093 : 0 : RangeFromExpr *clone_expr_impl () const override
2094 : : {
2095 : 0 : return new RangeFromExpr (*this);
2096 : : }
2097 : :
2098 : : /* Use covariance to implement clone function as returning this object rather
2099 : : * than base */
2100 : 0 : RangeFromExpr *clone_expr_without_block_impl () const override
2101 : : {
2102 : 0 : return new RangeFromExpr (*this);
2103 : : }
2104 : : };
2105 : :
2106 : : // Range to (exclusive) expression HIR node object
2107 : : // constructs a std::ops::RangeTo object
2108 : : class RangeToExpr : public RangeExpr
2109 : : {
2110 : : std::unique_ptr<Expr> to;
2111 : :
2112 : : public:
2113 : : std::string to_string () const override;
2114 : :
2115 : : // outer attributes not allowed
2116 : : RangeToExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> range_to,
2117 : : location_t locus);
2118 : :
2119 : : // Copy constructor with clone
2120 : : RangeToExpr (RangeToExpr const &other);
2121 : :
2122 : : // Overload assignment operator to clone unique_ptr
2123 : : RangeToExpr &operator= (RangeToExpr const &other);
2124 : :
2125 : : // move constructors
2126 : : RangeToExpr (RangeToExpr &&other) = default;
2127 : : RangeToExpr &operator= (RangeToExpr &&other) = default;
2128 : :
2129 : : void accept_vis (HIRFullVisitor &vis) override;
2130 : : void accept_vis (HIRExpressionVisitor &vis) override;
2131 : :
2132 : 42 : Expr &get_to_expr () { return *to; }
2133 : :
2134 : : protected:
2135 : : /* Use covariance to implement clone function as returning this object rather
2136 : : * than base */
2137 : 0 : RangeToExpr *clone_expr_impl () const override
2138 : : {
2139 : 0 : return new RangeToExpr (*this);
2140 : : }
2141 : :
2142 : : /* Use covariance to implement clone function as returning this object rather
2143 : : * than base */
2144 : 0 : RangeToExpr *clone_expr_without_block_impl () const override
2145 : : {
2146 : 0 : return new RangeToExpr (*this);
2147 : : }
2148 : : };
2149 : :
2150 : : // Full range expression HIR node object
2151 : : // constructs a std::ops::RangeFull object
2152 : 0 : class RangeFullExpr : public RangeExpr
2153 : : {
2154 : : public:
2155 : : std::string to_string () const override;
2156 : :
2157 : : RangeFullExpr (Analysis::NodeMapping mappings, location_t locus);
2158 : : // outer attributes not allowed
2159 : :
2160 : : void accept_vis (HIRFullVisitor &vis) override;
2161 : : void accept_vis (HIRExpressionVisitor &vis) override;
2162 : :
2163 : : protected:
2164 : : /* Use covariance to implement clone function as returning this object rather
2165 : : * than base */
2166 : 0 : RangeFullExpr *clone_expr_impl () const override
2167 : : {
2168 : 0 : return new RangeFullExpr (*this);
2169 : : }
2170 : :
2171 : : /* Use covariance to implement clone function as returning this object rather
2172 : : * than base */
2173 : 0 : RangeFullExpr *clone_expr_without_block_impl () const override
2174 : : {
2175 : 0 : return new RangeFullExpr (*this);
2176 : : }
2177 : : };
2178 : :
2179 : : // Range from (inclusive) and to (inclusive) expression HIR node object
2180 : : // aka RangeInclusiveExpr; constructs a std::ops::RangeInclusive object
2181 : : class RangeFromToInclExpr : public RangeExpr
2182 : : {
2183 : : std::unique_ptr<Expr> from;
2184 : : std::unique_ptr<Expr> to;
2185 : :
2186 : : public:
2187 : : std::string to_string () const override;
2188 : :
2189 : : RangeFromToInclExpr (Analysis::NodeMapping mappings,
2190 : : std::unique_ptr<Expr> range_from,
2191 : : std::unique_ptr<Expr> range_to, location_t locus);
2192 : : // outer attributes not allowed
2193 : :
2194 : : // Copy constructor with clone
2195 : : RangeFromToInclExpr (RangeFromToInclExpr const &other);
2196 : :
2197 : : // Overload assignment operator to use clone
2198 : : RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other);
2199 : :
2200 : : // move constructors
2201 : : RangeFromToInclExpr (RangeFromToInclExpr &&other) = default;
2202 : : RangeFromToInclExpr &operator= (RangeFromToInclExpr &&other) = default;
2203 : :
2204 : : void accept_vis (HIRFullVisitor &vis) override;
2205 : : void accept_vis (HIRExpressionVisitor &vis) override;
2206 : :
2207 : 49 : Expr &get_from_expr () { return *from; }
2208 : 42 : Expr &get_to_expr () { return *to; }
2209 : :
2210 : : protected:
2211 : : /* Use covariance to implement clone function as returning this object rather
2212 : : * than base */
2213 : 0 : RangeFromToInclExpr *clone_expr_impl () const override
2214 : : {
2215 : 0 : return new RangeFromToInclExpr (*this);
2216 : : }
2217 : :
2218 : : /* Use covariance to implement clone function as returning this object rather
2219 : : * than base */
2220 : 0 : RangeFromToInclExpr *clone_expr_without_block_impl () const override
2221 : : {
2222 : 0 : return new RangeFromToInclExpr (*this);
2223 : : }
2224 : : };
2225 : :
2226 : : // Range to (inclusive) expression HIR node object
2227 : : // aka RangeToInclusiveExpr; constructs a std::ops::RangeToInclusive object
2228 : : class RangeToInclExpr : public RangeExpr
2229 : : {
2230 : : std::unique_ptr<Expr> to;
2231 : :
2232 : : public:
2233 : : std::string to_string () const override;
2234 : :
2235 : : RangeToInclExpr (Analysis::NodeMapping mappings,
2236 : : std::unique_ptr<Expr> range_to, location_t locus);
2237 : : // outer attributes not allowed
2238 : :
2239 : : // Copy constructor with clone
2240 : : RangeToInclExpr (RangeToInclExpr const &other);
2241 : :
2242 : : // Overload assignment operator to clone pointer
2243 : : RangeToInclExpr &operator= (RangeToInclExpr const &other);
2244 : :
2245 : : // move constructors
2246 : : RangeToInclExpr (RangeToInclExpr &&other) = default;
2247 : : RangeToInclExpr &operator= (RangeToInclExpr &&other) = default;
2248 : :
2249 : : void accept_vis (HIRFullVisitor &vis) override;
2250 : : void accept_vis (HIRExpressionVisitor &vis) override;
2251 : :
2252 : 0 : Expr &get_to_expr () { return *to; };
2253 : :
2254 : : protected:
2255 : : /* Use covariance to implement clone function as returning this object rather
2256 : : * than base */
2257 : 0 : RangeToInclExpr *clone_expr_impl () const override
2258 : : {
2259 : 0 : return new RangeToInclExpr (*this);
2260 : : }
2261 : :
2262 : : /* Use covariance to implement clone function as returning this object rather
2263 : : * than base */
2264 : 0 : RangeToInclExpr *clone_expr_without_block_impl () const override
2265 : : {
2266 : 0 : return new RangeToInclExpr (*this);
2267 : : }
2268 : : };
2269 : :
2270 : : // Return expression HIR node representation
2271 : : class ReturnExpr : public ExprWithoutBlock
2272 : : {
2273 : : public:
2274 : : std::unique_ptr<Expr> return_expr;
2275 : :
2276 : : location_t locus;
2277 : :
2278 : : std::string to_string () const override;
2279 : :
2280 : : /* Returns whether the object has an expression returned (i.e. not void return
2281 : : * type). */
2282 : 5162 : bool has_return_expr () const { return return_expr != nullptr; }
2283 : :
2284 : : // Constructor for ReturnExpr.
2285 : : ReturnExpr (Analysis::NodeMapping mappings, location_t locus,
2286 : : std::unique_ptr<Expr> returned_expr = nullptr,
2287 : : AST::AttrVec outer_attribs = AST::AttrVec ());
2288 : :
2289 : : // Copy constructor with clone
2290 : : ReturnExpr (ReturnExpr const &other);
2291 : :
2292 : : // Overloaded assignment operator to clone return_expr pointer
2293 : : ReturnExpr &operator= (ReturnExpr const &other);
2294 : :
2295 : : // move constructors
2296 : : ReturnExpr (ReturnExpr &&other) = default;
2297 : : ReturnExpr &operator= (ReturnExpr &&other) = default;
2298 : :
2299 : 1658 : location_t get_locus () const override final { return locus; }
2300 : :
2301 : : void accept_vis (HIRFullVisitor &vis) override;
2302 : : void accept_vis (HIRExpressionVisitor &vis) override;
2303 : :
2304 : 370 : bool has_expr () { return return_expr != nullptr; }
2305 : 4739 : Expr &get_expr () { return *return_expr; }
2306 : :
2307 : 0 : ExprType get_expression_type () const override final
2308 : : {
2309 : 0 : return ExprType::Return;
2310 : : }
2311 : :
2312 : : protected:
2313 : : /* Use covariance to implement clone function as returning this object rather
2314 : : * than base */
2315 : 0 : ReturnExpr *clone_expr_impl () const override
2316 : : {
2317 : 0 : return new ReturnExpr (*this);
2318 : : }
2319 : :
2320 : : /* Use covariance to implement clone function as returning this object rather
2321 : : * than base */
2322 : 0 : ReturnExpr *clone_expr_without_block_impl () const override
2323 : : {
2324 : 0 : return new ReturnExpr (*this);
2325 : : }
2326 : : };
2327 : :
2328 : : // An unsafe block HIR node
2329 : : class UnsafeBlockExpr : public ExprWithBlock
2330 : : {
2331 : : // Or just have it extend BlockExpr
2332 : : std::unique_ptr<BlockExpr> expr;
2333 : : location_t locus;
2334 : :
2335 : : public:
2336 : : std::string to_string () const override;
2337 : :
2338 : : UnsafeBlockExpr (Analysis::NodeMapping mappings,
2339 : : std::unique_ptr<BlockExpr> block_expr,
2340 : : AST::AttrVec outer_attribs, location_t locus);
2341 : :
2342 : : // Copy constructor with clone
2343 : : UnsafeBlockExpr (UnsafeBlockExpr const &other);
2344 : :
2345 : : // Overloaded assignment operator to clone
2346 : : UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other);
2347 : :
2348 : : // move constructors
2349 : : UnsafeBlockExpr (UnsafeBlockExpr &&other) = default;
2350 : : UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
2351 : :
2352 : 9811 : location_t get_locus () const override final { return locus; }
2353 : :
2354 : : void accept_vis (HIRFullVisitor &vis) override;
2355 : : void accept_vis (HIRExpressionVisitor &vis) override;
2356 : :
2357 : 28430 : BlockExpr &get_block_expr () { return *expr; }
2358 : :
2359 : 0 : ExprType get_expression_type () const override final
2360 : : {
2361 : 0 : return ExprType::UnsafeBlock;
2362 : : }
2363 : :
2364 : : protected:
2365 : : /* Use covariance to implement clone function as returning this object rather
2366 : : * than base */
2367 : 0 : UnsafeBlockExpr *clone_expr_impl () const override
2368 : : {
2369 : 0 : return new UnsafeBlockExpr (*this);
2370 : : }
2371 : :
2372 : : /* Use covariance to implement clone function as returning this object rather
2373 : : * than base */
2374 : 0 : UnsafeBlockExpr *clone_expr_with_block_impl () const override
2375 : : {
2376 : 0 : return new UnsafeBlockExpr (*this);
2377 : : }
2378 : : };
2379 : :
2380 : : // Base loop expression HIR node - aka LoopExpr
2381 : : class BaseLoopExpr : public ExprWithBlock
2382 : : {
2383 : : protected:
2384 : : tl::optional<LoopLabel> loop_label;
2385 : : std::unique_ptr<BlockExpr> loop_block;
2386 : :
2387 : : private:
2388 : : location_t locus;
2389 : :
2390 : : protected:
2391 : : // Constructor for BaseLoopExpr
2392 : : BaseLoopExpr (Analysis::NodeMapping mappings,
2393 : : std::unique_ptr<BlockExpr> loop_block, location_t locus,
2394 : : tl::optional<LoopLabel> loop_label,
2395 : : AST::AttrVec outer_attribs = AST::AttrVec ());
2396 : :
2397 : : // Copy constructor for BaseLoopExpr with clone
2398 : : BaseLoopExpr (BaseLoopExpr const &other);
2399 : :
2400 : : // Overloaded assignment operator to clone
2401 : : BaseLoopExpr &operator= (BaseLoopExpr const &other);
2402 : :
2403 : : // move constructors
2404 : : BaseLoopExpr (BaseLoopExpr &&other) = default;
2405 : : BaseLoopExpr &operator= (BaseLoopExpr &&other) = default;
2406 : :
2407 : 3 : ExprType get_expression_type () const final override
2408 : : {
2409 : 3 : return ExprType::BaseLoop;
2410 : : }
2411 : :
2412 : : public:
2413 : 365 : bool has_loop_label () const { return loop_label.has_value (); }
2414 : :
2415 : 1384 : location_t get_locus () const override final { return locus; }
2416 : :
2417 : 1674 : HIR::BlockExpr &get_loop_block () { return *loop_block; };
2418 : :
2419 : 79 : LoopLabel &get_loop_label () { return loop_label.value (); }
2420 : 0 : const LoopLabel &get_loop_label () const { return loop_label.value (); }
2421 : : };
2422 : :
2423 : : // 'Loop' expression (i.e. the infinite loop) HIR node
2424 : 0 : class LoopExpr : public BaseLoopExpr
2425 : : {
2426 : : public:
2427 : : std::string to_string () const override;
2428 : :
2429 : : // Constructor for LoopExpr
2430 : : LoopExpr (Analysis::NodeMapping mappings,
2431 : : std::unique_ptr<BlockExpr> loop_block, location_t locus,
2432 : : tl::optional<LoopLabel> loop_label,
2433 : : AST::AttrVec outer_attribs = AST::AttrVec ());
2434 : :
2435 : : void accept_vis (HIRFullVisitor &vis) override;
2436 : : void accept_vis (HIRExpressionVisitor &vis) override;
2437 : :
2438 : : protected:
2439 : : /* Use covariance to implement clone function as returning this object rather
2440 : : * than base */
2441 : 0 : LoopExpr *clone_expr_impl () const override { return new LoopExpr (*this); }
2442 : :
2443 : : /* Use covariance to implement clone function as returning this object rather
2444 : : * than base */
2445 : 0 : LoopExpr *clone_expr_with_block_impl () const override
2446 : : {
2447 : 0 : return new LoopExpr (*this);
2448 : : }
2449 : : };
2450 : :
2451 : : // While loop expression HIR node (predicate loop)
2452 : : class WhileLoopExpr : public BaseLoopExpr
2453 : : {
2454 : : std::unique_ptr<Expr> condition;
2455 : :
2456 : : public:
2457 : : std::string to_string () const override;
2458 : :
2459 : : // Constructor for while loop with loop label
2460 : : WhileLoopExpr (Analysis::NodeMapping mappings,
2461 : : std::unique_ptr<Expr> loop_condition,
2462 : : std::unique_ptr<BlockExpr> loop_block, location_t locus,
2463 : : tl::optional<LoopLabel> loop_label,
2464 : : AST::AttrVec outer_attribs = AST::AttrVec ());
2465 : :
2466 : : // Copy constructor with clone
2467 : : WhileLoopExpr (WhileLoopExpr const &other);
2468 : :
2469 : : // Overloaded assignment operator to clone
2470 : : WhileLoopExpr &operator= (WhileLoopExpr const &other);
2471 : :
2472 : : // move constructors
2473 : : WhileLoopExpr (WhileLoopExpr &&other) = default;
2474 : : WhileLoopExpr &operator= (WhileLoopExpr &&other) = default;
2475 : :
2476 : : void accept_vis (HIRFullVisitor &vis) override;
2477 : : void accept_vis (HIRExpressionVisitor &vis) override;
2478 : :
2479 : 646 : Expr &get_predicate_expr () { return *condition; }
2480 : :
2481 : : protected:
2482 : : /* Use covariance to implement clone function as returning this object rather
2483 : : * than base */
2484 : 0 : WhileLoopExpr *clone_expr_impl () const override
2485 : : {
2486 : 0 : return new WhileLoopExpr (*this);
2487 : : }
2488 : :
2489 : : /* Use covariance to implement clone function as returning this object rather
2490 : : * than base */
2491 : 0 : WhileLoopExpr *clone_expr_with_block_impl () const override
2492 : : {
2493 : 0 : return new WhileLoopExpr (*this);
2494 : : }
2495 : : };
2496 : :
2497 : : // While let loop expression HIR node (predicate pattern loop)
2498 : : class WhileLetLoopExpr : public BaseLoopExpr
2499 : : {
2500 : : // MatchArmPatterns patterns;
2501 : : std::unique_ptr<Pattern> match_arm_pattern; // inlined
2502 : : std::unique_ptr<Expr> condition;
2503 : :
2504 : : public:
2505 : : std::string to_string () const override;
2506 : :
2507 : : // Constructor with a loop label
2508 : : WhileLetLoopExpr (Analysis::NodeMapping mappings,
2509 : : std::unique_ptr<Pattern> match_arm_pattern,
2510 : : std::unique_ptr<Expr> condition,
2511 : : std::unique_ptr<BlockExpr> loop_block, location_t locus,
2512 : : tl::optional<LoopLabel> loop_label,
2513 : : AST::AttrVec outer_attribs = AST::AttrVec ());
2514 : :
2515 : : // Copy constructor with clone
2516 : : WhileLetLoopExpr (WhileLetLoopExpr const &other);
2517 : :
2518 : : // Overloaded assignment operator to clone pointers
2519 : : WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other);
2520 : :
2521 : : // move constructors
2522 : : WhileLetLoopExpr (WhileLetLoopExpr &&other) = default;
2523 : : WhileLetLoopExpr &operator= (WhileLetLoopExpr &&other) = default;
2524 : :
2525 : : void accept_vis (HIRFullVisitor &vis) override;
2526 : : void accept_vis (HIRExpressionVisitor &vis) override;
2527 : :
2528 : 0 : Expr &get_cond () { return *condition; }
2529 : 0 : std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
2530 : :
2531 : : protected:
2532 : : /* Use covariance to implement clone function as returning this object rather
2533 : : * than base */
2534 : 0 : WhileLetLoopExpr *clone_expr_impl () const override
2535 : : {
2536 : 0 : return new WhileLetLoopExpr (*this);
2537 : : }
2538 : :
2539 : : /* Use covariance to implement clone function as returning this object rather
2540 : : * than base */
2541 : 0 : WhileLetLoopExpr *clone_expr_with_block_impl () const override
2542 : : {
2543 : 0 : return new WhileLetLoopExpr (*this);
2544 : : }
2545 : : };
2546 : :
2547 : : // Base if expression with no "else" or "if let" HIR node
2548 : : class IfExpr : public ExprWithBlock
2549 : : {
2550 : : std::unique_ptr<Expr> condition;
2551 : : std::unique_ptr<BlockExpr> if_block;
2552 : :
2553 : : location_t locus;
2554 : :
2555 : : public:
2556 : : std::string to_string () const override;
2557 : :
2558 : : IfExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition,
2559 : : std::unique_ptr<BlockExpr> if_block, location_t locus);
2560 : : // outer attributes are never allowed on IfExprs
2561 : :
2562 : : // Copy constructor with clone
2563 : : IfExpr (IfExpr const &other);
2564 : :
2565 : : // Overloaded assignment operator to clone expressions
2566 : : IfExpr &operator= (IfExpr const &other);
2567 : :
2568 : : // move constructors
2569 : : IfExpr (IfExpr &&other) = default;
2570 : : IfExpr &operator= (IfExpr &&other) = default;
2571 : :
2572 : : // Unique pointer custom clone function
2573 : : std::unique_ptr<IfExpr> clone_if_expr () const
2574 : : {
2575 : : return std::unique_ptr<IfExpr> (clone_if_expr_impl ());
2576 : : }
2577 : :
2578 : : /* Note that multiple "else if"s are handled via nested HIRs rather than a
2579 : : * vector of else ifs - i.e. not like a switch statement. TODO - is this a
2580 : : * better approach? or does it not parse correctly and have downsides? */
2581 : :
2582 : 9764 : location_t get_locus () const override final { return locus; }
2583 : :
2584 : : void accept_vis (HIRFullVisitor &vis) override;
2585 : : void accept_vis (HIRExpressionVisitor &vis) override;
2586 : :
2587 : : void vis_if_condition (HIRFullVisitor &vis) { condition->accept_vis (vis); }
2588 : : void vis_if_block (HIRFullVisitor &vis) { if_block->accept_vis (vis); }
2589 : :
2590 : 12661 : Expr &get_if_condition () { return *condition; }
2591 : 14293 : BlockExpr &get_if_block () { return *if_block; }
2592 : :
2593 : 0 : ExprType get_expression_type () const final override { return ExprType::If; }
2594 : :
2595 : : protected:
2596 : : /* Use covariance to implement clone function as returning this object rather
2597 : : * than base */
2598 : 0 : IfExpr *clone_expr_impl () const override { return new IfExpr (*this); }
2599 : :
2600 : : // Base clone function but still concrete as concrete base class
2601 : 0 : virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); }
2602 : :
2603 : : /* Use covariance to implement clone function as returning this object rather
2604 : : * than base */
2605 : 0 : IfExpr *clone_expr_with_block_impl () const override
2606 : : {
2607 : 0 : return new IfExpr (*this);
2608 : : }
2609 : : };
2610 : :
2611 : : // If expression with an ending "else" expression HIR node (trailing)
2612 : : class IfExprConseqElse : public IfExpr
2613 : : {
2614 : : std::unique_ptr<ExprWithBlock> else_block;
2615 : :
2616 : : public:
2617 : : std::string to_string () const override;
2618 : :
2619 : : IfExprConseqElse (Analysis::NodeMapping mappings,
2620 : : std::unique_ptr<Expr> condition,
2621 : : std::unique_ptr<BlockExpr> if_block,
2622 : : std::unique_ptr<ExprWithBlock> else_block,
2623 : : location_t locus);
2624 : : // again, outer attributes not allowed
2625 : :
2626 : : // Copy constructor with clone
2627 : : IfExprConseqElse (IfExprConseqElse const &other);
2628 : :
2629 : : // Overloaded assignment operator with cloning
2630 : : IfExprConseqElse &operator= (IfExprConseqElse const &other);
2631 : :
2632 : : // move constructors
2633 : : IfExprConseqElse (IfExprConseqElse &&other) = default;
2634 : : IfExprConseqElse &operator= (IfExprConseqElse &&other) = default;
2635 : :
2636 : : void accept_vis (HIRFullVisitor &vis) override;
2637 : : void accept_vis (HIRExpressionVisitor &vis) override;
2638 : :
2639 : : void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); }
2640 : :
2641 : 11093 : ExprWithBlock &get_else_block () { return *else_block; }
2642 : :
2643 : : protected:
2644 : : /* Use covariance to implement clone function as returning this object rather
2645 : : * than base */
2646 : 0 : IfExprConseqElse *clone_expr_impl () const override
2647 : : {
2648 : 0 : return new IfExprConseqElse (*this);
2649 : : }
2650 : :
2651 : : /* Use covariance to implement clone function as returning this object rather
2652 : : * than base */
2653 : 0 : IfExprConseqElse *clone_expr_with_block_impl () const override
2654 : : {
2655 : 0 : return new IfExprConseqElse (*this);
2656 : : }
2657 : :
2658 : : /* Use covariance to implement clone function as returning this object rather
2659 : : * than base */
2660 : 0 : IfExprConseqElse *clone_if_expr_impl () const override
2661 : : {
2662 : 0 : return new IfExprConseqElse (*this);
2663 : : }
2664 : : };
2665 : :
2666 : : // Match arm expression
2667 : : struct MatchArm
2668 : : {
2669 : : private:
2670 : : AST::AttrVec outer_attrs;
2671 : : std::unique_ptr<Pattern> match_arm_pattern;
2672 : : std::unique_ptr<Expr> guard_expr;
2673 : : location_t locus;
2674 : :
2675 : : public:
2676 : : // Returns whether the MatchArm has a match arm guard expression
2677 : 8067 : bool has_match_arm_guard () const { return guard_expr != nullptr; }
2678 : :
2679 : : // Constructor for match arm with a guard expression
2680 : : MatchArm (std::unique_ptr<Pattern> match_arm_pattern, location_t locus,
2681 : : std::unique_ptr<Expr> guard_expr = nullptr,
2682 : : AST::AttrVec outer_attrs = AST::AttrVec ());
2683 : :
2684 : : // Copy constructor with clone
2685 : : MatchArm (MatchArm const &other);
2686 : :
2687 : 9870 : ~MatchArm () = default;
2688 : :
2689 : : // Overload assignment operator to clone
2690 : : MatchArm &operator= (MatchArm const &other);
2691 : :
2692 : : // move constructors
2693 : 5014 : MatchArm (MatchArm &&other) = default;
2694 : : MatchArm &operator= (MatchArm &&other) = default;
2695 : :
2696 : : // Returns whether match arm is in an error state.
2697 : : bool is_error () const { return match_arm_pattern == nullptr; }
2698 : :
2699 : : // Creates a match arm in an error state.
2700 : : static MatchArm create_error ()
2701 : : {
2702 : : location_t locus = UNDEF_LOCATION;
2703 : : return MatchArm (nullptr, locus);
2704 : : }
2705 : :
2706 : : std::string to_string () const;
2707 : :
2708 : 9283 : std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
2709 : :
2710 : 1 : Expr &get_guard_expr () { return *guard_expr; }
2711 : :
2712 : 2025 : location_t get_locus () const { return locus; }
2713 : :
2714 : : AST::AttrVec &get_outer_attrs () { return outer_attrs; }
2715 : : };
2716 : :
2717 : : /* A "match case" - a correlated match arm and resulting expression. Not
2718 : : * abstract. */
2719 : : struct MatchCase
2720 : : {
2721 : : private:
2722 : : Analysis::NodeMapping mappings;
2723 : : MatchArm arm;
2724 : : std::unique_ptr<Expr> expr;
2725 : :
2726 : : public:
2727 : : MatchCase (Analysis::NodeMapping mappings, MatchArm arm,
2728 : : std::unique_ptr<Expr> expr);
2729 : :
2730 : : MatchCase (const MatchCase &other);
2731 : :
2732 : : MatchCase &operator= (const MatchCase &other);
2733 : :
2734 : 1542 : MatchCase (MatchCase &&other) = default;
2735 : : MatchCase &operator= (MatchCase &&other) = default;
2736 : :
2737 : 1542 : ~MatchCase () = default;
2738 : :
2739 : : std::string to_string () const;
2740 : : std::string to_debug_string () const;
2741 : :
2742 : : Analysis::NodeMapping get_mappings () const { return mappings; }
2743 : :
2744 : 12597 : MatchArm &get_arm () { return arm; }
2745 : 19462 : Expr &get_expr () { return *expr; }
2746 : : };
2747 : :
2748 : : // Match expression HIR node
2749 : : class MatchExpr : public ExprWithBlock, public WithInnerAttrs
2750 : : {
2751 : : std::unique_ptr<Expr> branch_value;
2752 : : std::vector<MatchCase> match_arms;
2753 : : location_t locus;
2754 : :
2755 : : public:
2756 : : std::string to_string () const override;
2757 : :
2758 : 2998 : bool has_match_arms () const { return !match_arms.empty (); }
2759 : :
2760 : : MatchExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> branch_value,
2761 : : std::vector<MatchCase> match_arms, AST::AttrVec inner_attrs,
2762 : : AST::AttrVec outer_attrs, location_t locus);
2763 : :
2764 : : // Copy constructor requires clone due to unique_ptr
2765 : : MatchExpr (MatchExpr const &other);
2766 : :
2767 : : // Overloaded assignment operator to clone due to unique_ptr
2768 : : MatchExpr &operator= (MatchExpr const &other);
2769 : :
2770 : : // move constructors
2771 : : MatchExpr (MatchExpr &&other) = default;
2772 : : MatchExpr &operator= (MatchExpr &&other) = default;
2773 : :
2774 : 12912 : location_t get_locus () const override final { return locus; }
2775 : :
2776 : : void accept_vis (HIRFullVisitor &vis) override;
2777 : : void accept_vis (HIRExpressionVisitor &vis) override;
2778 : :
2779 : 14365 : Expr &get_scrutinee_expr () { return *branch_value; }
2780 : 980 : AST::AttrVec get_inner_attrs () const { return inner_attrs; }
2781 : : const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
2782 : 8411 : std::vector<MatchCase> &get_match_cases () { return match_arms; }
2783 : :
2784 : 0 : ExprType get_expression_type () const final override
2785 : : {
2786 : 0 : return ExprType::Match;
2787 : : }
2788 : :
2789 : : protected:
2790 : : /* Use covariance to implement clone function as returning this object rather
2791 : : * than base */
2792 : 0 : MatchExpr *clone_expr_impl () const override { return new MatchExpr (*this); }
2793 : :
2794 : : /* Use covariance to implement clone function as returning this object rather
2795 : : * than base */
2796 : 0 : MatchExpr *clone_expr_with_block_impl () const override
2797 : : {
2798 : 0 : return new MatchExpr (*this);
2799 : : }
2800 : : };
2801 : :
2802 : : // Await expression HIR node (pseudo-member variable access)
2803 : : class AwaitExpr : public ExprWithoutBlock
2804 : : {
2805 : : std::unique_ptr<Expr> awaited_expr;
2806 : : location_t locus;
2807 : :
2808 : : public:
2809 : : // TODO: ensure outer attributes are actually allowed
2810 : : AwaitExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> awaited_expr,
2811 : : AST::AttrVec outer_attrs, location_t locus);
2812 : :
2813 : : // copy constructor with clone
2814 : : AwaitExpr (AwaitExpr const &other);
2815 : :
2816 : : // overloaded assignment operator with clone
2817 : : AwaitExpr &operator= (AwaitExpr const &other);
2818 : :
2819 : : // move constructors
2820 : : AwaitExpr (AwaitExpr &&other) = default;
2821 : : AwaitExpr &operator= (AwaitExpr &&other) = default;
2822 : :
2823 : : std::string to_string () const override;
2824 : :
2825 : 0 : location_t get_locus () const override final { return locus; }
2826 : :
2827 : : void accept_vis (HIRFullVisitor &vis) override;
2828 : : void accept_vis (HIRExpressionVisitor &vis) override;
2829 : :
2830 : 0 : Expr &get_awaited_expr () { return *awaited_expr; }
2831 : :
2832 : 0 : ExprType get_expression_type () const final override
2833 : : {
2834 : 0 : return ExprType::Await;
2835 : : }
2836 : :
2837 : : protected:
2838 : : /* Use covariance to implement clone function as returning this object rather
2839 : : * than base */
2840 : 0 : AwaitExpr *clone_expr_without_block_impl () const override
2841 : : {
2842 : 0 : return new AwaitExpr (*this);
2843 : : }
2844 : : };
2845 : :
2846 : : // Async block expression HIR node (block expr that evaluates to a future)
2847 : : class AsyncBlockExpr : public ExprWithBlock
2848 : : {
2849 : : bool has_move;
2850 : : std::unique_ptr<BlockExpr> block_expr;
2851 : : location_t locus;
2852 : :
2853 : : public:
2854 : : AsyncBlockExpr (Analysis::NodeMapping mappings,
2855 : : std::unique_ptr<BlockExpr> block_expr, bool has_move,
2856 : : AST::AttrVec outer_attrs, location_t locus);
2857 : :
2858 : : // copy constructor with clone
2859 : : AsyncBlockExpr (AsyncBlockExpr const &other);
2860 : :
2861 : : // overloaded assignment operator to clone
2862 : : AsyncBlockExpr &operator= (AsyncBlockExpr const &other);
2863 : :
2864 : : // move constructors
2865 : : AsyncBlockExpr (AsyncBlockExpr &&other) = default;
2866 : : AsyncBlockExpr &operator= (AsyncBlockExpr &&other) = default;
2867 : :
2868 : : std::string to_string () const override;
2869 : :
2870 : 0 : location_t get_locus () const override final { return locus; }
2871 : :
2872 : 0 : bool get_has_move () const { return has_move; }
2873 : 0 : BlockExpr &get_block_expr () { return *block_expr; }
2874 : :
2875 : : void accept_vis (HIRFullVisitor &vis) override;
2876 : : void accept_vis (HIRExpressionVisitor &vis) override;
2877 : :
2878 : 0 : ExprType get_expression_type () const final override
2879 : : {
2880 : 0 : return ExprType::AsyncBlock;
2881 : : }
2882 : :
2883 : : protected:
2884 : : /* Use covariance to implement clone function as returning this object rather
2885 : : * than base */
2886 : 0 : AsyncBlockExpr *clone_expr_with_block_impl () const override
2887 : : {
2888 : 0 : return new AsyncBlockExpr (*this);
2889 : : }
2890 : : };
2891 : :
2892 : : // this is a utility helper class for type-checking and code-generation
2893 : : class OperatorExprMeta
2894 : : {
2895 : : public:
2896 : : OperatorExprMeta (HIR::CompoundAssignmentExpr &expr);
2897 : :
2898 : : OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr);
2899 : :
2900 : : OperatorExprMeta (HIR::NegationExpr &expr);
2901 : :
2902 : : OperatorExprMeta (HIR::DereferenceExpr &expr);
2903 : :
2904 : : OperatorExprMeta (HIR::ArrayIndexExpr &expr);
2905 : :
2906 : : OperatorExprMeta (HIR::ComparisonExpr &expr);
2907 : :
2908 : 56 : OperatorExprMeta (const OperatorExprMeta &other)
2909 : 56 : : node_mappings (other.node_mappings),
2910 : 56 : lvalue_mappings (other.lvalue_mappings),
2911 : 24 : rvalue_mappings (other.rvalue_mappings), locus (other.locus)
2912 : : {}
2913 : :
2914 : 0 : OperatorExprMeta &operator= (const OperatorExprMeta &other)
2915 : : {
2916 : 0 : node_mappings = other.node_mappings;
2917 : 0 : lvalue_mappings = other.lvalue_mappings;
2918 : 0 : rvalue_mappings = other.rvalue_mappings;
2919 : 0 : locus = other.locus;
2920 : :
2921 : 0 : return *this;
2922 : : }
2923 : :
2924 : 2418 : const Analysis::NodeMapping &get_mappings () const { return node_mappings; }
2925 : :
2926 : 2568 : const Analysis::NodeMapping &get_lvalue_mappings () const
2927 : : {
2928 : 2568 : return lvalue_mappings;
2929 : : }
2930 : :
2931 : : const Analysis::NodeMapping &get_rvalue_mappings () const
2932 : : {
2933 : : return rvalue_mappings;
2934 : : }
2935 : :
2936 : 8 : bool has_rvalue_mappings () const
2937 : : {
2938 : 8 : return rvalue_mappings.get_hirid () != UNKNOWN_HIRID;
2939 : : }
2940 : :
2941 : 6442 : location_t get_locus () const { return locus; }
2942 : :
2943 : : private:
2944 : : Analysis::NodeMapping node_mappings;
2945 : : Analysis::NodeMapping lvalue_mappings;
2946 : : Analysis::NodeMapping rvalue_mappings;
2947 : : location_t locus;
2948 : : };
2949 : :
2950 : : class InlineAsmReg
2951 : : {
2952 : : enum Kind
2953 : : {
2954 : : X86,
2955 : : Arm,
2956 : : AArch64,
2957 : : RiscV,
2958 : : Nvptx,
2959 : : PowerPC,
2960 : : Hexagon,
2961 : : Mips,
2962 : : S390x,
2963 : : SpirV,
2964 : : Wasm,
2965 : : Bpf,
2966 : : Avr,
2967 : : Msp430,
2968 : : // Placeholder for invalid register constraints for the current target
2969 : : Err,
2970 : : };
2971 : :
2972 : : // this placeholder is to be removed when the definations
2973 : : // of the above enums are made in a later PR/patch.
2974 : : std::string placeholder;
2975 : : };
2976 : :
2977 : : class InlineAsmRegClass
2978 : : {
2979 : : enum Type
2980 : : {
2981 : : X86,
2982 : : Arm,
2983 : : AArch64,
2984 : : RiscV,
2985 : : Nvptx,
2986 : : PowerPC,
2987 : : Hexagon,
2988 : : Mips,
2989 : : S390x,
2990 : : SpirV,
2991 : : Wasm,
2992 : : Bpf,
2993 : : Avr,
2994 : : Msp430,
2995 : : // Placeholder for invalid register constraints for the current target
2996 : : Err,
2997 : : };
2998 : :
2999 : : // this placeholder is to be removed when the definations
3000 : : // of the above enums are made in a later PR/patch.
3001 : : std::string placeholder;
3002 : : };
3003 : :
3004 : : class InlineAsmOperand
3005 : : {
3006 : : public:
3007 : : struct In
3008 : : {
3009 : : tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
3010 : : std::unique_ptr<Expr> expr;
3011 : :
3012 : : In (const tl::optional<struct AST::InlineAsmRegOrRegClass> ®,
3013 : : std::unique_ptr<Expr> expr);
3014 : :
3015 : : In (const struct In &other);
3016 : :
3017 : : In operator= (const struct In &other);
3018 : : };
3019 : :
3020 : : struct Out
3021 : : {
3022 : : tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
3023 : : bool late;
3024 : : std::unique_ptr<Expr> expr; // can be null
3025 : :
3026 : : Out (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late,
3027 : : std::unique_ptr<Expr> expr);
3028 : :
3029 : : Out (const struct Out &other);
3030 : :
3031 : : Out operator= (const struct Out &other);
3032 : : };
3033 : :
3034 : : struct InOut
3035 : : {
3036 : : tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
3037 : : bool late;
3038 : : std::unique_ptr<Expr> expr; // this can't be null
3039 : :
3040 : : InOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late,
3041 : : std::unique_ptr<Expr> expr);
3042 : :
3043 : : InOut (const struct InOut &other);
3044 : :
3045 : : InOut operator= (const struct InOut &other);
3046 : : };
3047 : :
3048 : : struct SplitInOut
3049 : : {
3050 : : tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
3051 : : bool late;
3052 : : std::unique_ptr<Expr> in_expr;
3053 : : std::unique_ptr<Expr> out_expr; // could be null
3054 : :
3055 : : SplitInOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®,
3056 : : bool late, std::unique_ptr<Expr> in_expr,
3057 : : std::unique_ptr<Expr> out_expr);
3058 : :
3059 : : SplitInOut (const struct SplitInOut &other);
3060 : :
3061 : : SplitInOut operator= (const struct SplitInOut &other);
3062 : : };
3063 : :
3064 : 0 : struct Const
3065 : : {
3066 : : AnonConst anon_const;
3067 : : };
3068 : :
3069 : 0 : struct Sym
3070 : : {
3071 : : std::unique_ptr<Expr> expr;
3072 : :
3073 : : Sym (std::unique_ptr<Expr> expr);
3074 : :
3075 : : Sym (const struct Sym &other);
3076 : :
3077 : : Sym operator= (const struct Sym &other);
3078 : : };
3079 : :
3080 : 0 : struct Label
3081 : : {
3082 : : std::string label_name;
3083 : : std::unique_ptr<Expr> expr;
3084 : :
3085 : : Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr);
3086 : :
3087 : : Label (const struct Label &other);
3088 : :
3089 : : Label operator= (const struct Label &other);
3090 : : };
3091 : :
3092 : : using RegisterType = AST::InlineAsmOperand::RegisterType;
3093 : :
3094 : : private:
3095 : : AST::InlineAsmOperand::RegisterType register_type;
3096 : :
3097 : : tl::optional<struct In> in;
3098 : : tl::optional<struct Out> out;
3099 : : tl::optional<struct InOut> in_out;
3100 : : tl::optional<struct SplitInOut> split_in_out;
3101 : : tl::optional<struct Const> cnst;
3102 : : tl::optional<struct Sym> sym;
3103 : : tl::optional<struct Label> label;
3104 : :
3105 : : public:
3106 : 67 : InlineAsmOperand (const InlineAsmOperand &other)
3107 : 67 : : register_type (other.register_type), in (other.in), out (other.out),
3108 : 67 : in_out (other.in_out), split_in_out (other.split_in_out),
3109 : 67 : cnst (other.cnst), sym (other.sym)
3110 : 67 : {}
3111 : :
3112 : 10 : InlineAsmOperand (const struct In ®)
3113 : 10 : : register_type (RegisterType::In), in (reg)
3114 : 10 : {}
3115 : :
3116 : 17 : InlineAsmOperand (const struct Out ®)
3117 : 17 : : register_type (RegisterType::Out), out (reg)
3118 : 17 : {}
3119 : 0 : InlineAsmOperand (const struct InOut ®)
3120 : 0 : : register_type (RegisterType::InOut), in_out (reg)
3121 : 0 : {}
3122 : 2 : InlineAsmOperand (const struct SplitInOut ®)
3123 : 2 : : register_type (RegisterType::SplitInOut), split_in_out (reg)
3124 : 2 : {}
3125 : 0 : InlineAsmOperand (const struct Const ®)
3126 : 0 : : register_type (RegisterType::Const), cnst (reg)
3127 : 0 : {}
3128 : 0 : InlineAsmOperand (const struct Sym ®)
3129 : 0 : : register_type (RegisterType::Sym), sym (reg)
3130 : 0 : {}
3131 : 0 : InlineAsmOperand (const struct Label ®)
3132 : 0 : : register_type (RegisterType::Label), label (reg)
3133 : 0 : {}
3134 : :
3135 : 116 : RegisterType get_register_type () const { return register_type; }
3136 : :
3137 : : // Potentially unsafe without get_register_type() check
3138 : 10 : const struct In &get_in () const { return in.value (); }
3139 : 17 : const struct Out &get_out () const { return out.value (); }
3140 : 0 : const struct InOut &get_in_out () const { return in_out.value (); }
3141 : 2 : const struct SplitInOut &get_split_in_out () const
3142 : : {
3143 : 2 : return split_in_out.value ();
3144 : : }
3145 : 0 : const struct Const &get_const () const { return cnst.value (); }
3146 : 0 : const struct Sym &get_sym () const { return sym.value (); }
3147 : 0 : const struct Label &get_label () const { return label.value (); }
3148 : :
3149 : 20 : struct In &get_in () { return in.value (); }
3150 : 34 : struct Out &get_out () { return out.value (); }
3151 : 0 : struct InOut &get_in_out () { return in_out.value (); }
3152 : 8 : struct SplitInOut &get_split_in_out () { return split_in_out.value (); }
3153 : 0 : struct Const &get_const () { return cnst.value (); }
3154 : 0 : struct Sym &get_sym () { return sym.value (); }
3155 : 0 : struct Label &get_label () { return label.value (); }
3156 : : };
3157 : :
3158 : : // Inline Assembly Node
3159 : : class InlineAsm : public ExprWithoutBlock
3160 : : {
3161 : : NodeId id;
3162 : : location_t locus;
3163 : :
3164 : : public:
3165 : : bool is_global_asm;
3166 : :
3167 : : std::vector<AST::InlineAsmTemplatePiece> template_;
3168 : : std::vector<AST::TupleTemplateStr> template_strs;
3169 : : std::vector<HIR::InlineAsmOperand> operands;
3170 : : std::vector<AST::TupleClobber> clobber_abi;
3171 : : std::set<AST::InlineAsm::Option> options;
3172 : :
3173 : : std::vector<location_t> line_spans;
3174 : :
3175 : : void accept_vis (HIRExpressionVisitor &vis) override;
3176 : :
3177 : : void accept_vis (HIRFullVisitor &vis) override;
3178 : :
3179 : 0 : std::string to_string () const override { return "InlineAsm HIR Node"; }
3180 : :
3181 : 58 : location_t get_locus () const override { return locus; }
3182 : :
3183 : 0 : InlineAsm *clone_expr_without_block_impl () const override
3184 : : {
3185 : 0 : return new InlineAsm (*this);
3186 : : }
3187 : :
3188 : 0 : ExprType get_expression_type () const final override
3189 : : {
3190 : 0 : return ExprType::InlineAsm;
3191 : : }
3192 : 0 : std::vector<AST::InlineAsmTemplatePiece> get_template_ ()
3193 : : {
3194 : 0 : return template_;
3195 : : }
3196 : :
3197 : 0 : std::vector<AST::TupleTemplateStr> get_template_strs ()
3198 : : {
3199 : 0 : return template_strs;
3200 : : }
3201 : :
3202 : 103 : std::vector<HIR::InlineAsmOperand> &get_operands () { return operands; }
3203 : :
3204 : : std::vector<AST::TupleClobber> get_clobber_abi () { return clobber_abi; }
3205 : :
3206 : : std::set<AST::InlineAsm::Option> get_options () { return options; }
3207 : :
3208 : 26 : bool is_simple_asm ()
3209 : : {
3210 : : // INFO: A simple asm is an asm that does not have any operands
3211 : 26 : return this->operands.size () == 0;
3212 : : }
3213 : :
3214 : 26 : bool is_inline_asm ()
3215 : : {
3216 : : // INFO: An inline asm is asm!, which is the opposite of a global_asm()
3217 : 26 : return !this->is_global_asm;
3218 : : }
3219 : :
3220 : : InlineAsm (location_t locus, bool is_global_asm,
3221 : : std::vector<AST::InlineAsmTemplatePiece> template_,
3222 : : std::vector<AST::TupleTemplateStr> template_strs,
3223 : : std::vector<HIR::InlineAsmOperand> operands,
3224 : : std::vector<AST::TupleClobber> clobber_abi,
3225 : : std::set<AST::InlineAsm::Option> options,
3226 : : Analysis::NodeMapping mappings,
3227 : : AST::AttrVec outer_attribs = AST::AttrVec ());
3228 : : };
3229 : :
3230 : : class OffsetOf : public ExprWithoutBlock
3231 : : {
3232 : : public:
3233 : 15 : OffsetOf (std::unique_ptr<Type> &&type, Identifier field,
3234 : : Analysis::NodeMapping mappings, location_t loc)
3235 : 30 : : ExprWithoutBlock (mappings), type (std::move (type)), field (field),
3236 : 15 : loc (loc)
3237 : 15 : {}
3238 : :
3239 : 0 : OffsetOf (const OffsetOf &other)
3240 : 0 : : ExprWithoutBlock (other), type (other.type->clone_type ()),
3241 : 0 : field (other.field), loc (other.loc)
3242 : 0 : {}
3243 : :
3244 : : OffsetOf &operator= (const OffsetOf &other);
3245 : :
3246 : : ExprWithoutBlock *clone_expr_without_block_impl () const override;
3247 : : std::string to_string () const override;
3248 : :
3249 : : void accept_vis (HIRExpressionVisitor &vis) override;
3250 : : void accept_vis (HIRFullVisitor &vis) override;
3251 : :
3252 : 0 : ExprType get_expression_type () const override { return ExprType::OffsetOf; }
3253 : :
3254 : 44 : location_t get_locus () const override { return loc; }
3255 : :
3256 : 29 : Type &get_type () { return *type; }
3257 : : const Type &get_type () const { return *type; }
3258 : : const Identifier &get_field () const { return field; }
3259 : :
3260 : : private:
3261 : : std::unique_ptr<Type> type;
3262 : : Identifier field;
3263 : : location_t loc;
3264 : : };
3265 : :
3266 : 4 : struct LlvmOperand
3267 : : {
3268 : : std::string constraint;
3269 : : std::unique_ptr<Expr> expr;
3270 : :
3271 : 2 : LlvmOperand (std::string constraint, std::unique_ptr<Expr> &&expr)
3272 : 4 : : constraint (constraint), expr (std::move (expr))
3273 : : {}
3274 : :
3275 : 4 : LlvmOperand (const LlvmOperand &other)
3276 : 8 : : constraint (other.constraint), expr (other.expr->clone_expr ())
3277 : 4 : {}
3278 : : LlvmOperand &operator= (const LlvmOperand &other)
3279 : : {
3280 : : constraint = other.constraint;
3281 : : expr = other.expr->clone_expr ();
3282 : :
3283 : : return *this;
3284 : : }
3285 : : };
3286 : :
3287 : : class LlvmInlineAsm : public ExprWithoutBlock
3288 : : {
3289 : : public:
3290 : : struct Options
3291 : : {
3292 : : bool is_volatile;
3293 : : bool align_stack;
3294 : : AST::LlvmInlineAsm::Dialect dialect;
3295 : : };
3296 : :
3297 : : location_t locus;
3298 : : AST::AttrVec outer_attrs;
3299 : : std::vector<LlvmOperand> inputs;
3300 : : std::vector<LlvmOperand> outputs;
3301 : : std::vector<AST::TupleTemplateStr> templates;
3302 : : std::vector<AST::TupleClobber> clobbers;
3303 : : Options options;
3304 : :
3305 : 2 : LlvmInlineAsm (location_t locus, std::vector<LlvmOperand> inputs,
3306 : : std::vector<LlvmOperand> outputs,
3307 : : std::vector<AST::TupleTemplateStr> templates,
3308 : : std::vector<AST::TupleClobber> clobbers, Options options,
3309 : : AST::AttrVec outer_attrs, Analysis::NodeMapping mappings)
3310 : 4 : : ExprWithoutBlock (mappings, std::move (outer_attrs)), locus (locus),
3311 : 2 : inputs (std::move (inputs)), outputs (std::move (outputs)),
3312 : 2 : templates (std::move (templates)), clobbers (std::move (clobbers)),
3313 : 2 : options (options)
3314 : 2 : {}
3315 : :
3316 : : AST::LlvmInlineAsm::Dialect get_dialect () { return options.dialect; }
3317 : :
3318 : 4 : location_t get_locus () const override { return locus; }
3319 : :
3320 : : std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
3321 : :
3322 : : void accept_vis (HIRFullVisitor &vis) override;
3323 : : void accept_vis (HIRExpressionVisitor &vis) override;
3324 : :
3325 : 0 : LlvmInlineAsm *clone_expr_without_block_impl () const override
3326 : : {
3327 : 0 : return new LlvmInlineAsm (*this);
3328 : : }
3329 : :
3330 : : std::vector<AST::TupleTemplateStr> &get_templates () { return templates; }
3331 : :
3332 : 0 : Expr::ExprType get_expression_type () const override
3333 : : {
3334 : 0 : return Expr::ExprType::LlvmInlineAsm;
3335 : : }
3336 : :
3337 : 2 : std::vector<AST::TupleClobber> get_clobbers () { return clobbers; }
3338 : : };
3339 : :
3340 : : } // namespace HIR
3341 : : } // namespace Rust
3342 : :
3343 : : #endif
|