1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of GCC.
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
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
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/>.
19 #ifndef RUST_HIR_EXPR_H
20 #define RUST_HIR_EXPR_H
22 #include "rust-common.h"
23 #include "rust-ast-full-decls.h"
25 #include "rust-hir-path.h"
31 // HIR node for an expression with an accompanying block - abstract
32 class ExprWithBlock
: public Expr
34 // TODO: should this mean that a BlockExpr should be a member variable?
36 ExprWithBlock (Analysis::NodeMapping mappings
,
37 AST::AttrVec outer_attrs
= AST::AttrVec ())
38 : Expr (std::move (mappings
), std::move (outer_attrs
))
41 // pure virtual clone implementation
42 virtual ExprWithBlock
*clone_expr_with_block_impl () const = 0;
44 // prevent having to define multiple clone expressions
45 ExprWithBlock
*clone_expr_impl () const override
47 return clone_expr_with_block_impl ();
51 // Unique pointer custom clone function
52 std::unique_ptr
<ExprWithBlock
> clone_expr_with_block () const
54 return std::unique_ptr
<ExprWithBlock
> (clone_expr_with_block_impl ());
57 BlockType
get_block_expr_type () const final override
59 return BlockType::WITH_BLOCK
;
63 // Literals? Or literal base?
64 class LiteralExpr
: public ExprWithoutBlock
70 std::string
as_string () const override
72 return "( " + literal
.as_string () + " (" + get_mappings ().as_string ()
76 Literal::LitType
get_lit_type () const { return literal
.get_lit_type (); }
78 LiteralExpr (Analysis::NodeMapping mappings
, std::string value_as_string
,
79 Literal::LitType type
, PrimitiveCoreType type_hint
,
80 Location locus
, AST::AttrVec outer_attrs
)
81 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attrs
)),
82 literal (std::move (value_as_string
), type
, type_hint
), locus (locus
)
85 LiteralExpr (Analysis::NodeMapping mappings
, Literal literal
, Location locus
,
86 AST::AttrVec outer_attrs
)
87 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attrs
)),
88 literal (std::move (literal
)), locus (locus
)
91 // Unique pointer custom clone function
92 std::unique_ptr
<LiteralExpr
> clone_literal_expr () const
94 return std::unique_ptr
<LiteralExpr
> (clone_literal_expr_impl ());
97 Location
get_locus () const override final
{ return locus
; }
99 void accept_vis (HIRFullVisitor
&vis
) override
;
100 void accept_vis (HIRExpressionVisitor
&vis
) override
;
102 Literal
&get_literal () { return literal
; }
103 const Literal
&get_literal () const { return literal
; }
105 ExprType
get_expression_type () const override final
{ return ExprType::Lit
; }
108 /* Use covariance to implement clone function as returning this object rather
110 LiteralExpr
*clone_expr_impl () const override
112 return new LiteralExpr (*this);
115 /* Use covariance to implement clone function as returning this object rather
117 LiteralExpr
*clone_expr_without_block_impl () const override
119 return new LiteralExpr (*this);
122 /* not virtual as currently no subclasses of LiteralExpr, but could be in
124 /*virtual*/ LiteralExpr
*clone_literal_expr_impl () const
126 return new LiteralExpr (*this);
130 /* Represents an expression using unary or binary operators as HIR node. Can be
132 class OperatorExpr
: public ExprWithoutBlock
134 // TODO: create binary and unary operator subclasses?
139 /* Variable must be protected to allow derived classes to use it as a first
141 std::unique_ptr
<Expr
> main_or_left_expr
;
143 // Constructor (only for initialisation of expr purposes)
144 OperatorExpr (Analysis::NodeMapping mappings
,
145 std::unique_ptr
<Expr
> main_or_left_expr
,
146 AST::AttrVec outer_attribs
, Location locus
)
147 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
148 locus (locus
), main_or_left_expr (std::move (main_or_left_expr
))
151 // Copy constructor (only for initialisation of expr purposes)
152 OperatorExpr (OperatorExpr
const &other
)
153 : ExprWithoutBlock (other
), locus (other
.locus
),
154 main_or_left_expr (other
.main_or_left_expr
->clone_expr ())
157 // Overload assignment operator to deep copy expr
158 OperatorExpr
&operator= (OperatorExpr
const &other
)
160 ExprWithoutBlock::operator= (other
);
161 main_or_left_expr
= other
.main_or_left_expr
->clone_expr ();
163 // outer_attrs = other.outer_attrs;
169 OperatorExpr (OperatorExpr
&&other
) = default;
170 OperatorExpr
&operator= (OperatorExpr
&&other
) = default;
173 Location
get_locus () const override final
{ return locus
; }
175 std::unique_ptr
<Expr
> &get_expr () { return main_or_left_expr
; }
177 ExprType
get_expression_type () const override final
179 return ExprType::Operator
;
183 /* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be
185 class BorrowExpr
: public OperatorExpr
191 std::string
as_string () const override
;
193 BorrowExpr (Analysis::NodeMapping mappings
,
194 std::unique_ptr
<Expr
> borrow_lvalue
, Mutability mut
,
195 bool is_double_borrow
, AST::AttrVec outer_attribs
, Location locus
)
196 : OperatorExpr (std::move (mappings
), std::move (borrow_lvalue
),
197 std::move (outer_attribs
), locus
),
198 mut (mut
), double_borrow (is_double_borrow
)
201 void accept_vis (HIRFullVisitor
&vis
) override
;
202 void accept_vis (HIRExpressionVisitor
&vis
) override
;
204 Mutability
get_mut () const { return mut
; }
205 bool is_mut () const { return mut
== Mutability::Mut
; }
206 bool get_is_double_borrow () const { return double_borrow
; }
209 /* Use covariance to implement clone function as returning this object rather
211 BorrowExpr
*clone_expr_impl () const override
213 return new BorrowExpr (*this);
216 /* Use covariance to implement clone function as returning this object rather
218 BorrowExpr
*clone_expr_without_block_impl () const override
220 return new BorrowExpr (*this);
224 // Unary prefix * deference operator
225 class DereferenceExpr
: public OperatorExpr
228 std::string
as_string () const override
;
230 // Constructor calls OperatorExpr's protected constructor
231 DereferenceExpr (Analysis::NodeMapping mappings
,
232 std::unique_ptr
<Expr
> deref_lvalue
,
233 AST::AttrVec outer_attribs
, Location locus
)
234 : OperatorExpr (std::move (mappings
), std::move (deref_lvalue
),
235 std::move (outer_attribs
), locus
)
238 void accept_vis (HIRFullVisitor
&vis
) override
;
239 void accept_vis (HIRExpressionVisitor
&vis
) override
;
242 /* Use covariance to implement clone function as returning this object rather
244 DereferenceExpr
*clone_expr_impl () const override
246 return new DereferenceExpr (*this);
249 /* Use covariance to implement clone function as returning this object rather
251 DereferenceExpr
*clone_expr_without_block_impl () const override
253 return new DereferenceExpr (*this);
257 // Unary postfix ? error propogation operator. Cannot be overloaded.
258 class ErrorPropagationExpr
: public OperatorExpr
261 std::string
as_string () const override
;
263 // Constructor calls OperatorExpr's protected constructor
264 ErrorPropagationExpr (Analysis::NodeMapping mappings
,
265 std::unique_ptr
<Expr
> potential_error_value
,
266 AST::AttrVec outer_attribs
, Location locus
)
267 : OperatorExpr (std::move (mappings
), std::move (potential_error_value
),
268 std::move (outer_attribs
), locus
)
271 void accept_vis (HIRFullVisitor
&vis
) override
;
272 void accept_vis (HIRExpressionVisitor
&vis
) override
;
275 /* Use covariance to implement clone function as returning this object rather
277 ErrorPropagationExpr
*clone_expr_impl () const override
279 return new ErrorPropagationExpr (*this);
282 /* Use covariance to implement clone function as returning this object rather
284 ErrorPropagationExpr
*clone_expr_without_block_impl () const override
286 return new ErrorPropagationExpr (*this);
290 // Unary prefix - or ! negation or NOT operators.
291 class NegationExpr
: public OperatorExpr
294 using ExprType
= NegationOperator
;
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) */
303 std::string
as_string () const override
;
305 ExprType
get_expr_type () const { return expr_type
; }
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 locus
)
311 : OperatorExpr (std::move (mappings
), std::move (negated_value
),
312 std::move (outer_attribs
), locus
),
313 expr_type (expr_kind
)
316 void accept_vis (HIRFullVisitor
&vis
) override
;
317 void accept_vis (HIRExpressionVisitor
&vis
) override
;
320 /* Use covariance to implement clone function as returning this object rather
322 NegationExpr
*clone_expr_impl () const override
324 return new NegationExpr (*this);
327 /* Use covariance to implement clone function as returning this object rather
329 NegationExpr
*clone_expr_without_block_impl () const override
331 return new NegationExpr (*this);
335 // Infix binary operators. +, -, *, /, %, &, |, ^, <<, >>
336 class ArithmeticOrLogicalExpr
: public OperatorExpr
339 using ExprType
= ArithmeticOrLogicalOperator
;
342 // Note: overloading trait specified in comments
345 std::unique_ptr
<Expr
> right_expr
;
348 std::string
as_string () const override
;
350 ExprType
get_expr_type () const { return expr_type
; }
352 // Constructor calls OperatorExpr's protected constructor
353 ArithmeticOrLogicalExpr (Analysis::NodeMapping mappings
,
354 std::unique_ptr
<Expr
> left_value
,
355 std::unique_ptr
<Expr
> right_value
,
356 ExprType expr_kind
, Location locus
)
357 : OperatorExpr (std::move (mappings
), std::move (left_value
),
358 AST::AttrVec (), locus
),
359 expr_type (expr_kind
), right_expr (std::move (right_value
))
361 // outer attributes not allowed
363 // Copy constructor - probably required due to unique pointer
364 ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr
const &other
)
365 : OperatorExpr (other
), expr_type (other
.expr_type
),
366 right_expr (other
.right_expr
->clone_expr ())
369 // Overload assignment operator
370 ArithmeticOrLogicalExpr
&operator= (ArithmeticOrLogicalExpr
const &other
)
372 OperatorExpr::operator= (other
);
373 // main_or_left_expr = other.main_or_left_expr->clone_expr();
374 right_expr
= other
.right_expr
->clone_expr ();
375 expr_type
= other
.expr_type
;
381 ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr
&&other
) = default;
382 ArithmeticOrLogicalExpr
&operator= (ArithmeticOrLogicalExpr
&&other
)
385 void accept_vis (HIRFullVisitor
&vis
) override
;
386 void accept_vis (HIRExpressionVisitor
&vis
) override
;
388 void visit_lhs (HIRFullVisitor
&vis
) { main_or_left_expr
->accept_vis (vis
); }
389 void visit_rhs (HIRFullVisitor
&vis
) { right_expr
->accept_vis (vis
); }
391 Expr
*get_lhs () { return main_or_left_expr
.get (); }
392 Expr
*get_rhs () { return right_expr
.get (); }
395 /* Use covariance to implement clone function as returning this object rather
397 ArithmeticOrLogicalExpr
*clone_expr_impl () const override
399 return new ArithmeticOrLogicalExpr (*this);
402 /* Use covariance to implement clone function as returning this object rather
404 ArithmeticOrLogicalExpr
*clone_expr_without_block_impl () const override
406 return new ArithmeticOrLogicalExpr (*this);
410 // Infix binary comparison operators. ==, !=, <, <=, >, >=
411 class ComparisonExpr
: public OperatorExpr
414 using ExprType
= ComparisonOperator
;
417 // Note: overloading trait specified in comments
420 std::unique_ptr
<Expr
> right_expr
;
423 std::string
as_string () const override
;
425 ExprType
get_expr_type () const { return expr_type
; }
427 // Constructor requires pointers for polymorphism
428 ComparisonExpr (Analysis::NodeMapping mappings
,
429 std::unique_ptr
<Expr
> left_value
,
430 std::unique_ptr
<Expr
> right_value
, ExprType comparison_kind
,
432 : OperatorExpr (std::move (mappings
), std::move (left_value
),
433 AST::AttrVec (), locus
),
434 expr_type (comparison_kind
), right_expr (std::move (right_value
))
436 // outer attributes not allowed
438 // Copy constructor also calls OperatorExpr's protected constructor
439 ComparisonExpr (ComparisonExpr
const &other
)
440 : OperatorExpr (other
), expr_type (other
.expr_type
),
441 right_expr (other
.right_expr
->clone_expr ())
444 // Overload assignment operator to deep copy
445 ComparisonExpr
&operator= (ComparisonExpr
const &other
)
447 OperatorExpr::operator= (other
);
448 // main_or_left_expr = other.main_or_left_expr->clone_expr();
449 right_expr
= other
.right_expr
->clone_expr ();
450 expr_type
= other
.expr_type
;
451 // outer_attrs = other.outer_attrs;
457 ComparisonExpr (ComparisonExpr
&&other
) = default;
458 ComparisonExpr
&operator= (ComparisonExpr
&&other
) = default;
460 void accept_vis (HIRFullVisitor
&vis
) override
;
461 void accept_vis (HIRExpressionVisitor
&vis
) override
;
463 Expr
*get_lhs () { return main_or_left_expr
.get (); }
464 Expr
*get_rhs () { return right_expr
.get (); }
466 ExprType
get_kind () { return expr_type
; }
468 /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
471 /* Use covariance to implement clone function as returning this object rather
473 ComparisonExpr
*clone_expr_impl () const override
475 return new ComparisonExpr (*this);
478 /* Use covariance to implement clone function as returning this object rather
480 ComparisonExpr
*clone_expr_without_block_impl () const override
482 return new ComparisonExpr (*this);
486 // Infix binary lazy boolean logical operators && and ||.
487 class LazyBooleanExpr
: public OperatorExpr
490 using ExprType
= LazyBooleanOperator
;
495 std::unique_ptr
<Expr
> right_expr
;
498 // Constructor calls OperatorExpr's protected constructor
499 LazyBooleanExpr (Analysis::NodeMapping mappings
,
500 std::unique_ptr
<Expr
> left_bool_expr
,
501 std::unique_ptr
<Expr
> right_bool_expr
, ExprType expr_kind
,
503 : OperatorExpr (std::move (mappings
), std::move (left_bool_expr
),
504 AST::AttrVec (), locus
),
505 expr_type (expr_kind
), right_expr (std::move (right_bool_expr
))
507 // outer attributes not allowed
509 // Copy constructor also calls OperatorExpr's protected constructor
510 LazyBooleanExpr (LazyBooleanExpr
const &other
)
511 : OperatorExpr (other
), expr_type (other
.expr_type
),
512 right_expr (other
.right_expr
->clone_expr ())
515 // Overload assignment operator to deep copy
516 LazyBooleanExpr
&operator= (LazyBooleanExpr
const &other
)
518 OperatorExpr::operator= (other
);
519 // main_or_left_expr = other.main_or_left_expr->clone_expr();
520 right_expr
= other
.right_expr
->clone_expr ();
521 expr_type
= other
.expr_type
;
527 LazyBooleanExpr (LazyBooleanExpr
&&other
) = default;
528 LazyBooleanExpr
&operator= (LazyBooleanExpr
&&other
) = default;
530 std::string
as_string () const override
;
532 ExprType
get_expr_type () const { return expr_type
; }
534 void accept_vis (HIRFullVisitor
&vis
) override
;
535 void accept_vis (HIRExpressionVisitor
&vis
) override
;
537 Expr
*get_lhs () { return main_or_left_expr
.get (); }
539 Expr
*get_rhs () { return right_expr
.get (); }
542 /* Use covariance to implement clone function as returning this object rather
544 LazyBooleanExpr
*clone_expr_impl () const override
546 return new LazyBooleanExpr (*this);
549 /* Use covariance to implement clone function as returning this object rather
551 LazyBooleanExpr
*clone_expr_without_block_impl () const override
553 return new LazyBooleanExpr (*this);
557 // Binary infix "as" chir expression.
558 class TypeCastExpr
: public OperatorExpr
560 std::unique_ptr
<Type
> type_to_convert_to
;
562 // Note: only certain type casts allowed, outlined in reference
564 std::string
as_string () const override
;
566 // Constructor requires calling protected constructor of OperatorExpr
567 TypeCastExpr (Analysis::NodeMapping mappings
,
568 std::unique_ptr
<Expr
> expr_to_cast
,
569 std::unique_ptr
<Type
> type_to_cast_to
, Location locus
)
570 : OperatorExpr (std::move (mappings
), std::move (expr_to_cast
),
571 AST::AttrVec (), locus
),
572 type_to_convert_to (std::move (type_to_cast_to
))
574 // outer attributes not allowed
576 // Copy constructor also requires calling protected constructor
577 TypeCastExpr (TypeCastExpr
const &other
)
578 : OperatorExpr (other
),
579 type_to_convert_to (other
.type_to_convert_to
->clone_type ())
582 // Overload assignment operator to deep copy
583 TypeCastExpr
&operator= (TypeCastExpr
const &other
)
585 OperatorExpr::operator= (other
);
586 // main_or_left_expr = other.main_or_left_expr->clone_expr();
587 type_to_convert_to
= other
.type_to_convert_to
->clone_type ();
592 // move constructors as not supported in c++03
593 TypeCastExpr (TypeCastExpr
&&other
) = default;
594 TypeCastExpr
&operator= (TypeCastExpr
&&other
) = default;
596 void accept_vis (HIRFullVisitor
&vis
) override
;
597 void accept_vis (HIRExpressionVisitor
&vis
) override
;
599 std::unique_ptr
<Expr
> &get_casted_expr ()
601 rust_assert (main_or_left_expr
!= nullptr);
602 return main_or_left_expr
;
605 std::unique_ptr
<Type
> &get_type_to_convert_to ()
607 rust_assert (type_to_convert_to
!= nullptr);
608 return type_to_convert_to
;
612 /* Use covariance to implement clone function as returning this object rather
614 TypeCastExpr
*clone_expr_impl () const override
616 return new TypeCastExpr (*this);
619 /* Use covariance to implement clone function as returning this object rather
621 TypeCastExpr
*clone_expr_without_block_impl () const override
623 return new TypeCastExpr (*this);
627 // Binary assignment expression.
628 class AssignmentExpr
: public OperatorExpr
630 std::unique_ptr
<Expr
> right_expr
;
633 std::string
as_string () const override
;
635 // Call OperatorExpr constructor to initialise left_expr
636 AssignmentExpr (Analysis::NodeMapping mappings
,
637 std::unique_ptr
<Expr
> value_to_assign_to
,
638 std::unique_ptr
<Expr
> value_to_assign
, Location locus
)
639 : OperatorExpr (std::move (mappings
), std::move (value_to_assign_to
),
640 AST::AttrVec (), locus
),
641 right_expr (std::move (value_to_assign
))
643 // outer attributes not allowed
645 // Call OperatorExpr constructor in copy constructor, as well as clone
646 AssignmentExpr (AssignmentExpr
const &other
)
647 : OperatorExpr (other
), right_expr (other
.right_expr
->clone_expr ())
650 // Overload assignment operator to clone unique_ptr right_expr
651 AssignmentExpr
&operator= (AssignmentExpr
const &other
)
653 OperatorExpr::operator= (other
);
654 // main_or_left_expr = other.main_or_left_expr->clone_expr();
655 right_expr
= other
.right_expr
->clone_expr ();
656 // outer_attrs = other.outer_attrs;
662 AssignmentExpr (AssignmentExpr
&&other
) = default;
663 AssignmentExpr
&operator= (AssignmentExpr
&&other
) = default;
665 void accept_vis (HIRFullVisitor
&vis
) override
;
666 void accept_vis (HIRExpressionVisitor
&vis
) override
;
668 void visit_lhs (HIRFullVisitor
&vis
) { main_or_left_expr
->accept_vis (vis
); }
669 void visit_rhs (HIRFullVisitor
&vis
) { right_expr
->accept_vis (vis
); }
671 Expr
*get_lhs () { return main_or_left_expr
.get (); }
672 Expr
*get_rhs () { return right_expr
.get (); }
675 /* Use covariance to implement clone function as returning this object rather
677 AssignmentExpr
*clone_expr_impl () const override
679 return new AssignmentExpr (*this);
682 /* Use covariance to implement clone function as returning this object rather
684 AssignmentExpr
*clone_expr_without_block_impl () const override
686 return new AssignmentExpr (*this);
690 class CompoundAssignmentExpr
: public OperatorExpr
693 using ExprType
= ArithmeticOrLogicalOperator
;
696 // Note: overloading trait specified in comments
698 std::unique_ptr
<Expr
> right_expr
;
701 std::string
as_string () const override
;
703 ExprType
get_expr_type () const { return expr_type
; }
705 // Use pointers in constructor to enable polymorphism
706 CompoundAssignmentExpr (Analysis::NodeMapping mappings
,
707 std::unique_ptr
<Expr
> value_to_assign_to
,
708 std::unique_ptr
<Expr
> value_to_assign
,
709 ExprType expr_kind
, Location locus
)
710 : OperatorExpr (std::move (mappings
), std::move (value_to_assign_to
),
711 AST::AttrVec (), locus
),
712 expr_type (expr_kind
), right_expr (std::move (value_to_assign
))
714 // outer attributes not allowed
716 // Have clone in copy constructor
717 CompoundAssignmentExpr (CompoundAssignmentExpr
const &other
)
718 : OperatorExpr (other
), expr_type (other
.expr_type
),
719 right_expr (other
.right_expr
->clone_expr ())
722 // Overload assignment operator to clone
723 CompoundAssignmentExpr
&operator= (CompoundAssignmentExpr
const &other
)
725 OperatorExpr::operator= (other
);
726 // main_or_left_expr = other.main_or_left_expr->clone_expr();
727 right_expr
= other
.right_expr
->clone_expr ();
728 expr_type
= other
.expr_type
;
729 // outer_attrs = other.outer_attrs;
735 CompoundAssignmentExpr (CompoundAssignmentExpr
&&other
) = default;
736 CompoundAssignmentExpr
&operator= (CompoundAssignmentExpr
&&other
) = default;
738 void accept_vis (HIRFullVisitor
&vis
) override
;
739 void accept_vis (HIRExpressionVisitor
&vis
) override
;
741 std::unique_ptr
<Expr
> &get_left_expr ()
743 rust_assert (main_or_left_expr
!= nullptr);
744 return main_or_left_expr
;
747 std::unique_ptr
<Expr
> &get_right_expr ()
749 rust_assert (right_expr
!= nullptr);
753 void visit_lhs (HIRFullVisitor
&vis
) { main_or_left_expr
->accept_vis (vis
); }
754 void visit_rhs (HIRFullVisitor
&vis
) { right_expr
->accept_vis (vis
); }
757 /* Use covariance to implement clone function as returning this object rather
759 CompoundAssignmentExpr
*clone_expr_without_block_impl () const override
761 return new CompoundAssignmentExpr (*this);
765 // Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
766 class GroupedExpr
: public ExprWithoutBlock
768 AST::AttrVec inner_attrs
;
769 std::unique_ptr
<Expr
> expr_in_parens
;
774 std::string
as_string () const override
;
776 AST::AttrVec
get_inner_attrs () const { return inner_attrs
; }
778 GroupedExpr (Analysis::NodeMapping mappings
,
779 std::unique_ptr
<Expr
> parenthesised_expr
,
780 AST::AttrVec inner_attribs
, AST::AttrVec outer_attribs
,
782 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
783 inner_attrs (std::move (inner_attribs
)),
784 expr_in_parens (std::move (parenthesised_expr
)), locus (locus
)
787 // Copy constructor includes clone for expr_in_parens
788 GroupedExpr (GroupedExpr
const &other
)
789 : ExprWithoutBlock (other
), inner_attrs (other
.inner_attrs
),
790 expr_in_parens (other
.expr_in_parens
->clone_expr ()), locus (other
.locus
)
793 // Overloaded assignment operator to clone expr_in_parens
794 GroupedExpr
&operator= (GroupedExpr
const &other
)
796 ExprWithoutBlock::operator= (other
);
797 inner_attrs
= other
.inner_attrs
;
798 expr_in_parens
= other
.expr_in_parens
->clone_expr ();
800 // outer_attrs = other.outer_attrs;
806 GroupedExpr (GroupedExpr
&&other
) = default;
807 GroupedExpr
&operator= (GroupedExpr
&&other
) = default;
809 Location
get_locus () const override final
{ return locus
; }
811 void accept_vis (HIRFullVisitor
&vis
) override
;
812 void accept_vis (HIRExpressionVisitor
&vis
) override
;
814 std::unique_ptr
<Expr
> &get_expr_in_parens ()
816 rust_assert (expr_in_parens
!= nullptr);
817 return expr_in_parens
;
820 ExprType
get_expression_type () const override final
822 return ExprType::Grouped
;
826 /* Use covariance to implement clone function as returning this object rather
828 GroupedExpr
*clone_expr_impl () const override
830 return new GroupedExpr (*this);
833 /* Use covariance to implement clone function as returning this object rather
835 GroupedExpr
*clone_expr_without_block_impl () const override
837 return new GroupedExpr (*this);
841 // Base array initialisation internal element representation thing (abstract)
852 ArrayElems (Analysis::NodeMapping mappings
) : mappings (mappings
){};
854 virtual ~ArrayElems () {}
856 // Unique pointer custom clone ArrayElems function
857 std::unique_ptr
<ArrayElems
> clone_array_elems () const
859 return std::unique_ptr
<ArrayElems
> (clone_array_elems_impl ());
862 virtual std::string
as_string () const = 0;
864 virtual void accept_vis (HIRFullVisitor
&vis
) = 0;
866 virtual ArrayExprType
get_array_expr_type () const = 0;
868 Analysis::NodeMapping
&get_mappings () { return mappings
; }
871 // pure virtual clone implementation
872 virtual ArrayElems
*clone_array_elems_impl () const = 0;
874 Analysis::NodeMapping mappings
;
877 // Value array elements
878 class ArrayElemsValues
: public ArrayElems
880 std::vector
<std::unique_ptr
<Expr
> > values
;
882 // TODO: should this store location data?
885 ArrayElemsValues (Analysis::NodeMapping mappings
,
886 std::vector
<std::unique_ptr
<Expr
> > elems
)
887 : ArrayElems (mappings
), values (std::move (elems
))
890 // copy constructor with vector clone
891 ArrayElemsValues (ArrayElemsValues
const &other
) : ArrayElems (other
)
893 values
.reserve (other
.values
.size ());
894 for (const auto &e
: other
.values
)
895 values
.push_back (e
->clone_expr ());
898 // overloaded assignment operator with vector clone
899 ArrayElemsValues
&operator= (ArrayElemsValues
const &other
)
901 values
.reserve (other
.values
.size ());
902 for (const auto &e
: other
.values
)
903 values
.push_back (e
->clone_expr ());
909 ArrayElemsValues (ArrayElemsValues
&&other
) = default;
910 ArrayElemsValues
&operator= (ArrayElemsValues
&&other
) = default;
912 std::string
as_string () const override
;
914 void accept_vis (HIRFullVisitor
&vis
) override
;
916 size_t get_num_elements () const { return values
.size (); }
918 std::vector
<std::unique_ptr
<Expr
> > &get_values () { return values
; }
920 ArrayElems::ArrayExprType
get_array_expr_type () const override final
922 return ArrayElems::ArrayExprType::VALUES
;
926 ArrayElemsValues
*clone_array_elems_impl () const override
928 return new ArrayElemsValues (*this);
932 // Copied array element and number of copies
933 class ArrayElemsCopied
: public ArrayElems
935 std::unique_ptr
<Expr
> elem_to_copy
;
936 std::unique_ptr
<Expr
> num_copies
;
939 // Constructor requires pointers for polymorphism
940 ArrayElemsCopied (Analysis::NodeMapping mappings
,
941 std::unique_ptr
<Expr
> copied_elem
,
942 std::unique_ptr
<Expr
> copy_amount
)
943 : ArrayElems (mappings
), elem_to_copy (std::move (copied_elem
)),
944 num_copies (std::move (copy_amount
))
947 // Copy constructor required due to unique_ptr - uses custom clone
948 ArrayElemsCopied (ArrayElemsCopied
const &other
)
949 : ArrayElems (other
), elem_to_copy (other
.elem_to_copy
->clone_expr ()),
950 num_copies (other
.num_copies
->clone_expr ())
953 // Overloaded assignment operator for deep copying
954 ArrayElemsCopied
&operator= (ArrayElemsCopied
const &other
)
956 elem_to_copy
= other
.elem_to_copy
->clone_expr ();
957 num_copies
= other
.num_copies
->clone_expr ();
963 ArrayElemsCopied (ArrayElemsCopied
&&other
) = default;
964 ArrayElemsCopied
&operator= (ArrayElemsCopied
&&other
) = default;
966 std::string
as_string () const override
;
968 void accept_vis (HIRFullVisitor
&vis
) override
;
970 Expr
*get_elem_to_copy () { return elem_to_copy
.get (); }
972 Expr
*get_num_copies_expr () { return num_copies
.get (); }
974 ArrayElems::ArrayExprType
get_array_expr_type () const override final
976 return ArrayElems::ArrayExprType::COPIED
;
980 ArrayElemsCopied
*clone_array_elems_impl () const override
982 return new ArrayElemsCopied (*this);
986 // Array definition-ish expression
987 class ArrayExpr
: public ExprWithoutBlock
989 AST::AttrVec inner_attrs
;
990 std::unique_ptr
<ArrayElems
> internal_elements
;
995 std::string
as_string () const override
;
997 AST::AttrVec
get_inner_attrs () const { return inner_attrs
; }
999 // Returns whether array expr has array elems or if it is just empty.
1000 bool has_array_elems () const { return internal_elements
!= nullptr; }
1002 // Constructor requires ArrayElems pointer
1003 ArrayExpr (Analysis::NodeMapping mappings
,
1004 std::unique_ptr
<ArrayElems
> array_elems
,
1005 AST::AttrVec inner_attribs
, AST::AttrVec outer_attribs
,
1007 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1008 inner_attrs (std::move (inner_attribs
)),
1009 internal_elements (std::move (array_elems
)), locus (locus
)
1012 // Copy constructor requires cloning ArrayElems for polymorphism to hold
1013 ArrayExpr (ArrayExpr
const &other
)
1014 : ExprWithoutBlock (other
), inner_attrs (other
.inner_attrs
),
1017 if (other
.has_array_elems ())
1018 internal_elements
= other
.internal_elements
->clone_array_elems ();
1021 // Overload assignment operator to clone internal_elements
1022 ArrayExpr
&operator= (ArrayExpr
const &other
)
1024 ExprWithoutBlock::operator= (other
);
1025 inner_attrs
= other
.inner_attrs
;
1026 if (other
.has_array_elems ())
1027 internal_elements
= other
.internal_elements
->clone_array_elems ();
1028 locus
= other
.locus
;
1029 // outer_attrs = other.outer_attrs;
1034 // move constructors
1035 ArrayExpr (ArrayExpr
&&other
) = default;
1036 ArrayExpr
&operator= (ArrayExpr
&&other
) = default;
1038 Location
get_locus () const override final
{ return locus
; }
1040 void accept_vis (HIRFullVisitor
&vis
) override
;
1041 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1043 ArrayElems
*get_internal_elements () { return internal_elements
.get (); };
1045 ExprType
get_expression_type () const override final
1047 return ExprType::Array
;
1051 /* Use covariance to implement clone function as returning this object rather
1053 ArrayExpr
*clone_expr_impl () const override
{ return new ArrayExpr (*this); }
1055 /* Use covariance to implement clone function as returning this object rather
1057 ArrayExpr
*clone_expr_without_block_impl () const override
1059 return new ArrayExpr (*this);
1063 class ArrayIndexExpr
: public ExprWithoutBlock
1065 std::unique_ptr
<Expr
> array_expr
;
1066 std::unique_ptr
<Expr
> index_expr
;
1071 std::string
as_string () const override
;
1073 ArrayIndexExpr (Analysis::NodeMapping mappings
,
1074 std::unique_ptr
<Expr
> array_expr
,
1075 std::unique_ptr
<Expr
> array_index_expr
,
1076 AST::AttrVec outer_attribs
, Location locus
)
1077 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1078 array_expr (std::move (array_expr
)),
1079 index_expr (std::move (array_index_expr
)), locus (locus
)
1082 // Copy constructor requires special cloning due to unique_ptr
1083 ArrayIndexExpr (ArrayIndexExpr
const &other
)
1084 : ExprWithoutBlock (other
), array_expr (other
.array_expr
->clone_expr ()),
1085 index_expr (other
.index_expr
->clone_expr ()), locus (other
.locus
)
1088 // Overload assignment operator to clone unique_ptrs
1089 ArrayIndexExpr
&operator= (ArrayIndexExpr
const &other
)
1091 ExprWithoutBlock::operator= (other
);
1092 array_expr
= other
.array_expr
->clone_expr ();
1093 index_expr
= other
.index_expr
->clone_expr ();
1094 // outer_attrs = other.outer_attrs;
1095 locus
= other
.locus
;
1100 // move constructors
1101 ArrayIndexExpr (ArrayIndexExpr
&&other
) = default;
1102 ArrayIndexExpr
&operator= (ArrayIndexExpr
&&other
) = default;
1104 Location
get_locus () const override final
{ return locus
; }
1106 void accept_vis (HIRFullVisitor
&vis
) override
;
1107 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1109 Expr
*get_array_expr () { return array_expr
.get (); }
1110 Expr
*get_index_expr () { return index_expr
.get (); }
1112 ExprType
get_expression_type () const override final
1114 return ExprType::ArrayIndex
;
1118 /* Use covariance to implement clone function as returning this object rather
1120 ArrayIndexExpr
*clone_expr_impl () const override
1122 return new ArrayIndexExpr (*this);
1125 /* Use covariance to implement clone function as returning this object rather
1127 ArrayIndexExpr
*clone_expr_without_block_impl () const override
1129 return new ArrayIndexExpr (*this);
1133 // HIR representation of a tuple
1134 class TupleExpr
: public ExprWithoutBlock
1136 AST::AttrVec inner_attrs
;
1138 std::vector
<std::unique_ptr
<Expr
> > tuple_elems
;
1139 // replaces (inlined version of) TupleElements
1144 std::string
as_string () const override
;
1146 AST::AttrVec
get_inner_attrs () const { return inner_attrs
; }
1148 TupleExpr (Analysis::NodeMapping mappings
,
1149 std::vector
<std::unique_ptr
<Expr
> > tuple_elements
,
1150 AST::AttrVec inner_attribs
, AST::AttrVec outer_attribs
,
1152 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1153 inner_attrs (std::move (inner_attribs
)),
1154 tuple_elems (std::move (tuple_elements
)), locus (locus
)
1157 // copy constructor with vector clone
1158 TupleExpr (TupleExpr
const &other
)
1159 : ExprWithoutBlock (other
), inner_attrs (other
.inner_attrs
),
1162 tuple_elems
.reserve (other
.tuple_elems
.size ());
1163 for (const auto &e
: other
.tuple_elems
)
1164 tuple_elems
.push_back (e
->clone_expr ());
1167 // overloaded assignment operator to vector clone
1168 TupleExpr
&operator= (TupleExpr
const &other
)
1170 ExprWithoutBlock::operator= (other
);
1171 inner_attrs
= other
.inner_attrs
;
1172 locus
= other
.locus
;
1174 tuple_elems
.reserve (other
.tuple_elems
.size ());
1175 for (const auto &e
: other
.tuple_elems
)
1176 tuple_elems
.push_back (e
->clone_expr ());
1181 // move constructors
1182 TupleExpr (TupleExpr
&&other
) = default;
1183 TupleExpr
&operator= (TupleExpr
&&other
) = default;
1185 /* Note: syntactically, can disambiguate single-element tuple from parens with
1186 * comma, i.e. (0,) rather than (0) */
1188 Location
get_locus () const override final
{ return locus
; }
1190 void accept_vis (HIRFullVisitor
&vis
) override
;
1191 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1193 const std::vector
<std::unique_ptr
<Expr
> > &get_tuple_elems () const
1197 std::vector
<std::unique_ptr
<Expr
> > &get_tuple_elems ()
1202 bool is_unit () const { return tuple_elems
.size () == 0; }
1204 ExprType
get_expression_type () const override final
1206 return ExprType::Tuple
;
1210 /* Use covariance to implement clone function as returning this object rather
1212 TupleExpr
*clone_expr_impl () const override
{ return new TupleExpr (*this); }
1214 /* Use covariance to implement clone function as returning this object rather
1216 TupleExpr
*clone_expr_without_block_impl () const override
1218 return new TupleExpr (*this);
1222 class TupleIndexExpr
: public ExprWithoutBlock
1224 std::unique_ptr
<Expr
> tuple_expr
;
1225 TupleIndex tuple_index
;
1229 std::string
as_string () const override
;
1231 TupleIndex
get_tuple_index () const { return tuple_index
; }
1233 TupleIndexExpr (Analysis::NodeMapping mappings
,
1234 std::unique_ptr
<Expr
> tuple_expr
, TupleIndex index
,
1235 AST::AttrVec outer_attribs
, Location locus
)
1236 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1237 tuple_expr (std::move (tuple_expr
)), tuple_index (index
), locus (locus
)
1240 // Copy constructor requires a clone for tuple_expr
1241 TupleIndexExpr (TupleIndexExpr
const &other
)
1242 : ExprWithoutBlock (other
), tuple_expr (other
.tuple_expr
->clone_expr ()),
1243 tuple_index (other
.tuple_index
), locus (other
.locus
)
1246 // Overload assignment operator in order to clone
1247 TupleIndexExpr
&operator= (TupleIndexExpr
const &other
)
1249 ExprWithoutBlock::operator= (other
);
1250 tuple_expr
= other
.tuple_expr
->clone_expr ();
1251 tuple_index
= other
.tuple_index
;
1252 locus
= other
.locus
;
1253 // outer_attrs = other.outer_attrs;
1258 // move constructors
1259 TupleIndexExpr (TupleIndexExpr
&&other
) = default;
1260 TupleIndexExpr
&operator= (TupleIndexExpr
&&other
) = default;
1262 Location
get_locus () const override final
{ return locus
; }
1264 void accept_vis (HIRFullVisitor
&vis
) override
;
1265 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1267 std::unique_ptr
<Expr
> &get_tuple_expr ()
1269 rust_assert (tuple_expr
!= nullptr);
1273 ExprType
get_expression_type () const override final
1275 return ExprType::TupleIdx
;
1279 /* Use covariance to implement clone function as returning this object rather
1281 TupleIndexExpr
*clone_expr_impl () const override
1283 return new TupleIndexExpr (*this);
1286 /* Use covariance to implement clone function as returning this object rather
1288 TupleIndexExpr
*clone_expr_without_block_impl () const override
1290 return new TupleIndexExpr (*this);
1294 // Base struct/tuple/union value creator HIR node (abstract)
1295 class StructExpr
: public ExprWithoutBlock
1298 PathInExpression struct_name
;
1300 // Protected constructor to allow initialising struct_name
1301 StructExpr (Analysis::NodeMapping mappings
, PathInExpression struct_path
,
1302 AST::AttrVec outer_attribs
)
1303 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1304 struct_name (std::move (struct_path
))
1308 PathInExpression
&get_struct_name () { return struct_name
; }
1310 std::string
as_string () const override
;
1312 ExprType
get_expression_type () const override final
1314 return ExprType::Struct
;
1318 // Actual HIR node of the struct creator (with no fields). Not abstract!
1319 class StructExprStruct
: public StructExpr
1321 AST::AttrVec inner_attrs
;
1326 std::string
as_string () const override
;
1328 AST::AttrVec
get_inner_attrs () const { return inner_attrs
; }
1330 // Constructor has to call protected constructor of base class
1331 StructExprStruct (Analysis::NodeMapping mappings
,
1332 PathInExpression struct_path
, AST::AttrVec inner_attribs
,
1333 AST::AttrVec outer_attribs
, Location locus
)
1334 : StructExpr (std::move (mappings
), std::move (struct_path
),
1335 std::move (outer_attribs
)),
1336 inner_attrs (std::move (inner_attribs
)), locus (locus
)
1339 Location
get_locus () const override final
{ return locus
; }
1341 void accept_vis (HIRFullVisitor
&vis
) override
;
1342 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1345 /* Use covariance to implement clone function as returning this object rather
1347 StructExprStruct
*clone_expr_impl () const override
1349 return new StructExprStruct (*this);
1352 /* Use covariance to implement clone function as returning this object rather
1354 StructExprStruct
*clone_expr_without_block_impl () const override
1356 return new StructExprStruct (*this);
1360 /* HIR node representing expression used to fill a struct's fields from another
1365 std::unique_ptr
<Expr
> base_struct
;
1367 // TODO: should this store location data?
1368 StructBase (std::unique_ptr
<Expr
> base_struct_ptr
)
1369 : base_struct (std::move (base_struct_ptr
))
1372 // Copy constructor requires clone
1373 StructBase (StructBase
const &other
)
1375 /* HACK: gets around base_struct pointer being null (e.g. if no struct base
1377 if (other
.base_struct
!= nullptr)
1378 other
.base_struct
->clone_expr ();
1382 ~StructBase () = default;
1384 // Overload assignment operator to clone base_struct
1385 StructBase
&operator= (StructBase
const &other
)
1387 base_struct
= other
.base_struct
->clone_expr ();
1392 // move constructors
1393 StructBase (StructBase
&&other
) = default;
1394 StructBase
&operator= (StructBase
&&other
) = default;
1396 // Returns a null expr-ed StructBase - error state
1397 static StructBase
error () { return StructBase (nullptr); }
1399 // Returns whether StructBase is in error state
1400 bool is_invalid () const { return base_struct
== nullptr; }
1402 std::string
as_string () const;
1404 Expr
*get_base () { return base_struct
.get (); }
1407 /* Base HIR node for a single struct expression field (in struct instance
1408 * creation) - abstract */
1409 class StructExprField
1412 enum StructExprFieldKind
1419 virtual ~StructExprField () {}
1421 // Unique pointer custom clone function
1422 std::unique_ptr
<StructExprField
> clone_struct_expr_field () const
1424 return std::unique_ptr
<StructExprField
> (clone_struct_expr_field_impl ());
1427 virtual std::string
as_string () const = 0;
1429 virtual void accept_vis (HIRFullVisitor
&vis
) = 0;
1430 virtual void accept_vis (HIRExpressionVisitor
&vis
) = 0;
1432 Analysis::NodeMapping
&get_mappings () { return mappings
; }
1434 Location
get_locus () { return locus
; }
1436 virtual StructExprFieldKind
get_kind () const = 0;
1439 // pure virtual clone implementation
1440 virtual StructExprField
*clone_struct_expr_field_impl () const = 0;
1442 StructExprField (Analysis::NodeMapping mapping
, Location locus
)
1443 : mappings (mapping
), locus (locus
)
1446 Analysis::NodeMapping mappings
;
1450 // Identifier-only variant of StructExprField HIR node
1451 class StructExprFieldIdentifier
: public StructExprField
1454 Identifier field_name
;
1456 // TODO: should this store location data?
1458 StructExprFieldIdentifier (Analysis::NodeMapping mapping
,
1459 Identifier field_identifier
, Location locus
)
1460 : StructExprField (mapping
, locus
),
1461 field_name (std::move (field_identifier
))
1464 std::string
as_string () const override
{ return field_name
; }
1466 void accept_vis (HIRFullVisitor
&vis
) override
;
1467 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1469 Identifier
get_field_name () const { return field_name
; }
1471 StructExprFieldKind
get_kind () const override
1473 return StructExprFieldKind::IDENTIFIER
;
1477 /* Use covariance to implement clone function as returning this object rather
1479 StructExprFieldIdentifier
*clone_struct_expr_field_impl () const override
1481 return new StructExprFieldIdentifier (*this);
1485 /* Base HIR node for a single struct expression field with an assigned value -
1487 class StructExprFieldWithVal
: public StructExprField
1489 std::unique_ptr
<Expr
> value
;
1492 StructExprFieldWithVal (Analysis::NodeMapping mapping
,
1493 std::unique_ptr
<Expr
> field_value
, Location locus
)
1494 : StructExprField (mapping
, locus
), value (std::move (field_value
))
1497 // Copy constructor requires clone
1498 StructExprFieldWithVal (StructExprFieldWithVal
const &other
)
1499 : StructExprField (other
.mappings
, other
.locus
),
1500 value (other
.value
->clone_expr ())
1503 // Overload assignment operator to clone unique_ptr
1504 StructExprFieldWithVal
&operator= (StructExprFieldWithVal
const &other
)
1506 value
= other
.value
->clone_expr ();
1507 mappings
= other
.mappings
;
1508 locus
= other
.locus
;
1513 // move constructors
1514 StructExprFieldWithVal (StructExprFieldWithVal
&&other
) = default;
1515 StructExprFieldWithVal
&operator= (StructExprFieldWithVal
&&other
) = default;
1518 std::string
as_string () const override
;
1520 Expr
*get_value () { return value
.get (); }
1523 // Identifier and value variant of StructExprField HIR node
1524 class StructExprFieldIdentifierValue
: public StructExprFieldWithVal
1527 Identifier field_name
;
1529 // TODO: should this store location data?
1531 StructExprFieldIdentifierValue (Analysis::NodeMapping mapping
,
1532 Identifier field_identifier
,
1533 std::unique_ptr
<Expr
> field_value
,
1535 : StructExprFieldWithVal (mapping
, std::move (field_value
), locus
),
1536 field_name (std::move (field_identifier
))
1539 std::string
as_string () const override
;
1541 void accept_vis (HIRFullVisitor
&vis
) override
;
1542 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1544 StructExprFieldKind
get_kind () const override
1546 return StructExprFieldKind::IDENTIFIER_VALUE
;
1550 /* Use covariance to implement clone function as returning this object rather
1552 StructExprFieldIdentifierValue
*clone_struct_expr_field_impl () const override
1554 return new StructExprFieldIdentifierValue (*this);
1558 // Tuple index and value variant of StructExprField HIR node
1559 class StructExprFieldIndexValue
: public StructExprFieldWithVal
1564 // TODO: should this store location data?
1566 StructExprFieldIndexValue (Analysis::NodeMapping mapping
,
1567 TupleIndex tuple_index
,
1568 std::unique_ptr
<Expr
> field_value
, Location locus
)
1569 : StructExprFieldWithVal (mapping
, std::move (field_value
), locus
),
1573 std::string
as_string () const override
;
1575 TupleIndex
get_tuple_index () const { return index
; };
1577 void accept_vis (HIRFullVisitor
&vis
) override
;
1578 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1580 StructExprFieldKind
get_kind () const override
1582 return StructExprFieldKind::INDEX_VALUE
;
1586 /* Use covariance to implement clone function as returning this object rather
1588 StructExprFieldIndexValue
*clone_struct_expr_field_impl () const override
1590 return new StructExprFieldIndexValue (*this);
1594 // HIR node of a struct creator with fields
1595 class StructExprStructFields
: public StructExprStruct
1598 // std::vector<StructExprField> fields;
1599 std::vector
<std::unique_ptr
<StructExprField
> > fields
;
1601 // bool has_struct_base;
1602 // FIXME make unique_ptr
1603 StructBase
*struct_base
;
1605 // For unions there is just one field, the index
1606 // is set when type checking
1607 int union_index
= -1;
1609 std::string
as_string () const override
;
1611 bool has_struct_base () const { return struct_base
!= nullptr; }
1613 // Constructor for StructExprStructFields when no struct base is used
1614 StructExprStructFields (
1615 Analysis::NodeMapping mappings
, PathInExpression struct_path
,
1616 std::vector
<std::unique_ptr
<StructExprField
> > expr_fields
, Location locus
,
1617 StructBase
*base_struct
, AST::AttrVec inner_attribs
= AST::AttrVec (),
1618 AST::AttrVec outer_attribs
= AST::AttrVec ())
1619 : StructExprStruct (std::move (mappings
), std::move (struct_path
),
1620 std::move (inner_attribs
), std::move (outer_attribs
),
1622 fields (std::move (expr_fields
)), struct_base (base_struct
)
1625 // copy constructor with vector clone
1626 StructExprStructFields (StructExprStructFields
const &other
)
1627 : StructExprStruct (other
), struct_base (other
.struct_base
),
1628 union_index (other
.union_index
)
1630 fields
.reserve (other
.fields
.size ());
1631 for (const auto &e
: other
.fields
)
1632 fields
.push_back (e
->clone_struct_expr_field ());
1635 // overloaded assignment operator with vector clone
1636 StructExprStructFields
&operator= (StructExprStructFields
const &other
)
1638 StructExprStruct::operator= (other
);
1639 struct_base
= other
.struct_base
;
1640 union_index
= other
.union_index
;
1642 fields
.reserve (other
.fields
.size ());
1643 for (const auto &e
: other
.fields
)
1644 fields
.push_back (e
->clone_struct_expr_field ());
1649 // move constructors
1650 StructExprStructFields (StructExprStructFields
&&other
) = default;
1651 StructExprStructFields
&operator= (StructExprStructFields
&&other
) = default;
1653 void accept_vis (HIRFullVisitor
&vis
) override
;
1654 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1656 std::vector
<std::unique_ptr
<StructExprField
> > &get_fields ()
1661 const std::vector
<std::unique_ptr
<StructExprField
> > &get_fields () const
1666 void set_fields_as_owner (
1667 std::vector
<std::unique_ptr
<StructExprField
> > new_fields
)
1669 fields
= std::move (new_fields
);
1673 /* Use covariance to implement clone function as returning this object rather
1675 StructExprStructFields
*clone_expr_impl () const override
1677 return new StructExprStructFields (*this);
1680 /* Use covariance to implement clone function as returning this object rather
1682 StructExprStructFields
*clone_expr_without_block_impl () const override
1684 return new StructExprStructFields (*this);
1688 // HIR node of the functional update struct creator
1689 class StructExprStructBase
: public StructExprStruct
1691 StructBase struct_base
;
1694 std::string
as_string () const override
;
1696 /*inline StructBase get_struct_base() const {
1700 StructExprStructBase (Analysis::NodeMapping mappings
,
1701 PathInExpression struct_path
, StructBase base_struct
,
1702 AST::AttrVec inner_attribs
, AST::AttrVec outer_attribs
,
1704 : StructExprStruct (std::move (mappings
), std::move (struct_path
),
1705 std::move (inner_attribs
), std::move (outer_attribs
),
1707 struct_base (std::move (base_struct
))
1710 void accept_vis (HIRFullVisitor
&vis
) override
;
1711 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1713 StructBase
*get_struct_base () { return &struct_base
; }
1716 /* Use covariance to implement clone function as returning this object rather
1718 StructExprStructBase
*clone_expr_impl () const override
1720 return new StructExprStructBase (*this);
1723 /* Use covariance to implement clone function as returning this object rather
1725 StructExprStructBase
*clone_expr_without_block_impl () const override
1727 return new StructExprStructBase (*this);
1731 // Function call expression HIR node
1732 class CallExpr
: public ExprWithoutBlock
1734 std::unique_ptr
<Expr
> function
;
1735 std::vector
<std::unique_ptr
<Expr
> > params
;
1739 std::string
as_string () const override
;
1741 CallExpr (Analysis::NodeMapping mappings
, std::unique_ptr
<Expr
> function_expr
,
1742 std::vector
<std::unique_ptr
<Expr
> > function_params
,
1743 AST::AttrVec outer_attribs
, Location locus
)
1744 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1745 function (std::move (function_expr
)),
1746 params (std::move (function_params
)), locus (locus
)
1749 // copy constructor requires clone
1750 CallExpr (CallExpr
const &other
)
1751 : ExprWithoutBlock (other
), function (other
.function
->clone_expr ()),
1753 /*, params(other.params),*/ {
1754 params
.reserve (other
.params
.size ());
1755 for (const auto &e
: other
.params
)
1756 params
.push_back (e
->clone_expr ());
1759 // Overload assignment operator to clone
1760 CallExpr
&operator= (CallExpr
const &other
)
1762 ExprWithoutBlock::operator= (other
);
1763 function
= other
.function
->clone_expr ();
1764 locus
= other
.locus
;
1765 // params = other.params;
1766 // outer_attrs = other.outer_attrs;
1768 params
.reserve (other
.params
.size ());
1769 for (const auto &e
: other
.params
)
1770 params
.push_back (e
->clone_expr ());
1775 // move constructors
1776 CallExpr (CallExpr
&&other
) = default;
1777 CallExpr
&operator= (CallExpr
&&other
) = default;
1779 // Returns whether function call has parameters.
1780 bool has_params () const { return !params
.empty (); }
1782 Location
get_locus () const override final
{ return locus
; }
1784 void accept_vis (HIRFullVisitor
&vis
) override
;
1785 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1787 Expr
*get_fnexpr () { return function
.get (); }
1789 size_t num_params () const { return params
.size (); }
1791 std::vector
<std::unique_ptr
<Expr
> > &get_arguments () { return params
; }
1793 const std::vector
<std::unique_ptr
<Expr
> > &get_arguments () const
1798 ExprType
get_expression_type () const override final
1800 return ExprType::Call
;
1804 /* Use covariance to implement clone function as returning this object rather
1806 CallExpr
*clone_expr_impl () const override
{ return new CallExpr (*this); }
1808 /* Use covariance to implement clone function as returning this object rather
1810 CallExpr
*clone_expr_without_block_impl () const override
1812 return new CallExpr (*this);
1816 // Method call expression HIR node
1817 class MethodCallExpr
: public ExprWithoutBlock
1819 std::unique_ptr
<Expr
> receiver
;
1820 PathExprSegment method_name
;
1821 std::vector
<std::unique_ptr
<Expr
> > params
;
1825 std::string
as_string () const override
;
1827 MethodCallExpr (Analysis::NodeMapping mappings
,
1828 std::unique_ptr
<Expr
> call_receiver
,
1829 PathExprSegment method_path
,
1830 std::vector
<std::unique_ptr
<Expr
> > method_params
,
1831 AST::AttrVec outer_attribs
, Location locus
)
1832 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1833 receiver (std::move (call_receiver
)),
1834 method_name (std::move (method_path
)), params (std::move (method_params
)),
1838 // copy constructor required due to cloning
1839 MethodCallExpr (MethodCallExpr
const &other
)
1840 : ExprWithoutBlock (other
), receiver (other
.receiver
->clone_expr ()),
1841 method_name (other
.method_name
), locus (other
.locus
)
1842 /*, params(other.params),*/ {
1843 params
.reserve (other
.params
.size ());
1844 for (const auto &e
: other
.params
)
1845 params
.push_back (e
->clone_expr ());
1848 // Overload assignment operator to clone receiver object
1849 MethodCallExpr
&operator= (MethodCallExpr
const &other
)
1851 ExprWithoutBlock::operator= (other
);
1852 receiver
= other
.receiver
->clone_expr ();
1853 method_name
= other
.method_name
;
1854 locus
= other
.locus
;
1855 // params = other.params;
1856 // outer_attrs = other.outer_attrs;
1858 params
.reserve (other
.params
.size ());
1859 for (const auto &e
: other
.params
)
1860 params
.push_back (e
->clone_expr ());
1865 // move constructors
1866 MethodCallExpr (MethodCallExpr
&&other
) = default;
1867 MethodCallExpr
&operator= (MethodCallExpr
&&other
) = default;
1869 Location
get_locus () const override final
{ return locus
; }
1871 void accept_vis (HIRFullVisitor
&vis
) override
;
1872 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1874 std::unique_ptr
<Expr
> &get_receiver () { return receiver
; }
1876 PathExprSegment
get_method_name () const { return method_name
; };
1878 size_t num_params () const { return params
.size (); }
1880 std::vector
<std::unique_ptr
<Expr
> > &get_arguments () { return params
; }
1882 const std::vector
<std::unique_ptr
<Expr
> > &get_arguments () const
1887 ExprType
get_expression_type () const override final
1889 return ExprType::MethodCall
;
1893 /* Use covariance to implement clone function as returning this object rather
1895 MethodCallExpr
*clone_expr_impl () const override
1897 return new MethodCallExpr (*this);
1900 /* Use covariance to implement clone function as returning this object rather
1902 MethodCallExpr
*clone_expr_without_block_impl () const override
1904 return new MethodCallExpr (*this);
1908 // aka FieldExpression
1909 // Struct or union field access expression HIR node
1910 class FieldAccessExpr
: public ExprWithoutBlock
1912 std::unique_ptr
<Expr
> receiver
;
1918 std::string
as_string () const override
;
1920 FieldAccessExpr (Analysis::NodeMapping mappings
,
1921 std::unique_ptr
<Expr
> field_access_receiver
,
1922 Identifier field_name
, AST::AttrVec outer_attribs
,
1924 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
1925 receiver (std::move (field_access_receiver
)),
1926 field (std::move (field_name
)), locus (locus
)
1929 // Copy constructor required due to unique_ptr cloning
1930 FieldAccessExpr (FieldAccessExpr
const &other
)
1931 : ExprWithoutBlock (other
), receiver (other
.receiver
->clone_expr ()),
1932 field (other
.field
), locus (other
.locus
)
1935 // Overload assignment operator to clone unique_ptr
1936 FieldAccessExpr
&operator= (FieldAccessExpr
const &other
)
1938 ExprWithoutBlock::operator= (other
);
1939 receiver
= other
.receiver
->clone_expr ();
1940 field
= other
.field
;
1941 locus
= other
.locus
;
1942 // outer_attrs = other.outer_attrs;
1947 // move constructors
1948 FieldAccessExpr (FieldAccessExpr
&&other
) = default;
1949 FieldAccessExpr
&operator= (FieldAccessExpr
&&other
) = default;
1951 Location
get_locus () const override final
{ return locus
; }
1953 void accept_vis (HIRFullVisitor
&vis
) override
;
1954 void accept_vis (HIRExpressionVisitor
&vis
) override
;
1956 std::unique_ptr
<Expr
> &get_receiver_expr ()
1958 rust_assert (receiver
!= nullptr);
1962 Identifier
get_field_name () const { return field
; }
1964 ExprType
get_expression_type () const override final
1966 return ExprType::FieldAccess
;
1970 /* Use covariance to implement clone function as returning this object rather
1972 FieldAccessExpr
*clone_expr_impl () const override
1974 return new FieldAccessExpr (*this);
1977 /* Use covariance to implement clone function as returning this object rather
1979 FieldAccessExpr
*clone_expr_without_block_impl () const override
1981 return new FieldAccessExpr (*this);
1985 // Closure parameter data structure
1989 std::unique_ptr
<Pattern
> pattern
;
1991 // bool has_type_given;
1992 std::unique_ptr
<Type
> type
;
1994 // TODO: should this store location data?
1997 // Returns whether the type of the parameter has been given.
1998 bool has_type_given () const { return type
!= nullptr; }
2000 // Constructor for closure parameter
2001 ClosureParam (std::unique_ptr
<Pattern
> param_pattern
,
2002 std::unique_ptr
<Type
> param_type
= nullptr)
2003 : pattern (std::move (param_pattern
)), type (std::move (param_type
))
2006 // Copy constructor required due to cloning as a result of unique_ptrs
2007 ClosureParam (ClosureParam
const &other
)
2008 : pattern (other
.pattern
->clone_pattern ())
2010 // guard to protect from null pointer dereference
2011 if (other
.type
!= nullptr)
2012 type
= other
.type
->clone_type ();
2015 ~ClosureParam () = default;
2017 // Assignment operator must be overloaded to clone as well
2018 ClosureParam
&operator= (ClosureParam
const &other
)
2020 pattern
= other
.pattern
->clone_pattern ();
2021 type
= other
.type
->clone_type ();
2026 // move constructors
2027 ClosureParam (ClosureParam
&&other
) = default;
2028 ClosureParam
&operator= (ClosureParam
&&other
) = default;
2030 // Returns whether closure parameter is in an error state.
2031 bool is_error () const { return pattern
== nullptr; }
2033 // Creates an error state closure parameter.
2034 static ClosureParam
create_error () { return ClosureParam (nullptr); }
2036 std::string
as_string () const;
2039 // Base closure definition expression HIR node - abstract
2040 class ClosureExpr
: public ExprWithoutBlock
2043 std::vector
<ClosureParam
> params
;
2047 ClosureExpr (Analysis::NodeMapping mappings
,
2048 std::vector
<ClosureParam
> closure_params
, bool has_move
,
2049 AST::AttrVec outer_attribs
, Location locus
)
2050 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
2051 has_move (has_move
), params (std::move (closure_params
)), locus (locus
)
2055 std::string
as_string () const override
;
2057 Location
get_locus () const override final
{ return locus
; }
2059 ExprType
get_expression_type () const override final
2061 return ExprType::Closure
;
2065 // Represents a non-type-specified closure expression HIR node
2066 class ClosureExprInner
: public ClosureExpr
2068 std::unique_ptr
<Expr
> closure_inner
;
2071 std::string
as_string () const override
;
2073 // Constructor for a ClosureExprInner
2074 ClosureExprInner (Analysis::NodeMapping mappings
,
2075 std::unique_ptr
<Expr
> closure_inner_expr
,
2076 std::vector
<ClosureParam
> closure_params
, Location locus
,
2077 bool is_move
= false,
2078 AST::AttrVec outer_attribs
= AST::AttrVec ())
2079 : ClosureExpr (std::move (mappings
), std::move (closure_params
), is_move
,
2080 std::move (outer_attribs
), locus
),
2081 closure_inner (std::move (closure_inner_expr
))
2084 // Copy constructor must be defined to allow copying via cloning of unique_ptr
2085 ClosureExprInner (ClosureExprInner
const &other
)
2086 : ClosureExpr (other
), closure_inner (other
.closure_inner
->clone_expr ())
2089 // Overload assignment operator to clone closure_inner
2090 ClosureExprInner
&operator= (ClosureExprInner
const &other
)
2092 ClosureExpr::operator= (other
);
2093 closure_inner
= other
.closure_inner
->clone_expr ();
2094 // params = other.params;
2095 // has_move = other.has_move;
2096 // outer_attrs = other.outer_attrs;
2101 // move constructors
2102 ClosureExprInner (ClosureExprInner
&&other
) = default;
2103 ClosureExprInner
&operator= (ClosureExprInner
&&other
) = default;
2105 void accept_vis (HIRFullVisitor
&vis
) override
;
2106 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2109 /* Use covariance to implement clone function as returning this object rather
2111 ClosureExprInner
*clone_expr_impl () const override
2113 return new ClosureExprInner (*this);
2116 /* Use covariance to implement clone function as returning this object rather
2118 ClosureExprInner
*clone_expr_without_block_impl () const override
2120 return new ClosureExprInner (*this);
2125 class BlockExpr
: public ExprWithBlock
2128 AST::AttrVec inner_attrs
;
2129 std::vector
<std::unique_ptr
<Stmt
> > statements
;
2130 std::unique_ptr
<Expr
> expr
;
2131 bool tail_reachable
;
2132 Location start_locus
;
2135 std::string
as_string () const override
;
2137 // Returns whether the block contains statements.
2138 bool has_statements () const { return !statements
.empty (); }
2140 // Returns whether the block contains an expression
2141 bool has_expr () const { return expr
!= nullptr; }
2143 bool is_tail_reachable () const { return tail_reachable
; }
2145 BlockExpr (Analysis::NodeMapping mappings
,
2146 std::vector
<std::unique_ptr
<Stmt
> > block_statements
,
2147 std::unique_ptr
<Expr
> block_expr
, bool tail_reachable
,
2148 AST::AttrVec inner_attribs
, AST::AttrVec outer_attribs
,
2149 Location start_locus
, Location end_locus
)
2150 : ExprWithBlock (std::move (mappings
), std::move (outer_attribs
)),
2151 inner_attrs (std::move (inner_attribs
)),
2152 statements (std::move (block_statements
)), expr (std::move (block_expr
)),
2153 tail_reachable (tail_reachable
), start_locus (start_locus
),
2154 end_locus (end_locus
)
2157 // Copy constructor with clone
2158 BlockExpr (BlockExpr
const &other
)
2159 : ExprWithBlock (other
), /*statements(other.statements),*/
2160 inner_attrs (other
.inner_attrs
), start_locus (other
.start_locus
),
2161 end_locus (other
.end_locus
)
2163 // guard to protect from null pointer dereference
2164 if (other
.expr
!= nullptr)
2165 expr
= other
.expr
->clone_expr ();
2167 statements
.reserve (other
.statements
.size ());
2168 for (const auto &e
: other
.statements
)
2169 statements
.push_back (e
->clone_stmt ());
2172 // Overloaded assignment operator to clone pointer
2173 BlockExpr
&operator= (BlockExpr
const &other
)
2175 ExprWithBlock::operator= (other
);
2176 // statements = other.statements;
2177 expr
= other
.expr
->clone_expr ();
2178 inner_attrs
= other
.inner_attrs
;
2179 start_locus
= other
.end_locus
;
2180 end_locus
= other
.end_locus
;
2181 // outer_attrs = other.outer_attrs;
2183 statements
.reserve (other
.statements
.size ());
2184 for (const auto &e
: other
.statements
)
2185 statements
.push_back (e
->clone_stmt ());
2190 // move constructors
2191 BlockExpr (BlockExpr
&&other
) = default;
2192 BlockExpr
&operator= (BlockExpr
&&other
) = default;
2194 // Unique pointer custom clone function
2195 std::unique_ptr
<BlockExpr
> clone_block_expr () const
2197 return std::unique_ptr
<BlockExpr
> (clone_block_expr_impl ());
2200 Location
get_locus () const override final
{ return start_locus
; }
2202 Location
get_start_locus () const { return start_locus
; }
2204 Location
get_end_locus () const { return end_locus
; }
2206 void accept_vis (HIRFullVisitor
&vis
) override
;
2207 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2209 bool is_final_stmt (Stmt
*stmt
) { return statements
.back ().get () == stmt
; }
2211 std::unique_ptr
<Expr
> &get_final_expr () { return expr
; }
2213 std::vector
<std::unique_ptr
<Stmt
> > &get_statements () { return statements
; }
2215 ExprType
get_expression_type () const final override
2217 return ExprType::Block
;
2221 /* Use covariance to implement clone function as returning this object rather
2223 BlockExpr
*clone_expr_impl () const override
2225 return clone_block_expr_impl ();
2228 /* Use covariance to implement clone function as returning this object rather
2230 BlockExpr
*clone_expr_with_block_impl () const override
2232 return clone_block_expr_impl ();
2235 /* This is the base method as not an abstract class - not virtual but could be
2236 * in future if required. */
2237 /*virtual*/ BlockExpr
*clone_block_expr_impl () const
2239 return new BlockExpr (*this);
2243 // Represents a type-specified closure expression HIR node
2244 class ClosureExprInnerTyped
: public ClosureExpr
2246 std::unique_ptr
<Type
> return_type
;
2247 std::unique_ptr
<BlockExpr
>
2248 expr
; // only used because may be polymorphic in future
2251 std::string
as_string () const override
;
2253 // Constructor potentially with a move
2254 ClosureExprInnerTyped (Analysis::NodeMapping mappings
,
2255 std::unique_ptr
<Type
> closure_return_type
,
2256 std::unique_ptr
<BlockExpr
> closure_expr
,
2257 std::vector
<ClosureParam
> closure_params
,
2258 Location locus
, bool is_move
= false,
2259 AST::AttrVec outer_attribs
= AST::AttrVec ())
2260 : ClosureExpr (std::move (mappings
), std::move (closure_params
), is_move
,
2261 std::move (outer_attribs
), locus
),
2262 return_type (std::move (closure_return_type
)),
2263 expr (std::move (closure_expr
))
2266 // Copy constructor requires cloning
2267 ClosureExprInnerTyped (ClosureExprInnerTyped
const &other
)
2268 : ClosureExpr (other
), return_type (other
.return_type
->clone_type ()),
2269 expr (other
.expr
->clone_block_expr ())
2272 // Overload assignment operator to clone unique_ptrs
2273 ClosureExprInnerTyped
&operator= (ClosureExprInnerTyped
const &other
)
2275 ClosureExpr::operator= (other
);
2276 return_type
= other
.return_type
->clone_type ();
2277 expr
= other
.expr
->clone_block_expr ();
2278 // params = other.params;
2279 // has_move = other.has_move;
2280 // outer_attrs = other.outer_attrs;
2285 // move constructors
2286 ClosureExprInnerTyped (ClosureExprInnerTyped
&&other
) = default;
2287 ClosureExprInnerTyped
&operator= (ClosureExprInnerTyped
&&other
) = default;
2289 void accept_vis (HIRFullVisitor
&vis
) override
;
2290 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2293 /* Use covariance to implement clone function as returning this object rather
2295 ClosureExprInnerTyped
*clone_expr_impl () const override
2297 return new ClosureExprInnerTyped (*this);
2300 /* Use covariance to implement clone function as returning this object rather
2302 ClosureExprInnerTyped
*clone_expr_without_block_impl () const override
2304 return new ClosureExprInnerTyped (*this);
2308 // HIR node representing continue expression within loops
2309 class ContinueExpr
: public ExprWithoutBlock
2315 std::string
as_string () const override
;
2317 // Returns true if the continue expr has a label.
2318 bool has_label () const { return !label
.is_error (); }
2320 // Constructor for a ContinueExpr with a label.
2321 ContinueExpr (Analysis::NodeMapping mappings
, Location locus
, Lifetime label
,
2322 AST::AttrVec outer_attribs
= AST::AttrVec ())
2323 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
2324 label (std::move (label
)), locus (locus
)
2327 Location
get_locus () const override final
{ return locus
; }
2329 void accept_vis (HIRFullVisitor
&vis
) override
;
2330 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2332 Lifetime
&get_label () { return label
; }
2334 ExprType
get_expression_type () const final override
2336 return ExprType::Continue
;
2340 /* Use covariance to implement clone function as returning this object rather
2342 ContinueExpr
*clone_expr_impl () const override
2344 return new ContinueExpr (*this);
2347 /* Use covariance to implement clone function as returning this object rather
2349 ContinueExpr
*clone_expr_without_block_impl () const override
2351 return new ContinueExpr (*this);
2355 // HIR node representing break expression within loops
2356 class BreakExpr
: public ExprWithoutBlock
2361 // bool has_break_expr;
2362 std::unique_ptr
<Expr
> break_expr
;
2367 std::string
as_string () const override
;
2369 // Returns whether the break expression has a label or not.
2370 bool has_label () const { return !label
.is_error (); }
2372 /* Returns whether the break expression has an expression used in the break or
2374 bool has_break_expr () const { return break_expr
!= nullptr; }
2376 // Constructor for a break expression
2377 BreakExpr (Analysis::NodeMapping mappings
, Location locus
,
2378 Lifetime break_label
,
2379 std::unique_ptr
<Expr
> expr_in_break
= nullptr,
2380 AST::AttrVec outer_attribs
= AST::AttrVec ())
2381 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
2382 label (std::move (break_label
)), break_expr (std::move (expr_in_break
)),
2386 // Copy constructor defined to use clone for unique pointer
2387 BreakExpr (BreakExpr
const &other
)
2388 : ExprWithoutBlock (other
), label (other
.label
), locus (other
.locus
)
2390 // guard to protect from null pointer dereference
2391 if (other
.break_expr
!= nullptr)
2392 break_expr
= other
.break_expr
->clone_expr ();
2395 // Overload assignment operator to clone unique pointer
2396 BreakExpr
&operator= (BreakExpr
const &other
)
2398 ExprWithoutBlock::operator= (other
);
2399 label
= other
.label
;
2400 break_expr
= other
.break_expr
->clone_expr ();
2401 locus
= other
.locus
;
2402 // outer_attrs = other.outer_attrs;
2407 // move constructors
2408 BreakExpr (BreakExpr
&&other
) = default;
2409 BreakExpr
&operator= (BreakExpr
&&other
) = default;
2411 Location
get_locus () const override final
{ return locus
; }
2413 void accept_vis (HIRFullVisitor
&vis
) override
;
2414 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2416 Lifetime
&get_label () { return label
; }
2418 std::unique_ptr
<Expr
> &get_expr () { return break_expr
; }
2420 ExprType
get_expression_type () const override final
2422 return ExprType::Break
;
2426 /* Use covariance to implement clone function as returning this object rather
2428 BreakExpr
*clone_expr_impl () const override
{ return new BreakExpr (*this); }
2430 /* Use covariance to implement clone function as returning this object rather
2432 BreakExpr
*clone_expr_without_block_impl () const override
2434 return new BreakExpr (*this);
2438 // Base range expression HIR node object - abstract
2439 class RangeExpr
: public ExprWithoutBlock
2444 // outer attributes not allowed before range expressions
2445 RangeExpr (Analysis::NodeMapping mappings
, Location locus
)
2446 : ExprWithoutBlock (std::move (mappings
), AST::AttrVec ()), locus (locus
)
2450 Location
get_locus () const override final
{ return locus
; }
2452 ExprType
get_expression_type () const override final
2454 return ExprType::Range
;
2458 // Range from (inclusive) and to (exclusive) expression HIR node object
2459 // aka RangeExpr; constructs a std::ops::Range object
2460 class RangeFromToExpr
: public RangeExpr
2462 std::unique_ptr
<Expr
> from
;
2463 std::unique_ptr
<Expr
> to
;
2466 std::string
as_string () const override
;
2468 RangeFromToExpr (Analysis::NodeMapping mappings
,
2469 std::unique_ptr
<Expr
> range_from
,
2470 std::unique_ptr
<Expr
> range_to
, Location locus
)
2471 : RangeExpr (std::move (mappings
), locus
), from (std::move (range_from
)),
2472 to (std::move (range_to
))
2475 // Copy constructor with cloning
2476 RangeFromToExpr (RangeFromToExpr
const &other
)
2477 : RangeExpr (other
), from (other
.from
->clone_expr ()),
2478 to (other
.to
->clone_expr ())
2481 // Overload assignment operator to clone unique pointers
2482 RangeFromToExpr
&operator= (RangeFromToExpr
const &other
)
2484 RangeExpr::operator= (other
);
2485 from
= other
.from
->clone_expr ();
2486 to
= other
.to
->clone_expr ();
2491 // move constructors
2492 RangeFromToExpr (RangeFromToExpr
&&other
) = default;
2493 RangeFromToExpr
&operator= (RangeFromToExpr
&&other
) = default;
2495 void accept_vis (HIRFullVisitor
&vis
) override
;
2496 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2498 std::unique_ptr
<Expr
> &get_from_expr () { return from
; }
2499 std::unique_ptr
<Expr
> &get_to_expr () { return to
; }
2502 /* Use covariance to implement clone function as returning this object rather
2504 RangeFromToExpr
*clone_expr_impl () const override
2506 return new RangeFromToExpr (*this);
2509 /* Use covariance to implement clone function as returning this object rather
2511 RangeFromToExpr
*clone_expr_without_block_impl () const override
2513 return new RangeFromToExpr (*this);
2517 // Range from (inclusive) expression HIR node object
2518 // constructs a std::ops::RangeFrom object
2519 class RangeFromExpr
: public RangeExpr
2521 std::unique_ptr
<Expr
> from
;
2524 std::string
as_string () const override
;
2526 RangeFromExpr (Analysis::NodeMapping mappings
,
2527 std::unique_ptr
<Expr
> range_from
, Location locus
)
2528 : RangeExpr (std::move (mappings
), locus
), from (std::move (range_from
))
2531 // Copy constructor with clone
2532 RangeFromExpr (RangeFromExpr
const &other
)
2533 : RangeExpr (other
), from (other
.from
->clone_expr ())
2536 // Overload assignment operator to clone unique_ptr
2537 RangeFromExpr
&operator= (RangeFromExpr
const &other
)
2539 RangeExpr::operator= (other
);
2540 from
= other
.from
->clone_expr ();
2545 // move constructors
2546 RangeFromExpr (RangeFromExpr
&&other
) = default;
2547 RangeFromExpr
&operator= (RangeFromExpr
&&other
) = default;
2549 void accept_vis (HIRFullVisitor
&vis
) override
;
2550 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2552 std::unique_ptr
<Expr
> &get_from_expr () { return from
; }
2555 /* Use covariance to implement clone function as returning this object rather
2557 RangeFromExpr
*clone_expr_impl () const override
2559 return new RangeFromExpr (*this);
2562 /* Use covariance to implement clone function as returning this object rather
2564 RangeFromExpr
*clone_expr_without_block_impl () const override
2566 return new RangeFromExpr (*this);
2570 // Range to (exclusive) expression HIR node object
2571 // constructs a std::ops::RangeTo object
2572 class RangeToExpr
: public RangeExpr
2574 std::unique_ptr
<Expr
> to
;
2577 std::string
as_string () const override
;
2579 // outer attributes not allowed
2580 RangeToExpr (Analysis::NodeMapping mappings
, std::unique_ptr
<Expr
> range_to
,
2582 : RangeExpr (std::move (mappings
), locus
), to (std::move (range_to
))
2585 // Copy constructor with clone
2586 RangeToExpr (RangeToExpr
const &other
)
2587 : RangeExpr (other
), to (other
.to
->clone_expr ())
2590 // Overload assignment operator to clone unique_ptr
2591 RangeToExpr
&operator= (RangeToExpr
const &other
)
2593 RangeExpr::operator= (other
);
2594 to
= other
.to
->clone_expr ();
2599 // move constructors
2600 RangeToExpr (RangeToExpr
&&other
) = default;
2601 RangeToExpr
&operator= (RangeToExpr
&&other
) = default;
2603 void accept_vis (HIRFullVisitor
&vis
) override
;
2604 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2606 std::unique_ptr
<Expr
> &get_to_expr () { return to
; }
2609 /* Use covariance to implement clone function as returning this object rather
2611 RangeToExpr
*clone_expr_impl () const override
2613 return new RangeToExpr (*this);
2616 /* Use covariance to implement clone function as returning this object rather
2618 RangeToExpr
*clone_expr_without_block_impl () const override
2620 return new RangeToExpr (*this);
2624 // Full range expression HIR node object
2625 // constructs a std::ops::RangeFull object
2626 class RangeFullExpr
: public RangeExpr
2629 std::string
as_string () const override
;
2631 RangeFullExpr (Analysis::NodeMapping mappings
, Location locus
)
2632 : RangeExpr (std::move (mappings
), locus
)
2634 // outer attributes not allowed
2636 void accept_vis (HIRFullVisitor
&vis
) override
;
2637 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2640 /* Use covariance to implement clone function as returning this object rather
2642 RangeFullExpr
*clone_expr_impl () const override
2644 return new RangeFullExpr (*this);
2647 /* Use covariance to implement clone function as returning this object rather
2649 RangeFullExpr
*clone_expr_without_block_impl () const override
2651 return new RangeFullExpr (*this);
2655 // Range from (inclusive) and to (inclusive) expression HIR node object
2656 // aka RangeInclusiveExpr; constructs a std::ops::RangeInclusive object
2657 class RangeFromToInclExpr
: public RangeExpr
2659 std::unique_ptr
<Expr
> from
;
2660 std::unique_ptr
<Expr
> to
;
2663 std::string
as_string () const override
;
2665 RangeFromToInclExpr (Analysis::NodeMapping mappings
,
2666 std::unique_ptr
<Expr
> range_from
,
2667 std::unique_ptr
<Expr
> range_to
, Location locus
)
2668 : RangeExpr (std::move (mappings
), locus
), from (std::move (range_from
)),
2669 to (std::move (range_to
))
2671 // outer attributes not allowed
2673 // Copy constructor with clone
2674 RangeFromToInclExpr (RangeFromToInclExpr
const &other
)
2675 : RangeExpr (other
), from (other
.from
->clone_expr ()),
2676 to (other
.to
->clone_expr ())
2679 // Overload assignment operator to use clone
2680 RangeFromToInclExpr
&operator= (RangeFromToInclExpr
const &other
)
2682 RangeExpr::operator= (other
);
2683 from
= other
.from
->clone_expr ();
2684 to
= other
.to
->clone_expr ();
2689 // move constructors
2690 RangeFromToInclExpr (RangeFromToInclExpr
&&other
) = default;
2691 RangeFromToInclExpr
&operator= (RangeFromToInclExpr
&&other
) = default;
2693 void accept_vis (HIRFullVisitor
&vis
) override
;
2694 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2696 std::unique_ptr
<Expr
> &get_from_expr () { return from
; }
2697 std::unique_ptr
<Expr
> &get_to_expr () { return to
; }
2700 /* Use covariance to implement clone function as returning this object rather
2702 RangeFromToInclExpr
*clone_expr_impl () const override
2704 return new RangeFromToInclExpr (*this);
2707 /* Use covariance to implement clone function as returning this object rather
2709 RangeFromToInclExpr
*clone_expr_without_block_impl () const override
2711 return new RangeFromToInclExpr (*this);
2715 // Range to (inclusive) expression HIR node object
2716 // aka RangeToInclusiveExpr; constructs a std::ops::RangeToInclusive object
2717 class RangeToInclExpr
: public RangeExpr
2719 std::unique_ptr
<Expr
> to
;
2722 std::string
as_string () const override
;
2724 RangeToInclExpr (Analysis::NodeMapping mappings
,
2725 std::unique_ptr
<Expr
> range_to
, Location locus
)
2726 : RangeExpr (std::move (mappings
), locus
), to (std::move (range_to
))
2728 // outer attributes not allowed
2730 // Copy constructor with clone
2731 RangeToInclExpr (RangeToInclExpr
const &other
)
2732 : RangeExpr (other
), to (other
.to
->clone_expr ())
2735 // Overload assignment operator to clone pointer
2736 RangeToInclExpr
&operator= (RangeToInclExpr
const &other
)
2738 RangeExpr::operator= (other
);
2739 to
= other
.to
->clone_expr ();
2744 // move constructors
2745 RangeToInclExpr (RangeToInclExpr
&&other
) = default;
2746 RangeToInclExpr
&operator= (RangeToInclExpr
&&other
) = default;
2748 void accept_vis (HIRFullVisitor
&vis
) override
;
2749 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2751 std::unique_ptr
<Expr
> &get_to_expr () { return to
; };
2754 /* Use covariance to implement clone function as returning this object rather
2756 RangeToInclExpr
*clone_expr_impl () const override
2758 return new RangeToInclExpr (*this);
2761 /* Use covariance to implement clone function as returning this object rather
2763 RangeToInclExpr
*clone_expr_without_block_impl () const override
2765 return new RangeToInclExpr (*this);
2769 // Return expression HIR node representation
2770 class ReturnExpr
: public ExprWithoutBlock
2773 std::unique_ptr
<Expr
> return_expr
;
2777 std::string
as_string () const override
;
2779 /* Returns whether the object has an expression returned (i.e. not void return
2781 bool has_return_expr () const { return return_expr
!= nullptr; }
2783 // Constructor for ReturnExpr.
2784 ReturnExpr (Analysis::NodeMapping mappings
, Location locus
,
2785 std::unique_ptr
<Expr
> returned_expr
= nullptr,
2786 AST::AttrVec outer_attribs
= AST::AttrVec ())
2787 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attribs
)),
2788 return_expr (std::move (returned_expr
)), locus (locus
)
2791 // Copy constructor with clone
2792 ReturnExpr (ReturnExpr
const &other
)
2793 : ExprWithoutBlock (other
), locus (other
.locus
)
2795 // guard to protect from null pointer dereference
2796 if (other
.return_expr
!= nullptr)
2797 return_expr
= other
.return_expr
->clone_expr ();
2800 // Overloaded assignment operator to clone return_expr pointer
2801 ReturnExpr
&operator= (ReturnExpr
const &other
)
2803 ExprWithoutBlock::operator= (other
);
2804 return_expr
= other
.return_expr
->clone_expr ();
2805 locus
= other
.locus
;
2806 // outer_attrs = other.outer_attrs;
2811 // move constructors
2812 ReturnExpr (ReturnExpr
&&other
) = default;
2813 ReturnExpr
&operator= (ReturnExpr
&&other
) = default;
2815 Location
get_locus () const override final
{ return locus
; }
2817 void accept_vis (HIRFullVisitor
&vis
) override
;
2818 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2820 Expr
*get_expr () { return return_expr
.get (); }
2822 ExprType
get_expression_type () const override final
2824 return ExprType::Return
;
2828 /* Use covariance to implement clone function as returning this object rather
2830 ReturnExpr
*clone_expr_impl () const override
2832 return new ReturnExpr (*this);
2835 /* Use covariance to implement clone function as returning this object rather
2837 ReturnExpr
*clone_expr_without_block_impl () const override
2839 return new ReturnExpr (*this);
2843 // An unsafe block HIR node
2844 class UnsafeBlockExpr
: public ExprWithBlock
2846 // Or just have it extend BlockExpr
2847 std::unique_ptr
<BlockExpr
> expr
;
2851 std::string
as_string () const override
;
2853 UnsafeBlockExpr (Analysis::NodeMapping mappings
,
2854 std::unique_ptr
<BlockExpr
> block_expr
,
2855 AST::AttrVec outer_attribs
, Location locus
)
2856 : ExprWithBlock (std::move (mappings
), std::move (outer_attribs
)),
2857 expr (std::move (block_expr
)), locus (locus
)
2860 // Copy constructor with clone
2861 UnsafeBlockExpr (UnsafeBlockExpr
const &other
)
2862 : ExprWithBlock (other
), expr (other
.expr
->clone_block_expr ()),
2866 // Overloaded assignment operator to clone
2867 UnsafeBlockExpr
&operator= (UnsafeBlockExpr
const &other
)
2869 ExprWithBlock::operator= (other
);
2870 expr
= other
.expr
->clone_block_expr ();
2871 locus
= other
.locus
;
2872 // outer_attrs = other.outer_attrs;
2877 // move constructors
2878 UnsafeBlockExpr (UnsafeBlockExpr
&&other
) = default;
2879 UnsafeBlockExpr
&operator= (UnsafeBlockExpr
&&other
) = default;
2881 Location
get_locus () const override final
{ return locus
; }
2883 void accept_vis (HIRFullVisitor
&vis
) override
;
2884 void accept_vis (HIRExpressionVisitor
&vis
) override
;
2886 std::unique_ptr
<BlockExpr
> &get_block_expr () { return expr
; }
2888 ExprType
get_expression_type () const override final
2890 return ExprType::UnsafeBlock
;
2894 /* Use covariance to implement clone function as returning this object rather
2896 UnsafeBlockExpr
*clone_expr_impl () const override
2898 return new UnsafeBlockExpr (*this);
2901 /* Use covariance to implement clone function as returning this object rather
2903 UnsafeBlockExpr
*clone_expr_with_block_impl () const override
2905 return new UnsafeBlockExpr (*this);
2909 // Loop label expression HIR node used with break and continue expressions
2911 class LoopLabel
/*: public Node*/
2913 Lifetime label
; // or type LIFETIME_OR_LABEL
2917 Analysis::NodeMapping mappings
;
2920 std::string
as_string () const;
2922 LoopLabel (Analysis::NodeMapping mapping
, Lifetime loop_label
, Location locus
)
2923 : label (std::move (loop_label
)), locus (locus
), mappings (mapping
)
2926 // Returns whether the LoopLabel is in an error state.
2927 bool is_error () const { return label
.is_error (); }
2929 Location
get_locus () const { return locus
; }
2931 Analysis::NodeMapping
&get_mappings () { return mappings
; }
2933 Lifetime
&get_lifetime () { return label
; }
2936 // Base loop expression HIR node - aka LoopExpr
2937 class BaseLoopExpr
: public ExprWithBlock
2940 LoopLabel loop_label
;
2941 std::unique_ptr
<BlockExpr
> loop_block
;
2947 // Constructor for BaseLoopExpr
2948 BaseLoopExpr (Analysis::NodeMapping mappings
,
2949 std::unique_ptr
<BlockExpr
> loop_block
, Location locus
,
2950 LoopLabel loop_label
,
2951 AST::AttrVec outer_attribs
= AST::AttrVec ())
2952 : ExprWithBlock (std::move (mappings
), std::move (outer_attribs
)),
2953 loop_label (std::move (loop_label
)), loop_block (std::move (loop_block
)),
2957 // Copy constructor for BaseLoopExpr with clone
2958 BaseLoopExpr (BaseLoopExpr
const &other
)
2959 : ExprWithBlock (other
), loop_label (other
.loop_label
),
2960 loop_block (other
.loop_block
->clone_block_expr ()), locus (other
.locus
)
2963 // Overloaded assignment operator to clone
2964 BaseLoopExpr
&operator= (BaseLoopExpr
const &other
)
2966 ExprWithBlock::operator= (other
);
2967 loop_block
= other
.loop_block
->clone_block_expr ();
2968 loop_label
= other
.loop_label
;
2969 locus
= other
.locus
;
2970 // outer_attrs = other.outer_attrs;
2975 // move constructors
2976 BaseLoopExpr (BaseLoopExpr
&&other
) = default;
2977 BaseLoopExpr
&operator= (BaseLoopExpr
&&other
) = default;
2979 ExprType
get_expression_type () const final override
2981 return ExprType::BaseLoop
;
2985 bool has_loop_label () const { return !loop_label
.is_error (); }
2987 Location
get_locus () const override final
{ return locus
; }
2989 std::unique_ptr
<HIR::BlockExpr
> &get_loop_block () { return loop_block
; };
2991 LoopLabel
&get_loop_label () { return loop_label
; }
2994 // 'Loop' expression (i.e. the infinite loop) HIR node
2995 class LoopExpr
: public BaseLoopExpr
2998 std::string
as_string () const override
;
3000 // Constructor for LoopExpr
3001 LoopExpr (Analysis::NodeMapping mappings
,
3002 std::unique_ptr
<BlockExpr
> loop_block
, Location locus
,
3003 LoopLabel loop_label
, AST::AttrVec outer_attribs
= AST::AttrVec ())
3004 : BaseLoopExpr (std::move (mappings
), std::move (loop_block
), locus
,
3005 std::move (loop_label
), std::move (outer_attribs
))
3008 void accept_vis (HIRFullVisitor
&vis
) override
;
3009 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3012 /* Use covariance to implement clone function as returning this object rather
3014 LoopExpr
*clone_expr_impl () const override
{ return new LoopExpr (*this); }
3016 /* Use covariance to implement clone function as returning this object rather
3018 LoopExpr
*clone_expr_with_block_impl () const override
3020 return new LoopExpr (*this);
3024 // While loop expression HIR node (predicate loop)
3025 class WhileLoopExpr
: public BaseLoopExpr
3027 std::unique_ptr
<Expr
> condition
;
3030 std::string
as_string () const override
;
3032 // Constructor for while loop with loop label
3033 WhileLoopExpr (Analysis::NodeMapping mappings
,
3034 std::unique_ptr
<Expr
> loop_condition
,
3035 std::unique_ptr
<BlockExpr
> loop_block
, Location locus
,
3036 LoopLabel loop_label
,
3037 AST::AttrVec outer_attribs
= AST::AttrVec ())
3038 : BaseLoopExpr (std::move (mappings
), std::move (loop_block
), locus
,
3039 std::move (loop_label
), std::move (outer_attribs
)),
3040 condition (std::move (loop_condition
))
3043 // Copy constructor with clone
3044 WhileLoopExpr (WhileLoopExpr
const &other
)
3045 : BaseLoopExpr (other
), condition (other
.condition
->clone_expr ())
3048 // Overloaded assignment operator to clone
3049 WhileLoopExpr
&operator= (WhileLoopExpr
const &other
)
3051 BaseLoopExpr::operator= (other
);
3052 condition
= other
.condition
->clone_expr ();
3053 // loop_block = other.loop_block->clone_block_expr();
3054 // loop_label = other.loop_label;
3055 // outer_attrs = other.outer_attrs;
3060 // move constructors
3061 WhileLoopExpr (WhileLoopExpr
&&other
) = default;
3062 WhileLoopExpr
&operator= (WhileLoopExpr
&&other
) = default;
3064 void accept_vis (HIRFullVisitor
&vis
) override
;
3065 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3067 std::unique_ptr
<Expr
> &get_predicate_expr () { return condition
; }
3070 /* Use covariance to implement clone function as returning this object rather
3072 WhileLoopExpr
*clone_expr_impl () const override
3074 return new WhileLoopExpr (*this);
3077 /* Use covariance to implement clone function as returning this object rather
3079 WhileLoopExpr
*clone_expr_with_block_impl () const override
3081 return new WhileLoopExpr (*this);
3085 // While let loop expression HIR node (predicate pattern loop)
3086 class WhileLetLoopExpr
: public BaseLoopExpr
3088 // MatchArmPatterns patterns;
3089 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
; // inlined
3090 std::unique_ptr
<Expr
> condition
;
3093 std::string
as_string () const override
;
3095 // Constructor with a loop label
3096 WhileLetLoopExpr (Analysis::NodeMapping mappings
,
3097 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
,
3098 std::unique_ptr
<Expr
> condition
,
3099 std::unique_ptr
<BlockExpr
> loop_block
, Location locus
,
3100 LoopLabel loop_label
,
3101 AST::AttrVec outer_attribs
= AST::AttrVec ())
3102 : BaseLoopExpr (std::move (mappings
), std::move (loop_block
), locus
,
3103 std::move (loop_label
), std::move (outer_attribs
)),
3104 match_arm_patterns (std::move (match_arm_patterns
)),
3105 condition (std::move (condition
))
3108 // Copy constructor with clone
3109 WhileLetLoopExpr (WhileLetLoopExpr
const &other
)
3110 : BaseLoopExpr (other
),
3111 /*match_arm_patterns(other.match_arm_patterns),*/ condition (
3112 other
.condition
->clone_expr ())
3114 match_arm_patterns
.reserve (other
.match_arm_patterns
.size ());
3115 for (const auto &e
: other
.match_arm_patterns
)
3116 match_arm_patterns
.push_back (e
->clone_pattern ());
3119 // Overloaded assignment operator to clone pointers
3120 WhileLetLoopExpr
&operator= (WhileLetLoopExpr
const &other
)
3122 BaseLoopExpr::operator= (other
);
3123 // match_arm_patterns = other.match_arm_patterns;
3124 condition
= other
.condition
->clone_expr ();
3125 // loop_block = other.loop_block->clone_block_expr();
3126 // loop_label = other.loop_label;
3127 // outer_attrs = other.outer_attrs;
3129 match_arm_patterns
.reserve (other
.match_arm_patterns
.size ());
3130 for (const auto &e
: other
.match_arm_patterns
)
3131 match_arm_patterns
.push_back (e
->clone_pattern ());
3136 // move constructors
3137 WhileLetLoopExpr (WhileLetLoopExpr
&&other
) = default;
3138 WhileLetLoopExpr
&operator= (WhileLetLoopExpr
&&other
) = default;
3140 void accept_vis (HIRFullVisitor
&vis
) override
;
3141 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3143 std::unique_ptr
<Expr
> &get_cond () { return condition
; }
3146 /* Use covariance to implement clone function as returning this object rather
3148 WhileLetLoopExpr
*clone_expr_impl () const override
3150 return new WhileLetLoopExpr (*this);
3153 /* Use covariance to implement clone function as returning this object rather
3155 WhileLetLoopExpr
*clone_expr_with_block_impl () const override
3157 return new WhileLetLoopExpr (*this);
3161 // For loop expression HIR node (iterator loop)
3162 class ForLoopExpr
: public BaseLoopExpr
3164 std::unique_ptr
<Pattern
> pattern
;
3165 std::unique_ptr
<Expr
> iterator_expr
;
3168 std::string
as_string () const override
;
3170 // Constructor with loop label
3171 ForLoopExpr (Analysis::NodeMapping mappings
,
3172 std::unique_ptr
<Pattern
> loop_pattern
,
3173 std::unique_ptr
<Expr
> iterator_expr
,
3174 std::unique_ptr
<BlockExpr
> loop_body
, Location locus
,
3175 LoopLabel loop_label
,
3176 AST::AttrVec outer_attribs
= AST::AttrVec ())
3177 : BaseLoopExpr (std::move (mappings
), std::move (loop_body
), locus
,
3178 std::move (loop_label
), std::move (outer_attribs
)),
3179 pattern (std::move (loop_pattern
)),
3180 iterator_expr (std::move (iterator_expr
))
3183 // Copy constructor with clone
3184 ForLoopExpr (ForLoopExpr
const &other
)
3185 : BaseLoopExpr (other
), pattern (other
.pattern
->clone_pattern ()),
3186 iterator_expr (other
.iterator_expr
->clone_expr ())
3189 // Overloaded assignment operator to clone
3190 ForLoopExpr
&operator= (ForLoopExpr
const &other
)
3192 BaseLoopExpr::operator= (other
);
3193 pattern
= other
.pattern
->clone_pattern ();
3194 iterator_expr
= other
.iterator_expr
->clone_expr ();
3195 /*loop_block = other.loop_block->clone_block_expr();
3196 loop_label = other.loop_label;
3197 outer_attrs = other.outer_attrs;*/
3202 // move constructors
3203 ForLoopExpr (ForLoopExpr
&&other
) = default;
3204 ForLoopExpr
&operator= (ForLoopExpr
&&other
) = default;
3206 void accept_vis (HIRFullVisitor
&vis
) override
;
3207 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3209 std::unique_ptr
<Expr
> &get_iterator_expr () { return iterator_expr
; }
3212 /* Use covariance to implement clone function as returning this object rather
3214 ForLoopExpr
*clone_expr_impl () const override
3216 return new ForLoopExpr (*this);
3219 /* Use covariance to implement clone function as returning this object rather
3221 ForLoopExpr
*clone_expr_with_block_impl () const override
3223 return new ForLoopExpr (*this);
3227 // forward decl for IfExpr
3230 // Base if expression with no "else" or "if let" HIR node
3231 class IfExpr
: public ExprWithBlock
3233 std::unique_ptr
<Expr
> condition
;
3234 std::unique_ptr
<BlockExpr
> if_block
;
3239 std::string
as_string () const override
;
3241 IfExpr (Analysis::NodeMapping mappings
, std::unique_ptr
<Expr
> condition
,
3242 std::unique_ptr
<BlockExpr
> if_block
, Location locus
)
3243 : ExprWithBlock (std::move (mappings
), AST::AttrVec ()),
3244 condition (std::move (condition
)), if_block (std::move (if_block
)),
3247 // outer attributes are never allowed on IfExprs
3249 // Copy constructor with clone
3250 IfExpr (IfExpr
const &other
)
3251 : ExprWithBlock (other
), condition (other
.condition
->clone_expr ()),
3252 if_block (other
.if_block
->clone_block_expr ()), locus (other
.locus
)
3255 // Overloaded assignment operator to clone expressions
3256 IfExpr
&operator= (IfExpr
const &other
)
3258 ExprWithBlock::operator= (other
);
3259 condition
= other
.condition
->clone_expr ();
3260 if_block
= other
.if_block
->clone_block_expr ();
3261 locus
= other
.locus
;
3266 // move constructors
3267 IfExpr (IfExpr
&&other
) = default;
3268 IfExpr
&operator= (IfExpr
&&other
) = default;
3270 // Unique pointer custom clone function
3271 std::unique_ptr
<IfExpr
> clone_if_expr () const
3273 return std::unique_ptr
<IfExpr
> (clone_if_expr_impl ());
3276 /* Note that multiple "else if"s are handled via nested HIRs rather than a
3277 * vector of else ifs - i.e. not like a switch statement. TODO - is this a
3278 * better approach? or does it not parse correctly and have downsides? */
3280 Location
get_locus () const override final
{ return locus
; }
3282 void accept_vis (HIRFullVisitor
&vis
) override
;
3283 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3285 void vis_if_condition (HIRFullVisitor
&vis
) { condition
->accept_vis (vis
); }
3286 void vis_if_block (HIRFullVisitor
&vis
) { if_block
->accept_vis (vis
); }
3288 Expr
*get_if_condition () { return condition
.get (); }
3289 BlockExpr
*get_if_block () { return if_block
.get (); }
3291 ExprType
get_expression_type () const final override
{ return ExprType::If
; }
3294 /* Use covariance to implement clone function as returning this object rather
3296 IfExpr
*clone_expr_impl () const override
{ return new IfExpr (*this); }
3298 // Base clone function but still concrete as concrete base class
3299 virtual IfExpr
*clone_if_expr_impl () const { return new IfExpr (*this); }
3301 /* Use covariance to implement clone function as returning this object rather
3303 IfExpr
*clone_expr_with_block_impl () const override
3305 return new IfExpr (*this);
3309 // If expression with an ending "else" expression HIR node (trailing)
3310 class IfExprConseqElse
: public IfExpr
3312 std::unique_ptr
<BlockExpr
> else_block
;
3315 std::string
as_string () const override
;
3317 IfExprConseqElse (Analysis::NodeMapping mappings
,
3318 std::unique_ptr
<Expr
> condition
,
3319 std::unique_ptr
<BlockExpr
> if_block
,
3320 std::unique_ptr
<BlockExpr
> else_block
, Location locus
)
3321 : IfExpr (std::move (mappings
), std::move (condition
), std::move (if_block
),
3323 else_block (std::move (else_block
))
3325 // again, outer attributes not allowed
3327 // Copy constructor with clone
3328 IfExprConseqElse (IfExprConseqElse
const &other
)
3329 : IfExpr (other
), else_block (other
.else_block
->clone_block_expr ())
3332 // Overloaded assignment operator with cloning
3333 IfExprConseqElse
&operator= (IfExprConseqElse
const &other
)
3335 IfExpr::operator= (other
);
3336 // condition = other.condition->clone_expr();
3337 // if_block = other.if_block->clone_block_expr();
3338 else_block
= other
.else_block
->clone_block_expr ();
3343 // move constructors
3344 IfExprConseqElse (IfExprConseqElse
&&other
) = default;
3345 IfExprConseqElse
&operator= (IfExprConseqElse
&&other
) = default;
3347 void accept_vis (HIRFullVisitor
&vis
) override
;
3348 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3350 void vis_else_block (HIRFullVisitor
&vis
) { else_block
->accept_vis (vis
); }
3352 BlockExpr
*get_else_block () { return else_block
.get (); }
3355 /* Use covariance to implement clone function as returning this object rather
3357 IfExprConseqElse
*clone_expr_impl () const override
3359 return new IfExprConseqElse (*this);
3362 /* Use covariance to implement clone function as returning this object rather
3364 IfExprConseqElse
*clone_expr_with_block_impl () const override
3366 return new IfExprConseqElse (*this);
3369 /* Use covariance to implement clone function as returning this object rather
3371 IfExprConseqElse
*clone_if_expr_impl () const override
3373 return new IfExprConseqElse (*this);
3377 // If expression with an ending "else if" expression HIR node
3378 class IfExprConseqIf
: public IfExpr
3380 std::unique_ptr
<IfExpr
> conseq_if_expr
;
3383 std::string
as_string () const override
;
3385 IfExprConseqIf (Analysis::NodeMapping mappings
,
3386 std::unique_ptr
<Expr
> condition
,
3387 std::unique_ptr
<BlockExpr
> if_block
,
3388 std::unique_ptr
<IfExpr
> conseq_if_expr
, Location locus
)
3389 : IfExpr (std::move (mappings
), std::move (condition
), std::move (if_block
),
3391 conseq_if_expr (std::move (conseq_if_expr
))
3393 // outer attributes not allowed
3395 // Copy constructor with clone
3396 IfExprConseqIf (IfExprConseqIf
const &other
)
3397 : IfExpr (other
), conseq_if_expr (other
.conseq_if_expr
->clone_if_expr ())
3400 // Overloaded assignment operator to use clone
3401 IfExprConseqIf
&operator= (IfExprConseqIf
const &other
)
3403 IfExpr::operator= (other
);
3404 // condition = other.condition->clone_expr();
3405 // if_block = other.if_block->clone_block_expr();
3406 conseq_if_expr
= other
.conseq_if_expr
->clone_if_expr ();
3411 // move constructors
3412 IfExprConseqIf (IfExprConseqIf
&&other
) = default;
3413 IfExprConseqIf
&operator= (IfExprConseqIf
&&other
) = default;
3415 void accept_vis (HIRFullVisitor
&vis
) override
;
3416 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3418 void vis_conseq_if_expr (HIRFullVisitor
&vis
)
3420 conseq_if_expr
->accept_vis (vis
);
3423 IfExpr
*get_conseq_if_expr () { return conseq_if_expr
.get (); }
3426 /* Use covariance to implement clone function as returning this object rather
3428 IfExprConseqIf
*clone_expr_impl () const override
3430 return new IfExprConseqIf (*this);
3433 /* Use covariance to implement clone function as returning this object rather
3435 IfExprConseqIf
*clone_expr_with_block_impl () const override
3437 return new IfExprConseqIf (*this);
3440 /* Use covariance to implement clone function as returning this object rather
3442 IfExprConseqIf
*clone_if_expr_impl () const override
3444 return new IfExprConseqIf (*this);
3448 // Basic "if let" expression HIR node with no else
3449 class IfLetExpr
: public ExprWithBlock
3451 // MatchArmPatterns patterns;
3452 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
; // inlined
3453 std::unique_ptr
<Expr
> value
;
3454 std::unique_ptr
<BlockExpr
> if_block
;
3459 std::string
as_string () const override
;
3461 IfLetExpr (Analysis::NodeMapping mappings
,
3462 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
,
3463 std::unique_ptr
<Expr
> value
, std::unique_ptr
<BlockExpr
> if_block
,
3465 : ExprWithBlock (std::move (mappings
), AST::AttrVec ()),
3466 match_arm_patterns (std::move (match_arm_patterns
)),
3467 value (std::move (value
)), if_block (std::move (if_block
)), locus (locus
)
3469 // outer attributes not allowed on if let exprs either
3471 // copy constructor with clone
3472 IfLetExpr (IfLetExpr
const &other
)
3473 : ExprWithBlock (other
),
3474 /*match_arm_patterns(other.match_arm_patterns),*/ value (
3475 other
.value
->clone_expr ()),
3476 if_block (other
.if_block
->clone_block_expr ()), locus (other
.locus
)
3478 match_arm_patterns
.reserve (other
.match_arm_patterns
.size ());
3479 for (const auto &e
: other
.match_arm_patterns
)
3480 match_arm_patterns
.push_back (e
->clone_pattern ());
3483 // overload assignment operator to clone
3484 IfLetExpr
&operator= (IfLetExpr
const &other
)
3486 ExprWithBlock::operator= (other
);
3487 // match_arm_patterns = other.match_arm_patterns;
3488 value
= other
.value
->clone_expr ();
3489 if_block
= other
.if_block
->clone_block_expr ();
3490 locus
= other
.locus
;
3492 match_arm_patterns
.reserve (other
.match_arm_patterns
.size ());
3493 for (const auto &e
: other
.match_arm_patterns
)
3494 match_arm_patterns
.push_back (e
->clone_pattern ());
3499 // move constructors
3500 IfLetExpr (IfLetExpr
&&other
) = default;
3501 IfLetExpr
&operator= (IfLetExpr
&&other
) = default;
3503 // Unique pointer custom clone function
3504 std::unique_ptr
<IfLetExpr
> clone_if_let_expr () const
3506 return std::unique_ptr
<IfLetExpr
> (clone_if_let_expr_impl ());
3509 Location
get_locus () const override final
{ return locus
; }
3511 void accept_vis (HIRFullVisitor
&vis
) override
;
3512 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3514 std::unique_ptr
<Expr
> &get_scrutinee_expr ()
3516 rust_assert (value
!= nullptr);
3520 std::vector
<std::unique_ptr
<Pattern
> > &get_patterns ()
3522 return match_arm_patterns
;
3525 BlockExpr
*get_if_block () { return if_block
.get (); }
3527 ExprType
get_expression_type () const final override
3529 return ExprType::IfLet
;
3533 /* Use covariance to implement clone function as returning this object rather
3535 IfLetExpr
*clone_expr_impl () const override
{ return new IfLetExpr (*this); }
3537 /* Use covariance to implement clone function as returning this object rather
3539 IfLetExpr
*clone_expr_with_block_impl () const override
3541 return new IfLetExpr (*this);
3544 // Base clone function but still concrete as concrete base class
3545 virtual IfLetExpr
*clone_if_let_expr_impl () const
3547 return new IfLetExpr (*this);
3551 // If expression with an ending "else if let" expression HIR node
3552 class IfExprConseqIfLet
: public IfExpr
3554 std::unique_ptr
<IfLetExpr
> if_let_expr
;
3557 std::string
as_string () const override
;
3559 IfExprConseqIfLet (Analysis::NodeMapping mappings
,
3560 std::unique_ptr
<Expr
> condition
,
3561 std::unique_ptr
<BlockExpr
> if_block
,
3562 std::unique_ptr
<IfLetExpr
> conseq_if_let_expr
,
3564 : IfExpr (std::move (mappings
), std::move (condition
), std::move (if_block
),
3566 if_let_expr (std::move (conseq_if_let_expr
))
3568 // outer attributes not allowed
3570 // Copy constructor with clone
3571 IfExprConseqIfLet (IfExprConseqIfLet
const &other
)
3572 : IfExpr (other
), if_let_expr (other
.if_let_expr
->clone_if_let_expr ())
3575 // Overloaded assignment operator to use clone
3576 IfExprConseqIfLet
&operator= (IfExprConseqIfLet
const &other
)
3578 IfExpr::operator= (other
);
3579 // condition = other.condition->clone_expr();
3580 // if_block = other.if_block->clone_block_expr();
3581 if_let_expr
= other
.if_let_expr
->clone_if_let_expr ();
3586 // move constructors
3587 IfExprConseqIfLet (IfExprConseqIfLet
&&other
) = default;
3588 IfExprConseqIfLet
&operator= (IfExprConseqIfLet
&&other
) = default;
3590 void accept_vis (HIRFullVisitor
&vis
) override
;
3591 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3594 /* Use covariance to implement clone function as returning this object rather
3596 IfExprConseqIfLet
*clone_expr_impl () const override
3598 return new IfExprConseqIfLet (*this);
3601 /* Use covariance to implement clone function as returning this object rather
3603 IfExprConseqIfLet
*clone_expr_with_block_impl () const override
3605 return new IfExprConseqIfLet (*this);
3608 /* Use covariance to implement clone function as returning this object rather
3610 IfExprConseqIfLet
*clone_if_expr_impl () const override
3612 return new IfExprConseqIfLet (*this);
3616 /* HIR node representing "if let" expression with an "else" expression at the
3618 class IfLetExprConseqElse
: public IfLetExpr
3620 std::unique_ptr
<BlockExpr
> else_block
;
3623 std::string
as_string () const override
;
3625 IfLetExprConseqElse (
3626 Analysis::NodeMapping mappings
,
3627 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
,
3628 std::unique_ptr
<Expr
> value
, std::unique_ptr
<BlockExpr
> if_block
,
3629 std::unique_ptr
<BlockExpr
> else_block
, Location locus
)
3630 : IfLetExpr (std::move (mappings
), std::move (match_arm_patterns
),
3631 std::move (value
), std::move (if_block
), locus
),
3632 else_block (std::move (else_block
))
3634 // outer attributes not allowed
3636 // copy constructor with clone
3637 IfLetExprConseqElse (IfLetExprConseqElse
const &other
)
3638 : IfLetExpr (other
), else_block (other
.else_block
->clone_block_expr ())
3641 // overload assignment operator to clone
3642 IfLetExprConseqElse
&operator= (IfLetExprConseqElse
const &other
)
3644 IfLetExpr::operator= (other
);
3645 // match_arm_patterns = other.match_arm_patterns;
3646 // value = other.value->clone_expr();
3647 // if_block = other.if_block->clone_block_expr();
3648 else_block
= other
.else_block
->clone_block_expr ();
3649 // outer_attrs = other.outer_attrs;
3654 // move constructors
3655 IfLetExprConseqElse (IfLetExprConseqElse
&&other
) = default;
3656 IfLetExprConseqElse
&operator= (IfLetExprConseqElse
&&other
) = default;
3658 void accept_vis (HIRFullVisitor
&vis
) override
;
3659 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3662 /* Use covariance to implement clone function as returning this object rather
3664 IfLetExprConseqElse
*clone_expr_impl () const override
3666 return new IfLetExprConseqElse (*this);
3669 /* Use covariance to implement clone function as returning this object rather
3671 IfLetExprConseqElse
*clone_expr_with_block_impl () const override
3673 return new IfLetExprConseqElse (*this);
3676 /* Use covariance to implement clone function as returning this object rather
3678 IfLetExprConseqElse
*clone_if_let_expr_impl () const override
3680 return new IfLetExprConseqElse (*this);
3684 /* HIR node representing "if let" expression with an "else if" expression at the
3686 class IfLetExprConseqIf
: public IfLetExpr
3688 std::unique_ptr
<IfExpr
> if_expr
;
3691 std::string
as_string () const override
;
3693 IfLetExprConseqIf (Analysis::NodeMapping mappings
,
3694 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
,
3695 std::unique_ptr
<Expr
> value
,
3696 std::unique_ptr
<BlockExpr
> if_block
,
3697 std::unique_ptr
<IfExpr
> if_expr
, Location locus
)
3698 : IfLetExpr (std::move (mappings
), std::move (match_arm_patterns
),
3699 std::move (value
), std::move (if_block
), locus
),
3700 if_expr (std::move (if_expr
))
3702 // again, outer attributes not allowed
3704 // copy constructor with clone
3705 IfLetExprConseqIf (IfLetExprConseqIf
const &other
)
3706 : IfLetExpr (other
), if_expr (other
.if_expr
->clone_if_expr ())
3709 // overload assignment operator to clone
3710 IfLetExprConseqIf
&operator= (IfLetExprConseqIf
const &other
)
3712 IfLetExpr::operator= (other
);
3713 // match_arm_patterns = other.match_arm_patterns;
3714 // value = other.value->clone_expr();
3715 // if_block = other.if_block->clone_block_expr();
3716 if_expr
= other
.if_expr
->clone_if_expr ();
3721 // move constructors
3722 IfLetExprConseqIf (IfLetExprConseqIf
&&other
) = default;
3723 IfLetExprConseqIf
&operator= (IfLetExprConseqIf
&&other
) = default;
3725 void accept_vis (HIRFullVisitor
&vis
) override
;
3726 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3729 /* Use covariance to implement clone function as returning this object rather
3731 IfLetExprConseqIf
*clone_expr_impl () const override
3733 return new IfLetExprConseqIf (*this);
3736 /* Use covariance to implement clone function as returning this object rather
3738 IfLetExprConseqIf
*clone_expr_with_block_impl () const override
3740 return new IfLetExprConseqIf (*this);
3743 /* Use covariance to implement clone function as returning this object rather
3745 IfLetExprConseqIf
*clone_if_let_expr_impl () const override
3747 return new IfLetExprConseqIf (*this);
3751 /* HIR node representing "if let" expression with an "else if let" expression at
3753 class IfLetExprConseqIfLet
: public IfLetExpr
3755 std::unique_ptr
<IfLetExpr
> if_let_expr
;
3758 std::string
as_string () const override
;
3760 IfLetExprConseqIfLet (
3761 Analysis::NodeMapping mappings
,
3762 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
,
3763 std::unique_ptr
<Expr
> value
, std::unique_ptr
<BlockExpr
> if_block
,
3764 std::unique_ptr
<IfLetExpr
> if_let_expr
, Location locus
)
3765 : IfLetExpr (std::move (mappings
), std::move (match_arm_patterns
),
3766 std::move (value
), std::move (if_block
), locus
),
3767 if_let_expr (std::move (if_let_expr
))
3769 // outer attributes not allowed
3771 // copy constructor with clone
3772 IfLetExprConseqIfLet (IfLetExprConseqIfLet
const &other
)
3773 : IfLetExpr (other
), if_let_expr (other
.if_let_expr
->clone_if_let_expr ())
3776 // overload assignment operator to clone
3777 IfLetExprConseqIfLet
&operator= (IfLetExprConseqIfLet
const &other
)
3779 IfLetExpr::operator= (other
);
3780 // match_arm_patterns = other.match_arm_patterns;
3781 // value = other.value->clone_expr();
3782 // if_block = other.if_block->clone_block_expr();
3783 if_let_expr
= other
.if_let_expr
->clone_if_let_expr ();
3788 // move constructors
3789 IfLetExprConseqIfLet (IfLetExprConseqIfLet
&&other
) = default;
3790 IfLetExprConseqIfLet
&operator= (IfLetExprConseqIfLet
&&other
) = default;
3792 void accept_vis (HIRFullVisitor
&vis
) override
;
3793 void accept_vis (HIRExpressionVisitor
&vis
) override
;
3796 /* Use covariance to implement clone function as returning this object rather
3798 IfLetExprConseqIfLet
*clone_expr_impl () const override
3800 return new IfLetExprConseqIfLet (*this);
3803 /* Use covariance to implement clone function as returning this object rather
3805 IfLetExprConseqIfLet
*clone_expr_with_block_impl () const override
3807 return new IfLetExprConseqIfLet (*this);
3810 /* Use covariance to implement clone function as returning this object rather
3812 IfLetExprConseqIfLet
*clone_if_let_expr_impl () const override
3814 return new IfLetExprConseqIfLet (*this);
3818 // Match arm expression
3822 AST::AttrVec outer_attrs
;
3823 std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
;
3824 std::unique_ptr
<Expr
> guard_expr
;
3828 // Returns whether the MatchArm has a match arm guard expression
3829 bool has_match_arm_guard () const { return guard_expr
!= nullptr; }
3831 // Constructor for match arm with a guard expression
3832 MatchArm (std::vector
<std::unique_ptr
<Pattern
> > match_arm_patterns
,
3833 Location locus
, std::unique_ptr
<Expr
> guard_expr
= nullptr,
3834 AST::AttrVec outer_attrs
= AST::AttrVec ())
3835 : outer_attrs (std::move (outer_attrs
)),
3836 match_arm_patterns (std::move (match_arm_patterns
)),
3837 guard_expr (std::move (guard_expr
)), locus (locus
)
3840 // Copy constructor with clone
3841 MatchArm (MatchArm
const &other
) : outer_attrs (other
.outer_attrs
)
3843 // guard to protect from null pointer dereference
3844 if (other
.guard_expr
!= nullptr)
3845 guard_expr
= other
.guard_expr
->clone_expr ();
3847 match_arm_patterns
.reserve (other
.match_arm_patterns
.size ());
3848 for (const auto &e
: other
.match_arm_patterns
)
3849 match_arm_patterns
.push_back (e
->clone_pattern ());
3851 locus
= other
.locus
;
3854 ~MatchArm () = default;
3856 // Overload assignment operator to clone
3857 MatchArm
&operator= (MatchArm
const &other
)
3859 outer_attrs
= other
.outer_attrs
;
3861 if (other
.guard_expr
!= nullptr)
3862 guard_expr
= other
.guard_expr
->clone_expr ();
3864 match_arm_patterns
.clear ();
3865 match_arm_patterns
.reserve (other
.match_arm_patterns
.size ());
3866 for (const auto &e
: other
.match_arm_patterns
)
3867 match_arm_patterns
.push_back (e
->clone_pattern ());
3872 // move constructors
3873 MatchArm (MatchArm
&&other
) = default;
3874 MatchArm
&operator= (MatchArm
&&other
) = default;
3876 // Returns whether match arm is in an error state.
3877 bool is_error () const { return match_arm_patterns
.empty (); }
3879 // Creates a match arm in an error state.
3880 static MatchArm
create_error ()
3882 Location locus
= Location ();
3883 return MatchArm (std::vector
<std::unique_ptr
<Pattern
> > (), locus
);
3886 std::string
as_string () const;
3888 std::vector
<std::unique_ptr
<Pattern
> > &get_patterns ()
3890 return match_arm_patterns
;
3893 std::unique_ptr
<Expr
> &get_guard_expr ()
3895 rust_assert (has_match_arm_guard ());
3899 Location
get_locus () const { return locus
; }
3902 /* A "match case" - a correlated match arm and resulting expression. Not
3907 Analysis::NodeMapping mappings
;
3909 std::unique_ptr
<Expr
> expr
;
3912 MatchCase (Analysis::NodeMapping mappings
, MatchArm arm
,
3913 std::unique_ptr
<Expr
> expr
)
3914 : mappings (mappings
), arm (std::move (arm
)), expr (std::move (expr
))
3917 MatchCase (const MatchCase
&other
)
3918 : mappings (other
.mappings
), arm (other
.arm
),
3919 expr (other
.expr
->clone_expr ())
3922 MatchCase
&operator= (const MatchCase
&other
)
3924 mappings
= other
.mappings
;
3926 expr
= other
.expr
->clone_expr ();
3931 MatchCase (MatchCase
&&other
) = default;
3932 MatchCase
&operator= (MatchCase
&&other
) = default;
3934 ~MatchCase () = default;
3936 std::string
as_string () const;
3938 Analysis::NodeMapping
get_mappings () const { return mappings
; }
3940 MatchArm
&get_arm () { return arm
; }
3941 std::unique_ptr
<Expr
> &get_expr () { return expr
; }
3944 // Match expression HIR node
3945 class MatchExpr
: public ExprWithBlock
3947 std::unique_ptr
<Expr
> branch_value
;
3948 AST::AttrVec inner_attrs
;
3949 std::vector
<MatchCase
> match_arms
;
3953 std::string
as_string () const override
;
3955 bool has_match_arms () const { return !match_arms
.empty (); }
3957 MatchExpr (Analysis::NodeMapping mappings
, std::unique_ptr
<Expr
> branch_value
,
3958 std::vector
<MatchCase
> match_arms
, AST::AttrVec inner_attrs
,
3959 AST::AttrVec outer_attrs
, Location locus
)
3960 : ExprWithBlock (std::move (mappings
), std::move (outer_attrs
)),
3961 branch_value (std::move (branch_value
)),
3962 inner_attrs (std::move (inner_attrs
)),
3963 match_arms (std::move (match_arms
)), locus (locus
)
3966 // Copy constructor requires clone due to unique_ptr
3967 MatchExpr (MatchExpr
const &other
)
3968 : ExprWithBlock (other
), branch_value (other
.branch_value
->clone_expr ()),
3969 inner_attrs (other
.inner_attrs
), match_arms (other
.match_arms
),
3972 /*match_arms.reserve (other.match_arms.size ());
3973 for (const auto &e : other.match_arms)
3974 match_arms.push_back (e->clone_match_case ());*/
3977 // Overloaded assignment operator to clone due to unique_ptr
3978 MatchExpr
&operator= (MatchExpr
const &other
)
3980 ExprWithBlock::operator= (other
);
3981 branch_value
= other
.branch_value
->clone_expr ();
3982 inner_attrs
= other
.inner_attrs
;
3983 match_arms
= other
.match_arms
;
3984 // outer_attrs = other.outer_attrs;
3985 locus
= other
.locus
;
3987 /*match_arms.reserve (other.match_arms.size ());
3988 for (const auto &e : other.match_arms)
3989 match_arms.push_back (e->clone_match_case ());*/
3994 // move constructors
3995 MatchExpr (MatchExpr
&&other
) = default;
3996 MatchExpr
&operator= (MatchExpr
&&other
) = default;
3998 Location
get_locus () const override final
{ return locus
; }
4000 void accept_vis (HIRFullVisitor
&vis
) override
;
4001 void accept_vis (HIRExpressionVisitor
&vis
) override
;
4003 std::unique_ptr
<Expr
> &get_scrutinee_expr ()
4005 rust_assert (branch_value
!= nullptr);
4006 return branch_value
;
4009 const std::vector
<MatchCase
> &get_match_cases () const { return match_arms
; }
4010 std::vector
<MatchCase
> &get_match_cases () { return match_arms
; }
4012 ExprType
get_expression_type () const final override
4014 return ExprType::Match
;
4018 /* Use covariance to implement clone function as returning this object rather
4020 MatchExpr
*clone_expr_impl () const override
{ return new MatchExpr (*this); }
4022 /* Use covariance to implement clone function as returning this object rather
4024 MatchExpr
*clone_expr_with_block_impl () const override
4026 return new MatchExpr (*this);
4030 // Await expression HIR node (pseudo-member variable access)
4031 class AwaitExpr
: public ExprWithoutBlock
4033 std::unique_ptr
<Expr
> awaited_expr
;
4037 // TODO: ensure outer attributes are actually allowed
4038 AwaitExpr (Analysis::NodeMapping mappings
, std::unique_ptr
<Expr
> awaited_expr
,
4039 AST::AttrVec outer_attrs
, Location locus
)
4040 : ExprWithoutBlock (std::move (mappings
), std::move (outer_attrs
)),
4041 awaited_expr (std::move (awaited_expr
)), locus (locus
)
4044 // copy constructor with clone
4045 AwaitExpr (AwaitExpr
const &other
)
4046 : ExprWithoutBlock (other
),
4047 awaited_expr (other
.awaited_expr
->clone_expr ()), locus (other
.locus
)
4050 // overloaded assignment operator with clone
4051 AwaitExpr
&operator= (AwaitExpr
const &other
)
4053 ExprWithoutBlock::operator= (other
);
4054 awaited_expr
= other
.awaited_expr
->clone_expr ();
4055 locus
= other
.locus
;
4060 // move constructors
4061 AwaitExpr (AwaitExpr
&&other
) = default;
4062 AwaitExpr
&operator= (AwaitExpr
&&other
) = default;
4064 std::string
as_string () const override
;
4066 Location
get_locus () const override final
{ return locus
; }
4068 void accept_vis (HIRFullVisitor
&vis
) override
;
4069 void accept_vis (HIRExpressionVisitor
&vis
) override
;
4071 ExprType
get_expression_type () const final override
4073 return ExprType::Await
;
4077 /* Use covariance to implement clone function as returning this object rather
4079 AwaitExpr
*clone_expr_without_block_impl () const override
4081 return new AwaitExpr (*this);
4085 // Async block expression HIR node (block expr that evaluates to a future)
4086 class AsyncBlockExpr
: public ExprWithBlock
4089 std::unique_ptr
<BlockExpr
> block_expr
;
4093 AsyncBlockExpr (Analysis::NodeMapping mappings
,
4094 std::unique_ptr
<BlockExpr
> block_expr
, bool has_move
,
4095 AST::AttrVec outer_attrs
, Location locus
)
4096 : ExprWithBlock (std::move (mappings
), std::move (outer_attrs
)),
4097 has_move (has_move
), block_expr (std::move (block_expr
)), locus (locus
)
4100 // copy constructor with clone
4101 AsyncBlockExpr (AsyncBlockExpr
const &other
)
4102 : ExprWithBlock (other
), has_move (other
.has_move
),
4103 block_expr (other
.block_expr
->clone_block_expr ()), locus (other
.locus
)
4106 // overloaded assignment operator to clone
4107 AsyncBlockExpr
&operator= (AsyncBlockExpr
const &other
)
4109 ExprWithBlock::operator= (other
);
4110 has_move
= other
.has_move
;
4111 block_expr
= other
.block_expr
->clone_block_expr ();
4112 locus
= other
.locus
;
4117 // move constructors
4118 AsyncBlockExpr (AsyncBlockExpr
&&other
) = default;
4119 AsyncBlockExpr
&operator= (AsyncBlockExpr
&&other
) = default;
4121 std::string
as_string () const override
;
4123 Location
get_locus () const override final
{ return locus
; }
4125 void accept_vis (HIRFullVisitor
&vis
) override
;
4126 void accept_vis (HIRExpressionVisitor
&vis
) override
;
4128 ExprType
get_expression_type () const final override
4130 return ExprType::AsyncBlock
;
4134 /* Use covariance to implement clone function as returning this object rather
4136 AsyncBlockExpr
*clone_expr_with_block_impl () const override
4138 return new AsyncBlockExpr (*this);
4142 // this is a utility helper class for type-checking and code-generation
4143 class OperatorExprMeta
4146 OperatorExprMeta (HIR::CompoundAssignmentExpr
&expr
)
4147 : node_mappings (expr
.get_mappings ()),
4148 lvalue_mappings (expr
.get_expr ()->get_mappings ()),
4149 locus (expr
.get_locus ())
4152 OperatorExprMeta (HIR::ArithmeticOrLogicalExpr
&expr
)
4153 : node_mappings (expr
.get_mappings ()),
4154 lvalue_mappings (expr
.get_expr ()->get_mappings ()),
4155 locus (expr
.get_locus ())
4158 OperatorExprMeta (HIR::NegationExpr
&expr
)
4159 : node_mappings (expr
.get_mappings ()),
4160 lvalue_mappings (expr
.get_expr ()->get_mappings ()),
4161 locus (expr
.get_locus ())
4164 OperatorExprMeta (HIR::DereferenceExpr
&expr
)
4165 : node_mappings (expr
.get_mappings ()),
4166 lvalue_mappings (expr
.get_expr ()->get_mappings ()),
4167 locus (expr
.get_locus ())
4170 OperatorExprMeta (HIR::ArrayIndexExpr
&expr
)
4171 : node_mappings (expr
.get_mappings ()),
4172 lvalue_mappings (expr
.get_array_expr ()->get_mappings ()),
4173 locus (expr
.get_locus ())
4176 const Analysis::NodeMapping
&get_mappings () const { return node_mappings
; }
4178 const Analysis::NodeMapping
&get_lvalue_mappings () const
4180 return lvalue_mappings
;
4183 Location
get_locus () const { return locus
; }
4186 const Analysis::NodeMapping node_mappings
;
4187 const Analysis::NodeMapping lvalue_mappings
;