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