]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/hir/tree/rust-hir.h
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / hir / tree / rust-hir.h
CommitLineData
83ffe9cd 1// Copyright (C) 2020-2023 Free Software Foundation, Inc.
7641eaea
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_BASE_H
20#define RUST_HIR_BASE_H
21
22#include "rust-ast.h"
23#include "rust-system.h"
24#include "rust-token.h"
25#include "rust-location.h"
26#include "rust-hir-map.h"
27#include "rust-diagnostics.h"
28
29namespace Rust {
30typedef std::string Identifier;
31typedef int TupleIndex;
32
33namespace HIR {
34// foward decl: ast visitor
35class HIRFullVisitor;
36class HIRStmtVisitor;
37class HIRTraitItemVisitor;
38class HIRExternalItemVisitor;
39class HIRVisItemVisitor;
40class HIRExpressionVisitor;
41class HIRPatternVisitor;
42class HIRImplVisitor;
43class HIRTypeVisitor;
44
45// forward decl for use in token tree method
46class Token;
47
48class Node
49{
50public:
51 // Kind for downcasting various HIR nodes to other base classes when visiting
52 // them
53 enum BaseKind
54 {
55 /* class ExternalItem */
56 EXTERNAL,
57 /* class TraitItem */
58 TRAIT_ITEM,
59 /* class VisItem */
60 VIS_ITEM,
61 /* class Item */
62 ITEM,
63 /* class ImplItem */
64 IMPL,
65 /* class Type */
66 TYPE,
67 /* class Stmt */
68 STMT,
69 /* class Expr */
70 EXPR,
71 /* class Pattern */
72 PATTERN,
73 };
74
75 /**
76 * Get the kind of HIR node we are dealing with. This is useful for
77 * downcasting to more precise types when necessary, i.e going from an `Item*`
78 * to a `VisItem*`
79 */
80 virtual BaseKind get_hir_kind () = 0;
81};
82
83// A literal - value with a type. Used in LiteralExpr and LiteralPattern.
84struct Literal
85{
86public:
87 enum LitType
88 {
89 CHAR,
90 STRING,
91 BYTE,
92 BYTE_STRING,
93 INT,
94 FLOAT,
95 BOOL
96 };
97
98private:
99 std::string value_as_string;
100 LitType type;
101 PrimitiveCoreType type_hint;
102
103public:
104 std::string as_string () const { return value_as_string; }
105
106 LitType get_lit_type () const { return type; }
107
108 PrimitiveCoreType get_type_hint () const { return type_hint; }
109
110 Literal (std::string value_as_string, LitType type,
111 PrimitiveCoreType type_hint)
112 : value_as_string (std::move (value_as_string)), type (type),
113 type_hint (type_hint)
114 {}
115
116 static Literal create_error ()
117 {
118 return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN);
119 }
120
121 void set_lit_type (LitType lt) { type = lt; }
122
123 // Returns whether literal is in an invalid state.
124 bool is_error () const { return value_as_string == ""; }
125
126 bool is_equal (Literal &other)
127 {
128 return value_as_string == other.value_as_string && type == other.type
129 && type_hint == other.type_hint;
130 }
131};
132
133/* Base statement abstract class. Note that most "statements" are not allowed in
134 * top-level module scope - only a subclass of statements called "items" are. */
135class Stmt : public Node
136{
137public:
138 // Unique pointer custom clone function
139 std::unique_ptr<Stmt> clone_stmt () const
140 {
141 return std::unique_ptr<Stmt> (clone_stmt_impl ());
142 }
143
144 BaseKind get_hir_kind () override { return STMT; }
145
146 virtual ~Stmt () {}
147
148 virtual std::string as_string () const = 0;
149
150 virtual void accept_vis (HIRFullVisitor &vis) = 0;
151 virtual void accept_vis (HIRStmtVisitor &vis) = 0;
152
153 virtual Location get_locus () const = 0;
154
155 virtual bool is_unit_check_needed () const { return false; }
156
157 const Analysis::NodeMapping &get_mappings () const { return mappings; }
158
159 virtual bool is_item () const = 0;
160
161protected:
162 Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {}
163
164 // Clone function implementation as pure virtual method
165 virtual Stmt *clone_stmt_impl () const = 0;
166
167 Analysis::NodeMapping mappings;
168};
169
170// Rust "item" HIR node (declaration of top-level/module-level allowed stuff)
171class Item : public Stmt
172{
173 AST::AttrVec outer_attrs;
174
175 // TODO: should outer attrs be defined here or in each derived class?
176
177public:
178 enum class ItemKind
179 {
180 Static,
181 Constant,
182 TypeAlias,
183 Function,
184 UseDeclaration,
185 ExternBlock,
186 ExternCrate,
187 Struct,
188 Union,
189 Enum,
190 EnumItem, // FIXME: ARTHUR: Do we need that?
191 Trait,
192 Impl,
193 Module,
194 };
195
196 virtual ItemKind get_item_kind () const = 0;
197
198 // Unique pointer custom clone function
199 std::unique_ptr<Item> clone_item () const
200 {
201 return std::unique_ptr<Item> (clone_item_impl ());
202 }
203
204 BaseKind get_hir_kind () override { return ITEM; }
205
206 std::string as_string () const override;
207
208 /* Adds crate names to the vector passed by reference, if it can
209 * (polymorphism). */
210 virtual void
211 add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
212 {}
213
214 AST::AttrVec &get_outer_attrs () { return outer_attrs; }
215 const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
216
217 bool is_item () const override final { return true; }
218
219protected:
220 // Constructor
221 Item (Analysis::NodeMapping mappings,
222 AST::AttrVec outer_attribs = AST::AttrVec ())
223 : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attribs))
224 {}
225
226 // Clone function implementation as pure virtual method
227 virtual Item *clone_item_impl () const = 0;
228
229 /* Save having to specify two clone methods in derived classes by making
230 * statement clone return item clone. Hopefully won't affect performance too
231 * much. */
232 Item *clone_stmt_impl () const override { return clone_item_impl (); }
233};
234
235// forward decl of ExprWithoutBlock
236class ExprWithoutBlock;
237
238// Base expression HIR node - abstract
239class Expr : public Node
240{
241 AST::AttrVec outer_attrs;
242 Analysis::NodeMapping mappings;
243
244public:
245 enum BlockType
246 {
247 WITH_BLOCK,
248 WITHOUT_BLOCK,
249 };
250
251 enum ExprType
252 {
253 Lit,
254 Operator,
255 Grouped,
256 Array,
257 ArrayIndex,
258 Tuple,
259 TupleIdx,
260 Struct,
261 Call,
262 MethodCall,
263 FieldAccess,
264 Closure,
265 Block,
266 Continue,
267 Break,
268 Range,
269 Return,
270 UnsafeBlock,
271 BaseLoop,
272 If,
273 IfLet,
274 Match,
275 Await,
276 AsyncBlock,
277 Path,
278 };
279
280 BaseKind get_hir_kind () override final { return EXPR; }
281
282 const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
283
284 // Unique pointer custom clone function
285 std::unique_ptr<Expr> clone_expr () const
286 {
287 return std::unique_ptr<Expr> (clone_expr_impl ());
288 }
289
290 /* HACK: downcasting without dynamic_cast (if possible) via polymorphism -
291 * overrided in subclasses of ExprWithoutBlock */
292 virtual ExprWithoutBlock *as_expr_without_block () const { return nullptr; }
293
294 // TODO: make pure virtual if move out outer attributes to derived classes
295 virtual std::string as_string () const;
296
297 virtual ~Expr () {}
298
299 virtual Location get_locus () const = 0;
300
301 const Analysis::NodeMapping &get_mappings () const { return mappings; }
302
303 // Clone function implementation as pure virtual method
304 virtual Expr *clone_expr_impl () const = 0;
305
306 virtual BlockType get_block_expr_type () const = 0;
307
308 virtual ExprType get_expression_type () const = 0;
309
310 virtual void accept_vis (HIRExpressionVisitor &vis) = 0;
311 virtual void accept_vis (HIRFullVisitor &vis) = 0;
312
313protected:
314 // Constructor
315 Expr (Analysis::NodeMapping mappings,
316 AST::AttrVec outer_attribs = AST::AttrVec ())
317 : outer_attrs (std::move (outer_attribs)), mappings (std::move (mappings))
318 {}
319
320 // TODO: think of less hacky way to implement this kind of thing
321 // Sets outer attributes.
322 void set_outer_attrs (AST::AttrVec outer_attrs_to_set)
323 {
324 outer_attrs = std::move (outer_attrs_to_set);
325 }
326};
327
328// HIR node for an expression without an accompanying block - abstract
329class ExprWithoutBlock : public Expr
330{
331protected:
332 // Constructor
333 ExprWithoutBlock (Analysis::NodeMapping mappings,
334 AST::AttrVec outer_attribs = AST::AttrVec ())
335 : Expr (std::move (mappings), std::move (outer_attribs))
336 {}
337
338 // pure virtual clone implementation
339 virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
340
341 /* Save having to specify two clone methods in derived classes by making expr
342 * clone return exprwithoutblock clone. Hopefully won't affect performance too
343 * much. */
344 ExprWithoutBlock *clone_expr_impl () const override
345 {
346 return clone_expr_without_block_impl ();
347 }
348
349public:
350 // Unique pointer custom clone function
351 std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
352 {
353 return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
354 }
355
356 /* downcasting hack from expr to use pratt parsing with
357 * parse_expr_without_block */
358 ExprWithoutBlock *as_expr_without_block () const override
359 {
360 return clone_expr_without_block_impl ();
361 }
362
363 BlockType get_block_expr_type () const final override
364 {
365 return BlockType::WITHOUT_BLOCK;
366 };
367};
368
369// Pattern base HIR node
370class Pattern : public Node
371{
372public:
373 enum PatternType
374 {
375 PATH,
376 LITERAL,
377 IDENTIFIER,
378 WILDCARD,
379 RANGE,
380 REFERENCE,
381 STRUCT,
382 TUPLE_STRUCT,
383 TUPLE,
384 GROUPED,
385 SLICE,
386 };
387
388 BaseKind get_hir_kind () override final { return PATTERN; }
389
390 // Unique pointer custom clone function
391 std::unique_ptr<Pattern> clone_pattern () const
392 {
393 return std::unique_ptr<Pattern> (clone_pattern_impl ());
394 }
395
396 // possible virtual methods: is_refutable()
397
398 virtual ~Pattern () {}
399
400 virtual std::string as_string () const = 0;
401
402 virtual void accept_vis (HIRFullVisitor &vis) = 0;
403 virtual void accept_vis (HIRPatternVisitor &vis) = 0;
404
405 virtual Analysis::NodeMapping get_pattern_mappings () const = 0;
406
407 virtual Location get_locus () const = 0;
408
409 virtual PatternType get_pattern_type () const = 0;
410
411protected:
412 // Clone pattern implementation as pure virtual method
413 virtual Pattern *clone_pattern_impl () const = 0;
414};
415
416// forward decl for Type
417class TraitBound;
418
419// Base class for types as represented in HIR - abstract
420class Type : public Node
421{
422public:
423 // Unique pointer custom clone function
424 std::unique_ptr<Type> clone_type () const
425 {
426 return std::unique_ptr<Type> (clone_type_impl ());
427 }
428
429 // virtual destructor
430 virtual ~Type () {}
431
432 BaseKind get_hir_kind () override final { return TYPE; }
433
434 virtual std::string as_string () const = 0;
435
436 /* HACK: convert to trait bound. Virtual method overriden by classes that
437 * enable this. */
438 virtual TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const
439 {
440 return nullptr;
441 }
442 /* as pointer, shouldn't require definition beforehand, only forward
443 * declaration. */
444
445 virtual void accept_vis (HIRFullVisitor &vis) = 0;
446 virtual void accept_vis (HIRTypeVisitor &vis) = 0;
447
448 virtual Analysis::NodeMapping get_mappings () const { return mappings; }
449 virtual Location get_locus () const { return locus; }
450
451protected:
452 Type (Analysis::NodeMapping mappings, Location locus)
453 : mappings (mappings), locus (locus)
454 {}
455
456 // Clone function implementation as pure virtual method
457 virtual Type *clone_type_impl () const = 0;
458
459 Analysis::NodeMapping mappings;
460 Location locus;
461};
462
463// A type without parentheses? - abstract
464class TypeNoBounds : public Type
465{
466public:
467 // Unique pointer custom clone function
468 std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
469 {
470 return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
471 }
472
473protected:
474 TypeNoBounds (Analysis::NodeMapping mappings, Location locus)
475 : Type (mappings, locus)
476 {}
477
478 // Clone function implementation as pure virtual method
479 virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
480
481 /* Save having to specify two clone methods in derived classes by making type
482 * clone return typenobounds clone. Hopefully won't affect performance too
483 * much. */
484 TypeNoBounds *clone_type_impl () const override
485 {
486 return clone_type_no_bounds_impl ();
487 }
488};
489
490/* Abstract base class representing a type param bound - Lifetime and TraitBound
491 * extends it */
492class TypeParamBound
493{
494public:
495 enum BoundType
496 {
497 LIFETIME,
498 TRAITBOUND
499 };
500
501 virtual ~TypeParamBound () {}
502
503 // Unique pointer custom clone function
504 std::unique_ptr<TypeParamBound> clone_type_param_bound () const
505 {
506 return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
507 }
508
509 virtual std::string as_string () const = 0;
510
511 virtual void accept_vis (HIRFullVisitor &vis) = 0;
512
513 virtual Analysis::NodeMapping get_mappings () const = 0;
514
515 virtual Location get_locus () const = 0;
516
517 virtual BoundType get_bound_type () const = 0;
518
519protected:
520 // Clone function implementation as pure virtual method
521 virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
522};
523
524// Represents a lifetime (and is also a kind of type param bound)
525class Lifetime : public TypeParamBound
526{
527private:
528 AST::Lifetime::LifetimeType lifetime_type;
529 std::string lifetime_name;
530 Location locus;
531 Analysis::NodeMapping mappings;
532
533public:
534 // Constructor
535 Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type,
536 std::string name, Location locus)
537 : lifetime_type (type), lifetime_name (std::move (name)), locus (locus),
538 mappings (mapping)
539 {}
540
541 // Returns true if the lifetime is in an error state.
542 bool is_error () const
543 {
544 return lifetime_type == AST::Lifetime::LifetimeType::NAMED
545 && lifetime_name.empty ();
546 }
547
548 static Lifetime error ()
549 {
550 return Lifetime (Analysis::NodeMapping::get_error (),
551 AST::Lifetime::LifetimeType::NAMED, "", Location ());
552 }
553
554 std::string as_string () const override;
555
556 void accept_vis (HIRFullVisitor &vis) override;
557
558 std::string get_name () const { return lifetime_name; }
559
560 AST::Lifetime::LifetimeType get_lifetime_type () const
561 {
562 return lifetime_type;
563 }
564
565 Location get_locus () const override final { return locus; }
566
567 Analysis::NodeMapping get_mappings () const override final
568 {
569 return mappings;
570 }
571
572 BoundType get_bound_type () const final override { return LIFETIME; }
573
574protected:
575 /* Use covariance to implement clone function as returning this object rather
576 * than base */
577 Lifetime *clone_type_param_bound_impl () const override
578 {
579 return new Lifetime (*this);
580 }
581};
582
583/* Base generic parameter in HIR. Abstract - can be represented by a Lifetime or
584 * Type param */
585class GenericParam
586{
587public:
588 virtual ~GenericParam () {}
589
590 enum class GenericKind
591 {
592 TYPE,
593 LIFETIME,
594 CONST,
595 };
596
597 // Unique pointer custom clone function
598 std::unique_ptr<GenericParam> clone_generic_param () const
599 {
600 return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
601 }
602
603 virtual std::string as_string () const = 0;
604
605 virtual void accept_vis (HIRFullVisitor &vis) = 0;
606
607 virtual Location get_locus () const = 0;
608
609 Analysis::NodeMapping get_mappings () const { return mappings; }
610
611 enum GenericKind get_kind () const { return kind; }
612
613protected:
614 // Clone function implementation as pure virtual method
615 virtual GenericParam *clone_generic_param_impl () const = 0;
616
617 Analysis::NodeMapping mappings;
618
619 enum GenericKind kind;
620
621 GenericParam (Analysis::NodeMapping mapping,
622 enum GenericKind kind = GenericKind::TYPE)
623 : mappings (mapping), kind (kind)
624 {}
625};
626
627// A lifetime generic parameter (as opposed to a type generic parameter)
628class LifetimeParam : public GenericParam
629{
630 Lifetime lifetime;
631
632 // bool has_lifetime_bounds;
633 // LifetimeBounds lifetime_bounds;
634 std::vector<Lifetime> lifetime_bounds; // inlined LifetimeBounds
635
636 // bool has_outer_attribute;
637 // std::unique_ptr<Attribute> outer_attr;
638 AST::Attribute outer_attr;
639
640 Location locus;
641
642public:
643 Lifetime get_lifetime () { return lifetime; }
644
645 // Returns whether the lifetime param has any lifetime bounds.
646 bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
647
648 // Returns whether the lifetime param has an outer attribute.
649 bool has_outer_attribute () const { return !outer_attr.is_empty (); }
650
651 // Returns whether the lifetime param is in an error state.
652 bool is_error () const { return lifetime.is_error (); }
653
654 // Constructor
655 LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime,
656 Location locus = Location (),
657 std::vector<Lifetime> lifetime_bounds
658 = std::vector<Lifetime> (),
659 AST::Attribute outer_attr = AST::Attribute::create_empty ())
660 : GenericParam (mappings, GenericKind::LIFETIME),
661 lifetime (std::move (lifetime)),
662 lifetime_bounds (std::move (lifetime_bounds)),
663 outer_attr (std::move (outer_attr)), locus (locus)
664 {}
665
666 // TODO: remove copy and assignment operator definitions - not required
667
668 // Copy constructor with clone
669 LifetimeParam (LifetimeParam const &other)
670 : GenericParam (other.mappings, GenericKind::LIFETIME),
671 lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds),
672 outer_attr (other.outer_attr), locus (other.locus)
673 {}
674
675 // Overloaded assignment operator to clone attribute
676 LifetimeParam &operator= (LifetimeParam const &other)
677 {
678 lifetime = other.lifetime;
679 lifetime_bounds = other.lifetime_bounds;
680 outer_attr = other.outer_attr;
681 locus = other.locus;
682 mappings = other.mappings;
683
684 return *this;
685 }
686
687 // move constructors
688 LifetimeParam (LifetimeParam &&other) = default;
689 LifetimeParam &operator= (LifetimeParam &&other) = default;
690
691 std::string as_string () const override;
692
693 void accept_vis (HIRFullVisitor &vis) override;
694
695 Location get_locus () const override final { return locus; }
696
697protected:
698 /* Use covariance to implement clone function as returning this object rather
699 * than base */
700 LifetimeParam *clone_generic_param_impl () const override
701 {
702 return new LifetimeParam (*this);
703 }
704};
705
706class ConstGenericParam : public GenericParam
707{
708public:
709 ConstGenericParam (std::string name, std::unique_ptr<Type> type,
710 std::unique_ptr<Expr> default_expression,
711 Analysis::NodeMapping mapping, Location locus)
712 : GenericParam (mapping, GenericKind::CONST), name (std::move (name)),
713 type (std::move (type)),
714 default_expression (std::move (default_expression)), locus (locus)
715 {}
716
717 ConstGenericParam (const ConstGenericParam &other) : GenericParam (other)
718 {
719 name = other.name;
720 locus = other.locus;
721
722 if (other.type)
723 type = other.type->clone_type ();
724 if (other.default_expression)
725 default_expression = other.default_expression->clone_expr ();
726 }
727
728 std::string as_string () const override final;
729
730 void accept_vis (HIRFullVisitor &vis) override final;
731
732 Location get_locus () const override final { return locus; };
733
734 bool has_default_expression () { return default_expression != nullptr; }
735
736 std::unique_ptr<Type> &get_type () { return type; }
737 std::unique_ptr<Expr> &get_default_expression ()
738 {
739 rust_assert (has_default_expression ());
740
741 return default_expression;
742 }
743
744protected:
745 /* Use covariance to implement clone function as returning this object rather
746 * than base */
747 ConstGenericParam *clone_generic_param_impl () const override
748 {
749 return new ConstGenericParam (*this);
750 }
751
752private:
753 std::string name;
754 std::unique_ptr<Type> type;
755
756 /* Optional - can be a null pointer if there is no default expression */
757 std::unique_ptr<Expr> default_expression;
758
759 Location locus;
760};
761
762// Item used in trait declarations - abstract base class
763class TraitItem : public Node
764{
765public:
766 enum TraitItemKind
767 {
768 FUNC,
769 CONST,
770 TYPE
771 };
772
773 BaseKind get_hir_kind () override final { return TRAIT_ITEM; }
774
775protected:
776 // Constructor
777 TraitItem (Analysis::NodeMapping mappings) : mappings (mappings) {}
778
779 // Clone function implementation as pure virtual method
780 virtual TraitItem *clone_trait_item_impl () const = 0;
781
782 Analysis::NodeMapping mappings;
783
784public:
785 virtual ~TraitItem () {}
786
787 std::unique_ptr<TraitItem> clone_trait_item () const
788 {
789 return std::unique_ptr<TraitItem> (clone_trait_item_impl ());
790 }
791
792 virtual std::string as_string () const = 0;
793
794 virtual void accept_vis (HIRTraitItemVisitor &vis) = 0;
795 virtual void accept_vis (HIRFullVisitor &vis) = 0;
796
797 virtual const std::string trait_identifier () const = 0;
798
799 const Analysis::NodeMapping get_mappings () const { return mappings; }
800
801 virtual TraitItemKind get_item_kind () const = 0;
802
803 virtual AST::AttrVec &get_outer_attrs () = 0;
804 virtual const AST::AttrVec &get_outer_attrs () const = 0;
805};
806
807class ImplItem : public Node
808{
809public:
810 enum ImplItemType
811 {
812 FUNCTION,
813 TYPE_ALIAS,
814 CONSTANT
815 };
816
817 virtual ~ImplItem () {}
818
819 BaseKind get_hir_kind () override final { return IMPL; }
820
821 // Unique pointer custom clone function
822 std::unique_ptr<ImplItem> clone_inherent_impl_item () const
823 {
824 return std::unique_ptr<ImplItem> (clone_inherent_impl_item_impl ());
825 }
826
827 virtual std::string as_string () const = 0;
828
829 virtual void accept_vis (HIRImplVisitor &vis) = 0;
830 virtual void accept_vis (HIRFullVisitor &vis) = 0;
831 virtual void accept_vis (HIRStmtVisitor &vis) = 0;
832
833 virtual Analysis::NodeMapping get_impl_mappings () const = 0;
834
835 virtual Location get_locus () const = 0;
836
837 virtual ImplItemType get_impl_item_type () const = 0;
838
839protected:
840 // Clone function implementation as pure virtual method
841 virtual ImplItem *clone_inherent_impl_item_impl () const = 0;
842};
843
844// A crate HIR object - holds all the data for a single compilation unit
845struct Crate
846{
847 AST::AttrVec inner_attrs;
848 // dodgy spacing required here
849 /* TODO: is it better to have a vector of items here or a module (implicit
850 * top-level one)? */
851 std::vector<std::unique_ptr<Item> > items;
852
853 Analysis::NodeMapping mappings;
854
855public:
856 // Constructor
857 Crate (std::vector<std::unique_ptr<Item> > items, AST::AttrVec inner_attrs,
858 Analysis::NodeMapping mappings)
859 : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
860 mappings (mappings)
861 {}
862
863 // Copy constructor with vector clone
864 Crate (Crate const &other)
865 : inner_attrs (other.inner_attrs), mappings (other.mappings)
866 {
867 items.reserve (other.items.size ());
868 for (const auto &e : other.items)
869 items.push_back (e->clone_item ());
870 }
871
872 ~Crate () = default;
873
874 // Overloaded assignment operator with vector clone
875 Crate &operator= (Crate const &other)
876 {
877 inner_attrs = other.inner_attrs;
878 mappings = other.mappings;
879
880 items.reserve (other.items.size ());
881 for (const auto &e : other.items)
882 items.push_back (e->clone_item ());
883
884 return *this;
885 }
886
887 // Move constructors
888 Crate (Crate &&other) = default;
889 Crate &operator= (Crate &&other) = default;
890
891 // Get crate representation as string (e.g. for debugging).
892 std::string as_string () const;
893
894 const Analysis::NodeMapping &get_mappings () const { return mappings; }
895};
896
897// Base path expression HIR node - abstract
898class PathExpr : public ExprWithoutBlock
899{
900protected:
901 PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs)
902 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs))
903 {}
904
905public:
906 /* Replaces the outer attributes of this path expression with the given outer
907 * attributes. */
908 void replace_outer_attrs (AST::AttrVec outer_attrs)
909 {
910 set_outer_attrs (std::move (outer_attrs));
911 }
912
913 ExprType get_expression_type () const final override
914 {
915 return ExprType::Path;
916 }
917};
918} // namespace HIR
919} // namespace Rust
920
921#endif