]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/hir/tree/rust-hir-item.h
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / hir / tree / rust-hir-item.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_ITEM_H
20 #define RUST_HIR_ITEM_H
21
22 #include "rust-abi.h"
23 #include "rust-ast-full-decls.h"
24 #include "rust-common.h"
25 #include "rust-hir.h"
26 #include "rust-hir-path.h"
27
28 namespace Rust {
29 namespace HIR {
30 // forward decls
31 class BlockExpr;
32 class TypePath;
33
34 // A type generic parameter (as opposed to a lifetime generic parameter)
35 class TypeParam : public GenericParam
36 {
37 // bool has_outer_attribute;
38 // std::unique_ptr<Attribute> outer_attr;
39 AST::Attribute outer_attr;
40
41 Identifier type_representation;
42
43 // bool has_type_param_bounds;
44 // TypeParamBounds type_param_bounds;
45 std::vector<std::unique_ptr<TypeParamBound>>
46 type_param_bounds; // inlined form
47
48 // bool has_type;
49 std::unique_ptr<Type> type;
50
51 Location locus;
52
53 public:
54 // Returns whether the type of the type param has been specified.
55 bool has_type () const { return type != nullptr; }
56
57 // Returns whether the type param has type param bounds.
58 bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
59
60 // Returns whether the type param has an outer attribute.
61 bool has_outer_attribute () const { return !outer_attr.is_empty (); }
62
63 TypeParam (Analysis::NodeMapping mappings, Identifier type_representation,
64 Location locus = Location (),
65 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds
66 = std::vector<std::unique_ptr<TypeParamBound>> (),
67 std::unique_ptr<Type> type = nullptr,
68 AST::Attribute outer_attr = AST::Attribute::create_empty ())
69 : GenericParam (mappings), outer_attr (std::move (outer_attr)),
70 type_representation (std::move (type_representation)),
71 type_param_bounds (std::move (type_param_bounds)),
72 type (std::move (type)), locus (locus)
73 {}
74
75 // Copy constructor uses clone
76 TypeParam (TypeParam const &other)
77 : GenericParam (other.mappings), outer_attr (other.outer_attr),
78 type_representation (other.type_representation), locus (other.locus)
79 {
80 // guard to prevent null pointer dereference
81 if (other.type != nullptr)
82 type = other.type->clone_type ();
83
84 type_param_bounds.reserve (other.type_param_bounds.size ());
85 for (const auto &e : other.type_param_bounds)
86 type_param_bounds.push_back (e->clone_type_param_bound ());
87 }
88
89 // Overloaded assignment operator to clone
90 TypeParam &operator= (TypeParam const &other)
91 {
92 type_representation = other.type_representation;
93 outer_attr = other.outer_attr;
94 locus = other.locus;
95 mappings = other.mappings;
96
97 // guard to prevent null pointer dereference
98 if (other.type != nullptr)
99 type = other.type->clone_type ();
100 else
101 type = nullptr;
102
103 type_param_bounds.reserve (other.type_param_bounds.size ());
104 for (const auto &e : other.type_param_bounds)
105 type_param_bounds.push_back (e->clone_type_param_bound ());
106
107 return *this;
108 }
109 // move constructors
110 TypeParam (TypeParam &&other) = default;
111 TypeParam &operator= (TypeParam &&other) = default;
112
113 std::string as_string () const override;
114
115 Location get_locus () const override final { return locus; }
116
117 void accept_vis (HIRFullVisitor &vis) override;
118
119 Identifier get_type_representation () const { return type_representation; }
120
121 std::unique_ptr<Type> &get_type ()
122 {
123 rust_assert (type != nullptr);
124 return type;
125 }
126
127 Analysis::NodeMapping get_type_mappings () const
128 {
129 rust_assert (type != nullptr);
130 return type->get_mappings ();
131 }
132
133 std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
134 {
135 return type_param_bounds;
136 }
137
138 protected:
139 // Clone function implementation as (not pure) virtual method
140 TypeParam *clone_generic_param_impl () const override
141 {
142 return new TypeParam (*this);
143 }
144 };
145
146 /* "where" clause item base. Abstract - use LifetimeWhereClauseItem,
147 * TypeBoundWhereClauseItem */
148 class WhereClauseItem
149 {
150 public:
151 enum ItemType
152 {
153 LIFETIME,
154 TYPE_BOUND,
155 };
156
157 virtual ~WhereClauseItem () {}
158
159 // Unique pointer custom clone function
160 std::unique_ptr<WhereClauseItem> clone_where_clause_item () const
161 {
162 return std::unique_ptr<WhereClauseItem> (clone_where_clause_item_impl ());
163 }
164
165 virtual std::string as_string () const = 0;
166
167 virtual void accept_vis (HIRFullVisitor &vis) = 0;
168
169 virtual Analysis::NodeMapping get_mappings () const = 0;
170
171 virtual ItemType get_item_type () const = 0;
172
173 protected:
174 // Clone function implementation as pure virtual method
175 virtual WhereClauseItem *clone_where_clause_item_impl () const = 0;
176 };
177
178 // A lifetime where clause item
179 class LifetimeWhereClauseItem : public WhereClauseItem
180 {
181 Lifetime lifetime;
182 std::vector<Lifetime> lifetime_bounds;
183 Location locus;
184 Analysis::NodeMapping mappings;
185
186 public:
187 LifetimeWhereClauseItem (Analysis::NodeMapping mappings, Lifetime lifetime,
188 std::vector<Lifetime> lifetime_bounds,
189 Location locus)
190 : lifetime (std::move (lifetime)),
191 lifetime_bounds (std::move (lifetime_bounds)), locus (locus),
192 mappings (std::move (mappings))
193 {}
194
195 std::string as_string () const override;
196
197 void accept_vis (HIRFullVisitor &vis) override;
198
199 Lifetime &get_lifetime () { return lifetime; }
200
201 std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
202
203 Analysis::NodeMapping get_mappings () const override final
204 {
205 return mappings;
206 };
207
208 ItemType get_item_type () const override final
209 {
210 return WhereClauseItem::ItemType::LIFETIME;
211 }
212
213 protected:
214 // Clone function implementation as (not pure) virtual method
215 LifetimeWhereClauseItem *clone_where_clause_item_impl () const override
216 {
217 return new LifetimeWhereClauseItem (*this);
218 }
219 };
220
221 // A type bound where clause item
222 class TypeBoundWhereClauseItem : public WhereClauseItem
223 {
224 std::vector<LifetimeParam> for_lifetimes;
225 std::unique_ptr<Type> bound_type;
226 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
227 Analysis::NodeMapping mappings;
228 Location locus;
229
230 public:
231 // Returns whether the item has ForLifetimes
232 bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
233
234 // Returns whether the item has type param bounds
235 bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
236
237 TypeBoundWhereClauseItem (
238 Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes,
239 std::unique_ptr<Type> bound_type,
240 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
241 Location locus)
242 : for_lifetimes (std::move (for_lifetimes)),
243 bound_type (std::move (bound_type)),
244 type_param_bounds (std::move (type_param_bounds)),
245 mappings (std::move (mappings)), locus (locus)
246 {}
247
248 // Copy constructor requires clone
249 TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other)
250 : for_lifetimes (other.for_lifetimes),
251 bound_type (other.bound_type->clone_type ()), mappings (other.mappings)
252 {
253 type_param_bounds.reserve (other.type_param_bounds.size ());
254 for (const auto &e : other.type_param_bounds)
255 type_param_bounds.push_back (e->clone_type_param_bound ());
256 }
257
258 // Overload assignment operator to clone
259 TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other)
260 {
261 mappings = other.mappings;
262 for_lifetimes = other.for_lifetimes;
263 bound_type = other.bound_type->clone_type ();
264 type_param_bounds.reserve (other.type_param_bounds.size ());
265 for (const auto &e : other.type_param_bounds)
266 type_param_bounds.push_back (e->clone_type_param_bound ());
267
268 return *this;
269 }
270
271 // move constructors
272 TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default;
273 TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem &&other)
274 = default;
275
276 std::string as_string () const override;
277
278 void accept_vis (HIRFullVisitor &vis) override;
279
280 std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
281
282 std::unique_ptr<Type> &get_bound_type () { return bound_type; }
283
284 std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
285 {
286 return type_param_bounds;
287 }
288
289 Analysis::NodeMapping get_mappings () const override final
290 {
291 return mappings;
292 };
293
294 ItemType get_item_type () const override final
295 {
296 return WhereClauseItem::ItemType::TYPE_BOUND;
297 }
298
299 protected:
300 // Clone function implementation as (not pure) virtual method
301 TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
302 {
303 return new TypeBoundWhereClauseItem (*this);
304 }
305 };
306
307 // A where clause
308 struct WhereClause
309 {
310 private:
311 std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items;
312
313 // should this store location info?
314
315 public:
316 WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items)
317 : where_clause_items (std::move (where_clause_items))
318 {}
319
320 // copy constructor with vector clone
321 WhereClause (WhereClause const &other)
322 {
323 where_clause_items.reserve (other.where_clause_items.size ());
324 for (const auto &e : other.where_clause_items)
325 where_clause_items.push_back (e->clone_where_clause_item ());
326 }
327
328 // overloaded assignment operator with vector clone
329 WhereClause &operator= (WhereClause const &other)
330 {
331 where_clause_items.reserve (other.where_clause_items.size ());
332 for (const auto &e : other.where_clause_items)
333 where_clause_items.push_back (e->clone_where_clause_item ());
334
335 return *this;
336 }
337
338 // move constructors
339 WhereClause (WhereClause &&other) = default;
340 WhereClause &operator= (WhereClause &&other) = default;
341
342 // Creates a WhereClause with no items.
343 static WhereClause create_empty ()
344 {
345 return WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> ());
346 }
347
348 // Returns whether the WhereClause has no items.
349 bool is_empty () const { return where_clause_items.empty (); }
350
351 std::string as_string () const;
352
353 std::vector<std::unique_ptr<WhereClauseItem>> &get_items ()
354 {
355 return where_clause_items;
356 }
357 const std::vector<std::unique_ptr<WhereClauseItem>> &get_items () const
358 {
359 return where_clause_items;
360 }
361 };
362
363 // A self parameter in a method
364 struct SelfParam
365 {
366 public:
367 enum ImplicitSelfKind
368 {
369 IMM, // self
370 MUT, // mut self
371 IMM_REF, // &self
372 MUT_REF, // &mut self
373 NONE
374 };
375
376 private:
377 ImplicitSelfKind self_kind;
378 Lifetime lifetime;
379 std::unique_ptr<Type> type;
380 Location locus;
381 Analysis::NodeMapping mappings;
382
383 SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind,
384 Lifetime lifetime, Type *type)
385 : self_kind (self_kind), lifetime (std::move (lifetime)), type (type),
386 mappings (mappings)
387 {}
388
389 public:
390 // Type-based self parameter (not ref, no lifetime)
391 SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
392 bool is_mut, Location locus)
393 : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM),
394 lifetime (
395 Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)),
396 type (std::move (type)), locus (locus), mappings (mappings)
397 {}
398
399 // Lifetime-based self parameter (is ref, no type)
400 SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool is_mut,
401 Location locus)
402 : self_kind (is_mut ? ImplicitSelfKind::MUT_REF
403 : ImplicitSelfKind::IMM_REF),
404 lifetime (std::move (lifetime)), locus (locus), mappings (mappings)
405 {}
406
407 // Copy constructor requires clone
408 SelfParam (SelfParam const &other)
409 : self_kind (other.self_kind), lifetime (other.lifetime),
410 locus (other.locus), mappings (other.mappings)
411 {
412 if (other.type != nullptr)
413 type = other.type->clone_type ();
414 }
415
416 // Overload assignment operator to use clone
417 SelfParam &operator= (SelfParam const &other)
418 {
419 if (other.type != nullptr)
420 type = other.type->clone_type ();
421
422 self_kind = other.self_kind;
423 lifetime = other.lifetime;
424 locus = other.locus;
425 mappings = other.mappings;
426
427 return *this;
428 }
429
430 // move constructors
431 SelfParam (SelfParam &&other) = default;
432 SelfParam &operator= (SelfParam &&other) = default;
433
434 static SelfParam error ()
435 {
436 return SelfParam (Analysis::NodeMapping::get_error (),
437 ImplicitSelfKind::NONE, Lifetime::error (), nullptr);
438 }
439
440 // Returns whether the self-param has a type field.
441 bool has_type () const { return type != nullptr; }
442
443 // Returns whether the self-param has a valid lifetime.
444 bool has_lifetime () const { return !lifetime.is_error (); }
445
446 // Returns whether the self-param is in an error state.
447 bool is_error () const { return self_kind == ImplicitSelfKind::NONE; }
448
449 std::string as_string () const;
450
451 Location get_locus () const { return locus; }
452
453 ImplicitSelfKind get_self_kind () const { return self_kind; }
454
455 std::unique_ptr<Type> &get_type ()
456 {
457 rust_assert (has_type ());
458 return type;
459 }
460
461 Analysis::NodeMapping get_mappings () { return mappings; }
462
463 Mutability get_mut () const
464 {
465 return (self_kind == ImplicitSelfKind::MUT
466 || self_kind == ImplicitSelfKind::MUT_REF)
467 ? Mutability::Mut
468 : Mutability::Imm;
469 }
470
471 bool is_mut () const
472 {
473 return self_kind == ImplicitSelfKind::MUT
474 || self_kind == ImplicitSelfKind::MUT_REF;
475 }
476
477 bool is_ref () const
478 {
479 return self_kind == ImplicitSelfKind::IMM_REF
480 || self_kind == ImplicitSelfKind::MUT_REF;
481 }
482 };
483
484 // Qualifiers for function, i.e. const, unsafe, extern etc.
485 struct FunctionQualifiers
486 {
487 private:
488 AsyncConstStatus const_status;
489 Unsafety unsafety;
490 bool has_extern;
491 ABI abi;
492
493 public:
494 FunctionQualifiers (AsyncConstStatus const_status, Unsafety unsafety,
495 bool has_extern, ABI abi)
496 : const_status (const_status), unsafety (unsafety), has_extern (has_extern),
497 abi (abi)
498 {}
499
500 std::string as_string () const;
501
502 AsyncConstStatus get_status () const { return const_status; }
503
504 bool is_const () const { return const_status == AsyncConstStatus::CONST_FN; }
505 bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
506
507 ABI get_abi () const { return abi; }
508 };
509
510 // A function parameter
511 struct FunctionParam
512 {
513 std::unique_ptr<Pattern> param_name;
514 std::unique_ptr<Type> type;
515 Location locus;
516 Analysis::NodeMapping mappings;
517
518 public:
519 FunctionParam (Analysis::NodeMapping mappings,
520 std::unique_ptr<Pattern> param_name,
521 std::unique_ptr<Type> param_type, Location locus)
522 : param_name (std::move (param_name)), type (std::move (param_type)),
523 locus (locus), mappings (mappings)
524 {}
525
526 // Copy constructor uses clone
527 FunctionParam (FunctionParam const &other)
528 : param_name (other.param_name->clone_pattern ()),
529 type (other.type->clone_type ()), locus (other.locus),
530 mappings (other.mappings)
531 {}
532
533 // Overload assignment operator to use clone
534 FunctionParam &operator= (FunctionParam const &other)
535 {
536 param_name = other.param_name->clone_pattern ();
537 type = other.type->clone_type ();
538 locus = other.locus;
539 mappings = other.mappings;
540
541 return *this;
542 }
543
544 // move constructors
545 FunctionParam (FunctionParam &&other) = default;
546 FunctionParam &operator= (FunctionParam &&other) = default;
547
548 std::string as_string () const;
549
550 Location get_locus () const { return locus; }
551
552 Pattern *get_param_name () { return param_name.get (); }
553
554 Type *get_type () { return type.get (); }
555
556 const Analysis::NodeMapping &get_mappings () const { return mappings; }
557 };
558
559 // Visibility of an item
560 struct Visibility
561 {
562 public:
563 enum VisType
564 {
565 PRIVATE,
566 PUBLIC,
567 RESTRICTED,
568 ERROR,
569 };
570
571 private:
572 VisType vis_type;
573 HIR::SimplePath path;
574
575 // should this store location info?
576
577 public:
578 Visibility (VisType vis_type,
579 HIR::SimplePath path = HIR::SimplePath::create_empty ())
580 : vis_type (vis_type), path (std::move (path))
581 {}
582
583 // Returns whether visibility is in an error state.
584 bool is_error () const { return vis_type == ERROR; }
585
586 // Does the current visibility refer to a simple `pub <item>` entirely public
587 bool is_public () const { return vis_type == PUBLIC; }
588
589 // Is the current visibility public restricted to a certain path
590 bool is_restricted () const { return vis_type == RESTRICTED; }
591
592 // Creates an error visibility.
593 static Visibility create_error ()
594 {
595 return Visibility (ERROR, HIR::SimplePath::create_empty ());
596 }
597
598 VisType get_vis_type () const { return vis_type; }
599
600 const HIR::SimplePath &get_path () const
601 {
602 rust_assert (!is_error ());
603 return path;
604 }
605
606 std::string as_string () const;
607 };
608
609 // Item that supports visibility - abstract base class
610 class VisItem : public Item
611 {
612 Visibility visibility;
613
614 protected:
615 // Visibility constructor
616 VisItem (Analysis::NodeMapping mappings, Visibility visibility,
617 AST::AttrVec outer_attrs = AST::AttrVec ())
618 : Item (std::move (mappings), std::move (outer_attrs)),
619 visibility (std::move (visibility))
620 {}
621
622 // Visibility copy constructor
623 VisItem (VisItem const &other) : Item (other), visibility (other.visibility)
624 {}
625
626 // Overload assignment operator to clone
627 VisItem &operator= (VisItem const &other)
628 {
629 Item::operator= (other);
630 visibility = other.visibility;
631 // outer_attrs = other.outer_attrs;
632
633 return *this;
634 }
635
636 // move constructors
637 VisItem (VisItem &&other) = default;
638 VisItem &operator= (VisItem &&other) = default;
639
640 public:
641 using HIR::Stmt::accept_vis;
642
643 BaseKind get_hir_kind () override final { return VIS_ITEM; }
644
645 /* Does the item have some kind of public visibility (non-default
646 * visibility)? */
647 bool has_visibility () const { return !visibility.is_error (); }
648
649 virtual void accept_vis (HIRVisItemVisitor &vis) = 0;
650
651 Visibility &get_visibility () { return visibility; }
652 const Visibility &get_visibility () const { return visibility; }
653
654 std::string as_string () const override;
655 };
656
657 // Rust module item - abstract base class
658 class Module : public VisItem
659 {
660 Identifier module_name;
661 Location locus;
662 // bool has_inner_attrs;
663 AST::AttrVec inner_attrs;
664 // bool has_items;
665 std::vector<std::unique_ptr<Item>> items;
666
667 public:
668 std::string as_string () const override;
669
670 // Returns whether the module has items in its body.
671 bool has_items () const { return !items.empty (); }
672
673 // Returns whether the module has any inner attributes.
674 bool has_inner_attrs () const { return !inner_attrs.empty (); }
675
676 // Full constructor
677 Module (Analysis::NodeMapping mappings, Identifier module_name,
678 Location locus, std::vector<std::unique_ptr<Item>> items,
679 Visibility visibility = Visibility::create_error (),
680 AST::AttrVec inner_attrs = AST::AttrVec (),
681 AST::AttrVec outer_attrs = AST::AttrVec ())
682 : VisItem (std::move (mappings), std::move (visibility),
683 std::move (outer_attrs)),
684 module_name (module_name), locus (locus),
685 inner_attrs (std::move (inner_attrs)), items (std::move (items))
686 {}
687
688 // Copy constructor with vector clone
689 Module (Module const &other)
690 : VisItem (other), inner_attrs (other.inner_attrs)
691 {
692 items.reserve (other.items.size ());
693 for (const auto &e : other.items)
694 items.push_back (e->clone_item ());
695 }
696
697 // Overloaded assignment operator with vector clone
698 Module &operator= (Module const &other)
699 {
700 VisItem::operator= (other);
701 inner_attrs = other.inner_attrs;
702
703 items.reserve (other.items.size ());
704 for (const auto &e : other.items)
705 items.push_back (e->clone_item ());
706
707 return *this;
708 }
709
710 // move constructors
711 Module (Module &&other) = default;
712 Module &operator= (Module &&other) = default;
713
714 void accept_vis (HIRFullVisitor &vis) override;
715 void accept_vis (HIRStmtVisitor &vis) override;
716 void accept_vis (HIRVisItemVisitor &vis) override;
717
718 std::vector<std::unique_ptr<Item>> &get_items () { return items; };
719
720 /* Override that runs the function recursively on all items contained within
721 * the module. */
722 void add_crate_name (std::vector<std::string> &names) const override;
723
724 Location get_locus () const override final { return locus; }
725
726 ItemKind get_item_kind () const override { return ItemKind::Module; }
727
728 protected:
729 /* Use covariance to implement clone function as returning this object
730 * rather than base */
731 Module *clone_item_impl () const override { return new Module (*this); }
732
733 /* Use covariance to implement clone function as returning this object
734 * rather than base */
735 /*virtual Module* clone_statement_impl() const override {
736 return new Module(*this);
737 }*/
738 };
739
740 // Rust extern crate declaration HIR node
741 class ExternCrate : public VisItem
742 {
743 // this is either an identifier or "self", with self parsed to string
744 std::string referenced_crate;
745 // bool has_as_clause;
746 // AsClause as_clause;
747 // this is either an identifier or "_", with _ parsed to string
748 std::string as_clause_name;
749
750 Location locus;
751
752 /* e.g.
753 "extern crate foo as _"
754 "extern crate foo"
755 "extern crate std as cool_std" */
756 public:
757 std::string as_string () const override;
758
759 // Returns whether extern crate declaration has an as clause.
760 bool has_as_clause () const { return !as_clause_name.empty (); }
761
762 /* Returns whether extern crate declaration references the current crate
763 * (i.e. self). */
764 bool references_self () const { return referenced_crate == "self"; }
765
766 // Constructor
767 ExternCrate (Analysis::NodeMapping mappings, std::string referenced_crate,
768 Visibility visibility, AST::AttrVec outer_attrs, Location locus,
769 std::string as_clause_name = std::string ())
770 : VisItem (std::move (mappings), std::move (visibility),
771 std::move (outer_attrs)),
772 referenced_crate (std::move (referenced_crate)),
773 as_clause_name (std::move (as_clause_name)), locus (locus)
774 {}
775
776 Location get_locus () const override final { return locus; }
777
778 ItemKind get_item_kind () const override { return ItemKind::ExternCrate; }
779
780 void accept_vis (HIRFullVisitor &vis) override;
781 void accept_vis (HIRStmtVisitor &vis) override;
782 void accept_vis (HIRVisItemVisitor &vis) override;
783
784 // Override that adds extern crate name in decl to passed list of names.
785 void add_crate_name (std::vector<std::string> &names) const override
786 {
787 names.push_back (referenced_crate);
788 }
789
790 protected:
791 /* Use covariance to implement clone function as returning this object
792 * rather than base */
793 ExternCrate *clone_item_impl () const override
794 {
795 return new ExternCrate (*this);
796 }
797
798 /* Use covariance to implement clone function as returning this object
799 * rather than base */
800 /*virtual ExternCrate* clone_statement_impl() const override {
801 return new ExternCrate(*this);
802 }*/
803 };
804
805 // The path-ish thing referred to in a use declaration - abstract base class
806 class UseTree
807 {
808 Location locus;
809
810 public:
811 virtual ~UseTree () {}
812
813 // Unique pointer custom clone function
814 std::unique_ptr<UseTree> clone_use_tree () const
815 {
816 return std::unique_ptr<UseTree> (clone_use_tree_impl ());
817 }
818
819 virtual std::string as_string () const = 0;
820
821 Location get_locus () const { return locus; }
822
823 virtual void accept_vis (HIRFullVisitor &vis) = 0;
824
825 protected:
826 // Clone function implementation as pure virtual method
827 virtual UseTree *clone_use_tree_impl () const = 0;
828
829 UseTree (Location locus) : locus (locus) {}
830 };
831
832 // Use tree with a glob (wildcard) operator
833 class UseTreeGlob : public UseTree
834 {
835 public:
836 enum PathType
837 {
838 NO_PATH,
839 GLOBAL,
840 PATH_PREFIXED
841 };
842
843 private:
844 PathType glob_type;
845 AST::SimplePath path;
846
847 public:
848 UseTreeGlob (PathType glob_type, AST::SimplePath path, Location locus)
849 : UseTree (locus), glob_type (glob_type), path (std::move (path))
850 {
851 if (this->glob_type != PATH_PREFIXED)
852 {
853 // compiler implementation error if there is a path with a
854 // non-path-prefixed use tree glob
855 gcc_assert (!has_path ());
856 }
857 // TODO: do path-prefixed paths also have to have a path? If so, have an
858 // assert for that too.
859 }
860
861 /* Returns whether has path. Should be made redundant by PathType
862 * PATH_PREFIXED. */
863 bool has_path () const { return !path.is_empty (); }
864
865 std::string as_string () const override;
866
867 void accept_vis (HIRFullVisitor &vis) override;
868
869 /* TODO: find way to ensure only PATH_PREFIXED glob_type has path - factory
870 * methods? */
871 protected:
872 /* Use covariance to implement clone function as returning this object
873 * rather than base */
874 UseTreeGlob *clone_use_tree_impl () const override
875 {
876 return new UseTreeGlob (*this);
877 }
878 };
879
880 // Use tree with a list of paths with a common prefix
881 class UseTreeList : public UseTree
882 {
883 public:
884 enum PathType
885 {
886 NO_PATH,
887 GLOBAL,
888 PATH_PREFIXED
889 };
890
891 private:
892 PathType path_type;
893 AST::SimplePath path;
894
895 std::vector<std::unique_ptr<UseTree>> trees;
896
897 public:
898 UseTreeList (PathType path_type, AST::SimplePath path,
899 std::vector<std::unique_ptr<UseTree>> trees, Location locus)
900 : UseTree (locus), path_type (path_type), path (std::move (path)),
901 trees (std::move (trees))
902 {
903 if (this->path_type != PATH_PREFIXED)
904 {
905 // compiler implementation error if there is a path with a
906 // non-path-prefixed use tree glob
907 gcc_assert (!has_path ());
908 }
909 // TODO: do path-prefixed paths also have to have a path? If so, have an
910 // assert for that too.
911 }
912
913 // copy constructor with vector clone
914 UseTreeList (UseTreeList const &other)
915 : UseTree (other), path_type (other.path_type), path (other.path)
916 {
917 trees.reserve (other.trees.size ());
918 for (const auto &e : other.trees)
919 trees.push_back (e->clone_use_tree ());
920 }
921
922 // overloaded assignment operator with vector clone
923 UseTreeList &operator= (UseTreeList const &other)
924 {
925 UseTree::operator= (other);
926 path_type = other.path_type;
927 path = other.path;
928
929 trees.reserve (other.trees.size ());
930 for (const auto &e : other.trees)
931 trees.push_back (e->clone_use_tree ());
932
933 return *this;
934 }
935
936 // move constructors
937 UseTreeList (UseTreeList &&other) = default;
938 UseTreeList &operator= (UseTreeList &&other) = default;
939
940 // Returns whether has path. Should be made redundant by path_type.
941 bool has_path () const { return !path.is_empty (); }
942
943 // Returns whether has inner tree elements.
944 bool has_trees () const { return !trees.empty (); }
945
946 std::string as_string () const override;
947
948 void accept_vis (HIRFullVisitor &vis) override;
949
950 // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
951 // methods?
952 protected:
953 /* Use covariance to implement clone function as returning this object
954 * rather than base */
955 UseTreeList *clone_use_tree_impl () const override
956 {
957 return new UseTreeList (*this);
958 }
959 };
960
961 // Use tree where it rebinds the module name as something else
962 class UseTreeRebind : public UseTree
963 {
964 public:
965 enum NewBindType
966 {
967 NONE,
968 IDENTIFIER,
969 WILDCARD
970 };
971
972 private:
973 AST::SimplePath path;
974
975 NewBindType bind_type;
976 Identifier identifier; // only if NewBindType is IDENTIFIER
977
978 public:
979 UseTreeRebind (NewBindType bind_type, AST::SimplePath path, Location locus,
980 Identifier identifier = std::string ())
981 : UseTree (locus), path (std::move (path)), bind_type (bind_type),
982 identifier (std::move (identifier))
983 {}
984
985 // Returns whether has path (this should always be true).
986 bool has_path () const { return !path.is_empty (); }
987
988 // Returns whether has identifier (or, rather, is allowed to).
989 bool has_identifier () const { return bind_type == IDENTIFIER; }
990
991 std::string as_string () const override;
992
993 void accept_vis (HIRFullVisitor &vis) override;
994
995 // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
996 // methods?
997 protected:
998 /* Use covariance to implement clone function as returning this object
999 * rather than base */
1000 virtual UseTreeRebind *clone_use_tree_impl () const override
1001 {
1002 return new UseTreeRebind (*this);
1003 }
1004 };
1005
1006 // Rust use declaration (i.e. for modules) HIR node
1007 class UseDeclaration : public VisItem
1008 {
1009 std::unique_ptr<UseTree> use_tree;
1010 Location locus;
1011
1012 public:
1013 std::string as_string () const override;
1014
1015 UseDeclaration (Analysis::NodeMapping mappings,
1016 std::unique_ptr<UseTree> use_tree, Visibility visibility,
1017 AST::AttrVec outer_attrs, Location locus)
1018 : VisItem (std::move (mappings), std::move (visibility),
1019 std::move (outer_attrs)),
1020 use_tree (std::move (use_tree)), locus (locus)
1021 {}
1022
1023 // Copy constructor with clone
1024 UseDeclaration (UseDeclaration const &other)
1025 : VisItem (other), use_tree (other.use_tree->clone_use_tree ()),
1026 locus (other.locus)
1027 {}
1028
1029 // Overloaded assignment operator to clone
1030 UseDeclaration &operator= (UseDeclaration const &other)
1031 {
1032 VisItem::operator= (other);
1033 use_tree = other.use_tree->clone_use_tree ();
1034 // visibility = other.visibility->clone_visibility();
1035 // outer_attrs = other.outer_attrs;
1036 locus = other.locus;
1037
1038 return *this;
1039 }
1040
1041 // move constructors
1042 UseDeclaration (UseDeclaration &&other) = default;
1043 UseDeclaration &operator= (UseDeclaration &&other) = default;
1044
1045 Location get_locus () const override final { return locus; }
1046 ItemKind get_item_kind () const override { return ItemKind::UseDeclaration; }
1047
1048 void accept_vis (HIRFullVisitor &vis) override;
1049 void accept_vis (HIRStmtVisitor &vis) override;
1050 void accept_vis (HIRVisItemVisitor &vis) override;
1051
1052 protected:
1053 /* Use covariance to implement clone function as returning this object
1054 * rather than base */
1055 UseDeclaration *clone_item_impl () const override
1056 {
1057 return new UseDeclaration (*this);
1058 }
1059
1060 /* Use covariance to implement clone function as returning this object
1061 * rather than base */
1062 /*virtual UseDeclaration* clone_statement_impl() const override {
1063 return new UseDeclaration(*this);
1064 }*/
1065 };
1066
1067 class LetStmt;
1068
1069 // Rust function declaration HIR node
1070 class Function : public VisItem, public ImplItem
1071 {
1072 FunctionQualifiers qualifiers;
1073 Identifier function_name;
1074 std::vector<std::unique_ptr<GenericParam>> generic_params;
1075 std::vector<FunctionParam> function_params;
1076 std::unique_ptr<Type> return_type;
1077 WhereClause where_clause;
1078 std::unique_ptr<BlockExpr> function_body;
1079 SelfParam self;
1080 Location locus;
1081
1082 public:
1083 std::string as_string () const override;
1084
1085 // Returns whether function has generic parameters.
1086 bool has_generics () const { return !generic_params.empty (); }
1087
1088 // Returns whether function has regular parameters.
1089 bool has_function_params () const { return !function_params.empty (); }
1090
1091 // Returns whether function has return type - if not, it is void.
1092 bool has_function_return_type () const { return return_type != nullptr; }
1093
1094 // Returns whether function has a where clause.
1095 bool has_where_clause () const { return !where_clause.is_empty (); }
1096
1097 ImplItemType get_impl_item_type () const override final
1098 {
1099 return ImplItem::ImplItemType::FUNCTION;
1100 }
1101
1102 ItemKind get_item_kind () const override { return ItemKind::Function; }
1103
1104 // Mega-constructor with all possible fields
1105 Function (Analysis::NodeMapping mappings, Identifier function_name,
1106 FunctionQualifiers qualifiers,
1107 std::vector<std::unique_ptr<GenericParam>> generic_params,
1108 std::vector<FunctionParam> function_params,
1109 std::unique_ptr<Type> return_type, WhereClause where_clause,
1110 std::unique_ptr<BlockExpr> function_body, Visibility vis,
1111 AST::AttrVec outer_attrs, SelfParam self, Location locus)
1112 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1113 qualifiers (std::move (qualifiers)),
1114 function_name (std::move (function_name)),
1115 generic_params (std::move (generic_params)),
1116 function_params (std::move (function_params)),
1117 return_type (std::move (return_type)),
1118 where_clause (std::move (where_clause)),
1119 function_body (std::move (function_body)), self (std::move (self)),
1120 locus (locus)
1121 {}
1122
1123 // Copy constructor with clone
1124 Function (Function const &other)
1125 : VisItem (other), qualifiers (other.qualifiers),
1126 function_name (other.function_name),
1127 function_params (other.function_params),
1128 where_clause (other.where_clause),
1129 function_body (other.function_body->clone_block_expr ()),
1130 self (other.self), locus (other.locus)
1131 {
1132 // guard to prevent null dereference (always required)
1133 if (other.return_type != nullptr)
1134 return_type = other.return_type->clone_type ();
1135 else
1136 return_type = nullptr;
1137
1138 generic_params.reserve (other.generic_params.size ());
1139 for (const auto &e : other.generic_params)
1140 generic_params.push_back (e->clone_generic_param ());
1141 }
1142
1143 // Overloaded assignment operator to clone
1144 Function &operator= (Function const &other)
1145 {
1146 VisItem::operator= (other);
1147 function_name = other.function_name;
1148 qualifiers = other.qualifiers;
1149 function_params = other.function_params;
1150
1151 // guard to prevent null dereference (always required)
1152 if (other.return_type != nullptr)
1153 return_type = other.return_type->clone_type ();
1154 else
1155 return_type = nullptr;
1156
1157 where_clause = other.where_clause;
1158 function_body = other.function_body->clone_block_expr ();
1159 locus = other.locus;
1160 self = other.self;
1161
1162 generic_params.reserve (other.generic_params.size ());
1163 for (const auto &e : other.generic_params)
1164 generic_params.push_back (e->clone_generic_param ());
1165
1166 return *this;
1167 }
1168
1169 // move constructors
1170 Function (Function &&other) = default;
1171 Function &operator= (Function &&other) = default;
1172
1173 Location get_locus () const override final { return locus; }
1174
1175 void accept_vis (HIRFullVisitor &vis) override;
1176 void accept_vis (HIRImplVisitor &vis) override;
1177 void accept_vis (HIRStmtVisitor &vis) override;
1178 void accept_vis (HIRVisItemVisitor &vis) override;
1179
1180 Analysis::NodeMapping get_impl_mappings () const override
1181 {
1182 return get_mappings ();
1183 };
1184
1185 std::vector<FunctionParam> &get_function_params () { return function_params; }
1186 const std::vector<FunctionParam> &get_function_params () const
1187 {
1188 return function_params;
1189 }
1190
1191 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1192 {
1193 return generic_params;
1194 }
1195 const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
1196 {
1197 return generic_params;
1198 }
1199
1200 // TODO: is this better? Or is a "vis_block" better?
1201 std::unique_ptr<BlockExpr> &get_definition ()
1202 {
1203 rust_assert (function_body != nullptr);
1204 return function_body;
1205 }
1206
1207 const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
1208
1209 Identifier get_function_name () const { return function_name; }
1210
1211 // TODO: is this better? Or is a "vis_block" better?
1212 WhereClause &get_where_clause () { return where_clause; }
1213
1214 bool has_return_type () const { return return_type != nullptr; }
1215
1216 // TODO: is this better? Or is a "vis_block" better?
1217 std::unique_ptr<Type> &get_return_type ()
1218 {
1219 rust_assert (has_return_type ());
1220 return return_type;
1221 }
1222
1223 bool is_method () const { return !self.is_error (); }
1224
1225 SelfParam &get_self_param () { return self; }
1226
1227 protected:
1228 /* Use covariance to implement clone function as returning this object
1229 * rather than base */
1230 Function *clone_item_impl () const override { return new Function (*this); }
1231
1232 /* Use covariance to implement clone function as returning this object
1233 * rather than base */
1234 Function *clone_inherent_impl_item_impl () const override
1235 {
1236 return new Function (*this);
1237 }
1238 };
1239
1240 // Rust type alias (i.e. typedef) HIR node
1241 class TypeAlias : public VisItem, public ImplItem
1242 {
1243 Identifier new_type_name;
1244
1245 // bool has_generics;
1246 // Generics generic_params;
1247 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1248
1249 // bool has_where_clause;
1250 WhereClause where_clause;
1251
1252 std::unique_ptr<Type> existing_type;
1253
1254 Location locus;
1255
1256 public:
1257 std::string as_string () const override;
1258
1259 // Returns whether type alias has generic parameters.
1260 bool has_generics () const { return !generic_params.empty (); }
1261
1262 // Returns whether type alias has a where clause.
1263 bool has_where_clause () const { return !where_clause.is_empty (); }
1264
1265 ImplItemType get_impl_item_type () const override final
1266 {
1267 return ImplItem::ImplItemType::TYPE_ALIAS;
1268 }
1269
1270 // Mega-constructor with all possible fields
1271 TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
1272 std::vector<std::unique_ptr<GenericParam>> generic_params,
1273 WhereClause where_clause, std::unique_ptr<Type> existing_type,
1274 Visibility vis, AST::AttrVec outer_attrs, Location locus)
1275 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1276 new_type_name (std::move (new_type_name)),
1277 generic_params (std::move (generic_params)),
1278 where_clause (std::move (where_clause)),
1279 existing_type (std::move (existing_type)), locus (locus)
1280 {}
1281
1282 // Copy constructor
1283 TypeAlias (TypeAlias const &other)
1284 : VisItem (other), new_type_name (other.new_type_name),
1285 where_clause (other.where_clause),
1286 existing_type (other.existing_type->clone_type ()), locus (other.locus)
1287 {
1288 generic_params.reserve (other.generic_params.size ());
1289 for (const auto &e : other.generic_params)
1290 generic_params.push_back (e->clone_generic_param ());
1291 }
1292
1293 // Overloaded assignment operator to clone
1294 TypeAlias &operator= (TypeAlias const &other)
1295 {
1296 VisItem::operator= (other);
1297 new_type_name = other.new_type_name;
1298 where_clause = other.where_clause;
1299 existing_type = other.existing_type->clone_type ();
1300 locus = other.locus;
1301
1302 generic_params.reserve (other.generic_params.size ());
1303 for (const auto &e : other.generic_params)
1304 generic_params.push_back (e->clone_generic_param ());
1305
1306 return *this;
1307 }
1308
1309 // move constructors
1310 TypeAlias (TypeAlias &&other) = default;
1311 TypeAlias &operator= (TypeAlias &&other) = default;
1312
1313 Location get_locus () const override final { return locus; }
1314
1315 void accept_vis (HIRFullVisitor &vis) override;
1316 void accept_vis (HIRImplVisitor &vis) override;
1317 void accept_vis (HIRStmtVisitor &vis) override;
1318 void accept_vis (HIRVisItemVisitor &vis) override;
1319
1320 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1321 {
1322 return generic_params;
1323 }
1324 const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
1325 {
1326 return generic_params;
1327 }
1328
1329 WhereClause &get_where_clause () { return where_clause; }
1330
1331 std::unique_ptr<Type> &get_type_aliased ()
1332 {
1333 rust_assert (existing_type != nullptr);
1334 return existing_type;
1335 }
1336
1337 Identifier get_new_type_name () const { return new_type_name; }
1338
1339 ItemKind get_item_kind () const override { return ItemKind::TypeAlias; }
1340
1341 Analysis::NodeMapping get_impl_mappings () const override
1342 {
1343 return get_mappings ();
1344 };
1345
1346 protected:
1347 /* Use covariance to implement clone function as returning this object
1348 * rather than base */
1349 TypeAlias *clone_item_impl () const override { return new TypeAlias (*this); }
1350
1351 /* Use covariance to implement clone function as returning this object
1352 * rather than base */
1353 TypeAlias *clone_inherent_impl_item_impl () const override
1354 {
1355 return new TypeAlias (*this);
1356 }
1357 };
1358
1359 // Rust base struct declaration HIR node - abstract base class
1360 class Struct : public VisItem
1361 {
1362 protected:
1363 // protected to enable access by derived classes - allows better as_string
1364 Identifier struct_name;
1365
1366 // bool has_generics;
1367 // Generics generic_params;
1368 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1369
1370 // bool has_where_clause;
1371 WhereClause where_clause;
1372
1373 Location locus;
1374
1375 public:
1376 Identifier get_identifier () const { return struct_name; }
1377
1378 // Returns whether struct has generic parameters.
1379 bool has_generics () const { return !generic_params.empty (); }
1380
1381 // Returns whether struct has a where clause.
1382 bool has_where_clause () const { return !where_clause.is_empty (); }
1383
1384 Location get_locus () const override final { return locus; }
1385 ItemKind get_item_kind () const override { return ItemKind::Struct; }
1386
1387 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1388 {
1389 return generic_params;
1390 }
1391
1392 WhereClause &get_where_clause () { return where_clause; }
1393
1394 protected:
1395 Struct (Analysis::NodeMapping mappings, Identifier struct_name,
1396 std::vector<std::unique_ptr<GenericParam>> generic_params,
1397 WhereClause where_clause, Visibility vis, Location locus,
1398 AST::AttrVec outer_attrs = AST::AttrVec ())
1399 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1400 struct_name (std::move (struct_name)),
1401 generic_params (std::move (generic_params)),
1402 where_clause (std::move (where_clause)), locus (locus)
1403 {}
1404
1405 // Copy constructor with vector clone
1406 Struct (Struct const &other)
1407 : VisItem (other), struct_name (other.struct_name),
1408 where_clause (other.where_clause), locus (other.locus)
1409 {
1410 generic_params.reserve (other.generic_params.size ());
1411 for (const auto &e : other.generic_params)
1412 generic_params.push_back (e->clone_generic_param ());
1413 }
1414
1415 // Overloaded assignment operator with vector clone
1416 Struct &operator= (Struct const &other)
1417 {
1418 VisItem::operator= (other);
1419 struct_name = other.struct_name;
1420 where_clause = other.where_clause;
1421 locus = other.locus;
1422
1423 generic_params.reserve (other.generic_params.size ());
1424 for (const auto &e : other.generic_params)
1425 generic_params.push_back (e->clone_generic_param ());
1426
1427 return *this;
1428 }
1429
1430 // move constructors
1431 Struct (Struct &&other) = default;
1432 Struct &operator= (Struct &&other) = default;
1433 };
1434
1435 // A single field in a struct
1436 struct StructField
1437 {
1438 public:
1439 // bool has_outer_attributes;
1440 AST::AttrVec outer_attrs;
1441
1442 // bool has_visibility;
1443 Visibility visibility;
1444
1445 Identifier field_name;
1446 std::unique_ptr<Type> field_type;
1447
1448 Analysis::NodeMapping mappings;
1449
1450 Location locus;
1451
1452 // Returns whether struct field has any outer attributes.
1453 bool has_outer_attributes () const { return !outer_attrs.empty (); }
1454
1455 // Returns whether struct field has a non-private (non-default) visibility.
1456 bool has_visibility () const { return !visibility.is_error (); }
1457
1458 StructField (Analysis::NodeMapping mappings, Identifier field_name,
1459 std::unique_ptr<Type> field_type, Visibility vis, Location locus,
1460 AST::AttrVec outer_attrs = AST::AttrVec ())
1461 : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
1462 field_name (std::move (field_name)), field_type (std::move (field_type)),
1463 mappings (mappings), locus (locus)
1464 {}
1465
1466 // Copy constructor
1467 StructField (StructField const &other)
1468 : outer_attrs (other.outer_attrs), visibility (other.visibility),
1469 field_name (other.field_name),
1470 field_type (other.field_type->clone_type ()), mappings (other.mappings)
1471 {}
1472
1473 ~StructField () = default;
1474
1475 // Overloaded assignment operator to clone
1476 StructField &operator= (StructField const &other)
1477 {
1478 field_name = other.field_name;
1479 field_type = other.field_type->clone_type ();
1480 visibility = other.visibility;
1481 outer_attrs = other.outer_attrs;
1482 mappings = other.mappings;
1483
1484 return *this;
1485 }
1486
1487 // move constructors
1488 StructField (StructField &&other) = default;
1489 StructField &operator= (StructField &&other) = default;
1490
1491 std::string as_string () const;
1492
1493 Identifier get_field_name () const { return field_name; }
1494
1495 std::unique_ptr<Type> &get_field_type ()
1496 {
1497 rust_assert (field_type != nullptr);
1498 return field_type;
1499 }
1500
1501 Analysis::NodeMapping get_mappings () const { return mappings; }
1502
1503 Location get_locus () { return locus; }
1504
1505 Visibility &get_visibility () { return visibility; }
1506 };
1507
1508 // Rust struct declaration with true struct type HIR node
1509 class StructStruct : public Struct
1510 {
1511 public:
1512 std::vector<StructField> fields;
1513 bool is_unit;
1514
1515 std::string as_string () const override;
1516
1517 // Mega-constructor with all possible fields
1518 StructStruct (Analysis::NodeMapping mappings, std::vector<StructField> fields,
1519 Identifier struct_name,
1520 std::vector<std::unique_ptr<GenericParam>> generic_params,
1521 WhereClause where_clause, bool is_unit, Visibility vis,
1522 AST::AttrVec outer_attrs, Location locus)
1523 : Struct (std::move (mappings), std::move (struct_name),
1524 std::move (generic_params), std::move (where_clause),
1525 std::move (vis), locus, std::move (outer_attrs)),
1526 fields (std::move (fields)), is_unit (is_unit)
1527 {}
1528
1529 // Unit struct constructor
1530 StructStruct (Analysis::NodeMapping mappings, Identifier struct_name,
1531 std::vector<std::unique_ptr<GenericParam>> generic_params,
1532 WhereClause where_clause, Visibility vis,
1533 AST::AttrVec outer_attrs, Location locus)
1534 : Struct (std::move (mappings), std::move (struct_name),
1535 std::move (generic_params), std::move (where_clause),
1536 std::move (vis), locus, std::move (outer_attrs)),
1537 is_unit (true)
1538 {}
1539 // TODO: can a unit struct have generic fields? assuming yes for now.
1540
1541 /* Returns whether the struct is a unit struct - struct defined without
1542 * fields. This is important because it also means an implicit constant of its
1543 * type is defined. */
1544 bool is_unit_struct () const { return is_unit; }
1545
1546 void accept_vis (HIRFullVisitor &vis) override;
1547 void accept_vis (HIRStmtVisitor &vis) override;
1548 void accept_vis (HIRVisItemVisitor &vis) override;
1549
1550 std::vector<StructField> &get_fields () { return fields; }
1551
1552 protected:
1553 /* Use covariance to implement clone function as returning this object
1554 * rather than base */
1555 StructStruct *clone_item_impl () const override
1556 {
1557 return new StructStruct (*this);
1558 }
1559
1560 /* Use covariance to implement clone function as returning this object
1561 * rather than base */
1562 /*virtual StructStruct* clone_statement_impl() const override {
1563 return new StructStruct(*this);
1564 }*/
1565 };
1566
1567 // A single field in a tuple
1568 struct TupleField
1569 {
1570 private:
1571 // bool has_outer_attributes;
1572 AST::AttrVec outer_attrs;
1573
1574 // bool has_visibility;
1575 Visibility visibility;
1576
1577 std::unique_ptr<Type> field_type;
1578
1579 Location locus;
1580
1581 Analysis::NodeMapping mappings;
1582
1583 public:
1584 // Returns whether tuple field has outer attributes.
1585 bool has_outer_attributes () const { return !outer_attrs.empty (); }
1586
1587 /* Returns whether tuple field has a non-default visibility (i.e. a public
1588 * one) */
1589 bool has_visibility () const { return !visibility.is_error (); }
1590
1591 // Complete constructor
1592 TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type,
1593 Visibility vis, Location locus,
1594 AST::AttrVec outer_attrs = AST::AttrVec ())
1595 : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
1596 field_type (std::move (field_type)), locus (locus), mappings (mapping)
1597 {}
1598
1599 // Copy constructor with clone
1600 TupleField (TupleField const &other)
1601 : outer_attrs (other.outer_attrs), visibility (other.visibility),
1602 field_type (other.field_type->clone_type ()), locus (other.locus),
1603 mappings (other.mappings)
1604 {}
1605
1606 ~TupleField () = default;
1607
1608 // Overloaded assignment operator to clone
1609 TupleField &operator= (TupleField const &other)
1610 {
1611 field_type = other.field_type->clone_type ();
1612 visibility = other.visibility;
1613 outer_attrs = other.outer_attrs;
1614 locus = other.locus;
1615 mappings = other.mappings;
1616
1617 return *this;
1618 }
1619
1620 // move constructors
1621 TupleField (TupleField &&other) = default;
1622 TupleField &operator= (TupleField &&other) = default;
1623
1624 // Returns whether tuple field is in an error state.
1625 bool is_error () const { return field_type == nullptr; }
1626
1627 std::string as_string () const;
1628
1629 Analysis::NodeMapping get_mappings () const { return mappings; }
1630
1631 Location get_locus () const { return locus; }
1632
1633 std::unique_ptr<HIR::Type> &get_field_type () { return field_type; }
1634 };
1635
1636 // Rust tuple declared using struct keyword HIR node
1637 class TupleStruct : public Struct
1638 {
1639 std::vector<TupleField> fields;
1640
1641 public:
1642 std::string as_string () const override;
1643
1644 // Mega-constructor with all possible fields
1645 TupleStruct (Analysis::NodeMapping mappings, std::vector<TupleField> fields,
1646 Identifier struct_name,
1647 std::vector<std::unique_ptr<GenericParam>> generic_params,
1648 WhereClause where_clause, Visibility vis,
1649 AST::AttrVec outer_attrs, Location locus)
1650 : Struct (std::move (mappings), std::move (struct_name),
1651 std::move (generic_params), std::move (where_clause),
1652 std::move (vis), locus, std::move (outer_attrs)),
1653 fields (std::move (fields))
1654 {}
1655
1656 void accept_vis (HIRFullVisitor &vis) override;
1657 void accept_vis (HIRStmtVisitor &vis) override;
1658 void accept_vis (HIRVisItemVisitor &vis) override;
1659
1660 std::vector<TupleField> &get_fields () { return fields; }
1661 const std::vector<TupleField> &get_fields () const { return fields; }
1662
1663 protected:
1664 /* Use covariance to implement clone function as returning this object
1665 * rather than base */
1666 TupleStruct *clone_item_impl () const override
1667 {
1668 return new TupleStruct (*this);
1669 }
1670
1671 /* Use covariance to implement clone function as returning this object
1672 * rather than base */
1673 /*virtual TupleStruct* clone_statement_impl() const override {
1674 return new TupleStruct(*this);
1675 }*/
1676 };
1677
1678 /* An item used in an "enum" tagged union - not abstract: base represents a
1679 name-only enum. Syntactically EnumItem's can have a Visibility. But not
1680 Semantically. So check there is no Visibility when lowering and make this
1681 an Item, not an VisItem. */
1682 class EnumItem : public Item
1683 {
1684 Identifier variant_name;
1685 Location locus;
1686
1687 public:
1688 virtual ~EnumItem () {}
1689
1690 enum EnumItemKind
1691 {
1692 Named,
1693 Tuple,
1694 Struct,
1695 Discriminant,
1696 };
1697
1698 EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
1699 AST::AttrVec outer_attrs, Location locus)
1700 : Item (std::move (mappings), std::move (outer_attrs)),
1701 variant_name (std::move (variant_name)), locus (locus)
1702 {}
1703
1704 // Unique pointer custom clone function
1705 std::unique_ptr<EnumItem> clone_enum_item () const
1706 {
1707 return std::unique_ptr<EnumItem> (clone_item_impl ());
1708 }
1709
1710 virtual std::string as_string () const override;
1711 virtual EnumItemKind get_enum_item_kind () const { return Named; };
1712
1713 // not pure virtual as not abstract
1714 void accept_vis (HIRFullVisitor &vis) override;
1715 void accept_vis (HIRStmtVisitor &vis) override;
1716 // void accept_vis (HIRVisItemVisitor &vis) override;
1717
1718 Location get_locus () const override { return locus; }
1719
1720 Identifier get_identifier () const { return variant_name; }
1721
1722 ItemKind get_item_kind () const override { return ItemKind::EnumItem; }
1723
1724 protected:
1725 EnumItem *clone_item_impl () const override { return new EnumItem (*this); }
1726 };
1727
1728 // A tuple item used in an "enum" tagged union
1729 class EnumItemTuple : public EnumItem
1730 {
1731 // bool has_tuple_fields;
1732 std::vector<TupleField> tuple_fields;
1733
1734 public:
1735 // Returns whether tuple enum item has tuple fields.
1736 bool has_tuple_fields () const { return !tuple_fields.empty (); }
1737
1738 EnumItemKind get_enum_item_kind () const override
1739 {
1740 return EnumItemKind::Tuple;
1741 }
1742
1743 EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
1744 std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
1745 Location locus)
1746 : EnumItem (std::move (mappings), std::move (variant_name),
1747 std::move (outer_attrs), locus),
1748 tuple_fields (std::move (tuple_fields))
1749 {}
1750
1751 std::string as_string () const override;
1752
1753 void accept_vis (HIRFullVisitor &vis) override;
1754 void accept_vis (HIRStmtVisitor &vis) override;
1755
1756 std::vector<TupleField> &get_tuple_fields () { return tuple_fields; }
1757
1758 protected:
1759 // Clone function implementation as (not pure) virtual method
1760 EnumItemTuple *clone_item_impl () const override
1761 {
1762 return new EnumItemTuple (*this);
1763 }
1764 };
1765
1766 // A struct item used in an "enum" tagged union
1767 class EnumItemStruct : public EnumItem
1768 {
1769 // bool has_struct_fields;
1770 std::vector<StructField> struct_fields;
1771
1772 public:
1773 // Returns whether struct enum item has struct fields.
1774 bool has_struct_fields () const { return !struct_fields.empty (); }
1775
1776 EnumItemKind get_enum_item_kind () const override
1777 {
1778 return EnumItemKind::Struct;
1779 }
1780
1781 EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
1782 std::vector<StructField> struct_fields,
1783 AST::AttrVec outer_attrs, Location locus)
1784 : EnumItem (std::move (mappings), std::move (variant_name),
1785 std::move (outer_attrs), locus),
1786 struct_fields (std::move (struct_fields))
1787 {}
1788
1789 std::string as_string () const override;
1790
1791 void accept_vis (HIRFullVisitor &vis) override;
1792 void accept_vis (HIRStmtVisitor &vis) override;
1793
1794 std::vector<StructField> &get_struct_fields () { return struct_fields; }
1795
1796 protected:
1797 // Clone function implementation as (not pure) virtual method
1798 EnumItemStruct *clone_item_impl () const override
1799 {
1800 return new EnumItemStruct (*this);
1801 }
1802 };
1803
1804 // A discriminant (numbered enum) item used in an "enum" tagged union
1805 class EnumItemDiscriminant : public EnumItem
1806 {
1807 std::unique_ptr<Expr> expression;
1808
1809 public:
1810 EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name,
1811 std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs,
1812 Location locus)
1813 : EnumItem (std::move (mappings), std::move (variant_name),
1814 std::move (outer_attrs), locus),
1815 expression (std::move (expr))
1816 {}
1817
1818 // Copy constructor with clone
1819 EnumItemDiscriminant (EnumItemDiscriminant const &other)
1820 : EnumItem (other), expression (other.expression->clone_expr ())
1821 {}
1822
1823 // Overloaded assignment operator to clone
1824 EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other)
1825 {
1826 EnumItem::operator= (other);
1827 expression = other.expression->clone_expr ();
1828 // variant_name = other.variant_name;
1829 // outer_attrs = other.outer_attrs;
1830
1831 return *this;
1832 }
1833
1834 // move constructors
1835 EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
1836 EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
1837
1838 EnumItemKind get_enum_item_kind () const override
1839 {
1840 return EnumItemKind::Discriminant;
1841 }
1842
1843 std::string as_string () const override;
1844
1845 void accept_vis (HIRFullVisitor &vis) override;
1846 void accept_vis (HIRStmtVisitor &vis) override;
1847
1848 std::unique_ptr<Expr> &get_discriminant_expression () { return expression; }
1849
1850 protected:
1851 // Clone function implementation as (not pure) virtual method
1852 EnumItemDiscriminant *clone_item_impl () const override
1853 {
1854 return new EnumItemDiscriminant (*this);
1855 }
1856 };
1857
1858 // HIR node for Rust "enum" - tagged union
1859 class Enum : public VisItem
1860 {
1861 Identifier enum_name;
1862
1863 // bool has_generics;
1864 // Generics generic_params;
1865 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1866
1867 // bool has_where_clause;
1868 WhereClause where_clause;
1869
1870 std::vector<std::unique_ptr<EnumItem>> items;
1871
1872 Location locus;
1873
1874 public:
1875 std::string as_string () const override;
1876
1877 // Returns whether "enum" has generic parameters.
1878 bool has_generics () const { return !generic_params.empty (); }
1879
1880 // Returns whether "enum" has a where clause.
1881 bool has_where_clause () const { return !where_clause.is_empty (); }
1882
1883 /* Returns whether enum is a "zero-variant" (no possible variant) enum,
1884 * which cannot be instantiated. */
1885 bool is_zero_variant () const { return items.empty (); }
1886
1887 // Mega-constructor
1888 Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis,
1889 std::vector<std::unique_ptr<GenericParam>> generic_params,
1890 WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items,
1891 AST::AttrVec outer_attrs, Location locus)
1892 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1893 enum_name (std::move (enum_name)),
1894 generic_params (std::move (generic_params)),
1895 where_clause (std::move (where_clause)), items (std::move (items)),
1896 locus (locus)
1897 {}
1898
1899 // TODO: constructor with less arguments
1900
1901 // Copy constructor with vector clone
1902 Enum (Enum const &other)
1903 : VisItem (other), enum_name (other.enum_name),
1904 where_clause (other.where_clause), locus (other.locus)
1905 {
1906 generic_params.reserve (other.generic_params.size ());
1907 for (const auto &e : other.generic_params)
1908 generic_params.push_back (e->clone_generic_param ());
1909
1910 items.reserve (other.items.size ());
1911 for (const auto &e : other.items)
1912 items.push_back (e->clone_enum_item ());
1913 }
1914
1915 // Overloaded assignment operator with vector clone
1916 Enum &operator= (Enum const &other)
1917 {
1918 VisItem::operator= (other);
1919 enum_name = other.enum_name;
1920 where_clause = other.where_clause;
1921 locus = other.locus;
1922
1923 generic_params.reserve (other.generic_params.size ());
1924 for (const auto &e : other.generic_params)
1925 generic_params.push_back (e->clone_generic_param ());
1926
1927 items.reserve (other.items.size ());
1928 for (const auto &e : other.items)
1929 items.push_back (e->clone_enum_item ());
1930
1931 return *this;
1932 }
1933
1934 // Move constructors
1935 Enum (Enum &&other) = default;
1936 Enum &operator= (Enum &&other) = default;
1937
1938 Location get_locus () const override final { return locus; }
1939
1940 void accept_vis (HIRFullVisitor &vis) override;
1941 void accept_vis (HIRStmtVisitor &vis) override;
1942 void accept_vis (HIRVisItemVisitor &vis) override;
1943
1944 Identifier get_identifier () const { return enum_name; }
1945 ItemKind get_item_kind () const override { return ItemKind::Enum; }
1946
1947 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1948 {
1949 return generic_params;
1950 }
1951
1952 const std::vector<std::unique_ptr<EnumItem>> &get_variants () const
1953 {
1954 return items;
1955 }
1956
1957 protected:
1958 /* Use covariance to implement clone function as returning this object
1959 * rather than base */
1960 Enum *clone_item_impl () const override { return new Enum (*this); }
1961
1962 /* Use covariance to implement clone function as returning this object
1963 * rather than base */
1964 /*virtual Enum* clone_statement_impl() const override {
1965 return new Enum(*this);
1966 }*/
1967 };
1968
1969 // Rust untagged union used for C compat HIR node
1970 class Union : public VisItem
1971 {
1972 Identifier union_name;
1973
1974 // bool has_generics;
1975 // Generics generic_params;
1976 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1977
1978 // bool has_where_clause;
1979 WhereClause where_clause;
1980
1981 std::vector<StructField> variants;
1982
1983 Location locus;
1984
1985 public:
1986 std::string as_string () const override;
1987
1988 // Returns whether union has generic params.
1989 bool has_generics () const { return !generic_params.empty (); }
1990
1991 // Returns whether union has where clause.
1992 bool has_where_clause () const { return !where_clause.is_empty (); }
1993
1994 Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis,
1995 std::vector<std::unique_ptr<GenericParam>> generic_params,
1996 WhereClause where_clause, std::vector<StructField> variants,
1997 AST::AttrVec outer_attrs, Location locus)
1998 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1999 union_name (std::move (union_name)),
2000 generic_params (std::move (generic_params)),
2001 where_clause (std::move (where_clause)), variants (std::move (variants)),
2002 locus (locus)
2003 {}
2004
2005 // copy constructor with vector clone
2006 Union (Union const &other)
2007 : VisItem (other), union_name (other.union_name),
2008 where_clause (other.where_clause), variants (other.variants),
2009 locus (other.locus)
2010 {
2011 generic_params.reserve (other.generic_params.size ());
2012 for (const auto &e : other.generic_params)
2013 generic_params.push_back (e->clone_generic_param ());
2014 }
2015
2016 // overloaded assignment operator with vector clone
2017 Union &operator= (Union const &other)
2018 {
2019 VisItem::operator= (other);
2020 union_name = other.union_name;
2021 where_clause = other.where_clause;
2022 variants = other.variants;
2023 locus = other.locus;
2024
2025 generic_params.reserve (other.generic_params.size ());
2026 for (const auto &e : other.generic_params)
2027 generic_params.push_back (e->clone_generic_param ());
2028
2029 return *this;
2030 }
2031
2032 // move constructors
2033 Union (Union &&other) = default;
2034 Union &operator= (Union &&other) = default;
2035
2036 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2037 {
2038 return generic_params;
2039 }
2040
2041 Identifier get_identifier () const { return union_name; }
2042
2043 Location get_locus () const override final { return locus; }
2044
2045 void accept_vis (HIRFullVisitor &vis) override;
2046 void accept_vis (HIRStmtVisitor &vis) override;
2047 void accept_vis (HIRVisItemVisitor &vis) override;
2048
2049 std::vector<StructField> &get_variants () { return variants; }
2050
2051 WhereClause &get_where_clause () { return where_clause; }
2052
2053 ItemKind get_item_kind () const override { return ItemKind::Union; }
2054
2055 protected:
2056 /* Use covariance to implement clone function as returning this object
2057 * rather than base */
2058 Union *clone_item_impl () const override { return new Union (*this); }
2059 };
2060
2061 class ConstantItem : public VisItem, public ImplItem
2062 {
2063 Identifier identifier;
2064 std::unique_ptr<Type> type;
2065 std::unique_ptr<Expr> const_expr;
2066 Location locus;
2067
2068 public:
2069 std::string as_string () const override;
2070
2071 ConstantItem (Analysis::NodeMapping mappings, Identifier ident,
2072 Visibility vis, std::unique_ptr<Type> type,
2073 std::unique_ptr<Expr> const_expr, AST::AttrVec outer_attrs,
2074 Location locus)
2075 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2076 identifier (std::move (ident)), type (std::move (type)),
2077 const_expr (std::move (const_expr)), locus (locus)
2078 {}
2079
2080 ConstantItem (ConstantItem const &other)
2081 : VisItem (other), identifier (other.identifier),
2082 type (other.type->clone_type ()),
2083 const_expr (other.const_expr->clone_expr ()), locus (other.locus)
2084 {}
2085
2086 // Overload assignment operator to clone
2087 ConstantItem &operator= (ConstantItem const &other)
2088 {
2089 VisItem::operator= (other);
2090 identifier = other.identifier;
2091 type = other.type->clone_type ();
2092 const_expr = other.const_expr->clone_expr ();
2093 locus = other.locus;
2094
2095 return *this;
2096 }
2097
2098 // move constructors
2099 ConstantItem (ConstantItem &&other) = default;
2100 ConstantItem &operator= (ConstantItem &&other) = default;
2101
2102 // Returns whether constant item is an "unnamed" (wildcard underscore used
2103 // as identifier) constant.
2104 bool is_unnamed () const { return identifier == std::string ("_"); }
2105
2106 Location get_locus () const override final { return locus; }
2107
2108 void accept_vis (HIRFullVisitor &vis) override;
2109 void accept_vis (HIRStmtVisitor &vis) override;
2110 void accept_vis (HIRImplVisitor &vis) override;
2111 void accept_vis (HIRVisItemVisitor &vis) override;
2112
2113 Type *get_type () { return type.get (); }
2114
2115 Expr *get_expr () { return const_expr.get (); }
2116
2117 std::string get_identifier () { return identifier; }
2118
2119 Analysis::NodeMapping get_impl_mappings () const override
2120 {
2121 return get_mappings ();
2122 };
2123
2124 ImplItemType get_impl_item_type () const override final
2125 {
2126 return ImplItem::ImplItemType::CONSTANT;
2127 }
2128
2129 ItemKind get_item_kind () const override { return ItemKind::Constant; }
2130
2131 protected:
2132 /* Use covariance to implement clone function as returning this object
2133 * rather than base */
2134 ConstantItem *clone_item_impl () const override
2135 {
2136 return new ConstantItem (*this);
2137 }
2138
2139 /* Use covariance to implement clone function as returning this object
2140 * rather than base */
2141 ConstantItem *clone_inherent_impl_item_impl () const override
2142 {
2143 return new ConstantItem (*this);
2144 }
2145 };
2146
2147 /* Static item HIR node - items within module scope with fixed storage
2148 * duration? */
2149 class StaticItem : public VisItem
2150 {
2151 Mutability mut;
2152 Identifier name;
2153 std::unique_ptr<Type> type;
2154 std::unique_ptr<Expr> expr;
2155 Location locus;
2156
2157 public:
2158 std::string as_string () const override;
2159
2160 StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut,
2161 std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
2162 Visibility vis, AST::AttrVec outer_attrs, Location locus)
2163 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2164 mut (mut), name (std::move (name)), type (std::move (type)),
2165 expr (std::move (expr)), locus (locus)
2166 {}
2167
2168 // Copy constructor with clone
2169 StaticItem (StaticItem const &other)
2170 : VisItem (other), mut (other.mut), name (other.name),
2171 type (other.type->clone_type ()), expr (other.expr->clone_expr ()),
2172 locus (other.locus)
2173 {}
2174
2175 // Overloaded assignment operator to clone
2176 StaticItem &operator= (StaticItem const &other)
2177 {
2178 VisItem::operator= (other);
2179 name = other.name;
2180 mut = other.mut;
2181 type = other.type->clone_type ();
2182 expr = other.expr->clone_expr ();
2183 locus = other.locus;
2184
2185 return *this;
2186 }
2187
2188 // move constructors
2189 StaticItem (StaticItem &&other) = default;
2190 StaticItem &operator= (StaticItem &&other) = default;
2191
2192 Location get_locus () const override final { return locus; }
2193
2194 void accept_vis (HIRFullVisitor &vis) override;
2195 void accept_vis (HIRStmtVisitor &vis) override;
2196 void accept_vis (HIRVisItemVisitor &vis) override;
2197
2198 Identifier get_identifier () const { return name; }
2199
2200 Mutability get_mut () const { return mut; }
2201
2202 bool is_mut () const { return mut == Mutability::Mut; }
2203
2204 Expr *get_expr () { return expr.get (); }
2205
2206 Type *get_type () { return type.get (); }
2207
2208 ItemKind get_item_kind () const override { return ItemKind::Static; }
2209
2210 protected:
2211 StaticItem *clone_item_impl () const override
2212 {
2213 return new StaticItem (*this);
2214 }
2215 };
2216
2217 // Function declaration in traits
2218 struct TraitFunctionDecl
2219 {
2220 private:
2221 FunctionQualifiers qualifiers;
2222 Identifier function_name;
2223 std::vector<std::unique_ptr<GenericParam>> generic_params;
2224 std::vector<FunctionParam> function_params;
2225 std::unique_ptr<Type> return_type;
2226 WhereClause where_clause;
2227 SelfParam self;
2228
2229 public:
2230 // Mega-constructor
2231 TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
2232 std::vector<std::unique_ptr<GenericParam>> generic_params,
2233 SelfParam self, std::vector<FunctionParam> function_params,
2234 std::unique_ptr<Type> return_type,
2235 WhereClause where_clause)
2236 : qualifiers (std::move (qualifiers)),
2237 function_name (std::move (function_name)),
2238 generic_params (std::move (generic_params)),
2239 function_params (std::move (function_params)),
2240 return_type (std::move (return_type)),
2241 where_clause (std::move (where_clause)), self (std::move (self))
2242 {}
2243
2244 // Copy constructor with clone
2245 TraitFunctionDecl (TraitFunctionDecl const &other)
2246 : qualifiers (other.qualifiers), function_name (other.function_name),
2247 function_params (other.function_params),
2248 return_type (other.return_type->clone_type ()),
2249 where_clause (other.where_clause), self (other.self)
2250 {
2251 generic_params.reserve (other.generic_params.size ());
2252 for (const auto &e : other.generic_params)
2253 generic_params.push_back (e->clone_generic_param ());
2254 }
2255
2256 ~TraitFunctionDecl () = default;
2257
2258 // Overloaded assignment operator with clone
2259 TraitFunctionDecl &operator= (TraitFunctionDecl const &other)
2260 {
2261 function_name = other.function_name;
2262 qualifiers = other.qualifiers;
2263 function_params = other.function_params;
2264 return_type = other.return_type->clone_type ();
2265 where_clause = other.where_clause;
2266 self = other.self;
2267
2268 generic_params.reserve (other.generic_params.size ());
2269 for (const auto &e : other.generic_params)
2270 generic_params.push_back (e->clone_generic_param ());
2271
2272 return *this;
2273 }
2274
2275 // move constructors
2276 TraitFunctionDecl (TraitFunctionDecl &&other) = default;
2277 TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default;
2278
2279 std::string as_string () const;
2280
2281 // Returns whether function decl has generic parameters.
2282 bool has_generics () const { return !generic_params.empty (); }
2283
2284 // Returns whether function decl has regular parameters.
2285 bool has_params () const { return !function_params.empty (); }
2286
2287 // Returns whether function has return type (otherwise is void).
2288 bool has_return_type () const { return return_type != nullptr; }
2289
2290 // Returns whether function has a where clause.
2291 bool has_where_clause () const { return !where_clause.is_empty (); }
2292
2293 bool is_method () const { return !self.is_error (); }
2294
2295 SelfParam &get_self () { return self; }
2296
2297 Identifier get_function_name () const { return function_name; }
2298
2299 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2300 {
2301 return generic_params;
2302 }
2303
2304 std::unique_ptr<Type> &get_return_type ()
2305 {
2306 rust_assert (has_return_type ());
2307 return return_type;
2308 }
2309
2310 std::vector<FunctionParam> &get_function_params () { return function_params; }
2311
2312 const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
2313 };
2314
2315 // Actual trait item function declaration within traits
2316 class TraitItemFunc : public TraitItem
2317 {
2318 AST::AttrVec outer_attrs;
2319 TraitFunctionDecl decl;
2320 std::unique_ptr<BlockExpr> block_expr;
2321 Location locus;
2322
2323 public:
2324 // Returns whether function has a definition or is just a declaration.
2325 bool has_definition () const { return block_expr != nullptr; }
2326
2327 TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl,
2328 std::unique_ptr<BlockExpr> block_expr,
2329 AST::AttrVec outer_attrs, Location locus)
2330 : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
2331 decl (std::move (decl)), block_expr (std::move (block_expr)),
2332 locus (locus)
2333 {}
2334
2335 // Copy constructor with clone
2336 TraitItemFunc (TraitItemFunc const &other)
2337 : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
2338 decl (other.decl), locus (other.locus)
2339 {
2340 if (other.block_expr != nullptr)
2341 block_expr = other.block_expr->clone_block_expr ();
2342 }
2343
2344 // Overloaded assignment operator to clone
2345 TraitItemFunc &operator= (TraitItemFunc const &other)
2346 {
2347 TraitItem::operator= (other);
2348 outer_attrs = other.outer_attrs;
2349 decl = other.decl;
2350 locus = other.locus;
2351 mappings = other.mappings;
2352 if (other.block_expr != nullptr)
2353 block_expr = other.block_expr->clone_block_expr ();
2354
2355 return *this;
2356 }
2357
2358 // move constructors
2359 TraitItemFunc (TraitItemFunc &&other) = default;
2360 TraitItemFunc &operator= (TraitItemFunc &&other) = default;
2361
2362 std::string as_string () const override;
2363
2364 Location get_locus () const { return locus; }
2365
2366 void accept_vis (HIRFullVisitor &vis) override;
2367 void accept_vis (HIRTraitItemVisitor &vis) override;
2368
2369 TraitFunctionDecl &get_decl () { return decl; }
2370
2371 const TraitFunctionDecl &get_decl () const { return decl; }
2372
2373 bool has_block_defined () const { return block_expr != nullptr; }
2374
2375 std::unique_ptr<BlockExpr> &get_block_expr ()
2376 {
2377 rust_assert (has_block_defined ());
2378 return block_expr;
2379 }
2380
2381 const std::string trait_identifier () const override final
2382 {
2383 return decl.get_function_name ();
2384 }
2385
2386 TraitItemKind get_item_kind () const override final
2387 {
2388 return TraitItemKind::FUNC;
2389 }
2390
2391 AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
2392 const AST::AttrVec &get_outer_attrs () const override final
2393 {
2394 return outer_attrs;
2395 }
2396
2397 protected:
2398 // Clone function implementation as (not pure) virtual method
2399 TraitItemFunc *clone_trait_item_impl () const override
2400 {
2401 return new TraitItemFunc (*this);
2402 }
2403 };
2404
2405 // Constant item within traits
2406 class TraitItemConst : public TraitItem
2407 {
2408 AST::AttrVec outer_attrs;
2409 Identifier name;
2410 std::unique_ptr<Type> type;
2411 std::unique_ptr<Expr> expr;
2412 Location locus;
2413
2414 public:
2415 // Whether the constant item has an associated expression.
2416 bool has_expression () const { return expr != nullptr; }
2417
2418 TraitItemConst (Analysis::NodeMapping mappings, Identifier name,
2419 std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
2420 AST::AttrVec outer_attrs, Location locus)
2421 : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
2422 name (std::move (name)), type (std::move (type)), expr (std::move (expr)),
2423 locus (locus)
2424 {}
2425
2426 // Copy constructor with clones
2427 TraitItemConst (TraitItemConst const &other)
2428 : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
2429 name (other.name), type (other.type->clone_type ()),
2430 expr (other.expr->clone_expr ()), locus (other.locus)
2431 {}
2432
2433 // Overloaded assignment operator to clone
2434 TraitItemConst &operator= (TraitItemConst const &other)
2435 {
2436 TraitItem::operator= (other);
2437 outer_attrs = other.outer_attrs;
2438 name = other.name;
2439 type = other.type->clone_type ();
2440 expr = other.expr->clone_expr ();
2441 locus = other.locus;
2442 mappings = other.mappings;
2443
2444 return *this;
2445 }
2446
2447 // move constructors
2448 TraitItemConst (TraitItemConst &&other) = default;
2449 TraitItemConst &operator= (TraitItemConst &&other) = default;
2450
2451 std::string as_string () const override;
2452
2453 Location get_locus () const { return locus; }
2454
2455 void accept_vis (HIRFullVisitor &vis) override;
2456 void accept_vis (HIRTraitItemVisitor &vis) override;
2457
2458 Identifier get_name () const { return name; }
2459
2460 bool has_expr () const { return expr != nullptr; }
2461
2462 std::unique_ptr<Type> &get_type () { return type; }
2463
2464 std::unique_ptr<Expr> &get_expr ()
2465 {
2466 rust_assert (has_expr ());
2467 return expr;
2468 }
2469
2470 const std::string trait_identifier () const override final { return name; }
2471
2472 TraitItemKind get_item_kind () const override final
2473 {
2474 return TraitItemKind::CONST;
2475 }
2476
2477 AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
2478 const AST::AttrVec &get_outer_attrs () const override final
2479 {
2480 return outer_attrs;
2481 }
2482
2483 protected:
2484 // Clone function implementation as (not pure) virtual method
2485 TraitItemConst *clone_trait_item_impl () const override
2486 {
2487 return new TraitItemConst (*this);
2488 }
2489 };
2490
2491 // Type items within traits
2492 class TraitItemType : public TraitItem
2493 {
2494 AST::AttrVec outer_attrs;
2495
2496 Identifier name;
2497 std::vector<std::unique_ptr<TypeParamBound>>
2498 type_param_bounds; // inlined form
2499 Location locus;
2500
2501 public:
2502 // Returns whether trait item type has type param bounds.
2503 bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
2504
2505 TraitItemType (Analysis::NodeMapping mappings, Identifier name,
2506 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
2507 AST::AttrVec outer_attrs, Location locus)
2508 : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
2509 name (std::move (name)),
2510 type_param_bounds (std::move (type_param_bounds)), locus (locus)
2511 {}
2512
2513 // Copy constructor with vector clone
2514 TraitItemType (TraitItemType const &other)
2515 : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
2516 name (other.name), locus (other.locus)
2517 {
2518 type_param_bounds.reserve (other.type_param_bounds.size ());
2519 for (const auto &e : other.type_param_bounds)
2520 type_param_bounds.push_back (e->clone_type_param_bound ());
2521 }
2522
2523 // Overloaded assignment operator with vector clone
2524 TraitItemType &operator= (TraitItemType const &other)
2525 {
2526 TraitItem::operator= (other);
2527 outer_attrs = other.outer_attrs;
2528 name = other.name;
2529 locus = other.locus;
2530 mappings = other.mappings;
2531
2532 type_param_bounds.reserve (other.type_param_bounds.size ());
2533 for (const auto &e : other.type_param_bounds)
2534 type_param_bounds.push_back (e->clone_type_param_bound ());
2535
2536 return *this;
2537 }
2538
2539 // default move constructors
2540 TraitItemType (TraitItemType &&other) = default;
2541 TraitItemType &operator= (TraitItemType &&other) = default;
2542
2543 std::string as_string () const override;
2544
2545 Location get_locus () const { return locus; }
2546
2547 void accept_vis (HIRFullVisitor &vis) override;
2548 void accept_vis (HIRTraitItemVisitor &vis) override;
2549
2550 Identifier get_name () const { return name; }
2551
2552 std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
2553 {
2554 return type_param_bounds;
2555 }
2556
2557 const std::string trait_identifier () const override final { return name; }
2558
2559 TraitItemKind get_item_kind () const override final
2560 {
2561 return TraitItemKind::TYPE;
2562 }
2563
2564 AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
2565 const AST::AttrVec &get_outer_attrs () const override final
2566 {
2567 return outer_attrs;
2568 }
2569
2570 protected:
2571 // Clone function implementation as (not pure) virtual method
2572 TraitItemType *clone_trait_item_impl () const override
2573 {
2574 return new TraitItemType (*this);
2575 }
2576 };
2577
2578 // Rust trait item declaration HIR node
2579 class Trait : public VisItem
2580 {
2581 Unsafety unsafety;
2582 Identifier name;
2583 std::vector<std::unique_ptr<GenericParam>> generic_params;
2584 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
2585 WhereClause where_clause;
2586 std::vector<std::unique_ptr<TraitItem>> trait_items;
2587 Location locus;
2588
2589 public:
2590 std::string as_string () const override;
2591
2592 // Returns whether trait has generic parameters.
2593 bool has_generics () const { return !generic_params.empty (); }
2594
2595 // Returns whether trait has type parameter bounds.
2596 bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
2597
2598 // Returns whether trait has where clause.
2599 bool has_where_clause () const { return !where_clause.is_empty (); }
2600
2601 // Returns whether trait has trait items.
2602 bool has_trait_items () const { return !trait_items.empty (); }
2603
2604 std::vector<std::unique_ptr<TraitItem>> &get_trait_items ()
2605 {
2606 return trait_items;
2607 }
2608
2609 Identifier get_name () const { return name; }
2610
2611 // Mega-constructor
2612 Trait (Analysis::NodeMapping mappings, Identifier name, Unsafety unsafety,
2613 std::vector<std::unique_ptr<GenericParam>> generic_params,
2614 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
2615 WhereClause where_clause,
2616 std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis,
2617 AST::AttrVec outer_attrs, Location locus)
2618 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2619 unsafety (unsafety), name (std::move (name)),
2620 generic_params (std::move (generic_params)),
2621 type_param_bounds (std::move (type_param_bounds)),
2622 where_clause (std::move (where_clause)),
2623 trait_items (std::move (trait_items)), locus (locus)
2624 {}
2625
2626 // Copy constructor with vector clone
2627 Trait (Trait const &other)
2628 : VisItem (other), unsafety (other.unsafety), name (other.name),
2629 where_clause (other.where_clause), locus (other.locus)
2630 {
2631 generic_params.reserve (other.generic_params.size ());
2632 for (const auto &e : other.generic_params)
2633 generic_params.push_back (e->clone_generic_param ());
2634
2635 type_param_bounds.reserve (other.type_param_bounds.size ());
2636 for (const auto &e : other.type_param_bounds)
2637 type_param_bounds.push_back (e->clone_type_param_bound ());
2638
2639 trait_items.reserve (other.trait_items.size ());
2640 for (const auto &e : other.trait_items)
2641 trait_items.push_back (e->clone_trait_item ());
2642 }
2643
2644 // Overloaded assignment operator with vector clone
2645 Trait &operator= (Trait const &other)
2646 {
2647 VisItem::operator= (other);
2648 name = other.name;
2649 unsafety = other.unsafety;
2650 where_clause = other.where_clause;
2651 locus = other.locus;
2652
2653 generic_params.reserve (other.generic_params.size ());
2654 for (const auto &e : other.generic_params)
2655 generic_params.push_back (e->clone_generic_param ());
2656
2657 type_param_bounds.reserve (other.type_param_bounds.size ());
2658 for (const auto &e : other.type_param_bounds)
2659 type_param_bounds.push_back (e->clone_type_param_bound ());
2660
2661 trait_items.reserve (other.trait_items.size ());
2662 for (const auto &e : other.trait_items)
2663 trait_items.push_back (e->clone_trait_item ());
2664
2665 return *this;
2666 }
2667
2668 // default move constructors
2669 Trait (Trait &&other) = default;
2670 Trait &operator= (Trait &&other) = default;
2671
2672 Location get_locus () const override final { return locus; }
2673
2674 void accept_vis (HIRFullVisitor &vis) override;
2675 void accept_vis (HIRStmtVisitor &vis) override;
2676 void accept_vis (HIRVisItemVisitor &vis) override;
2677
2678 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2679 {
2680 return generic_params;
2681 }
2682
2683 const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
2684 {
2685 return generic_params;
2686 }
2687
2688 std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
2689 {
2690 return type_param_bounds;
2691 }
2692
2693 const std::vector<std::unique_ptr<TypeParamBound>> &
2694 get_type_param_bounds () const
2695 {
2696 return type_param_bounds;
2697 }
2698
2699 ItemKind get_item_kind () const override { return ItemKind::Trait; }
2700
2701 protected:
2702 /* Use covariance to implement clone function as returning this object
2703 * rather than base */
2704 Trait *clone_item_impl () const override { return new Trait (*this); }
2705 };
2706
2707 class ImplBlock : public VisItem
2708 {
2709 std::vector<std::unique_ptr<GenericParam>> generic_params;
2710 std::unique_ptr<Type> impl_type;
2711 std::unique_ptr<TypePath> trait_ref;
2712 WhereClause where_clause;
2713 Polarity polarity;
2714 AST::AttrVec inner_attrs;
2715 Location locus;
2716 std::vector<std::unique_ptr<ImplItem>> impl_items;
2717
2718 public:
2719 ImplBlock (Analysis::NodeMapping mappings,
2720 std::vector<std::unique_ptr<ImplItem>> impl_items,
2721 std::vector<std::unique_ptr<GenericParam>> generic_params,
2722 std::unique_ptr<Type> impl_type,
2723 std::unique_ptr<TypePath> trait_ref, WhereClause where_clause,
2724 Polarity polarity, Visibility vis, AST::AttrVec inner_attrs,
2725 AST::AttrVec outer_attrs, Location locus)
2726 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2727 generic_params (std::move (generic_params)),
2728 impl_type (std::move (impl_type)), trait_ref (std::move (trait_ref)),
2729 where_clause (std::move (where_clause)), polarity (polarity),
2730 inner_attrs (std::move (inner_attrs)), locus (locus),
2731 impl_items (std::move (impl_items))
2732 {}
2733
2734 ImplBlock (ImplBlock const &other)
2735 : VisItem (other), impl_type (other.impl_type->clone_type ()),
2736 where_clause (other.where_clause), polarity (other.polarity),
2737 inner_attrs (other.inner_attrs), locus (other.locus)
2738 {
2739 generic_params.reserve (other.generic_params.size ());
2740 for (const auto &e : other.generic_params)
2741 generic_params.push_back (e->clone_generic_param ());
2742
2743 impl_items.reserve (other.impl_items.size ());
2744 for (const auto &e : other.impl_items)
2745 impl_items.push_back (e->clone_inherent_impl_item ());
2746 }
2747
2748 ImplBlock &operator= (ImplBlock const &other)
2749 {
2750 VisItem::operator= (other);
2751 impl_type = other.impl_type->clone_type ();
2752 where_clause = other.where_clause;
2753 polarity = other.polarity;
2754 inner_attrs = other.inner_attrs;
2755 locus = other.locus;
2756
2757 generic_params.reserve (other.generic_params.size ());
2758 for (const auto &e : other.generic_params)
2759 generic_params.push_back (e->clone_generic_param ());
2760
2761 impl_items.reserve (other.impl_items.size ());
2762 for (const auto &e : other.impl_items)
2763 impl_items.push_back (e->clone_inherent_impl_item ());
2764
2765 return *this;
2766 }
2767
2768 ImplBlock (ImplBlock &&other) = default;
2769 ImplBlock &operator= (ImplBlock &&other) = default;
2770
2771 std::string as_string () const override;
2772
2773 // Returns whether inherent impl block has inherent impl items.
2774 bool has_impl_items () const { return !impl_items.empty (); }
2775
2776 void accept_vis (HIRFullVisitor &vis) override;
2777 void accept_vis (HIRStmtVisitor &vis) override;
2778 void accept_vis (HIRVisItemVisitor &vis) override;
2779
2780 std::vector<std::unique_ptr<ImplItem>> &get_impl_items ()
2781 {
2782 return impl_items;
2783 };
2784
2785 const std::vector<std::unique_ptr<ImplItem>> &get_impl_items () const
2786 {
2787 return impl_items;
2788 };
2789
2790 // Returns whether impl has generic parameters.
2791 bool has_generics () const { return !generic_params.empty (); }
2792
2793 // Returns whether impl has where clause.
2794 bool has_where_clause () const { return !where_clause.is_empty (); }
2795
2796 // Returns the polarity of the impl.
2797 Polarity get_polarity () const { return polarity; }
2798
2799 // Returns whether impl has inner attributes.
2800 bool has_inner_attrs () const { return !inner_attrs.empty (); }
2801
2802 Location get_locus () const override final { return locus; }
2803
2804 std::unique_ptr<Type> &get_type () { return impl_type; };
2805
2806 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2807 {
2808 return generic_params;
2809 }
2810
2811 bool has_trait_ref () const { return trait_ref != nullptr; }
2812
2813 std::unique_ptr<TypePath> &get_trait_ref ()
2814 {
2815 rust_assert (has_trait_ref ());
2816 return trait_ref;
2817 }
2818
2819 WhereClause &get_where_clause () { return where_clause; }
2820
2821 ItemKind get_item_kind () const override { return ItemKind::Impl; }
2822
2823 protected:
2824 ImplBlock *clone_item_impl () const override { return new ImplBlock (*this); }
2825 };
2826
2827 // Abstract base class for an item used inside an extern block
2828 class ExternalItem : public Node
2829 {
2830 Analysis::NodeMapping mappings;
2831 AST::AttrVec outer_attrs;
2832 Visibility visibility;
2833 Identifier item_name;
2834 Location locus;
2835
2836 public:
2837 enum class ExternKind
2838 {
2839 Static,
2840 Function,
2841 };
2842
2843 virtual ~ExternalItem () {}
2844
2845 BaseKind get_hir_kind () override final { return EXTERNAL; }
2846
2847 virtual ExternKind get_extern_kind () = 0;
2848
2849 // Returns whether item has outer attributes.
2850 bool has_outer_attrs () const { return !outer_attrs.empty (); }
2851
2852 // Returns whether item has non-default visibility.
2853 bool has_visibility () const { return !visibility.is_error (); }
2854
2855 // Unique pointer custom clone function
2856 std::unique_ptr<ExternalItem> clone_external_item () const
2857 {
2858 return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
2859 }
2860
2861 virtual std::string as_string () const;
2862
2863 Location get_locus () const { return locus; }
2864
2865 virtual void accept_vis (HIRFullVisitor &vis) = 0;
2866 virtual void accept_vis (HIRExternalItemVisitor &vis) = 0;
2867
2868 Analysis::NodeMapping get_mappings () const { return mappings; }
2869
2870 Identifier get_item_name () const { return item_name; }
2871
2872 AST::AttrVec &get_outer_attrs () { return outer_attrs; }
2873
2874 protected:
2875 ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
2876 Visibility vis, AST::AttrVec outer_attrs, Location locus)
2877 : mappings (mappings), outer_attrs (std::move (outer_attrs)),
2878 visibility (std::move (vis)), item_name (std::move (item_name)),
2879 locus (locus)
2880 {}
2881
2882 // Copy constructor
2883 ExternalItem (ExternalItem const &other)
2884 : mappings (other.mappings), outer_attrs (other.outer_attrs),
2885 visibility (other.visibility), item_name (other.item_name),
2886 locus (other.locus)
2887 {}
2888
2889 // Overloaded assignment operator to clone
2890 ExternalItem &operator= (ExternalItem const &other)
2891 {
2892 mappings = other.mappings;
2893 item_name = other.item_name;
2894 visibility = other.visibility;
2895 outer_attrs = other.outer_attrs;
2896 locus = other.locus;
2897
2898 return *this;
2899 }
2900
2901 // move constructors
2902 ExternalItem (ExternalItem &&other) = default;
2903 ExternalItem &operator= (ExternalItem &&other) = default;
2904
2905 // Clone function implementation as pure virtual method
2906 virtual ExternalItem *clone_external_item_impl () const = 0;
2907 };
2908
2909 // A static item used in an extern block
2910 class ExternalStaticItem : public ExternalItem
2911 {
2912 Mutability mut;
2913 std::unique_ptr<Type> item_type;
2914
2915 public:
2916 ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name,
2917 std::unique_ptr<Type> item_type, Mutability mut,
2918 Visibility vis, AST::AttrVec outer_attrs, Location locus)
2919 : ExternalItem (std::move (mappings), std::move (item_name),
2920 std::move (vis), std::move (outer_attrs), locus),
2921 mut (mut), item_type (std::move (item_type))
2922 {}
2923
2924 // Copy constructor
2925 ExternalStaticItem (ExternalStaticItem const &other)
2926 : ExternalItem (other), mut (other.mut),
2927 item_type (other.item_type->clone_type ())
2928 {}
2929
2930 // Overloaded assignment operator to clone
2931 ExternalStaticItem &operator= (ExternalStaticItem const &other)
2932 {
2933 ExternalItem::operator= (other);
2934 item_type = other.item_type->clone_type ();
2935 mut = other.mut;
2936
2937 return *this;
2938 }
2939
2940 // move constructors
2941 ExternalStaticItem (ExternalStaticItem &&other) = default;
2942 ExternalStaticItem &operator= (ExternalStaticItem &&other) = default;
2943
2944 std::string as_string () const override;
2945
2946 void accept_vis (HIRFullVisitor &vis) override;
2947 void accept_vis (HIRExternalItemVisitor &vis) override;
2948
2949 bool is_mut () const { return mut == Mutability::Mut; }
2950
2951 Mutability get_mut () { return mut; }
2952
2953 std::unique_ptr<Type> &get_item_type () { return item_type; }
2954
2955 ExternKind get_extern_kind () override { return ExternKind::Static; }
2956
2957 protected:
2958 /* Use covariance to implement clone function as returning this object
2959 * rather than base */
2960 ExternalStaticItem *clone_external_item_impl () const override
2961 {
2962 return new ExternalStaticItem (*this);
2963 }
2964 };
2965
2966 // A named function parameter used in external functions
2967 struct NamedFunctionParam
2968 {
2969 private:
2970 Identifier name;
2971 std::unique_ptr<Type> param_type;
2972 Analysis::NodeMapping mappings;
2973
2974 public:
2975 bool has_name () const { return name != "_"; }
2976
2977 NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name,
2978 std::unique_ptr<Type> param_type)
2979 : name (std::move (name)), param_type (std::move (param_type)),
2980 mappings (std::move (mappings))
2981 {}
2982
2983 // Copy constructor
2984 NamedFunctionParam (NamedFunctionParam const &other)
2985 : name (other.name), param_type (other.param_type->clone_type ()),
2986 mappings (other.mappings)
2987 {}
2988
2989 ~NamedFunctionParam () = default;
2990
2991 // Overloaded assignment operator to clone
2992 NamedFunctionParam &operator= (NamedFunctionParam const &other)
2993 {
2994 mappings = other.mappings;
2995 name = other.name;
2996 param_type = other.param_type->clone_type ();
2997 // has_name = other.has_name;
2998
2999 return *this;
3000 }
3001
3002 // move constructors
3003 NamedFunctionParam (NamedFunctionParam &&other) = default;
3004 NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;
3005
3006 std::string as_string () const;
3007
3008 Identifier get_param_name () const { return name; }
3009
3010 std::unique_ptr<Type> &get_type () { return param_type; }
3011
3012 Analysis::NodeMapping get_mappings () const { return mappings; }
3013 };
3014
3015 // A function item used in an extern block
3016 class ExternalFunctionItem : public ExternalItem
3017 {
3018 // bool has_generics;
3019 // Generics generic_params;
3020 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
3021
3022 // bool has_return_type;
3023 // FunctionReturnType return_type;
3024 std::unique_ptr<Type> return_type; // inlined
3025
3026 // bool has_where_clause;
3027 WhereClause where_clause;
3028
3029 std::vector<NamedFunctionParam> function_params;
3030 bool has_variadics;
3031
3032 public:
3033 // Returns whether item has generic parameters.
3034 bool has_generics () const { return !generic_params.empty (); }
3035
3036 // Returns whether item has a return type (otherwise void).
3037 bool has_return_type () const { return return_type != nullptr; }
3038
3039 // Returns whether item has a where clause.
3040 bool has_where_clause () const { return !where_clause.is_empty (); }
3041
3042 ExternalFunctionItem (
3043 Analysis::NodeMapping mappings, Identifier item_name,
3044 std::vector<std::unique_ptr<GenericParam>> generic_params,
3045 std::unique_ptr<Type> return_type, WhereClause where_clause,
3046 std::vector<NamedFunctionParam> function_params, bool has_variadics,
3047 Visibility vis, AST::AttrVec outer_attrs, Location locus)
3048 : ExternalItem (std::move (mappings), std::move (item_name),
3049 std::move (vis), std::move (outer_attrs), locus),
3050 generic_params (std::move (generic_params)),
3051 return_type (std::move (return_type)),
3052 where_clause (std::move (where_clause)),
3053 function_params (std::move (function_params)),
3054 has_variadics (has_variadics)
3055 {}
3056
3057 // Copy constructor with clone
3058 ExternalFunctionItem (ExternalFunctionItem const &other)
3059 : ExternalItem (other), return_type (other.return_type->clone_type ()),
3060 where_clause (other.where_clause),
3061 function_params (other.function_params),
3062 has_variadics (other.has_variadics)
3063 {
3064 generic_params.reserve (other.generic_params.size ());
3065 for (const auto &e : other.generic_params)
3066 generic_params.push_back (e->clone_generic_param ());
3067 }
3068
3069 // Overloaded assignment operator with clone
3070 ExternalFunctionItem &operator= (ExternalFunctionItem const &other)
3071 {
3072 ExternalItem::operator= (other);
3073 return_type = other.return_type->clone_type ();
3074 where_clause = other.where_clause;
3075 function_params = other.function_params;
3076 has_variadics = other.has_variadics;
3077
3078 generic_params.reserve (other.generic_params.size ());
3079 for (const auto &e : other.generic_params)
3080 generic_params.push_back (e->clone_generic_param ());
3081
3082 return *this;
3083 }
3084
3085 // move constructors
3086 ExternalFunctionItem (ExternalFunctionItem &&other) = default;
3087 ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default;
3088
3089 std::string as_string () const override;
3090
3091 void accept_vis (HIRFullVisitor &vis) override;
3092 void accept_vis (HIRExternalItemVisitor &vis) override;
3093
3094 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
3095 {
3096 return generic_params;
3097 }
3098
3099 std::unique_ptr<Type> &get_return_type () { return return_type; }
3100
3101 std::vector<NamedFunctionParam> &get_function_params ()
3102 {
3103 return function_params;
3104 }
3105
3106 bool is_variadic () const { return has_variadics; }
3107
3108 ExternKind get_extern_kind () override { return ExternKind::Function; }
3109
3110 protected:
3111 /* Use covariance to implement clone function as returning this object
3112 * rather than base */
3113 ExternalFunctionItem *clone_external_item_impl () const override
3114 {
3115 return new ExternalFunctionItem (*this);
3116 }
3117 };
3118
3119 // An extern block HIR node
3120 class ExternBlock : public VisItem
3121 {
3122 ABI abi;
3123 AST::AttrVec inner_attrs;
3124 std::vector<std::unique_ptr<ExternalItem>> extern_items;
3125 Location locus;
3126
3127 public:
3128 std::string as_string () const override;
3129
3130 // Returns whether extern block has inner attributes.
3131 bool has_inner_attrs () const { return !inner_attrs.empty (); }
3132
3133 // Returns whether extern block has extern items.
3134 bool has_extern_items () const { return !extern_items.empty (); }
3135
3136 ABI get_abi () const { return abi; }
3137
3138 ExternBlock (Analysis::NodeMapping mappings, ABI abi,
3139 std::vector<std::unique_ptr<ExternalItem>> extern_items,
3140 Visibility vis, AST::AttrVec inner_attrs,
3141 AST::AttrVec outer_attrs, Location locus)
3142 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
3143 abi (abi), inner_attrs (std::move (inner_attrs)),
3144 extern_items (std::move (extern_items)), locus (locus)
3145 {}
3146
3147 // Copy constructor with vector clone
3148 ExternBlock (ExternBlock const &other)
3149 : VisItem (other), abi (other.abi), inner_attrs (other.inner_attrs),
3150 locus (other.locus)
3151 {
3152 extern_items.reserve (other.extern_items.size ());
3153 for (const auto &e : other.extern_items)
3154 extern_items.push_back (e->clone_external_item ());
3155 }
3156
3157 // Overloaded assignment operator with vector clone
3158 ExternBlock &operator= (ExternBlock const &other)
3159 {
3160 VisItem::operator= (other);
3161 abi = other.abi;
3162 inner_attrs = other.inner_attrs;
3163 locus = other.locus;
3164
3165 extern_items.reserve (other.extern_items.size ());
3166 for (const auto &e : other.extern_items)
3167 extern_items.push_back (e->clone_external_item ());
3168
3169 return *this;
3170 }
3171
3172 // move constructors
3173 ExternBlock (ExternBlock &&other) = default;
3174 ExternBlock &operator= (ExternBlock &&other) = default;
3175
3176 Location get_locus () const override final { return locus; }
3177
3178 void accept_vis (HIRFullVisitor &vis) override;
3179 void accept_vis (HIRStmtVisitor &vis) override;
3180 void accept_vis (HIRVisItemVisitor &vis) override;
3181
3182 std::vector<std::unique_ptr<ExternalItem>> &get_extern_items ()
3183 {
3184 return extern_items;
3185 }
3186
3187 ItemKind get_item_kind () const override { return ItemKind::ExternBlock; }
3188
3189 protected:
3190 /* Use covariance to implement clone function as returning this object
3191 * rather than base */
3192 ExternBlock *clone_item_impl () const override
3193 {
3194 return new ExternBlock (*this);
3195 }
3196
3197 /* Use covariance to implement clone function as returning this object
3198 * rather than base */
3199 /*virtual ExternBlock* clone_statement_impl() const override {
3200 return new ExternBlock(*this);
3201 }*/
3202 };
3203
3204 } // namespace HIR
3205 } // namespace Rust
3206
3207 #endif