[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / rust / ast / rust-ast.h
blob0db46d64f3244bf28b0152d9b00c7f15068375e8
1 // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
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
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"
30 namespace Rust {
31 // TODO: remove typedefs and make actual types for these
32 typedef int TupleIndex;
33 struct Session;
34 struct MacroExpander;
36 class Identifier
38 public:
39 // Create dummy identifier
40 Identifier () : ident (""), loc (UNDEF_LOCATION) {}
41 // Create identifier with dummy location
42 Identifier (std::string ident, location_t loc = UNDEF_LOCATION)
43 : ident (ident), loc (loc)
45 // Create identifier from token
46 Identifier (const_TokenPtr token)
47 : ident (token->get_str ()), loc (token->get_locus ())
50 Identifier (const Identifier &) = default;
51 Identifier (Identifier &&) = default;
52 Identifier &operator= (const Identifier &) = default;
53 Identifier &operator= (Identifier &&) = default;
55 location_t get_locus () const { return loc; }
56 const std::string &as_string () const { return ident; }
58 bool empty () const { return ident.empty (); }
60 private:
61 std::string ident;
62 location_t loc;
65 std::ostream &
66 operator<< (std::ostream &os, Identifier const &i);
68 namespace AST {
69 // foward decl: ast visitor
70 class ASTVisitor;
71 using AttrVec = std::vector<Attribute>;
73 // The available kinds of AST Nodes
74 enum class Kind
76 UNKNOWN,
77 MODULE,
78 MACRO_RULES_DEFINITION,
79 MACRO_INVOCATION,
80 IDENTIFIER,
83 class Visitable
85 public:
86 virtual ~Visitable () = default;
87 virtual void accept_vis (ASTVisitor &vis) = 0;
90 // Abstract base class for all AST elements
91 class Node : public Visitable
93 public:
94 /**
95 * Get the kind of Node this is. This is used to differentiate various AST
96 * elements with very little overhead when extracting the derived type
97 * through static casting is not necessary.
99 // FIXME: Mark this as `= 0` in the future to make sure every node
100 // implements it
101 virtual Kind get_ast_kind () const { return Kind::UNKNOWN; }
104 // Delimiter types - used in macros and whatever.
105 enum DelimType
107 PARENS,
108 SQUARE,
109 CURLY
112 // forward decl for use in token tree method
113 class Token;
115 // A tree of tokens (or a single token) - abstract base class
116 class TokenTree : public Visitable
118 public:
119 virtual ~TokenTree () {}
121 // Unique pointer custom clone function
122 std::unique_ptr<TokenTree> clone_token_tree () const
124 return std::unique_ptr<TokenTree> (clone_token_tree_impl ());
127 virtual std::string as_string () const = 0;
129 /* Converts token tree to a flat token stream. Tokens must be pointer to
130 * avoid mutual dependency with Token. */
131 virtual std::vector<std::unique_ptr<Token>> to_token_stream () const = 0;
133 protected:
134 // pure virtual clone implementation
135 virtual TokenTree *clone_token_tree_impl () const = 0;
138 // Abstract base class for a macro match
139 class MacroMatch : public Visitable
141 public:
142 enum MacroMatchType
144 Fragment,
145 Repetition,
146 Matcher,
150 virtual ~MacroMatch () {}
152 virtual std::string as_string () const = 0;
153 virtual location_t get_match_locus () const = 0;
155 // Unique pointer custom clone function
156 std::unique_ptr<MacroMatch> clone_macro_match () const
158 return std::unique_ptr<MacroMatch> (clone_macro_match_impl ());
161 virtual MacroMatchType get_macro_match_type () const = 0;
163 protected:
164 // pure virtual clone implementation
165 virtual MacroMatch *clone_macro_match_impl () const = 0;
168 // A token is a kind of token tree (except delimiter tokens)
169 class Token : public TokenTree, public MacroMatch
171 // A token is a kind of token tree (except delimiter tokens)
172 // A token is a kind of MacroMatch (except $ and delimiter tokens)
173 #if 0
174 // TODO: improve member variables - current ones are the same as lexer token
175 // Token kind.
176 TokenId token_id;
177 // Token location.
178 location_t locus;
179 // Associated text (if any) of token.
180 std::string str;
181 // Token type hint (if any).
182 PrimitiveCoreType type_hint;
183 #endif
185 const_TokenPtr tok_ref;
187 /* new idea: wrapper around const_TokenPtr used for heterogeneuous storage
188 * in token trees. rather than convert back and forth when parsing macros,
189 * just wrap it. */
191 public:
192 // Unique pointer custom clone function
193 std::unique_ptr<Token> clone_token () const
195 return std::unique_ptr<Token> (clone_token_impl ());
198 #if 0
199 /* constructor from general text - avoid using if lexer const_TokenPtr is
200 * available */
201 Token (TokenId token_id, location_t locus, std::string str,
202 PrimitiveCoreType type_hint)
203 : token_id (token_id), locus (locus), str (std::move (str)),
204 type_hint (type_hint)
206 #endif
207 // not doable with new implementation - will have to make a const_TokenPtr
209 // Constructor from lexer const_TokenPtr
210 #if 0
211 /* TODO: find workaround for std::string being nullptr - probably have to
212 * introduce new method in lexer Token, or maybe make conversion method
213 * there */
214 Token (const_TokenPtr lexer_token_ptr)
215 : token_id (lexer_token_ptr->get_id ()),
216 locus (lexer_token_ptr->get_locus ()), str (""),
217 type_hint (lexer_token_ptr->get_type_hint ())
219 // FIXME: change to "should have str" later?
220 if (lexer_token_ptr->has_str ())
222 str = lexer_token_ptr->get_str ();
224 // DEBUG
225 rust_debug ("ast token created with str '%s'", str.c_str ());
227 else
229 // FIXME: is this returning correct thing?
230 str = lexer_token_ptr->get_token_description ();
232 // DEBUG
233 rust_debug ("ast token created with string '%s'", str.c_str ());
236 // DEBUG
237 if (lexer_token_ptr->should_have_str () && !lexer_token_ptr->has_str ())
239 rust_debug (
240 "BAD: for token '%s', should have string but does not!",
241 lexer_token_ptr->get_token_description ());
244 #endif
245 Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
247 bool is_string_lit () const
249 switch (get_id ())
251 case STRING_LITERAL:
252 case BYTE_STRING_LITERAL:
253 return true;
254 default:
255 return false;
259 std::string as_string () const override;
260 location_t get_match_locus () const override
262 return tok_ref->get_locus ();
265 void accept_vis (ASTVisitor &vis) override;
267 // Return copy of itself but in token stream form.
268 std::vector<std::unique_ptr<Token>> to_token_stream () const override;
270 TokenId get_id () const { return tok_ref->get_id (); }
271 const std::string &get_str () const { return tok_ref->get_str (); }
273 location_t get_locus () const { return tok_ref->get_locus (); }
275 PrimitiveCoreType get_type_hint () const { return tok_ref->get_type_hint (); }
277 // Get a new token pointer copy.
278 const_TokenPtr get_tok_ptr () const { return tok_ref; }
280 MacroMatchType get_macro_match_type () const override
282 return MacroMatchType::Tok;
285 protected:
286 // No virtual for now as not polymorphic but can be in future
287 /*virtual*/ Token *clone_token_impl () const { return new Token (*this); }
289 /* Use covariance to implement clone function as returning this object
290 * rather than base */
291 Token *clone_token_tree_impl () const final override
293 return clone_token_impl ();
296 /* Use covariance to implement clone function as returning this object
297 * rather than base */
298 Token *clone_macro_match_impl () const final override
300 return clone_token_impl ();
304 // A literal - value with a type. Used in LiteralExpr and LiteralPattern.
305 struct Literal
307 public:
308 enum LitType
310 CHAR,
311 STRING,
312 BYTE,
313 BYTE_STRING,
314 INT,
315 FLOAT,
316 BOOL,
317 ERROR
320 private:
321 /* TODO: maybe make subclasses of each type of literal with their typed
322 * values (or generics) */
323 std::string value_as_string;
324 LitType type;
325 PrimitiveCoreType type_hint;
327 public:
328 std::string as_string () const { return value_as_string; }
330 LitType get_lit_type () const { return type; }
332 PrimitiveCoreType get_type_hint () const { return type_hint; }
334 Literal (std::string value_as_string, LitType type,
335 PrimitiveCoreType type_hint)
336 : value_as_string (std::move (value_as_string)), type (type),
337 type_hint (type_hint)
340 static Literal create_error ()
342 return Literal ("", ERROR, PrimitiveCoreType::CORETYPE_UNKNOWN);
345 // Returns whether literal is in an invalid state.
346 bool is_error () const { return type == ERROR; }
349 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
350 * to be defined */
351 class AttrInputLiteral;
353 /* TODO: move applicable stuff into here or just don't include it because
354 * nothing uses it A segment of a path (maybe) */
355 class PathSegment
357 public:
358 virtual ~PathSegment () {}
360 virtual std::string as_string () const = 0;
362 // TODO: add visitor here?
365 // A segment of a simple path without generic or type arguments
366 class SimplePathSegment : public PathSegment
368 std::string segment_name;
369 location_t locus;
370 NodeId node_id;
372 // only allow identifiers, "super", "self", "crate", or "$crate"
373 public:
374 // TODO: put checks in constructor to enforce this rule?
375 SimplePathSegment (std::string segment_name, location_t locus)
376 : segment_name (std::move (segment_name)), locus (locus),
377 node_id (Analysis::Mappings::get ()->get_next_node_id ())
380 /* Returns whether simple path segment is in an invalid state (currently, if
381 * empty). */
382 bool is_error () const { return segment_name.empty (); }
384 // Creates an error SimplePathSegment
385 static SimplePathSegment create_error ()
387 return SimplePathSegment (std::string (""), UNDEF_LOCATION);
390 std::string as_string () const override;
392 location_t get_locus () const { return locus; }
393 NodeId get_node_id () const { return node_id; }
394 const std::string &get_segment_name () const { return segment_name; }
395 bool is_super_path_seg () const
397 return as_string ().compare (Values::Keywords::SUPER) == 0;
399 bool is_crate_path_seg () const
401 return as_string ().compare (Values::Keywords::CRATE) == 0;
403 bool is_lower_self_seg () const
405 return as_string ().compare (Values::Keywords::SELF) == 0;
407 bool is_big_self () const
409 return as_string ().compare (Values::Keywords::SELF_ALIAS) == 0;
413 // A simple path without generic or type arguments
414 class SimplePath
416 bool opening_scope_resolution;
417 std::vector<SimplePathSegment> segments;
418 location_t locus;
419 NodeId node_id;
421 public:
422 // Constructor
423 SimplePath (std::vector<SimplePathSegment> path_segments,
424 bool has_opening_scope_resolution = false,
425 location_t locus = UNDEF_LOCATION)
426 : opening_scope_resolution (has_opening_scope_resolution),
427 segments (std::move (path_segments)), locus (locus),
428 node_id (Analysis::Mappings::get ()->get_next_node_id ())
431 SimplePath (Identifier ident)
432 : opening_scope_resolution (false),
433 segments ({SimplePathSegment (ident.as_string (), ident.get_locus ())}),
434 locus (ident.get_locus ()),
435 node_id (Analysis::Mappings::get ()->get_next_node_id ())
438 // Creates an empty SimplePath.
439 static SimplePath create_empty ()
441 return SimplePath (std::vector<SimplePathSegment> ());
444 // Returns whether the SimplePath is empty, i.e. has path segments.
445 bool is_empty () const { return segments.empty (); }
447 const std::string as_string () const;
449 bool has_opening_scope_resolution () const
451 return opening_scope_resolution;
454 location_t get_locus () const { return locus; }
455 NodeId get_node_id () const { return node_id; }
457 // does this need visitor if not polymorphic? probably not
459 // path-to-string comparison operator
460 bool operator== (const std::string &rhs) const
462 return !opening_scope_resolution && segments.size () == 1
463 && segments[0].as_string () == rhs;
466 /* Creates a single-segment SimplePath from a string. This will not check to
467 * ensure that this is a valid identifier in path, so be careful. Also, this
468 * will have no location data.
469 * TODO have checks? */
470 static SimplePath from_str (std::string str, location_t locus)
472 std::vector<AST::SimplePathSegment> single_segments
473 = {AST::SimplePathSegment (std::move (str), locus)};
474 return SimplePath (std::move (single_segments), false, locus);
477 const std::vector<SimplePathSegment> &get_segments () const
479 return segments;
482 std::vector<SimplePathSegment> &get_segments () { return segments; }
484 const SimplePathSegment &get_final_segment () const
486 return segments.back ();
490 // path-to-string inverse comparison operator
491 inline bool
492 operator!= (const SimplePath &lhs, const std::string &rhs)
494 return !(lhs == rhs);
497 // forward decl for Attribute
498 class AttrInput;
500 // Visibility of item - if the item has it, then it is some form of public
501 struct Visibility
503 public:
504 enum VisType
506 PRIV,
507 PUB,
508 PUB_CRATE,
509 PUB_SELF,
510 PUB_SUPER,
511 PUB_IN_PATH
514 private:
515 VisType vis_type;
516 // Only assigned if vis_type is IN_PATH
517 SimplePath in_path;
518 location_t locus;
520 // should this store location info?
522 public:
523 // Creates a Visibility - TODO make constructor protected or private?
524 Visibility (VisType vis_type, SimplePath in_path, location_t locus)
525 : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
528 VisType get_vis_type () const { return vis_type; }
530 // Returns whether visibility is in an error state.
531 bool is_error () const
533 return vis_type == PUB_IN_PATH && in_path.is_empty ();
536 // Returns whether a visibility has a path
537 bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; }
539 // Returns whether visibility is public or not.
540 bool is_public () const { return vis_type != PRIV && !is_error (); }
542 location_t get_locus () const { return locus; }
544 // empty?
545 // Creates an error visibility.
546 static Visibility create_error ()
548 return Visibility (PUB_IN_PATH, SimplePath::create_empty (),
549 UNDEF_LOCATION);
552 // Unique pointer custom clone function
553 /*std::unique_ptr<Visibility> clone_visibility() const {
554 return std::unique_ptr<Visibility>(clone_visibility_impl());
557 /* TODO: think of a way to only allow valid Visibility states - polymorphism
558 * is one idea but may be too resource-intensive. */
560 // Creates a public visibility with no further features/arguments.
561 // empty?
562 static Visibility create_public (location_t pub_vis_location)
564 return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
567 // Creates a public visibility with crate-relative paths
568 static Visibility create_crate (location_t crate_tok_location,
569 location_t crate_vis_location)
571 return Visibility (PUB_CRATE,
572 SimplePath::from_str (Values::Keywords::CRATE,
573 crate_tok_location),
574 crate_vis_location);
577 // Creates a public visibility with self-relative paths
578 static Visibility create_self (location_t self_tok_location,
579 location_t self_vis_location)
581 return Visibility (PUB_SELF,
582 SimplePath::from_str (Values::Keywords::SELF,
583 self_tok_location),
584 self_vis_location);
587 // Creates a public visibility with parent module-relative paths
588 static Visibility create_super (location_t super_tok_location,
589 location_t super_vis_location)
591 return Visibility (PUB_SUPER,
592 SimplePath::from_str (Values::Keywords::SUPER,
593 super_tok_location),
594 super_vis_location);
597 // Creates a private visibility
598 static Visibility create_private ()
600 return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
603 // Creates a public visibility with a given path or whatever.
604 static Visibility create_in_path (SimplePath in_path,
605 location_t in_path_vis_location)
607 return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
610 std::string as_string () const;
611 const SimplePath &get_path () const { return in_path; }
612 SimplePath &get_path () { return in_path; }
614 protected:
615 // Clone function implementation - not currently virtual but may be if
616 // polymorphism used
617 /*virtual*/ Visibility *clone_visibility_impl () const
619 return new Visibility (*this);
623 // aka Attr
624 // Attribute AST representation
625 struct Attribute
627 private:
628 SimplePath path;
630 // bool has_attr_input;
631 std::unique_ptr<AttrInput> attr_input;
633 location_t locus;
635 bool inner_attribute;
637 // TODO: maybe a variable storing whether attr input is parsed or not
639 public:
640 // Returns whether Attribute has AttrInput
641 bool has_attr_input () const { return attr_input != nullptr; }
643 // Constructor has pointer AttrInput for polymorphism reasons
644 Attribute (SimplePath path, std::unique_ptr<AttrInput> input,
645 location_t locus = UNDEF_LOCATION, bool inner_attribute = false)
646 : path (std::move (path)), attr_input (std::move (input)), locus (locus),
647 inner_attribute (inner_attribute)
650 bool is_derive () const;
652 std::vector<std::reference_wrapper<AST::SimplePath>> get_traits_to_derive ();
654 // default destructor
655 ~Attribute () = default;
657 // no point in being defined inline as requires virtual call anyway
658 Attribute (const Attribute &other);
660 // no point in being defined inline as requires virtual call anyway
661 Attribute &operator= (const Attribute &other);
663 // default move semantics
664 Attribute (Attribute &&other) = default;
665 Attribute &operator= (Attribute &&other) = default;
667 // Unique pointer custom clone function
668 std::unique_ptr<Attribute> clone_attribute () const
670 return std::unique_ptr<Attribute> (clone_attribute_impl ());
673 // Creates an empty attribute (which is invalid)
674 static Attribute create_empty ()
676 return Attribute (SimplePath::create_empty (), nullptr);
679 // Returns whether the attribute is considered an "empty" attribute.
680 bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
682 location_t get_locus () const { return locus; }
684 AttrInput &get_attr_input () const { return *attr_input; }
686 /* e.g.:
687 #![crate_type = "lib"]
688 #[test]
689 #[cfg(target_os = "linux")]
690 #[allow(non_camel_case_types)]
691 #![allow(unused_variables)]
694 // Full built-in attribute list:
695 /* cfg
696 * cfg_attr
697 * test
698 * ignore
699 * should_panic
700 * derive
701 * macro_export
702 * macro_use
703 * proc_macro
704 * proc_macro_derive
705 * proc_macro_attribute
706 * allow
707 * warn
708 * deny
709 * forbid
710 * deprecated
711 * must_use
712 * link
713 * link_name
714 * no_link
715 * repr
716 * crate_type
717 * no_main
718 * export_name
719 * link_section
720 * no_mangle
721 * used
722 * crate_name
723 * inline
724 * cold
725 * no_builtins
726 * target_feature
727 * doc
728 * no_std
729 * no_implicit_prelude
730 * path
731 * recursion_limit
732 * type_length_limit
733 * panic_handler
734 * global_allocator
735 * windows_subsystem
736 * feature */
738 std::string as_string () const;
740 bool is_inner_attribute () const { return inner_attribute; }
742 // no visitor pattern as not currently polymorphic
744 const SimplePath &get_path () const { return path; }
745 SimplePath &get_path () { return path; }
747 // Call to parse attribute body to meta item syntax.
748 void parse_attr_to_meta_item ();
750 /* Determines whether cfg predicate is true and item with attribute should
751 * not be stripped. Attribute body must already be parsed to meta item. */
752 bool check_cfg_predicate (const Session &session) const;
754 // Returns whether body has been parsed to meta item form or not.
755 bool is_parsed_to_meta_item () const;
757 /* Returns any attributes generated from cfg_attr attributes. Attribute body
758 * must already be parsed to meta item. */
759 std::vector<Attribute> separate_cfg_attrs () const;
761 protected:
762 // not virtual as currently no subclasses of Attribute, but could be in
763 // future
764 /*virtual*/ Attribute *clone_attribute_impl () const
766 return new Attribute (*this);
770 // Attribute body - abstract base class
771 class AttrInput : public Visitable
773 public:
774 enum AttrInputType
776 LITERAL,
777 MACRO,
778 META_ITEM,
779 TOKEN_TREE,
782 virtual ~AttrInput () {}
784 // Unique pointer custom clone function
785 std::unique_ptr<AttrInput> clone_attr_input () const
787 return std::unique_ptr<AttrInput> (clone_attr_input_impl ());
790 virtual std::string as_string () const = 0;
792 virtual bool check_cfg_predicate (const Session &session) const = 0;
794 // Parse attribute input to meta item, if possible
795 virtual AttrInput *parse_to_meta_item () const { return nullptr; }
797 virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; }
799 // Returns whether attr input has been parsed to meta item syntax.
800 virtual bool is_meta_item () const = 0;
802 virtual AttrInputType get_attr_input_type () const = 0;
804 protected:
805 // pure virtual clone implementation
806 virtual AttrInput *clone_attr_input_impl () const = 0;
809 // Forward decl - defined in rust-macro.h
810 class MetaNameValueStr;
812 // abstract base meta item inner class
813 class MetaItemInner : public Visitable
815 protected:
816 // pure virtual as MetaItemInner
817 virtual MetaItemInner *clone_meta_item_inner_impl () const = 0;
819 public:
820 enum class Kind
822 LitExpr,
823 MetaItem,
826 // Unique pointer custom clone function
827 std::unique_ptr<MetaItemInner> clone_meta_item_inner () const
829 return std::unique_ptr<MetaItemInner> (clone_meta_item_inner_impl ());
832 virtual Kind get_kind () = 0;
834 virtual ~MetaItemInner ();
836 virtual location_t get_locus () const = 0;
838 virtual std::string as_string () const = 0;
840 /* HACK: used to simplify parsing - creates a copy of that type, or returns
841 * null */
842 virtual std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const;
844 // HACK: used to simplify parsing - same thing
845 virtual SimplePath to_path_item () const
847 return SimplePath::create_empty ();
850 virtual Attribute to_attribute () const { return Attribute::create_empty (); }
852 virtual bool check_cfg_predicate (const Session &session) const = 0;
854 virtual bool is_key_value_pair () const { return false; }
857 // Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
858 class AttrInputMetaItemContainer : public AttrInput
860 std::vector<std::unique_ptr<MetaItemInner>> items;
862 public:
863 AttrInputMetaItemContainer (std::vector<std::unique_ptr<MetaItemInner>> items)
864 : items (std::move (items))
867 // copy constructor with vector clone
868 AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other)
870 items.reserve (other.items.size ());
871 for (const auto &e : other.items)
872 items.push_back (e->clone_meta_item_inner ());
875 // copy assignment operator with vector clone
876 AttrInputMetaItemContainer &
877 operator= (const AttrInputMetaItemContainer &other)
879 AttrInput::operator= (other);
881 items.reserve (other.items.size ());
882 for (const auto &e : other.items)
883 items.push_back (e->clone_meta_item_inner ());
885 return *this;
888 // default move constructors
889 AttrInputMetaItemContainer (AttrInputMetaItemContainer &&other) = default;
890 AttrInputMetaItemContainer &operator= (AttrInputMetaItemContainer &&other)
891 = default;
893 std::string as_string () const override;
895 void accept_vis (ASTVisitor &vis) override;
897 bool check_cfg_predicate (const Session &session) const override;
899 AttrInputType get_attr_input_type () const final override
901 return AttrInput::AttrInputType::META_ITEM;
904 // Clones this object.
905 std::unique_ptr<AttrInputMetaItemContainer>
906 clone_attr_input_meta_item_container () const
908 return std::unique_ptr<AttrInputMetaItemContainer> (
909 clone_attr_input_meta_item_container_impl ());
912 std::vector<Attribute> separate_cfg_attrs () const override;
914 bool is_meta_item () const override { return true; }
916 // TODO: this mutable getter seems dodgy
917 std::vector<std::unique_ptr<MetaItemInner>> &get_items () { return items; }
918 const std::vector<std::unique_ptr<MetaItemInner>> &get_items () const
920 return items;
923 protected:
924 // Use covariance to implement clone function as returning this type
925 AttrInputMetaItemContainer *clone_attr_input_impl () const final override
927 return clone_attr_input_meta_item_container_impl ();
930 AttrInputMetaItemContainer *clone_attr_input_meta_item_container_impl () const
932 return new AttrInputMetaItemContainer (*this);
936 // A token tree with delimiters
937 class DelimTokenTree : public TokenTree, public AttrInput
939 DelimType delim_type;
940 std::vector<std::unique_ptr<TokenTree>> token_trees;
941 location_t locus;
943 protected:
944 DelimTokenTree *clone_delim_tok_tree_impl () const
946 return new DelimTokenTree (*this);
949 /* Use covariance to implement clone function as returning a DelimTokenTree
950 * object */
951 DelimTokenTree *clone_attr_input_impl () const final override
953 return clone_delim_tok_tree_impl ();
956 /* Use covariance to implement clone function as returning a DelimTokenTree
957 * object */
958 DelimTokenTree *clone_token_tree_impl () const final override
960 return clone_delim_tok_tree_impl ();
963 public:
964 DelimTokenTree (DelimType delim_type,
965 std::vector<std::unique_ptr<TokenTree>> token_trees
966 = std::vector<std::unique_ptr<TokenTree>> (),
967 location_t locus = UNDEF_LOCATION)
968 : delim_type (delim_type), token_trees (std::move (token_trees)),
969 locus (locus)
972 // Copy constructor with vector clone
973 DelimTokenTree (DelimTokenTree const &other)
974 : delim_type (other.delim_type), locus (other.locus)
976 token_trees.clear ();
977 token_trees.reserve (other.token_trees.size ());
978 for (const auto &e : other.token_trees)
979 token_trees.push_back (e->clone_token_tree ());
982 // overloaded assignment operator with vector clone
983 DelimTokenTree &operator= (DelimTokenTree const &other)
985 delim_type = other.delim_type;
986 locus = other.locus;
988 token_trees.clear ();
989 token_trees.reserve (other.token_trees.size ());
990 for (const auto &e : other.token_trees)
991 token_trees.push_back (e->clone_token_tree ());
993 return *this;
996 // move constructors
997 DelimTokenTree (DelimTokenTree &&other) = default;
998 DelimTokenTree &operator= (DelimTokenTree &&other) = default;
1000 static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
1002 std::string as_string () const override;
1004 void accept_vis (ASTVisitor &vis) override;
1006 bool check_cfg_predicate (const Session &) const override
1008 // this should never be called - should be converted first
1009 rust_assert (false);
1010 return false;
1013 AttrInputMetaItemContainer *parse_to_meta_item () const override;
1015 std::vector<std::unique_ptr<Token>> to_token_stream () const override;
1017 std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
1019 return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
1022 bool is_meta_item () const override { return false; }
1024 AttrInputType get_attr_input_type () const final override
1026 return AttrInput::AttrInputType::TOKEN_TREE;
1029 std::vector<std::unique_ptr<TokenTree>> &get_token_trees ()
1031 return token_trees;
1034 const std::vector<std::unique_ptr<TokenTree>> &get_token_trees () const
1036 return token_trees;
1039 DelimType get_delim_type () const { return delim_type; }
1042 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
1043 * to be defined */
1044 class AttrInputLiteral;
1046 // abstract base meta item class
1047 class MetaItem : public MetaItemInner
1049 public:
1050 enum class ItemKind
1052 Path,
1053 Word,
1054 NameValueStr,
1055 PathLit,
1056 Seq,
1057 ListPaths,
1058 ListNameValueStr,
1061 MetaItemInner::Kind get_kind () override
1063 return MetaItemInner::Kind::MetaItem;
1066 virtual ItemKind get_item_kind () const = 0;
1069 // Forward decl - defined in rust-expr.h
1070 class MetaItemLitExpr;
1072 // Forward decl - defined in rust-expr.h
1073 class MetaItemPathLit;
1075 // Forward decl - defined in rust-macro.h
1076 class MetaItemPath;
1078 // Forward decl - defined in rust-macro.h
1079 class MetaItemSeq;
1081 // Forward decl - defined in rust-macro.h
1082 class MetaWord;
1084 // Forward decl - defined in rust-macro.h
1085 class MetaListPaths;
1087 // Forward decl - defined in rust-macro.h
1088 class MetaListNameValueStr;
1090 /* Base statement abstract class. Note that most "statements" are not allowed
1091 * in top-level module scope - only a subclass of statements called "items"
1092 * are. */
1093 class Stmt : public Node
1095 public:
1096 enum class Kind
1098 Empty,
1099 Item,
1100 Let,
1101 Expr,
1102 MacroInvocation,
1105 // Unique pointer custom clone function
1106 std::unique_ptr<Stmt> clone_stmt () const
1108 return std::unique_ptr<Stmt> (clone_stmt_impl ());
1111 virtual ~Stmt () {}
1113 virtual std::string as_string () const = 0;
1115 virtual location_t get_locus () const = 0;
1117 virtual void mark_for_strip () = 0;
1118 virtual bool is_marked_for_strip () const = 0;
1119 NodeId get_node_id () const { return node_id; }
1121 virtual Kind get_stmt_kind () = 0;
1123 // TODO: Can we remove these two?
1124 virtual bool is_item () const = 0;
1125 virtual bool is_expr () const { return false; }
1127 virtual void add_semicolon () {}
1129 protected:
1130 Stmt () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1132 // Clone function implementation as pure virtual method
1133 virtual Stmt *clone_stmt_impl () const = 0;
1135 NodeId node_id;
1138 // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
1139 class Item : public Stmt
1141 public:
1142 // Unique pointer custom clone function
1143 std::unique_ptr<Item> clone_item () const
1145 return std::unique_ptr<Item> (clone_item_impl ());
1148 /* Adds crate names to the vector passed by reference, if it can
1149 * (polymorphism). TODO: remove, unused. */
1150 virtual void
1151 add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
1154 Stmt::Kind get_stmt_kind () final { return Stmt::Kind::Item; }
1156 // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
1157 // behavior that we have items that can also be expressions?
1158 bool is_item () const override { return true; }
1160 virtual std::vector<Attribute> &get_outer_attrs () = 0;
1161 virtual const std::vector<Attribute> &get_outer_attrs () const = 0;
1163 virtual bool has_outer_attrs () const { return !get_outer_attrs ().empty (); }
1165 protected:
1166 // Clone function implementation as pure virtual method
1167 virtual Item *clone_item_impl () const = 0;
1169 /* Save having to specify two clone methods in derived classes by making
1170 * statement clone return item clone. Hopefully won't affect performance too
1171 * much. */
1172 Item *clone_stmt_impl () const final override { return clone_item_impl (); }
1175 // Item that supports visibility - abstract base class
1176 class VisItem : public Item
1178 Visibility visibility;
1179 std::vector<Attribute> outer_attrs;
1181 protected:
1182 // Visibility constructor
1183 VisItem (Visibility visibility,
1184 std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
1185 : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
1188 // Visibility copy constructor
1189 VisItem (VisItem const &other)
1190 : visibility (other.visibility), outer_attrs (other.outer_attrs)
1193 // Overload assignment operator to clone
1194 VisItem &operator= (VisItem const &other)
1196 visibility = other.visibility;
1197 outer_attrs = other.outer_attrs;
1199 return *this;
1202 // move constructors
1203 VisItem (VisItem &&other) = default;
1204 VisItem &operator= (VisItem &&other) = default;
1206 public:
1207 /* Does the item have some kind of public visibility (non-default
1208 * visibility)? */
1209 bool has_visibility () const { return visibility.is_public (); }
1211 std::string as_string () const override;
1213 // TODO: this mutable getter seems really dodgy. Think up better way.
1214 Visibility &get_visibility () { return visibility; }
1215 const Visibility &get_visibility () const { return visibility; }
1217 std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1218 const std::vector<Attribute> &get_outer_attrs () const override
1220 return outer_attrs;
1223 // forward decl of ExprWithoutBlock
1224 class ExprWithoutBlock;
1226 // Base expression AST node - abstract
1227 class Expr : public Node
1229 public:
1230 // Unique pointer custom clone function
1231 std::unique_ptr<Expr> clone_expr () const
1233 return std::unique_ptr<Expr> (clone_expr_impl ());
1236 /* TODO: public methods that could be useful:
1237 * - get_type() - returns type of expression. set_type() may also be useful
1238 * for some?
1239 * - evaluate() - evaluates expression if constant? can_evaluate()? */
1241 virtual std::string as_string () const = 0;
1243 virtual ~Expr () {}
1245 virtual location_t get_locus () const = 0;
1247 virtual bool is_literal () const { return false; }
1249 // HACK: strictly not needed, but faster than full downcast clone
1250 virtual bool is_expr_without_block () const = 0;
1252 virtual void mark_for_strip () = 0;
1253 virtual bool is_marked_for_strip () const = 0;
1255 virtual NodeId get_node_id () const { return node_id; }
1257 virtual void set_node_id (NodeId id) { node_id = id; }
1259 virtual std::vector<Attribute> &get_outer_attrs () = 0;
1261 // TODO: think of less hacky way to implement this kind of thing
1262 // Sets outer attributes.
1263 virtual void set_outer_attrs (std::vector<Attribute>) = 0;
1265 protected:
1266 // Constructor
1267 Expr () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1269 // Clone function implementation as pure virtual method
1270 virtual Expr *clone_expr_impl () const = 0;
1272 NodeId node_id;
1275 // AST node for an expression without an accompanying block - abstract
1276 class ExprWithoutBlock : public Expr
1278 protected:
1279 // pure virtual clone implementation
1280 virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
1282 /* Save having to specify two clone methods in derived classes by making
1283 * expr clone return exprwithoutblock clone. Hopefully won't affect
1284 * performance too much. */
1285 ExprWithoutBlock *clone_expr_impl () const final override
1287 return clone_expr_without_block_impl ();
1290 bool is_expr_without_block () const final override { return true; };
1292 public:
1293 // Unique pointer custom clone function
1294 std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
1296 return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
1300 /* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1301 * Pratt parser */
1302 /* Alternatively, identifiers could just be represented as single-segment
1303 * paths
1305 class IdentifierExpr : public ExprWithoutBlock
1307 std::vector<Attribute> outer_attrs;
1308 Identifier ident;
1309 location_t locus;
1311 public:
1312 IdentifierExpr (Identifier ident, std::vector<Attribute> outer_attrs,
1313 location_t locus)
1314 : outer_attrs (std::move (outer_attrs)), ident (std::move (ident)),
1315 locus (locus)
1318 std::string as_string () const override { return ident.as_string (); }
1320 location_t get_locus () const override final { return locus; }
1322 Identifier get_ident () const { return ident; }
1324 void accept_vis (ASTVisitor &vis) override;
1326 // Clones this object.
1327 std::unique_ptr<IdentifierExpr> clone_identifier_expr () const
1329 return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
1332 // "Error state" if ident is empty, so base stripping on this.
1333 void mark_for_strip () override { ident = {""}; }
1334 bool is_marked_for_strip () const override { return ident.empty (); }
1336 const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
1337 std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1339 void set_outer_attrs (std::vector<Attribute> new_attrs) override
1341 outer_attrs = std::move (new_attrs);
1344 Kind get_ast_kind () const override { return Kind::IDENTIFIER; }
1346 protected:
1347 // Clone method implementation
1348 IdentifierExpr *clone_expr_without_block_impl () const final override
1350 return clone_identifier_expr_impl ();
1353 IdentifierExpr *clone_identifier_expr_impl () const
1355 return new IdentifierExpr (*this);
1359 // Pattern base AST node
1360 class Pattern : public Visitable
1362 public:
1363 enum class Kind
1365 Literal,
1366 Identifier,
1367 Wildcard,
1368 Rest,
1369 Range,
1370 Reference,
1371 Struct,
1372 TupleStruct,
1373 Tuple,
1374 Grouped,
1375 Slice,
1376 Alt,
1377 Path,
1378 MacroInvocation,
1381 // Unique pointer custom clone function
1382 std::unique_ptr<Pattern> clone_pattern () const
1384 return std::unique_ptr<Pattern> (clone_pattern_impl ());
1387 virtual Kind get_pattern_kind () = 0;
1389 // possible virtual methods: is_refutable()
1391 virtual ~Pattern () {}
1393 virtual std::string as_string () const = 0;
1395 // as only one kind of pattern can be stripped, have default of nothing
1396 virtual void mark_for_strip () {}
1397 virtual bool is_marked_for_strip () const { return false; }
1399 virtual location_t get_locus () const = 0;
1400 virtual NodeId get_node_id () const = 0;
1402 protected:
1403 // Clone pattern implementation as pure virtual method
1404 virtual Pattern *clone_pattern_impl () const = 0;
1407 // forward decl for Type
1408 class TraitBound;
1410 // Base class for types as represented in AST - abstract
1411 class Type : public Node
1413 public:
1414 // Unique pointer custom clone function
1415 std::unique_ptr<Type> clone_type () const
1417 return std::unique_ptr<Type> (clone_type_impl ());
1420 // virtual destructor
1421 virtual ~Type () {}
1423 virtual std::string as_string () const = 0;
1425 /* HACK: convert to trait bound. Virtual method overriden by classes that
1426 * enable this. */
1427 virtual TraitBound *to_trait_bound (bool) const { return nullptr; }
1428 /* as pointer, shouldn't require definition beforehand, only forward
1429 * declaration. */
1431 // as only two kinds of types can be stripped, have default of nothing
1432 virtual void mark_for_strip () {}
1433 virtual bool is_marked_for_strip () const { return false; }
1435 virtual location_t get_locus () const = 0;
1437 NodeId get_node_id () const { return node_id; }
1439 protected:
1440 Type () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1442 // Clone function implementation as pure virtual method
1443 virtual Type *clone_type_impl () const = 0;
1445 NodeId node_id;
1448 // A type without parentheses? - abstract
1449 class TypeNoBounds : public Type
1451 public:
1452 // Unique pointer custom clone function
1453 std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
1455 return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
1458 protected:
1459 // Clone function implementation as pure virtual method
1460 virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
1462 /* Save having to specify two clone methods in derived classes by making
1463 * type clone return typenobounds clone. Hopefully won't affect performance
1464 * too much. */
1465 TypeNoBounds *clone_type_impl () const final override
1467 return clone_type_no_bounds_impl ();
1470 TypeNoBounds () : Type () {}
1473 /* Abstract base class representing a type param bound - Lifetime and
1474 * TraitBound extends it */
1475 class TypeParamBound : public Visitable
1477 public:
1478 virtual ~TypeParamBound () {}
1480 // Unique pointer custom clone function
1481 std::unique_ptr<TypeParamBound> clone_type_param_bound () const
1483 return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
1486 virtual std::string as_string () const = 0;
1488 NodeId get_node_id () const { return node_id; }
1490 virtual location_t get_locus () const = 0;
1492 protected:
1493 // Clone function implementation as pure virtual method
1494 virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
1496 TypeParamBound (NodeId node_id) : node_id (node_id) {}
1498 NodeId node_id;
1501 // Represents a lifetime (and is also a kind of type param bound)
1502 class Lifetime : public TypeParamBound
1504 public:
1505 enum LifetimeType
1507 NAMED, // corresponds to LIFETIME_OR_LABEL
1508 STATIC, // corresponds to 'static
1509 WILDCARD // corresponds to '_
1512 private:
1513 LifetimeType lifetime_type;
1514 std::string lifetime_name;
1515 location_t locus;
1516 NodeId node_id;
1518 public:
1519 // Constructor
1520 Lifetime (LifetimeType type, std::string name = std::string (),
1521 location_t locus = UNDEF_LOCATION)
1522 : TypeParamBound (Analysis::Mappings::get ()->get_next_node_id ()),
1523 lifetime_type (type), lifetime_name (std::move (name)), locus (locus)
1526 Lifetime (NodeId id, LifetimeType type, std::string name = std::string (),
1527 location_t locus = UNDEF_LOCATION)
1528 : TypeParamBound (id), lifetime_type (type),
1529 lifetime_name (std::move (name)), locus (locus)
1532 // Creates an "error" lifetime.
1533 static Lifetime error () { return Lifetime (NAMED, ""); }
1535 static Lifetime elided () { return Lifetime (WILDCARD, ""); }
1537 // Returns true if the lifetime is in an error state.
1538 bool is_error () const
1540 return lifetime_type == NAMED && lifetime_name.empty ();
1543 std::string as_string () const override;
1545 void accept_vis (ASTVisitor &vis) override;
1547 LifetimeType get_lifetime_type () { return lifetime_type; }
1549 location_t get_locus () const override final { return locus; }
1551 std::string get_lifetime_name () const { return lifetime_name; }
1553 protected:
1554 /* Use covariance to implement clone function as returning this object
1555 * rather than base */
1556 Lifetime *clone_type_param_bound_impl () const override
1558 return new Lifetime (node_id, lifetime_type, lifetime_name, locus);
1562 /* Base generic parameter in AST. Abstract - can be represented by a Lifetime
1563 * or Type param */
1564 class GenericParam : public Visitable
1566 public:
1567 enum class Kind
1569 Lifetime,
1570 Type,
1571 Const,
1574 virtual ~GenericParam () {}
1576 // Unique pointer custom clone function
1577 std::unique_ptr<GenericParam> clone_generic_param () const
1579 return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
1582 virtual std::string as_string () const = 0;
1584 virtual location_t get_locus () const = 0;
1586 virtual Kind get_kind () const = 0;
1588 NodeId get_node_id () { return node_id; }
1590 protected:
1591 GenericParam () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1592 GenericParam (NodeId node_id) : node_id (node_id) {}
1594 // Clone function implementation as pure virtual method
1595 virtual GenericParam *clone_generic_param_impl () const = 0;
1597 NodeId node_id;
1600 // A lifetime generic parameter (as opposed to a type generic parameter)
1601 class LifetimeParam : public GenericParam
1603 Lifetime lifetime;
1604 std::vector<Lifetime> lifetime_bounds;
1605 Attribute outer_attr;
1606 location_t locus;
1608 public:
1609 Lifetime get_lifetime () const { return lifetime; }
1611 Lifetime &get_lifetime () { return lifetime; }
1613 Attribute &get_outer_attribute () { return outer_attr; }
1615 // Returns whether the lifetime param has any lifetime bounds.
1616 bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
1618 std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
1620 // Returns whether the lifetime param has an outer attribute.
1621 bool has_outer_attribute () const { return !outer_attr.is_empty (); }
1623 // Creates an error state lifetime param.
1624 static LifetimeParam create_error ()
1626 return LifetimeParam (Lifetime::error (), {}, Attribute::create_empty (),
1627 UNDEF_LOCATION);
1630 // Returns whether the lifetime param is in an error state.
1631 bool is_error () const { return lifetime.is_error (); }
1633 // Constructor
1634 LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
1635 Attribute outer_attr, location_t locus)
1636 : lifetime (std::move (lifetime)),
1637 lifetime_bounds (std::move (lifetime_bounds)),
1638 outer_attr (std::move (outer_attr)), locus (locus)
1641 std::string as_string () const override;
1643 void accept_vis (ASTVisitor &vis) override;
1645 location_t get_locus () const override final { return locus; }
1647 Kind get_kind () const override final { return Kind::Lifetime; }
1649 protected:
1650 /* Use covariance to implement clone function as returning this object
1651 * rather than base */
1652 LifetimeParam *clone_generic_param_impl () const override
1654 return new LifetimeParam (*this);
1658 class AssociatedItem : public Visitable
1660 protected:
1661 // Clone function implementation as pure virtual method
1662 virtual AssociatedItem *clone_associated_item_impl () const = 0;
1664 public:
1665 virtual ~AssociatedItem () {}
1667 std::unique_ptr<AssociatedItem> clone_associated_item () const
1669 return std::unique_ptr<AssociatedItem> (clone_associated_item_impl ());
1672 virtual std::string as_string () const = 0;
1674 virtual void mark_for_strip () = 0;
1675 virtual bool is_marked_for_strip () const = 0;
1677 virtual location_t get_locus () const = 0;
1680 // Item used in trait declarations - abstract base class
1681 class TraitItem : public AssociatedItem
1683 protected:
1684 TraitItem (location_t locus)
1685 : node_id (Analysis::Mappings::get ()->get_next_node_id ()),
1686 vis (Visibility::create_private ()), locus (locus)
1689 TraitItem (Visibility vis, location_t locus)
1690 : node_id (Analysis::Mappings::get ()->get_next_node_id ()), vis (vis),
1691 locus (locus)
1694 // Clone function implementation as pure virtual method
1695 virtual TraitItem *clone_associated_item_impl () const override = 0;
1697 NodeId node_id;
1698 Visibility vis;
1699 location_t locus;
1701 public:
1702 // Unique pointer custom clone function
1703 std::unique_ptr<TraitItem> clone_trait_item () const
1705 return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
1708 NodeId get_node_id () const { return node_id; }
1709 location_t get_locus () const override { return locus; }
1712 // Abstract base class for an item used inside an extern block
1713 class ExternalItem : public Visitable
1715 public:
1716 ExternalItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1718 ExternalItem (NodeId node_id) : node_id (node_id) {}
1720 virtual ~ExternalItem () {}
1722 // Unique pointer custom clone function
1723 std::unique_ptr<ExternalItem> clone_external_item () const
1725 return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
1728 virtual std::string as_string () const = 0;
1730 virtual void mark_for_strip () = 0;
1731 virtual bool is_marked_for_strip () const = 0;
1733 virtual NodeId get_node_id () const { return node_id; }
1735 protected:
1736 // Clone function implementation as pure virtual method
1737 virtual ExternalItem *clone_external_item_impl () const = 0;
1739 NodeId node_id;
1742 /* Data structure to store the data used in macro invocations and macro
1743 * invocations with semicolons. */
1744 struct MacroInvocData
1746 private:
1747 SimplePath path;
1748 DelimTokenTree token_tree;
1750 // One way of parsing the macro. Probably not applicable for all macros.
1751 std::vector<std::unique_ptr<MetaItemInner>> parsed_items;
1752 bool parsed_to_meta_item = false;
1753 MacroExpander *expander = nullptr;
1755 public:
1756 std::string as_string () const;
1758 MacroInvocData (SimplePath path, DelimTokenTree token_tree)
1759 : path (std::move (path)), token_tree (std::move (token_tree))
1762 // Copy constructor with vector clone
1763 MacroInvocData (const MacroInvocData &other)
1764 : path (other.path), token_tree (other.token_tree),
1765 parsed_to_meta_item (other.parsed_to_meta_item)
1767 parsed_items.reserve (other.parsed_items.size ());
1768 for (const auto &e : other.parsed_items)
1769 parsed_items.push_back (e->clone_meta_item_inner ());
1772 // Copy assignment operator with vector clone
1773 MacroInvocData &operator= (const MacroInvocData &other)
1775 path = other.path;
1776 token_tree = other.token_tree;
1777 parsed_to_meta_item = other.parsed_to_meta_item;
1778 expander = other.expander;
1780 parsed_items.reserve (other.parsed_items.size ());
1781 for (const auto &e : other.parsed_items)
1782 parsed_items.push_back (e->clone_meta_item_inner ());
1784 return *this;
1787 // Move constructors
1788 MacroInvocData (MacroInvocData &&other) = default;
1789 MacroInvocData &operator= (MacroInvocData &&other) = default;
1791 // Invalid if path is empty, so base stripping on that.
1792 void mark_for_strip () { path = SimplePath::create_empty (); }
1793 bool is_marked_for_strip () const { return path.is_empty (); }
1795 // Returns whether the macro has been parsed already.
1796 bool is_parsed () const { return parsed_to_meta_item; }
1797 // TODO: update on other ways of parsing it
1799 // TODO: this mutable getter seems kinda dodgy
1800 DelimTokenTree &get_delim_tok_tree () { return token_tree; }
1801 const DelimTokenTree &get_delim_tok_tree () const { return token_tree; }
1803 // Set the delim token tree of a macro invocation
1804 void set_delim_tok_tree (DelimTokenTree tree) { token_tree = tree; }
1806 // TODO: this mutable getter seems kinda dodgy
1807 SimplePath &get_path () { return path; }
1808 const SimplePath &get_path () const { return path; }
1810 void set_expander (MacroExpander *new_expander) { expander = new_expander; }
1811 MacroExpander *get_expander ()
1813 rust_assert (expander);
1814 return expander;
1817 void
1818 set_meta_item_output (std::vector<std::unique_ptr<MetaItemInner>> new_items)
1820 parsed_items = std::move (new_items);
1822 // TODO: mutable getter seems kinda dodgy
1823 std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
1825 return parsed_items;
1827 const std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items () const
1829 return parsed_items;
1833 class SingleASTNode : public Visitable
1835 public:
1836 enum NodeType
1838 EXPRESSION,
1839 ITEM,
1840 STMT,
1841 EXTERN,
1842 ASSOC_ITEM,
1843 TYPE,
1846 private:
1847 NodeType kind;
1849 // FIXME make this a union
1850 std::unique_ptr<Expr> expr;
1851 std::unique_ptr<Item> item;
1852 std::unique_ptr<Stmt> stmt;
1853 std::unique_ptr<ExternalItem> external_item;
1854 std::unique_ptr<AssociatedItem> assoc_item;
1855 std::unique_ptr<Type> type;
1857 public:
1858 SingleASTNode (std::unique_ptr<Expr> expr)
1859 : kind (EXPRESSION), expr (std::move (expr))
1862 SingleASTNode (std::unique_ptr<Item> item)
1863 : kind (ITEM), item (std::move (item))
1866 SingleASTNode (std::unique_ptr<Stmt> stmt)
1867 : kind (STMT), stmt (std::move (stmt))
1870 SingleASTNode (std::unique_ptr<ExternalItem> item)
1871 : kind (EXTERN), external_item (std::move (item))
1874 SingleASTNode (std::unique_ptr<AssociatedItem> item)
1875 : kind (ASSOC_ITEM), assoc_item (std::move (item))
1878 SingleASTNode (std::unique_ptr<Type> type)
1879 : kind (TYPE), type (std::move (type))
1882 SingleASTNode (SingleASTNode const &other);
1884 SingleASTNode operator= (SingleASTNode const &other);
1886 SingleASTNode (SingleASTNode &&other) = default;
1887 SingleASTNode &operator= (SingleASTNode &&other) = default;
1889 NodeType get_kind () const { return kind; }
1891 std::unique_ptr<Expr> &get_expr ()
1893 rust_assert (kind == EXPRESSION);
1894 return expr;
1897 std::unique_ptr<Item> &get_item ()
1899 rust_assert (kind == ITEM);
1900 return item;
1903 std::unique_ptr<Stmt> &get_stmt ()
1905 rust_assert (kind == STMT);
1906 return stmt;
1910 * Access the inner nodes and take ownership of them.
1911 * You can only call these functions once per node
1914 std::unique_ptr<Stmt> take_stmt ()
1916 rust_assert (!is_error ());
1917 return std::move (stmt);
1920 std::unique_ptr<Expr> take_expr ()
1922 rust_assert (!is_error ());
1923 return std::move (expr);
1926 std::unique_ptr<Item> take_item ()
1928 rust_assert (!is_error ());
1929 return std::move (item);
1932 std::unique_ptr<AssociatedItem> take_trait_item ()
1934 rust_assert (!is_error ());
1935 return std::unique_ptr<AssociatedItem> (
1936 static_cast<AssociatedItem *> (assoc_item.release ()));
1939 std::unique_ptr<ExternalItem> take_external_item ()
1941 rust_assert (!is_error ());
1942 return std::move (external_item);
1945 std::unique_ptr<AssociatedItem> take_assoc_item ()
1947 rust_assert (!is_error ());
1948 return std::move (assoc_item);
1951 std::unique_ptr<AssociatedItem> take_impl_item ()
1953 return take_assoc_item ();
1956 std::unique_ptr<AssociatedItem> take_trait_impl_item ()
1958 return take_assoc_item ();
1961 std::unique_ptr<Type> take_type ()
1963 rust_assert (!is_error ());
1964 return std::move (type);
1967 void accept_vis (ASTVisitor &vis) override;
1969 bool is_error ();
1971 std::string as_string () const;
1974 // A crate AST object - holds all the data for a single compilation unit
1975 struct Crate
1977 std::vector<Attribute> inner_attrs;
1978 // dodgy spacing required here
1979 /* TODO: is it better to have a vector of items here or a module (implicit
1980 * top-level one)? */
1981 std::vector<std::unique_ptr<Item>> items;
1983 NodeId node_id;
1985 public:
1986 // Constructor
1987 Crate (std::vector<std::unique_ptr<Item>> items,
1988 std::vector<Attribute> inner_attrs)
1989 : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
1990 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1993 // Copy constructor with vector clone
1994 Crate (Crate const &other)
1995 : inner_attrs (other.inner_attrs), node_id (other.node_id)
1997 items.reserve (other.items.size ());
1998 for (const auto &e : other.items)
1999 items.push_back (e->clone_item ());
2002 ~Crate () = default;
2004 // Overloaded assignment operator with vector clone
2005 Crate &operator= (Crate const &other)
2007 inner_attrs = other.inner_attrs;
2008 node_id = other.node_id;
2010 items.reserve (other.items.size ());
2011 for (const auto &e : other.items)
2012 items.push_back (e->clone_item ());
2014 return *this;
2017 // Move constructors
2018 Crate (Crate &&other) = default;
2019 Crate &operator= (Crate &&other) = default;
2021 // Get crate representation as string (e.g. for debugging).
2022 std::string as_string () const;
2024 // Delete all crate information, e.g. if fails cfg.
2025 void strip_crate ()
2027 inner_attrs.clear ();
2028 inner_attrs.shrink_to_fit ();
2030 items.clear ();
2031 items.shrink_to_fit ();
2032 // TODO: is this the best way to do this?
2035 NodeId get_node_id () const { return node_id; }
2036 const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
2037 std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
2039 std::vector<std::unique_ptr<AST::Item>> take_items ()
2041 return std::move (items);
2044 void set_items (std::vector<std::unique_ptr<AST::Item>> &&new_items)
2046 items = std::move (new_items);
2050 // Base path expression AST node - abstract
2051 class PathExpr : public ExprWithoutBlock
2055 } // namespace AST
2056 } // namespace Rust
2058 namespace std {
2059 template <> struct less<Rust::Identifier>
2061 bool operator() (const Rust::Identifier &lhs,
2062 const Rust::Identifier &rhs) const
2064 return lhs.as_string () < rhs.as_string ();
2067 } // namespace std
2069 #endif