Line data Source code
1 : // Copyright (C) 2020-2026 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_AST_BASE_H
20 : #define RUST_AST_BASE_H
21 : // Base for AST used in gccrs, basically required by all specific ast things
22 :
23 : #include "rust-system.h"
24 : #include "rust-hir-map.h"
25 : #include "rust-token.h"
26 : #include "rust-location.h"
27 : #include "rust-diagnostics.h"
28 : #include "rust-keyword-values.h"
29 : #include "rust-cloneable.h"
30 :
31 : namespace Rust {
32 : // TODO: remove typedefs and make actual types for these
33 : typedef int TupleIndex;
34 : struct Session;
35 : struct MacroExpander;
36 :
37 3905840 : class Identifier
38 : {
39 : public:
40 : // Create dummy identifier
41 1036 : Identifier () : ident (""), loc (UNDEF_LOCATION) {}
42 : // Create identifier with dummy location
43 310189 : Identifier (std::string ident, location_t loc = UNDEF_LOCATION)
44 619276 : : ident (ident), loc (loc)
45 : {}
46 : // Create identifier from token
47 43932 : Identifier (const_TokenPtr token)
48 43932 : : ident (token->get_str ()), loc (token->get_locus ())
49 43932 : {}
50 :
51 4432361 : Identifier (const Identifier &) = default;
52 1127199 : Identifier (Identifier &&) = default;
53 0 : Identifier &operator= (const Identifier &) = default;
54 3395 : Identifier &operator= (Identifier &&) = default;
55 :
56 4511 : location_t get_locus () const { return loc; }
57 2056130 : const std::string &as_string () const { return ident; }
58 :
59 200402 : bool empty () const { return ident.empty (); }
60 :
61 : bool operator== (const Identifier &other) const
62 : {
63 : return ident == other.ident;
64 : }
65 :
66 1 : operator const std::string & () const { return ident; }
67 :
68 : private:
69 : std::string ident;
70 : location_t loc;
71 : };
72 :
73 : std::ostream &operator<< (std::ostream &os, Identifier const &i);
74 :
75 : namespace AST {
76 : // foward decl: ast visitor
77 : class ASTVisitor;
78 : using AttrVec = std::vector<Attribute>;
79 :
80 419666 : class Visitable
81 : {
82 : public:
83 365796 : virtual ~Visitable () = default;
84 : virtual void accept_vis (ASTVisitor &vis) = 0;
85 : };
86 :
87 : /**
88 : * Base function for reconstructing and asserting that the new NodeId is
89 : * different from the old NodeId. It then wraps the given pointer into a unique
90 : * pointer and returns it.
91 : */
92 : template <typename T>
93 : std::unique_ptr<T>
94 95 : reconstruct_base (const T *instance)
95 : {
96 95 : auto *reconstructed = instance->reconstruct_impl ();
97 :
98 95 : rust_assert (reconstructed->get_node_id () != instance->get_node_id ());
99 :
100 95 : return std::unique_ptr<T> (reconstructed);
101 : }
102 :
103 : /**
104 : * Reconstruct multiple items in a vector
105 : */
106 : template <typename T>
107 : std::vector<std::unique_ptr<T>>
108 93 : reconstruct_vec (const std::vector<std::unique_ptr<T>> &to_reconstruct)
109 : {
110 93 : std::vector<std::unique_ptr<T>> reconstructed;
111 93 : reconstructed.reserve (to_reconstruct.size ());
112 :
113 186 : for (const auto &elt : to_reconstruct)
114 93 : reconstructed.emplace_back (std::unique_ptr<T> (elt->reconstruct_impl ()));
115 :
116 93 : return reconstructed;
117 : }
118 :
119 : // Delimiter types - used in macros and whatever.
120 : enum DelimType
121 : {
122 : PARENS,
123 : SQUARE,
124 : CURLY
125 : };
126 :
127 : // forward decl for use in token tree method
128 : class Token;
129 :
130 : // A tree of tokens (or a single token) - abstract base class
131 393545 : class TokenTree : public Visitable
132 : {
133 : public:
134 50484 : virtual ~TokenTree () {}
135 :
136 : // Unique pointer custom clone function
137 569508 : std::unique_ptr<TokenTree> clone_token_tree () const
138 : {
139 569508 : return std::unique_ptr<TokenTree> (clone_token_tree_impl ());
140 : }
141 :
142 : virtual std::string as_string () const = 0;
143 :
144 : /* Converts token tree to a flat token stream. Tokens must be pointer to
145 : * avoid mutual dependency with Token. */
146 : virtual std::vector<std::unique_ptr<Token>> to_token_stream () const = 0;
147 :
148 : protected:
149 : // pure virtual clone implementation
150 : virtual TokenTree *clone_token_tree_impl () const = 0;
151 : };
152 :
153 : // Abstract base class for a macro match
154 139009 : class MacroMatch : public Visitable
155 : {
156 : public:
157 : enum MacroMatchType
158 : {
159 : Fragment,
160 : Repetition,
161 : Matcher,
162 : Tok
163 : };
164 :
165 1230 : virtual ~MacroMatch () {}
166 :
167 : virtual std::string as_string () const = 0;
168 : virtual location_t get_match_locus () const = 0;
169 :
170 : // Unique pointer custom clone function
171 4535 : std::unique_ptr<MacroMatch> clone_macro_match () const
172 : {
173 4535 : return std::unique_ptr<MacroMatch> (clone_macro_match_impl ());
174 : }
175 :
176 : virtual MacroMatchType get_macro_match_type () const = 0;
177 :
178 : protected:
179 : // pure virtual clone implementation
180 : virtual MacroMatch *clone_macro_match_impl () const = 0;
181 : };
182 :
183 : // A token is a kind of token tree (except delimiter tokens)
184 : class Token : public TokenTree, public MacroMatch
185 : {
186 : // A token is a kind of token tree (except delimiter tokens)
187 : // A token is a kind of MacroMatch (except $ and delimiter tokens)
188 :
189 : const_TokenPtr tok_ref;
190 :
191 : /* new idea: wrapper around const_TokenPtr used for heterogeneuous storage
192 : * in token trees. rather than convert back and forth when parsing macros,
193 : * just wrap it. */
194 :
195 : public:
196 : // Unique pointer custom clone function
197 910521 : std::unique_ptr<Token> clone_token () const
198 : {
199 910521 : return std::unique_ptr<Token> (clone_token_impl ());
200 : }
201 :
202 : // Constructor from lexer const_TokenPtr
203 237856 : Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
204 :
205 42799 : bool is_string_lit () const
206 : {
207 42799 : switch (get_id ())
208 : {
209 : case STRING_LITERAL:
210 : case BYTE_STRING_LITERAL:
211 : case RAW_STRING_LITERAL:
212 : case C_STRING_LITERAL:
213 : return true;
214 41983 : default:
215 41983 : return false;
216 : }
217 : }
218 :
219 : std::string as_string () const override;
220 212 : location_t get_match_locus () const override
221 : {
222 212 : return tok_ref->get_locus ();
223 : };
224 :
225 : void accept_vis (ASTVisitor &vis) override;
226 :
227 : // Return copy of itself but in token stream form.
228 : std::vector<std::unique_ptr<Token>> to_token_stream () const override;
229 :
230 275256 : TokenId get_id () const { return tok_ref->get_id (); }
231 17 : bool should_have_str () const { return tok_ref->should_have_str (); }
232 25187 : const std::string &get_str () const { return tok_ref->get_str (); }
233 :
234 884 : location_t get_locus () const { return tok_ref->get_locus (); }
235 :
236 2 : PrimitiveCoreType get_type_hint () const { return tok_ref->get_type_hint (); }
237 :
238 : // Get a new token pointer copy.
239 414004 : const_TokenPtr get_tok_ptr () const { return tok_ref; }
240 :
241 4301 : MacroMatchType get_macro_match_type () const override
242 : {
243 4301 : return MacroMatchType::Tok;
244 : }
245 :
246 : protected:
247 : // No virtual for now as not polymorphic but can be in future
248 1608585 : /*virtual*/ Token *clone_token_impl () const { return new Token (*this); }
249 :
250 : /* Use covariance to implement clone function as returning this object
251 : * rather than base */
252 541344 : Token *clone_token_tree_impl () const final override
253 : {
254 541344 : return clone_token_impl ();
255 : }
256 :
257 : /* Use covariance to implement clone function as returning this object
258 : * rather than base */
259 0 : Token *clone_macro_match_impl () const final override
260 : {
261 0 : return clone_token_impl ();
262 : }
263 : };
264 :
265 : // A literal - value with a type. Used in LiteralExpr and LiteralPattern.
266 24709 : struct Literal
267 : {
268 : public:
269 : enum LitType
270 : {
271 : CHAR,
272 : STRING,
273 : BYTE,
274 : BYTE_STRING,
275 : RAW_STRING,
276 : C_STRING,
277 : INT,
278 : FLOAT,
279 : BOOL,
280 : ERROR
281 : };
282 :
283 : private:
284 : /* TODO: maybe make subclasses of each type of literal with their typed
285 : * values (or generics) */
286 : std::string value_as_string;
287 : LitType type;
288 : PrimitiveCoreType type_hint;
289 :
290 : public:
291 36287 : std::string as_string () const { return value_as_string; }
292 :
293 32174 : LitType get_lit_type () const { return type; }
294 :
295 22652 : PrimitiveCoreType get_type_hint () const { return type_hint; }
296 :
297 40483 : Literal (std::string value_as_string, LitType type,
298 : PrimitiveCoreType type_hint)
299 40483 : : value_as_string (std::move (value_as_string)), type (type),
300 40483 : type_hint (type_hint)
301 : {}
302 :
303 0 : static Literal create_error ()
304 : {
305 0 : return Literal ("", ERROR, PrimitiveCoreType::CORETYPE_UNKNOWN);
306 : }
307 :
308 : // Returns whether literal is in an invalid state.
309 621893 : bool is_error () const { return type == ERROR; }
310 : };
311 :
312 : /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
313 : * to be defined */
314 : class AttrInputLiteral;
315 :
316 : /* TODO: move applicable stuff into here or just don't include it because
317 : * nothing uses it A segment of a path (maybe) */
318 99008 : class PathSegment
319 : {
320 : public:
321 24957 : virtual ~PathSegment () {}
322 :
323 : virtual std::string as_string () const = 0;
324 :
325 : // TODO: add visitor here?
326 : };
327 :
328 : // A segment of a simple path without generic or type arguments
329 96328 : class SimplePathSegment : public PathSegment
330 : {
331 : std::string segment_name;
332 : location_t locus;
333 : NodeId node_id;
334 :
335 : // only allow identifiers, "super", "self", "crate", or "$crate"
336 : public:
337 : // TODO: put checks in constructor to enforce this rule?
338 35916 : SimplePathSegment (std::string segment_name, location_t locus)
339 71832 : : segment_name (std::move (segment_name)), locus (locus),
340 35916 : node_id (Analysis::Mappings::get ().get_next_node_id ())
341 35916 : {}
342 :
343 : /* Returns whether simple path segment is in an invalid state (currently, if
344 : * empty). */
345 205618 : bool is_error () const { return segment_name.empty (); }
346 :
347 : // Creates an error SimplePathSegment
348 : static SimplePathSegment create_error ()
349 : {
350 : return SimplePathSegment (std::string (""), UNDEF_LOCATION);
351 : }
352 :
353 : std::string as_string () const override;
354 :
355 38455 : location_t get_locus () const { return locus; }
356 14416 : NodeId get_node_id () const { return node_id; }
357 116498 : const std::string &get_segment_name () const { return segment_name; }
358 2275 : bool is_super_path_seg () const
359 : {
360 2275 : return as_string ().compare (Values::Keywords::SUPER) == 0;
361 : }
362 2328 : bool is_crate_path_seg () const
363 : {
364 2328 : return as_string ().compare (Values::Keywords::CRATE) == 0;
365 : }
366 7859 : bool is_lower_self_seg () const
367 : {
368 7859 : return as_string ().compare (Values::Keywords::SELF) == 0;
369 : }
370 2263 : bool is_big_self () const
371 : {
372 2263 : return as_string ().compare (Values::Keywords::SELF_ALIAS) == 0;
373 : }
374 : };
375 :
376 : // A simple path without generic or type arguments
377 437694 : class SimplePath
378 : {
379 : bool opening_scope_resolution;
380 : std::vector<SimplePathSegment> segments;
381 : location_t locus;
382 : NodeId node_id;
383 :
384 : public:
385 : // Constructor
386 103921 : explicit SimplePath (std::vector<SimplePathSegment> path_segments,
387 : bool has_opening_scope_resolution = false,
388 : location_t locus = UNDEF_LOCATION)
389 103921 : : opening_scope_resolution (has_opening_scope_resolution),
390 103921 : segments (std::move (path_segments)), locus (locus),
391 103921 : node_id (Analysis::Mappings::get ().get_next_node_id ())
392 103921 : {}
393 :
394 102 : explicit SimplePath (Identifier ident)
395 102 : : opening_scope_resolution (false),
396 306 : segments ({SimplePathSegment (ident.as_string (), ident.get_locus ())}),
397 102 : locus (ident.get_locus ()),
398 102 : node_id (Analysis::Mappings::get ().get_next_node_id ())
399 102 : {}
400 :
401 : // Creates an empty SimplePath.
402 69157 : static SimplePath create_empty ()
403 : {
404 69157 : return SimplePath (std::vector<SimplePathSegment> ());
405 : }
406 :
407 : // Returns whether the SimplePath is empty, i.e. has path segments.
408 13489 : bool is_empty () const { return segments.empty (); }
409 :
410 : const std::string as_string () const;
411 :
412 6265 : bool has_opening_scope_resolution () const
413 : {
414 6265 : return opening_scope_resolution;
415 : }
416 :
417 4211 : location_t get_locus () const { return locus; }
418 129 : NodeId get_node_id () const { return node_id; }
419 :
420 : // does this need visitor if not polymorphic? probably not
421 :
422 : // path-to-string comparison operator
423 456363 : bool operator== (const std::string &rhs) const
424 : {
425 456363 : return !opening_scope_resolution && segments.size () == 1
426 912726 : && segments[0].as_string () == rhs;
427 : }
428 :
429 : /* Creates a single-segment SimplePath from a string. This will not check to
430 : * ensure that this is a valid identifier in path, so be careful. Also, this
431 : * will have no location data.
432 : * TODO have checks? */
433 358 : static SimplePath from_str (std::string str, location_t locus)
434 : {
435 358 : std::vector<AST::SimplePathSegment> single_segments
436 716 : = {AST::SimplePathSegment (std::move (str), locus)};
437 358 : return SimplePath (std::move (single_segments), false, locus);
438 358 : }
439 :
440 30842 : const std::vector<SimplePathSegment> &get_segments () const
441 : {
442 32027 : return segments;
443 : }
444 :
445 702539 : std::vector<SimplePathSegment> &get_segments () { return segments; }
446 :
447 13445 : const SimplePathSegment &get_final_segment () const
448 : {
449 13445 : return segments.back ();
450 : }
451 : };
452 :
453 : // path-to-string inverse comparison operator
454 : inline bool
455 12481 : operator!= (const SimplePath &lhs, const std::string &rhs)
456 : {
457 12481 : return !(lhs == rhs);
458 : }
459 :
460 : // forward decl for Attribute
461 : class AttrInput;
462 :
463 : // Visibility of item - if the item has it, then it is some form of public
464 279671 : struct Visibility
465 : {
466 : public:
467 : enum VisType
468 : {
469 : PRIV,
470 : PUB,
471 : PUB_CRATE,
472 : PUB_SELF,
473 : PUB_SUPER,
474 : PUB_IN_PATH
475 : };
476 :
477 : private:
478 : VisType vis_type;
479 : // Only assigned if vis_type is IN_PATH
480 : SimplePath in_path;
481 : location_t locus;
482 :
483 62823 : Visibility (VisType vis_type, SimplePath in_path, location_t locus)
484 14220 : : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
485 : {}
486 :
487 : public:
488 41744 : VisType get_vis_type () const { return vis_type; }
489 :
490 : // Returns whether a visibility has a path
491 804846 : bool has_path () const { return vis_type >= PUB_CRATE; }
492 :
493 : // Returns whether visibility is public or not.
494 1255 : bool is_public () const { return vis_type != PRIV; }
495 :
496 2875 : location_t get_locus () const { return locus; }
497 :
498 : // Unique pointer custom clone function
499 : /*std::unique_ptr<Visibility> clone_visibility() const {
500 : return std::unique_ptr<Visibility>(clone_visibility_impl());
501 : }*/
502 :
503 : /* TODO: think of a way to only allow valid Visibility states - polymorphism
504 : * is one idea but may be too resource-intensive. */
505 :
506 : // Creates a public visibility with no further features/arguments.
507 : // empty?
508 8866 : static Visibility create_public (location_t pub_vis_location)
509 : {
510 8866 : return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
511 : }
512 :
513 : // Creates a public visibility with crate-relative paths
514 53 : static Visibility create_crate (location_t crate_tok_location,
515 : location_t crate_vis_location)
516 : {
517 53 : return Visibility (PUB_CRATE,
518 53 : SimplePath::from_str (Values::Keywords::CRATE,
519 : crate_tok_location),
520 53 : crate_vis_location);
521 : }
522 :
523 : // Creates a public visibility with self-relative paths
524 0 : static Visibility create_self (location_t self_tok_location,
525 : location_t self_vis_location)
526 : {
527 0 : return Visibility (PUB_SELF,
528 0 : SimplePath::from_str (Values::Keywords::SELF,
529 : self_tok_location),
530 0 : self_vis_location);
531 : }
532 :
533 : // Creates a public visibility with parent module-relative paths
534 1 : static Visibility create_super (location_t super_tok_location,
535 : location_t super_vis_location)
536 : {
537 1 : return Visibility (PUB_SUPER,
538 1 : SimplePath::from_str (Values::Keywords::SUPER,
539 : super_tok_location),
540 1 : super_vis_location);
541 : }
542 :
543 : // Creates a private visibility
544 53891 : static Visibility create_private ()
545 : {
546 53891 : return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
547 : }
548 :
549 : // Creates a public visibility with a given path or whatever.
550 12 : static Visibility create_in_path (SimplePath in_path,
551 : location_t in_path_vis_location)
552 : {
553 12 : return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
554 : }
555 :
556 : std::string as_string () const;
557 61 : const SimplePath &get_path () const { return in_path; }
558 1334 : SimplePath &get_path () { return in_path; }
559 :
560 : protected:
561 : // Clone function implementation - not currently virtual but may be if
562 : // polymorphism used
563 : /*virtual*/ Visibility *clone_visibility_impl () const
564 : {
565 : return new Visibility (*this);
566 : }
567 : };
568 :
569 : // aka Attr
570 : // Attribute AST representation
571 : class Attribute : public Visitable
572 : {
573 : SimplePath path;
574 :
575 : // bool has_attr_input;
576 : std::unique_ptr<AttrInput> attr_input;
577 :
578 : location_t locus;
579 :
580 : bool inner_attribute;
581 :
582 : NodeId node_id;
583 :
584 : // TODO: maybe a variable storing whether attr input is parsed or not
585 :
586 : public:
587 : // Returns whether Attribute has AttrInput
588 735260 : bool has_attr_input () const { return attr_input != nullptr; }
589 :
590 : // Constructor has pointer AttrInput for polymorphism reasons
591 35552 : Attribute (SimplePath path, std::unique_ptr<AttrInput> input,
592 : location_t locus = UNDEF_LOCATION, bool inner_attribute = false)
593 35552 : : path (std::move (path)), attr_input (std::move (input)), locus (locus),
594 35552 : inner_attribute (inner_attribute),
595 35552 : node_id (Analysis::Mappings::get ().get_next_node_id ())
596 35552 : {}
597 :
598 : bool is_derive () const;
599 :
600 : std::vector<std::reference_wrapper<AST::SimplePath>> get_traits_to_derive ();
601 :
602 : // default destructor
603 190741 : ~Attribute () = default;
604 :
605 : // no point in being defined inline as requires virtual call anyway
606 : Attribute (const Attribute &other);
607 :
608 : // no point in being defined inline as requires virtual call anyway
609 : Attribute &operator= (const Attribute &other);
610 :
611 : // default move semantics
612 96703 : Attribute (Attribute &&other) = default;
613 7 : Attribute &operator= (Attribute &&other) = default;
614 :
615 : // Unique pointer custom clone function
616 : std::unique_ptr<Attribute> clone_attribute () const
617 : {
618 : return std::unique_ptr<Attribute> (clone_attribute_impl ());
619 : }
620 :
621 : // Creates an empty attribute (which is invalid)
622 5784 : static Attribute create_empty ()
623 : {
624 5784 : return Attribute (SimplePath::create_empty (), nullptr);
625 : }
626 :
627 : // Returns whether the attribute is considered an "empty" attribute.
628 2669 : bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
629 :
630 : // Returns whether the attribute has no input
631 8085 : bool empty_input () const { return !attr_input; }
632 :
633 11914 : location_t get_locus () const { return locus; }
634 :
635 532006 : AttrInput &get_attr_input () const { return *attr_input; }
636 :
637 2 : void set_attr_input (std::unique_ptr<AST::AttrInput> input)
638 : {
639 2 : attr_input = std::move (input);
640 : }
641 :
642 : /* e.g.:
643 : #![crate_type = "lib"]
644 : #[test]
645 : #[cfg(target_os = "linux")]
646 : #[allow(non_camel_case_types)]
647 : #![allow(unused_variables)]
648 : */
649 :
650 : // Full built-in attribute list:
651 : /* cfg
652 : * cfg_attr
653 : * test
654 : * ignore
655 : * should_panic
656 : * derive
657 : * macro_export
658 : * macro_use
659 : * proc_macro
660 : * proc_macro_derive
661 : * proc_macro_attribute
662 : * allow
663 : * warn
664 : * deny
665 : * forbid
666 : * deprecated
667 : * must_use
668 : * link
669 : * link_name
670 : * no_link
671 : * repr
672 : * crate_type
673 : * no_main
674 : * export_name
675 : * link_section
676 : * no_mangle
677 : * used
678 : * crate_name
679 : * inline
680 : * cold
681 : * no_builtins
682 : * target_feature
683 : * doc
684 : * no_std
685 : * no_implicit_prelude
686 : * path
687 : * recursion_limit
688 : * type_length_limit
689 : * panic_handler
690 : * global_allocator
691 : * windows_subsystem
692 : * feature */
693 :
694 : std::string as_string () const;
695 :
696 2261 : bool is_inner_attribute () const { return inner_attribute; }
697 :
698 : void accept_vis (ASTVisitor &vis) override;
699 :
700 255961 : const SimplePath &get_path () const { return path; }
701 873800 : SimplePath &get_path () { return path; }
702 :
703 : NodeId get_node_id () { return node_id; }
704 :
705 : // Call to parse attribute body to meta item syntax.
706 : void parse_attr_to_meta_item ();
707 :
708 : /* Determines whether cfg predicate is true and item with attribute should
709 : * not be stripped. Attribute body must already be parsed to meta item. */
710 : bool check_cfg_predicate (const Session &session) const;
711 :
712 : // Returns whether body has been parsed to meta item form or not.
713 : bool is_parsed_to_meta_item () const;
714 :
715 : /* Returns any attributes generated from cfg_attr attributes. Attribute body
716 : * must already be parsed to meta item. */
717 : std::vector<Attribute> separate_cfg_attrs () const;
718 :
719 : protected:
720 : // not virtual as currently no subclasses of Attribute, but could be in
721 : // future
722 : /*virtual*/ Attribute *clone_attribute_impl () const
723 : {
724 : return new Attribute (*this);
725 : }
726 : };
727 :
728 : // Attribute body - abstract base class
729 86740 : class AttrInput : public Visitable
730 : {
731 : public:
732 : enum AttrInputType
733 : {
734 : EXPR,
735 : LITERAL,
736 : META_ITEM,
737 : TOKEN_TREE,
738 : };
739 :
740 50484 : virtual ~AttrInput () {}
741 :
742 : // Unique pointer custom clone function
743 109973 : std::unique_ptr<AttrInput> clone_attr_input () const
744 : {
745 109973 : return std::unique_ptr<AttrInput> (clone_attr_input_impl ());
746 : }
747 :
748 : virtual std::string as_string () const = 0;
749 :
750 : virtual bool check_cfg_predicate (const Session &session) const = 0;
751 :
752 : // Parse attribute input to meta item, if possible
753 0 : virtual AttrInput *parse_to_meta_item () const { return nullptr; }
754 :
755 0 : virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; }
756 :
757 : // Returns whether attr input has been parsed to meta item syntax.
758 : virtual bool is_meta_item () const = 0;
759 :
760 : virtual AttrInputType get_attr_input_type () const = 0;
761 :
762 : protected:
763 : // pure virtual clone implementation
764 : virtual AttrInput *clone_attr_input_impl () const = 0;
765 : };
766 :
767 : // Forward decl - defined in rust-macro.h
768 : class MetaNameValueStr;
769 :
770 : // abstract base meta item inner class
771 28 : class MetaItemInner : public Visitable
772 : {
773 : protected:
774 : // pure virtual as MetaItemInner
775 : virtual MetaItemInner *clone_meta_item_inner_impl () const = 0;
776 :
777 : public:
778 : enum class Kind
779 : {
780 : LitExpr,
781 : MetaItem,
782 : };
783 :
784 : // Unique pointer custom clone function
785 2916 : std::unique_ptr<MetaItemInner> clone_meta_item_inner () const
786 : {
787 2916 : return std::unique_ptr<MetaItemInner> (clone_meta_item_inner_impl ());
788 : }
789 :
790 : virtual Kind get_kind () = 0;
791 :
792 : virtual ~MetaItemInner ();
793 :
794 : virtual location_t get_locus () const = 0;
795 :
796 : virtual std::string as_string () const = 0;
797 :
798 : /* HACK: used to simplify parsing - creates a copy of that type, or returns
799 : * null */
800 : virtual std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const;
801 :
802 : // HACK: used to simplify parsing - same thing
803 0 : virtual SimplePath to_path_item () const
804 : {
805 0 : return SimplePath::create_empty ();
806 : }
807 :
808 0 : virtual Attribute to_attribute () const { return Attribute::create_empty (); }
809 :
810 : virtual bool check_cfg_predicate (const Session &session) const = 0;
811 :
812 99 : virtual bool is_key_value_pair () const { return false; }
813 : };
814 :
815 : // Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
816 : class AttrInputMetaItemContainer : public AttrInput
817 : {
818 : std::vector<std::unique_ptr<MetaItemInner>> items;
819 :
820 : public:
821 10401 : AttrInputMetaItemContainer (std::vector<std::unique_ptr<MetaItemInner>> items)
822 10401 : : items (std::move (items))
823 : {}
824 :
825 : // copy constructor with vector clone
826 2716 : AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other)
827 2716 : {
828 2716 : items.reserve (other.items.size ());
829 5575 : for (const auto &e : other.items)
830 2859 : items.push_back (e->clone_meta_item_inner ());
831 2716 : }
832 :
833 : // copy assignment operator with vector clone
834 : AttrInputMetaItemContainer &
835 : operator= (const AttrInputMetaItemContainer &other)
836 : {
837 : AttrInput::operator= (other);
838 :
839 : items.reserve (other.items.size ());
840 : for (const auto &e : other.items)
841 : items.push_back (e->clone_meta_item_inner ());
842 :
843 : return *this;
844 : }
845 :
846 : // default move constructors
847 : AttrInputMetaItemContainer (AttrInputMetaItemContainer &&other) = default;
848 : AttrInputMetaItemContainer &operator= (AttrInputMetaItemContainer &&other)
849 : = default;
850 :
851 : std::string as_string () const override;
852 :
853 : void accept_vis (ASTVisitor &vis) override;
854 :
855 : bool check_cfg_predicate (const Session &session) const override;
856 :
857 406 : AttrInputType get_attr_input_type () const final override
858 : {
859 406 : return AttrInput::AttrInputType::META_ITEM;
860 : }
861 :
862 : // Clones this object.
863 : std::unique_ptr<AttrInputMetaItemContainer>
864 : clone_attr_input_meta_item_container () const
865 : {
866 : return std::unique_ptr<AttrInputMetaItemContainer> (
867 : clone_attr_input_meta_item_container_impl ());
868 : }
869 :
870 : std::vector<Attribute> separate_cfg_attrs () const override;
871 :
872 6260 : bool is_meta_item () const override { return true; }
873 :
874 : // TODO: this mutable getter seems dodgy
875 14405 : std::vector<std::unique_ptr<MetaItemInner>> &get_items () { return items; }
876 28 : const std::vector<std::unique_ptr<MetaItemInner>> &get_items () const
877 : {
878 7194 : return items;
879 : }
880 :
881 : protected:
882 : // Use covariance to implement clone function as returning this type
883 2715 : AttrInputMetaItemContainer *clone_attr_input_impl () const final override
884 : {
885 2715 : return clone_attr_input_meta_item_container_impl ();
886 : }
887 :
888 2715 : AttrInputMetaItemContainer *clone_attr_input_meta_item_container_impl () const
889 : {
890 2715 : return new AttrInputMetaItemContainer (*this);
891 : }
892 : };
893 :
894 : // A token tree with delimiters
895 49315 : class DelimTokenTree : public TokenTree, public AttrInput
896 : {
897 : DelimType delim_type;
898 : std::vector<std::unique_ptr<TokenTree>> token_trees;
899 : location_t locus;
900 :
901 : protected:
902 63332 : DelimTokenTree *clone_delim_tok_tree_impl () const
903 : {
904 63332 : return new DelimTokenTree (*this);
905 : }
906 :
907 : /* Use covariance to implement clone function as returning a DelimTokenTree
908 : * object */
909 0 : DelimTokenTree *clone_attr_input_impl () const final override
910 : {
911 0 : return clone_delim_tok_tree_impl ();
912 : }
913 :
914 : /* Use covariance to implement clone function as returning a DelimTokenTree
915 : * object */
916 28164 : DelimTokenTree *clone_token_tree_impl () const final override
917 : {
918 28164 : return clone_delim_tok_tree_impl ();
919 : }
920 :
921 : public:
922 23335 : DelimTokenTree (DelimType delim_type,
923 : std::vector<std::unique_ptr<TokenTree>> token_trees
924 : = std::vector<std::unique_ptr<TokenTree>> (),
925 : location_t locus = UNDEF_LOCATION)
926 23335 : : delim_type (delim_type), token_trees (std::move (token_trees)),
927 23335 : locus (locus)
928 : {}
929 :
930 : // Copy constructor with vector clone
931 99012 : DelimTokenTree (DelimTokenTree const &other)
932 99012 : : delim_type (other.delim_type), locus (other.locus)
933 : {
934 99012 : token_trees.clear ();
935 99012 : token_trees.reserve (other.token_trees.size ());
936 668323 : for (const auto &e : other.token_trees)
937 569311 : token_trees.push_back (e->clone_token_tree ());
938 99012 : }
939 :
940 : // overloaded assignment operator with vector clone
941 46 : DelimTokenTree &operator= (DelimTokenTree const &other)
942 : {
943 46 : delim_type = other.delim_type;
944 46 : locus = other.locus;
945 :
946 46 : token_trees.clear ();
947 46 : token_trees.reserve (other.token_trees.size ());
948 243 : for (const auto &e : other.token_trees)
949 197 : token_trees.push_back (e->clone_token_tree ());
950 :
951 46 : return *this;
952 : }
953 :
954 : // move constructors
955 24632 : DelimTokenTree (DelimTokenTree &&other) = default;
956 : DelimTokenTree &operator= (DelimTokenTree &&other) = default;
957 :
958 13 : static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
959 :
960 : std::string as_string () const override;
961 :
962 : void accept_vis (ASTVisitor &vis) override;
963 :
964 0 : bool check_cfg_predicate (const Session &) const override
965 : {
966 : // this should never be called - should be converted first
967 0 : rust_assert (false);
968 : return false;
969 : }
970 :
971 : AttrInputMetaItemContainer *parse_to_meta_item () const override;
972 :
973 : std::vector<std::unique_ptr<Token>> to_token_stream () const override;
974 :
975 : std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
976 : {
977 : return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
978 : }
979 :
980 1161 : bool is_meta_item () const override { return false; }
981 :
982 15081 : AttrInputType get_attr_input_type () const final override
983 : {
984 15081 : return AttrInput::AttrInputType::TOKEN_TREE;
985 : }
986 :
987 : std::vector<std::unique_ptr<TokenTree>> &get_token_trees ()
988 : {
989 294069 : return token_trees;
990 : }
991 :
992 : const std::vector<std::unique_ptr<TokenTree>> &get_token_trees () const
993 : {
994 0 : return token_trees;
995 : }
996 :
997 7864 : DelimType get_delim_type () const { return delim_type; }
998 4894 : location_t get_locus () const { return locus; }
999 : };
1000 :
1001 : /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
1002 : * to be defined */
1003 : class AttrInputLiteral;
1004 :
1005 : // abstract base meta item class
1006 12325 : class MetaItem : public MetaItemInner
1007 : {
1008 : public:
1009 : enum class ItemKind
1010 : {
1011 : Path,
1012 : Word,
1013 : NameValueStr,
1014 : PathExpr,
1015 : Seq,
1016 : ListPaths,
1017 : ListNameValueStr,
1018 : };
1019 :
1020 608 : MetaItemInner::Kind get_kind () override
1021 : {
1022 608 : return MetaItemInner::Kind::MetaItem;
1023 : }
1024 :
1025 : virtual ItemKind get_item_kind () const = 0;
1026 : };
1027 :
1028 : // Forward decl - defined in rust-expr.h
1029 : class MetaItemLitExpr;
1030 :
1031 : // Forward decl - defined in rust-expr.h
1032 : class MetaItemPathExpr;
1033 :
1034 : // Forward decl - defined in rust-macro.h
1035 : class MetaItemPath;
1036 :
1037 : // Forward decl - defined in rust-macro.h
1038 : class MetaItemSeq;
1039 :
1040 : // Forward decl - defined in rust-macro.h
1041 : class MetaWord;
1042 :
1043 : // Forward decl - defined in rust-macro.h
1044 : class MetaListPaths;
1045 :
1046 : // Forward decl - defined in rust-macro.h
1047 : class MetaListNameValueStr;
1048 :
1049 : /* Base statement abstract class. Note that most "statements" are not allowed
1050 : * in top-level module scope - only a subclass of statements called "items"
1051 : * are. */
1052 1115 : class Stmt : public Visitable
1053 : {
1054 : public:
1055 : enum class Kind
1056 : {
1057 : Empty,
1058 : Item,
1059 : Let,
1060 : Expr,
1061 : MacroInvocation,
1062 : };
1063 :
1064 : // Unique pointer custom clone function
1065 38057 : std::unique_ptr<Stmt> clone_stmt () const
1066 : {
1067 38057 : return std::unique_ptr<Stmt> (clone_stmt_impl ());
1068 : }
1069 :
1070 : virtual ~Stmt () {}
1071 :
1072 : virtual std::string as_string () const = 0;
1073 :
1074 : virtual location_t get_locus () const = 0;
1075 :
1076 : virtual void mark_for_strip () = 0;
1077 : virtual bool is_marked_for_strip () const = 0;
1078 :
1079 : // TODO: put this in a virtual base class?
1080 210337 : virtual NodeId get_node_id () const { return node_id; }
1081 :
1082 : virtual Kind get_stmt_kind () = 0;
1083 :
1084 : // TODO: Can we remove these two?
1085 : virtual bool is_item () const = 0;
1086 4181 : virtual bool is_expr () const { return false; }
1087 :
1088 38 : virtual void add_semicolon () {}
1089 :
1090 : protected:
1091 220709 : Stmt () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1092 :
1093 : // Clone function implementation as pure virtual method
1094 : virtual Stmt *clone_stmt_impl () const = 0;
1095 :
1096 : NodeId node_id;
1097 : };
1098 :
1099 : // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
1100 15712 : class Item : public Stmt
1101 : {
1102 : public:
1103 : enum class Kind
1104 : {
1105 : MacroRulesDefinition,
1106 : MacroInvocation,
1107 : Module,
1108 : ExternCrate,
1109 : UseDeclaration,
1110 : Function,
1111 : TypeAlias,
1112 : Struct,
1113 : EnumItem,
1114 : Enum,
1115 : Union,
1116 : ConstantItem,
1117 : StaticItem,
1118 : Trait,
1119 : Impl,
1120 : ExternBlock,
1121 : };
1122 :
1123 : virtual Kind get_item_kind () const = 0;
1124 :
1125 : // Unique pointer custom clone function
1126 38832 : std::unique_ptr<Item> clone_item () const
1127 : {
1128 38832 : return std::unique_ptr<Item> (clone_item_impl ());
1129 : }
1130 :
1131 : /* Adds crate names to the vector passed by reference, if it can
1132 : * (polymorphism). TODO: remove, unused. */
1133 : virtual void
1134 0 : add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
1135 0 : {}
1136 :
1137 2806 : Stmt::Kind get_stmt_kind () final { return Stmt::Kind::Item; }
1138 :
1139 : // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
1140 : // behavior that we have items that can also be expressions?
1141 0 : bool is_item () const override { return true; }
1142 :
1143 : virtual std::vector<Attribute> &get_outer_attrs () = 0;
1144 : virtual const std::vector<Attribute> &get_outer_attrs () const = 0;
1145 :
1146 60587 : virtual bool has_outer_attrs () const { return !get_outer_attrs ().empty (); }
1147 :
1148 : protected:
1149 : // Clone function implementation as pure virtual method
1150 : virtual Item *clone_item_impl () const = 0;
1151 :
1152 : /* Save having to specify two clone methods in derived classes by making
1153 : * statement clone return item clone. Hopefully won't affect performance too
1154 : * much. */
1155 1348 : Item *clone_stmt_impl () const final override { return clone_item_impl (); }
1156 : };
1157 :
1158 6768 : class GlobContainer
1159 : {
1160 : public:
1161 : enum class Kind
1162 : {
1163 : Crate,
1164 : Module,
1165 : Enum,
1166 : };
1167 :
1168 : virtual Kind get_glob_container_kind () const = 0;
1169 : };
1170 :
1171 : // Item that supports visibility - abstract base class
1172 : class VisItem : public Item
1173 : {
1174 : Visibility visibility;
1175 : std::vector<Attribute> outer_attrs;
1176 :
1177 : protected:
1178 : // Visibility constructor
1179 41160 : VisItem (Visibility visibility,
1180 : std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
1181 41160 : : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
1182 41160 : {}
1183 :
1184 : // Visibility copy constructor
1185 103444 : VisItem (VisItem const &other)
1186 103444 : : visibility (other.visibility), outer_attrs (other.outer_attrs)
1187 103444 : {}
1188 :
1189 : // Overload assignment operator to clone
1190 0 : VisItem &operator= (VisItem const &other)
1191 : {
1192 0 : visibility = other.visibility;
1193 0 : outer_attrs = other.outer_attrs;
1194 :
1195 0 : return *this;
1196 : }
1197 :
1198 : // move constructors
1199 985 : VisItem (VisItem &&other) = default;
1200 : VisItem &operator= (VisItem &&other) = default;
1201 :
1202 : public:
1203 : /* Does the item have some kind of public visibility (non-default
1204 : * visibility)? */
1205 1255 : bool has_visibility () const { return visibility.is_public (); }
1206 :
1207 : std::string as_string () const override;
1208 :
1209 : // TODO: this mutable getter seems really dodgy. Think up better way.
1210 760682 : Visibility &get_visibility () { return visibility; }
1211 : const Visibility &get_visibility () const { return visibility; }
1212 :
1213 1138863 : std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1214 81929 : const std::vector<Attribute> &get_outer_attrs () const override
1215 : {
1216 81929 : return outer_attrs;
1217 : }
1218 :
1219 : virtual Item::Kind get_item_kind () const override = 0;
1220 : };
1221 :
1222 : // forward decl of ExprWithoutBlock
1223 : class ExprWithoutBlock;
1224 :
1225 : // Base expression AST node - abstract
1226 69117 : class Expr : public Visitable
1227 : {
1228 : public:
1229 : enum class Kind
1230 : {
1231 : PathInExpression,
1232 : QualifiedPathInExpression,
1233 : Literal,
1234 : Operator,
1235 : Grouped,
1236 : Array,
1237 : ArrayIndex,
1238 : Tuple,
1239 : TupleIndex,
1240 : Struct,
1241 : Call,
1242 : MethodCall,
1243 : FieldAccess,
1244 : Closure,
1245 : Block,
1246 : ConstExpr,
1247 : ConstBlock,
1248 : Continue,
1249 : Break,
1250 : Range,
1251 : Box,
1252 : Return,
1253 : UnsafeBlock,
1254 : Loop,
1255 : If,
1256 : IfLet,
1257 : Match,
1258 : Await,
1259 : AsyncBlock,
1260 : InlineAsm,
1261 : LlvmInlineAsm,
1262 : Identifier,
1263 : FormatArgs,
1264 : OffsetOf,
1265 : MacroInvocation,
1266 : Borrow,
1267 : Dereference,
1268 : ErrorPropagation,
1269 : Negation,
1270 : ArithmeticOrLogical,
1271 : Comparison,
1272 : LazyBoolean,
1273 : TypeCast,
1274 : Assignment,
1275 : CompoundAssignment,
1276 : Try,
1277 : };
1278 :
1279 : virtual Kind get_expr_kind () const = 0;
1280 :
1281 : // Unique pointer custom clone function
1282 155 : std::unique_ptr<Expr> clone_expr () const
1283 : {
1284 311202 : return std::unique_ptr<Expr> (clone_expr_impl ());
1285 : }
1286 :
1287 : /* TODO: public methods that could be useful:
1288 : * - get_type() - returns type of expression. set_type() may also be useful
1289 : * for some?
1290 : * - evaluate() - evaluates expression if constant? can_evaluate()? */
1291 :
1292 : virtual std::string as_string () const = 0;
1293 :
1294 2049 : virtual ~Expr () {}
1295 :
1296 : virtual location_t get_locus () const = 0;
1297 :
1298 45 : virtual bool is_literal () const { return false; }
1299 :
1300 : // HACK: strictly not needed, but faster than full downcast clone
1301 : virtual bool is_expr_without_block () const = 0;
1302 :
1303 : virtual void mark_for_strip () = 0;
1304 : virtual bool is_marked_for_strip () const = 0;
1305 :
1306 1569556 : virtual NodeId get_node_id () const { return node_id; }
1307 :
1308 0 : virtual void set_node_id (NodeId id) { node_id = id; }
1309 :
1310 : virtual std::vector<Attribute> &get_outer_attrs () = 0;
1311 :
1312 : // TODO: think of less hacky way to implement this kind of thing
1313 : // Sets outer attributes.
1314 : virtual void set_outer_attrs (std::vector<Attribute>) = 0;
1315 :
1316 : protected:
1317 : // Constructor
1318 299857 : Expr () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1319 :
1320 : // Clone function implementation as pure virtual method
1321 : virtual Expr *clone_expr_impl () const = 0;
1322 :
1323 : NodeId node_id;
1324 : };
1325 :
1326 : // AST node for an expression without an accompanying block - abstract
1327 283915 : class ExprWithoutBlock : public Expr
1328 : {
1329 : protected:
1330 : // pure virtual clone implementation
1331 : virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
1332 :
1333 : /* Save having to specify two clone methods in derived classes by making
1334 : * expr clone return exprwithoutblock clone. Hopefully won't affect
1335 : * performance too much. */
1336 292551 : ExprWithoutBlock *clone_expr_impl () const final override
1337 : {
1338 292551 : return clone_expr_without_block_impl ();
1339 : }
1340 :
1341 47122 : bool is_expr_without_block () const final override { return true; };
1342 :
1343 : public:
1344 : // Unique pointer custom clone function
1345 31 : std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
1346 : {
1347 31 : return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
1348 : }
1349 : };
1350 :
1351 : /* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1352 : * Pratt parser */
1353 : /* Alternatively, identifiers could just be represented as single-segment
1354 : * paths
1355 : */
1356 : class IdentifierExpr : public ExprWithoutBlock
1357 : {
1358 : std::vector<Attribute> outer_attrs;
1359 : Identifier ident;
1360 : location_t locus;
1361 :
1362 : public:
1363 25576 : IdentifierExpr (Identifier ident, std::vector<Attribute> outer_attrs,
1364 : location_t locus)
1365 76728 : : outer_attrs (std::move (outer_attrs)), ident (std::move (ident)),
1366 25576 : locus (locus)
1367 25576 : {}
1368 :
1369 12 : std::string as_string () const override { return ident.as_string (); }
1370 :
1371 88881 : location_t get_locus () const override final { return locus; }
1372 :
1373 51219 : Identifier get_ident () const { return ident; }
1374 :
1375 : void accept_vis (ASTVisitor &vis) override;
1376 :
1377 : // Clones this object.
1378 : std::unique_ptr<IdentifierExpr> clone_identifier_expr () const
1379 : {
1380 : return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
1381 : }
1382 :
1383 : // "Error state" if ident is empty, so base stripping on this.
1384 0 : void mark_for_strip () override { ident = {""}; }
1385 169509 : bool is_marked_for_strip () const override { return ident.empty (); }
1386 :
1387 : const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
1388 984623 : std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1389 :
1390 0 : void set_outer_attrs (std::vector<Attribute> new_attrs) override
1391 : {
1392 0 : outer_attrs = std::move (new_attrs);
1393 0 : }
1394 :
1395 24672 : Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
1396 :
1397 : protected:
1398 : // Clone method implementation
1399 58552 : IdentifierExpr *clone_expr_without_block_impl () const final override
1400 : {
1401 58552 : return clone_identifier_expr_impl ();
1402 : }
1403 :
1404 58552 : IdentifierExpr *clone_identifier_expr_impl () const
1405 : {
1406 58552 : return new IdentifierExpr (*this);
1407 : }
1408 : };
1409 :
1410 : // Pattern base AST node
1411 123279 : class Pattern : public Visitable
1412 : {
1413 : public:
1414 : enum class Kind
1415 : {
1416 : Literal,
1417 : Identifier,
1418 : Wildcard,
1419 : Rest,
1420 : Range,
1421 : Reference,
1422 : Struct,
1423 : TupleStruct,
1424 : Tuple,
1425 : Grouped,
1426 : Slice,
1427 : Alt,
1428 : Path,
1429 : MacroInvocation,
1430 : };
1431 :
1432 : // Unique pointer custom clone function
1433 64635 : std::unique_ptr<Pattern> clone_pattern () const
1434 : {
1435 64635 : return std::unique_ptr<Pattern> (clone_pattern_impl ());
1436 : }
1437 :
1438 : virtual Kind get_pattern_kind () = 0;
1439 :
1440 : // possible virtual methods: is_refutable()
1441 :
1442 : virtual ~Pattern () {}
1443 :
1444 : virtual std::string as_string () const = 0;
1445 :
1446 : // as only one kind of pattern can be stripped, have default of nothing
1447 0 : virtual void mark_for_strip () {}
1448 142201 : virtual bool is_marked_for_strip () const { return false; }
1449 :
1450 : virtual location_t get_locus () const = 0;
1451 : virtual NodeId get_node_id () const = 0;
1452 :
1453 : protected:
1454 : // Clone pattern implementation as pure virtual method
1455 : virtual Pattern *clone_pattern_impl () const = 0;
1456 : };
1457 :
1458 : // forward decl for Type
1459 : class TraitBound;
1460 :
1461 : // Base class for types as represented in AST - abstract
1462 228168 : class Type : public Visitable
1463 : {
1464 : public:
1465 : enum Kind
1466 : {
1467 : MacroInvocation,
1468 : TypePath,
1469 : QualifiedPathInType,
1470 : ImplTrait,
1471 : TraitObject,
1472 : Parenthesised,
1473 : ImplTraitTypeOneBound,
1474 : TraitObjectTypeOneBound,
1475 : Tuple,
1476 : Never,
1477 : RawPointer,
1478 : Reference,
1479 : Array,
1480 : Slice,
1481 : Inferred,
1482 : BareFunction,
1483 : };
1484 :
1485 : virtual Kind get_type_kind () const = 0;
1486 :
1487 : // Unique pointer custom clone function
1488 129766 : std::unique_ptr<Type> clone_type () const
1489 : {
1490 129766 : return std::unique_ptr<Type> (clone_type_impl ());
1491 : }
1492 :
1493 : // Similar to `clone_type`, but generates a new instance of the node with a
1494 : // different NodeId
1495 95 : std::unique_ptr<Type> reconstruct () const { return reconstruct_base (this); }
1496 :
1497 : // virtual destructor
1498 71424 : virtual ~Type () {}
1499 :
1500 : virtual std::string as_string () const = 0;
1501 :
1502 : /* HACK: convert to trait bound. Virtual method overriden by classes that
1503 : * enable this. */
1504 4 : virtual TraitBound *to_trait_bound (bool) const { return nullptr; }
1505 : /* as pointer, shouldn't require definition beforehand, only forward
1506 : * declaration. */
1507 :
1508 : // as only two kinds of types can be stripped, have default of nothing
1509 0 : virtual void mark_for_strip () {}
1510 78210 : virtual bool is_marked_for_strip () const { return false; }
1511 :
1512 : virtual location_t get_locus () const = 0;
1513 :
1514 : // TODO: put this in a virtual base class?
1515 48996 : virtual NodeId get_node_id () const { return node_id; }
1516 : virtual Type *reconstruct_impl () const = 0;
1517 :
1518 : protected:
1519 120631 : Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1520 24 : Type (NodeId node_id) : node_id (node_id) {}
1521 :
1522 : // Clone and reconstruct function implementations as pure virtual methods
1523 : virtual Type *clone_type_impl () const = 0;
1524 :
1525 : NodeId node_id;
1526 : };
1527 :
1528 : // A type without parentheses? - abstract
1529 290179 : class TypeNoBounds : public Type
1530 : {
1531 : public:
1532 : // Unique pointer custom clone function
1533 35313 : std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
1534 : {
1535 35313 : return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
1536 : }
1537 :
1538 0 : std::unique_ptr<TypeNoBounds> reconstruct () const
1539 : {
1540 0 : return reconstruct_base (this);
1541 : }
1542 :
1543 : virtual TypeNoBounds *reconstruct_impl () const override = 0;
1544 :
1545 : protected:
1546 : // Clone function implementation as pure virtual method
1547 : virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
1548 :
1549 : /* Save having to specify two clone methods in derived classes by making
1550 : * type clone return typenobounds clone. Hopefully won't affect performance
1551 : * too much. */
1552 129742 : TypeNoBounds *clone_type_impl () const final override
1553 : {
1554 129742 : return clone_type_no_bounds_impl ();
1555 : }
1556 :
1557 120617 : TypeNoBounds () : Type () {}
1558 : };
1559 :
1560 : /* Abstract base class representing a type param bound - Lifetime and
1561 : * TraitBound extends it */
1562 : class TypeParamBound : public Visitable
1563 : {
1564 : public:
1565 : enum TypeParamBoundType
1566 : {
1567 : TRAIT,
1568 : LIFETIME
1569 : };
1570 :
1571 10979 : virtual ~TypeParamBound () {}
1572 :
1573 : // Unique pointer custom clone function
1574 4992 : std::unique_ptr<TypeParamBound> clone_type_param_bound () const
1575 : {
1576 4992 : return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
1577 : }
1578 :
1579 0 : std::unique_ptr<TypeParamBound> reconstruct () const
1580 : {
1581 0 : return reconstruct_base (this);
1582 : }
1583 :
1584 : virtual std::string as_string () const = 0;
1585 :
1586 11865 : NodeId get_node_id () const { return node_id; }
1587 :
1588 : virtual location_t get_locus () const = 0;
1589 :
1590 : virtual TypeParamBoundType get_bound_type () const = 0;
1591 :
1592 : virtual TypeParamBound *reconstruct_impl () const = 0;
1593 :
1594 : protected:
1595 : // Clone function implementation as pure virtual method
1596 : virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
1597 :
1598 : TypeParamBound () : node_id (Analysis::Mappings::get ().get_next_node_id ())
1599 : {}
1600 855 : TypeParamBound (NodeId node_id) : node_id (node_id) {}
1601 :
1602 : NodeId node_id;
1603 : };
1604 :
1605 : // Represents a lifetime (and is also a kind of type param bound)
1606 35420 : class Lifetime : public TypeParamBound
1607 : {
1608 : public:
1609 : enum LifetimeType
1610 : {
1611 : NAMED, // corresponds to LIFETIME_OR_LABEL
1612 : STATIC, // corresponds to 'static
1613 : WILDCARD // corresponds to '_
1614 : };
1615 :
1616 : private:
1617 : LifetimeType lifetime_type;
1618 : std::string lifetime_name;
1619 : location_t locus;
1620 : NodeId node_id;
1621 :
1622 : public:
1623 : // Constructor
1624 24328 : Lifetime (LifetimeType type, std::string name = std::string (),
1625 : location_t locus = UNDEF_LOCATION)
1626 24328 : : TypeParamBound (Analysis::Mappings::get ().get_next_node_id ()),
1627 24328 : lifetime_type (type), lifetime_name (std::move (name)), locus (locus)
1628 24328 : {}
1629 :
1630 24 : Lifetime (NodeId id, LifetimeType type, std::string name = std::string (),
1631 : location_t locus = UNDEF_LOCATION)
1632 24 : : TypeParamBound (id), lifetime_type (type),
1633 48 : lifetime_name (std::move (name)), locus (locus)
1634 : {}
1635 :
1636 23457 : static Lifetime elided () { return Lifetime (WILDCARD, ""); }
1637 :
1638 : // Returns true if the lifetime is in an error state.
1639 : std::string as_string () const override;
1640 :
1641 : void accept_vis (ASTVisitor &vis) override;
1642 :
1643 10542 : LifetimeType get_lifetime_type () const { return lifetime_type; }
1644 :
1645 10605 : location_t get_locus () const override final { return locus; }
1646 :
1647 30803 : std::string get_lifetime_name () const { return lifetime_name; }
1648 :
1649 0 : TypeParamBoundType get_bound_type () const override
1650 : {
1651 0 : return TypeParamBound::TypeParamBoundType::LIFETIME;
1652 : }
1653 :
1654 : protected:
1655 : /* Use covariance to implement clone function as returning this object
1656 : * rather than base */
1657 24 : Lifetime *clone_type_param_bound_impl () const override
1658 : {
1659 48 : return new Lifetime (node_id, lifetime_type, lifetime_name, locus);
1660 : }
1661 0 : Lifetime *reconstruct_impl () const override
1662 : {
1663 0 : return new Lifetime (lifetime_type, lifetime_name, locus);
1664 : }
1665 : };
1666 :
1667 : /* Base generic parameter in AST. Abstract - can be represented by a Lifetime
1668 : * or Type param */
1669 : class GenericParam : public Visitable
1670 : {
1671 : public:
1672 : enum class Kind
1673 : {
1674 : Lifetime,
1675 : Type,
1676 : Const,
1677 : };
1678 :
1679 : virtual ~GenericParam () {}
1680 :
1681 : // Unique pointer custom clone function
1682 11513 : std::unique_ptr<GenericParam> clone_generic_param () const
1683 : {
1684 11513 : return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
1685 : }
1686 :
1687 : virtual std::string as_string () const = 0;
1688 :
1689 : virtual location_t get_locus () const = 0;
1690 :
1691 : virtual Kind get_kind () const = 0;
1692 :
1693 100457 : NodeId get_node_id () const { return node_id; }
1694 :
1695 : protected:
1696 581 : GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1697 28529 : GenericParam (NodeId node_id) : node_id (node_id) {}
1698 :
1699 : // Clone function implementation as pure virtual method
1700 : virtual GenericParam *clone_generic_param_impl () const = 0;
1701 :
1702 : NodeId node_id;
1703 : };
1704 :
1705 : // A lifetime generic parameter (as opposed to a type generic parameter)
1706 : class LifetimeParam : public GenericParam
1707 : {
1708 : Lifetime lifetime;
1709 : std::vector<Lifetime> lifetime_bounds;
1710 : AST::AttrVec outer_attrs;
1711 : location_t locus;
1712 :
1713 : public:
1714 0 : Lifetime get_lifetime () const { return lifetime; }
1715 :
1716 3782 : Lifetime &get_lifetime () { return lifetime; }
1717 :
1718 4860 : AST::AttrVec &get_outer_attrs () { return outer_attrs; }
1719 :
1720 : // Returns whether the lifetime param has any lifetime bounds.
1721 21 : bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
1722 :
1723 3564 : std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
1724 :
1725 : const std::vector<Lifetime> &get_lifetime_bounds () const
1726 : {
1727 0 : return lifetime_bounds;
1728 : }
1729 :
1730 : // Returns whether the lifetime param has an outer attribute.
1731 0 : bool has_outer_attribute () const { return !outer_attrs.empty (); }
1732 :
1733 : // Constructor
1734 271 : LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
1735 : AST::AttrVec outer_attrs, location_t locus)
1736 542 : : lifetime (std::move (lifetime)),
1737 271 : lifetime_bounds (std::move (lifetime_bounds)),
1738 271 : outer_attrs (std::move (outer_attrs)), locus (locus)
1739 271 : {}
1740 :
1741 : std::string as_string () const override;
1742 :
1743 : void accept_vis (ASTVisitor &vis) override;
1744 :
1745 394 : location_t get_locus () const override final { return locus; }
1746 :
1747 745 : Kind get_kind () const override final { return Kind::Lifetime; }
1748 :
1749 : protected:
1750 : /* Use covariance to implement clone function as returning this object
1751 : * rather than base */
1752 810 : LifetimeParam *clone_generic_param_impl () const override
1753 : {
1754 810 : return new LifetimeParam (*this);
1755 : }
1756 : };
1757 :
1758 53775 : class AssociatedItem : public Visitable
1759 : {
1760 : protected:
1761 : // Clone function implementation as pure virtual method
1762 : virtual AssociatedItem *clone_associated_item_impl () const = 0;
1763 :
1764 : public:
1765 : virtual ~AssociatedItem () {}
1766 :
1767 38183 : std::unique_ptr<AssociatedItem> clone_associated_item () const
1768 : {
1769 38183 : return std::unique_ptr<AssociatedItem> (clone_associated_item_impl ());
1770 : }
1771 :
1772 : virtual std::string as_string () const = 0;
1773 :
1774 : virtual void mark_for_strip () = 0;
1775 : virtual bool is_marked_for_strip () const = 0;
1776 :
1777 : virtual location_t get_locus () const = 0;
1778 :
1779 : virtual NodeId get_node_id () const = 0;
1780 : };
1781 :
1782 : // Item used in trait declarations - abstract base class
1783 : class TraitItem : public AssociatedItem
1784 : {
1785 : protected:
1786 16763 : TraitItem (location_t locus)
1787 16763 : : node_id (Analysis::Mappings::get ().get_next_node_id ()),
1788 33526 : vis (Visibility::create_private ()), locus (locus)
1789 16763 : {}
1790 :
1791 751 : TraitItem (Visibility vis, location_t locus)
1792 751 : : node_id (Analysis::Mappings::get ().get_next_node_id ()), vis (vis),
1793 751 : locus (locus)
1794 751 : {}
1795 :
1796 : // Clone function implementation as pure virtual method
1797 : virtual TraitItem *clone_associated_item_impl () const override = 0;
1798 :
1799 : NodeId node_id;
1800 : Visibility vis;
1801 : location_t locus;
1802 :
1803 : public:
1804 : // Unique pointer custom clone function
1805 : std::unique_ptr<TraitItem> clone_trait_item () const
1806 : {
1807 : return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
1808 : }
1809 :
1810 5325 : NodeId get_node_id () const override { return node_id; }
1811 3788 : location_t get_locus () const override { return locus; }
1812 : };
1813 :
1814 : // Abstract base class for an item used inside an extern block
1815 : class ExternalItem : public Visitable
1816 : {
1817 : public:
1818 4 : ExternalItem () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1819 :
1820 79032 : ExternalItem (NodeId node_id) : node_id (node_id) {}
1821 :
1822 : virtual ~ExternalItem () {}
1823 :
1824 : // Unique pointer custom clone function
1825 5800 : std::unique_ptr<ExternalItem> clone_external_item () const
1826 : {
1827 5800 : return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
1828 : }
1829 :
1830 : virtual std::string as_string () const = 0;
1831 :
1832 : virtual void mark_for_strip () = 0;
1833 : virtual bool is_marked_for_strip () const = 0;
1834 :
1835 3042 : virtual NodeId get_node_id () const { return node_id; }
1836 :
1837 : protected:
1838 : // Clone function implementation as pure virtual method
1839 : virtual ExternalItem *clone_external_item_impl () const = 0;
1840 :
1841 : NodeId node_id;
1842 : };
1843 :
1844 : /* Data structure to store the data used in macro invocations and macro
1845 : * invocations with semicolons. */
1846 : struct MacroInvocData
1847 : {
1848 : private:
1849 : SimplePath path;
1850 : DelimTokenTree token_tree;
1851 :
1852 : // One way of parsing the macro. Probably not applicable for all macros.
1853 : std::vector<std::unique_ptr<MetaItemInner>> parsed_items;
1854 : bool parsed_to_meta_item = false;
1855 : MacroExpander *expander = nullptr;
1856 :
1857 : public:
1858 : std::string as_string () const;
1859 :
1860 3038 : MacroInvocData (SimplePath path, DelimTokenTree token_tree)
1861 3038 : : path (std::move (path)), token_tree (std::move (token_tree))
1862 3038 : {}
1863 :
1864 : // Copy constructor with vector clone
1865 15071 : MacroInvocData (const MacroInvocData &other)
1866 15071 : : path (other.path), token_tree (other.token_tree),
1867 15071 : parsed_to_meta_item (other.parsed_to_meta_item)
1868 : {
1869 15071 : parsed_items.reserve (other.parsed_items.size ());
1870 15071 : for (const auto &e : other.parsed_items)
1871 0 : parsed_items.push_back (e->clone_meta_item_inner ());
1872 15071 : }
1873 :
1874 : // Copy assignment operator with vector clone
1875 : MacroInvocData &operator= (const MacroInvocData &other)
1876 : {
1877 : path = other.path;
1878 : token_tree = other.token_tree;
1879 : parsed_to_meta_item = other.parsed_to_meta_item;
1880 : expander = other.expander;
1881 :
1882 : parsed_items.reserve (other.parsed_items.size ());
1883 : for (const auto &e : other.parsed_items)
1884 : parsed_items.push_back (e->clone_meta_item_inner ());
1885 :
1886 : return *this;
1887 : }
1888 :
1889 : // Move constructors
1890 3422 : MacroInvocData (MacroInvocData &&other) = default;
1891 : MacroInvocData &operator= (MacroInvocData &&other) = default;
1892 :
1893 : // Invalid if path is empty, so base stripping on that.
1894 0 : void mark_for_strip () { path = SimplePath::create_empty (); }
1895 6387 : bool is_marked_for_strip () const { return path.is_empty (); }
1896 :
1897 : // Returns whether the macro has been parsed already.
1898 47 : bool is_parsed () const { return parsed_to_meta_item; }
1899 : // TODO: update on other ways of parsing it
1900 :
1901 : // TODO: this mutable getter seems kinda dodgy
1902 10166 : DelimTokenTree &get_delim_tok_tree () { return token_tree; }
1903 : const DelimTokenTree &get_delim_tok_tree () const { return token_tree; }
1904 :
1905 : // Set the delim token tree of a macro invocation
1906 46 : void set_delim_tok_tree (DelimTokenTree tree) { token_tree = tree; }
1907 :
1908 : // TODO: this mutable getter seems kinda dodgy
1909 10208 : SimplePath &get_path () { return path; }
1910 : const SimplePath &get_path () const { return path; }
1911 :
1912 2863 : void set_expander (MacroExpander *new_expander) { expander = new_expander; }
1913 224 : MacroExpander *get_expander ()
1914 : {
1915 224 : rust_assert (expander);
1916 224 : return expander;
1917 : }
1918 :
1919 : void
1920 47 : set_meta_item_output (std::vector<std::unique_ptr<MetaItemInner>> new_items)
1921 : {
1922 47 : parsed_items = std::move (new_items);
1923 : }
1924 : std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
1925 : {
1926 : return parsed_items;
1927 : }
1928 : const std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items () const
1929 : {
1930 : return parsed_items;
1931 : }
1932 : };
1933 :
1934 : class SingleASTNode : public Visitable
1935 : {
1936 : public:
1937 : enum class Kind
1938 : {
1939 : Expr,
1940 : Item,
1941 : Stmt,
1942 : Extern,
1943 : Assoc,
1944 : Type,
1945 : Pattern,
1946 : };
1947 :
1948 : private:
1949 : Kind kind;
1950 :
1951 : // FIXME make this a union
1952 : std::unique_ptr<Expr> expr;
1953 : std::unique_ptr<Item> item;
1954 : std::unique_ptr<Stmt> stmt;
1955 : std::unique_ptr<ExternalItem> external_item;
1956 : std::unique_ptr<AssociatedItem> assoc_item;
1957 : std::unique_ptr<Type> type;
1958 : std::unique_ptr<Pattern> pattern;
1959 :
1960 : public:
1961 1974 : SingleASTNode (std::unique_ptr<Expr> expr)
1962 1974 : : kind (Kind::Expr), expr (std::move (expr))
1963 : {}
1964 :
1965 2593 : SingleASTNode (std::unique_ptr<Item> item)
1966 2593 : : kind (Kind::Item), item (std::move (item))
1967 : {}
1968 :
1969 470 : SingleASTNode (std::unique_ptr<Stmt> stmt)
1970 470 : : kind (Kind::Stmt), stmt (std::move (stmt))
1971 : {}
1972 :
1973 3 : SingleASTNode (std::unique_ptr<ExternalItem> item)
1974 3 : : kind (Kind::Extern), external_item (std::move (item))
1975 : {}
1976 :
1977 107 : SingleASTNode (std::unique_ptr<AssociatedItem> item)
1978 107 : : kind (Kind::Assoc), assoc_item (std::move (item))
1979 : {}
1980 :
1981 29 : SingleASTNode (std::unique_ptr<Type> type)
1982 29 : : kind (Kind::Type), type (std::move (type))
1983 : {}
1984 :
1985 2 : SingleASTNode (std::unique_ptr<Pattern> pattern)
1986 2 : : kind (Kind::Pattern), pattern (std::move (pattern))
1987 : {}
1988 :
1989 : SingleASTNode (SingleASTNode const &other);
1990 :
1991 : SingleASTNode operator= (SingleASTNode const &other);
1992 :
1993 6103 : SingleASTNode (SingleASTNode &&other) = default;
1994 : SingleASTNode &operator= (SingleASTNode &&other) = default;
1995 :
1996 3866 : Kind get_kind () const { return kind; }
1997 :
1998 : std::unique_ptr<Expr> &get_expr ()
1999 : {
2000 : rust_assert (kind == Kind::Expr);
2001 : return expr;
2002 : }
2003 :
2004 0 : std::unique_ptr<Item> &get_item ()
2005 : {
2006 0 : rust_assert (kind == Kind::Item);
2007 0 : return item;
2008 : }
2009 :
2010 : std::unique_ptr<Stmt> &get_stmt ()
2011 : {
2012 : rust_assert (kind == Kind::Stmt);
2013 : return stmt;
2014 : }
2015 :
2016 : /**
2017 : * Access the inner nodes and take ownership of them.
2018 : * You can only call these functions once per node
2019 : */
2020 :
2021 483 : std::unique_ptr<Stmt> take_stmt ()
2022 : {
2023 483 : rust_assert (!is_error ());
2024 483 : return std::move (stmt);
2025 : }
2026 :
2027 1903 : std::unique_ptr<Expr> take_expr ()
2028 : {
2029 1903 : rust_assert (!is_error ());
2030 1903 : return std::move (expr);
2031 : }
2032 :
2033 2592 : std::unique_ptr<Item> take_item ()
2034 : {
2035 2592 : rust_assert (!is_error ());
2036 2592 : return std::move (item);
2037 : }
2038 :
2039 3 : std::unique_ptr<ExternalItem> take_external_item ()
2040 : {
2041 3 : rust_assert (!is_error ());
2042 3 : return std::move (external_item);
2043 : }
2044 :
2045 107 : std::unique_ptr<AssociatedItem> take_assoc_item ()
2046 : {
2047 107 : rust_assert (!is_error ());
2048 107 : return std::move (assoc_item);
2049 : }
2050 :
2051 29 : std::unique_ptr<Type> take_type ()
2052 : {
2053 29 : rust_assert (!is_error ());
2054 29 : return std::move (type);
2055 : }
2056 :
2057 1 : std::unique_ptr<Pattern> take_pattern ()
2058 : {
2059 1 : rust_assert (!is_error ());
2060 1 : return std::move (pattern);
2061 : }
2062 :
2063 : void accept_vis (ASTVisitor &vis) override;
2064 :
2065 : bool is_error ();
2066 :
2067 : std::string as_string () const;
2068 : };
2069 :
2070 : // A crate AST object - holds all the data for a single compilation unit
2071 : struct Crate final : public GlobContainer
2072 : {
2073 : std::vector<Attribute> inner_attrs;
2074 : // dodgy spacing required here
2075 : /* TODO: is it better to have a vector of items here or a module (implicit
2076 : * top-level one)? */
2077 : std::vector<std::unique_ptr<Item>> items;
2078 :
2079 : NodeId node_id;
2080 :
2081 : public:
2082 : // Constructor
2083 4932 : Crate (std::vector<std::unique_ptr<Item>> items,
2084 : std::vector<Attribute> inner_attrs)
2085 4932 : : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
2086 4932 : node_id (Analysis::Mappings::get ().get_next_node_id ())
2087 4932 : {}
2088 :
2089 : // Copy constructor with vector clone
2090 4772 : Crate (Crate const &other)
2091 4772 : : inner_attrs (other.inner_attrs), node_id (other.node_id)
2092 : {
2093 4772 : items.reserve (other.items.size ());
2094 24302 : for (const auto &e : other.items)
2095 19530 : items.push_back (e->clone_item ());
2096 4772 : }
2097 :
2098 4883 : ~Crate () = default;
2099 :
2100 : // Overloaded assignment operator with vector clone
2101 : Crate &operator= (Crate const &other)
2102 : {
2103 : inner_attrs = other.inner_attrs;
2104 : node_id = other.node_id;
2105 :
2106 : items.reserve (other.items.size ());
2107 : for (const auto &e : other.items)
2108 : items.push_back (e->clone_item ());
2109 :
2110 : return *this;
2111 : }
2112 :
2113 : // Move constructors
2114 : Crate (Crate &&other) = default;
2115 : Crate &operator= (Crate &&other) = default;
2116 :
2117 : // Get crate representation as string (e.g. for debugging).
2118 : std::string as_string () const;
2119 :
2120 : // Delete all crate information, e.g. if fails cfg.
2121 1 : void strip_crate ()
2122 : {
2123 1 : inner_attrs.clear ();
2124 1 : inner_attrs.shrink_to_fit ();
2125 :
2126 1 : items.clear ();
2127 1 : items.shrink_to_fit ();
2128 : // TODO: is this the best way to do this?
2129 1 : }
2130 :
2131 : void inject_extern_crate (std::string name);
2132 : void inject_inner_attribute (Attribute attribute);
2133 :
2134 148512 : NodeId get_node_id () const { return node_id; }
2135 : const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
2136 105483 : std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
2137 :
2138 : std::vector<std::unique_ptr<AST::Item>> take_items ()
2139 : {
2140 : return std::move (items);
2141 : }
2142 :
2143 : void set_items (std::vector<std::unique_ptr<AST::Item>> &&new_items)
2144 : {
2145 : items = std::move (new_items);
2146 : }
2147 :
2148 4773 : GlobContainer::Kind get_glob_container_kind () const override
2149 : {
2150 4773 : return GlobContainer::Kind::Crate;
2151 : }
2152 : };
2153 :
2154 : } // namespace AST
2155 :
2156 : template <> struct CloneableDelegate<std::unique_ptr<AST::Pattern>>
2157 : {
2158 : static std::unique_ptr<AST::Pattern>
2159 61180 : clone (const std::unique_ptr<AST::Pattern> &other)
2160 : {
2161 61180 : if (other == nullptr)
2162 53872 : return nullptr;
2163 : else
2164 7308 : return other->clone_pattern ();
2165 : }
2166 : };
2167 :
2168 : } // namespace Rust
2169 :
2170 : namespace std {
2171 : template <> struct less<Rust::Identifier>
2172 : {
2173 : bool operator() (const Rust::Identifier &lhs,
2174 : const Rust::Identifier &rhs) const
2175 : {
2176 : return lhs.as_string () < rhs.as_string ();
2177 : }
2178 : };
2179 :
2180 : template <> struct hash<Rust::Identifier>
2181 : {
2182 : std::size_t operator() (const Rust::Identifier &k) const
2183 : {
2184 : using std::hash;
2185 : using std::size_t;
2186 : using std::string;
2187 :
2188 : return hash<string> () (k.as_string ()) ^ (hash<int> () (k.get_locus ()));
2189 : }
2190 : };
2191 :
2192 : } // namespace std
2193 :
2194 : #endif
|