]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/hir/tree/rust-hir-item.h
gccrs: Extract query_type from TypeCheckBase to be a simple extern
[thirdparty/gcc.git] / gcc / rust / hir / tree / rust-hir-item.h
CommitLineData
83ffe9cd 1// Copyright (C) 2020-2023 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
1229protected:
1230 /* Use covariance to implement clone function as returning this object
1231 * rather than base */
1232 Function *clone_item_impl () const override { return new Function (*this); }
1233
1234 /* Use covariance to implement clone function as returning this object
1235 * rather than base */
1236 Function *clone_inherent_impl_item_impl () const override
1237 {
1238 return new Function (*this);
1239 }
1240};
1241
1242// Rust type alias (i.e. typedef) HIR node
1243class TypeAlias : public VisItem, public ImplItem
1244{
1245 Identifier new_type_name;
1246
1247 // bool has_generics;
1248 // Generics generic_params;
1249 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1250
1251 // bool has_where_clause;
1252 WhereClause where_clause;
1253
1254 std::unique_ptr<Type> existing_type;
1255
1256 Location locus;
1257
1258public:
1259 std::string as_string () const override;
1260
1261 // Returns whether type alias has generic parameters.
1262 bool has_generics () const { return !generic_params.empty (); }
1263
1264 // Returns whether type alias has a where clause.
1265 bool has_where_clause () const { return !where_clause.is_empty (); }
1266
1267 ImplItemType get_impl_item_type () const override final
1268 {
1269 return ImplItem::ImplItemType::TYPE_ALIAS;
1270 }
1271
1272 // Mega-constructor with all possible fields
1273 TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
1274 std::vector<std::unique_ptr<GenericParam>> generic_params,
1275 WhereClause where_clause, std::unique_ptr<Type> existing_type,
1276 Visibility vis, AST::AttrVec outer_attrs, Location locus)
1277 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1278 new_type_name (std::move (new_type_name)),
1279 generic_params (std::move (generic_params)),
1280 where_clause (std::move (where_clause)),
1281 existing_type (std::move (existing_type)), locus (locus)
1282 {}
1283
1284 // Copy constructor
1285 TypeAlias (TypeAlias const &other)
1286 : VisItem (other), new_type_name (other.new_type_name),
1287 where_clause (other.where_clause),
1288 existing_type (other.existing_type->clone_type ()), locus (other.locus)
1289 {
1290 generic_params.reserve (other.generic_params.size ());
1291 for (const auto &e : other.generic_params)
1292 generic_params.push_back (e->clone_generic_param ());
1293 }
1294
1295 // Overloaded assignment operator to clone
1296 TypeAlias &operator= (TypeAlias const &other)
1297 {
1298 VisItem::operator= (other);
1299 new_type_name = other.new_type_name;
1300 where_clause = other.where_clause;
1301 existing_type = other.existing_type->clone_type ();
1302 locus = other.locus;
1303
1304 generic_params.reserve (other.generic_params.size ());
1305 for (const auto &e : other.generic_params)
1306 generic_params.push_back (e->clone_generic_param ());
1307
1308 return *this;
1309 }
1310
1311 // move constructors
1312 TypeAlias (TypeAlias &&other) = default;
1313 TypeAlias &operator= (TypeAlias &&other) = default;
1314
1315 Location get_locus () const override final { return locus; }
1316
1317 void accept_vis (HIRFullVisitor &vis) override;
1318 void accept_vis (HIRImplVisitor &vis) override;
1319 void accept_vis (HIRStmtVisitor &vis) override;
1320 void accept_vis (HIRVisItemVisitor &vis) override;
1321
1322 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1323 {
1324 return generic_params;
1325 }
1326 const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
1327 {
1328 return generic_params;
1329 }
1330
1331 WhereClause &get_where_clause () { return where_clause; }
1332
1333 std::unique_ptr<Type> &get_type_aliased ()
1334 {
1335 rust_assert (existing_type != nullptr);
1336 return existing_type;
1337 }
1338
1339 Identifier get_new_type_name () const { return new_type_name; }
1340
1341 ItemKind get_item_kind () const override { return ItemKind::TypeAlias; }
1342
1343 Analysis::NodeMapping get_impl_mappings () const override
1344 {
1345 return get_mappings ();
1346 };
1347
1348protected:
1349 /* Use covariance to implement clone function as returning this object
1350 * rather than base */
1351 TypeAlias *clone_item_impl () const override { return new TypeAlias (*this); }
1352
1353 /* Use covariance to implement clone function as returning this object
1354 * rather than base */
1355 TypeAlias *clone_inherent_impl_item_impl () const override
1356 {
1357 return new TypeAlias (*this);
1358 }
1359};
1360
1361// Rust base struct declaration HIR node - abstract base class
1362class Struct : public VisItem
1363{
1364protected:
1365 // protected to enable access by derived classes - allows better as_string
1366 Identifier struct_name;
1367
1368 // bool has_generics;
1369 // Generics generic_params;
1370 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1371
1372 // bool has_where_clause;
1373 WhereClause where_clause;
1374
1375 Location locus;
1376
1377public:
1378 Identifier get_identifier () const { return struct_name; }
1379
1380 // Returns whether struct has generic parameters.
1381 bool has_generics () const { return !generic_params.empty (); }
1382
1383 // Returns whether struct has a where clause.
1384 bool has_where_clause () const { return !where_clause.is_empty (); }
1385
1386 Location get_locus () const override final { return locus; }
1387 ItemKind get_item_kind () const override { return ItemKind::Struct; }
1388
1389 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1390 {
1391 return generic_params;
1392 }
1393
1394 WhereClause &get_where_clause () { return where_clause; }
1395
1396protected:
1397 Struct (Analysis::NodeMapping mappings, Identifier struct_name,
1398 std::vector<std::unique_ptr<GenericParam>> generic_params,
1399 WhereClause where_clause, Visibility vis, Location locus,
1400 AST::AttrVec outer_attrs = AST::AttrVec ())
1401 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1402 struct_name (std::move (struct_name)),
1403 generic_params (std::move (generic_params)),
1404 where_clause (std::move (where_clause)), locus (locus)
1405 {}
1406
1407 // Copy constructor with vector clone
1408 Struct (Struct const &other)
1409 : VisItem (other), struct_name (other.struct_name),
1410 where_clause (other.where_clause), locus (other.locus)
1411 {
1412 generic_params.reserve (other.generic_params.size ());
1413 for (const auto &e : other.generic_params)
1414 generic_params.push_back (e->clone_generic_param ());
1415 }
1416
1417 // Overloaded assignment operator with vector clone
1418 Struct &operator= (Struct const &other)
1419 {
1420 VisItem::operator= (other);
1421 struct_name = other.struct_name;
1422 where_clause = other.where_clause;
1423 locus = other.locus;
1424
1425 generic_params.reserve (other.generic_params.size ());
1426 for (const auto &e : other.generic_params)
1427 generic_params.push_back (e->clone_generic_param ());
1428
1429 return *this;
1430 }
1431
1432 // move constructors
1433 Struct (Struct &&other) = default;
1434 Struct &operator= (Struct &&other) = default;
1435};
1436
1437// A single field in a struct
1438struct StructField
1439{
1440public:
1441 // bool has_outer_attributes;
1442 AST::AttrVec outer_attrs;
1443
1444 // bool has_visibility;
1445 Visibility visibility;
1446
1447 Identifier field_name;
1448 std::unique_ptr<Type> field_type;
1449
1450 Analysis::NodeMapping mappings;
1451
1452 Location locus;
1453
1454 // Returns whether struct field has any outer attributes.
1455 bool has_outer_attributes () const { return !outer_attrs.empty (); }
1456
1457 // Returns whether struct field has a non-private (non-default) visibility.
1458 bool has_visibility () const { return !visibility.is_error (); }
1459
1460 StructField (Analysis::NodeMapping mappings, Identifier field_name,
1461 std::unique_ptr<Type> field_type, Visibility vis, Location locus,
1462 AST::AttrVec outer_attrs = AST::AttrVec ())
1463 : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
1464 field_name (std::move (field_name)), field_type (std::move (field_type)),
1465 mappings (mappings), locus (locus)
1466 {}
1467
1468 // Copy constructor
1469 StructField (StructField const &other)
1470 : outer_attrs (other.outer_attrs), visibility (other.visibility),
1471 field_name (other.field_name),
1472 field_type (other.field_type->clone_type ()), mappings (other.mappings)
1473 {}
1474
1475 ~StructField () = default;
1476
1477 // Overloaded assignment operator to clone
1478 StructField &operator= (StructField const &other)
1479 {
1480 field_name = other.field_name;
1481 field_type = other.field_type->clone_type ();
1482 visibility = other.visibility;
1483 outer_attrs = other.outer_attrs;
1484 mappings = other.mappings;
1485
1486 return *this;
1487 }
1488
1489 // move constructors
1490 StructField (StructField &&other) = default;
1491 StructField &operator= (StructField &&other) = default;
1492
1493 std::string as_string () const;
1494
1495 Identifier get_field_name () const { return field_name; }
1496
1497 std::unique_ptr<Type> &get_field_type ()
1498 {
1499 rust_assert (field_type != nullptr);
1500 return field_type;
1501 }
1502
1503 Analysis::NodeMapping get_mappings () const { return mappings; }
1504
1505 Location get_locus () { return locus; }
1506
1507 Visibility &get_visibility () { return visibility; }
1508};
1509
1510// Rust struct declaration with true struct type HIR node
1511class StructStruct : public Struct
1512{
1513public:
1514 std::vector<StructField> fields;
1515 bool is_unit;
1516
1517 std::string as_string () const override;
1518
1519 // Mega-constructor with all possible fields
1520 StructStruct (Analysis::NodeMapping mappings, std::vector<StructField> fields,
1521 Identifier struct_name,
1522 std::vector<std::unique_ptr<GenericParam>> generic_params,
1523 WhereClause where_clause, bool is_unit, Visibility vis,
1524 AST::AttrVec outer_attrs, Location locus)
1525 : Struct (std::move (mappings), std::move (struct_name),
1526 std::move (generic_params), std::move (where_clause),
1527 std::move (vis), locus, std::move (outer_attrs)),
1528 fields (std::move (fields)), is_unit (is_unit)
1529 {}
1530
1531 // Unit struct constructor
1532 StructStruct (Analysis::NodeMapping mappings, Identifier struct_name,
1533 std::vector<std::unique_ptr<GenericParam>> generic_params,
1534 WhereClause where_clause, Visibility vis,
1535 AST::AttrVec outer_attrs, Location locus)
1536 : Struct (std::move (mappings), std::move (struct_name),
1537 std::move (generic_params), std::move (where_clause),
1538 std::move (vis), locus, std::move (outer_attrs)),
1539 is_unit (true)
1540 {}
1541 // TODO: can a unit struct have generic fields? assuming yes for now.
1542
1543 /* Returns whether the struct is a unit struct - struct defined without
1544 * fields. This is important because it also means an implicit constant of its
1545 * type is defined. */
1546 bool is_unit_struct () const { return is_unit; }
1547
1548 void accept_vis (HIRFullVisitor &vis) override;
1549 void accept_vis (HIRStmtVisitor &vis) override;
1550 void accept_vis (HIRVisItemVisitor &vis) override;
1551
1552 std::vector<StructField> &get_fields () { return fields; }
1553
1554protected:
1555 /* Use covariance to implement clone function as returning this object
1556 * rather than base */
1557 StructStruct *clone_item_impl () const override
1558 {
1559 return new StructStruct (*this);
1560 }
1561
1562 /* Use covariance to implement clone function as returning this object
1563 * rather than base */
1564 /*virtual StructStruct* clone_statement_impl() const override {
1565 return new StructStruct(*this);
1566 }*/
1567};
1568
1569// A single field in a tuple
1570struct TupleField
1571{
1572private:
1573 // bool has_outer_attributes;
1574 AST::AttrVec outer_attrs;
1575
1576 // bool has_visibility;
1577 Visibility visibility;
1578
1579 std::unique_ptr<Type> field_type;
1580
1581 Location locus;
1582
1583 Analysis::NodeMapping mappings;
1584
1585public:
1586 // Returns whether tuple field has outer attributes.
1587 bool has_outer_attributes () const { return !outer_attrs.empty (); }
1588
1589 /* Returns whether tuple field has a non-default visibility (i.e. a public
1590 * one) */
1591 bool has_visibility () const { return !visibility.is_error (); }
1592
1593 // Complete constructor
1594 TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type,
1595 Visibility vis, Location locus,
1596 AST::AttrVec outer_attrs = AST::AttrVec ())
1597 : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
1598 field_type (std::move (field_type)), locus (locus), mappings (mapping)
1599 {}
1600
1601 // Copy constructor with clone
1602 TupleField (TupleField const &other)
1603 : outer_attrs (other.outer_attrs), visibility (other.visibility),
1604 field_type (other.field_type->clone_type ()), locus (other.locus),
1605 mappings (other.mappings)
1606 {}
1607
1608 ~TupleField () = default;
1609
1610 // Overloaded assignment operator to clone
1611 TupleField &operator= (TupleField const &other)
1612 {
1613 field_type = other.field_type->clone_type ();
1614 visibility = other.visibility;
1615 outer_attrs = other.outer_attrs;
1616 locus = other.locus;
1617 mappings = other.mappings;
1618
1619 return *this;
1620 }
1621
1622 // move constructors
1623 TupleField (TupleField &&other) = default;
1624 TupleField &operator= (TupleField &&other) = default;
1625
1626 // Returns whether tuple field is in an error state.
1627 bool is_error () const { return field_type == nullptr; }
1628
1629 std::string as_string () const;
1630
1631 Analysis::NodeMapping get_mappings () const { return mappings; }
1632
1633 Location get_locus () const { return locus; }
1634
1635 std::unique_ptr<HIR::Type> &get_field_type () { return field_type; }
1636};
1637
1638// Rust tuple declared using struct keyword HIR node
1639class TupleStruct : public Struct
1640{
1641 std::vector<TupleField> fields;
1642
1643public:
1644 std::string as_string () const override;
1645
1646 // Mega-constructor with all possible fields
1647 TupleStruct (Analysis::NodeMapping mappings, std::vector<TupleField> fields,
1648 Identifier struct_name,
1649 std::vector<std::unique_ptr<GenericParam>> generic_params,
1650 WhereClause where_clause, Visibility vis,
1651 AST::AttrVec outer_attrs, Location locus)
1652 : Struct (std::move (mappings), std::move (struct_name),
1653 std::move (generic_params), std::move (where_clause),
1654 std::move (vis), locus, std::move (outer_attrs)),
1655 fields (std::move (fields))
1656 {}
1657
1658 void accept_vis (HIRFullVisitor &vis) override;
1659 void accept_vis (HIRStmtVisitor &vis) override;
1660 void accept_vis (HIRVisItemVisitor &vis) override;
1661
1662 std::vector<TupleField> &get_fields () { return fields; }
1663 const std::vector<TupleField> &get_fields () const { return fields; }
1664
1665protected:
1666 /* Use covariance to implement clone function as returning this object
1667 * rather than base */
1668 TupleStruct *clone_item_impl () const override
1669 {
1670 return new TupleStruct (*this);
1671 }
1672
1673 /* Use covariance to implement clone function as returning this object
1674 * rather than base */
1675 /*virtual TupleStruct* clone_statement_impl() const override {
1676 return new TupleStruct(*this);
1677 }*/
1678};
1679
1680/* An item used in an "enum" tagged union - not abstract: base represents a
1681 name-only enum. Syntactically EnumItem's can have a Visibility. But not
1682 Semantically. So check there is no Visibility when lowering and make this
1683 an Item, not an VisItem. */
1684class EnumItem : public Item
1685{
1686 Identifier variant_name;
1687 Location locus;
1688
1689public:
1690 virtual ~EnumItem () {}
1691
1692 enum EnumItemKind
1693 {
1694 Named,
1695 Tuple,
1696 Struct,
1697 Discriminant,
1698 };
1699
1700 EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
1701 AST::AttrVec outer_attrs, Location locus)
1702 : Item (std::move (mappings), std::move (outer_attrs)),
1703 variant_name (std::move (variant_name)), locus (locus)
1704 {}
1705
1706 // Unique pointer custom clone function
1707 std::unique_ptr<EnumItem> clone_enum_item () const
1708 {
1709 return std::unique_ptr<EnumItem> (clone_item_impl ());
1710 }
1711
1712 virtual std::string as_string () const override;
1713 virtual EnumItemKind get_enum_item_kind () const { return Named; };
1714
1715 // not pure virtual as not abstract
1716 void accept_vis (HIRFullVisitor &vis) override;
1717 void accept_vis (HIRStmtVisitor &vis) override;
1718 // void accept_vis (HIRVisItemVisitor &vis) override;
1719
1720 Location get_locus () const override { return locus; }
1721
1722 Identifier get_identifier () const { return variant_name; }
1723
1724 ItemKind get_item_kind () const override { return ItemKind::EnumItem; }
1725
1726protected:
1727 EnumItem *clone_item_impl () const override { return new EnumItem (*this); }
1728};
1729
1730// A tuple item used in an "enum" tagged union
1731class EnumItemTuple : public EnumItem
1732{
1733 // bool has_tuple_fields;
1734 std::vector<TupleField> tuple_fields;
1735
1736public:
1737 // Returns whether tuple enum item has tuple fields.
1738 bool has_tuple_fields () const { return !tuple_fields.empty (); }
1739
1740 EnumItemKind get_enum_item_kind () const override
1741 {
1742 return EnumItemKind::Tuple;
1743 }
1744
1745 EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
1746 std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
1747 Location locus)
1748 : EnumItem (std::move (mappings), std::move (variant_name),
1749 std::move (outer_attrs), locus),
1750 tuple_fields (std::move (tuple_fields))
1751 {}
1752
1753 std::string as_string () const override;
1754
1755 void accept_vis (HIRFullVisitor &vis) override;
1756 void accept_vis (HIRStmtVisitor &vis) override;
1757
1758 std::vector<TupleField> &get_tuple_fields () { return tuple_fields; }
1759
1760protected:
1761 // Clone function implementation as (not pure) virtual method
1762 EnumItemTuple *clone_item_impl () const override
1763 {
1764 return new EnumItemTuple (*this);
1765 }
1766};
1767
1768// A struct item used in an "enum" tagged union
1769class EnumItemStruct : public EnumItem
1770{
1771 // bool has_struct_fields;
1772 std::vector<StructField> struct_fields;
1773
1774public:
1775 // Returns whether struct enum item has struct fields.
1776 bool has_struct_fields () const { return !struct_fields.empty (); }
1777
1778 EnumItemKind get_enum_item_kind () const override
1779 {
1780 return EnumItemKind::Struct;
1781 }
1782
1783 EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
1784 std::vector<StructField> struct_fields,
1785 AST::AttrVec outer_attrs, Location locus)
1786 : EnumItem (std::move (mappings), std::move (variant_name),
1787 std::move (outer_attrs), locus),
1788 struct_fields (std::move (struct_fields))
1789 {}
1790
1791 std::string as_string () const override;
1792
1793 void accept_vis (HIRFullVisitor &vis) override;
1794 void accept_vis (HIRStmtVisitor &vis) override;
1795
1796 std::vector<StructField> &get_struct_fields () { return struct_fields; }
1797
1798protected:
1799 // Clone function implementation as (not pure) virtual method
1800 EnumItemStruct *clone_item_impl () const override
1801 {
1802 return new EnumItemStruct (*this);
1803 }
1804};
1805
1806// A discriminant (numbered enum) item used in an "enum" tagged union
1807class EnumItemDiscriminant : public EnumItem
1808{
1809 std::unique_ptr<Expr> expression;
1810
1811public:
1812 EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name,
1813 std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs,
1814 Location locus)
1815 : EnumItem (std::move (mappings), std::move (variant_name),
1816 std::move (outer_attrs), locus),
1817 expression (std::move (expr))
1818 {}
1819
1820 // Copy constructor with clone
1821 EnumItemDiscriminant (EnumItemDiscriminant const &other)
1822 : EnumItem (other), expression (other.expression->clone_expr ())
1823 {}
1824
1825 // Overloaded assignment operator to clone
1826 EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other)
1827 {
1828 EnumItem::operator= (other);
1829 expression = other.expression->clone_expr ();
1830 // variant_name = other.variant_name;
1831 // outer_attrs = other.outer_attrs;
1832
1833 return *this;
1834 }
1835
1836 // move constructors
1837 EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
1838 EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
1839
1840 EnumItemKind get_enum_item_kind () const override
1841 {
1842 return EnumItemKind::Discriminant;
1843 }
1844
1845 std::string as_string () const override;
1846
1847 void accept_vis (HIRFullVisitor &vis) override;
1848 void accept_vis (HIRStmtVisitor &vis) override;
1849
1850 std::unique_ptr<Expr> &get_discriminant_expression () { return expression; }
1851
1852protected:
1853 // Clone function implementation as (not pure) virtual method
1854 EnumItemDiscriminant *clone_item_impl () const override
1855 {
1856 return new EnumItemDiscriminant (*this);
1857 }
1858};
1859
1860// HIR node for Rust "enum" - tagged union
1861class Enum : public VisItem
1862{
1863 Identifier enum_name;
1864
1865 // bool has_generics;
1866 // Generics generic_params;
1867 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1868
1869 // bool has_where_clause;
1870 WhereClause where_clause;
1871
1872 std::vector<std::unique_ptr<EnumItem>> items;
1873
1874 Location locus;
1875
1876public:
1877 std::string as_string () const override;
1878
1879 // Returns whether "enum" has generic parameters.
1880 bool has_generics () const { return !generic_params.empty (); }
1881
1882 // Returns whether "enum" has a where clause.
1883 bool has_where_clause () const { return !where_clause.is_empty (); }
1884
1885 /* Returns whether enum is a "zero-variant" (no possible variant) enum,
1886 * which cannot be instantiated. */
1887 bool is_zero_variant () const { return items.empty (); }
1888
1889 // Mega-constructor
1890 Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis,
1891 std::vector<std::unique_ptr<GenericParam>> generic_params,
1892 WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items,
1893 AST::AttrVec outer_attrs, Location locus)
1894 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1895 enum_name (std::move (enum_name)),
1896 generic_params (std::move (generic_params)),
1897 where_clause (std::move (where_clause)), items (std::move (items)),
1898 locus (locus)
1899 {}
1900
1901 // TODO: constructor with less arguments
1902
1903 // Copy constructor with vector clone
1904 Enum (Enum const &other)
1905 : VisItem (other), enum_name (other.enum_name),
1906 where_clause (other.where_clause), locus (other.locus)
1907 {
1908 generic_params.reserve (other.generic_params.size ());
1909 for (const auto &e : other.generic_params)
1910 generic_params.push_back (e->clone_generic_param ());
1911
1912 items.reserve (other.items.size ());
1913 for (const auto &e : other.items)
1914 items.push_back (e->clone_enum_item ());
1915 }
1916
1917 // Overloaded assignment operator with vector clone
1918 Enum &operator= (Enum const &other)
1919 {
1920 VisItem::operator= (other);
1921 enum_name = other.enum_name;
1922 where_clause = other.where_clause;
1923 locus = other.locus;
1924
1925 generic_params.reserve (other.generic_params.size ());
1926 for (const auto &e : other.generic_params)
1927 generic_params.push_back (e->clone_generic_param ());
1928
1929 items.reserve (other.items.size ());
1930 for (const auto &e : other.items)
1931 items.push_back (e->clone_enum_item ());
1932
1933 return *this;
1934 }
1935
1936 // Move constructors
1937 Enum (Enum &&other) = default;
1938 Enum &operator= (Enum &&other) = default;
1939
1940 Location get_locus () const override final { return locus; }
1941
1942 void accept_vis (HIRFullVisitor &vis) override;
1943 void accept_vis (HIRStmtVisitor &vis) override;
1944 void accept_vis (HIRVisItemVisitor &vis) override;
1945
1946 Identifier get_identifier () const { return enum_name; }
1947 ItemKind get_item_kind () const override { return ItemKind::Enum; }
1948
1949 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
1950 {
1951 return generic_params;
1952 }
1953
1954 const std::vector<std::unique_ptr<EnumItem>> &get_variants () const
1955 {
1956 return items;
1957 }
1958
1959protected:
1960 /* Use covariance to implement clone function as returning this object
1961 * rather than base */
1962 Enum *clone_item_impl () const override { return new Enum (*this); }
1963
1964 /* Use covariance to implement clone function as returning this object
1965 * rather than base */
1966 /*virtual Enum* clone_statement_impl() const override {
1967 return new Enum(*this);
1968 }*/
1969};
1970
1971// Rust untagged union used for C compat HIR node
1972class Union : public VisItem
1973{
1974 Identifier union_name;
1975
1976 // bool has_generics;
1977 // Generics generic_params;
1978 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
1979
1980 // bool has_where_clause;
1981 WhereClause where_clause;
1982
1983 std::vector<StructField> variants;
1984
1985 Location locus;
1986
1987public:
1988 std::string as_string () const override;
1989
1990 // Returns whether union has generic params.
1991 bool has_generics () const { return !generic_params.empty (); }
1992
1993 // Returns whether union has where clause.
1994 bool has_where_clause () const { return !where_clause.is_empty (); }
1995
1996 Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis,
1997 std::vector<std::unique_ptr<GenericParam>> generic_params,
1998 WhereClause where_clause, std::vector<StructField> variants,
1999 AST::AttrVec outer_attrs, Location locus)
2000 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2001 union_name (std::move (union_name)),
2002 generic_params (std::move (generic_params)),
2003 where_clause (std::move (where_clause)), variants (std::move (variants)),
2004 locus (locus)
2005 {}
2006
2007 // copy constructor with vector clone
2008 Union (Union const &other)
2009 : VisItem (other), union_name (other.union_name),
2010 where_clause (other.where_clause), variants (other.variants),
2011 locus (other.locus)
2012 {
2013 generic_params.reserve (other.generic_params.size ());
2014 for (const auto &e : other.generic_params)
2015 generic_params.push_back (e->clone_generic_param ());
2016 }
2017
2018 // overloaded assignment operator with vector clone
2019 Union &operator= (Union const &other)
2020 {
2021 VisItem::operator= (other);
2022 union_name = other.union_name;
2023 where_clause = other.where_clause;
2024 variants = other.variants;
2025 locus = other.locus;
2026
2027 generic_params.reserve (other.generic_params.size ());
2028 for (const auto &e : other.generic_params)
2029 generic_params.push_back (e->clone_generic_param ());
2030
2031 return *this;
2032 }
2033
2034 // move constructors
2035 Union (Union &&other) = default;
2036 Union &operator= (Union &&other) = default;
2037
2038 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2039 {
2040 return generic_params;
2041 }
2042
2043 Identifier get_identifier () const { return union_name; }
2044
2045 Location get_locus () const override final { return locus; }
2046
2047 void accept_vis (HIRFullVisitor &vis) override;
2048 void accept_vis (HIRStmtVisitor &vis) override;
2049 void accept_vis (HIRVisItemVisitor &vis) override;
2050
2051 std::vector<StructField> &get_variants () { return variants; }
2052
2053 WhereClause &get_where_clause () { return where_clause; }
2054
2055 ItemKind get_item_kind () const override { return ItemKind::Union; }
2056
2057protected:
2058 /* Use covariance to implement clone function as returning this object
2059 * rather than base */
2060 Union *clone_item_impl () const override { return new Union (*this); }
2061};
2062
2063class ConstantItem : public VisItem, public ImplItem
2064{
2065 Identifier identifier;
2066 std::unique_ptr<Type> type;
2067 std::unique_ptr<Expr> const_expr;
2068 Location locus;
2069
2070public:
2071 std::string as_string () const override;
2072
2073 ConstantItem (Analysis::NodeMapping mappings, Identifier ident,
2074 Visibility vis, std::unique_ptr<Type> type,
2075 std::unique_ptr<Expr> const_expr, AST::AttrVec outer_attrs,
2076 Location locus)
2077 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2078 identifier (std::move (ident)), type (std::move (type)),
2079 const_expr (std::move (const_expr)), locus (locus)
2080 {}
2081
2082 ConstantItem (ConstantItem const &other)
2083 : VisItem (other), identifier (other.identifier),
2084 type (other.type->clone_type ()),
2085 const_expr (other.const_expr->clone_expr ()), locus (other.locus)
2086 {}
2087
2088 // Overload assignment operator to clone
2089 ConstantItem &operator= (ConstantItem const &other)
2090 {
2091 VisItem::operator= (other);
2092 identifier = other.identifier;
2093 type = other.type->clone_type ();
2094 const_expr = other.const_expr->clone_expr ();
2095 locus = other.locus;
2096
2097 return *this;
2098 }
2099
2100 // move constructors
2101 ConstantItem (ConstantItem &&other) = default;
2102 ConstantItem &operator= (ConstantItem &&other) = default;
2103
2104 // Returns whether constant item is an "unnamed" (wildcard underscore used
2105 // as identifier) constant.
2106 bool is_unnamed () const { return identifier == std::string ("_"); }
2107
2108 Location get_locus () const override final { return locus; }
2109
2110 void accept_vis (HIRFullVisitor &vis) override;
2111 void accept_vis (HIRStmtVisitor &vis) override;
2112 void accept_vis (HIRImplVisitor &vis) override;
2113 void accept_vis (HIRVisItemVisitor &vis) override;
2114
2115 Type *get_type () { return type.get (); }
2116
2117 Expr *get_expr () { return const_expr.get (); }
2118
2119 std::string get_identifier () { return identifier; }
2120
2121 Analysis::NodeMapping get_impl_mappings () const override
2122 {
2123 return get_mappings ();
2124 };
2125
2126 ImplItemType get_impl_item_type () const override final
2127 {
2128 return ImplItem::ImplItemType::CONSTANT;
2129 }
2130
2131 ItemKind get_item_kind () const override { return ItemKind::Constant; }
2132
2133protected:
2134 /* Use covariance to implement clone function as returning this object
2135 * rather than base */
2136 ConstantItem *clone_item_impl () const override
2137 {
2138 return new ConstantItem (*this);
2139 }
2140
2141 /* Use covariance to implement clone function as returning this object
2142 * rather than base */
2143 ConstantItem *clone_inherent_impl_item_impl () const override
2144 {
2145 return new ConstantItem (*this);
2146 }
2147};
2148
2149/* Static item HIR node - items within module scope with fixed storage
2150 * duration? */
2151class StaticItem : public VisItem
2152{
2153 Mutability mut;
2154 Identifier name;
2155 std::unique_ptr<Type> type;
2156 std::unique_ptr<Expr> expr;
2157 Location locus;
2158
2159public:
2160 std::string as_string () const override;
2161
2162 StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut,
2163 std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
2164 Visibility vis, AST::AttrVec outer_attrs, Location locus)
2165 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2166 mut (mut), name (std::move (name)), type (std::move (type)),
2167 expr (std::move (expr)), locus (locus)
2168 {}
2169
2170 // Copy constructor with clone
2171 StaticItem (StaticItem const &other)
2172 : VisItem (other), mut (other.mut), name (other.name),
2173 type (other.type->clone_type ()), expr (other.expr->clone_expr ()),
2174 locus (other.locus)
2175 {}
2176
2177 // Overloaded assignment operator to clone
2178 StaticItem &operator= (StaticItem const &other)
2179 {
2180 VisItem::operator= (other);
2181 name = other.name;
2182 mut = other.mut;
2183 type = other.type->clone_type ();
2184 expr = other.expr->clone_expr ();
2185 locus = other.locus;
2186
2187 return *this;
2188 }
2189
2190 // move constructors
2191 StaticItem (StaticItem &&other) = default;
2192 StaticItem &operator= (StaticItem &&other) = default;
2193
2194 Location get_locus () const override final { return locus; }
2195
2196 void accept_vis (HIRFullVisitor &vis) override;
2197 void accept_vis (HIRStmtVisitor &vis) override;
2198 void accept_vis (HIRVisItemVisitor &vis) override;
2199
2200 Identifier get_identifier () const { return name; }
2201
2202 Mutability get_mut () const { return mut; }
2203
2204 bool is_mut () const { return mut == Mutability::Mut; }
2205
2206 Expr *get_expr () { return expr.get (); }
2207
2208 Type *get_type () { return type.get (); }
2209
2210 ItemKind get_item_kind () const override { return ItemKind::Static; }
2211
2212protected:
2213 StaticItem *clone_item_impl () const override
2214 {
2215 return new StaticItem (*this);
2216 }
2217};
2218
2219// Function declaration in traits
2220struct TraitFunctionDecl
2221{
2222private:
2223 FunctionQualifiers qualifiers;
2224 Identifier function_name;
2225 std::vector<std::unique_ptr<GenericParam>> generic_params;
2226 std::vector<FunctionParam> function_params;
2227 std::unique_ptr<Type> return_type;
2228 WhereClause where_clause;
2229 SelfParam self;
2230
2231public:
2232 // Mega-constructor
2233 TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
2234 std::vector<std::unique_ptr<GenericParam>> generic_params,
2235 SelfParam self, std::vector<FunctionParam> function_params,
2236 std::unique_ptr<Type> return_type,
2237 WhereClause where_clause)
2238 : qualifiers (std::move (qualifiers)),
2239 function_name (std::move (function_name)),
2240 generic_params (std::move (generic_params)),
2241 function_params (std::move (function_params)),
2242 return_type (std::move (return_type)),
2243 where_clause (std::move (where_clause)), self (std::move (self))
2244 {}
2245
2246 // Copy constructor with clone
2247 TraitFunctionDecl (TraitFunctionDecl const &other)
2248 : qualifiers (other.qualifiers), function_name (other.function_name),
2249 function_params (other.function_params),
2250 return_type (other.return_type->clone_type ()),
2251 where_clause (other.where_clause), self (other.self)
2252 {
2253 generic_params.reserve (other.generic_params.size ());
2254 for (const auto &e : other.generic_params)
2255 generic_params.push_back (e->clone_generic_param ());
2256 }
2257
2258 ~TraitFunctionDecl () = default;
2259
2260 // Overloaded assignment operator with clone
2261 TraitFunctionDecl &operator= (TraitFunctionDecl const &other)
2262 {
2263 function_name = other.function_name;
2264 qualifiers = other.qualifiers;
2265 function_params = other.function_params;
2266 return_type = other.return_type->clone_type ();
2267 where_clause = other.where_clause;
2268 self = other.self;
2269
2270 generic_params.reserve (other.generic_params.size ());
2271 for (const auto &e : other.generic_params)
2272 generic_params.push_back (e->clone_generic_param ());
2273
2274 return *this;
2275 }
2276
2277 // move constructors
2278 TraitFunctionDecl (TraitFunctionDecl &&other) = default;
2279 TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default;
2280
2281 std::string as_string () const;
2282
2283 // Returns whether function decl has generic parameters.
2284 bool has_generics () const { return !generic_params.empty (); }
2285
2286 // Returns whether function decl has regular parameters.
2287 bool has_params () const { return !function_params.empty (); }
2288
2289 // Returns whether function has return type (otherwise is void).
2290 bool has_return_type () const { return return_type != nullptr; }
2291
2292 // Returns whether function has a where clause.
2293 bool has_where_clause () const { return !where_clause.is_empty (); }
2294
2295 bool is_method () const { return !self.is_error (); }
2296
2297 SelfParam &get_self () { return self; }
2298
2299 Identifier get_function_name () const { return function_name; }
2300
2301 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2302 {
2303 return generic_params;
2304 }
2305
2306 std::unique_ptr<Type> &get_return_type ()
2307 {
2308 rust_assert (has_return_type ());
2309 return return_type;
2310 }
2311
2312 std::vector<FunctionParam> &get_function_params () { return function_params; }
2313
2314 const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
2315};
2316
2317// Actual trait item function declaration within traits
2318class TraitItemFunc : public TraitItem
2319{
2320 AST::AttrVec outer_attrs;
2321 TraitFunctionDecl decl;
2322 std::unique_ptr<BlockExpr> block_expr;
2323 Location locus;
2324
2325public:
2326 // Returns whether function has a definition or is just a declaration.
2327 bool has_definition () const { return block_expr != nullptr; }
2328
2329 TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl,
2330 std::unique_ptr<BlockExpr> block_expr,
2331 AST::AttrVec outer_attrs, Location locus)
2332 : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
2333 decl (std::move (decl)), block_expr (std::move (block_expr)),
2334 locus (locus)
2335 {}
2336
2337 // Copy constructor with clone
2338 TraitItemFunc (TraitItemFunc const &other)
2339 : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
2340 decl (other.decl), locus (other.locus)
2341 {
2342 if (other.block_expr != nullptr)
2343 block_expr = other.block_expr->clone_block_expr ();
2344 }
2345
2346 // Overloaded assignment operator to clone
2347 TraitItemFunc &operator= (TraitItemFunc const &other)
2348 {
2349 TraitItem::operator= (other);
2350 outer_attrs = other.outer_attrs;
2351 decl = other.decl;
2352 locus = other.locus;
2353 mappings = other.mappings;
2354 if (other.block_expr != nullptr)
2355 block_expr = other.block_expr->clone_block_expr ();
2356
2357 return *this;
2358 }
2359
2360 // move constructors
2361 TraitItemFunc (TraitItemFunc &&other) = default;
2362 TraitItemFunc &operator= (TraitItemFunc &&other) = default;
2363
2364 std::string as_string () const override;
2365
2366 Location get_locus () const { return locus; }
2367
2368 void accept_vis (HIRFullVisitor &vis) override;
2369 void accept_vis (HIRTraitItemVisitor &vis) override;
2370
2371 TraitFunctionDecl &get_decl () { return decl; }
2372
2373 const TraitFunctionDecl &get_decl () const { return decl; }
2374
2375 bool has_block_defined () const { return block_expr != nullptr; }
2376
2377 std::unique_ptr<BlockExpr> &get_block_expr ()
2378 {
2379 rust_assert (has_block_defined ());
2380 return block_expr;
2381 }
2382
2383 const std::string trait_identifier () const override final
2384 {
2385 return decl.get_function_name ();
2386 }
2387
2388 TraitItemKind get_item_kind () const override final
2389 {
2390 return TraitItemKind::FUNC;
2391 }
2392
2393 AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
2394 const AST::AttrVec &get_outer_attrs () const override final
2395 {
2396 return outer_attrs;
2397 }
2398
8f0b1526
PH
2399 Location get_trait_locus () const override { return get_locus (); }
2400
8ad1d56d
PH
2401protected:
2402 // Clone function implementation as (not pure) virtual method
2403 TraitItemFunc *clone_trait_item_impl () const override
2404 {
2405 return new TraitItemFunc (*this);
2406 }
2407};
2408
2409// Constant item within traits
2410class TraitItemConst : public TraitItem
2411{
2412 AST::AttrVec outer_attrs;
2413 Identifier name;
2414 std::unique_ptr<Type> type;
2415 std::unique_ptr<Expr> expr;
2416 Location locus;
2417
2418public:
2419 // Whether the constant item has an associated expression.
2420 bool has_expression () const { return expr != nullptr; }
2421
2422 TraitItemConst (Analysis::NodeMapping mappings, Identifier name,
2423 std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
2424 AST::AttrVec outer_attrs, Location locus)
2425 : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
2426 name (std::move (name)), type (std::move (type)), expr (std::move (expr)),
2427 locus (locus)
2428 {}
2429
2430 // Copy constructor with clones
2431 TraitItemConst (TraitItemConst const &other)
2432 : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
2433 name (other.name), type (other.type->clone_type ()),
2434 expr (other.expr->clone_expr ()), locus (other.locus)
2435 {}
2436
2437 // Overloaded assignment operator to clone
2438 TraitItemConst &operator= (TraitItemConst const &other)
2439 {
2440 TraitItem::operator= (other);
2441 outer_attrs = other.outer_attrs;
2442 name = other.name;
2443 type = other.type->clone_type ();
2444 expr = other.expr->clone_expr ();
2445 locus = other.locus;
2446 mappings = other.mappings;
2447
2448 return *this;
2449 }
2450
2451 // move constructors
2452 TraitItemConst (TraitItemConst &&other) = default;
2453 TraitItemConst &operator= (TraitItemConst &&other) = default;
2454
2455 std::string as_string () const override;
2456
2457 Location get_locus () const { return locus; }
2458
2459 void accept_vis (HIRFullVisitor &vis) override;
2460 void accept_vis (HIRTraitItemVisitor &vis) override;
2461
2462 Identifier get_name () const { return name; }
2463
2464 bool has_expr () const { return expr != nullptr; }
2465
2466 std::unique_ptr<Type> &get_type () { return type; }
2467
2468 std::unique_ptr<Expr> &get_expr ()
2469 {
2470 rust_assert (has_expr ());
2471 return expr;
2472 }
2473
2474 const std::string trait_identifier () const override final { return name; }
2475
2476 TraitItemKind get_item_kind () const override final
2477 {
2478 return TraitItemKind::CONST;
2479 }
2480
2481 AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
2482 const AST::AttrVec &get_outer_attrs () const override final
2483 {
2484 return outer_attrs;
2485 }
2486
8f0b1526
PH
2487 Location get_trait_locus () const override { return get_locus (); }
2488
8ad1d56d
PH
2489protected:
2490 // Clone function implementation as (not pure) virtual method
2491 TraitItemConst *clone_trait_item_impl () const override
2492 {
2493 return new TraitItemConst (*this);
2494 }
2495};
2496
2497// Type items within traits
2498class TraitItemType : public TraitItem
2499{
2500 AST::AttrVec outer_attrs;
2501
2502 Identifier name;
2503 std::vector<std::unique_ptr<TypeParamBound>>
2504 type_param_bounds; // inlined form
2505 Location locus;
2506
2507public:
2508 // Returns whether trait item type has type param bounds.
2509 bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
2510
2511 TraitItemType (Analysis::NodeMapping mappings, Identifier name,
2512 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
2513 AST::AttrVec outer_attrs, Location locus)
2514 : TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
2515 name (std::move (name)),
2516 type_param_bounds (std::move (type_param_bounds)), locus (locus)
2517 {}
2518
2519 // Copy constructor with vector clone
2520 TraitItemType (TraitItemType const &other)
2521 : TraitItem (other.mappings), outer_attrs (other.outer_attrs),
2522 name (other.name), locus (other.locus)
2523 {
2524 type_param_bounds.reserve (other.type_param_bounds.size ());
2525 for (const auto &e : other.type_param_bounds)
2526 type_param_bounds.push_back (e->clone_type_param_bound ());
2527 }
2528
2529 // Overloaded assignment operator with vector clone
2530 TraitItemType &operator= (TraitItemType const &other)
2531 {
2532 TraitItem::operator= (other);
2533 outer_attrs = other.outer_attrs;
2534 name = other.name;
2535 locus = other.locus;
2536 mappings = other.mappings;
2537
2538 type_param_bounds.reserve (other.type_param_bounds.size ());
2539 for (const auto &e : other.type_param_bounds)
2540 type_param_bounds.push_back (e->clone_type_param_bound ());
2541
2542 return *this;
2543 }
2544
2545 // default move constructors
2546 TraitItemType (TraitItemType &&other) = default;
2547 TraitItemType &operator= (TraitItemType &&other) = default;
2548
2549 std::string as_string () const override;
2550
2551 Location get_locus () const { return locus; }
2552
2553 void accept_vis (HIRFullVisitor &vis) override;
2554 void accept_vis (HIRTraitItemVisitor &vis) override;
2555
2556 Identifier get_name () const { return name; }
2557
2558 std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
2559 {
2560 return type_param_bounds;
2561 }
2562
2563 const std::string trait_identifier () const override final { return name; }
2564
2565 TraitItemKind get_item_kind () const override final
2566 {
2567 return TraitItemKind::TYPE;
2568 }
2569
2570 AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
2571 const AST::AttrVec &get_outer_attrs () const override final
2572 {
2573 return outer_attrs;
2574 }
2575
8f0b1526
PH
2576 Location get_trait_locus () const override { return get_locus (); }
2577
8ad1d56d
PH
2578protected:
2579 // Clone function implementation as (not pure) virtual method
2580 TraitItemType *clone_trait_item_impl () const override
2581 {
2582 return new TraitItemType (*this);
2583 }
2584};
2585
2586// Rust trait item declaration HIR node
2587class Trait : public VisItem
2588{
2589 Unsafety unsafety;
2590 Identifier name;
2591 std::vector<std::unique_ptr<GenericParam>> generic_params;
2592 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
2593 WhereClause where_clause;
2594 std::vector<std::unique_ptr<TraitItem>> trait_items;
2595 Location locus;
2596
2597public:
2598 std::string as_string () const override;
2599
2600 // Returns whether trait has generic parameters.
2601 bool has_generics () const { return !generic_params.empty (); }
2602
2603 // Returns whether trait has type parameter bounds.
2604 bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
2605
2606 // Returns whether trait has where clause.
2607 bool has_where_clause () const { return !where_clause.is_empty (); }
2608
2609 // Returns whether trait has trait items.
2610 bool has_trait_items () const { return !trait_items.empty (); }
2611
2612 std::vector<std::unique_ptr<TraitItem>> &get_trait_items ()
2613 {
2614 return trait_items;
2615 }
2616
2617 Identifier get_name () const { return name; }
2618
2619 // Mega-constructor
2620 Trait (Analysis::NodeMapping mappings, Identifier name, Unsafety unsafety,
2621 std::vector<std::unique_ptr<GenericParam>> generic_params,
2622 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
2623 WhereClause where_clause,
2624 std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis,
2625 AST::AttrVec outer_attrs, Location locus)
2626 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2627 unsafety (unsafety), name (std::move (name)),
2628 generic_params (std::move (generic_params)),
2629 type_param_bounds (std::move (type_param_bounds)),
2630 where_clause (std::move (where_clause)),
2631 trait_items (std::move (trait_items)), locus (locus)
2632 {}
2633
2634 // Copy constructor with vector clone
2635 Trait (Trait const &other)
2636 : VisItem (other), unsafety (other.unsafety), name (other.name),
2637 where_clause (other.where_clause), locus (other.locus)
2638 {
2639 generic_params.reserve (other.generic_params.size ());
2640 for (const auto &e : other.generic_params)
2641 generic_params.push_back (e->clone_generic_param ());
2642
2643 type_param_bounds.reserve (other.type_param_bounds.size ());
2644 for (const auto &e : other.type_param_bounds)
2645 type_param_bounds.push_back (e->clone_type_param_bound ());
2646
2647 trait_items.reserve (other.trait_items.size ());
2648 for (const auto &e : other.trait_items)
2649 trait_items.push_back (e->clone_trait_item ());
2650 }
2651
2652 // Overloaded assignment operator with vector clone
2653 Trait &operator= (Trait const &other)
2654 {
2655 VisItem::operator= (other);
2656 name = other.name;
2657 unsafety = other.unsafety;
2658 where_clause = other.where_clause;
2659 locus = other.locus;
2660
2661 generic_params.reserve (other.generic_params.size ());
2662 for (const auto &e : other.generic_params)
2663 generic_params.push_back (e->clone_generic_param ());
2664
2665 type_param_bounds.reserve (other.type_param_bounds.size ());
2666 for (const auto &e : other.type_param_bounds)
2667 type_param_bounds.push_back (e->clone_type_param_bound ());
2668
2669 trait_items.reserve (other.trait_items.size ());
2670 for (const auto &e : other.trait_items)
2671 trait_items.push_back (e->clone_trait_item ());
2672
2673 return *this;
2674 }
2675
2676 // default move constructors
2677 Trait (Trait &&other) = default;
2678 Trait &operator= (Trait &&other) = default;
2679
2680 Location get_locus () const override final { return locus; }
2681
2682 void accept_vis (HIRFullVisitor &vis) override;
2683 void accept_vis (HIRStmtVisitor &vis) override;
2684 void accept_vis (HIRVisItemVisitor &vis) override;
2685
2686 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2687 {
2688 return generic_params;
2689 }
2690
2691 const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
2692 {
2693 return generic_params;
2694 }
2695
2696 std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
2697 {
2698 return type_param_bounds;
2699 }
2700
2701 const std::vector<std::unique_ptr<TypeParamBound>> &
2702 get_type_param_bounds () const
2703 {
2704 return type_param_bounds;
2705 }
2706
2707 ItemKind get_item_kind () const override { return ItemKind::Trait; }
2708
2709protected:
2710 /* Use covariance to implement clone function as returning this object
2711 * rather than base */
2712 Trait *clone_item_impl () const override { return new Trait (*this); }
2713};
2714
2715class ImplBlock : public VisItem
2716{
2717 std::vector<std::unique_ptr<GenericParam>> generic_params;
2718 std::unique_ptr<Type> impl_type;
2719 std::unique_ptr<TypePath> trait_ref;
2720 WhereClause where_clause;
2721 Polarity polarity;
2722 AST::AttrVec inner_attrs;
2723 Location locus;
2724 std::vector<std::unique_ptr<ImplItem>> impl_items;
2725
2726public:
2727 ImplBlock (Analysis::NodeMapping mappings,
2728 std::vector<std::unique_ptr<ImplItem>> impl_items,
2729 std::vector<std::unique_ptr<GenericParam>> generic_params,
2730 std::unique_ptr<Type> impl_type,
2731 std::unique_ptr<TypePath> trait_ref, WhereClause where_clause,
2732 Polarity polarity, Visibility vis, AST::AttrVec inner_attrs,
2733 AST::AttrVec outer_attrs, Location locus)
2734 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
2735 generic_params (std::move (generic_params)),
2736 impl_type (std::move (impl_type)), trait_ref (std::move (trait_ref)),
2737 where_clause (std::move (where_clause)), polarity (polarity),
2738 inner_attrs (std::move (inner_attrs)), locus (locus),
2739 impl_items (std::move (impl_items))
2740 {}
2741
2742 ImplBlock (ImplBlock const &other)
2743 : VisItem (other), impl_type (other.impl_type->clone_type ()),
2744 where_clause (other.where_clause), polarity (other.polarity),
2745 inner_attrs (other.inner_attrs), locus (other.locus)
2746 {
2747 generic_params.reserve (other.generic_params.size ());
2748 for (const auto &e : other.generic_params)
2749 generic_params.push_back (e->clone_generic_param ());
2750
2751 impl_items.reserve (other.impl_items.size ());
2752 for (const auto &e : other.impl_items)
2753 impl_items.push_back (e->clone_inherent_impl_item ());
2754 }
2755
2756 ImplBlock &operator= (ImplBlock const &other)
2757 {
2758 VisItem::operator= (other);
2759 impl_type = other.impl_type->clone_type ();
2760 where_clause = other.where_clause;
2761 polarity = other.polarity;
2762 inner_attrs = other.inner_attrs;
2763 locus = other.locus;
2764
2765 generic_params.reserve (other.generic_params.size ());
2766 for (const auto &e : other.generic_params)
2767 generic_params.push_back (e->clone_generic_param ());
2768
2769 impl_items.reserve (other.impl_items.size ());
2770 for (const auto &e : other.impl_items)
2771 impl_items.push_back (e->clone_inherent_impl_item ());
2772
2773 return *this;
2774 }
2775
2776 ImplBlock (ImplBlock &&other) = default;
2777 ImplBlock &operator= (ImplBlock &&other) = default;
2778
2779 std::string as_string () const override;
2780
2781 // Returns whether inherent impl block has inherent impl items.
2782 bool has_impl_items () const { return !impl_items.empty (); }
2783
2784 void accept_vis (HIRFullVisitor &vis) override;
2785 void accept_vis (HIRStmtVisitor &vis) override;
2786 void accept_vis (HIRVisItemVisitor &vis) override;
2787
2788 std::vector<std::unique_ptr<ImplItem>> &get_impl_items ()
2789 {
2790 return impl_items;
2791 };
2792
2793 const std::vector<std::unique_ptr<ImplItem>> &get_impl_items () const
2794 {
2795 return impl_items;
2796 };
2797
2798 // Returns whether impl has generic parameters.
2799 bool has_generics () const { return !generic_params.empty (); }
2800
2801 // Returns whether impl has where clause.
2802 bool has_where_clause () const { return !where_clause.is_empty (); }
2803
2804 // Returns the polarity of the impl.
2805 Polarity get_polarity () const { return polarity; }
2806
2807 // Returns whether impl has inner attributes.
2808 bool has_inner_attrs () const { return !inner_attrs.empty (); }
2809
2810 Location get_locus () const override final { return locus; }
2811
2812 std::unique_ptr<Type> &get_type () { return impl_type; };
2813
2814 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2815 {
2816 return generic_params;
2817 }
2818
2819 bool has_trait_ref () const { return trait_ref != nullptr; }
2820
2821 std::unique_ptr<TypePath> &get_trait_ref ()
2822 {
2823 rust_assert (has_trait_ref ());
2824 return trait_ref;
2825 }
2826
2827 WhereClause &get_where_clause () { return where_clause; }
2828
2829 ItemKind get_item_kind () const override { return ItemKind::Impl; }
2830
2831protected:
2832 ImplBlock *clone_item_impl () const override { return new ImplBlock (*this); }
2833};
2834
2835// Abstract base class for an item used inside an extern block
2836class ExternalItem : public Node
2837{
2838 Analysis::NodeMapping mappings;
2839 AST::AttrVec outer_attrs;
2840 Visibility visibility;
2841 Identifier item_name;
2842 Location locus;
2843
2844public:
2845 enum class ExternKind
2846 {
2847 Static,
2848 Function,
2849 };
2850
2851 virtual ~ExternalItem () {}
2852
2853 BaseKind get_hir_kind () override final { return EXTERNAL; }
2854
2855 virtual ExternKind get_extern_kind () = 0;
2856
2857 // Returns whether item has outer attributes.
2858 bool has_outer_attrs () const { return !outer_attrs.empty (); }
2859
2860 // Returns whether item has non-default visibility.
2861 bool has_visibility () const { return !visibility.is_error (); }
2862
2863 // Unique pointer custom clone function
2864 std::unique_ptr<ExternalItem> clone_external_item () const
2865 {
2866 return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
2867 }
2868
2869 virtual std::string as_string () const;
2870
2871 Location get_locus () const { return locus; }
2872
2873 virtual void accept_vis (HIRFullVisitor &vis) = 0;
2874 virtual void accept_vis (HIRExternalItemVisitor &vis) = 0;
2875
2876 Analysis::NodeMapping get_mappings () const { return mappings; }
2877
2878 Identifier get_item_name () const { return item_name; }
2879
2880 AST::AttrVec &get_outer_attrs () { return outer_attrs; }
2881
2882protected:
2883 ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
2884 Visibility vis, AST::AttrVec outer_attrs, Location locus)
2885 : mappings (mappings), outer_attrs (std::move (outer_attrs)),
2886 visibility (std::move (vis)), item_name (std::move (item_name)),
2887 locus (locus)
2888 {}
2889
2890 // Copy constructor
2891 ExternalItem (ExternalItem const &other)
2892 : mappings (other.mappings), outer_attrs (other.outer_attrs),
2893 visibility (other.visibility), item_name (other.item_name),
2894 locus (other.locus)
2895 {}
2896
2897 // Overloaded assignment operator to clone
2898 ExternalItem &operator= (ExternalItem const &other)
2899 {
2900 mappings = other.mappings;
2901 item_name = other.item_name;
2902 visibility = other.visibility;
2903 outer_attrs = other.outer_attrs;
2904 locus = other.locus;
2905
2906 return *this;
2907 }
2908
2909 // move constructors
2910 ExternalItem (ExternalItem &&other) = default;
2911 ExternalItem &operator= (ExternalItem &&other) = default;
2912
2913 // Clone function implementation as pure virtual method
2914 virtual ExternalItem *clone_external_item_impl () const = 0;
2915};
2916
2917// A static item used in an extern block
2918class ExternalStaticItem : public ExternalItem
2919{
2920 Mutability mut;
2921 std::unique_ptr<Type> item_type;
2922
2923public:
2924 ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name,
2925 std::unique_ptr<Type> item_type, Mutability mut,
2926 Visibility vis, AST::AttrVec outer_attrs, Location locus)
2927 : ExternalItem (std::move (mappings), std::move (item_name),
2928 std::move (vis), std::move (outer_attrs), locus),
2929 mut (mut), item_type (std::move (item_type))
2930 {}
2931
2932 // Copy constructor
2933 ExternalStaticItem (ExternalStaticItem const &other)
2934 : ExternalItem (other), mut (other.mut),
2935 item_type (other.item_type->clone_type ())
2936 {}
2937
2938 // Overloaded assignment operator to clone
2939 ExternalStaticItem &operator= (ExternalStaticItem const &other)
2940 {
2941 ExternalItem::operator= (other);
2942 item_type = other.item_type->clone_type ();
2943 mut = other.mut;
2944
2945 return *this;
2946 }
2947
2948 // move constructors
2949 ExternalStaticItem (ExternalStaticItem &&other) = default;
2950 ExternalStaticItem &operator= (ExternalStaticItem &&other) = default;
2951
2952 std::string as_string () const override;
2953
2954 void accept_vis (HIRFullVisitor &vis) override;
2955 void accept_vis (HIRExternalItemVisitor &vis) override;
2956
2957 bool is_mut () const { return mut == Mutability::Mut; }
2958
2959 Mutability get_mut () { return mut; }
2960
2961 std::unique_ptr<Type> &get_item_type () { return item_type; }
2962
2963 ExternKind get_extern_kind () override { return ExternKind::Static; }
2964
2965protected:
2966 /* Use covariance to implement clone function as returning this object
2967 * rather than base */
2968 ExternalStaticItem *clone_external_item_impl () const override
2969 {
2970 return new ExternalStaticItem (*this);
2971 }
2972};
2973
2974// A named function parameter used in external functions
2975struct NamedFunctionParam
2976{
2977private:
2978 Identifier name;
2979 std::unique_ptr<Type> param_type;
2980 Analysis::NodeMapping mappings;
2981
2982public:
2983 bool has_name () const { return name != "_"; }
2984
2985 NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name,
2986 std::unique_ptr<Type> param_type)
2987 : name (std::move (name)), param_type (std::move (param_type)),
2988 mappings (std::move (mappings))
2989 {}
2990
2991 // Copy constructor
2992 NamedFunctionParam (NamedFunctionParam const &other)
2993 : name (other.name), param_type (other.param_type->clone_type ()),
2994 mappings (other.mappings)
2995 {}
2996
2997 ~NamedFunctionParam () = default;
2998
2999 // Overloaded assignment operator to clone
3000 NamedFunctionParam &operator= (NamedFunctionParam const &other)
3001 {
3002 mappings = other.mappings;
3003 name = other.name;
3004 param_type = other.param_type->clone_type ();
3005 // has_name = other.has_name;
3006
3007 return *this;
3008 }
3009
3010 // move constructors
3011 NamedFunctionParam (NamedFunctionParam &&other) = default;
3012 NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;
3013
3014 std::string as_string () const;
3015
3016 Identifier get_param_name () const { return name; }
3017
3018 std::unique_ptr<Type> &get_type () { return param_type; }
3019
3020 Analysis::NodeMapping get_mappings () const { return mappings; }
3021};
3022
3023// A function item used in an extern block
3024class ExternalFunctionItem : public ExternalItem
3025{
3026 // bool has_generics;
3027 // Generics generic_params;
3028 std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
3029
3030 // bool has_return_type;
3031 // FunctionReturnType return_type;
3032 std::unique_ptr<Type> return_type; // inlined
3033
3034 // bool has_where_clause;
3035 WhereClause where_clause;
3036
3037 std::vector<NamedFunctionParam> function_params;
3038 bool has_variadics;
3039
3040public:
3041 // Returns whether item has generic parameters.
3042 bool has_generics () const { return !generic_params.empty (); }
3043
3044 // Returns whether item has a return type (otherwise void).
3045 bool has_return_type () const { return return_type != nullptr; }
3046
3047 // Returns whether item has a where clause.
3048 bool has_where_clause () const { return !where_clause.is_empty (); }
3049
3050 ExternalFunctionItem (
3051 Analysis::NodeMapping mappings, Identifier item_name,
3052 std::vector<std::unique_ptr<GenericParam>> generic_params,
3053 std::unique_ptr<Type> return_type, WhereClause where_clause,
3054 std::vector<NamedFunctionParam> function_params, bool has_variadics,
3055 Visibility vis, AST::AttrVec outer_attrs, Location locus)
3056 : ExternalItem (std::move (mappings), std::move (item_name),
3057 std::move (vis), std::move (outer_attrs), locus),
3058 generic_params (std::move (generic_params)),
3059 return_type (std::move (return_type)),
3060 where_clause (std::move (where_clause)),
3061 function_params (std::move (function_params)),
3062 has_variadics (has_variadics)
3063 {}
3064
3065 // Copy constructor with clone
3066 ExternalFunctionItem (ExternalFunctionItem const &other)
3067 : ExternalItem (other), return_type (other.return_type->clone_type ()),
3068 where_clause (other.where_clause),
3069 function_params (other.function_params),
3070 has_variadics (other.has_variadics)
3071 {
3072 generic_params.reserve (other.generic_params.size ());
3073 for (const auto &e : other.generic_params)
3074 generic_params.push_back (e->clone_generic_param ());
3075 }
3076
3077 // Overloaded assignment operator with clone
3078 ExternalFunctionItem &operator= (ExternalFunctionItem const &other)
3079 {
3080 ExternalItem::operator= (other);
3081 return_type = other.return_type->clone_type ();
3082 where_clause = other.where_clause;
3083 function_params = other.function_params;
3084 has_variadics = other.has_variadics;
3085
3086 generic_params.reserve (other.generic_params.size ());
3087 for (const auto &e : other.generic_params)
3088 generic_params.push_back (e->clone_generic_param ());
3089
3090 return *this;
3091 }
3092
3093 // move constructors
3094 ExternalFunctionItem (ExternalFunctionItem &&other) = default;
3095 ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default;
3096
3097 std::string as_string () const override;
3098
3099 void accept_vis (HIRFullVisitor &vis) override;
3100 void accept_vis (HIRExternalItemVisitor &vis) override;
3101
3102 std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
3103 {
3104 return generic_params;
3105 }
3106
3107 std::unique_ptr<Type> &get_return_type () { return return_type; }
3108
3109 std::vector<NamedFunctionParam> &get_function_params ()
3110 {
3111 return function_params;
3112 }
3113
3114 bool is_variadic () const { return has_variadics; }
3115
3116 ExternKind get_extern_kind () override { return ExternKind::Function; }
3117
3118protected:
3119 /* Use covariance to implement clone function as returning this object
3120 * rather than base */
3121 ExternalFunctionItem *clone_external_item_impl () const override
3122 {
3123 return new ExternalFunctionItem (*this);
3124 }
3125};
3126
3127// An extern block HIR node
3128class ExternBlock : public VisItem
3129{
3130 ABI abi;
3131 AST::AttrVec inner_attrs;
3132 std::vector<std::unique_ptr<ExternalItem>> extern_items;
3133 Location locus;
3134
3135public:
3136 std::string as_string () const override;
3137
3138 // Returns whether extern block has inner attributes.
3139 bool has_inner_attrs () const { return !inner_attrs.empty (); }
3140
3141 // Returns whether extern block has extern items.
3142 bool has_extern_items () const { return !extern_items.empty (); }
3143
3144 ABI get_abi () const { return abi; }
3145
3146 ExternBlock (Analysis::NodeMapping mappings, ABI abi,
3147 std::vector<std::unique_ptr<ExternalItem>> extern_items,
3148 Visibility vis, AST::AttrVec inner_attrs,
3149 AST::AttrVec outer_attrs, Location locus)
3150 : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
3151 abi (abi), inner_attrs (std::move (inner_attrs)),
3152 extern_items (std::move (extern_items)), locus (locus)
3153 {}
3154
3155 // Copy constructor with vector clone
3156 ExternBlock (ExternBlock const &other)
3157 : VisItem (other), abi (other.abi), inner_attrs (other.inner_attrs),
3158 locus (other.locus)
3159 {
3160 extern_items.reserve (other.extern_items.size ());
3161 for (const auto &e : other.extern_items)
3162 extern_items.push_back (e->clone_external_item ());
3163 }
3164
3165 // Overloaded assignment operator with vector clone
3166 ExternBlock &operator= (ExternBlock const &other)
3167 {
3168 VisItem::operator= (other);
3169 abi = other.abi;
3170 inner_attrs = other.inner_attrs;
3171 locus = other.locus;
3172
3173 extern_items.reserve (other.extern_items.size ());
3174 for (const auto &e : other.extern_items)
3175 extern_items.push_back (e->clone_external_item ());
3176
3177 return *this;
3178 }
3179
3180 // move constructors
3181 ExternBlock (ExternBlock &&other) = default;
3182 ExternBlock &operator= (ExternBlock &&other) = default;
3183
3184 Location get_locus () const override final { return locus; }
3185
3186 void accept_vis (HIRFullVisitor &vis) override;
3187 void accept_vis (HIRStmtVisitor &vis) override;
3188 void accept_vis (HIRVisItemVisitor &vis) override;
3189
3190 std::vector<std::unique_ptr<ExternalItem>> &get_extern_items ()
3191 {
3192 return extern_items;
3193 }
3194
3195 ItemKind get_item_kind () const override { return ItemKind::ExternBlock; }
3196
3197protected:
3198 /* Use covariance to implement clone function as returning this object
3199 * rather than base */
3200 ExternBlock *clone_item_impl () const override
3201 {
3202 return new ExternBlock (*this);
3203 }
3204
3205 /* Use covariance to implement clone function as returning this object
3206 * rather than base */
3207 /*virtual ExternBlock* clone_statement_impl() const override {
3208 return new ExternBlock(*this);
3209 }*/
3210};
3211
3212} // namespace HIR
3213} // namespace Rust
3214
3215#endif