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