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 3883762 : class Identifier
38 : {
39 : public:
40 : // Create dummy identifier
41 1027 : Identifier () : ident (""), loc (UNDEF_LOCATION) {}
42 : // Create identifier with dummy location
43 307885 : Identifier (std::string ident, location_t loc = UNDEF_LOCATION)
44 614678 : : ident (ident), loc (loc)
45 : {}
46 : // Create identifier from token
47 43250 : Identifier (const_TokenPtr token)
48 43250 : : ident (token->get_str ()), loc (token->get_locus ())
49 43250 : {}
50 :
51 4350205 : Identifier (const Identifier &) = default;
52 1110509 : Identifier (Identifier &&) = default;
53 0 : Identifier &operator= (const Identifier &) = default;
54 3337 : Identifier &operator= (Identifier &&) = default;
55 :
56 4506 : location_t get_locus () const { return loc; }
57 2066810 : const std::string &as_string () const { return ident; }
58 :
59 198962 : 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 417519 : class Visitable
81 : {
82 : public:
83 362195 : 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 391633 : class TokenTree : public Visitable
132 : {
133 : public:
134 50115 : virtual ~TokenTree () {}
135 :
136 : // Unique pointer custom clone function
137 566386 : std::unique_ptr<TokenTree> clone_token_tree () const
138 : {
139 566386 : 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 138929 : class MacroMatch : public Visitable
155 : {
156 : public:
157 : enum MacroMatchType
158 : {
159 : Fragment,
160 : Repetition,
161 : Matcher,
162 : Tok
163 : };
164 :
165 1225 : 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 4514 : std::unique_ptr<MacroMatch> clone_macro_match () const
172 : {
173 4514 : 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 910163 : std::unique_ptr<Token> clone_token () const
198 : {
199 910163 : return std::unique_ptr<Token> (clone_token_impl ());
200 : }
201 :
202 : // Constructor from lexer const_TokenPtr
203 236883 : Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
204 :
205 42610 : bool is_string_lit () const
206 : {
207 42610 : switch (get_id ())
208 : {
209 : case STRING_LITERAL:
210 : case BYTE_STRING_LITERAL:
211 : case RAW_STRING_LITERAL:
212 : return true;
213 41794 : default:
214 41794 : 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 275005 : 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 877 : 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 412280 : 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 1604259 : /*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 538271 : Token *clone_token_tree_impl () const final override
252 : {
253 538271 : 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 24263 : 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 35627 : std::string as_string () const { return value_as_string; }
290 :
291 31588 : LitType get_lit_type () const { return type; }
292 :
293 22255 : PrimitiveCoreType get_type_hint () const { return type_hint; }
294 :
295 40019 : Literal (std::string value_as_string, LitType type,
296 : PrimitiveCoreType type_hint)
297 40019 : : value_as_string (std::move (value_as_string)), type (type),
298 40019 : 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 620715 : 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 97932 : class PathSegment
317 : {
318 : public:
319 24614 : 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 95270 : 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 35553 : SimplePathSegment (std::string segment_name, location_t locus)
337 71106 : : segment_name (std::move (segment_name)), locus (locus),
338 35553 : node_id (Analysis::Mappings::get ().get_next_node_id ())
339 35553 : {}
340 :
341 : /* Returns whether simple path segment is in an invalid state (currently, if
342 : * empty). */
343 318854 : 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 57222 : location_t get_locus () const { return locus; }
354 26358 : NodeId get_node_id () const { return node_id; }
355 115360 : const std::string &get_segment_name () const { return segment_name; }
356 2240 : bool is_super_path_seg () const
357 : {
358 2240 : return as_string ().compare (Values::Keywords::SUPER) == 0;
359 : }
360 2293 : bool is_crate_path_seg () const
361 : {
362 2293 : return as_string ().compare (Values::Keywords::CRATE) == 0;
363 : }
364 6649 : bool is_lower_self_seg () const
365 : {
366 6649 : return as_string ().compare (Values::Keywords::SELF) == 0;
367 : }
368 2228 : bool is_big_self () const
369 : {
370 2228 : return as_string ().compare (Values::Keywords::SELF_ALIAS) == 0;
371 : }
372 : };
373 :
374 : // A simple path without generic or type arguments
375 433475 : 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 102669 : explicit SimplePath (std::vector<SimplePathSegment> path_segments,
385 : bool has_opening_scope_resolution = false,
386 : location_t locus = UNDEF_LOCATION)
387 102669 : : opening_scope_resolution (has_opening_scope_resolution),
388 102669 : segments (std::move (path_segments)), locus (locus),
389 102669 : node_id (Analysis::Mappings::get ().get_next_node_id ())
390 102669 : {}
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 68256 : static SimplePath create_empty ()
401 : {
402 68256 : return SimplePath (std::vector<SimplePathSegment> ());
403 : }
404 :
405 : // Returns whether the SimplePath is empty, i.e. has path segments.
406 13365 : bool is_empty () const { return segments.empty (); }
407 :
408 : const std::string as_string () const;
409 :
410 11943 : bool has_opening_scope_resolution () const
411 : {
412 11943 : return opening_scope_resolution;
413 : }
414 :
415 2936 : 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 452675 : bool operator== (const std::string &rhs) const
422 : {
423 452675 : return !opening_scope_resolution && segments.size () == 1
424 905350 : && 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 358 : static SimplePath from_str (std::string str, location_t locus)
432 : {
433 358 : std::vector<AST::SimplePathSegment> single_segments
434 716 : = {AST::SimplePathSegment (std::move (str), locus)};
435 358 : return SimplePath (std::move (single_segments), false, locus);
436 358 : }
437 :
438 32438 : const std::vector<SimplePathSegment> &get_segments () const
439 : {
440 35532 : return segments;
441 : }
442 :
443 692634 : std::vector<SimplePathSegment> &get_segments () { return segments; }
444 :
445 13119 : const SimplePathSegment &get_final_segment () const
446 : {
447 13119 : return segments.back ();
448 : }
449 : };
450 :
451 : // path-to-string inverse comparison operator
452 : inline bool
453 12267 : operator!= (const SimplePath &lhs, const std::string &rhs)
454 : {
455 12267 : 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 275152 : 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 62025 : Visibility (VisType vis_type, SimplePath in_path, location_t locus)
482 14164 : : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
483 : {}
484 :
485 : public:
486 41079 : VisType get_vis_type () const { return vis_type; }
487 :
488 : // Returns whether a visibility has a path
489 792562 : bool has_path () const { return vis_type >= PUB_CRATE; }
490 :
491 : // Returns whether visibility is public or not.
492 1247 : bool is_public () const { return vis_type != PRIV; }
493 :
494 2827 : 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 8702 : static Visibility create_public (location_t pub_vis_location)
507 : {
508 8702 : 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 53257 : static Visibility create_private ()
543 : {
544 53257 : 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 1334 : 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 728332 : bool has_attr_input () const { return attr_input != nullptr; }
587 :
588 : // Constructor has pointer AttrInput for polymorphism reasons
589 35142 : Attribute (SimplePath path, std::unique_ptr<AttrInput> input,
590 : location_t locus = UNDEF_LOCATION, bool inner_attribute = false)
591 35142 : : path (std::move (path)), attr_input (std::move (input)), locus (locus),
592 35142 : inner_attribute (inner_attribute),
593 35142 : node_id (Analysis::Mappings::get ().get_next_node_id ())
594 35142 : {}
595 :
596 : bool is_derive () const;
597 :
598 : std::vector<std::reference_wrapper<AST::SimplePath>> get_traits_to_derive ();
599 :
600 : // default destructor
601 189226 : ~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 95885 : 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 5689 : static Attribute create_empty ()
621 : {
622 5689 : return Attribute (SimplePath::create_empty (), nullptr);
623 : }
624 :
625 : // Returns whether the attribute is considered an "empty" attribute.
626 2637 : bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
627 :
628 : // Returns whether the attribute has no input
629 7959 : bool empty_input () const { return !attr_input; }
630 :
631 11544 : location_t get_locus () const { return locus; }
632 :
633 527310 : AttrInput &get_attr_input () const { return *attr_input; }
634 :
635 2 : void set_attr_input (std::unique_ptr<AST::AttrInput> input)
636 : {
637 2 : attr_input = std::move (input);
638 : }
639 :
640 : /* e.g.:
641 : #![crate_type = "lib"]
642 : #[test]
643 : #[cfg(target_os = "linux")]
644 : #[allow(non_camel_case_types)]
645 : #![allow(unused_variables)]
646 : */
647 :
648 : // Full built-in attribute list:
649 : /* cfg
650 : * cfg_attr
651 : * test
652 : * ignore
653 : * should_panic
654 : * derive
655 : * macro_export
656 : * macro_use
657 : * proc_macro
658 : * proc_macro_derive
659 : * proc_macro_attribute
660 : * allow
661 : * warn
662 : * deny
663 : * forbid
664 : * deprecated
665 : * must_use
666 : * link
667 : * link_name
668 : * no_link
669 : * repr
670 : * crate_type
671 : * no_main
672 : * export_name
673 : * link_section
674 : * no_mangle
675 : * used
676 : * crate_name
677 : * inline
678 : * cold
679 : * no_builtins
680 : * target_feature
681 : * doc
682 : * no_std
683 : * no_implicit_prelude
684 : * path
685 : * recursion_limit
686 : * type_length_limit
687 : * panic_handler
688 : * global_allocator
689 : * windows_subsystem
690 : * feature */
691 :
692 : std::string as_string () const;
693 :
694 2228 : bool is_inner_attribute () const { return inner_attribute; }
695 :
696 : void accept_vis (ASTVisitor &vis) override;
697 :
698 243725 : const SimplePath &get_path () const { return path; }
699 866073 : SimplePath &get_path () { return path; }
700 :
701 : NodeId get_node_id () { return node_id; }
702 :
703 : // Call to parse attribute body to meta item syntax.
704 : void parse_attr_to_meta_item ();
705 :
706 : /* Determines whether cfg predicate is true and item with attribute should
707 : * not be stripped. Attribute body must already be parsed to meta item. */
708 : bool check_cfg_predicate (const Session &session) const;
709 :
710 : // Returns whether body has been parsed to meta item form or not.
711 : bool is_parsed_to_meta_item () const;
712 :
713 : /* Returns any attributes generated from cfg_attr attributes. Attribute body
714 : * must already be parsed to meta item. */
715 : std::vector<Attribute> separate_cfg_attrs () const;
716 :
717 : protected:
718 : // not virtual as currently no subclasses of Attribute, but could be in
719 : // future
720 : /*virtual*/ Attribute *clone_attribute_impl () const
721 : {
722 : return new Attribute (*this);
723 : }
724 : };
725 :
726 : // Attribute body - abstract base class
727 86249 : class AttrInput : public Visitable
728 : {
729 : public:
730 : enum AttrInputType
731 : {
732 : EXPR,
733 : LITERAL,
734 : META_ITEM,
735 : TOKEN_TREE,
736 : };
737 :
738 50115 : virtual ~AttrInput () {}
739 :
740 : // Unique pointer custom clone function
741 109312 : std::unique_ptr<AttrInput> clone_attr_input () const
742 : {
743 109312 : return std::unique_ptr<AttrInput> (clone_attr_input_impl ());
744 : }
745 :
746 : virtual std::string as_string () const = 0;
747 :
748 : virtual bool check_cfg_predicate (const Session &session) const = 0;
749 :
750 : // Parse attribute input to meta item, if possible
751 0 : virtual AttrInput *parse_to_meta_item () const { return nullptr; }
752 :
753 0 : virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; }
754 :
755 : // Returns whether attr input has been parsed to meta item syntax.
756 : virtual bool is_meta_item () const = 0;
757 :
758 : virtual AttrInputType get_attr_input_type () const = 0;
759 :
760 : protected:
761 : // pure virtual clone implementation
762 : virtual AttrInput *clone_attr_input_impl () const = 0;
763 : };
764 :
765 : // Forward decl - defined in rust-macro.h
766 : class MetaNameValueStr;
767 :
768 : // abstract base meta item inner class
769 28 : class MetaItemInner : public Visitable
770 : {
771 : protected:
772 : // pure virtual as MetaItemInner
773 : virtual MetaItemInner *clone_meta_item_inner_impl () const = 0;
774 :
775 : public:
776 : enum class Kind
777 : {
778 : LitExpr,
779 : MetaItem,
780 : };
781 :
782 : // Unique pointer custom clone function
783 2916 : std::unique_ptr<MetaItemInner> clone_meta_item_inner () const
784 : {
785 2916 : return std::unique_ptr<MetaItemInner> (clone_meta_item_inner_impl ());
786 : }
787 :
788 : virtual Kind get_kind () = 0;
789 :
790 : virtual ~MetaItemInner ();
791 :
792 : virtual location_t get_locus () const = 0;
793 :
794 : virtual std::string as_string () const = 0;
795 :
796 : /* HACK: used to simplify parsing - creates a copy of that type, or returns
797 : * null */
798 : virtual std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const;
799 :
800 : // HACK: used to simplify parsing - same thing
801 0 : virtual SimplePath to_path_item () const
802 : {
803 0 : return SimplePath::create_empty ();
804 : }
805 :
806 0 : virtual Attribute to_attribute () const { return Attribute::create_empty (); }
807 :
808 : virtual bool check_cfg_predicate (const Session &session) const = 0;
809 :
810 99 : virtual bool is_key_value_pair () const { return false; }
811 : };
812 :
813 : // Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
814 : class AttrInputMetaItemContainer : public AttrInput
815 : {
816 : std::vector<std::unique_ptr<MetaItemInner>> items;
817 :
818 : public:
819 10274 : AttrInputMetaItemContainer (std::vector<std::unique_ptr<MetaItemInner>> items)
820 10274 : : items (std::move (items))
821 : {}
822 :
823 : // copy constructor with vector clone
824 2716 : AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other)
825 2716 : {
826 2716 : items.reserve (other.items.size ());
827 5575 : for (const auto &e : other.items)
828 2859 : items.push_back (e->clone_meta_item_inner ());
829 2716 : }
830 :
831 : // copy assignment operator with vector clone
832 : AttrInputMetaItemContainer &
833 : operator= (const AttrInputMetaItemContainer &other)
834 : {
835 : AttrInput::operator= (other);
836 :
837 : items.reserve (other.items.size ());
838 : for (const auto &e : other.items)
839 : items.push_back (e->clone_meta_item_inner ());
840 :
841 : return *this;
842 : }
843 :
844 : // default move constructors
845 : AttrInputMetaItemContainer (AttrInputMetaItemContainer &&other) = default;
846 : AttrInputMetaItemContainer &operator= (AttrInputMetaItemContainer &&other)
847 : = default;
848 :
849 : std::string as_string () const override;
850 :
851 : void accept_vis (ASTVisitor &vis) override;
852 :
853 : bool check_cfg_predicate (const Session &session) const override;
854 :
855 406 : AttrInputType get_attr_input_type () const final override
856 : {
857 406 : return AttrInput::AttrInputType::META_ITEM;
858 : }
859 :
860 : // Clones this object.
861 : std::unique_ptr<AttrInputMetaItemContainer>
862 : clone_attr_input_meta_item_container () const
863 : {
864 : return std::unique_ptr<AttrInputMetaItemContainer> (
865 : clone_attr_input_meta_item_container_impl ());
866 : }
867 :
868 : std::vector<Attribute> separate_cfg_attrs () const override;
869 :
870 6258 : bool is_meta_item () const override { return true; }
871 :
872 : // TODO: this mutable getter seems dodgy
873 14394 : std::vector<std::unique_ptr<MetaItemInner>> &get_items () { return items; }
874 28 : const std::vector<std::unique_ptr<MetaItemInner>> &get_items () const
875 : {
876 7077 : return items;
877 : }
878 :
879 : protected:
880 : // Use covariance to implement clone function as returning this type
881 2715 : AttrInputMetaItemContainer *clone_attr_input_impl () const final override
882 : {
883 2715 : return clone_attr_input_meta_item_container_impl ();
884 : }
885 :
886 2715 : AttrInputMetaItemContainer *clone_attr_input_meta_item_container_impl () const
887 : {
888 2715 : return new AttrInputMetaItemContainer (*this);
889 : }
890 : };
891 :
892 : // A token tree with delimiters
893 48952 : class DelimTokenTree : public TokenTree, public AttrInput
894 : {
895 : DelimType delim_type;
896 : std::vector<std::unique_ptr<TokenTree>> token_trees;
897 : location_t locus;
898 :
899 : protected:
900 63023 : DelimTokenTree *clone_delim_tok_tree_impl () const
901 : {
902 63023 : return new DelimTokenTree (*this);
903 : }
904 :
905 : /* Use covariance to implement clone function as returning a DelimTokenTree
906 : * object */
907 0 : DelimTokenTree *clone_attr_input_impl () const final override
908 : {
909 0 : return clone_delim_tok_tree_impl ();
910 : }
911 :
912 : /* Use covariance to implement clone function as returning a DelimTokenTree
913 : * object */
914 28115 : DelimTokenTree *clone_token_tree_impl () const final override
915 : {
916 28115 : return clone_delim_tok_tree_impl ();
917 : }
918 :
919 : public:
920 23166 : DelimTokenTree (DelimType delim_type,
921 : std::vector<std::unique_ptr<TokenTree>> token_trees
922 : = std::vector<std::unique_ptr<TokenTree>> (),
923 : location_t locus = UNDEF_LOCATION)
924 23166 : : delim_type (delim_type), token_trees (std::move (token_trees)),
925 23166 : locus (locus)
926 : {}
927 :
928 : // Copy constructor with vector clone
929 98470 : DelimTokenTree (DelimTokenTree const &other)
930 98470 : : delim_type (other.delim_type), locus (other.locus)
931 : {
932 98470 : token_trees.clear ();
933 98470 : token_trees.reserve (other.token_trees.size ());
934 664678 : for (const auto &e : other.token_trees)
935 566208 : token_trees.push_back (e->clone_token_tree ());
936 98470 : }
937 :
938 : // overloaded assignment operator with vector clone
939 45 : DelimTokenTree &operator= (DelimTokenTree const &other)
940 : {
941 45 : delim_type = other.delim_type;
942 45 : locus = other.locus;
943 :
944 45 : token_trees.clear ();
945 45 : token_trees.reserve (other.token_trees.size ());
946 223 : for (const auto &e : other.token_trees)
947 178 : token_trees.push_back (e->clone_token_tree ());
948 :
949 45 : return *this;
950 : }
951 :
952 : // move constructors
953 24446 : DelimTokenTree (DelimTokenTree &&other) = default;
954 : DelimTokenTree &operator= (DelimTokenTree &&other) = default;
955 :
956 13 : static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
957 :
958 : std::string as_string () const override;
959 :
960 : void accept_vis (ASTVisitor &vis) override;
961 :
962 0 : bool check_cfg_predicate (const Session &) const override
963 : {
964 : // this should never be called - should be converted first
965 0 : rust_assert (false);
966 : return false;
967 : }
968 :
969 : AttrInputMetaItemContainer *parse_to_meta_item () const override;
970 :
971 : std::vector<std::unique_ptr<Token>> to_token_stream () const override;
972 :
973 : std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
974 : {
975 : return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
976 : }
977 :
978 1159 : bool is_meta_item () const override { return false; }
979 :
980 14948 : AttrInputType get_attr_input_type () const final override
981 : {
982 14948 : return AttrInput::AttrInputType::TOKEN_TREE;
983 : }
984 :
985 : std::vector<std::unique_ptr<TokenTree>> &get_token_trees ()
986 : {
987 291510 : return token_trees;
988 : }
989 :
990 : const std::vector<std::unique_ptr<TokenTree>> &get_token_trees () const
991 : {
992 0 : return token_trees;
993 : }
994 :
995 7854 : DelimType get_delim_type () const { return delim_type; }
996 4890 : location_t get_locus () const { return locus; }
997 : };
998 :
999 : /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
1000 : * to be defined */
1001 : class AttrInputLiteral;
1002 :
1003 : // abstract base meta item class
1004 12022 : class MetaItem : public MetaItemInner
1005 : {
1006 : public:
1007 : enum class ItemKind
1008 : {
1009 : Path,
1010 : Word,
1011 : NameValueStr,
1012 : PathExpr,
1013 : Seq,
1014 : ListPaths,
1015 : ListNameValueStr,
1016 : };
1017 :
1018 608 : MetaItemInner::Kind get_kind () override
1019 : {
1020 608 : return MetaItemInner::Kind::MetaItem;
1021 : }
1022 :
1023 : virtual ItemKind get_item_kind () const = 0;
1024 : };
1025 :
1026 : // Forward decl - defined in rust-expr.h
1027 : class MetaItemLitExpr;
1028 :
1029 : // Forward decl - defined in rust-expr.h
1030 : class MetaItemPathExpr;
1031 :
1032 : // Forward decl - defined in rust-macro.h
1033 : class MetaItemPath;
1034 :
1035 : // Forward decl - defined in rust-macro.h
1036 : class MetaItemSeq;
1037 :
1038 : // Forward decl - defined in rust-macro.h
1039 : class MetaWord;
1040 :
1041 : // Forward decl - defined in rust-macro.h
1042 : class MetaListPaths;
1043 :
1044 : // Forward decl - defined in rust-macro.h
1045 : class MetaListNameValueStr;
1046 :
1047 : /* Base statement abstract class. Note that most "statements" are not allowed
1048 : * in top-level module scope - only a subclass of statements called "items"
1049 : * are. */
1050 1110 : class Stmt : public Visitable
1051 : {
1052 : public:
1053 : enum class Kind
1054 : {
1055 : Empty,
1056 : Item,
1057 : Let,
1058 : Expr,
1059 : MacroInvocation,
1060 : };
1061 :
1062 : // Unique pointer custom clone function
1063 37720 : std::unique_ptr<Stmt> clone_stmt () const
1064 : {
1065 37720 : return std::unique_ptr<Stmt> (clone_stmt_impl ());
1066 : }
1067 :
1068 : virtual ~Stmt () {}
1069 :
1070 : virtual std::string as_string () const = 0;
1071 :
1072 : virtual location_t get_locus () const = 0;
1073 :
1074 : virtual void mark_for_strip () = 0;
1075 : virtual bool is_marked_for_strip () const = 0;
1076 :
1077 : // TODO: put this in a virtual base class?
1078 207351 : virtual NodeId get_node_id () const { return node_id; }
1079 :
1080 : virtual Kind get_stmt_kind () = 0;
1081 :
1082 : // TODO: Can we remove these two?
1083 : virtual bool is_item () const = 0;
1084 4097 : virtual bool is_expr () const { return false; }
1085 :
1086 38 : virtual void add_semicolon () {}
1087 :
1088 : protected:
1089 218078 : Stmt () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1090 :
1091 : // Clone function implementation as pure virtual method
1092 : virtual Stmt *clone_stmt_impl () const = 0;
1093 :
1094 : NodeId node_id;
1095 : };
1096 :
1097 : // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
1098 15630 : class Item : public Stmt
1099 : {
1100 : public:
1101 : enum class Kind
1102 : {
1103 : MacroRulesDefinition,
1104 : MacroInvocation,
1105 : Module,
1106 : ExternCrate,
1107 : UseDeclaration,
1108 : Function,
1109 : TypeAlias,
1110 : Struct,
1111 : EnumItem,
1112 : Enum,
1113 : Union,
1114 : ConstantItem,
1115 : StaticItem,
1116 : Trait,
1117 : Impl,
1118 : ExternBlock,
1119 : };
1120 :
1121 : virtual Kind get_item_kind () const = 0;
1122 :
1123 : // Unique pointer custom clone function
1124 38353 : std::unique_ptr<Item> clone_item () const
1125 : {
1126 38353 : return std::unique_ptr<Item> (clone_item_impl ());
1127 : }
1128 :
1129 : /* Adds crate names to the vector passed by reference, if it can
1130 : * (polymorphism). TODO: remove, unused. */
1131 : virtual void
1132 0 : add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
1133 0 : {}
1134 :
1135 2782 : Stmt::Kind get_stmt_kind () final { return Stmt::Kind::Item; }
1136 :
1137 : // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
1138 : // behavior that we have items that can also be expressions?
1139 0 : bool is_item () const override { return true; }
1140 :
1141 : virtual std::vector<Attribute> &get_outer_attrs () = 0;
1142 : virtual const std::vector<Attribute> &get_outer_attrs () const = 0;
1143 :
1144 59678 : virtual bool has_outer_attrs () const { return !get_outer_attrs ().empty (); }
1145 :
1146 : protected:
1147 : // Clone function implementation as pure virtual method
1148 : virtual Item *clone_item_impl () const = 0;
1149 :
1150 : /* Save having to specify two clone methods in derived classes by making
1151 : * statement clone return item clone. Hopefully won't affect performance too
1152 : * much. */
1153 1340 : Item *clone_stmt_impl () const final override { return clone_item_impl (); }
1154 : };
1155 :
1156 6702 : class GlobContainer
1157 : {
1158 : public:
1159 : enum class Kind
1160 : {
1161 : Crate,
1162 : Module,
1163 : Enum,
1164 : };
1165 :
1166 : virtual Kind get_glob_container_kind () const = 0;
1167 : };
1168 :
1169 : // Item that supports visibility - abstract base class
1170 : class VisItem : public Item
1171 : {
1172 : Visibility visibility;
1173 : std::vector<Attribute> outer_attrs;
1174 :
1175 : protected:
1176 : // Visibility constructor
1177 40489 : VisItem (Visibility visibility,
1178 : std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
1179 40489 : : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
1180 40489 : {}
1181 :
1182 : // Visibility copy constructor
1183 102175 : VisItem (VisItem const &other)
1184 102175 : : visibility (other.visibility), outer_attrs (other.outer_attrs)
1185 102175 : {}
1186 :
1187 : // Overload assignment operator to clone
1188 0 : VisItem &operator= (VisItem const &other)
1189 : {
1190 0 : visibility = other.visibility;
1191 0 : outer_attrs = other.outer_attrs;
1192 :
1193 0 : return *this;
1194 : }
1195 :
1196 : // move constructors
1197 980 : VisItem (VisItem &&other) = default;
1198 : VisItem &operator= (VisItem &&other) = default;
1199 :
1200 : public:
1201 : /* Does the item have some kind of public visibility (non-default
1202 : * visibility)? */
1203 1247 : bool has_visibility () const { return visibility.is_public (); }
1204 :
1205 : std::string as_string () const override;
1206 :
1207 : // TODO: this mutable getter seems really dodgy. Think up better way.
1208 748866 : Visibility &get_visibility () { return visibility; }
1209 : const Visibility &get_visibility () const { return visibility; }
1210 :
1211 1102673 : std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1212 80589 : const std::vector<Attribute> &get_outer_attrs () const override
1213 : {
1214 80589 : return outer_attrs;
1215 : }
1216 :
1217 : virtual Item::Kind get_item_kind () const override = 0;
1218 : };
1219 :
1220 : // forward decl of ExprWithoutBlock
1221 : class ExprWithoutBlock;
1222 :
1223 : // Base expression AST node - abstract
1224 68407 : class Expr : public Visitable
1225 : {
1226 : public:
1227 : enum class Kind
1228 : {
1229 : PathInExpression,
1230 : QualifiedPathInExpression,
1231 : Literal,
1232 : Operator,
1233 : Grouped,
1234 : Array,
1235 : ArrayIndex,
1236 : Tuple,
1237 : TupleIndex,
1238 : Struct,
1239 : Call,
1240 : MethodCall,
1241 : FieldAccess,
1242 : Closure,
1243 : Block,
1244 : ConstExpr,
1245 : ConstBlock,
1246 : Continue,
1247 : Break,
1248 : Range,
1249 : Box,
1250 : Return,
1251 : UnsafeBlock,
1252 : Loop,
1253 : If,
1254 : IfLet,
1255 : Match,
1256 : Await,
1257 : AsyncBlock,
1258 : InlineAsm,
1259 : LlvmInlineAsm,
1260 : Identifier,
1261 : FormatArgs,
1262 : OffsetOf,
1263 : MacroInvocation,
1264 : Borrow,
1265 : Dereference,
1266 : ErrorPropagation,
1267 : Negation,
1268 : ArithmeticOrLogical,
1269 : Comparison,
1270 : LazyBoolean,
1271 : TypeCast,
1272 : Assignment,
1273 : CompoundAssignment,
1274 : Try,
1275 : };
1276 :
1277 : virtual Kind get_expr_kind () const = 0;
1278 :
1279 : // Unique pointer custom clone function
1280 155 : std::unique_ptr<Expr> clone_expr () const
1281 : {
1282 309160 : return std::unique_ptr<Expr> (clone_expr_impl ());
1283 : }
1284 :
1285 : /* TODO: public methods that could be useful:
1286 : * - get_type() - returns type of expression. set_type() may also be useful
1287 : * for some?
1288 : * - evaluate() - evaluates expression if constant? can_evaluate()? */
1289 :
1290 : virtual std::string as_string () const = 0;
1291 :
1292 2037 : virtual ~Expr () {}
1293 :
1294 : virtual location_t get_locus () const = 0;
1295 :
1296 45 : virtual bool is_literal () const { return false; }
1297 :
1298 : // HACK: strictly not needed, but faster than full downcast clone
1299 : virtual bool is_expr_without_block () const = 0;
1300 :
1301 : virtual void mark_for_strip () = 0;
1302 : virtual bool is_marked_for_strip () const = 0;
1303 :
1304 1562909 : virtual NodeId get_node_id () const { return node_id; }
1305 :
1306 0 : virtual void set_node_id (NodeId id) { node_id = id; }
1307 :
1308 : virtual std::vector<Attribute> &get_outer_attrs () = 0;
1309 :
1310 : // TODO: think of less hacky way to implement this kind of thing
1311 : // Sets outer attributes.
1312 : virtual void set_outer_attrs (std::vector<Attribute>) = 0;
1313 :
1314 : protected:
1315 : // Constructor
1316 296708 : Expr () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1317 :
1318 : // Clone function implementation as pure virtual method
1319 : virtual Expr *clone_expr_impl () const = 0;
1320 :
1321 : NodeId node_id;
1322 : };
1323 :
1324 : // AST node for an expression without an accompanying block - abstract
1325 281273 : class ExprWithoutBlock : public Expr
1326 : {
1327 : protected:
1328 : // pure virtual clone implementation
1329 : virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
1330 :
1331 : /* Save having to specify two clone methods in derived classes by making
1332 : * expr clone return exprwithoutblock clone. Hopefully won't affect
1333 : * performance too much. */
1334 290672 : ExprWithoutBlock *clone_expr_impl () const final override
1335 : {
1336 290672 : return clone_expr_without_block_impl ();
1337 : }
1338 :
1339 46418 : bool is_expr_without_block () const final override { return true; };
1340 :
1341 : public:
1342 : // Unique pointer custom clone function
1343 31 : std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
1344 : {
1345 31 : return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
1346 : }
1347 : };
1348 :
1349 : /* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1350 : * Pratt parser */
1351 : /* Alternatively, identifiers could just be represented as single-segment
1352 : * paths
1353 : */
1354 : class IdentifierExpr : public ExprWithoutBlock
1355 : {
1356 : std::vector<Attribute> outer_attrs;
1357 : Identifier ident;
1358 : location_t locus;
1359 :
1360 : public:
1361 25317 : IdentifierExpr (Identifier ident, std::vector<Attribute> outer_attrs,
1362 : location_t locus)
1363 75951 : : outer_attrs (std::move (outer_attrs)), ident (std::move (ident)),
1364 25317 : locus (locus)
1365 25317 : {}
1366 :
1367 12 : std::string as_string () const override { return ident.as_string (); }
1368 :
1369 87982 : location_t get_locus () const override final { return locus; }
1370 :
1371 50698 : Identifier get_ident () const { return ident; }
1372 :
1373 : void accept_vis (ASTVisitor &vis) override;
1374 :
1375 : // Clones this object.
1376 : std::unique_ptr<IdentifierExpr> clone_identifier_expr () const
1377 : {
1378 : return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
1379 : }
1380 :
1381 : // "Error state" if ident is empty, so base stripping on this.
1382 0 : void mark_for_strip () override { ident = {""}; }
1383 168400 : bool is_marked_for_strip () const override { return ident.empty (); }
1384 :
1385 : const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
1386 977222 : std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1387 :
1388 0 : void set_outer_attrs (std::vector<Attribute> new_attrs) override
1389 : {
1390 0 : outer_attrs = std::move (new_attrs);
1391 0 : }
1392 :
1393 24414 : Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
1394 :
1395 : protected:
1396 : // Clone method implementation
1397 58254 : IdentifierExpr *clone_expr_without_block_impl () const final override
1398 : {
1399 58254 : return clone_identifier_expr_impl ();
1400 : }
1401 :
1402 58254 : IdentifierExpr *clone_identifier_expr_impl () const
1403 : {
1404 58254 : return new IdentifierExpr (*this);
1405 : }
1406 : };
1407 :
1408 : // Pattern base AST node
1409 122084 : class Pattern : public Visitable
1410 : {
1411 : public:
1412 : enum class Kind
1413 : {
1414 : Literal,
1415 : Identifier,
1416 : Wildcard,
1417 : Rest,
1418 : Range,
1419 : Reference,
1420 : Struct,
1421 : TupleStruct,
1422 : Tuple,
1423 : Grouped,
1424 : Slice,
1425 : Alt,
1426 : Path,
1427 : MacroInvocation,
1428 : };
1429 :
1430 : // Unique pointer custom clone function
1431 64137 : std::unique_ptr<Pattern> clone_pattern () const
1432 : {
1433 64137 : return std::unique_ptr<Pattern> (clone_pattern_impl ());
1434 : }
1435 :
1436 : virtual Kind get_pattern_kind () = 0;
1437 :
1438 : // possible virtual methods: is_refutable()
1439 :
1440 : virtual ~Pattern () {}
1441 :
1442 : virtual std::string as_string () const = 0;
1443 :
1444 : // as only one kind of pattern can be stripped, have default of nothing
1445 0 : virtual void mark_for_strip () {}
1446 140936 : virtual bool is_marked_for_strip () const { return false; }
1447 :
1448 : virtual location_t get_locus () const = 0;
1449 : virtual NodeId get_node_id () const = 0;
1450 :
1451 : protected:
1452 : // Clone pattern implementation as pure virtual method
1453 : virtual Pattern *clone_pattern_impl () const = 0;
1454 : };
1455 :
1456 : // forward decl for Type
1457 : class TraitBound;
1458 :
1459 : // Base class for types as represented in AST - abstract
1460 225738 : class Type : public Visitable
1461 : {
1462 : public:
1463 : enum Kind
1464 : {
1465 : MacroInvocation,
1466 : TypePath,
1467 : QualifiedPathInType,
1468 : ImplTrait,
1469 : TraitObject,
1470 : Parenthesised,
1471 : ImplTraitTypeOneBound,
1472 : TraitObjectTypeOneBound,
1473 : Tuple,
1474 : Never,
1475 : RawPointer,
1476 : Reference,
1477 : Array,
1478 : Slice,
1479 : Inferred,
1480 : BareFunction,
1481 : };
1482 :
1483 : virtual Kind get_type_kind () const = 0;
1484 :
1485 : // Unique pointer custom clone function
1486 128619 : std::unique_ptr<Type> clone_type () const
1487 : {
1488 128619 : return std::unique_ptr<Type> (clone_type_impl ());
1489 : }
1490 :
1491 : // Similar to `clone_type`, but generates a new instance of the node with a
1492 : // different NodeId
1493 95 : std::unique_ptr<Type> reconstruct () const { return reconstruct_base (this); }
1494 :
1495 : // virtual destructor
1496 70534 : virtual ~Type () {}
1497 :
1498 : virtual std::string as_string () const = 0;
1499 :
1500 : /* HACK: convert to trait bound. Virtual method overriden by classes that
1501 : * enable this. */
1502 4 : virtual TraitBound *to_trait_bound (bool) const { return nullptr; }
1503 : /* as pointer, shouldn't require definition beforehand, only forward
1504 : * declaration. */
1505 :
1506 : // as only two kinds of types can be stripped, have default of nothing
1507 0 : virtual void mark_for_strip () {}
1508 76837 : virtual bool is_marked_for_strip () const { return false; }
1509 :
1510 : virtual location_t get_locus () const = 0;
1511 :
1512 : // TODO: put this in a virtual base class?
1513 47949 : virtual NodeId get_node_id () const { return node_id; }
1514 : virtual Type *reconstruct_impl () const = 0;
1515 :
1516 : protected:
1517 118947 : Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1518 24 : Type (NodeId node_id) : node_id (node_id) {}
1519 :
1520 : // Clone and reconstruct function implementations as pure virtual methods
1521 : virtual Type *clone_type_impl () const = 0;
1522 :
1523 : NodeId node_id;
1524 : };
1525 :
1526 : // A type without parentheses? - abstract
1527 286949 : class TypeNoBounds : public Type
1528 : {
1529 : public:
1530 : // Unique pointer custom clone function
1531 34744 : std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
1532 : {
1533 34744 : return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
1534 : }
1535 :
1536 0 : std::unique_ptr<TypeNoBounds> reconstruct () const
1537 : {
1538 0 : return reconstruct_base (this);
1539 : }
1540 :
1541 : virtual TypeNoBounds *reconstruct_impl () const override = 0;
1542 :
1543 : protected:
1544 : // Clone function implementation as pure virtual method
1545 : virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
1546 :
1547 : /* Save having to specify two clone methods in derived classes by making
1548 : * type clone return typenobounds clone. Hopefully won't affect performance
1549 : * too much. */
1550 128595 : TypeNoBounds *clone_type_impl () const final override
1551 : {
1552 128595 : return clone_type_no_bounds_impl ();
1553 : }
1554 :
1555 118933 : TypeNoBounds () : Type () {}
1556 : };
1557 :
1558 : /* Abstract base class representing a type param bound - Lifetime and
1559 : * TraitBound extends it */
1560 : class TypeParamBound : public Visitable
1561 : {
1562 : public:
1563 : enum TypeParamBoundType
1564 : {
1565 : TRAIT,
1566 : LIFETIME
1567 : };
1568 :
1569 10811 : virtual ~TypeParamBound () {}
1570 :
1571 : // Unique pointer custom clone function
1572 4973 : std::unique_ptr<TypeParamBound> clone_type_param_bound () const
1573 : {
1574 4973 : return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
1575 : }
1576 :
1577 0 : std::unique_ptr<TypeParamBound> reconstruct () const
1578 : {
1579 0 : return reconstruct_base (this);
1580 : }
1581 :
1582 : virtual std::string as_string () const = 0;
1583 :
1584 11435 : NodeId get_node_id () const { return node_id; }
1585 :
1586 : virtual location_t get_locus () const = 0;
1587 :
1588 : virtual TypeParamBoundType get_bound_type () const = 0;
1589 :
1590 : virtual TypeParamBound *reconstruct_impl () const = 0;
1591 :
1592 : protected:
1593 : // Clone function implementation as pure virtual method
1594 : virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
1595 :
1596 : TypeParamBound () : node_id (Analysis::Mappings::get ().get_next_node_id ())
1597 : {}
1598 659 : TypeParamBound (NodeId node_id) : node_id (node_id) {}
1599 :
1600 : NodeId node_id;
1601 : };
1602 :
1603 : // Represents a lifetime (and is also a kind of type param bound)
1604 34923 : class Lifetime : public TypeParamBound
1605 : {
1606 : public:
1607 : enum LifetimeType
1608 : {
1609 : NAMED, // corresponds to LIFETIME_OR_LABEL
1610 : STATIC, // corresponds to 'static
1611 : WILDCARD // corresponds to '_
1612 : };
1613 :
1614 : private:
1615 : LifetimeType lifetime_type;
1616 : std::string lifetime_name;
1617 : location_t locus;
1618 : NodeId node_id;
1619 :
1620 : public:
1621 : // Constructor
1622 23993 : Lifetime (LifetimeType type, std::string name = std::string (),
1623 : location_t locus = UNDEF_LOCATION)
1624 23993 : : TypeParamBound (Analysis::Mappings::get ().get_next_node_id ()),
1625 23993 : lifetime_type (type), lifetime_name (std::move (name)), locus (locus)
1626 23993 : {}
1627 :
1628 24 : Lifetime (NodeId id, LifetimeType type, std::string name = std::string (),
1629 : location_t locus = UNDEF_LOCATION)
1630 24 : : TypeParamBound (id), lifetime_type (type),
1631 48 : lifetime_name (std::move (name)), locus (locus)
1632 : {}
1633 :
1634 23118 : static Lifetime elided () { return Lifetime (WILDCARD, ""); }
1635 :
1636 : // Returns true if the lifetime is in an error state.
1637 : std::string as_string () const override;
1638 :
1639 : void accept_vis (ASTVisitor &vis) override;
1640 :
1641 10399 : LifetimeType get_lifetime_type () const { return lifetime_type; }
1642 :
1643 10477 : location_t get_locus () const override final { return locus; }
1644 :
1645 30373 : std::string get_lifetime_name () const { return lifetime_name; }
1646 :
1647 0 : TypeParamBoundType get_bound_type () const override
1648 : {
1649 0 : return TypeParamBound::TypeParamBoundType::LIFETIME;
1650 : }
1651 :
1652 : protected:
1653 : /* Use covariance to implement clone function as returning this object
1654 : * rather than base */
1655 24 : Lifetime *clone_type_param_bound_impl () const override
1656 : {
1657 48 : return new Lifetime (node_id, lifetime_type, lifetime_name, locus);
1658 : }
1659 0 : Lifetime *reconstruct_impl () const override
1660 : {
1661 0 : return new Lifetime (lifetime_type, lifetime_name, locus);
1662 : }
1663 : };
1664 :
1665 : /* Base generic parameter in AST. Abstract - can be represented by a Lifetime
1666 : * or Type param */
1667 : class GenericParam : public Visitable
1668 : {
1669 : public:
1670 : enum class Kind
1671 : {
1672 : Lifetime,
1673 : Type,
1674 : Const,
1675 : };
1676 :
1677 : virtual ~GenericParam () {}
1678 :
1679 : // Unique pointer custom clone function
1680 11328 : std::unique_ptr<GenericParam> clone_generic_param () const
1681 : {
1682 11328 : return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
1683 : }
1684 :
1685 : virtual std::string as_string () const = 0;
1686 :
1687 : virtual location_t get_locus () const = 0;
1688 :
1689 : virtual Kind get_kind () const = 0;
1690 :
1691 98657 : NodeId get_node_id () const { return node_id; }
1692 :
1693 : protected:
1694 582 : GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1695 27997 : GenericParam (NodeId node_id) : node_id (node_id) {}
1696 :
1697 : // Clone function implementation as pure virtual method
1698 : virtual GenericParam *clone_generic_param_impl () const = 0;
1699 :
1700 : NodeId node_id;
1701 : };
1702 :
1703 : // A lifetime generic parameter (as opposed to a type generic parameter)
1704 : class LifetimeParam : public GenericParam
1705 : {
1706 : Lifetime lifetime;
1707 : std::vector<Lifetime> lifetime_bounds;
1708 : AST::AttrVec outer_attrs;
1709 : location_t locus;
1710 :
1711 : public:
1712 0 : Lifetime get_lifetime () const { return lifetime; }
1713 :
1714 3915 : Lifetime &get_lifetime () { return lifetime; }
1715 :
1716 5033 : AST::AttrVec &get_outer_attrs () { return outer_attrs; }
1717 :
1718 : // Returns whether the lifetime param has any lifetime bounds.
1719 21 : bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
1720 :
1721 3687 : std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
1722 :
1723 : const std::vector<Lifetime> &get_lifetime_bounds () const
1724 : {
1725 0 : return lifetime_bounds;
1726 : }
1727 :
1728 : // Returns whether the lifetime param has an outer attribute.
1729 0 : bool has_outer_attribute () const { return !outer_attrs.empty (); }
1730 :
1731 : // Constructor
1732 281 : LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
1733 : AST::AttrVec outer_attrs, location_t locus)
1734 562 : : lifetime (std::move (lifetime)),
1735 281 : lifetime_bounds (std::move (lifetime_bounds)),
1736 281 : outer_attrs (std::move (outer_attrs)), locus (locus)
1737 281 : {}
1738 :
1739 : std::string as_string () const override;
1740 :
1741 : void accept_vis (ASTVisitor &vis) override;
1742 :
1743 414 : location_t get_locus () const override final { return locus; }
1744 :
1745 757 : Kind get_kind () const override final { return Kind::Lifetime; }
1746 :
1747 : protected:
1748 : /* Use covariance to implement clone function as returning this object
1749 : * rather than base */
1750 817 : LifetimeParam *clone_generic_param_impl () const override
1751 : {
1752 817 : return new LifetimeParam (*this);
1753 : }
1754 : };
1755 :
1756 53172 : class AssociatedItem : public Visitable
1757 : {
1758 : protected:
1759 : // Clone function implementation as pure virtual method
1760 : virtual AssociatedItem *clone_associated_item_impl () const = 0;
1761 :
1762 : public:
1763 : virtual ~AssociatedItem () {}
1764 :
1765 37865 : std::unique_ptr<AssociatedItem> clone_associated_item () const
1766 : {
1767 37865 : return std::unique_ptr<AssociatedItem> (clone_associated_item_impl ());
1768 : }
1769 :
1770 : virtual std::string as_string () const = 0;
1771 :
1772 : virtual void mark_for_strip () = 0;
1773 : virtual bool is_marked_for_strip () const = 0;
1774 :
1775 : virtual location_t get_locus () const = 0;
1776 :
1777 : virtual NodeId get_node_id () const = 0;
1778 : };
1779 :
1780 : // Item used in trait declarations - abstract base class
1781 : class TraitItem : public AssociatedItem
1782 : {
1783 : protected:
1784 16691 : TraitItem (location_t locus)
1785 16691 : : node_id (Analysis::Mappings::get ().get_next_node_id ()),
1786 33382 : vis (Visibility::create_private ()), locus (locus)
1787 16691 : {}
1788 :
1789 748 : TraitItem (Visibility vis, location_t locus)
1790 748 : : node_id (Analysis::Mappings::get ().get_next_node_id ()), vis (vis),
1791 748 : locus (locus)
1792 748 : {}
1793 :
1794 : // Clone function implementation as pure virtual method
1795 : virtual TraitItem *clone_associated_item_impl () const override = 0;
1796 :
1797 : NodeId node_id;
1798 : Visibility vis;
1799 : location_t locus;
1800 :
1801 : public:
1802 : // Unique pointer custom clone function
1803 : std::unique_ptr<TraitItem> clone_trait_item () const
1804 : {
1805 : return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
1806 : }
1807 :
1808 5307 : NodeId get_node_id () const override { return node_id; }
1809 3776 : location_t get_locus () const override { return locus; }
1810 : };
1811 :
1812 : // Abstract base class for an item used inside an extern block
1813 : class ExternalItem : public Visitable
1814 : {
1815 : public:
1816 4 : ExternalItem () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1817 :
1818 78198 : ExternalItem (NodeId node_id) : node_id (node_id) {}
1819 :
1820 : virtual ~ExternalItem () {}
1821 :
1822 : // Unique pointer custom clone function
1823 5707 : std::unique_ptr<ExternalItem> clone_external_item () const
1824 : {
1825 5707 : return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
1826 : }
1827 :
1828 : virtual std::string as_string () const = 0;
1829 :
1830 : virtual void mark_for_strip () = 0;
1831 : virtual bool is_marked_for_strip () const = 0;
1832 :
1833 3025 : virtual NodeId get_node_id () const { return node_id; }
1834 :
1835 : protected:
1836 : // Clone function implementation as pure virtual method
1837 : virtual ExternalItem *clone_external_item_impl () const = 0;
1838 :
1839 : NodeId node_id;
1840 : };
1841 :
1842 : /* Data structure to store the data used in macro invocations and macro
1843 : * invocations with semicolons. */
1844 : struct MacroInvocData
1845 : {
1846 : private:
1847 : SimplePath path;
1848 : DelimTokenTree token_tree;
1849 :
1850 : // One way of parsing the macro. Probably not applicable for all macros.
1851 : std::vector<std::unique_ptr<MetaItemInner>> parsed_items;
1852 : bool parsed_to_meta_item = false;
1853 : MacroExpander *expander = nullptr;
1854 :
1855 : public:
1856 : std::string as_string () const;
1857 :
1858 3021 : MacroInvocData (SimplePath path, DelimTokenTree token_tree)
1859 3021 : : path (std::move (path)), token_tree (std::move (token_tree))
1860 3021 : {}
1861 :
1862 : // Copy constructor with vector clone
1863 15003 : MacroInvocData (const MacroInvocData &other)
1864 15003 : : path (other.path), token_tree (other.token_tree),
1865 15003 : parsed_to_meta_item (other.parsed_to_meta_item)
1866 : {
1867 15003 : parsed_items.reserve (other.parsed_items.size ());
1868 15003 : for (const auto &e : other.parsed_items)
1869 0 : parsed_items.push_back (e->clone_meta_item_inner ());
1870 15003 : }
1871 :
1872 : // Copy assignment operator with vector clone
1873 : MacroInvocData &operator= (const MacroInvocData &other)
1874 : {
1875 : path = other.path;
1876 : token_tree = other.token_tree;
1877 : parsed_to_meta_item = other.parsed_to_meta_item;
1878 : expander = other.expander;
1879 :
1880 : parsed_items.reserve (other.parsed_items.size ());
1881 : for (const auto &e : other.parsed_items)
1882 : parsed_items.push_back (e->clone_meta_item_inner ());
1883 :
1884 : return *this;
1885 : }
1886 :
1887 : // Move constructors
1888 3405 : MacroInvocData (MacroInvocData &&other) = default;
1889 : MacroInvocData &operator= (MacroInvocData &&other) = default;
1890 :
1891 : // Invalid if path is empty, so base stripping on that.
1892 0 : void mark_for_strip () { path = SimplePath::create_empty (); }
1893 6373 : bool is_marked_for_strip () const { return path.is_empty (); }
1894 :
1895 : // Returns whether the macro has been parsed already.
1896 47 : bool is_parsed () const { return parsed_to_meta_item; }
1897 : // TODO: update on other ways of parsing it
1898 :
1899 : // TODO: this mutable getter seems kinda dodgy
1900 9909 : DelimTokenTree &get_delim_tok_tree () { return token_tree; }
1901 : const DelimTokenTree &get_delim_tok_tree () const { return token_tree; }
1902 :
1903 : // Set the delim token tree of a macro invocation
1904 45 : void set_delim_tok_tree (DelimTokenTree tree) { token_tree = tree; }
1905 :
1906 : // TODO: this mutable getter seems kinda dodgy
1907 9945 : SimplePath &get_path () { return path; }
1908 : const SimplePath &get_path () const { return path; }
1909 :
1910 2852 : void set_expander (MacroExpander *new_expander) { expander = new_expander; }
1911 223 : MacroExpander *get_expander ()
1912 : {
1913 223 : rust_assert (expander);
1914 223 : return expander;
1915 : }
1916 :
1917 : void
1918 47 : set_meta_item_output (std::vector<std::unique_ptr<MetaItemInner>> new_items)
1919 : {
1920 47 : parsed_items = std::move (new_items);
1921 : }
1922 : std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
1923 : {
1924 : return parsed_items;
1925 : }
1926 : const std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items () const
1927 : {
1928 : return parsed_items;
1929 : }
1930 : };
1931 :
1932 : class SingleASTNode : public Visitable
1933 : {
1934 : public:
1935 : enum class Kind
1936 : {
1937 : Expr,
1938 : Item,
1939 : Stmt,
1940 : Extern,
1941 : Assoc,
1942 : Type,
1943 : Pattern,
1944 : };
1945 :
1946 : private:
1947 : Kind kind;
1948 :
1949 : // FIXME make this a union
1950 : std::unique_ptr<Expr> expr;
1951 : std::unique_ptr<Item> item;
1952 : std::unique_ptr<Stmt> stmt;
1953 : std::unique_ptr<ExternalItem> external_item;
1954 : std::unique_ptr<AssociatedItem> assoc_item;
1955 : std::unique_ptr<Type> type;
1956 : std::unique_ptr<Pattern> pattern;
1957 :
1958 : public:
1959 1971 : SingleASTNode (std::unique_ptr<Expr> expr)
1960 1971 : : kind (Kind::Expr), expr (std::move (expr))
1961 : {}
1962 :
1963 2593 : SingleASTNode (std::unique_ptr<Item> item)
1964 2593 : : kind (Kind::Item), item (std::move (item))
1965 : {}
1966 :
1967 469 : SingleASTNode (std::unique_ptr<Stmt> stmt)
1968 469 : : kind (Kind::Stmt), stmt (std::move (stmt))
1969 : {}
1970 :
1971 3 : SingleASTNode (std::unique_ptr<ExternalItem> item)
1972 3 : : kind (Kind::Extern), external_item (std::move (item))
1973 : {}
1974 :
1975 107 : SingleASTNode (std::unique_ptr<AssociatedItem> item)
1976 107 : : kind (Kind::Assoc), assoc_item (std::move (item))
1977 : {}
1978 :
1979 29 : SingleASTNode (std::unique_ptr<Type> type)
1980 29 : : kind (Kind::Type), type (std::move (type))
1981 : {}
1982 :
1983 1 : SingleASTNode (std::unique_ptr<Pattern> pattern)
1984 1 : : kind (Kind::Pattern), pattern (std::move (pattern))
1985 : {}
1986 :
1987 : SingleASTNode (SingleASTNode const &other);
1988 :
1989 : SingleASTNode operator= (SingleASTNode const &other);
1990 :
1991 6102 : SingleASTNode (SingleASTNode &&other) = default;
1992 : SingleASTNode &operator= (SingleASTNode &&other) = default;
1993 :
1994 3860 : Kind get_kind () const { return kind; }
1995 :
1996 : std::unique_ptr<Expr> &get_expr ()
1997 : {
1998 : rust_assert (kind == Kind::Expr);
1999 : return expr;
2000 : }
2001 :
2002 0 : std::unique_ptr<Item> &get_item ()
2003 : {
2004 0 : rust_assert (kind == Kind::Item);
2005 0 : return item;
2006 : }
2007 :
2008 : std::unique_ptr<Stmt> &get_stmt ()
2009 : {
2010 : rust_assert (kind == Kind::Stmt);
2011 : return stmt;
2012 : }
2013 :
2014 : /**
2015 : * Access the inner nodes and take ownership of them.
2016 : * You can only call these functions once per node
2017 : */
2018 :
2019 482 : std::unique_ptr<Stmt> take_stmt ()
2020 : {
2021 482 : rust_assert (!is_error ());
2022 482 : return std::move (stmt);
2023 : }
2024 :
2025 1900 : std::unique_ptr<Expr> take_expr ()
2026 : {
2027 1900 : rust_assert (!is_error ());
2028 1900 : return std::move (expr);
2029 : }
2030 :
2031 2592 : std::unique_ptr<Item> take_item ()
2032 : {
2033 2592 : rust_assert (!is_error ());
2034 2592 : return std::move (item);
2035 : }
2036 :
2037 3 : std::unique_ptr<ExternalItem> take_external_item ()
2038 : {
2039 3 : rust_assert (!is_error ());
2040 3 : return std::move (external_item);
2041 : }
2042 :
2043 107 : std::unique_ptr<AssociatedItem> take_assoc_item ()
2044 : {
2045 107 : rust_assert (!is_error ());
2046 107 : return std::move (assoc_item);
2047 : }
2048 :
2049 29 : std::unique_ptr<Type> take_type ()
2050 : {
2051 29 : rust_assert (!is_error ());
2052 29 : return std::move (type);
2053 : }
2054 :
2055 1 : std::unique_ptr<Pattern> take_pattern ()
2056 : {
2057 1 : rust_assert (!is_error ());
2058 1 : return std::move (pattern);
2059 : }
2060 :
2061 : void accept_vis (ASTVisitor &vis) override;
2062 :
2063 : bool is_error ();
2064 :
2065 : std::string as_string () const;
2066 : };
2067 :
2068 : // A crate AST object - holds all the data for a single compilation unit
2069 : struct Crate final : public GlobContainer
2070 : {
2071 : std::vector<Attribute> inner_attrs;
2072 : // dodgy spacing required here
2073 : /* TODO: is it better to have a vector of items here or a module (implicit
2074 : * top-level one)? */
2075 : std::vector<std::unique_ptr<Item>> items;
2076 :
2077 : NodeId node_id;
2078 :
2079 : public:
2080 : // Constructor
2081 4840 : Crate (std::vector<std::unique_ptr<Item>> items,
2082 : std::vector<Attribute> inner_attrs)
2083 4840 : : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
2084 4840 : node_id (Analysis::Mappings::get ().get_next_node_id ())
2085 4840 : {}
2086 :
2087 : // Copy constructor with vector clone
2088 4685 : Crate (Crate const &other)
2089 4685 : : inner_attrs (other.inner_attrs), node_id (other.node_id)
2090 : {
2091 4685 : items.reserve (other.items.size ());
2092 23806 : for (const auto &e : other.items)
2093 19121 : items.push_back (e->clone_item ());
2094 4685 : }
2095 :
2096 4791 : ~Crate () = default;
2097 :
2098 : // Overloaded assignment operator with vector clone
2099 : Crate &operator= (Crate const &other)
2100 : {
2101 : inner_attrs = other.inner_attrs;
2102 : node_id = other.node_id;
2103 :
2104 : items.reserve (other.items.size ());
2105 : for (const auto &e : other.items)
2106 : items.push_back (e->clone_item ());
2107 :
2108 : return *this;
2109 : }
2110 :
2111 : // Move constructors
2112 : Crate (Crate &&other) = default;
2113 : Crate &operator= (Crate &&other) = default;
2114 :
2115 : // Get crate representation as string (e.g. for debugging).
2116 : std::string as_string () const;
2117 :
2118 : // Delete all crate information, e.g. if fails cfg.
2119 1 : void strip_crate ()
2120 : {
2121 1 : inner_attrs.clear ();
2122 1 : inner_attrs.shrink_to_fit ();
2123 :
2124 1 : items.clear ();
2125 1 : items.shrink_to_fit ();
2126 : // TODO: is this the best way to do this?
2127 1 : }
2128 :
2129 : void inject_extern_crate (std::string name);
2130 : void inject_inner_attribute (Attribute attribute);
2131 :
2132 115010 : NodeId get_node_id () const { return node_id; }
2133 : const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
2134 103672 : std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
2135 :
2136 : std::vector<std::unique_ptr<AST::Item>> take_items ()
2137 : {
2138 : return std::move (items);
2139 : }
2140 :
2141 : void set_items (std::vector<std::unique_ptr<AST::Item>> &&new_items)
2142 : {
2143 : items = std::move (new_items);
2144 : }
2145 :
2146 4685 : GlobContainer::Kind get_glob_container_kind () const override
2147 : {
2148 4685 : return GlobContainer::Kind::Crate;
2149 : }
2150 : };
2151 :
2152 : } // namespace AST
2153 :
2154 : template <> struct CloneableDelegate<std::unique_ptr<AST::Pattern>>
2155 : {
2156 : static std::unique_ptr<AST::Pattern>
2157 60727 : clone (const std::unique_ptr<AST::Pattern> &other)
2158 : {
2159 60727 : if (other == nullptr)
2160 53431 : return nullptr;
2161 : else
2162 7296 : return other->clone_pattern ();
2163 : }
2164 : };
2165 :
2166 : } // namespace Rust
2167 :
2168 : namespace std {
2169 : template <> struct less<Rust::Identifier>
2170 : {
2171 : bool operator() (const Rust::Identifier &lhs,
2172 : const Rust::Identifier &rhs) const
2173 : {
2174 : return lhs.as_string () < rhs.as_string ();
2175 : }
2176 : };
2177 :
2178 : template <> struct hash<Rust::Identifier>
2179 : {
2180 : std::size_t operator() (const Rust::Identifier &k) const
2181 : {
2182 : using std::hash;
2183 : using std::size_t;
2184 : using std::string;
2185 :
2186 : return hash<string> () (k.as_string ()) ^ (hash<int> () (k.get_locus ()));
2187 : }
2188 : };
2189 :
2190 : } // namespace std
2191 :
2192 : #endif
|