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_PATTERN_H
20 : : #define RUST_HIR_PATTERN_H
21 : :
22 : : #include "rust-hir-pattern-abstract.h"
23 : : #include "rust-common.h"
24 : : #include "rust-hir-literal.h"
25 : : #include "rust-hir-path.h"
26 : :
27 : : namespace Rust {
28 : : namespace HIR {
29 : : // Literal pattern HIR node (comparing to a literal)
30 : : class LiteralPattern : public Pattern
31 : : {
32 : : Literal lit;
33 : : location_t locus;
34 : : Analysis::NodeMapping mappings;
35 : : bool has_minus;
36 : :
37 : : public:
38 : : std::string as_string () const override;
39 : :
40 : : // Constructor for a literal pattern
41 : : LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus)
42 : : : lit (std::move (lit)), locus (locus), mappings (mappings),
43 : : has_minus (false)
44 : : {}
45 : :
46 : 417 : LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus,
47 : : bool has_minus)
48 : 834 : : lit (std::move (lit)), locus (locus), mappings (mappings),
49 : 417 : has_minus (has_minus)
50 : 417 : {}
51 : :
52 : : LiteralPattern (Analysis::NodeMapping mappings, std::string val,
53 : : Literal::LitType type, location_t locus)
54 : : : lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
55 : : locus (locus), mappings (mappings), has_minus (false)
56 : : {}
57 : :
58 : 2519 : location_t get_locus () const override { return locus; }
59 : :
60 : : void accept_vis (HIRFullVisitor &vis) override;
61 : : void accept_vis (HIRPatternVisitor &vis) override;
62 : :
63 : 2597 : const Analysis::NodeMapping &get_mappings () const override final
64 : : {
65 : 2597 : return mappings;
66 : : }
67 : :
68 : 196 : PatternType get_pattern_type () const override final
69 : : {
70 : 196 : return PatternType::LITERAL;
71 : : }
72 : :
73 : 802 : Literal &get_literal () { return lit; }
74 : : const Literal &get_literal () const { return lit; }
75 : :
76 : 393 : bool get_has_minus () const { return has_minus; }
77 : :
78 : : protected:
79 : : /* Use covariance to implement clone function as returning this object rather
80 : : * than base */
81 : 967 : virtual LiteralPattern *clone_pattern_impl () const override
82 : : {
83 : 967 : return new LiteralPattern (*this);
84 : : }
85 : : };
86 : :
87 : : // Identifier pattern HIR node (bind value matched to a variable)
88 : : class IdentifierPattern : public Pattern
89 : : {
90 : : Identifier variable_ident;
91 : : bool is_ref;
92 : : Mutability mut;
93 : : std::unique_ptr<Pattern> subpattern;
94 : : location_t locus;
95 : : Analysis::NodeMapping mappings;
96 : :
97 : : public:
98 : : std::string as_string () const override;
99 : :
100 : : // Returns whether the IdentifierPattern has a pattern to bind.
101 : 210540 : bool has_subpattern () const { return subpattern != nullptr; }
102 : :
103 : : // Constructor
104 : 53461 : IdentifierPattern (Analysis::NodeMapping mappings, Identifier ident,
105 : : location_t locus, bool is_ref = false,
106 : : Mutability mut = Mutability::Imm,
107 : : std::unique_ptr<Pattern> subpattern = nullptr)
108 : 106922 : : variable_ident (std::move (ident)), is_ref (is_ref), mut (mut),
109 : 53461 : subpattern (std::move (subpattern)), locus (locus), mappings (mappings)
110 : 53461 : {}
111 : :
112 : : // Copy constructor with clone
113 : 45591 : IdentifierPattern (IdentifierPattern const &other)
114 : 91182 : : variable_ident (other.variable_ident), is_ref (other.is_ref),
115 : 45591 : mut (other.mut), locus (other.locus), mappings (other.mappings)
116 : : {
117 : : // fix to get prevent null pointer dereference
118 : 45591 : if (other.subpattern != nullptr)
119 : 9 : subpattern = other.subpattern->clone_pattern ();
120 : 45591 : }
121 : :
122 : : // Overload assignment operator to use clone
123 : : IdentifierPattern &operator= (IdentifierPattern const &other)
124 : : {
125 : : variable_ident = other.variable_ident;
126 : : is_ref = other.is_ref;
127 : : mut = other.mut;
128 : : locus = other.locus;
129 : : mappings = other.mappings;
130 : :
131 : : // fix to get prevent null pointer dereference
132 : : if (other.subpattern != nullptr)
133 : : subpattern = other.subpattern->clone_pattern ();
134 : :
135 : : return *this;
136 : : }
137 : :
138 : : // default move semantics
139 : 32197 : IdentifierPattern (IdentifierPattern &&other) = default;
140 : : IdentifierPattern &operator= (IdentifierPattern &&other) = default;
141 : :
142 : 41738 : location_t get_locus () const override { return locus; }
143 : :
144 : 161960 : bool is_mut () const { return mut == Mutability::Mut; }
145 : 51347 : bool get_is_ref () const { return is_ref; }
146 : 58 : Pattern &get_subpattern () { return *subpattern; }
147 : :
148 : : void accept_vis (HIRFullVisitor &vis) override;
149 : : void accept_vis (HIRPatternVisitor &vis) override;
150 : :
151 : 170817 : const Analysis::NodeMapping &get_mappings () const override final
152 : : {
153 : 170817 : return mappings;
154 : : }
155 : :
156 : 21488 : Identifier get_identifier () const { return variable_ident; }
157 : :
158 : 15510 : PatternType get_pattern_type () const override final
159 : : {
160 : 15510 : return PatternType::IDENTIFIER;
161 : : }
162 : :
163 : : protected:
164 : : /* Use covariance to implement clone function as returning this object rather
165 : : * than base */
166 : 45591 : IdentifierPattern *clone_pattern_impl () const override
167 : : {
168 : 45591 : return new IdentifierPattern (*this);
169 : : }
170 : : };
171 : :
172 : : // HIR node for using the '_' wildcard "match any value" pattern
173 : 1207 : class WildcardPattern : public Pattern
174 : : {
175 : : location_t locus;
176 : : Analysis::NodeMapping mappings;
177 : :
178 : : public:
179 : 479 : std::string as_string () const override { return std::string (1, '_'); }
180 : :
181 : 1074 : WildcardPattern (Analysis::NodeMapping mappings, location_t locus)
182 : 1074 : : locus (locus), mappings (mappings)
183 : : {}
184 : :
185 : 2401 : location_t get_locus () const override { return locus; }
186 : :
187 : : void accept_vis (HIRFullVisitor &vis) override;
188 : : void accept_vis (HIRPatternVisitor &vis) override;
189 : :
190 : 6152 : const Analysis::NodeMapping &get_mappings () const override final
191 : : {
192 : 6152 : return mappings;
193 : : }
194 : :
195 : 950 : PatternType get_pattern_type () const override final
196 : : {
197 : 950 : return PatternType::WILDCARD;
198 : : }
199 : :
200 : : protected:
201 : : /* Use covariance to implement clone function as returning this object rather
202 : : * than base */
203 : 1207 : WildcardPattern *clone_pattern_impl () const override
204 : : {
205 : 1207 : return new WildcardPattern (*this);
206 : : }
207 : : };
208 : :
209 : : // Base range pattern bound (lower or upper limit) - abstract
210 : 360 : class RangePatternBound
211 : : {
212 : : public:
213 : : enum RangePatternBoundType
214 : : {
215 : : LITERAL,
216 : : PATH,
217 : : QUALPATH
218 : : };
219 : :
220 : : virtual ~RangePatternBound () {}
221 : :
222 : : // Unique pointer custom clone function
223 : 284 : std::unique_ptr<RangePatternBound> clone_range_pattern_bound () const
224 : : {
225 : 142 : return std::unique_ptr<RangePatternBound> (
226 : 142 : clone_range_pattern_bound_impl ());
227 : : }
228 : :
229 : : virtual std::string as_string () const = 0;
230 : :
231 : : virtual void accept_vis (HIRFullVisitor &vis) = 0;
232 : :
233 : : virtual RangePatternBoundType get_bound_type () const = 0;
234 : :
235 : : protected:
236 : : // pure virtual as RangePatternBound is abstract
237 : : virtual RangePatternBound *clone_range_pattern_bound_impl () const = 0;
238 : : };
239 : :
240 : : // Literal-based pattern bound
241 : 316 : class RangePatternBoundLiteral : public RangePatternBound
242 : : {
243 : : Literal literal;
244 : : /* Can only be a char, byte, int, or float literal - same impl here as
245 : : * previously */
246 : :
247 : : // Minus prefixed to literal (if integer or floating-point)
248 : : bool has_minus;
249 : :
250 : : location_t locus;
251 : :
252 : : public:
253 : : // Constructor
254 : 55 : RangePatternBoundLiteral (Literal literal, location_t locus,
255 : : bool has_minus = false)
256 : 55 : : literal (literal), has_minus (has_minus), locus (locus)
257 : : {}
258 : :
259 : : std::string as_string () const override;
260 : :
261 : : location_t get_locus () const { return locus; }
262 : :
263 : 110 : Literal get_literal () const { return literal; }
264 : 55 : bool get_has_minus () const { return has_minus; }
265 : :
266 : : void accept_vis (HIRFullVisitor &vis) override;
267 : :
268 : 110 : RangePatternBoundType get_bound_type () const override
269 : : {
270 : 110 : return RangePatternBoundType::LITERAL;
271 : : }
272 : :
273 : : protected:
274 : : /* Use covariance to implement clone function as returning this object rather
275 : : * than base */
276 : 158 : RangePatternBoundLiteral *clone_range_pattern_bound_impl () const override
277 : : {
278 : 158 : return new RangePatternBoundLiteral (*this);
279 : : }
280 : : };
281 : :
282 : : // Path-based pattern bound
283 : 126 : class RangePatternBoundPath : public RangePatternBound
284 : : {
285 : : PathInExpression path;
286 : :
287 : : /* TODO: should this be refactored so that PathInExpression is a subclass of
288 : : * RangePatternBound? */
289 : :
290 : : public:
291 : 21 : RangePatternBoundPath (PathInExpression path) : path (std::move (path)) {}
292 : :
293 : 0 : std::string as_string () const override { return path.as_string (); }
294 : :
295 : : location_t get_locus () const { return path.get_locus (); }
296 : :
297 : 42 : PathInExpression &get_path () { return path; }
298 : : const PathInExpression &get_path () const { return path; }
299 : :
300 : : void accept_vis (HIRFullVisitor &vis) override;
301 : :
302 : 42 : RangePatternBoundType get_bound_type () const override
303 : : {
304 : 42 : return RangePatternBoundType::PATH;
305 : : }
306 : :
307 : : protected:
308 : : /* Use covariance to implement clone function as returning this object rather
309 : : * than base */
310 : 126 : RangePatternBoundPath *clone_range_pattern_bound_impl () const override
311 : : {
312 : 126 : return new RangePatternBoundPath (*this);
313 : : }
314 : : };
315 : :
316 : : // Qualified path-based pattern bound
317 : 0 : class RangePatternBoundQualPath : public RangePatternBound
318 : : {
319 : : QualifiedPathInExpression path;
320 : :
321 : : /* TODO: should this be refactored so that QualifiedPathInExpression is a
322 : : * subclass of RangePatternBound? */
323 : :
324 : : public:
325 : 0 : RangePatternBoundQualPath (QualifiedPathInExpression path)
326 : 0 : : path (std::move (path))
327 : : {}
328 : :
329 : 0 : std::string as_string () const override { return path.as_string (); }
330 : :
331 : : location_t get_locus () const { return path.get_locus (); }
332 : :
333 : : void accept_vis (HIRFullVisitor &vis) override;
334 : :
335 : 0 : QualifiedPathInExpression &get_qualified_path () { return path; }
336 : : const QualifiedPathInExpression &get_qualified_path () const { return path; }
337 : :
338 : 0 : RangePatternBoundType get_bound_type () const override
339 : : {
340 : 0 : return RangePatternBoundType::QUALPATH;
341 : : }
342 : :
343 : : protected:
344 : : /* Use covariance to implement clone function as returning this object rather
345 : : * than base */
346 : 0 : RangePatternBoundQualPath *clone_range_pattern_bound_impl () const override
347 : : {
348 : 0 : return new RangePatternBoundQualPath (*this);
349 : : }
350 : : };
351 : :
352 : : // HIR node for matching within a certain range (range pattern)
353 : : class RangePattern : public Pattern
354 : : {
355 : : std::unique_ptr<RangePatternBound> lower;
356 : : std::unique_ptr<RangePatternBound> upper;
357 : :
358 : : bool has_ellipsis_syntax;
359 : :
360 : : /* location only stored to avoid a dereference - lower pattern should give
361 : : * correct location so maybe change in future */
362 : : location_t locus;
363 : : bool is_inclusive;
364 : : Analysis::NodeMapping mappings;
365 : :
366 : : public:
367 : : std::string as_string () const override;
368 : :
369 : : // Constructor
370 : 38 : RangePattern (Analysis::NodeMapping mappings,
371 : : std::unique_ptr<RangePatternBound> lower,
372 : : std::unique_ptr<RangePatternBound> upper, location_t locus,
373 : : bool is_inclusive, bool has_ellipsis_syntax = false)
374 : 38 : : lower (std::move (lower)), upper (std::move (upper)),
375 : 38 : has_ellipsis_syntax (has_ellipsis_syntax), locus (locus),
376 : 38 : is_inclusive (is_inclusive), mappings (mappings)
377 : : {}
378 : :
379 : : // Copy constructor with clone
380 : 142 : RangePattern (RangePattern const &other)
381 : 284 : : lower (other.lower->clone_range_pattern_bound ()),
382 : 142 : upper (other.upper->clone_range_pattern_bound ()),
383 : 142 : has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus),
384 : 142 : is_inclusive (other.is_inclusive), mappings (other.mappings)
385 : 142 : {}
386 : :
387 : : // Overloaded assignment operator to clone
388 : : RangePattern &operator= (RangePattern const &other)
389 : : {
390 : : lower = other.lower->clone_range_pattern_bound ();
391 : : upper = other.upper->clone_range_pattern_bound ();
392 : : has_ellipsis_syntax = other.has_ellipsis_syntax;
393 : : locus = other.locus;
394 : : is_inclusive = other.is_inclusive;
395 : : mappings = other.mappings;
396 : :
397 : : return *this;
398 : : }
399 : :
400 : : // default move semantics
401 : : RangePattern (RangePattern &&other) = default;
402 : : RangePattern &operator= (RangePattern &&other) = default;
403 : :
404 : 419 : location_t get_locus () const override { return locus; }
405 : :
406 : : void accept_vis (HIRFullVisitor &vis) override;
407 : : void accept_vis (HIRPatternVisitor &vis) override;
408 : :
409 : 0 : bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; };
410 : 38 : bool is_inclusive_range () const { return is_inclusive; }
411 : :
412 : 228 : const Analysis::NodeMapping &get_mappings () const override final
413 : : {
414 : 228 : return mappings;
415 : : }
416 : :
417 : 38 : PatternType get_pattern_type () const override final
418 : : {
419 : 38 : return PatternType::RANGE;
420 : : }
421 : :
422 : 113 : RangePatternBound &get_lower_bound () { return *lower; }
423 : :
424 : 113 : RangePatternBound &get_upper_bound () { return *upper; }
425 : :
426 : : protected:
427 : : /* Use covariance to implement clone function as returning this object rather
428 : : * than base */
429 : 142 : RangePattern *clone_pattern_impl () const override
430 : : {
431 : 142 : return new RangePattern (*this);
432 : : }
433 : : };
434 : :
435 : : // HIR node for pattern based on dereferencing the pointers given
436 : : class ReferencePattern : public Pattern
437 : : {
438 : : Mutability mut;
439 : : std::unique_ptr<Pattern> pattern;
440 : : location_t locus;
441 : : Analysis::NodeMapping mappings;
442 : :
443 : : public:
444 : : std::string as_string () const override;
445 : :
446 : 199 : ReferencePattern (Analysis::NodeMapping mappings,
447 : : std::unique_ptr<Pattern> pattern, Mutability reference_mut,
448 : : location_t locus)
449 : 199 : : mut (reference_mut), pattern (std::move (pattern)), locus (locus),
450 : 199 : mappings (mappings)
451 : : {}
452 : :
453 : : // Copy constructor requires clone
454 : 162 : ReferencePattern (ReferencePattern const &other)
455 : 324 : : mut (other.mut), pattern (other.pattern->clone_pattern ()),
456 : 162 : locus (other.locus), mappings (other.mappings)
457 : 162 : {}
458 : :
459 : : // Overload assignment operator to clone
460 : : ReferencePattern &operator= (ReferencePattern const &other)
461 : : {
462 : : pattern = other.pattern->clone_pattern ();
463 : : mut = other.mut;
464 : : locus = other.locus;
465 : : mappings = other.mappings;
466 : :
467 : : return *this;
468 : : }
469 : :
470 : : // default move semantics
471 : : ReferencePattern (ReferencePattern &&other) = default;
472 : : ReferencePattern &operator= (ReferencePattern &&other) = default;
473 : :
474 : 238 : bool is_mut () const { return mut == Mutability::Mut; }
475 : :
476 : 1 : Mutability get_mutability () const { return mut; }
477 : :
478 : : void accept_vis (HIRFullVisitor &vis) override;
479 : : void accept_vis (HIRPatternVisitor &vis) override;
480 : :
481 : 1113 : const Analysis::NodeMapping &get_mappings () const override final
482 : : {
483 : 1113 : return mappings;
484 : : }
485 : :
486 : 859 : location_t get_locus () const override final { return locus; }
487 : :
488 : 32 : PatternType get_pattern_type () const override final
489 : : {
490 : 32 : return PatternType::REFERENCE;
491 : : }
492 : :
493 : 728 : Pattern &get_referenced_pattern () { return *pattern; }
494 : :
495 : : protected:
496 : : /* Use covariance to implement clone function as returning this object rather
497 : : * than base */
498 : 162 : ReferencePattern *clone_pattern_impl () const override
499 : : {
500 : 162 : return new ReferencePattern (*this);
501 : : }
502 : : };
503 : :
504 : : // Base class for a single field in a struct pattern - abstract
505 : 354 : class StructPatternField
506 : : {
507 : : AST::AttrVec outer_attrs;
508 : : location_t locus;
509 : : Analysis::NodeMapping mappings;
510 : :
511 : : public:
512 : : enum ItemType
513 : : {
514 : : TUPLE_PAT,
515 : : IDENT_PAT,
516 : : IDENT
517 : : };
518 : :
519 : : virtual ~StructPatternField () {}
520 : :
521 : : // Unique pointer custom clone function
522 : 618 : std::unique_ptr<StructPatternField> clone_struct_pattern_field () const
523 : : {
524 : 618 : return std::unique_ptr<StructPatternField> (
525 : 618 : clone_struct_pattern_field_impl ());
526 : : }
527 : :
528 : : virtual std::string as_string () const;
529 : : virtual void accept_vis (HIRFullVisitor &vis) = 0;
530 : : virtual ItemType get_item_type () const = 0;
531 : :
532 : 378 : location_t get_locus () const { return locus; }
533 : 432 : Analysis::NodeMapping get_mappings () const { return mappings; };
534 : 203 : AST::AttrVec get_outer_attrs () { return outer_attrs; }
535 : :
536 : : protected:
537 : 249 : StructPatternField (Analysis::NodeMapping mappings,
538 : : AST::AttrVec outer_attribs, location_t locus)
539 : 249 : : outer_attrs (std::move (outer_attribs)), locus (locus),
540 : 249 : mappings (mappings)
541 : : {}
542 : :
543 : : // Clone function implementation as pure virtual method
544 : : virtual StructPatternField *clone_struct_pattern_field_impl () const = 0;
545 : : };
546 : :
547 : : // Tuple pattern single field in a struct pattern
548 : : class StructPatternFieldTuplePat : public StructPatternField
549 : : {
550 : : TupleIndex index;
551 : : std::unique_ptr<Pattern> tuple_pattern;
552 : :
553 : : public:
554 : 1 : StructPatternFieldTuplePat (Analysis::NodeMapping mappings, TupleIndex index,
555 : : std::unique_ptr<Pattern> tuple_pattern,
556 : : AST::AttrVec outer_attribs, location_t locus)
557 : 1 : : StructPatternField (mappings, std::move (outer_attribs), locus),
558 : 1 : index (index), tuple_pattern (std::move (tuple_pattern))
559 : 1 : {}
560 : :
561 : : // Copy constructor requires clone
562 : 0 : StructPatternFieldTuplePat (StructPatternFieldTuplePat const &other)
563 : 0 : : StructPatternField (other), index (other.index),
564 : 0 : tuple_pattern (other.tuple_pattern->clone_pattern ())
565 : 0 : {}
566 : :
567 : : // Overload assignment operator to perform clone
568 : : StructPatternFieldTuplePat &
569 : : operator= (StructPatternFieldTuplePat const &other)
570 : : {
571 : : StructPatternField::operator= (other);
572 : : tuple_pattern = other.tuple_pattern->clone_pattern ();
573 : : index = other.index;
574 : : // outer_attrs = other.outer_attrs;
575 : :
576 : : return *this;
577 : : }
578 : :
579 : : // default move semantics
580 : : StructPatternFieldTuplePat (StructPatternFieldTuplePat &&other) = default;
581 : : StructPatternFieldTuplePat &operator= (StructPatternFieldTuplePat &&other)
582 : : = default;
583 : :
584 : : std::string as_string () const override;
585 : :
586 : : void accept_vis (HIRFullVisitor &vis) override;
587 : :
588 : 0 : TupleIndex get_index () { return index; }
589 : 0 : Pattern &get_tuple_pattern () { return *tuple_pattern; }
590 : :
591 : 0 : ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
592 : :
593 : : protected:
594 : : /* Use covariance to implement clone function as returning this object rather
595 : : * than base */
596 : 0 : StructPatternFieldTuplePat *clone_struct_pattern_field_impl () const override
597 : : {
598 : 0 : return new StructPatternFieldTuplePat (*this);
599 : : }
600 : : };
601 : :
602 : : // Identifier pattern single field in a struct pattern
603 : : class StructPatternFieldIdentPat : public StructPatternField
604 : : {
605 : : Identifier ident;
606 : : std::unique_ptr<Pattern> ident_pattern;
607 : :
608 : : public:
609 : 150 : StructPatternFieldIdentPat (Analysis::NodeMapping mappings, Identifier ident,
610 : : std::unique_ptr<Pattern> ident_pattern,
611 : : AST::AttrVec outer_attrs, location_t locus)
612 : 150 : : StructPatternField (mappings, std::move (outer_attrs), locus),
613 : 150 : ident (std::move (ident)), ident_pattern (std::move (ident_pattern))
614 : 150 : {}
615 : :
616 : : // Copy constructor requires clone
617 : 177 : StructPatternFieldIdentPat (StructPatternFieldIdentPat const &other)
618 : 354 : : StructPatternField (other), ident (other.ident),
619 : 177 : ident_pattern (other.ident_pattern->clone_pattern ())
620 : 177 : {}
621 : :
622 : : // Overload assignment operator to clone
623 : : StructPatternFieldIdentPat &
624 : : operator= (StructPatternFieldIdentPat const &other)
625 : : {
626 : : StructPatternField::operator= (other);
627 : : ident = other.ident;
628 : : ident_pattern = other.ident_pattern->clone_pattern ();
629 : : // outer_attrs = other.outer_attrs;
630 : :
631 : : return *this;
632 : : }
633 : :
634 : : // default move semantics
635 : : StructPatternFieldIdentPat (StructPatternFieldIdentPat &&other) = default;
636 : : StructPatternFieldIdentPat &operator= (StructPatternFieldIdentPat &&other)
637 : : = default;
638 : :
639 : : std::string as_string () const override;
640 : :
641 : : void accept_vis (HIRFullVisitor &vis) override;
642 : :
643 : 461 : ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
644 : :
645 : 609 : Identifier get_identifier () const { return ident; }
646 : :
647 : 573 : Pattern &get_pattern () { return *ident_pattern; }
648 : :
649 : : protected:
650 : : /* Use covariance to implement clone function as returning this object rather
651 : : * than base */
652 : 177 : StructPatternFieldIdentPat *clone_struct_pattern_field_impl () const override
653 : : {
654 : 177 : return new StructPatternFieldIdentPat (*this);
655 : : }
656 : : };
657 : :
658 : : // Identifier only (with no pattern) single field in a struct pattern
659 : : class StructPatternFieldIdent : public StructPatternField
660 : : {
661 : : bool has_ref;
662 : : Mutability mut;
663 : : Identifier ident;
664 : :
665 : : public:
666 : 98 : StructPatternFieldIdent (Analysis::NodeMapping mappings, Identifier ident,
667 : : bool is_ref, Mutability mut,
668 : : AST::AttrVec outer_attrs, location_t locus)
669 : 98 : : StructPatternField (mappings, std::move (outer_attrs), locus),
670 : 98 : has_ref (is_ref), mut (mut), ident (std::move (ident))
671 : 98 : {}
672 : :
673 : : std::string as_string () const override;
674 : :
675 : 0 : bool is_mut () const { return mut == Mutability::Mut; }
676 : :
677 : : void accept_vis (HIRFullVisitor &vis) override;
678 : :
679 : 351 : ItemType get_item_type () const override final { return ItemType::IDENT; }
680 : 0 : bool get_has_ref () const { return has_ref; }
681 : 357 : Identifier get_identifier () const { return ident; };
682 : :
683 : : protected:
684 : : /* Use covariance to implement clone function as returning this object rather
685 : : * than base */
686 : 441 : StructPatternFieldIdent *clone_struct_pattern_field_impl () const override
687 : : {
688 : 441 : return new StructPatternFieldIdent (*this);
689 : : }
690 : : };
691 : :
692 : : // Elements of a struct pattern
693 : 231 : class StructPatternElements
694 : : {
695 : : std::vector<std::unique_ptr<StructPatternField>> fields;
696 : : bool has_rest_pattern;
697 : :
698 : : public:
699 : : // Returns whether there are any struct pattern fields
700 : 0 : bool has_struct_pattern_fields () const { return !fields.empty (); }
701 : :
702 : : /* Returns whether the struct pattern elements is entirely empty (no fields,
703 : : * no etc). */
704 : 0 : bool is_empty () const { return !has_struct_pattern_fields (); }
705 : :
706 : 142 : bool has_rest () const { return has_rest_pattern; }
707 : :
708 : : // Constructor for StructPatternElements with both (potentially)
709 : : StructPatternElements (
710 : : std::vector<std::unique_ptr<StructPatternField>> fields)
711 : : : fields (std::move (fields)), has_rest_pattern (false)
712 : : {}
713 : :
714 : 150 : StructPatternElements (
715 : : std::vector<std::unique_ptr<StructPatternField>> fields,
716 : : bool has_rest_pattern)
717 : 150 : : fields (std::move (fields)), has_rest_pattern (has_rest_pattern)
718 : : {}
719 : :
720 : : // Copy constructor with vector clone
721 : 351 : StructPatternElements (StructPatternElements const &other)
722 : 351 : {
723 : 351 : fields.reserve (other.fields.size ());
724 : 969 : for (const auto &e : other.fields)
725 : 618 : fields.emplace_back (e->clone_struct_pattern_field ());
726 : 351 : has_rest_pattern = other.has_rest_pattern;
727 : 351 : }
728 : :
729 : : // Overloaded assignment operator with vector clone
730 : : StructPatternElements &operator= (StructPatternElements const &other)
731 : : {
732 : : fields.clear ();
733 : : fields.reserve (other.fields.size ());
734 : : for (const auto &e : other.fields)
735 : : fields.emplace_back (e->clone_struct_pattern_field ());
736 : : has_rest_pattern = other.has_rest_pattern;
737 : : return *this;
738 : : }
739 : :
740 : : // move constructors
741 : 150 : StructPatternElements (StructPatternElements &&other) = default;
742 : : StructPatternElements &operator= (StructPatternElements &&other) = default;
743 : :
744 : : // Creates an empty StructPatternElements
745 : : static StructPatternElements create_empty ()
746 : : {
747 : : return StructPatternElements (
748 : : std::vector<std::unique_ptr<StructPatternField>> ());
749 : : }
750 : :
751 : : std::string as_string () const;
752 : :
753 : 3 : std::vector<std::unique_ptr<StructPatternField>> &get_struct_pattern_fields ()
754 : : {
755 : 527 : return fields;
756 : : }
757 : : };
758 : :
759 : : // Struct pattern HIR node representation
760 : : class StructPattern : public Pattern
761 : : {
762 : : PathInExpression path;
763 : : StructPatternElements elems;
764 : : Analysis::NodeMapping mappings;
765 : :
766 : : public:
767 : : std::string as_string () const override;
768 : :
769 : 150 : StructPattern (Analysis::NodeMapping mappings, PathInExpression struct_path,
770 : : StructPatternElements elems)
771 : 300 : : path (std::move (struct_path)), elems (std::move (elems)),
772 : 150 : mappings (mappings)
773 : 150 : {}
774 : :
775 : 0 : bool has_struct_pattern_elems () const { return !elems.is_empty (); }
776 : :
777 : 409 : location_t get_locus () const override { return path.get_locus (); }
778 : :
779 : : void accept_vis (HIRFullVisitor &vis) override;
780 : : void accept_vis (HIRPatternVisitor &vis) override;
781 : :
782 : 122 : PathInExpression &get_path () { return path; }
783 : 610 : StructPatternElements &get_struct_pattern_elems () { return elems; }
784 : :
785 : 599 : const Analysis::NodeMapping &get_mappings () const override final
786 : : {
787 : 599 : return mappings;
788 : : }
789 : :
790 : 81 : PatternType get_pattern_type () const override final
791 : : {
792 : 81 : return PatternType::STRUCT;
793 : : }
794 : :
795 : : protected:
796 : : /* Use covariance to implement clone function as returning this object rather
797 : : * than base */
798 : 270 : StructPattern *clone_pattern_impl () const override
799 : : {
800 : 270 : return new StructPattern (*this);
801 : : }
802 : : };
803 : :
804 : : // Base abstract class for TupleStructItems, TuplePatternItems &
805 : : // SlicePatternItems
806 : 2463 : class PatternItems : public FullVisitable
807 : : {
808 : : public:
809 : : enum ItemType
810 : : {
811 : : NO_REST,
812 : : HAS_REST,
813 : : };
814 : :
815 : : virtual ~PatternItems () {}
816 : :
817 : : // TODO: should this store location data?
818 : :
819 : : // Unique pointer custom clone function
820 : : std::unique_ptr<PatternItems> clone_pattern_items () const
821 : : {
822 : : return std::unique_ptr<PatternItems> (clone_pattern_items_impl ());
823 : : }
824 : :
825 : : virtual ItemType get_item_type () const = 0;
826 : :
827 : : virtual std::string as_string () const = 0;
828 : :
829 : : protected:
830 : : // pure virtual clone implementation
831 : : virtual PatternItems *clone_pattern_items_impl () const = 0;
832 : : };
833 : :
834 : : // Base abstract class for patterns used in TupleStructPattern
835 : 1732 : class TupleStructItems : public PatternItems
836 : : {
837 : : public:
838 : : // Unique pointer custom clone function
839 : 726 : std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
840 : : {
841 : 726 : return std::unique_ptr<TupleStructItems> (clone_pattern_items_impl ());
842 : : }
843 : :
844 : : protected:
845 : : // pure virtual clone implementation
846 : : virtual TupleStructItems *clone_pattern_items_impl () const override = 0;
847 : : };
848 : :
849 : : // Class for patterns within a tuple struct pattern, without a rest pattern
850 : : class TupleStructItemsNoRest : public TupleStructItems
851 : : {
852 : : std::vector<std::unique_ptr<Pattern>> patterns;
853 : :
854 : : public:
855 : 967 : TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
856 : 967 : : patterns (std::move (patterns))
857 : : {}
858 : :
859 : : // Copy constructor with vector clone
860 : 690 : TupleStructItemsNoRest (TupleStructItemsNoRest const &other)
861 : 690 : {
862 : 690 : patterns.reserve (other.patterns.size ());
863 : 1462 : for (const auto &e : other.patterns)
864 : 772 : patterns.push_back (e->clone_pattern ());
865 : 690 : }
866 : :
867 : : // Overloaded assignment operator with vector clone
868 : : TupleStructItemsNoRest &operator= (TupleStructItemsNoRest const &other)
869 : : {
870 : : patterns.clear ();
871 : : patterns.reserve (other.patterns.size ());
872 : : for (const auto &e : other.patterns)
873 : : patterns.push_back (e->clone_pattern ());
874 : :
875 : : return *this;
876 : : }
877 : :
878 : : // move constructors
879 : : TupleStructItemsNoRest (TupleStructItemsNoRest &&other) = default;
880 : : TupleStructItemsNoRest &operator= (TupleStructItemsNoRest &&other) = default;
881 : :
882 : : std::string as_string () const override;
883 : :
884 : : void accept_vis (HIRFullVisitor &vis) override;
885 : :
886 : 4966 : std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
887 : : const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
888 : : {
889 : : return patterns;
890 : : }
891 : :
892 : 3140 : ItemType get_item_type () const override final { return ItemType::NO_REST; }
893 : :
894 : : protected:
895 : : /* Use covariance to implement clone function as returning this object rather
896 : : * than base */
897 : 690 : TupleStructItemsNoRest *clone_pattern_items_impl () const override
898 : : {
899 : 690 : return new TupleStructItemsNoRest (*this);
900 : : }
901 : : };
902 : :
903 : : // Class for patterns within a tuple struct pattern, with a rest pattern
904 : : // included
905 : : class TupleStructItemsHasRest : public TupleStructItems
906 : : {
907 : : std::vector<std::unique_ptr<Pattern>> lower_patterns;
908 : : std::vector<std::unique_ptr<Pattern>> upper_patterns;
909 : :
910 : : public:
911 : 39 : TupleStructItemsHasRest (std::vector<std::unique_ptr<Pattern>> lower_patterns,
912 : : std::vector<std::unique_ptr<Pattern>> upper_patterns)
913 : 39 : : lower_patterns (std::move (lower_patterns)),
914 : 39 : upper_patterns (std::move (upper_patterns))
915 : : {}
916 : :
917 : : // Copy constructor with vector clone
918 : 36 : TupleStructItemsHasRest (TupleStructItemsHasRest const &other)
919 : 36 : {
920 : 36 : lower_patterns.reserve (other.lower_patterns.size ());
921 : 65 : for (const auto &e : other.lower_patterns)
922 : 29 : lower_patterns.push_back (e->clone_pattern ());
923 : :
924 : 36 : upper_patterns.reserve (other.upper_patterns.size ());
925 : 50 : for (const auto &e : other.upper_patterns)
926 : 14 : upper_patterns.push_back (e->clone_pattern ());
927 : 36 : }
928 : :
929 : : // Overloaded assignment operator to clone
930 : : TupleStructItemsHasRest &operator= (TupleStructItemsHasRest const &other)
931 : : {
932 : : lower_patterns.clear ();
933 : : lower_patterns.reserve (other.lower_patterns.size ());
934 : : for (const auto &e : other.lower_patterns)
935 : : lower_patterns.push_back (e->clone_pattern ());
936 : :
937 : : upper_patterns.clear ();
938 : : upper_patterns.reserve (other.upper_patterns.size ());
939 : : for (const auto &e : other.upper_patterns)
940 : : upper_patterns.push_back (e->clone_pattern ());
941 : :
942 : : return *this;
943 : : }
944 : :
945 : : // move constructors
946 : : TupleStructItemsHasRest (TupleStructItemsHasRest &&other) = default;
947 : : TupleStructItemsHasRest &operator= (TupleStructItemsHasRest &&other)
948 : : = default;
949 : :
950 : : std::string as_string () const override;
951 : :
952 : : void accept_vis (HIRFullVisitor &vis) override;
953 : :
954 : 0 : std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
955 : : {
956 : 182 : return lower_patterns;
957 : : }
958 : : const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
959 : : {
960 : : return lower_patterns;
961 : : }
962 : :
963 : : // TODO: seems kinda dodgy. Think of better way.
964 : 0 : std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
965 : : {
966 : 146 : return upper_patterns;
967 : : }
968 : : const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
969 : : {
970 : : return upper_patterns;
971 : : }
972 : :
973 : 146 : ItemType get_item_type () const override final { return ItemType::HAS_REST; }
974 : :
975 : : protected:
976 : : /* Use covariance to implement clone function as returning this object rather
977 : : * than base */
978 : 36 : TupleStructItemsHasRest *clone_pattern_items_impl () const override
979 : : {
980 : 36 : return new TupleStructItemsHasRest (*this);
981 : : }
982 : : };
983 : :
984 : : // HIR node representing a tuple struct pattern
985 : : class TupleStructPattern : public Pattern
986 : : {
987 : : PathInExpression path;
988 : : std::unique_ptr<TupleStructItems> items;
989 : : Analysis::NodeMapping mappings;
990 : :
991 : : /* TOOD: should this store location data? current accessor uses path location
992 : : * data */
993 : :
994 : : public:
995 : : std::string as_string () const override;
996 : :
997 : 1006 : TupleStructPattern (Analysis::NodeMapping mappings,
998 : : PathInExpression tuple_struct_path,
999 : : std::unique_ptr<TupleStructItems> items)
1000 : 2012 : : path (std::move (tuple_struct_path)), items (std::move (items)),
1001 : 1006 : mappings (mappings)
1002 : 1006 : {}
1003 : :
1004 : : // Copy constructor required to clone
1005 : 726 : TupleStructPattern (TupleStructPattern const &other)
1006 : 726 : : path (other.path), items (other.items->clone_tuple_struct_items ()),
1007 : 726 : mappings (other.mappings)
1008 : 726 : {}
1009 : :
1010 : : // Operator overload assignment operator to clone
1011 : : TupleStructPattern &operator= (TupleStructPattern const &other)
1012 : : {
1013 : : path = other.path;
1014 : : items = other.items->clone_tuple_struct_items ();
1015 : : mappings = other.mappings;
1016 : :
1017 : : return *this;
1018 : : }
1019 : :
1020 : : // move constructors
1021 : : TupleStructPattern (TupleStructPattern &&other) = default;
1022 : : TupleStructPattern &operator= (TupleStructPattern &&other) = default;
1023 : :
1024 : 2344 : location_t get_locus () const override { return path.get_locus (); }
1025 : :
1026 : : void accept_vis (HIRFullVisitor &vis) override;
1027 : : void accept_vis (HIRPatternVisitor &vis) override;
1028 : :
1029 : 914 : PathInExpression &get_path () { return path; }
1030 : :
1031 : 4200 : TupleStructItems &get_items () { return *items; }
1032 : :
1033 : 4029 : const Analysis::NodeMapping &get_mappings () const override final
1034 : : {
1035 : 4029 : return mappings;
1036 : : }
1037 : :
1038 : 821 : PatternType get_pattern_type () const override final
1039 : : {
1040 : 821 : return PatternType::TUPLE_STRUCT;
1041 : : }
1042 : :
1043 : : protected:
1044 : : /* Use covariance to implement clone function as returning this object rather
1045 : : * than base */
1046 : 726 : TupleStructPattern *clone_pattern_impl () const override
1047 : : {
1048 : 726 : return new TupleStructPattern (*this);
1049 : : }
1050 : : };
1051 : :
1052 : : // Base abstract class representing TuplePattern patterns
1053 : 582 : class TuplePatternItems : public PatternItems
1054 : : {
1055 : : public:
1056 : : // Unique pointer custom clone function
1057 : 162 : std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
1058 : : {
1059 : 162 : return std::unique_ptr<TuplePatternItems> (clone_pattern_items_impl ());
1060 : : }
1061 : :
1062 : : protected:
1063 : : // pure virtual clone implementation
1064 : : virtual TuplePatternItems *clone_pattern_items_impl () const override = 0;
1065 : : };
1066 : :
1067 : : // Class representing patterns within a TuplePattern, without a rest pattern
1068 : : class TuplePatternItemsNoRest : public TuplePatternItems
1069 : : {
1070 : : std::vector<std::unique_ptr<Pattern>> patterns;
1071 : :
1072 : : public:
1073 : 393 : TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
1074 : 393 : : patterns (std::move (patterns))
1075 : : {}
1076 : :
1077 : : // Copy constructor with vector clone
1078 : 140 : TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other)
1079 : 140 : {
1080 : 140 : patterns.reserve (other.patterns.size ());
1081 : 427 : for (const auto &e : other.patterns)
1082 : 287 : patterns.push_back (e->clone_pattern ());
1083 : 140 : }
1084 : :
1085 : : // Overloaded assignment operator to vector clone
1086 : : TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest const &other)
1087 : : {
1088 : : patterns.clear ();
1089 : : patterns.reserve (other.patterns.size ());
1090 : : for (const auto &e : other.patterns)
1091 : : patterns.push_back (e->clone_pattern ());
1092 : :
1093 : : return *this;
1094 : : }
1095 : :
1096 : : // move constructors
1097 : : TuplePatternItemsNoRest (TuplePatternItemsNoRest &&other) = default;
1098 : : TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest &&other)
1099 : : = default;
1100 : :
1101 : : std::string as_string () const override;
1102 : :
1103 : : void accept_vis (HIRFullVisitor &vis) override;
1104 : :
1105 : 1724 : ItemType get_item_type () const override { return ItemType::NO_REST; }
1106 : :
1107 : 1822 : std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
1108 : : const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
1109 : : {
1110 : : return patterns;
1111 : : }
1112 : :
1113 : : protected:
1114 : : /* Use covariance to implement clone function as returning this object rather
1115 : : * than base */
1116 : 140 : TuplePatternItemsNoRest *clone_pattern_items_impl () const override
1117 : : {
1118 : 140 : return new TuplePatternItemsNoRest (*this);
1119 : : }
1120 : : };
1121 : :
1122 : : // Class representing patterns within a TuplePattern, with a rest pattern
1123 : : // included
1124 : : class TuplePatternItemsHasRest : public TuplePatternItems
1125 : : {
1126 : : std::vector<std::unique_ptr<Pattern>> lower_patterns;
1127 : : std::vector<std::unique_ptr<Pattern>> upper_patterns;
1128 : :
1129 : : public:
1130 : 27 : TuplePatternItemsHasRest (
1131 : : std::vector<std::unique_ptr<Pattern>> lower_patterns,
1132 : : std::vector<std::unique_ptr<Pattern>> upper_patterns)
1133 : 27 : : lower_patterns (std::move (lower_patterns)),
1134 : 27 : upper_patterns (std::move (upper_patterns))
1135 : : {}
1136 : :
1137 : : // Copy constructor with vector clone
1138 : 22 : TuplePatternItemsHasRest (TuplePatternItemsHasRest const &other)
1139 : 22 : {
1140 : 22 : lower_patterns.reserve (other.lower_patterns.size ());
1141 : 44 : for (const auto &e : other.lower_patterns)
1142 : 22 : lower_patterns.push_back (e->clone_pattern ());
1143 : :
1144 : 22 : upper_patterns.reserve (other.upper_patterns.size ());
1145 : 44 : for (const auto &e : other.upper_patterns)
1146 : 22 : upper_patterns.push_back (e->clone_pattern ());
1147 : 22 : }
1148 : :
1149 : : // Overloaded assignment operator to clone
1150 : : TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest const &other)
1151 : : {
1152 : : lower_patterns.clear ();
1153 : : lower_patterns.reserve (other.lower_patterns.size ());
1154 : : for (const auto &e : other.lower_patterns)
1155 : : lower_patterns.push_back (e->clone_pattern ());
1156 : :
1157 : : lower_patterns.clear ();
1158 : : upper_patterns.reserve (other.upper_patterns.size ());
1159 : : for (const auto &e : other.upper_patterns)
1160 : : upper_patterns.push_back (e->clone_pattern ());
1161 : :
1162 : : return *this;
1163 : : }
1164 : :
1165 : : // move constructors
1166 : : TuplePatternItemsHasRest (TuplePatternItemsHasRest &&other) = default;
1167 : : TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest &&other)
1168 : : = default;
1169 : :
1170 : : std::string as_string () const override;
1171 : :
1172 : : void accept_vis (HIRFullVisitor &vis) override;
1173 : :
1174 : 79 : ItemType get_item_type () const override { return ItemType::HAS_REST; }
1175 : :
1176 : 2 : std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
1177 : : {
1178 : 101 : return lower_patterns;
1179 : : }
1180 : : const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
1181 : : {
1182 : : return lower_patterns;
1183 : : }
1184 : :
1185 : 2 : std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
1186 : : {
1187 : 101 : return upper_patterns;
1188 : : }
1189 : : const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
1190 : : {
1191 : : return upper_patterns;
1192 : : }
1193 : :
1194 : : protected:
1195 : : /* Use covariance to implement clone function as returning this object rather
1196 : : * than base */
1197 : 22 : TuplePatternItemsHasRest *clone_pattern_items_impl () const override
1198 : : {
1199 : 22 : return new TuplePatternItemsHasRest (*this);
1200 : : }
1201 : : };
1202 : :
1203 : : // HIR node representing a tuple pattern
1204 : : class TuplePattern : public Pattern
1205 : : {
1206 : : std::unique_ptr<TuplePatternItems> items;
1207 : : location_t locus;
1208 : : Analysis::NodeMapping mappings;
1209 : :
1210 : : public:
1211 : : std::string as_string () const override;
1212 : :
1213 : : // Returns true if the tuple pattern has items
1214 : 408 : bool has_tuple_pattern_items () const { return items != nullptr; }
1215 : :
1216 : 420 : TuplePattern (Analysis::NodeMapping mappings,
1217 : : std::unique_ptr<TuplePatternItems> items, location_t locus)
1218 : 420 : : items (std::move (items)), locus (locus), mappings (mappings)
1219 : : {}
1220 : :
1221 : : // Copy constructor requires clone
1222 : 162 : TuplePattern (TuplePattern const &other)
1223 : 324 : : items (other.items->clone_tuple_pattern_items ()), locus (other.locus),
1224 : 162 : mappings (other.mappings)
1225 : 162 : {}
1226 : :
1227 : : // Overload assignment operator to clone
1228 : : TuplePattern &operator= (TuplePattern const &other)
1229 : : {
1230 : : items = other.items->clone_tuple_pattern_items ();
1231 : : locus = other.locus;
1232 : : mappings = other.mappings;
1233 : :
1234 : : return *this;
1235 : : }
1236 : :
1237 : 1643 : location_t get_locus () const override { return locus; }
1238 : :
1239 : : void accept_vis (HIRFullVisitor &vis) override;
1240 : : void accept_vis (HIRPatternVisitor &vis) override;
1241 : :
1242 : 2809 : const Analysis::NodeMapping &get_mappings () const override final
1243 : : {
1244 : 2809 : return mappings;
1245 : : }
1246 : :
1247 : 401 : PatternType get_pattern_type () const override final
1248 : : {
1249 : 401 : return PatternType::TUPLE;
1250 : : }
1251 : :
1252 : 3726 : TuplePatternItems &get_items () { return *items; }
1253 : : const TuplePatternItems &get_items () const { return *items; }
1254 : :
1255 : : protected:
1256 : : /* Use covariance to implement clone function as returning this object rather
1257 : : * than base */
1258 : 162 : TuplePattern *clone_pattern_impl () const override
1259 : : {
1260 : 162 : return new TuplePattern (*this);
1261 : : }
1262 : : };
1263 : :
1264 : : // Base abstract class representing SlicePattern patterns
1265 : 149 : class SlicePatternItems : public PatternItems
1266 : : {
1267 : : public:
1268 : : // Unique pointer custom clone function
1269 : 73 : std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
1270 : : {
1271 : 73 : return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ());
1272 : : }
1273 : :
1274 : : protected:
1275 : : // pure virtual clone implementation
1276 : : virtual SlicePatternItems *clone_pattern_items_impl () const override = 0;
1277 : : };
1278 : :
1279 : : // Class representing patterns within a SlicePattern, without a rest pattern
1280 : : class SlicePatternItemsNoRest : public SlicePatternItems
1281 : : {
1282 : : std::vector<std::unique_ptr<Pattern>> patterns;
1283 : :
1284 : : public:
1285 : 32 : SlicePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
1286 : 32 : : patterns (std::move (patterns))
1287 : : {}
1288 : :
1289 : : // Copy constructor with vector clone
1290 : 31 : SlicePatternItemsNoRest (SlicePatternItemsNoRest const &other)
1291 : 31 : {
1292 : 31 : patterns.reserve (other.patterns.size ());
1293 : 92 : for (const auto &e : other.patterns)
1294 : 61 : patterns.push_back (e->clone_pattern ());
1295 : 31 : }
1296 : :
1297 : : // Overloaded assignment operator to vector clone
1298 : : SlicePatternItemsNoRest &operator= (SlicePatternItemsNoRest const &other)
1299 : : {
1300 : : patterns.clear ();
1301 : : patterns.reserve (other.patterns.size ());
1302 : : for (const auto &e : other.patterns)
1303 : : patterns.push_back (e->clone_pattern ());
1304 : :
1305 : : return *this;
1306 : : }
1307 : :
1308 : : // move constructors
1309 : : SlicePatternItemsNoRest (SlicePatternItemsNoRest &&other) = default;
1310 : : SlicePatternItemsNoRest &operator= (SlicePatternItemsNoRest &&other)
1311 : : = default;
1312 : :
1313 : : std::string as_string () const override;
1314 : :
1315 : : void accept_vis (HIRFullVisitor &vis) override;
1316 : :
1317 : 126 : ItemType get_item_type () const override { return ItemType::NO_REST; }
1318 : :
1319 : 125 : std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
1320 : : const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
1321 : : {
1322 : : return patterns;
1323 : : }
1324 : :
1325 : : protected:
1326 : : /* Use covariance to implement clone function as returning this object rather
1327 : : * than base */
1328 : 31 : SlicePatternItemsNoRest *clone_pattern_items_impl () const override
1329 : : {
1330 : 31 : return new SlicePatternItemsNoRest (*this);
1331 : : }
1332 : : };
1333 : :
1334 : : // Class representing patterns within a SlicePattern, with a rest pattern
1335 : : // included
1336 : : class SlicePatternItemsHasRest : public SlicePatternItems
1337 : : {
1338 : : std::vector<std::unique_ptr<Pattern>> lower_patterns;
1339 : : std::vector<std::unique_ptr<Pattern>> upper_patterns;
1340 : :
1341 : : public:
1342 : 44 : SlicePatternItemsHasRest (
1343 : : std::vector<std::unique_ptr<Pattern>> lower_patterns,
1344 : : std::vector<std::unique_ptr<Pattern>> upper_patterns)
1345 : 44 : : lower_patterns (std::move (lower_patterns)),
1346 : 44 : upper_patterns (std::move (upper_patterns))
1347 : : {}
1348 : :
1349 : : // Copy constructor with vector clone
1350 : 42 : SlicePatternItemsHasRest (SlicePatternItemsHasRest const &other)
1351 : 42 : {
1352 : 42 : lower_patterns.reserve (other.lower_patterns.size ());
1353 : 84 : for (const auto &e : other.lower_patterns)
1354 : 42 : lower_patterns.push_back (e->clone_pattern ());
1355 : :
1356 : 42 : upper_patterns.reserve (other.upper_patterns.size ());
1357 : 84 : for (const auto &e : other.upper_patterns)
1358 : 42 : upper_patterns.push_back (e->clone_pattern ());
1359 : 42 : }
1360 : :
1361 : : // Overloaded assignment operator to clone
1362 : : SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest const &other)
1363 : : {
1364 : : lower_patterns.clear ();
1365 : : lower_patterns.reserve (other.lower_patterns.size ());
1366 : : for (const auto &e : other.lower_patterns)
1367 : : lower_patterns.push_back (e->clone_pattern ());
1368 : :
1369 : : lower_patterns.clear ();
1370 : : upper_patterns.reserve (other.upper_patterns.size ());
1371 : : for (const auto &e : other.upper_patterns)
1372 : : upper_patterns.push_back (e->clone_pattern ());
1373 : :
1374 : : return *this;
1375 : : }
1376 : :
1377 : : // move constructors
1378 : : SlicePatternItemsHasRest (SlicePatternItemsHasRest &&other) = default;
1379 : : SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest &&other)
1380 : : = default;
1381 : :
1382 : : std::string as_string () const override;
1383 : :
1384 : : void accept_vis (HIRFullVisitor &vis) override;
1385 : :
1386 : 176 : ItemType get_item_type () const override { return ItemType::HAS_REST; }
1387 : :
1388 : 0 : std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
1389 : : {
1390 : 176 : return lower_patterns;
1391 : : }
1392 : : const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
1393 : : {
1394 : : return lower_patterns;
1395 : : }
1396 : :
1397 : 0 : std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
1398 : : {
1399 : 176 : return upper_patterns;
1400 : : }
1401 : : const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
1402 : : {
1403 : : return upper_patterns;
1404 : : }
1405 : :
1406 : : protected:
1407 : : /* Use covariance to implement clone function as returning this object rather
1408 : : * than base */
1409 : 42 : SlicePatternItemsHasRest *clone_pattern_items_impl () const override
1410 : : {
1411 : 42 : return new SlicePatternItemsHasRest (*this);
1412 : : }
1413 : : };
1414 : :
1415 : : // HIR node representing patterns that can match slices and arrays
1416 : : class SlicePattern : public Pattern
1417 : : {
1418 : : std::unique_ptr<SlicePatternItems> items;
1419 : : location_t locus;
1420 : : Analysis::NodeMapping mappings;
1421 : :
1422 : : public:
1423 : : std::string as_string () const override;
1424 : :
1425 : 76 : SlicePattern (Analysis::NodeMapping mappings,
1426 : : std::unique_ptr<SlicePatternItems> items, location_t locus)
1427 : 76 : : items (std::move (items)), locus (locus), mappings (mappings)
1428 : : {}
1429 : :
1430 : : // Copy constructor requires clone
1431 : 73 : SlicePattern (SlicePattern const &other)
1432 : 146 : : items (other.items->clone_slice_pattern_items ()), locus (other.locus),
1433 : 73 : mappings (other.mappings)
1434 : 73 : {}
1435 : :
1436 : : // Overloaded assignment operator to vector clone
1437 : : SlicePattern &operator= (SlicePattern const &other)
1438 : : {
1439 : : items = other.items->clone_slice_pattern_items ();
1440 : : locus = other.locus;
1441 : : mappings = other.mappings;
1442 : :
1443 : : return *this;
1444 : : }
1445 : :
1446 : : // move constructors
1447 : : SlicePattern (SlicePattern &&other) = default;
1448 : : SlicePattern &operator= (SlicePattern &&other) = default;
1449 : :
1450 : 679 : SlicePatternItems &get_items () { return *items; }
1451 : : const SlicePatternItems &get_items () const { return *items; }
1452 : :
1453 : 882 : location_t get_locus () const override { return locus; }
1454 : :
1455 : : void accept_vis (HIRFullVisitor &vis) override;
1456 : : void accept_vis (HIRPatternVisitor &vis) override;
1457 : :
1458 : 530 : const Analysis::NodeMapping &get_mappings () const override final
1459 : : {
1460 : 530 : return mappings;
1461 : : }
1462 : :
1463 : 75 : PatternType get_pattern_type () const override final
1464 : : {
1465 : 75 : return PatternType::SLICE;
1466 : : }
1467 : :
1468 : : protected:
1469 : : /* Use covariance to implement clone function as returning this object rather
1470 : : * than base */
1471 : 73 : SlicePattern *clone_pattern_impl () const override
1472 : : {
1473 : 73 : return new SlicePattern (*this);
1474 : : }
1475 : : };
1476 : :
1477 : : // HIR node for alternative patterns
1478 : : class AltPattern : public Pattern
1479 : : {
1480 : : std::vector<std::unique_ptr<Pattern>> alts;
1481 : : location_t locus;
1482 : : Analysis::NodeMapping mappings;
1483 : :
1484 : : public:
1485 : : std::string as_string () const override;
1486 : :
1487 : 147 : AltPattern (Analysis::NodeMapping mappings,
1488 : : std::vector<std::unique_ptr<Pattern>> alts, location_t locus)
1489 : 147 : : alts (std::move (alts)), locus (locus), mappings (mappings)
1490 : 147 : {}
1491 : :
1492 : : // Copy constructor with vector clone
1493 : 1 : AltPattern (AltPattern const &other)
1494 : 1 : : locus (other.locus), mappings (other.mappings)
1495 : : {
1496 : 1 : alts.reserve (other.alts.size ());
1497 : 4 : for (const auto &e : other.alts)
1498 : 3 : alts.push_back (e->clone_pattern ());
1499 : 1 : }
1500 : :
1501 : : // Overloaded assignment operator to vector clone
1502 : : AltPattern &operator= (AltPattern const &other)
1503 : : {
1504 : : locus = other.locus;
1505 : : mappings = other.mappings;
1506 : :
1507 : : alts.clear ();
1508 : : alts.reserve (other.alts.size ());
1509 : : for (const auto &e : other.alts)
1510 : : alts.push_back (e->clone_pattern ());
1511 : :
1512 : : return *this;
1513 : : }
1514 : :
1515 : : // move constructors
1516 : : AltPattern (AltPattern &&other) = default;
1517 : : AltPattern &operator= (AltPattern &&other) = default;
1518 : :
1519 : 333 : std::vector<std::unique_ptr<Pattern>> &get_alts () { return alts; }
1520 : : const std::vector<std::unique_ptr<Pattern>> &get_alts () const
1521 : : {
1522 : : return alts;
1523 : : }
1524 : :
1525 : 823 : location_t get_locus () const override { return locus; }
1526 : :
1527 : : void accept_vis (HIRFullVisitor &vis) override;
1528 : : void accept_vis (HIRPatternVisitor &vis) override;
1529 : :
1530 : 991 : const Analysis::NodeMapping &get_mappings () const override final
1531 : : {
1532 : 991 : return mappings;
1533 : : }
1534 : :
1535 : 145 : PatternType get_pattern_type () const override final
1536 : : {
1537 : 145 : return PatternType::ALT;
1538 : : }
1539 : :
1540 : : protected:
1541 : : /* Use covariance to implement clone function as returning this object rather
1542 : : * than base */
1543 : 1 : AltPattern *clone_pattern_impl () const override
1544 : : {
1545 : 1 : return new AltPattern (*this);
1546 : : }
1547 : : };
1548 : :
1549 : : // Moved definition to rust-path.h
1550 : : class PathPattern;
1551 : :
1552 : : // Forward decls for paths (defined in rust-path.h)
1553 : : class PathInExpression;
1554 : : class QualifiedPathInExpression;
1555 : :
1556 : : } // namespace HIR
1557 : : } // namespace Rust
1558 : :
1559 : : #endif
|