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