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