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