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