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