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