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
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"
27 #include "rust-diagnostics.h"
28 #include "rust-keyword-values.h"
31 // TODO: remove typedefs and make actual types for these
32 typedef int TupleIndex
;
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 (); }
66 operator<< (std::ostream
&os
, Identifier
const &i
);
69 // foward decl: ast visitor
71 using AttrVec
= std::vector
<Attribute
>;
73 // The available kinds of AST Nodes
78 MACRO_RULES_DEFINITION
,
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
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
101 virtual Kind
get_ast_kind () const { return Kind::UNKNOWN
; }
104 // Delimiter types - used in macros and whatever.
112 // forward decl for use in token tree method
115 // A tree of tokens (or a single token) - abstract base class
116 class TokenTree
: public Visitable
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;
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
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;
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)
174 // TODO: improve member variables - current ones are the same as lexer token
179 // Associated text (if any) of token.
181 // Token type hint (if any).
182 PrimitiveCoreType type_hint
;
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,
192 // Unique pointer custom clone function
193 std::unique_ptr
<Token
> clone_token () const
195 return std::unique_ptr
<Token
> (clone_token_impl ());
199 /* constructor from general text - avoid using if lexer const_TokenPtr is
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
)
207 // not doable with new implementation - will have to make a const_TokenPtr
209 // Constructor from lexer const_TokenPtr
211 /* TODO: find workaround for std::string being nullptr - probably have to
212 * introduce new method in lexer Token, or maybe make conversion method
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 ();
225 rust_debug ("ast token created with str '%s'", str
.c_str ());
229 // FIXME: is this returning correct thing?
230 str
= lexer_token_ptr
->get_token_description ();
233 rust_debug ("ast token created with string '%s'", str
.c_str ());
237 if (lexer_token_ptr
->should_have_str () && !lexer_token_ptr
->has_str ())
240 "BAD: for token '%s', should have string but does not!",
241 lexer_token_ptr
->get_token_description ());
245 Token (const_TokenPtr lexer_tok_ptr
) : tok_ref (std::move (lexer_tok_ptr
)) {}
247 bool is_string_lit () const
252 case BYTE_STRING_LITERAL
:
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
;
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.
321 /* TODO: maybe make subclasses of each type of literal with their typed
322 * values (or generics) */
323 std::string value_as_string
;
325 PrimitiveCoreType type_hint
;
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
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) */
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
;
372 // only allow identifiers, "super", "self", "crate", or "$crate"
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
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
416 bool opening_scope_resolution
;
417 std::vector
<SimplePathSegment
> segments
;
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
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
492 operator!= (const SimplePath
&lhs
, const std::string
&rhs
)
494 return !(lhs
== rhs
);
497 // forward decl for Attribute
500 // Visibility of item - if the item has it, then it is some form of public
516 // Only assigned if vis_type is IN_PATH
520 // should this store location info?
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
; }
545 // Creates an error visibility.
546 static Visibility
create_error ()
548 return Visibility (PUB_IN_PATH
, SimplePath::create_empty (),
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.
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
,
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
,
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
,
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
; }
615 // Clone function implementation - not currently virtual but may be if
617 /*virtual*/ Visibility
*clone_visibility_impl () const
619 return new Visibility (*this);
624 // Attribute AST representation
630 // bool has_attr_input;
631 std::unique_ptr
<AttrInput
> attr_input
;
635 bool inner_attribute
;
637 // TODO: maybe a variable storing whether attr input is parsed or not
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
; }
687 #![crate_type = "lib"]
689 #[cfg(target_os = "linux")]
690 #[allow(non_camel_case_types)]
691 #![allow(unused_variables)]
694 // Full built-in attribute list:
705 * proc_macro_attribute
729 * no_implicit_prelude
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;
762 // not virtual as currently no subclasses of Attribute, but could be in
764 /*virtual*/ Attribute
*clone_attribute_impl () const
766 return new Attribute (*this);
770 // Attribute body - abstract base class
771 class AttrInput
: public Visitable
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;
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
816 // pure virtual as MetaItemInner
817 virtual MetaItemInner
*clone_meta_item_inner_impl () const = 0;
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
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
;
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 ());
888 // default move constructors
889 AttrInputMetaItemContainer (AttrInputMetaItemContainer
&&other
) = default;
890 AttrInputMetaItemContainer
&operator= (AttrInputMetaItemContainer
&&other
)
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
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
;
944 DelimTokenTree
*clone_delim_tok_tree_impl () const
946 return new DelimTokenTree (*this);
949 /* Use covariance to implement clone function as returning a DelimTokenTree
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
958 DelimTokenTree
*clone_token_tree_impl () const final override
960 return clone_delim_tok_tree_impl ();
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
)),
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
;
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 ());
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);
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 ()
1034 const std::vector
<std::unique_ptr
<TokenTree
>> &get_token_trees () const
1039 DelimType
get_delim_type () const { return delim_type
; }
1042 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
1044 class AttrInputLiteral
;
1046 // abstract base meta item class
1047 class MetaItem
: public MetaItemInner
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
1078 // Forward decl - defined in rust-macro.h
1081 // Forward decl - defined in rust-macro.h
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"
1093 class Stmt
: public Node
1105 // Unique pointer custom clone function
1106 std::unique_ptr
<Stmt
> clone_stmt () const
1108 return std::unique_ptr
<Stmt
> (clone_stmt_impl ());
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 () {}
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;
1138 // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
1139 class Item
: public Stmt
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. */
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 (); }
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
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
;
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
;
1202 // move constructors
1203 VisItem (VisItem
&&other
) = default;
1204 VisItem
&operator= (VisItem
&&other
) = default;
1207 /* Does the item have some kind of public visibility (non-default
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
1223 // forward decl of ExprWithoutBlock
1224 class ExprWithoutBlock
;
1226 // Base expression AST node - abstract
1227 class Expr
: public Node
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
1239 * - evaluate() - evaluates expression if constant? can_evaluate()? */
1241 virtual std::string
as_string () const = 0;
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;
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;
1275 // AST node for an expression without an accompanying block - abstract
1276 class ExprWithoutBlock
: public Expr
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; };
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
1302 /* Alternatively, identifiers could just be represented as single-segment
1305 class IdentifierExpr
: public ExprWithoutBlock
1307 std::vector
<Attribute
> outer_attrs
;
1312 IdentifierExpr (Identifier ident
, std::vector
<Attribute
> outer_attrs
,
1314 : outer_attrs (std::move (outer_attrs
)), ident (std::move (ident
)),
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
; }
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
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;
1403 // Clone pattern implementation as pure virtual method
1404 virtual Pattern
*clone_pattern_impl () const = 0;
1407 // forward decl for Type
1410 // Base class for types as represented in AST - abstract
1411 class Type
: public Node
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
1423 virtual std::string
as_string () const = 0;
1425 /* HACK: convert to trait bound. Virtual method overriden by classes that
1427 virtual TraitBound
*to_trait_bound (bool) const { return nullptr; }
1428 /* as pointer, shouldn't require definition beforehand, only forward
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
; }
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;
1448 // A type without parentheses? - abstract
1449 class TypeNoBounds
: public Type
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 ());
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
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
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;
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
) {}
1501 // Represents a lifetime (and is also a kind of type param bound)
1502 class Lifetime
: public TypeParamBound
1507 NAMED
, // corresponds to LIFETIME_OR_LABEL
1508 STATIC
, // corresponds to 'static
1509 WILDCARD
// corresponds to '_
1513 LifetimeType lifetime_type
;
1514 std::string lifetime_name
;
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
; }
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
1564 class GenericParam
: public Visitable
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
; }
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;
1600 // A lifetime generic parameter (as opposed to a type generic parameter)
1601 class LifetimeParam
: public GenericParam
1604 std::vector
<Lifetime
> lifetime_bounds
;
1605 Attribute outer_attr
;
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 (),
1630 // Returns whether the lifetime param is in an error state.
1631 bool is_error () const { return lifetime
.is_error (); }
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
; }
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
1661 // Clone function implementation as pure virtual method
1662 virtual AssociatedItem
*clone_associated_item_impl () const = 0;
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
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
),
1694 // Clone function implementation as pure virtual method
1695 virtual TraitItem
*clone_associated_item_impl () const override
= 0;
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
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
; }
1736 // Clone function implementation as pure virtual method
1737 virtual ExternalItem
*clone_external_item_impl () const = 0;
1742 /* Data structure to store the data used in macro invocations and macro
1743 * invocations with semicolons. */
1744 struct MacroInvocData
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;
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
)
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 ());
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
);
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
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
;
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
);
1897 std::unique_ptr
<Item
> &get_item ()
1899 rust_assert (kind
== ITEM
);
1903 std::unique_ptr
<Stmt
> &get_stmt ()
1905 rust_assert (kind
== 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
;
1971 std::string
as_string () const;
1974 // A crate AST object - holds all the data for a single compilation unit
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
;
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 ());
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.
2027 inner_attrs
.clear ();
2028 inner_attrs
.shrink_to_fit ();
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
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 ();