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