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 4595019 : class Visitable
44 : {
45 : public:
46 2638570 : 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 199 : reconstruct_base (const T *instance)
58 : {
59 199 : auto *reconstructed = instance->reconstruct_impl ();
60 :
61 199 : rust_assert (reconstructed->get_node_id () != instance->get_node_id ());
62 :
63 199 : 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 187 : reconstruct_vec (const std::vector<std::unique_ptr<T>> &to_reconstruct)
72 : {
73 187 : std::vector<std::unique_ptr<T>> reconstructed;
74 187 : reconstructed.reserve (to_reconstruct.size ());
75 :
76 365 : for (const auto &elt : to_reconstruct)
77 178 : reconstructed.emplace_back (std::unique_ptr<T> (elt->reconstruct_impl ()));
78 :
79 187 : 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 4963857 : class TokenTree : public Visitable
95 : {
96 : public:
97 414620 : virtual ~TokenTree () {}
98 :
99 : // Unique pointer custom clone function
100 9020078 : std::unique_ptr<TokenTree> clone_token_tree () const
101 : {
102 9020078 : 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 2195660 : class MacroMatch : public Visitable
118 : {
119 : public:
120 : enum MacroMatchType
121 : {
122 : Fragment,
123 : Repetition,
124 : Matcher,
125 : Tok
126 : };
127 :
128 2047 : 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 16004 : std::unique_ptr<MacroMatch> clone_macro_match () const
135 : {
136 16004 : 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 12763045 : std::unique_ptr<Token> clone_token () const
161 : {
162 12763045 : return std::unique_ptr<Token> (clone_token_impl ());
163 : }
164 :
165 : // Constructor from lexer const_TokenPtr
166 3227003 : Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
167 :
168 12996518 : bool is_string_lit () const
169 : {
170 12996518 : 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 10224458 : default:
178 10224458 : return false;
179 : }
180 : }
181 :
182 : std::string as_string () const override;
183 1174 : location_t get_match_locus () const override
184 : {
185 1174 : 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 16280492 : TokenId get_id () const { return tok_ref->get_id (); }
194 17 : bool should_have_str () const { return tok_ref->should_have_str (); }
195 720511 : const std::string &get_str () const { return tok_ref->get_str (); }
196 :
197 74983 : location_t get_locus () const { return tok_ref->get_locus (); }
198 :
199 351 : PrimitiveCoreType get_type_hint () const { return tok_ref->get_type_hint (); }
200 :
201 : // Get a new token pointer copy.
202 6425594 : const_TokenPtr get_tok_ptr () const { return tok_ref; }
203 :
204 138231 : MacroMatchType get_macro_match_type () const override
205 : {
206 138231 : return MacroMatchType::Tok;
207 : }
208 :
209 : protected:
210 : // No virtual for now as not polymorphic but can be in future
211 25138015 : /*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 8772233 : Token *clone_token_tree_impl () const final override
216 : {
217 8772233 : 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 53237 : 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 41645298 : std::string as_string () const { return value_as_string; }
255 :
256 62816 : LitType get_lit_type () const { return type; }
257 :
258 38155 : PrimitiveCoreType get_type_hint () const { return type_hint; }
259 :
260 499719 : Literal (std::string value_as_string, LitType type,
261 : PrimitiveCoreType type_hint)
262 499719 : : value_as_string (std::move (value_as_string)), type (type),
263 499719 : 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 17121771 : 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 438019 : class PathSegment
282 : {
283 : public:
284 72332 : 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 382997 : 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 181419 : SimplePathSegment (std::string segment_name, location_t locus)
302 362838 : : segment_name (std::move (segment_name)), locus (locus),
303 181419 : node_id (Analysis::Mappings::get ().get_next_node_id ())
304 181419 : {}
305 :
306 : /* Returns whether simple path segment is in an invalid state (currently, if
307 : * empty). */
308 24395094 : 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 264491 : location_t get_locus () const { return locus; }
319 159981 : NodeId get_node_id () const { return node_id; }
320 3850131 : const std::string &get_segment_name () const { return segment_name; }
321 28920 : bool is_super_path_seg () const
322 : {
323 28920 : return as_string ().compare (Values::Keywords::SUPER) == 0;
324 : }
325 29317 : bool is_crate_path_seg () const
326 : {
327 29317 : return as_string ().compare (Values::Keywords::CRATE) == 0;
328 : }
329 90627 : bool is_lower_self_seg () const
330 : {
331 90627 : return as_string ().compare (Values::Keywords::SELF) == 0;
332 : }
333 28462 : bool is_big_self () const
334 : {
335 28462 : return as_string ().compare (Values::Keywords::SELF_ALIAS) == 0;
336 : }
337 : };
338 :
339 : // A simple path without generic or type arguments
340 4351860 : 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 671012 : explicit SimplePath (std::vector<SimplePathSegment> path_segments,
350 : bool has_opening_scope_resolution = false,
351 : location_t locus = UNDEF_LOCATION)
352 671012 : : opening_scope_resolution (has_opening_scope_resolution),
353 671012 : segments (std::move (path_segments)), locus (locus),
354 671012 : node_id (Analysis::Mappings::get ().get_next_node_id ())
355 671012 : {}
356 :
357 292 : explicit SimplePath (Identifier ident)
358 292 : : opening_scope_resolution (false),
359 1168 : segments ({SimplePathSegment (ident.as_string (), ident.get_locus ())}),
360 292 : locus (ident.get_locus ()),
361 292 : node_id (Analysis::Mappings::get ().get_next_node_id ())
362 292 : {}
363 :
364 : // Creates an empty SimplePath.
365 493118 : static SimplePath create_empty ()
366 : {
367 493118 : return SimplePath (std::vector<SimplePathSegment> ());
368 : }
369 :
370 : // Returns whether the SimplePath is empty, i.e. has path segments.
371 187461 : bool is_empty () const { return segments.empty (); }
372 :
373 : const std::string as_string () const;
374 :
375 92412 : bool has_opening_scope_resolution () const
376 : {
377 43963 : return opening_scope_resolution;
378 : }
379 :
380 63730 : location_t get_locus () const { return locus; }
381 447 : 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 15080673 : bool operator== (const std::string &rhs) const
387 : {
388 15080673 : return !opening_scope_resolution && segments.size () == 1
389 30158817 : && 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 1428 : static SimplePath from_str (std::string str, location_t locus)
397 : {
398 1428 : std::vector<AST::SimplePathSegment> single_segments
399 2856 : = {AST::SimplePathSegment (std::move (str), locus)};
400 1428 : return SimplePath (std::move (single_segments), false, locus);
401 1428 : }
402 :
403 129649 : const std::vector<SimplePathSegment> &get_segments () const
404 : {
405 136824 : return segments;
406 : }
407 :
408 20081582 : std::vector<SimplePathSegment> &get_segments () { return segments; }
409 :
410 204963 : const SimplePathSegment &get_final_segment () const
411 : {
412 204963 : return segments.back ();
413 : }
414 : };
415 :
416 : // path-to-string inverse comparison operator
417 : inline bool
418 12636 : operator!= (const SimplePath &lhs, const std::string &rhs)
419 : {
420 12636 : 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 452468 : 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 475136 : Visibility (VisType vis_type, SimplePath in_path, location_t locus)
447 340952 : : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
448 : {}
449 :
450 : public:
451 66068 : VisType get_vis_type () const { return vis_type; }
452 :
453 : // Returns whether a visibility has a path
454 5930051 : bool has_path () const { return vis_type >= PUB_CRATE; }
455 :
456 : // Returns whether visibility is public or not.
457 4477 : bool is_public () const { return vis_type != PRIV; }
458 :
459 8301 : 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 14565 : static Visibility create_public (location_t pub_vis_location)
472 : {
473 14565 : return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
474 : }
475 :
476 : // Creates a public visibility with crate-relative paths
477 266 : static Visibility create_crate (location_t crate_tok_location,
478 : location_t crate_vis_location)
479 : {
480 266 : return Visibility (PUB_CRATE,
481 266 : SimplePath::from_str (Values::Keywords::CRATE,
482 : crate_tok_location),
483 266 : 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 96 : static Visibility create_super (location_t super_tok_location,
498 : location_t super_vis_location)
499 : {
500 96 : return Visibility (PUB_SUPER,
501 96 : SimplePath::from_str (Values::Keywords::SUPER,
502 : super_tok_location),
503 96 : super_vis_location);
504 : }
505 :
506 : // Creates a private visibility
507 460189 : static Visibility create_private ()
508 : {
509 460189 : 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 63 : const SimplePath &get_path () const { return in_path; }
521 63844 : 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 20933212 : bool has_attr_input () const { return attr_input != nullptr; }
552 :
553 : // Constructor has pointer AttrInput for polymorphism reasons
554 117273 : Attribute (SimplePath path, std::unique_ptr<AttrInput> input,
555 : location_t locus = UNDEF_LOCATION, bool inner_attribute = false)
556 117273 : : path (std::move (path)), attr_input (std::move (input)), locus (locus),
557 117273 : inner_attribute (inner_attribute),
558 117273 : node_id (Analysis::Mappings::get ().get_next_node_id ())
559 117273 : {}
560 :
561 : bool is_derive () const;
562 :
563 : std::vector<std::reference_wrapper<AST::SimplePath>> get_traits_to_derive ();
564 :
565 : // default destructor
566 1880315 : ~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 331729 : Attribute (Attribute &&other) = default;
576 2095 : 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 9588 : static Attribute create_empty ()
586 : {
587 9588 : return Attribute (SimplePath::create_empty (), nullptr);
588 : }
589 :
590 : // Returns whether the attribute is considered an "empty" attribute.
591 3252 : bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
592 :
593 : // Returns whether the attribute has no input
594 12460 : bool empty_input () const { return !attr_input; }
595 :
596 43751 : location_t get_locus () const { return locus; }
597 :
598 14930073 : AttrInput &get_attr_input () const { return *attr_input; }
599 :
600 300 : void set_attr_input (std::unique_ptr<AST::AttrInput> input)
601 : {
602 300 : 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 26548 : bool is_inner_attribute () const { return inner_attribute; }
660 :
661 : void accept_vis (ASTVisitor &vis) override;
662 :
663 3915614 : const SimplePath &get_path () const { return path; }
664 23578603 : 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 1085881 : class AttrInput : public Visitable
693 : {
694 : public:
695 : enum AttrInputType
696 : {
697 : EXPR,
698 : LITERAL,
699 : META_ITEM,
700 : TOKEN_TREE,
701 : };
702 :
703 414620 : virtual ~AttrInput () {}
704 :
705 : // Unique pointer custom clone function
706 1432328 : std::unique_ptr<AttrInput> clone_attr_input () const
707 : {
708 1432328 : 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 37 : 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 13688 : std::unique_ptr<MetaItemInner> clone_meta_item_inner () const
749 : {
750 13688 : 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 233 : 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 17359 : AttrInputMetaItemContainer (std::vector<std::unique_ptr<MetaItemInner>> items)
785 17359 : : items (std::move (items))
786 : {}
787 :
788 : // copy constructor with vector clone
789 8379 : AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other)
790 8379 : {
791 8379 : items.reserve (other.items.size ());
792 17426 : for (const auto &e : other.items)
793 9047 : items.push_back (e->clone_meta_item_inner ());
794 8379 : }
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 3014 : AttrInputType get_attr_input_type () const final override
821 : {
822 3014 : 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 24043 : bool is_meta_item () const override { return true; }
836 :
837 : // TODO: this mutable getter seems dodgy
838 60837 : std::vector<std::unique_ptr<MetaItemInner>> &get_items () { return items; }
839 55 : const std::vector<std::unique_ptr<MetaItemInner>> &get_items () const
840 : {
841 7395 : return items;
842 : }
843 :
844 : protected:
845 : // Use covariance to implement clone function as returning this type
846 8378 : AttrInputMetaItemContainer *clone_attr_input_impl () const final override
847 : {
848 8378 : return clone_attr_input_meta_item_container_impl ();
849 : }
850 :
851 8378 : AttrInputMetaItemContainer *clone_attr_input_meta_item_container_impl () const
852 : {
853 8378 : return new AttrInputMetaItemContainer (*this);
854 : }
855 : };
856 :
857 : // A token tree with delimiters
858 412376 : 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 704041 : DelimTokenTree *clone_delim_tok_tree_impl () const
866 : {
867 704041 : 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 247845 : DelimTokenTree *clone_token_tree_impl () const final override
880 : {
881 247845 : return clone_delim_tok_tree_impl ();
882 : }
883 :
884 : public:
885 202825 : 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 202825 : : delim_type (delim_type), token_trees (std::move (token_trees)),
890 202812 : locus (locus)
891 : {}
892 :
893 : // Copy constructor with vector clone
894 1196932 : DelimTokenTree (DelimTokenTree const &other)
895 1196932 : : delim_type (other.delim_type), locus (other.locus)
896 : {
897 1196932 : token_trees.clear ();
898 1196932 : token_trees.reserve (other.token_trees.size ());
899 10211472 : for (const auto &e : other.token_trees)
900 9014540 : token_trees.push_back (e->clone_token_tree ());
901 1196932 : }
902 :
903 : // overloaded assignment operator with vector clone
904 382 : DelimTokenTree &operator= (DelimTokenTree const &other)
905 : {
906 382 : delim_type = other.delim_type;
907 382 : locus = other.locus;
908 :
909 382 : token_trees.clear ();
910 382 : token_trees.reserve (other.token_trees.size ());
911 5920 : for (const auto &e : other.token_trees)
912 5538 : token_trees.push_back (e->clone_token_tree ());
913 :
914 382 : return *this;
915 : }
916 :
917 : // move constructors
918 205498 : 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 5407 : bool is_meta_item () const override { return false; }
944 :
945 392001 : AttrInputType get_attr_input_type () const final override
946 : {
947 392001 : return AttrInput::AttrInputType::TOKEN_TREE;
948 : }
949 :
950 : std::vector<std::unique_ptr<TokenTree>> &get_token_trees ()
951 : {
952 4645397 : 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 168337 : DelimType get_delim_type () const { return delim_type; }
961 110420 : 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 32070 : 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 2124 : MetaItemInner::Kind get_kind () override
984 : {
985 2124 : 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 1834 : 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 79501 : std::unique_ptr<Stmt> clone_stmt () const
1029 : {
1030 79501 : 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 1582672 : 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 7388 : virtual bool is_expr () const { return false; }
1050 :
1051 38 : virtual void add_semicolon () {}
1052 :
1053 : protected:
1054 817590 : 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 398672 : 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 : Struct,
1076 : EnumItem,
1077 : Enum,
1078 : Union,
1079 : ConstantItem,
1080 : StaticItem,
1081 : Trait,
1082 : Impl,
1083 : ExternBlock,
1084 : };
1085 :
1086 : virtual Kind get_item_kind () const = 0;
1087 :
1088 : // Unique pointer custom clone function
1089 94181 : std::unique_ptr<Item> clone_item () const
1090 : {
1091 94181 : return std::unique_ptr<Item> (clone_item_impl ());
1092 : }
1093 :
1094 : /* Adds crate names to the vector passed by reference, if it can
1095 : * (polymorphism). TODO: remove, unused. */
1096 : virtual void
1097 0 : add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
1098 0 : {}
1099 :
1100 39920 : Stmt::Kind get_stmt_kind () final { return Stmt::Kind::Item; }
1101 :
1102 : // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
1103 : // behavior that we have items that can also be expressions?
1104 0 : bool is_item () const override { return true; }
1105 :
1106 : virtual std::vector<Attribute> &get_outer_attrs () = 0;
1107 : virtual const std::vector<Attribute> &get_outer_attrs () const = 0;
1108 :
1109 478333 : virtual bool has_outer_attrs () const { return !get_outer_attrs ().empty (); }
1110 :
1111 : protected:
1112 : // Clone function implementation as pure virtual method
1113 : virtual Item *clone_item_impl () const = 0;
1114 :
1115 : /* Save having to specify two clone methods in derived classes by making
1116 : * statement clone return item clone. Hopefully won't affect performance too
1117 : * much. */
1118 6391 : Item *clone_stmt_impl () const final override { return clone_item_impl (); }
1119 : };
1120 :
1121 7410 : class GlobContainer
1122 : {
1123 : public:
1124 : enum class Kind
1125 : {
1126 : Crate,
1127 : Module,
1128 : Enum,
1129 : };
1130 :
1131 : virtual Kind get_glob_container_kind () const = 0;
1132 : };
1133 :
1134 : // Item that supports visibility - abstract base class
1135 : class VisItem : public Item
1136 : {
1137 : Visibility visibility;
1138 : std::vector<Attribute> outer_attrs;
1139 :
1140 : protected:
1141 : // Visibility constructor
1142 68116 : VisItem (Visibility visibility,
1143 : std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
1144 68116 : : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
1145 68116 : {}
1146 :
1147 : // Visibility copy constructor
1148 236309 : VisItem (VisItem const &other)
1149 236309 : : visibility (other.visibility), outer_attrs (other.outer_attrs)
1150 236309 : {}
1151 :
1152 : // Overload assignment operator to clone
1153 0 : VisItem &operator= (VisItem const &other)
1154 : {
1155 0 : visibility = other.visibility;
1156 0 : outer_attrs = other.outer_attrs;
1157 :
1158 0 : return *this;
1159 : }
1160 :
1161 : // move constructors
1162 1704 : VisItem (VisItem &&other) = default;
1163 : VisItem &operator= (VisItem &&other) = default;
1164 :
1165 : public:
1166 : /* Does the item have some kind of public visibility (non-default
1167 : * visibility)? */
1168 4477 : bool has_visibility () const { return visibility.is_public (); }
1169 :
1170 : std::string as_string () const override;
1171 :
1172 : // TODO: this mutable getter seems really dodgy. Think up better way.
1173 5731934 : Visibility &get_visibility () { return visibility; }
1174 : const Visibility &get_visibility () const { return visibility; }
1175 :
1176 9104831 : std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1177 484125 : const std::vector<Attribute> &get_outer_attrs () const override
1178 : {
1179 484125 : return outer_attrs;
1180 : }
1181 :
1182 : virtual Item::Kind get_item_kind () const override = 0;
1183 : };
1184 :
1185 : // forward decl of ExprWithoutBlock
1186 : class ExprWithoutBlock;
1187 :
1188 : // Base expression AST node - abstract
1189 208772 : class Expr : public Visitable
1190 : {
1191 : public:
1192 : enum class Kind
1193 : {
1194 : PathInExpression,
1195 : QualifiedPathInExpression,
1196 : Literal,
1197 : Operator,
1198 : Grouped,
1199 : Array,
1200 : ArrayIndex,
1201 : Tuple,
1202 : TupleIndex,
1203 : Struct,
1204 : Call,
1205 : MethodCall,
1206 : FieldAccess,
1207 : Closure,
1208 : Block,
1209 : ConstExpr,
1210 : ConstBlock,
1211 : Continue,
1212 : Break,
1213 : Range,
1214 : Box,
1215 : Return,
1216 : UnsafeBlock,
1217 : Loop,
1218 : If,
1219 : IfLet,
1220 : Match,
1221 : Await,
1222 : AsyncBlock,
1223 : InlineAsm,
1224 : LlvmInlineAsm,
1225 : Identifier,
1226 : FormatArgs,
1227 : OffsetOf,
1228 : MacroInvocation,
1229 : Borrow,
1230 : Dereference,
1231 : ErrorPropagation,
1232 : Negation,
1233 : ArithmeticOrLogical,
1234 : Comparison,
1235 : LazyBoolean,
1236 : TypeCast,
1237 : Assignment,
1238 : CompoundAssignment,
1239 : Try,
1240 : };
1241 :
1242 : virtual Kind get_expr_kind () const = 0;
1243 :
1244 : // Unique pointer custom clone function
1245 309 : std::unique_ptr<Expr> clone_expr () const
1246 : {
1247 4455596 : return std::unique_ptr<Expr> (clone_expr_impl ());
1248 : }
1249 :
1250 : /* TODO: public methods that could be useful:
1251 : * - get_type() - returns type of expression. set_type() may also be useful
1252 : * for some?
1253 : * - evaluate() - evaluates expression if constant? can_evaluate()? */
1254 :
1255 : virtual std::string as_string () const = 0;
1256 :
1257 3072 : virtual ~Expr () {}
1258 :
1259 : virtual location_t get_locus () const = 0;
1260 :
1261 677 : virtual bool is_literal () const { return false; }
1262 :
1263 : // HACK: strictly not needed, but faster than full downcast clone
1264 : virtual bool is_expr_without_block () const = 0;
1265 :
1266 : virtual void mark_for_strip () = 0;
1267 : virtual bool is_marked_for_strip () const = 0;
1268 :
1269 18065187 : virtual NodeId get_node_id () const { return node_id; }
1270 :
1271 0 : virtual void set_node_id (NodeId id) { node_id = id; }
1272 :
1273 : virtual std::vector<Attribute> &get_outer_attrs () = 0;
1274 :
1275 : // TODO: think of less hacky way to implement this kind of thing
1276 : // Sets outer attributes.
1277 : virtual void set_outer_attrs (std::vector<Attribute>) = 0;
1278 :
1279 : protected:
1280 : // Constructor
1281 2010206 : Expr () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1282 :
1283 : // Clone function implementation as pure virtual method
1284 : virtual Expr *clone_expr_impl () const = 0;
1285 :
1286 : NodeId node_id;
1287 : };
1288 :
1289 : // AST node for an expression without an accompanying block - abstract
1290 2271644 : class ExprWithoutBlock : public Expr
1291 : {
1292 : protected:
1293 : // pure virtual clone implementation
1294 : virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
1295 :
1296 : /* Save having to specify two clone methods in derived classes by making
1297 : * expr clone return exprwithoutblock clone. Hopefully won't affect
1298 : * performance too much. */
1299 4377083 : ExprWithoutBlock *clone_expr_impl () const final override
1300 : {
1301 4377083 : return clone_expr_without_block_impl ();
1302 : }
1303 :
1304 183952 : bool is_expr_without_block () const final override { return true; };
1305 :
1306 : public:
1307 : // Unique pointer custom clone function
1308 43 : std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
1309 : {
1310 43 : return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
1311 : }
1312 : };
1313 :
1314 : /* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1315 : * Pratt parser */
1316 : /* Alternatively, identifiers could just be represented as single-segment
1317 : * paths
1318 : */
1319 : class IdentifierExpr : public ExprWithoutBlock
1320 : {
1321 : std::vector<Attribute> outer_attrs;
1322 : Identifier ident;
1323 : location_t locus;
1324 :
1325 : public:
1326 160140 : IdentifierExpr (Identifier ident, std::vector<Attribute> outer_attrs,
1327 : location_t locus)
1328 320280 : : outer_attrs (std::move (outer_attrs)), ident (std::move (ident)),
1329 160140 : locus (locus)
1330 160140 : {}
1331 :
1332 12 : std::string as_string () const override { return ident.as_string (); }
1333 :
1334 143162 : location_t get_locus () const override final { return locus; }
1335 :
1336 196110 : Identifier get_ident () const { return ident; }
1337 :
1338 : void accept_vis (ASTVisitor &vis) override;
1339 :
1340 : // Clones this object.
1341 : std::unique_ptr<IdentifierExpr> clone_identifier_expr () const
1342 : {
1343 : return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
1344 : }
1345 :
1346 : // "Error state" if ident is empty, so base stripping on this.
1347 0 : void mark_for_strip () override { ident = {""}; }
1348 9678186 : bool is_marked_for_strip () const override { return ident.empty (); }
1349 :
1350 : const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
1351 59847874 : std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1352 :
1353 0 : void set_outer_attrs (std::vector<Attribute> new_attrs) override
1354 : {
1355 0 : outer_attrs = std::move (new_attrs);
1356 0 : }
1357 :
1358 146729 : Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
1359 :
1360 : protected:
1361 : // Clone method implementation
1362 949964 : IdentifierExpr *clone_expr_without_block_impl () const final override
1363 : {
1364 949964 : return clone_identifier_expr_impl ();
1365 : }
1366 :
1367 949964 : IdentifierExpr *clone_identifier_expr_impl () const
1368 : {
1369 949964 : return new IdentifierExpr (*this);
1370 : }
1371 : };
1372 :
1373 : // Pattern base AST node
1374 904618 : class Pattern : public Visitable
1375 : {
1376 : public:
1377 : enum class Kind
1378 : {
1379 : Literal,
1380 : Identifier,
1381 : Wildcard,
1382 : Rest,
1383 : Range,
1384 : Reference,
1385 : Struct,
1386 : TupleStruct,
1387 : Tuple,
1388 : Grouped,
1389 : Slice,
1390 : Alt,
1391 : Path,
1392 : MacroInvocation,
1393 : };
1394 :
1395 : // Unique pointer custom clone function
1396 576355 : std::unique_ptr<Pattern> clone_pattern () const
1397 : {
1398 576355 : return std::unique_ptr<Pattern> (clone_pattern_impl ());
1399 : }
1400 :
1401 : virtual Kind get_pattern_kind () = 0;
1402 :
1403 : // possible virtual methods: is_refutable()
1404 :
1405 : virtual ~Pattern () {}
1406 :
1407 : virtual std::string as_string () const = 0;
1408 :
1409 : // as only one kind of pattern can be stripped, have default of nothing
1410 0 : virtual void mark_for_strip () {}
1411 4659893 : virtual bool is_marked_for_strip () const { return false; }
1412 :
1413 : virtual location_t get_locus () const = 0;
1414 : virtual NodeId get_node_id () const = 0;
1415 :
1416 : protected:
1417 : // Clone pattern implementation as pure virtual method
1418 : virtual Pattern *clone_pattern_impl () const = 0;
1419 : };
1420 :
1421 : // forward decl for Type
1422 : class TraitBound;
1423 :
1424 : // Base class for types as represented in AST - abstract
1425 701836 : class Type : public Visitable
1426 : {
1427 : public:
1428 : enum Kind
1429 : {
1430 : MacroInvocation,
1431 : TypePath,
1432 : QualifiedPathInType,
1433 : ImplTrait,
1434 : TraitObject,
1435 : Parenthesised,
1436 : ImplTraitTypeOneBound,
1437 : TraitObjectTypeOneBound,
1438 : Tuple,
1439 : Never,
1440 : RawPointer,
1441 : Reference,
1442 : Array,
1443 : Slice,
1444 : Inferred,
1445 : BareFunction,
1446 : };
1447 :
1448 : virtual Kind get_type_kind () const = 0;
1449 :
1450 : // Unique pointer custom clone function
1451 419722 : std::unique_ptr<Type> clone_type () const
1452 : {
1453 419722 : return std::unique_ptr<Type> (clone_type_impl ());
1454 : }
1455 :
1456 : // Similar to `clone_type`, but generates a new instance of the node with a
1457 : // different NodeId
1458 193 : std::unique_ptr<Type> reconstruct () const { return reconstruct_base (this); }
1459 :
1460 : // virtual destructor
1461 213269 : virtual ~Type () {}
1462 :
1463 : virtual std::string as_string () const = 0;
1464 :
1465 : /* HACK: convert to trait bound. Virtual method overriden by classes that
1466 : * enable this. */
1467 13 : virtual TraitBound *to_trait_bound (bool) const { return nullptr; }
1468 : /* as pointer, shouldn't require definition beforehand, only forward
1469 : * declaration. */
1470 :
1471 : // as only two kinds of types can be stripped, have default of nothing
1472 0 : virtual void mark_for_strip () {}
1473 1057757 : virtual bool is_marked_for_strip () const { return false; }
1474 :
1475 : virtual location_t get_locus () const = 0;
1476 :
1477 : // TODO: put this in a virtual base class?
1478 599049 : virtual NodeId get_node_id () const { return node_id; }
1479 : virtual Type *reconstruct_impl () const = 0;
1480 :
1481 : protected:
1482 694120 : Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1483 543 : Type (NodeId node_id) : node_id (node_id) {}
1484 :
1485 : // Clone and reconstruct function implementations as pure virtual methods
1486 : virtual Type *clone_type_impl () const = 0;
1487 :
1488 : NodeId node_id;
1489 : };
1490 :
1491 : // A type without parentheses? - abstract
1492 876103 : class TypeNoBounds : public Type
1493 : {
1494 : public:
1495 : // Unique pointer custom clone function
1496 108479 : std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
1497 : {
1498 108479 : return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
1499 : }
1500 :
1501 6 : std::unique_ptr<TypeNoBounds> reconstruct () const
1502 : {
1503 6 : return reconstruct_base (this);
1504 : }
1505 :
1506 : virtual TypeNoBounds *reconstruct_impl () const override = 0;
1507 :
1508 : protected:
1509 : // Clone function implementation as pure virtual method
1510 : virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
1511 :
1512 : /* Save having to specify two clone methods in derived classes by making
1513 : * type clone return typenobounds clone. Hopefully won't affect performance
1514 : * too much. */
1515 419179 : TypeNoBounds *clone_type_impl () const final override
1516 : {
1517 419179 : return clone_type_no_bounds_impl ();
1518 : }
1519 :
1520 693984 : TypeNoBounds () : Type () {}
1521 : };
1522 :
1523 : /* Abstract base class representing a type param bound - Lifetime and
1524 : * TraitBound extends it */
1525 : class TypeParamBound : public Visitable
1526 : {
1527 : public:
1528 : enum TypeParamBoundType
1529 : {
1530 : TRAIT,
1531 : LIFETIME
1532 : };
1533 :
1534 30876 : virtual ~TypeParamBound () {}
1535 :
1536 : // Unique pointer custom clone function
1537 19603 : std::unique_ptr<TypeParamBound> clone_type_param_bound () const
1538 : {
1539 19603 : return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
1540 : }
1541 :
1542 0 : std::unique_ptr<TypeParamBound> reconstruct () const
1543 : {
1544 0 : return reconstruct_base (this);
1545 : }
1546 :
1547 : virtual std::string as_string () const = 0;
1548 :
1549 12066 : NodeId get_node_id () const { return node_id; }
1550 :
1551 : virtual location_t get_locus () const = 0;
1552 :
1553 : virtual TypeParamBoundType get_bound_type () const = 0;
1554 :
1555 : virtual TypeParamBound *reconstruct_impl () const = 0;
1556 :
1557 : protected:
1558 : // Clone function implementation as pure virtual method
1559 : virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
1560 :
1561 : TypeParamBound () : node_id (Analysis::Mappings::get ().get_next_node_id ())
1562 : {}
1563 977 : TypeParamBound (NodeId node_id) : node_id (node_id) {}
1564 :
1565 : NodeId node_id;
1566 : };
1567 :
1568 : // Represents a lifetime (and is also a kind of type param bound)
1569 81483 : class Lifetime : public TypeParamBound
1570 : {
1571 : public:
1572 : enum LifetimeType
1573 : {
1574 : NAMED, // corresponds to LIFETIME_OR_LABEL
1575 : STATIC, // corresponds to 'static
1576 : WILDCARD // corresponds to '_
1577 : };
1578 :
1579 : private:
1580 : LifetimeType lifetime_type;
1581 : std::string lifetime_name;
1582 : location_t locus;
1583 : NodeId node_id;
1584 :
1585 : public:
1586 : // Constructor
1587 49785 : Lifetime (LifetimeType type, std::string name = std::string (),
1588 : location_t locus = UNDEF_LOCATION)
1589 49785 : : TypeParamBound (Analysis::Mappings::get ().get_next_node_id ()),
1590 49785 : lifetime_type (type), lifetime_name (std::move (name)), locus (locus)
1591 49785 : {}
1592 :
1593 369 : Lifetime (NodeId id, LifetimeType type, std::string name = std::string (),
1594 : location_t locus = UNDEF_LOCATION)
1595 369 : : TypeParamBound (id), lifetime_type (type),
1596 738 : lifetime_name (std::move (name)), locus (locus)
1597 : {}
1598 :
1599 44771 : static Lifetime elided () { return Lifetime (WILDCARD, ""); }
1600 :
1601 : // Returns true if the lifetime is in an error state.
1602 : std::string as_string () const override;
1603 :
1604 : void accept_vis (ASTVisitor &vis) override;
1605 :
1606 19230 : LifetimeType get_lifetime_type () const { return lifetime_type; }
1607 :
1608 19290 : location_t get_locus () const override final { return locus; }
1609 :
1610 86204 : std::string get_lifetime_name () const { return lifetime_name; }
1611 :
1612 19 : TypeParamBoundType get_bound_type () const override
1613 : {
1614 19 : return TypeParamBound::TypeParamBoundType::LIFETIME;
1615 : }
1616 :
1617 : protected:
1618 : /* Use covariance to implement clone function as returning this object
1619 : * rather than base */
1620 369 : Lifetime *clone_type_param_bound_impl () const override
1621 : {
1622 738 : return new Lifetime (node_id, lifetime_type, lifetime_name, locus);
1623 : }
1624 0 : Lifetime *reconstruct_impl () const override
1625 : {
1626 0 : return new Lifetime (lifetime_type, lifetime_name, locus);
1627 : }
1628 : };
1629 :
1630 : /* Base generic parameter in AST. Abstract - can be represented by a Lifetime
1631 : * or Type param */
1632 : class GenericParam : public Visitable
1633 : {
1634 : public:
1635 : enum class Kind
1636 : {
1637 : Lifetime,
1638 : Type,
1639 : Const,
1640 : };
1641 :
1642 : virtual ~GenericParam () {}
1643 :
1644 : // Unique pointer custom clone function
1645 54433 : std::unique_ptr<GenericParam> clone_generic_param () const
1646 : {
1647 54433 : return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
1648 : }
1649 :
1650 : virtual std::string as_string () const = 0;
1651 :
1652 : virtual location_t get_locus () const = 0;
1653 :
1654 : virtual Kind get_kind () const = 0;
1655 :
1656 896062 : NodeId get_node_id () const { return node_id; }
1657 :
1658 : protected:
1659 2061 : GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1660 72908 : GenericParam (NodeId node_id) : node_id (node_id) {}
1661 :
1662 : // Clone function implementation as pure virtual method
1663 : virtual GenericParam *clone_generic_param_impl () const = 0;
1664 :
1665 : NodeId node_id;
1666 : };
1667 :
1668 : // A lifetime generic parameter (as opposed to a type generic parameter)
1669 : class LifetimeParam : public GenericParam
1670 : {
1671 : Lifetime lifetime;
1672 : std::vector<Lifetime> lifetime_bounds;
1673 : AST::AttrVec outer_attrs;
1674 : location_t locus;
1675 :
1676 : public:
1677 0 : Lifetime get_lifetime () const { return lifetime; }
1678 :
1679 175149 : Lifetime &get_lifetime () { return lifetime; }
1680 :
1681 218333 : AST::AttrVec &get_outer_attrs () { return outer_attrs; }
1682 :
1683 : // Returns whether the lifetime param has any lifetime bounds.
1684 158 : bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
1685 :
1686 174701 : std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
1687 :
1688 : const std::vector<Lifetime> &get_lifetime_bounds () const
1689 : {
1690 0 : return lifetime_bounds;
1691 : }
1692 :
1693 : // Returns whether the lifetime param has an outer attribute.
1694 0 : bool has_outer_attribute () const { return !outer_attrs.empty (); }
1695 :
1696 : // Constructor
1697 1479 : LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
1698 : AST::AttrVec outer_attrs, location_t locus)
1699 1479 : : lifetime (std::move (lifetime)),
1700 1479 : lifetime_bounds (std::move (lifetime_bounds)),
1701 1479 : outer_attrs (std::move (outer_attrs)), locus (locus)
1702 1479 : {}
1703 :
1704 : std::string as_string () const override;
1705 :
1706 : void accept_vis (ASTVisitor &vis) override;
1707 :
1708 290 : location_t get_locus () const override final { return locus; }
1709 :
1710 4159 : Kind get_kind () const override final { return Kind::Lifetime; }
1711 :
1712 : protected:
1713 : /* Use covariance to implement clone function as returning this object
1714 : * rather than base */
1715 7002 : LifetimeParam *clone_generic_param_impl () const override
1716 : {
1717 7002 : return new LifetimeParam (*this);
1718 : }
1719 : };
1720 :
1721 140984 : class AssociatedItem : public Visitable
1722 : {
1723 : protected:
1724 : // Clone function implementation as pure virtual method
1725 : virtual AssociatedItem *clone_associated_item_impl () const = 0;
1726 :
1727 : public:
1728 : virtual ~AssociatedItem () {}
1729 :
1730 112630 : std::unique_ptr<AssociatedItem> clone_associated_item () const
1731 : {
1732 112630 : return std::unique_ptr<AssociatedItem> (clone_associated_item_impl ());
1733 : }
1734 :
1735 : virtual std::string as_string () const = 0;
1736 :
1737 : virtual void mark_for_strip () = 0;
1738 : virtual bool is_marked_for_strip () const = 0;
1739 :
1740 : virtual location_t get_locus () const = 0;
1741 :
1742 : virtual NodeId get_node_id () const = 0;
1743 : };
1744 :
1745 : // Item used in trait declarations - abstract base class
1746 : class TraitItem : public AssociatedItem
1747 : {
1748 : protected:
1749 400435 : TraitItem (location_t locus)
1750 400435 : : node_id (Analysis::Mappings::get ().get_next_node_id ()),
1751 800870 : vis (Visibility::create_private ()), locus (locus)
1752 400435 : {}
1753 :
1754 788 : TraitItem (Visibility vis, location_t locus)
1755 788 : : node_id (Analysis::Mappings::get ().get_next_node_id ()), vis (vis),
1756 788 : locus (locus)
1757 788 : {}
1758 :
1759 : // Clone function implementation as pure virtual method
1760 : virtual TraitItem *clone_associated_item_impl () const override = 0;
1761 :
1762 : NodeId node_id;
1763 : Visibility vis;
1764 : location_t locus;
1765 :
1766 : public:
1767 : // Unique pointer custom clone function
1768 : std::unique_ptr<TraitItem> clone_trait_item () const
1769 : {
1770 : return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
1771 : }
1772 :
1773 7938 : NodeId get_node_id () const override { return node_id; }
1774 5374 : location_t get_locus () const override { return locus; }
1775 : };
1776 :
1777 : // Abstract base class for an item used inside an extern block
1778 : class ExternalItem : public Visitable
1779 : {
1780 : public:
1781 6 : ExternalItem () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1782 :
1783 537118 : ExternalItem (NodeId node_id) : node_id (node_id) {}
1784 :
1785 : virtual ~ExternalItem () {}
1786 :
1787 : // Unique pointer custom clone function
1788 8594 : std::unique_ptr<ExternalItem> clone_external_item () const
1789 : {
1790 8594 : return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
1791 : }
1792 :
1793 : virtual std::string as_string () const = 0;
1794 :
1795 : virtual void mark_for_strip () = 0;
1796 : virtual bool is_marked_for_strip () const = 0;
1797 :
1798 61604 : virtual NodeId get_node_id () const { return node_id; }
1799 :
1800 : protected:
1801 : // Clone function implementation as pure virtual method
1802 : virtual ExternalItem *clone_external_item_impl () const = 0;
1803 :
1804 : NodeId node_id;
1805 : };
1806 :
1807 : /* Data structure to store the data used in macro invocations and macro
1808 : * invocations with semicolons. */
1809 : struct MacroInvocData
1810 : {
1811 : private:
1812 : SimplePath path;
1813 : DelimTokenTree token_tree;
1814 :
1815 : // One way of parsing the macro. Probably not applicable for all macros.
1816 : std::vector<std::unique_ptr<MetaItemInner>> parsed_items;
1817 : bool parsed_to_meta_item = false;
1818 : MacroExpander *expander = nullptr;
1819 :
1820 : public:
1821 : std::string as_string () const;
1822 :
1823 61516 : MacroInvocData (SimplePath path, DelimTokenTree token_tree)
1824 61516 : : path (std::move (path)), token_tree (std::move (token_tree))
1825 61516 : {}
1826 :
1827 : // Copy constructor with vector clone
1828 398847 : MacroInvocData (const MacroInvocData &other)
1829 398847 : : path (other.path), token_tree (other.token_tree),
1830 398847 : parsed_to_meta_item (other.parsed_to_meta_item)
1831 : {
1832 398847 : parsed_items.reserve (other.parsed_items.size ());
1833 398847 : for (const auto &e : other.parsed_items)
1834 0 : parsed_items.push_back (e->clone_meta_item_inner ());
1835 398847 : }
1836 :
1837 : // Copy assignment operator with vector clone
1838 : MacroInvocData &operator= (const MacroInvocData &other)
1839 : {
1840 : path = other.path;
1841 : token_tree = other.token_tree;
1842 : parsed_to_meta_item = other.parsed_to_meta_item;
1843 : expander = other.expander;
1844 :
1845 : parsed_items.reserve (other.parsed_items.size ());
1846 : for (const auto &e : other.parsed_items)
1847 : parsed_items.push_back (e->clone_meta_item_inner ());
1848 :
1849 : return *this;
1850 : }
1851 :
1852 : // Move constructors
1853 66508 : MacroInvocData (MacroInvocData &&other) = default;
1854 : MacroInvocData &operator= (MacroInvocData &&other) = default;
1855 :
1856 : // Invalid if path is empty, so base stripping on that.
1857 18 : void mark_for_strip () { path = SimplePath::create_empty (); }
1858 145786 : bool is_marked_for_strip () const { return path.is_empty (); }
1859 :
1860 : // Returns whether the macro has been parsed already.
1861 132 : bool is_parsed () const { return parsed_to_meta_item; }
1862 : // TODO: update on other ways of parsing it
1863 :
1864 : // TODO: this mutable getter seems kinda dodgy
1865 338068 : DelimTokenTree &get_delim_tok_tree () { return token_tree; }
1866 : const DelimTokenTree &get_delim_tok_tree () const { return token_tree; }
1867 :
1868 : // Set the delim token tree of a macro invocation
1869 382 : void set_delim_tok_tree (DelimTokenTree tree) { token_tree = tree; }
1870 :
1871 : // TODO: this mutable getter seems kinda dodgy
1872 371734 : SimplePath &get_path () { return path; }
1873 : const SimplePath &get_path () const { return path; }
1874 :
1875 57472 : void set_expander (MacroExpander *new_expander) { expander = new_expander; }
1876 822 : MacroExpander *get_expander ()
1877 : {
1878 822 : rust_assert (expander);
1879 822 : return expander;
1880 : }
1881 :
1882 : void
1883 132 : set_meta_item_output (std::vector<std::unique_ptr<MetaItemInner>> new_items)
1884 : {
1885 132 : parsed_items = std::move (new_items);
1886 : }
1887 : std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
1888 : {
1889 : return parsed_items;
1890 : }
1891 : const std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items () const
1892 : {
1893 : return parsed_items;
1894 : }
1895 : };
1896 :
1897 : class SingleASTNode : public Visitable
1898 : {
1899 : public:
1900 : enum class Kind
1901 : {
1902 : Expr,
1903 : Item,
1904 : Stmt,
1905 : Extern,
1906 : Assoc,
1907 : Type,
1908 : Pattern,
1909 : };
1910 :
1911 : private:
1912 : Kind kind;
1913 :
1914 : // FIXME make this a union
1915 : std::unique_ptr<Expr> expr;
1916 : std::unique_ptr<Item> item;
1917 : std::unique_ptr<Stmt> stmt;
1918 : std::unique_ptr<ExternalItem> external_item;
1919 : std::unique_ptr<AssociatedItem> assoc_item;
1920 : std::unique_ptr<Type> type;
1921 : std::unique_ptr<Pattern> pattern;
1922 :
1923 : public:
1924 51186 : SingleASTNode (std::unique_ptr<Expr> expr)
1925 51186 : : kind (Kind::Expr), expr (std::move (expr))
1926 : {}
1927 :
1928 10787 : SingleASTNode (std::unique_ptr<Item> item)
1929 10787 : : kind (Kind::Item), item (std::move (item))
1930 : {}
1931 :
1932 655 : SingleASTNode (std::unique_ptr<Stmt> stmt)
1933 655 : : kind (Kind::Stmt), stmt (std::move (stmt))
1934 : {}
1935 :
1936 3 : SingleASTNode (std::unique_ptr<ExternalItem> item)
1937 3 : : kind (Kind::Extern), external_item (std::move (item))
1938 : {}
1939 :
1940 2228 : SingleASTNode (std::unique_ptr<AssociatedItem> item)
1941 2228 : : kind (Kind::Assoc), assoc_item (std::move (item))
1942 : {}
1943 :
1944 497 : SingleASTNode (std::unique_ptr<Type> type)
1945 497 : : kind (Kind::Type), type (std::move (type))
1946 : {}
1947 :
1948 2 : SingleASTNode (std::unique_ptr<Pattern> pattern)
1949 2 : : kind (Kind::Pattern), pattern (std::move (pattern))
1950 : {}
1951 :
1952 : SingleASTNode (SingleASTNode const &other);
1953 :
1954 : SingleASTNode operator= (SingleASTNode const &other);
1955 :
1956 24516 : SingleASTNode (SingleASTNode &&other) = default;
1957 : SingleASTNode &operator= (SingleASTNode &&other) = default;
1958 :
1959 101530 : Kind get_kind () const { return kind; }
1960 :
1961 : std::unique_ptr<Expr> &get_expr ()
1962 : {
1963 : rust_assert (kind == Kind::Expr);
1964 : return expr;
1965 : }
1966 :
1967 0 : std::unique_ptr<Item> &get_item ()
1968 : {
1969 0 : rust_assert (kind == Kind::Item);
1970 0 : return item;
1971 : }
1972 :
1973 : std::unique_ptr<Stmt> &get_stmt ()
1974 : {
1975 : rust_assert (kind == Kind::Stmt);
1976 : return stmt;
1977 : }
1978 :
1979 : /**
1980 : * Access the inner nodes and take ownership of them.
1981 : * You can only call these functions once per node
1982 : */
1983 :
1984 840 : std::unique_ptr<Stmt> take_stmt ()
1985 : {
1986 840 : rust_assert (!is_error ());
1987 840 : return std::move (stmt);
1988 : }
1989 :
1990 50267 : std::unique_ptr<Expr> take_expr ()
1991 : {
1992 50267 : rust_assert (!is_error ());
1993 50267 : return std::move (expr);
1994 : }
1995 :
1996 10786 : std::unique_ptr<Item> take_item ()
1997 : {
1998 10786 : rust_assert (!is_error ());
1999 10786 : return std::move (item);
2000 : }
2001 :
2002 3 : std::unique_ptr<ExternalItem> take_external_item ()
2003 : {
2004 3 : rust_assert (!is_error ());
2005 3 : return std::move (external_item);
2006 : }
2007 :
2008 2228 : std::unique_ptr<AssociatedItem> take_assoc_item ()
2009 : {
2010 2228 : rust_assert (!is_error ());
2011 2228 : return std::move (assoc_item);
2012 : }
2013 :
2014 497 : std::unique_ptr<Type> take_type ()
2015 : {
2016 497 : rust_assert (!is_error ());
2017 497 : return std::move (type);
2018 : }
2019 :
2020 1 : std::unique_ptr<Pattern> take_pattern ()
2021 : {
2022 1 : rust_assert (!is_error ());
2023 1 : return std::move (pattern);
2024 : }
2025 :
2026 : void accept_vis (ASTVisitor &vis) override;
2027 :
2028 : bool is_error ();
2029 :
2030 : std::string as_string () const;
2031 : };
2032 :
2033 : // A crate AST object - holds all the data for a single compilation unit
2034 : struct Crate final : public GlobContainer
2035 : {
2036 : std::vector<Attribute> inner_attrs;
2037 : // dodgy spacing required here
2038 : /* TODO: is it better to have a vector of items here or a module (implicit
2039 : * top-level one)? */
2040 : std::vector<std::unique_ptr<Item>> items;
2041 :
2042 : NodeId node_id;
2043 :
2044 : public:
2045 : // Constructor
2046 5006 : Crate (std::vector<std::unique_ptr<Item>> items,
2047 : std::vector<Attribute> inner_attrs)
2048 5006 : : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
2049 5006 : node_id (Analysis::Mappings::get ().get_next_node_id ())
2050 5006 : {}
2051 :
2052 : // Copy constructor with vector clone
2053 4848 : Crate (Crate const &other)
2054 4848 : : inner_attrs (other.inner_attrs), node_id (other.node_id)
2055 : {
2056 4848 : items.reserve (other.items.size ());
2057 24806 : for (const auto &e : other.items)
2058 19958 : items.push_back (e->clone_item ());
2059 4848 : }
2060 :
2061 4960 : ~Crate () = default;
2062 :
2063 : // Overloaded assignment operator with vector clone
2064 : Crate &operator= (Crate const &other)
2065 : {
2066 : inner_attrs = other.inner_attrs;
2067 : node_id = other.node_id;
2068 :
2069 : items.reserve (other.items.size ());
2070 : for (const auto &e : other.items)
2071 : items.push_back (e->clone_item ());
2072 :
2073 : return *this;
2074 : }
2075 :
2076 : // Move constructors
2077 : Crate (Crate &&other) = default;
2078 : Crate &operator= (Crate &&other) = default;
2079 :
2080 : // Get crate representation as string (e.g. for debugging).
2081 : std::string as_string () const;
2082 :
2083 : // Delete all crate information, e.g. if fails cfg.
2084 1 : void strip_crate ()
2085 : {
2086 1 : inner_attrs.clear ();
2087 1 : inner_attrs.shrink_to_fit ();
2088 :
2089 1 : items.clear ();
2090 1 : items.shrink_to_fit ();
2091 : // TODO: is this the best way to do this?
2092 1 : }
2093 :
2094 : void inject_extern_crate (std::string name);
2095 : void inject_inner_attribute (Attribute attribute);
2096 :
2097 151206 : NodeId get_node_id () const { return node_id; }
2098 : const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
2099 118474 : std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
2100 :
2101 : std::vector<std::unique_ptr<AST::Item>> take_items ()
2102 : {
2103 : return std::move (items);
2104 : }
2105 :
2106 : void set_items (std::vector<std::unique_ptr<AST::Item>> &&new_items)
2107 : {
2108 : items = std::move (new_items);
2109 : }
2110 :
2111 4873 : GlobContainer::Kind get_glob_container_kind () const override
2112 : {
2113 4873 : return GlobContainer::Kind::Crate;
2114 : }
2115 : };
2116 :
2117 : } // namespace AST
2118 :
2119 : template <> struct CloneableDelegate<std::unique_ptr<AST::Pattern>>
2120 : {
2121 : static std::unique_ptr<AST::Pattern>
2122 203445 : clone (const std::unique_ptr<AST::Pattern> &other)
2123 : {
2124 203445 : if (other == nullptr)
2125 146662 : return nullptr;
2126 : else
2127 56783 : return other->clone_pattern ();
2128 : }
2129 : };
2130 :
2131 : } // namespace Rust
2132 :
2133 : namespace std {
2134 : template <> struct less<Rust::Identifier>
2135 : {
2136 : bool operator() (const Rust::Identifier &lhs,
2137 : const Rust::Identifier &rhs) const
2138 : {
2139 : return lhs.as_string () < rhs.as_string ();
2140 : }
2141 : };
2142 :
2143 : template <> struct hash<Rust::Identifier>
2144 : {
2145 : std::size_t operator() (const Rust::Identifier &k) const
2146 : {
2147 : using std::hash;
2148 : using std::size_t;
2149 : using std::string;
2150 :
2151 : return hash<string> () (k.as_string ()) ^ (hash<int> () (k.get_locus ()));
2152 : }
2153 : };
2154 :
2155 : } // namespace std
2156 :
2157 : #endif
|