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