1 // Copyright (C) 2020-2023 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
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
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"
29 // TODO: remove typedefs and make actual types for these
30 typedef std::string Identifier
;
31 typedef int TupleIndex
;
35 // foward decl: ast visitor
37 using AttrVec
= std::vector
<Attribute
>;
39 // The available kinds of AST Nodes
43 MACRO_RULES_DEFINITION
,
47 // Abstract base class for all AST elements
52 * Get the kind of Node this is. This is used to differentiate various AST
53 * elements with very little overhead when extracting the derived type through
54 * static casting is not necessary.
56 // FIXME: Mark this as `= 0` in the future to make sure every node implements
58 virtual Kind
get_ast_kind () const { return Kind::UNKNOWN
; }
61 // Delimiter types - used in macros and whatever.
69 // forward decl for use in token tree method
72 // A tree of tokens (or a single token) - abstract base class
76 virtual ~TokenTree () {}
78 // Unique pointer custom clone function
79 std::unique_ptr
<TokenTree
> clone_token_tree () const
81 return std::unique_ptr
<TokenTree
> (clone_token_tree_impl ());
84 virtual std::string
as_string () const = 0;
86 virtual void accept_vis (ASTVisitor
&vis
) = 0;
88 /* Converts token tree to a flat token stream. Tokens must be pointer to avoid
89 * mutual dependency with Token. */
90 virtual std::vector
<std::unique_ptr
<Token
> > to_token_stream () const = 0;
93 // pure virtual clone implementation
94 virtual TokenTree
*clone_token_tree_impl () const = 0;
97 // Abstract base class for a macro match
109 virtual ~MacroMatch () {}
111 virtual std::string
as_string () const = 0;
112 virtual Location
get_match_locus () const = 0;
114 // Unique pointer custom clone function
115 std::unique_ptr
<MacroMatch
> clone_macro_match () const
117 return std::unique_ptr
<MacroMatch
> (clone_macro_match_impl ());
120 virtual void accept_vis (ASTVisitor
&vis
) = 0;
122 virtual MacroMatchType
get_macro_match_type () const = 0;
125 // pure virtual clone implementation
126 virtual MacroMatch
*clone_macro_match_impl () const = 0;
129 // A token is a kind of token tree (except delimiter tokens)
130 class Token
: public TokenTree
, public MacroMatch
132 // A token is a kind of token tree (except delimiter tokens)
133 // A token is a kind of MacroMatch (except $ and delimiter tokens)
135 // TODO: improve member variables - current ones are the same as lexer token
140 // Associated text (if any) of token.
142 // Token type hint (if any).
143 PrimitiveCoreType type_hint
;
146 const_TokenPtr tok_ref
;
148 /* new idea: wrapper around const_TokenPtr used for heterogeneuous storage in
149 * token trees. rather than convert back and forth when parsing macros, just
153 // Unique pointer custom clone function
154 std::unique_ptr
<Token
> clone_token () const
156 return std::unique_ptr
<Token
> (clone_token_impl ());
160 /* constructor from general text - avoid using if lexer const_TokenPtr is
162 Token (TokenId token_id
, Location locus
, std::string str
,
163 PrimitiveCoreType type_hint
)
164 : token_id (token_id
), locus (locus
), str (std::move (str
)),
165 type_hint (type_hint
)
168 // not doable with new implementation - will have to make a const_TokenPtr
170 // Constructor from lexer const_TokenPtr
172 /* TODO: find workaround for std::string being nullptr - probably have to
173 * introduce new method in lexer Token, or maybe make conversion method
175 Token (const_TokenPtr lexer_token_ptr
)
176 : token_id (lexer_token_ptr
->get_id ()),
177 locus (lexer_token_ptr
->get_locus ()), str (""),
178 type_hint (lexer_token_ptr
->get_type_hint ())
180 // FIXME: change to "should have str" later?
181 if (lexer_token_ptr
->has_str ())
183 str
= lexer_token_ptr
->get_str ();
186 rust_debug ("ast token created with str '%s'", str
.c_str ());
190 // FIXME: is this returning correct thing?
191 str
= lexer_token_ptr
->get_token_description ();
194 rust_debug ("ast token created with string '%s'", str
.c_str ());
198 if (lexer_token_ptr
->should_have_str () && !lexer_token_ptr
->has_str ())
201 "BAD: for token '%s', should have string but does not!",
202 lexer_token_ptr
->get_token_description ());
206 Token (const_TokenPtr lexer_tok_ptr
) : tok_ref (std::move (lexer_tok_ptr
)) {}
208 bool is_string_lit () const
213 case BYTE_STRING_LITERAL
:
220 std::string
as_string () const override
;
221 Location
get_match_locus () const override
{ return tok_ref
->get_locus (); };
223 void accept_vis (ASTVisitor
&vis
) override
;
225 // Return copy of itself but in token stream form.
226 std::vector
<std::unique_ptr
<Token
> > to_token_stream () const override
;
228 TokenId
get_id () const { return tok_ref
->get_id (); }
229 const std::string
&get_str () const { return tok_ref
->get_str (); }
231 Location
get_locus () const { return tok_ref
->get_locus (); }
233 PrimitiveCoreType
get_type_hint () const { return tok_ref
->get_type_hint (); }
235 // Get a new token pointer copy.
236 const_TokenPtr
get_tok_ptr () const { return tok_ref
; }
238 MacroMatchType
get_macro_match_type () const override
240 return MacroMatchType::Tok
;
244 // No virtual for now as not polymorphic but can be in future
245 /*virtual*/ Token
*clone_token_impl () const { return new Token (*this); }
247 /* Use covariance to implement clone function as returning this object rather
249 Token
*clone_token_tree_impl () const final override
251 return clone_token_impl ();
254 /* Use covariance to implement clone function as returning this object rather
256 Token
*clone_macro_match_impl () const final override
258 return clone_token_impl ();
262 // A literal - value with a type. Used in LiteralExpr and LiteralPattern.
279 /* TODO: maybe make subclasses of each type of literal with their typed values
281 std::string value_as_string
;
283 PrimitiveCoreType type_hint
;
286 std::string
as_string () const { return value_as_string
; }
288 LitType
get_lit_type () const { return type
; }
290 PrimitiveCoreType
get_type_hint () const { return type_hint
; }
292 Literal (std::string value_as_string
, LitType type
,
293 PrimitiveCoreType type_hint
)
294 : value_as_string (std::move (value_as_string
)), type (type
),
295 type_hint (type_hint
)
298 static Literal
create_error ()
300 return Literal ("", ERROR
, PrimitiveCoreType::CORETYPE_UNKNOWN
);
303 // Returns whether literal is in an invalid state.
304 bool is_error () const { return type
== ERROR
; }
307 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
309 class AttrInputLiteral
;
311 /* TODO: move applicable stuff into here or just don't include it because
312 * nothing uses it A segment of a path (maybe) */
316 virtual ~PathSegment () {}
318 virtual std::string
as_string () const = 0;
320 // TODO: add visitor here?
323 // A segment of a simple path without generic or type arguments
324 class SimplePathSegment
: public PathSegment
326 std::string segment_name
;
330 // only allow identifiers, "super", "self", "crate", or "$crate"
332 // TODO: put checks in constructor to enforce this rule?
333 SimplePathSegment (std::string segment_name
, Location locus
)
334 : segment_name (std::move (segment_name
)), locus (locus
),
335 node_id (Analysis::Mappings::get ()->get_next_node_id ())
338 /* Returns whether simple path segment is in an invalid state (currently, if
340 bool is_error () const { return segment_name
.empty (); }
342 // Creates an error SimplePathSegment
343 static SimplePathSegment
create_error ()
345 return SimplePathSegment (std::string (""), Location ());
348 std::string
as_string () const override
;
350 Location
get_locus () const { return locus
; }
351 NodeId
get_node_id () const { return node_id
; }
352 const std::string
&get_segment_name () const { return segment_name
; }
353 bool is_super_path_seg () const
355 return as_string ().compare ("super") == 0;
357 bool is_crate_path_seg () const
359 return as_string ().compare ("crate") == 0;
361 bool is_lower_self () const { return as_string ().compare ("self") == 0; }
362 bool is_big_self () const { return as_string ().compare ("Self") == 0; }
365 // A simple path without generic or type arguments
368 bool has_opening_scope_resolution
;
369 std::vector
<SimplePathSegment
> segments
;
375 SimplePath (std::vector
<SimplePathSegment
> path_segments
,
376 bool has_opening_scope_resolution
= false,
377 Location locus
= Location ())
378 : has_opening_scope_resolution (has_opening_scope_resolution
),
379 segments (std::move (path_segments
)), locus (locus
),
380 node_id (Analysis::Mappings::get ()->get_next_node_id ())
383 // Creates an empty SimplePath.
384 static SimplePath
create_empty ()
386 return SimplePath (std::vector
<SimplePathSegment
> ());
389 // Returns whether the SimplePath is empty, i.e. has path segments.
390 bool is_empty () const { return segments
.empty (); }
392 std::string
as_string () const;
394 Location
get_locus () const { return locus
; }
395 NodeId
get_node_id () const { return node_id
; }
397 // does this need visitor if not polymorphic? probably not
399 // path-to-string comparison operator
400 bool operator== (const std::string
&rhs
) const
402 return !has_opening_scope_resolution
&& segments
.size () == 1
403 && segments
[0].as_string () == rhs
;
406 /* Creates a single-segment SimplePath from a string. This will not check to
407 * ensure that this is a valid identifier in path, so be careful. Also, this
408 * will have no location data.
409 * TODO have checks? */
410 static SimplePath
from_str (std::string str
, Location locus
)
412 std::vector
<AST::SimplePathSegment
> single_segments
413 = {AST::SimplePathSegment (std::move (str
), locus
)};
414 return SimplePath (std::move (single_segments
));
417 const std::vector
<SimplePathSegment
> &get_segments () const
422 std::vector
<SimplePathSegment
> &get_segments () { return segments
; }
425 // path-to-string inverse comparison operator
427 operator!= (const SimplePath
&lhs
, const std::string
&rhs
)
429 return !(lhs
== rhs
);
432 // forward decl for Attribute
436 // Attribute AST representation
442 // bool has_attr_input;
443 std::unique_ptr
<AttrInput
> attr_input
;
447 // TODO: maybe a variable storing whether attr input is parsed or not
450 // Returns whether Attribute has AttrInput
451 bool has_attr_input () const { return attr_input
!= nullptr; }
453 // Constructor has pointer AttrInput for polymorphism reasons
454 Attribute (SimplePath path
, std::unique_ptr
<AttrInput
> input
,
455 Location locus
= Location ())
456 : path (std::move (path
)), attr_input (std::move (input
)), locus (locus
)
459 // default destructor
460 ~Attribute () = default;
462 // no point in being defined inline as requires virtual call anyway
463 Attribute (const Attribute
&other
);
465 // no point in being defined inline as requires virtual call anyway
466 Attribute
&operator= (const Attribute
&other
);
468 // default move semantics
469 Attribute (Attribute
&&other
) = default;
470 Attribute
&operator= (Attribute
&&other
) = default;
472 // Unique pointer custom clone function
473 std::unique_ptr
<Attribute
> clone_attribute () const
475 return std::unique_ptr
<Attribute
> (clone_attribute_impl ());
478 // Creates an empty attribute (which is invalid)
479 static Attribute
create_empty ()
481 return Attribute (SimplePath::create_empty (), nullptr);
484 // Returns whether the attribute is considered an "empty" attribute.
485 bool is_empty () const { return attr_input
== nullptr && path
.is_empty (); }
487 Location
get_locus () const { return locus
; }
489 AttrInput
&get_attr_input () const { return *attr_input
; }
492 #![crate_type = "lib"]
494 #[cfg(target_os = "linux")]
495 #[allow(non_camel_case_types)]
496 #![allow(unused_variables)]
499 // Full built-in attribute list:
510 * proc_macro_attribute
534 * no_implicit_prelude
543 std::string
as_string () const;
545 // no visitor pattern as not currently polymorphic
547 const SimplePath
&get_path () const { return path
; }
548 SimplePath
&get_path () { return path
; }
550 // Call to parse attribute body to meta item syntax.
551 void parse_attr_to_meta_item ();
553 /* Determines whether cfg predicate is true and item with attribute should not
554 * be stripped. Attribute body must already be parsed to meta item. */
555 bool check_cfg_predicate (const Session
&session
) const;
557 // Returns whether body has been parsed to meta item form or not.
558 bool is_parsed_to_meta_item () const;
560 /* Returns any attributes generated from cfg_attr attributes. Attribute body
561 * must already be parsed to meta item. */
562 std::vector
<Attribute
> separate_cfg_attrs () const;
565 // not virtual as currently no subclasses of Attribute, but could be in future
566 /*virtual*/ Attribute
*clone_attribute_impl () const
568 return new Attribute (*this);
572 // Attribute body - abstract base class
583 virtual ~AttrInput () {}
585 // Unique pointer custom clone function
586 std::unique_ptr
<AttrInput
> clone_attr_input () const
588 return std::unique_ptr
<AttrInput
> (clone_attr_input_impl ());
591 virtual std::string
as_string () const = 0;
593 virtual void accept_vis (ASTVisitor
&vis
) = 0;
595 virtual bool check_cfg_predicate (const Session
&session
) const = 0;
597 // Parse attribute input to meta item, if possible
598 virtual AttrInput
*parse_to_meta_item () const { return nullptr; }
600 virtual std::vector
<Attribute
> separate_cfg_attrs () const { return {}; }
602 // Returns whether attr input has been parsed to meta item syntax.
603 virtual bool is_meta_item () const = 0;
605 virtual AttrInputType
get_attr_input_type () const = 0;
608 // pure virtual clone implementation
609 virtual AttrInput
*clone_attr_input_impl () const = 0;
612 // Forward decl - defined in rust-macro.h
613 class MetaNameValueStr
;
615 // abstract base meta item inner class
619 // pure virtual as MetaItemInner
620 virtual MetaItemInner
*clone_meta_item_inner_impl () const = 0;
623 // Unique pointer custom clone function
624 std::unique_ptr
<MetaItemInner
> clone_meta_item_inner () const
626 return std::unique_ptr
<MetaItemInner
> (clone_meta_item_inner_impl ());
629 virtual ~MetaItemInner ();
631 virtual std::string
as_string () const = 0;
633 virtual void accept_vis (ASTVisitor
&vis
) = 0;
635 /* HACK: used to simplify parsing - creates a copy of that type, or returns
637 virtual std::unique_ptr
<MetaNameValueStr
> to_meta_name_value_str () const;
639 // HACK: used to simplify parsing - same thing
640 virtual SimplePath
to_path_item () const
642 return SimplePath::create_empty ();
645 virtual Attribute
to_attribute () const { return Attribute::create_empty (); }
647 virtual bool check_cfg_predicate (const Session
&session
) const = 0;
649 virtual bool is_key_value_pair () const { return false; }
652 // Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
653 class AttrInputMetaItemContainer
: public AttrInput
655 std::vector
<std::unique_ptr
<MetaItemInner
> > items
;
658 AttrInputMetaItemContainer (
659 std::vector
<std::unique_ptr
<MetaItemInner
> > items
)
660 : items (std::move (items
))
663 // copy constructor with vector clone
664 AttrInputMetaItemContainer (const AttrInputMetaItemContainer
&other
)
666 items
.reserve (other
.items
.size ());
667 for (const auto &e
: other
.items
)
668 items
.push_back (e
->clone_meta_item_inner ());
671 // copy assignment operator with vector clone
672 AttrInputMetaItemContainer
&
673 operator= (const AttrInputMetaItemContainer
&other
)
675 AttrInput::operator= (other
);
677 items
.reserve (other
.items
.size ());
678 for (const auto &e
: other
.items
)
679 items
.push_back (e
->clone_meta_item_inner ());
684 // default move constructors
685 AttrInputMetaItemContainer (AttrInputMetaItemContainer
&&other
) = default;
686 AttrInputMetaItemContainer
&operator= (AttrInputMetaItemContainer
&&other
)
689 std::string
as_string () const override
;
691 void accept_vis (ASTVisitor
&vis
) override
;
693 bool check_cfg_predicate (const Session
&session
) const override
;
695 AttrInputType
get_attr_input_type () const final override
697 return AttrInput::AttrInputType::META_ITEM
;
700 // Clones this object.
701 std::unique_ptr
<AttrInputMetaItemContainer
>
702 clone_attr_input_meta_item_container () const
704 return std::unique_ptr
<AttrInputMetaItemContainer
> (
705 clone_attr_input_meta_item_container_impl ());
708 std::vector
<Attribute
> separate_cfg_attrs () const override
;
710 bool is_meta_item () const override
{ return true; }
712 // TODO: this mutable getter seems dodgy
713 std::vector
<std::unique_ptr
<MetaItemInner
> > &get_items () { return items
; }
714 const std::vector
<std::unique_ptr
<MetaItemInner
> > &get_items () const
720 // Use covariance to implement clone function as returning this type
721 AttrInputMetaItemContainer
*clone_attr_input_impl () const final override
723 return clone_attr_input_meta_item_container_impl ();
726 AttrInputMetaItemContainer
*clone_attr_input_meta_item_container_impl () const
728 return new AttrInputMetaItemContainer (*this);
732 // A token tree with delimiters
733 class DelimTokenTree
: public TokenTree
, public AttrInput
735 DelimType delim_type
;
736 std::vector
<std::unique_ptr
<TokenTree
> > token_trees
;
740 DelimTokenTree
*clone_delim_tok_tree_impl () const
742 return new DelimTokenTree (*this);
745 /* Use covariance to implement clone function as returning a DelimTokenTree
747 DelimTokenTree
*clone_attr_input_impl () const final override
749 return clone_delim_tok_tree_impl ();
752 /* Use covariance to implement clone function as returning a DelimTokenTree
754 DelimTokenTree
*clone_token_tree_impl () const final override
756 return clone_delim_tok_tree_impl ();
760 DelimTokenTree (DelimType delim_type
,
761 std::vector
<std::unique_ptr
<TokenTree
> > token_trees
762 = std::vector
<std::unique_ptr
<TokenTree
> > (),
763 Location locus
= Location ())
764 : delim_type (delim_type
), token_trees (std::move (token_trees
)),
768 // Copy constructor with vector clone
769 DelimTokenTree (DelimTokenTree
const &other
)
770 : delim_type (other
.delim_type
), locus (other
.locus
)
772 token_trees
.reserve (other
.token_trees
.size ());
773 for (const auto &e
: other
.token_trees
)
774 token_trees
.push_back (e
->clone_token_tree ());
777 // overloaded assignment operator with vector clone
778 DelimTokenTree
&operator= (DelimTokenTree
const &other
)
780 delim_type
= other
.delim_type
;
783 token_trees
.reserve (other
.token_trees
.size ());
784 for (const auto &e
: other
.token_trees
)
785 token_trees
.push_back (e
->clone_token_tree ());
791 DelimTokenTree (DelimTokenTree
&&other
) = default;
792 DelimTokenTree
&operator= (DelimTokenTree
&&other
) = default;
794 static DelimTokenTree
create_empty () { return DelimTokenTree (PARENS
); }
796 std::string
as_string () const override
;
798 void accept_vis (ASTVisitor
&vis
) override
;
800 bool check_cfg_predicate (const Session
&) const override
802 // this should never be called - should be converted first
807 AttrInputMetaItemContainer
*parse_to_meta_item () const override
;
809 std::vector
<std::unique_ptr
<Token
> > to_token_stream () const override
;
811 std::unique_ptr
<DelimTokenTree
> clone_delim_token_tree () const
813 return std::unique_ptr
<DelimTokenTree
> (clone_delim_tok_tree_impl ());
816 bool is_meta_item () const override
{ return false; }
818 AttrInputType
get_attr_input_type () const final override
820 return AttrInput::AttrInputType::TOKEN_TREE
;
823 std::vector
<std::unique_ptr
<TokenTree
> > &get_token_trees ()
828 DelimType
get_delim_type () const { return delim_type
; }
831 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
833 class AttrInputLiteral
;
835 // abstract base meta item class
836 class MetaItem
: public MetaItemInner
840 // Forward decl - defined in rust-expr.h
841 class MetaItemLitExpr
;
843 // Forward decl - defined in rust-expr.h
844 class MetaItemPathLit
;
846 // Forward decl - defined in rust-macro.h
849 // Forward decl - defined in rust-macro.h
852 // Forward decl - defined in rust-macro.h
855 // Forward decl - defined in rust-macro.h
858 // Forward decl - defined in rust-macro.h
859 class MetaListNameValueStr
;
861 /* Base statement abstract class. Note that most "statements" are not allowed in
862 * top-level module scope - only a subclass of statements called "items" are. */
863 class Stmt
: public Node
866 // Unique pointer custom clone function
867 std::unique_ptr
<Stmt
> clone_stmt () const
869 return std::unique_ptr
<Stmt
> (clone_stmt_impl ());
874 virtual std::string
as_string () const = 0;
876 virtual void accept_vis (ASTVisitor
&vis
) = 0;
878 virtual Location
get_locus () const = 0;
880 virtual void mark_for_strip () = 0;
881 virtual bool is_marked_for_strip () const = 0;
882 NodeId
get_node_id () const { return node_id
; }
884 virtual bool is_item () const = 0;
887 Stmt () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
889 // Clone function implementation as pure virtual method
890 virtual Stmt
*clone_stmt_impl () const = 0;
895 // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
896 class Item
: public Stmt
899 // Unique pointer custom clone function
900 std::unique_ptr
<Item
> clone_item () const
902 return std::unique_ptr
<Item
> (clone_item_impl ());
905 /* Adds crate names to the vector passed by reference, if it can
906 * (polymorphism). TODO: remove, unused. */
908 add_crate_name (std::vector
<std::string
> &names ATTRIBUTE_UNUSED
) const
911 // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
912 // behavior that we have items that can also be expressions?
913 bool is_item () const override
{ return true; }
916 // Clone function implementation as pure virtual method
917 virtual Item
*clone_item_impl () const = 0;
919 /* Save having to specify two clone methods in derived classes by making
920 * statement clone return item clone. Hopefully won't affect performance too
922 Item
*clone_stmt_impl () const final override
{ return clone_item_impl (); }
925 // forward decl of ExprWithoutBlock
926 class ExprWithoutBlock
;
928 // Base expression AST node - abstract
929 class Expr
: public Node
932 // Unique pointer custom clone function
933 std::unique_ptr
<Expr
> clone_expr () const
935 return std::unique_ptr
<Expr
> (clone_expr_impl ());
938 /* TODO: public methods that could be useful:
939 * - get_type() - returns type of expression. set_type() may also be useful
941 * - evaluate() - evaluates expression if constant? can_evaluate()? */
943 /* HACK: downcasting without dynamic_cast (if possible) via polymorphism -
944 * overrided in subclasses of ExprWithoutBlock */
945 virtual ExprWithoutBlock
*as_expr_without_block () const { return nullptr; }
947 virtual std::string
as_string () const = 0;
951 virtual Location
get_locus () const = 0;
953 // HACK: strictly not needed, but faster than full downcast clone
954 virtual bool is_expr_without_block () const = 0;
956 virtual void accept_vis (ASTVisitor
&vis
) = 0;
958 virtual void mark_for_strip () = 0;
959 virtual bool is_marked_for_strip () const = 0;
961 virtual NodeId
get_node_id () const { return node_id
; }
963 virtual void set_node_id (NodeId id
) { node_id
= id
; }
967 Expr () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
969 // Clone function implementation as pure virtual method
970 virtual Expr
*clone_expr_impl () const = 0;
972 // TODO: think of less hacky way to implement this kind of thing
973 // Sets outer attributes.
974 virtual void set_outer_attrs (std::vector
<Attribute
>) = 0;
979 // AST node for an expression without an accompanying block - abstract
980 class ExprWithoutBlock
: public Expr
983 // pure virtual clone implementation
984 virtual ExprWithoutBlock
*clone_expr_without_block_impl () const = 0;
986 /* Save having to specify two clone methods in derived classes by making expr
987 * clone return exprwithoutblock clone. Hopefully won't affect performance too
989 ExprWithoutBlock
*clone_expr_impl () const final override
991 return clone_expr_without_block_impl ();
994 bool is_expr_without_block () const final override
{ return true; };
997 // Unique pointer custom clone function
998 std::unique_ptr
<ExprWithoutBlock
> clone_expr_without_block () const
1000 return std::unique_ptr
<ExprWithoutBlock
> (clone_expr_without_block_impl ());
1003 /* downcasting hack from expr to use pratt parsing with
1004 * parse_expr_without_block */
1005 ExprWithoutBlock
*as_expr_without_block () const final override
1007 return clone_expr_without_block_impl ();
1010 virtual ExprWithoutBlock
*to_stmt () const { return clone_expr_impl (); }
1013 /* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1015 /* Alternatively, identifiers could just be represented as single-segment paths
1017 class IdentifierExpr
: public ExprWithoutBlock
1019 std::vector
<Attribute
> outer_attrs
;
1024 IdentifierExpr (Identifier ident
, std::vector
<Attribute
> outer_attrs
,
1026 : outer_attrs (std::move (outer_attrs
)), ident (std::move (ident
)),
1030 std::string
as_string () const override
{ return ident
; }
1032 Location
get_locus () const override final
{ return locus
; }
1034 Identifier
get_ident () const { return ident
; }
1036 void accept_vis (ASTVisitor
&vis
) override
;
1038 // Clones this object.
1039 std::unique_ptr
<IdentifierExpr
> clone_identifier_expr () const
1041 return std::unique_ptr
<IdentifierExpr
> (clone_identifier_expr_impl ());
1044 // "Error state" if ident is empty, so base stripping on this.
1045 void mark_for_strip () override
{ ident
= {}; }
1046 bool is_marked_for_strip () const override
{ return ident
.empty (); }
1048 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
1049 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
1051 void set_outer_attrs (std::vector
<Attribute
> new_attrs
) override
1053 outer_attrs
= std::move (new_attrs
);
1057 // Clone method implementation
1058 IdentifierExpr
*clone_expr_without_block_impl () const final override
1060 return clone_identifier_expr_impl ();
1063 IdentifierExpr
*clone_identifier_expr_impl () const
1065 return new IdentifierExpr (*this);
1069 // Pattern base AST node
1073 // Unique pointer custom clone function
1074 std::unique_ptr
<Pattern
> clone_pattern () const
1076 return std::unique_ptr
<Pattern
> (clone_pattern_impl ());
1079 // possible virtual methods: is_refutable()
1081 virtual ~Pattern () {}
1083 virtual std::string
as_string () const = 0;
1084 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1086 // as only one kind of pattern can be stripped, have default of nothing
1087 virtual void mark_for_strip () {}
1088 virtual bool is_marked_for_strip () const { return false; }
1090 virtual Location
get_locus () const = 0;
1091 virtual NodeId
get_pattern_node_id () const = 0;
1094 // Clone pattern implementation as pure virtual method
1095 virtual Pattern
*clone_pattern_impl () const = 0;
1098 // forward decl for Type
1101 // Base class for types as represented in AST - abstract
1102 class Type
: public Node
1105 // Unique pointer custom clone function
1106 std::unique_ptr
<Type
> clone_type () const
1108 return std::unique_ptr
<Type
> (clone_type_impl ());
1111 // virtual destructor
1114 virtual std::string
as_string () const = 0;
1116 /* HACK: convert to trait bound. Virtual method overriden by classes that
1118 virtual TraitBound
*to_trait_bound (bool) const { return nullptr; }
1119 /* as pointer, shouldn't require definition beforehand, only forward
1122 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1124 // as only two kinds of types can be stripped, have default of nothing
1125 virtual void mark_for_strip () {}
1126 virtual bool is_marked_for_strip () const { return false; }
1128 virtual Location
get_locus () const = 0;
1130 NodeId
get_node_id () const { return node_id
; }
1133 Type () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1135 // Clone function implementation as pure virtual method
1136 virtual Type
*clone_type_impl () const = 0;
1141 // A type without parentheses? - abstract
1142 class TypeNoBounds
: public Type
1145 // Unique pointer custom clone function
1146 std::unique_ptr
<TypeNoBounds
> clone_type_no_bounds () const
1148 return std::unique_ptr
<TypeNoBounds
> (clone_type_no_bounds_impl ());
1152 // Clone function implementation as pure virtual method
1153 virtual TypeNoBounds
*clone_type_no_bounds_impl () const = 0;
1155 /* Save having to specify two clone methods in derived classes by making type
1156 * clone return typenobounds clone. Hopefully won't affect performance too
1158 TypeNoBounds
*clone_type_impl () const final override
1160 return clone_type_no_bounds_impl ();
1163 TypeNoBounds () : Type () {}
1166 /* Abstract base class representing a type param bound - Lifetime and TraitBound
1168 class TypeParamBound
1171 virtual ~TypeParamBound () {}
1173 // Unique pointer custom clone function
1174 std::unique_ptr
<TypeParamBound
> clone_type_param_bound () const
1176 return std::unique_ptr
<TypeParamBound
> (clone_type_param_bound_impl ());
1179 virtual std::string
as_string () const = 0;
1181 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1183 NodeId
get_node_id () const { return node_id
; }
1185 virtual Location
get_locus () const = 0;
1188 // Clone function implementation as pure virtual method
1189 virtual TypeParamBound
*clone_type_param_bound_impl () const = 0;
1191 TypeParamBound (NodeId node_id
) : node_id (node_id
) {}
1196 // Represents a lifetime (and is also a kind of type param bound)
1197 class Lifetime
: public TypeParamBound
1202 NAMED
, // corresponds to LIFETIME_OR_LABEL
1203 STATIC
, // corresponds to 'static
1204 WILDCARD
// corresponds to '_
1208 LifetimeType lifetime_type
;
1209 std::string lifetime_name
;
1215 Lifetime (LifetimeType type
, std::string name
= std::string (),
1216 Location locus
= Location ())
1217 : TypeParamBound (Analysis::Mappings::get ()->get_next_node_id ()),
1218 lifetime_type (type
), lifetime_name (std::move (name
)), locus (locus
)
1221 Lifetime (NodeId id
, LifetimeType type
, std::string name
= std::string (),
1222 Location locus
= Location ())
1223 : TypeParamBound (id
), lifetime_type (type
),
1224 lifetime_name (std::move (name
)), locus (locus
)
1227 // Creates an "error" lifetime.
1228 static Lifetime
error () { return Lifetime (NAMED
, ""); }
1230 // Returns true if the lifetime is in an error state.
1231 bool is_error () const
1233 return lifetime_type
== NAMED
&& lifetime_name
.empty ();
1236 std::string
as_string () const override
;
1238 void accept_vis (ASTVisitor
&vis
) override
;
1240 LifetimeType
get_lifetime_type () { return lifetime_type
; }
1242 Location
get_locus () const override final
{ return locus
; }
1244 std::string
get_lifetime_name () const { return lifetime_name
; }
1247 /* Use covariance to implement clone function as returning this object rather
1249 Lifetime
*clone_type_param_bound_impl () const override
1251 return new Lifetime (node_id
, lifetime_type
, lifetime_name
, locus
);
1255 /* Base generic parameter in AST. Abstract - can be represented by a Lifetime or
1267 virtual ~GenericParam () {}
1269 // Unique pointer custom clone function
1270 std::unique_ptr
<GenericParam
> clone_generic_param () const
1272 return std::unique_ptr
<GenericParam
> (clone_generic_param_impl ());
1275 virtual std::string
as_string () const = 0;
1277 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1279 virtual Location
get_locus () const = 0;
1281 virtual Kind
get_kind () const = 0;
1283 NodeId
get_node_id () { return node_id
; }
1286 GenericParam () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1287 GenericParam (NodeId node_id
) : node_id (node_id
) {}
1289 // Clone function implementation as pure virtual method
1290 virtual GenericParam
*clone_generic_param_impl () const = 0;
1295 // A lifetime generic parameter (as opposed to a type generic parameter)
1296 class LifetimeParam
: public GenericParam
1299 std::vector
<Lifetime
> lifetime_bounds
;
1300 Attribute outer_attr
;
1304 Lifetime
get_lifetime () const { return lifetime
; }
1306 // Returns whether the lifetime param has any lifetime bounds.
1307 bool has_lifetime_bounds () const { return !lifetime_bounds
.empty (); }
1309 // Returns whether the lifetime param has an outer attribute.
1310 bool has_outer_attribute () const { return !outer_attr
.is_empty (); }
1312 // Creates an error state lifetime param.
1313 static LifetimeParam
create_error ()
1315 return LifetimeParam (Lifetime::error (), {}, Attribute::create_empty (),
1319 // Returns whether the lifetime param is in an error state.
1320 bool is_error () const { return lifetime
.is_error (); }
1323 LifetimeParam (Lifetime lifetime
, std::vector
<Lifetime
> lifetime_bounds
,
1324 Attribute outer_attr
, Location locus
)
1325 : lifetime (std::move (lifetime
)),
1326 lifetime_bounds (std::move (lifetime_bounds
)),
1327 outer_attr (std::move (outer_attr
)), locus (locus
)
1330 std::string
as_string () const override
;
1332 void accept_vis (ASTVisitor
&vis
) override
;
1334 Location
get_locus () const override final
{ return locus
; }
1336 Kind
get_kind () const override final
{ return Kind::Lifetime
; }
1339 /* Use covariance to implement clone function as returning this object rather
1341 LifetimeParam
*clone_generic_param_impl () const override
1343 return new LifetimeParam (*this);
1347 // A macro item AST node - abstract base class
1348 class MacroItem
: public Item
1352 // Item used in trait declarations - abstract base class
1356 TraitItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1358 // Clone function implementation as pure virtual method
1359 virtual TraitItem
*clone_trait_item_impl () const = 0;
1364 virtual ~TraitItem () {}
1366 // Unique pointer custom clone function
1367 std::unique_ptr
<TraitItem
> clone_trait_item () const
1369 return std::unique_ptr
<TraitItem
> (clone_trait_item_impl ());
1372 virtual std::string
as_string () const = 0;
1374 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1376 virtual void mark_for_strip () = 0;
1377 virtual bool is_marked_for_strip () const = 0;
1379 NodeId
get_node_id () const { return node_id
; }
1382 /* Abstract base class for items used within an inherent impl block (the impl
1384 class InherentImplItem
1387 // Clone function implementation as pure virtual method
1388 virtual InherentImplItem
*clone_inherent_impl_item_impl () const = 0;
1391 virtual ~InherentImplItem () {}
1393 // Unique pointer custom clone function
1394 std::unique_ptr
<InherentImplItem
> clone_inherent_impl_item () const
1396 return std::unique_ptr
<InherentImplItem
> (clone_inherent_impl_item_impl ());
1399 virtual std::string
as_string () const = 0;
1401 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1403 virtual void mark_for_strip () = 0;
1404 virtual bool is_marked_for_strip () const = 0;
1406 virtual Location
get_locus () const = 0;
1409 // Abstract base class for items used in a trait impl
1413 virtual TraitImplItem
*clone_trait_impl_item_impl () const = 0;
1416 virtual ~TraitImplItem (){};
1418 // Unique pointer custom clone function
1419 std::unique_ptr
<TraitImplItem
> clone_trait_impl_item () const
1421 return std::unique_ptr
<TraitImplItem
> (clone_trait_impl_item_impl ());
1424 virtual std::string
as_string () const = 0;
1426 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1428 virtual void mark_for_strip () = 0;
1429 virtual bool is_marked_for_strip () const = 0;
1432 // Abstract base class for an item used inside an extern block
1436 ExternalItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1438 virtual ~ExternalItem () {}
1440 // Unique pointer custom clone function
1441 std::unique_ptr
<ExternalItem
> clone_external_item () const
1443 return std::unique_ptr
<ExternalItem
> (clone_external_item_impl ());
1446 virtual std::string
as_string () const = 0;
1448 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1450 virtual void mark_for_strip () = 0;
1451 virtual bool is_marked_for_strip () const = 0;
1453 NodeId
get_node_id () const { return node_id
; }
1456 // Clone function implementation as pure virtual method
1457 virtual ExternalItem
*clone_external_item_impl () const = 0;
1462 /* Data structure to store the data used in macro invocations and macro
1463 * invocations with semicolons. */
1464 struct MacroInvocData
1468 DelimTokenTree token_tree
;
1470 // One way of parsing the macro. Probably not applicable for all macros.
1471 std::vector
<std::unique_ptr
<MetaItemInner
> > parsed_items
;
1472 bool parsed_to_meta_item
= false;
1475 std::string
as_string () const;
1477 MacroInvocData (SimplePath path
, DelimTokenTree token_tree
)
1478 : path (std::move (path
)), token_tree (std::move (token_tree
))
1481 // Copy constructor with vector clone
1482 MacroInvocData (const MacroInvocData
&other
)
1483 : path (other
.path
), token_tree (other
.token_tree
),
1484 parsed_to_meta_item (other
.parsed_to_meta_item
)
1486 parsed_items
.reserve (other
.parsed_items
.size ());
1487 for (const auto &e
: other
.parsed_items
)
1488 parsed_items
.push_back (e
->clone_meta_item_inner ());
1491 // Copy assignment operator with vector clone
1492 MacroInvocData
&operator= (const MacroInvocData
&other
)
1495 token_tree
= other
.token_tree
;
1496 parsed_to_meta_item
= other
.parsed_to_meta_item
;
1498 parsed_items
.reserve (other
.parsed_items
.size ());
1499 for (const auto &e
: other
.parsed_items
)
1500 parsed_items
.push_back (e
->clone_meta_item_inner ());
1505 // Move constructors
1506 MacroInvocData (MacroInvocData
&&other
) = default;
1507 MacroInvocData
&operator= (MacroInvocData
&&other
) = default;
1509 // Invalid if path is empty, so base stripping on that.
1510 void mark_for_strip () { path
= SimplePath::create_empty (); }
1511 bool is_marked_for_strip () const { return path
.is_empty (); }
1513 // Returns whether the macro has been parsed already.
1514 bool is_parsed () const { return parsed_to_meta_item
; }
1515 // TODO: update on other ways of parsing it
1517 // TODO: this mutable getter seems kinda dodgy
1518 DelimTokenTree
&get_delim_tok_tree () { return token_tree
; }
1519 const DelimTokenTree
&get_delim_tok_tree () const { return token_tree
; }
1521 // TODO: this mutable getter seems kinda dodgy
1522 SimplePath
&get_path () { return path
; }
1523 const SimplePath
&get_path () const { return path
; }
1526 set_meta_item_output (std::vector
<std::unique_ptr
<MetaItemInner
> > new_items
)
1528 parsed_items
= std::move (new_items
);
1530 // TODO: mutable getter seems kinda dodgy
1531 std::vector
<std::unique_ptr
<MetaItemInner
> > &get_meta_items ()
1533 return parsed_items
;
1535 const std::vector
<std::unique_ptr
<MetaItemInner
> > &get_meta_items () const
1537 return parsed_items
;
1559 // FIXME make this a union
1560 std::unique_ptr
<Expr
> expr
;
1561 std::unique_ptr
<Item
> item
;
1562 std::unique_ptr
<Stmt
> stmt
;
1563 std::unique_ptr
<ExternalItem
> external_item
;
1564 std::unique_ptr
<TraitItem
> trait_item
;
1565 std::unique_ptr
<InherentImplItem
> impl_item
;
1566 std::unique_ptr
<TraitImplItem
> trait_impl_item
;
1567 std::unique_ptr
<Type
> type
;
1570 SingleASTNode (std::unique_ptr
<Expr
> expr
)
1571 : kind (EXPRESSION
), expr (std::move (expr
))
1574 SingleASTNode (std::unique_ptr
<Item
> item
)
1575 : kind (ITEM
), item (std::move (item
))
1578 SingleASTNode (std::unique_ptr
<Stmt
> stmt
)
1579 : kind (STMT
), stmt (std::move (stmt
))
1582 SingleASTNode (std::unique_ptr
<ExternalItem
> item
)
1583 : kind (EXTERN
), external_item (std::move (item
))
1586 SingleASTNode (std::unique_ptr
<TraitItem
> item
)
1587 : kind (TRAIT
), trait_item (std::move (item
))
1590 SingleASTNode (std::unique_ptr
<InherentImplItem
> item
)
1591 : kind (IMPL
), impl_item (std::move (item
))
1594 SingleASTNode (std::unique_ptr
<TraitImplItem
> trait_impl_item
)
1595 : kind (TRAIT_IMPL
), trait_impl_item (std::move (trait_impl_item
))
1598 SingleASTNode (std::unique_ptr
<Type
> type
)
1599 : kind (TYPE
), type (std::move (type
))
1602 SingleASTNode (SingleASTNode
const &other
)
1608 expr
= other
.expr
->clone_expr ();
1612 item
= other
.item
->clone_item ();
1616 stmt
= other
.stmt
->clone_stmt ();
1620 external_item
= other
.external_item
->clone_external_item ();
1624 trait_item
= other
.trait_item
->clone_trait_item ();
1628 impl_item
= other
.impl_item
->clone_inherent_impl_item ();
1632 trait_impl_item
= other
.trait_impl_item
->clone_trait_impl_item ();
1636 type
= other
.type
->clone_type ();
1641 SingleASTNode
operator= (SingleASTNode
const &other
)
1647 expr
= other
.expr
->clone_expr ();
1651 item
= other
.item
->clone_item ();
1655 stmt
= other
.stmt
->clone_stmt ();
1659 external_item
= other
.external_item
->clone_external_item ();
1663 trait_item
= other
.trait_item
->clone_trait_item ();
1667 impl_item
= other
.impl_item
->clone_inherent_impl_item ();
1671 trait_impl_item
= other
.trait_impl_item
->clone_trait_impl_item ();
1675 type
= other
.type
->clone_type ();
1681 SingleASTNode (SingleASTNode
&&other
) = default;
1682 SingleASTNode
&operator= (SingleASTNode
&&other
) = default;
1684 NodeType
get_kind () const { return kind
; }
1686 std::unique_ptr
<Expr
> &get_expr ()
1688 rust_assert (kind
== EXPRESSION
);
1692 std::unique_ptr
<Item
> &get_item ()
1694 rust_assert (kind
== ITEM
);
1698 std::unique_ptr
<Stmt
> &get_stmt ()
1700 rust_assert (kind
== STMT
);
1705 * Access the inner nodes and take ownership of them.
1706 * You can only call these functions once per node
1709 std::unique_ptr
<Stmt
> take_stmt ()
1711 rust_assert (!is_error ());
1712 return std::move (stmt
);
1715 std::unique_ptr
<Expr
> take_expr ()
1717 rust_assert (!is_error ());
1718 return std::move (expr
);
1721 std::unique_ptr
<Item
> take_item ()
1723 rust_assert (!is_error ());
1724 return std::move (item
);
1727 std::unique_ptr
<TraitItem
> take_trait_item ()
1729 rust_assert (!is_error ());
1730 return std::move (trait_item
);
1733 std::unique_ptr
<ExternalItem
> take_external_item ()
1735 rust_assert (!is_error ());
1736 return std::move (external_item
);
1739 std::unique_ptr
<InherentImplItem
> take_impl_item ()
1741 rust_assert (!is_error ());
1742 return std::move (impl_item
);
1745 std::unique_ptr
<TraitImplItem
> take_trait_impl_item ()
1747 rust_assert (!is_error ());
1748 return std::move (trait_impl_item
);
1751 std::unique_ptr
<Type
> take_type ()
1753 rust_assert (!is_error ());
1754 return std::move (type
);
1757 void accept_vis (ASTVisitor
&vis
)
1762 expr
->accept_vis (vis
);
1766 item
->accept_vis (vis
);
1770 stmt
->accept_vis (vis
);
1774 external_item
->accept_vis (vis
);
1778 trait_item
->accept_vis (vis
);
1782 impl_item
->accept_vis (vis
);
1786 trait_impl_item
->accept_vis (vis
);
1790 type
->accept_vis (vis
);
1800 return expr
== nullptr;
1802 return item
== nullptr;
1804 return stmt
== nullptr;
1806 return external_item
== nullptr;
1808 return trait_item
== nullptr;
1810 return impl_item
== nullptr;
1812 return trait_impl_item
== nullptr;
1814 return type
== nullptr;
1821 std::string
as_string ()
1826 return "Expr: " + expr
->as_string ();
1828 return "Item: " + item
->as_string ();
1830 return "Stmt: " + stmt
->as_string ();
1832 return "External Item: " + external_item
->as_string ();
1834 return "Trait Item: " + trait_item
->as_string ();
1836 return "Impl Item: " + impl_item
->as_string ();
1838 return "Trait Impl Item: " + trait_impl_item
->as_string ();
1840 return "Type: " + type
->as_string ();
1848 /* Basically, a "fragment" that can be incorporated into the AST, created as
1849 * a result of macro expansion. Really annoying to work with due to the fact
1850 * that macros can really expand to anything. As such, horrible representation
1855 /* basic idea: essentially, a vector of tagged unions of different AST node
1856 * types. Now, this could actually be stored without a tagged union if the
1857 * different AST node types had a unified parent, but that would create
1858 * issues with the diamond problem or significant performance penalties. So
1859 * a tagged union had to be used instead. A vector is used to represent the
1860 * ability for a macro to expand to two statements, for instance. */
1862 std::vector
<SingleASTNode
> nodes
;
1863 bool fragment_is_error
;
1866 * We need to make a special case for Expression and Type fragments as only
1867 * one Node will be extracted from the `nodes` vector
1870 bool is_single_fragment () const { return nodes
.size () == 1; }
1872 bool is_single_fragment_kind (SingleASTNode::NodeType kind
) const
1874 return is_single_fragment () && nodes
[0].get_kind () == kind
;
1878 ASTFragment (std::vector
<SingleASTNode
> nodes
, bool fragment_is_error
= false)
1879 : nodes (std::move (nodes
)), fragment_is_error (fragment_is_error
)
1881 if (fragment_is_error
)
1882 rust_assert (nodes
.empty ());
1885 ASTFragment (ASTFragment
const &other
)
1886 : fragment_is_error (other
.fragment_is_error
)
1889 nodes
.reserve (other
.nodes
.size ());
1890 for (auto &n
: other
.nodes
)
1892 nodes
.push_back (n
);
1896 ASTFragment
&operator= (ASTFragment
const &other
)
1898 fragment_is_error
= other
.fragment_is_error
;
1900 nodes
.reserve (other
.nodes
.size ());
1901 for (auto &n
: other
.nodes
)
1903 nodes
.push_back (n
);
1909 static ASTFragment
create_error () { return ASTFragment ({}, true); }
1911 std::vector
<SingleASTNode
> &get_nodes () { return nodes
; }
1912 bool is_error () const { return fragment_is_error
; }
1914 bool should_expand () const { return !is_error (); }
1916 std::unique_ptr
<Expr
> take_expression_fragment ()
1918 rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::EXPRESSION
));
1919 return nodes
[0].take_expr ();
1922 std::unique_ptr
<Type
> take_type_fragment ()
1924 rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::TYPE
));
1925 return nodes
[0].take_type ();
1928 void accept_vis (ASTVisitor
&vis
)
1930 for (auto &node
: nodes
)
1931 node
.accept_vis (vis
);
1935 // A crate AST object - holds all the data for a single compilation unit
1938 std::vector
<Attribute
> inner_attrs
;
1939 // dodgy spacing required here
1940 /* TODO: is it better to have a vector of items here or a module (implicit
1941 * top-level one)? */
1942 std::vector
<std::unique_ptr
<Item
> > items
;
1948 Crate (std::vector
<std::unique_ptr
<Item
> > items
,
1949 std::vector
<Attribute
> inner_attrs
)
1950 : inner_attrs (std::move (inner_attrs
)), items (std::move (items
)),
1951 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1954 // Copy constructor with vector clone
1955 Crate (Crate
const &other
)
1956 : inner_attrs (other
.inner_attrs
), node_id (other
.node_id
)
1958 items
.reserve (other
.items
.size ());
1959 for (const auto &e
: other
.items
)
1960 items
.push_back (e
->clone_item ());
1963 ~Crate () = default;
1965 // Overloaded assignment operator with vector clone
1966 Crate
&operator= (Crate
const &other
)
1968 inner_attrs
= other
.inner_attrs
;
1969 node_id
= other
.node_id
;
1971 items
.reserve (other
.items
.size ());
1972 for (const auto &e
: other
.items
)
1973 items
.push_back (e
->clone_item ());
1978 // Move constructors
1979 Crate (Crate
&&other
) = default;
1980 Crate
&operator= (Crate
&&other
) = default;
1982 // Get crate representation as string (e.g. for debugging).
1983 std::string
as_string () const;
1985 // Delete all crate information, e.g. if fails cfg.
1988 inner_attrs
.clear ();
1989 inner_attrs
.shrink_to_fit ();
1992 items
.shrink_to_fit ();
1993 // TODO: is this the best way to do this?
1996 NodeId
get_node_id () const { return node_id
; }
1997 const std::vector
<Attribute
> &get_inner_attrs () const { return inner_attrs
; }
2000 // Base path expression AST node - abstract
2001 class PathExpr
: public ExprWithoutBlock