]>
Commit | Line | Data |
---|---|---|
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 | ||
29 | namespace Rust { | |
30 | typedef std::string Identifier; | |
31 | typedef int TupleIndex; | |
32 | ||
33 | namespace HIR { | |
34 | // foward decl: ast visitor | |
35 | class HIRFullVisitor; | |
36 | class HIRStmtVisitor; | |
37 | class HIRTraitItemVisitor; | |
38 | class HIRExternalItemVisitor; | |
39 | class HIRVisItemVisitor; | |
40 | class HIRExpressionVisitor; | |
41 | class HIRPatternVisitor; | |
42 | class HIRImplVisitor; | |
43 | class HIRTypeVisitor; | |
44 | ||
45 | // forward decl for use in token tree method | |
46 | class Token; | |
47 | ||
48 | class Node | |
49 | { | |
50 | public: | |
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. | |
84 | struct Literal | |
85 | { | |
86 | public: | |
87 | enum LitType | |
88 | { | |
89 | CHAR, | |
90 | STRING, | |
91 | BYTE, | |
92 | BYTE_STRING, | |
93 | INT, | |
94 | FLOAT, | |
95 | BOOL | |
96 | }; | |
97 | ||
98 | private: | |
99 | std::string value_as_string; | |
100 | LitType type; | |
101 | PrimitiveCoreType type_hint; | |
102 | ||
103 | public: | |
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. */ | |
135 | class Stmt : public Node | |
136 | { | |
137 | public: | |
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 | ||
161 | protected: | |
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) | |
171 | class Item : public Stmt | |
172 | { | |
173 | AST::AttrVec outer_attrs; | |
174 | ||
175 | // TODO: should outer attrs be defined here or in each derived class? | |
176 | ||
177 | public: | |
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 | ||
219 | protected: | |
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 | |
236 | class ExprWithoutBlock; | |
237 | ||
238 | // Base expression HIR node - abstract | |
239 | class Expr : public Node | |
240 | { | |
241 | AST::AttrVec outer_attrs; | |
242 | Analysis::NodeMapping mappings; | |
243 | ||
244 | public: | |
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 | ||
313 | protected: | |
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 | |
329 | class ExprWithoutBlock : public Expr | |
330 | { | |
331 | protected: | |
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 | ||
349 | public: | |
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 | |
370 | class Pattern : public Node | |
371 | { | |
372 | public: | |
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 | ||
411 | protected: | |
412 | // Clone pattern implementation as pure virtual method | |
413 | virtual Pattern *clone_pattern_impl () const = 0; | |
414 | }; | |
415 | ||
416 | // forward decl for Type | |
417 | class TraitBound; | |
418 | ||
419 | // Base class for types as represented in HIR - abstract | |
420 | class Type : public Node | |
421 | { | |
422 | public: | |
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 | ||
451 | protected: | |
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 | |
464 | class TypeNoBounds : public Type | |
465 | { | |
466 | public: | |
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 | ||
473 | protected: | |
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 */ | |
492 | class TypeParamBound | |
493 | { | |
494 | public: | |
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 | ||
519 | protected: | |
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) | |
525 | class Lifetime : public TypeParamBound | |
526 | { | |
527 | private: | |
528 | AST::Lifetime::LifetimeType lifetime_type; | |
529 | std::string lifetime_name; | |
530 | Location locus; | |
531 | Analysis::NodeMapping mappings; | |
532 | ||
533 | public: | |
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 | ||
574 | protected: | |
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 */ | |
585 | class GenericParam | |
586 | { | |
587 | public: | |
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 | ||
613 | protected: | |
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) | |
628 | class 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 | ||
642 | public: | |
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 | ||
697 | protected: | |
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 | ||
706 | class ConstGenericParam : public GenericParam | |
707 | { | |
708 | public: | |
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 | ||
744 | protected: | |
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 | ||
752 | private: | |
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 | |
763 | class TraitItem : public Node | |
764 | { | |
765 | public: | |
766 | enum TraitItemKind | |
767 | { | |
768 | FUNC, | |
769 | CONST, | |
770 | TYPE | |
771 | }; | |
772 | ||
773 | BaseKind get_hir_kind () override final { return TRAIT_ITEM; } | |
774 | ||
775 | protected: | |
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 | ||
784 | public: | |
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 | ||
807 | class ImplItem : public Node | |
808 | { | |
809 | public: | |
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 | ||
839 | protected: | |
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 | |
845 | struct 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 | ||
855 | public: | |
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 | |
898 | class PathExpr : public ExprWithoutBlock | |
899 | { | |
900 | protected: | |
901 | PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs) | |
902 | : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)) | |
903 | {} | |
904 | ||
905 | public: | |
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 |