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 (); }
60 bool operator== (const Identifier
&other
) const
62 return ident
== other
.ident
;
71 operator<< (std::ostream
&os
, Identifier
const &i
);
74 // foward decl: ast visitor
76 using AttrVec
= std::vector
<Attribute
>;
81 virtual ~Visitable () = default;
82 virtual void accept_vis (ASTVisitor
&vis
) = 0;
85 // Delimiter types - used in macros and whatever.
93 // forward decl for use in token tree method
96 // A tree of tokens (or a single token) - abstract base class
97 class TokenTree
: public Visitable
100 virtual ~TokenTree () {}
102 // Unique pointer custom clone function
103 std::unique_ptr
<TokenTree
> clone_token_tree () const
105 return std::unique_ptr
<TokenTree
> (clone_token_tree_impl ());
108 virtual std::string
as_string () const = 0;
110 /* Converts token tree to a flat token stream. Tokens must be pointer to
111 * avoid mutual dependency with Token. */
112 virtual std::vector
<std::unique_ptr
<Token
>> to_token_stream () const = 0;
115 // pure virtual clone implementation
116 virtual TokenTree
*clone_token_tree_impl () const = 0;
119 // Abstract base class for a macro match
120 class MacroMatch
: public Visitable
131 virtual ~MacroMatch () {}
133 virtual std::string
as_string () const = 0;
134 virtual location_t
get_match_locus () const = 0;
136 // Unique pointer custom clone function
137 std::unique_ptr
<MacroMatch
> clone_macro_match () const
139 return std::unique_ptr
<MacroMatch
> (clone_macro_match_impl ());
142 virtual MacroMatchType
get_macro_match_type () const = 0;
145 // pure virtual clone implementation
146 virtual MacroMatch
*clone_macro_match_impl () const = 0;
149 // A token is a kind of token tree (except delimiter tokens)
150 class Token
: public TokenTree
, public MacroMatch
152 // A token is a kind of token tree (except delimiter tokens)
153 // A token is a kind of MacroMatch (except $ and delimiter tokens)
155 // TODO: improve member variables - current ones are the same as lexer token
160 // Associated text (if any) of token.
162 // Token type hint (if any).
163 PrimitiveCoreType type_hint
;
166 const_TokenPtr tok_ref
;
168 /* new idea: wrapper around const_TokenPtr used for heterogeneuous storage
169 * in token trees. rather than convert back and forth when parsing macros,
173 // Unique pointer custom clone function
174 std::unique_ptr
<Token
> clone_token () const
176 return std::unique_ptr
<Token
> (clone_token_impl ());
180 /* constructor from general text - avoid using if lexer const_TokenPtr is
182 Token (TokenId token_id
, location_t locus
, std::string str
,
183 PrimitiveCoreType type_hint
)
184 : token_id (token_id
), locus (locus
), str (std::move (str
)),
185 type_hint (type_hint
)
188 // not doable with new implementation - will have to make a const_TokenPtr
190 // Constructor from lexer const_TokenPtr
192 /* TODO: find workaround for std::string being nullptr - probably have to
193 * introduce new method in lexer Token, or maybe make conversion method
195 Token (const_TokenPtr lexer_token_ptr
)
196 : token_id (lexer_token_ptr
->get_id ()),
197 locus (lexer_token_ptr
->get_locus ()), str (""),
198 type_hint (lexer_token_ptr
->get_type_hint ())
200 // FIXME: change to "should have str" later?
201 if (lexer_token_ptr
->has_str ())
203 str
= lexer_token_ptr
->get_str ();
206 rust_debug ("ast token created with str '%s'", str
.c_str ());
210 // FIXME: is this returning correct thing?
211 str
= lexer_token_ptr
->get_token_description ();
214 rust_debug ("ast token created with string '%s'", str
.c_str ());
218 if (lexer_token_ptr
->should_have_str () && !lexer_token_ptr
->has_str ())
221 "BAD: for token '%s', should have string but does not!",
222 lexer_token_ptr
->get_token_description ());
226 Token (const_TokenPtr lexer_tok_ptr
) : tok_ref (std::move (lexer_tok_ptr
)) {}
228 bool is_string_lit () const
233 case BYTE_STRING_LITERAL
:
234 case RAW_STRING_LITERAL
:
241 std::string
as_string () const override
;
242 location_t
get_match_locus () const override
244 return tok_ref
->get_locus ();
247 void accept_vis (ASTVisitor
&vis
) override
;
249 // Return copy of itself but in token stream form.
250 std::vector
<std::unique_ptr
<Token
>> to_token_stream () const override
;
252 TokenId
get_id () const { return tok_ref
->get_id (); }
253 const std::string
&get_str () const { return tok_ref
->get_str (); }
255 location_t
get_locus () const { return tok_ref
->get_locus (); }
257 PrimitiveCoreType
get_type_hint () const { return tok_ref
->get_type_hint (); }
259 // Get a new token pointer copy.
260 const_TokenPtr
get_tok_ptr () const { return tok_ref
; }
262 MacroMatchType
get_macro_match_type () const override
264 return MacroMatchType::Tok
;
268 // No virtual for now as not polymorphic but can be in future
269 /*virtual*/ Token
*clone_token_impl () const { return new Token (*this); }
271 /* Use covariance to implement clone function as returning this object
272 * rather than base */
273 Token
*clone_token_tree_impl () const final override
275 return clone_token_impl ();
278 /* Use covariance to implement clone function as returning this object
279 * rather than base */
280 Token
*clone_macro_match_impl () const final override
282 return clone_token_impl ();
286 // A literal - value with a type. Used in LiteralExpr and LiteralPattern.
304 /* TODO: maybe make subclasses of each type of literal with their typed
305 * values (or generics) */
306 std::string value_as_string
;
308 PrimitiveCoreType type_hint
;
311 std::string
as_string () const { return value_as_string
; }
313 LitType
get_lit_type () const { return type
; }
315 PrimitiveCoreType
get_type_hint () const { return type_hint
; }
317 Literal (std::string value_as_string
, LitType type
,
318 PrimitiveCoreType type_hint
)
319 : value_as_string (std::move (value_as_string
)), type (type
),
320 type_hint (type_hint
)
323 static Literal
create_error ()
325 return Literal ("", ERROR
, PrimitiveCoreType::CORETYPE_UNKNOWN
);
328 // Returns whether literal is in an invalid state.
329 bool is_error () const { return type
== ERROR
; }
332 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
334 class AttrInputLiteral
;
336 /* TODO: move applicable stuff into here or just don't include it because
337 * nothing uses it A segment of a path (maybe) */
341 virtual ~PathSegment () {}
343 virtual std::string
as_string () const = 0;
345 // TODO: add visitor here?
348 // A segment of a simple path without generic or type arguments
349 class SimplePathSegment
: public PathSegment
351 std::string segment_name
;
355 // only allow identifiers, "super", "self", "crate", or "$crate"
357 // TODO: put checks in constructor to enforce this rule?
358 SimplePathSegment (std::string segment_name
, location_t locus
)
359 : segment_name (std::move (segment_name
)), locus (locus
),
360 node_id (Analysis::Mappings::get ().get_next_node_id ())
363 /* Returns whether simple path segment is in an invalid state (currently, if
365 bool is_error () const { return segment_name
.empty (); }
367 // Creates an error SimplePathSegment
368 static SimplePathSegment
create_error ()
370 return SimplePathSegment (std::string (""), UNDEF_LOCATION
);
373 std::string
as_string () const override
;
375 location_t
get_locus () const { return locus
; }
376 NodeId
get_node_id () const { return node_id
; }
377 const std::string
&get_segment_name () const { return segment_name
; }
378 bool is_super_path_seg () const
380 return as_string ().compare (Values::Keywords::SUPER
) == 0;
382 bool is_crate_path_seg () const
384 return as_string ().compare (Values::Keywords::CRATE
) == 0;
386 bool is_lower_self_seg () const
388 return as_string ().compare (Values::Keywords::SELF
) == 0;
390 bool is_big_self () const
392 return as_string ().compare (Values::Keywords::SELF_ALIAS
) == 0;
396 // A simple path without generic or type arguments
399 bool opening_scope_resolution
;
400 std::vector
<SimplePathSegment
> segments
;
406 SimplePath (std::vector
<SimplePathSegment
> path_segments
,
407 bool has_opening_scope_resolution
= false,
408 location_t locus
= UNDEF_LOCATION
)
409 : opening_scope_resolution (has_opening_scope_resolution
),
410 segments (std::move (path_segments
)), locus (locus
),
411 node_id (Analysis::Mappings::get ().get_next_node_id ())
414 SimplePath (Identifier ident
)
415 : opening_scope_resolution (false),
416 segments ({SimplePathSegment (ident
.as_string (), ident
.get_locus ())}),
417 locus (ident
.get_locus ()),
418 node_id (Analysis::Mappings::get ().get_next_node_id ())
421 // Creates an empty SimplePath.
422 static SimplePath
create_empty ()
424 return SimplePath (std::vector
<SimplePathSegment
> ());
427 // Returns whether the SimplePath is empty, i.e. has path segments.
428 bool is_empty () const { return segments
.empty (); }
430 const std::string
as_string () const;
432 bool has_opening_scope_resolution () const
434 return opening_scope_resolution
;
437 location_t
get_locus () const { return locus
; }
438 NodeId
get_node_id () const { return node_id
; }
440 // does this need visitor if not polymorphic? probably not
442 // path-to-string comparison operator
443 bool operator== (const std::string
&rhs
) const
445 return !opening_scope_resolution
&& segments
.size () == 1
446 && segments
[0].as_string () == rhs
;
449 /* Creates a single-segment SimplePath from a string. This will not check to
450 * ensure that this is a valid identifier in path, so be careful. Also, this
451 * will have no location data.
452 * TODO have checks? */
453 static SimplePath
from_str (std::string str
, location_t locus
)
455 std::vector
<AST::SimplePathSegment
> single_segments
456 = {AST::SimplePathSegment (std::move (str
), locus
)};
457 return SimplePath (std::move (single_segments
), false, locus
);
460 const std::vector
<SimplePathSegment
> &get_segments () const
465 std::vector
<SimplePathSegment
> &get_segments () { return segments
; }
467 const SimplePathSegment
&get_final_segment () const
469 return segments
.back ();
473 // path-to-string inverse comparison operator
475 operator!= (const SimplePath
&lhs
, const std::string
&rhs
)
477 return !(lhs
== rhs
);
480 // forward decl for Attribute
483 // Visibility of item - if the item has it, then it is some form of public
499 // Only assigned if vis_type is IN_PATH
503 // should this store location info?
506 // Creates a Visibility - TODO make constructor protected or private?
507 Visibility (VisType vis_type
, SimplePath in_path
, location_t locus
)
508 : vis_type (vis_type
), in_path (std::move (in_path
)), locus (locus
)
511 VisType
get_vis_type () const { return vis_type
; }
513 // Returns whether visibility is in an error state.
514 bool is_error () const
516 return vis_type
== PUB_IN_PATH
&& in_path
.is_empty ();
519 // Returns whether a visibility has a path
520 bool has_path () const { return !is_error () && vis_type
>= PUB_CRATE
; }
522 // Returns whether visibility is public or not.
523 bool is_public () const { return vis_type
!= PRIV
&& !is_error (); }
525 location_t
get_locus () const { return locus
; }
528 // Creates an error visibility.
529 static Visibility
create_error ()
531 return Visibility (PUB_IN_PATH
, SimplePath::create_empty (),
535 // Unique pointer custom clone function
536 /*std::unique_ptr<Visibility> clone_visibility() const {
537 return std::unique_ptr<Visibility>(clone_visibility_impl());
540 /* TODO: think of a way to only allow valid Visibility states - polymorphism
541 * is one idea but may be too resource-intensive. */
543 // Creates a public visibility with no further features/arguments.
545 static Visibility
create_public (location_t pub_vis_location
)
547 return Visibility (PUB
, SimplePath::create_empty (), pub_vis_location
);
550 // Creates a public visibility with crate-relative paths
551 static Visibility
create_crate (location_t crate_tok_location
,
552 location_t crate_vis_location
)
554 return Visibility (PUB_CRATE
,
555 SimplePath::from_str (Values::Keywords::CRATE
,
560 // Creates a public visibility with self-relative paths
561 static Visibility
create_self (location_t self_tok_location
,
562 location_t self_vis_location
)
564 return Visibility (PUB_SELF
,
565 SimplePath::from_str (Values::Keywords::SELF
,
570 // Creates a public visibility with parent module-relative paths
571 static Visibility
create_super (location_t super_tok_location
,
572 location_t super_vis_location
)
574 return Visibility (PUB_SUPER
,
575 SimplePath::from_str (Values::Keywords::SUPER
,
580 // Creates a private visibility
581 static Visibility
create_private ()
583 return Visibility (PRIV
, SimplePath::create_empty (), UNDEF_LOCATION
);
586 // Creates a public visibility with a given path or whatever.
587 static Visibility
create_in_path (SimplePath in_path
,
588 location_t in_path_vis_location
)
590 return Visibility (PUB_IN_PATH
, std::move (in_path
), in_path_vis_location
);
593 std::string
as_string () const;
594 const SimplePath
&get_path () const { return in_path
; }
595 SimplePath
&get_path () { return in_path
; }
598 // Clone function implementation - not currently virtual but may be if
600 /*virtual*/ Visibility
*clone_visibility_impl () const
602 return new Visibility (*this);
607 // Attribute AST representation
613 // bool has_attr_input;
614 std::unique_ptr
<AttrInput
> attr_input
;
618 bool inner_attribute
;
620 // TODO: maybe a variable storing whether attr input is parsed or not
623 // Returns whether Attribute has AttrInput
624 bool has_attr_input () const { return attr_input
!= nullptr; }
626 // Constructor has pointer AttrInput for polymorphism reasons
627 Attribute (SimplePath path
, std::unique_ptr
<AttrInput
> input
,
628 location_t locus
= UNDEF_LOCATION
, bool inner_attribute
= false)
629 : path (std::move (path
)), attr_input (std::move (input
)), locus (locus
),
630 inner_attribute (inner_attribute
)
633 bool is_derive () const;
635 std::vector
<std::reference_wrapper
<AST::SimplePath
>> get_traits_to_derive ();
637 // default destructor
638 ~Attribute () = default;
640 // no point in being defined inline as requires virtual call anyway
641 Attribute (const Attribute
&other
);
643 // no point in being defined inline as requires virtual call anyway
644 Attribute
&operator= (const Attribute
&other
);
646 // default move semantics
647 Attribute (Attribute
&&other
) = default;
648 Attribute
&operator= (Attribute
&&other
) = default;
650 // Unique pointer custom clone function
651 std::unique_ptr
<Attribute
> clone_attribute () const
653 return std::unique_ptr
<Attribute
> (clone_attribute_impl ());
656 // Creates an empty attribute (which is invalid)
657 static Attribute
create_empty ()
659 return Attribute (SimplePath::create_empty (), nullptr);
662 // Returns whether the attribute is considered an "empty" attribute.
663 bool is_empty () const { return attr_input
== nullptr && path
.is_empty (); }
665 // Returns whether the attribute has no input
666 bool empty_input () const { return !attr_input
; }
668 location_t
get_locus () const { return locus
; }
670 AttrInput
&get_attr_input () const { return *attr_input
; }
673 #![crate_type = "lib"]
675 #[cfg(target_os = "linux")]
676 #[allow(non_camel_case_types)]
677 #![allow(unused_variables)]
680 // Full built-in attribute list:
691 * proc_macro_attribute
715 * no_implicit_prelude
724 std::string
as_string () const;
726 bool is_inner_attribute () const { return inner_attribute
; }
728 // no visitor pattern as not currently polymorphic
730 const SimplePath
&get_path () const { return path
; }
731 SimplePath
&get_path () { return path
; }
733 // Call to parse attribute body to meta item syntax.
734 void parse_attr_to_meta_item ();
736 /* Determines whether cfg predicate is true and item with attribute should
737 * not be stripped. Attribute body must already be parsed to meta item. */
738 bool check_cfg_predicate (const Session
&session
) const;
740 // Returns whether body has been parsed to meta item form or not.
741 bool is_parsed_to_meta_item () const;
743 /* Returns any attributes generated from cfg_attr attributes. Attribute body
744 * must already be parsed to meta item. */
745 std::vector
<Attribute
> separate_cfg_attrs () const;
748 // not virtual as currently no subclasses of Attribute, but could be in
750 /*virtual*/ Attribute
*clone_attribute_impl () const
752 return new Attribute (*this);
756 // Attribute body - abstract base class
757 class AttrInput
: public Visitable
768 virtual ~AttrInput () {}
770 // Unique pointer custom clone function
771 std::unique_ptr
<AttrInput
> clone_attr_input () const
773 return std::unique_ptr
<AttrInput
> (clone_attr_input_impl ());
776 virtual std::string
as_string () const = 0;
778 virtual bool check_cfg_predicate (const Session
&session
) const = 0;
780 // Parse attribute input to meta item, if possible
781 virtual AttrInput
*parse_to_meta_item () const { return nullptr; }
783 virtual std::vector
<Attribute
> separate_cfg_attrs () const { return {}; }
785 // Returns whether attr input has been parsed to meta item syntax.
786 virtual bool is_meta_item () const = 0;
788 virtual AttrInputType
get_attr_input_type () const = 0;
791 // pure virtual clone implementation
792 virtual AttrInput
*clone_attr_input_impl () const = 0;
795 // Forward decl - defined in rust-macro.h
796 class MetaNameValueStr
;
798 // abstract base meta item inner class
799 class MetaItemInner
: public Visitable
802 // pure virtual as MetaItemInner
803 virtual MetaItemInner
*clone_meta_item_inner_impl () const = 0;
812 // Unique pointer custom clone function
813 std::unique_ptr
<MetaItemInner
> clone_meta_item_inner () const
815 return std::unique_ptr
<MetaItemInner
> (clone_meta_item_inner_impl ());
818 virtual Kind
get_kind () = 0;
820 virtual ~MetaItemInner ();
822 virtual location_t
get_locus () const = 0;
824 virtual std::string
as_string () const = 0;
826 /* HACK: used to simplify parsing - creates a copy of that type, or returns
828 virtual std::unique_ptr
<MetaNameValueStr
> to_meta_name_value_str () const;
830 // HACK: used to simplify parsing - same thing
831 virtual SimplePath
to_path_item () const
833 return SimplePath::create_empty ();
836 virtual Attribute
to_attribute () const { return Attribute::create_empty (); }
838 virtual bool check_cfg_predicate (const Session
&session
) const = 0;
840 virtual bool is_key_value_pair () const { return false; }
843 // Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
844 class AttrInputMetaItemContainer
: public AttrInput
846 std::vector
<std::unique_ptr
<MetaItemInner
>> items
;
849 AttrInputMetaItemContainer (std::vector
<std::unique_ptr
<MetaItemInner
>> items
)
850 : items (std::move (items
))
853 // copy constructor with vector clone
854 AttrInputMetaItemContainer (const AttrInputMetaItemContainer
&other
)
856 items
.reserve (other
.items
.size ());
857 for (const auto &e
: other
.items
)
858 items
.push_back (e
->clone_meta_item_inner ());
861 // copy assignment operator with vector clone
862 AttrInputMetaItemContainer
&
863 operator= (const AttrInputMetaItemContainer
&other
)
865 AttrInput::operator= (other
);
867 items
.reserve (other
.items
.size ());
868 for (const auto &e
: other
.items
)
869 items
.push_back (e
->clone_meta_item_inner ());
874 // default move constructors
875 AttrInputMetaItemContainer (AttrInputMetaItemContainer
&&other
) = default;
876 AttrInputMetaItemContainer
&operator= (AttrInputMetaItemContainer
&&other
)
879 std::string
as_string () const override
;
881 void accept_vis (ASTVisitor
&vis
) override
;
883 bool check_cfg_predicate (const Session
&session
) const override
;
885 AttrInputType
get_attr_input_type () const final override
887 return AttrInput::AttrInputType::META_ITEM
;
890 // Clones this object.
891 std::unique_ptr
<AttrInputMetaItemContainer
>
892 clone_attr_input_meta_item_container () const
894 return std::unique_ptr
<AttrInputMetaItemContainer
> (
895 clone_attr_input_meta_item_container_impl ());
898 std::vector
<Attribute
> separate_cfg_attrs () const override
;
900 bool is_meta_item () const override
{ return true; }
902 // TODO: this mutable getter seems dodgy
903 std::vector
<std::unique_ptr
<MetaItemInner
>> &get_items () { return items
; }
904 const std::vector
<std::unique_ptr
<MetaItemInner
>> &get_items () const
910 // Use covariance to implement clone function as returning this type
911 AttrInputMetaItemContainer
*clone_attr_input_impl () const final override
913 return clone_attr_input_meta_item_container_impl ();
916 AttrInputMetaItemContainer
*clone_attr_input_meta_item_container_impl () const
918 return new AttrInputMetaItemContainer (*this);
922 // A token tree with delimiters
923 class DelimTokenTree
: public TokenTree
, public AttrInput
925 DelimType delim_type
;
926 std::vector
<std::unique_ptr
<TokenTree
>> token_trees
;
930 DelimTokenTree
*clone_delim_tok_tree_impl () const
932 return new DelimTokenTree (*this);
935 /* Use covariance to implement clone function as returning a DelimTokenTree
937 DelimTokenTree
*clone_attr_input_impl () const final override
939 return clone_delim_tok_tree_impl ();
942 /* Use covariance to implement clone function as returning a DelimTokenTree
944 DelimTokenTree
*clone_token_tree_impl () const final override
946 return clone_delim_tok_tree_impl ();
950 DelimTokenTree (DelimType delim_type
,
951 std::vector
<std::unique_ptr
<TokenTree
>> token_trees
952 = std::vector
<std::unique_ptr
<TokenTree
>> (),
953 location_t locus
= UNDEF_LOCATION
)
954 : delim_type (delim_type
), token_trees (std::move (token_trees
)),
958 // Copy constructor with vector clone
959 DelimTokenTree (DelimTokenTree
const &other
)
960 : delim_type (other
.delim_type
), locus (other
.locus
)
962 token_trees
.clear ();
963 token_trees
.reserve (other
.token_trees
.size ());
964 for (const auto &e
: other
.token_trees
)
965 token_trees
.push_back (e
->clone_token_tree ());
968 // overloaded assignment operator with vector clone
969 DelimTokenTree
&operator= (DelimTokenTree
const &other
)
971 delim_type
= other
.delim_type
;
974 token_trees
.clear ();
975 token_trees
.reserve (other
.token_trees
.size ());
976 for (const auto &e
: other
.token_trees
)
977 token_trees
.push_back (e
->clone_token_tree ());
983 DelimTokenTree (DelimTokenTree
&&other
) = default;
984 DelimTokenTree
&operator= (DelimTokenTree
&&other
) = default;
986 static DelimTokenTree
create_empty () { return DelimTokenTree (PARENS
); }
988 std::string
as_string () const override
;
990 void accept_vis (ASTVisitor
&vis
) override
;
992 bool check_cfg_predicate (const Session
&) const override
994 // this should never be called - should be converted first
999 AttrInputMetaItemContainer
*parse_to_meta_item () const override
;
1001 std::vector
<std::unique_ptr
<Token
>> to_token_stream () const override
;
1003 std::unique_ptr
<DelimTokenTree
> clone_delim_token_tree () const
1005 return std::unique_ptr
<DelimTokenTree
> (clone_delim_tok_tree_impl ());
1008 bool is_meta_item () const override
{ return false; }
1010 AttrInputType
get_attr_input_type () const final override
1012 return AttrInput::AttrInputType::TOKEN_TREE
;
1015 std::vector
<std::unique_ptr
<TokenTree
>> &get_token_trees ()
1020 const std::vector
<std::unique_ptr
<TokenTree
>> &get_token_trees () const
1025 DelimType
get_delim_type () const { return delim_type
; }
1026 location_t
get_locus () const { return locus
; }
1029 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
1031 class AttrInputLiteral
;
1033 // abstract base meta item class
1034 class MetaItem
: public MetaItemInner
1048 MetaItemInner::Kind
get_kind () override
1050 return MetaItemInner::Kind::MetaItem
;
1053 virtual ItemKind
get_item_kind () const = 0;
1056 // Forward decl - defined in rust-expr.h
1057 class MetaItemLitExpr
;
1059 // Forward decl - defined in rust-expr.h
1060 class MetaItemPathLit
;
1062 // Forward decl - defined in rust-macro.h
1065 // Forward decl - defined in rust-macro.h
1068 // Forward decl - defined in rust-macro.h
1071 // Forward decl - defined in rust-macro.h
1072 class MetaListPaths
;
1074 // Forward decl - defined in rust-macro.h
1075 class MetaListNameValueStr
;
1077 /* Base statement abstract class. Note that most "statements" are not allowed
1078 * in top-level module scope - only a subclass of statements called "items"
1080 class Stmt
: public Visitable
1092 // Unique pointer custom clone function
1093 std::unique_ptr
<Stmt
> clone_stmt () const
1095 return std::unique_ptr
<Stmt
> (clone_stmt_impl ());
1100 virtual std::string
as_string () const = 0;
1102 virtual location_t
get_locus () const = 0;
1104 virtual void mark_for_strip () = 0;
1105 virtual bool is_marked_for_strip () const = 0;
1106 NodeId
get_node_id () const { return node_id
; }
1108 virtual Kind
get_stmt_kind () = 0;
1110 // TODO: Can we remove these two?
1111 virtual bool is_item () const = 0;
1112 virtual bool is_expr () const { return false; }
1114 virtual void add_semicolon () {}
1117 Stmt () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1119 // Clone function implementation as pure virtual method
1120 virtual Stmt
*clone_stmt_impl () const = 0;
1125 // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
1126 class Item
: public Stmt
1131 MacroRulesDefinition
,
1149 virtual Kind
get_item_kind () const = 0;
1151 // Unique pointer custom clone function
1152 std::unique_ptr
<Item
> clone_item () const
1154 return std::unique_ptr
<Item
> (clone_item_impl ());
1157 /* Adds crate names to the vector passed by reference, if it can
1158 * (polymorphism). TODO: remove, unused. */
1160 add_crate_name (std::vector
<std::string
> &names ATTRIBUTE_UNUSED
) const
1163 Stmt::Kind
get_stmt_kind () final
{ return Stmt::Kind::Item
; }
1165 // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
1166 // behavior that we have items that can also be expressions?
1167 bool is_item () const override
{ return true; }
1169 virtual std::vector
<Attribute
> &get_outer_attrs () = 0;
1170 virtual const std::vector
<Attribute
> &get_outer_attrs () const = 0;
1172 virtual bool has_outer_attrs () const { return !get_outer_attrs ().empty (); }
1175 // Clone function implementation as pure virtual method
1176 virtual Item
*clone_item_impl () const = 0;
1178 /* Save having to specify two clone methods in derived classes by making
1179 * statement clone return item clone. Hopefully won't affect performance too
1181 Item
*clone_stmt_impl () const final override
{ return clone_item_impl (); }
1184 // Item that supports visibility - abstract base class
1185 class VisItem
: public Item
1187 Visibility visibility
;
1188 std::vector
<Attribute
> outer_attrs
;
1191 // Visibility constructor
1192 VisItem (Visibility visibility
,
1193 std::vector
<Attribute
> outer_attrs
= std::vector
<Attribute
> ())
1194 : visibility (std::move (visibility
)), outer_attrs (std::move (outer_attrs
))
1197 // Visibility copy constructor
1198 VisItem (VisItem
const &other
)
1199 : visibility (other
.visibility
), outer_attrs (other
.outer_attrs
)
1202 // Overload assignment operator to clone
1203 VisItem
&operator= (VisItem
const &other
)
1205 visibility
= other
.visibility
;
1206 outer_attrs
= other
.outer_attrs
;
1211 // move constructors
1212 VisItem (VisItem
&&other
) = default;
1213 VisItem
&operator= (VisItem
&&other
) = default;
1216 /* Does the item have some kind of public visibility (non-default
1218 bool has_visibility () const { return visibility
.is_public (); }
1220 std::string
as_string () const override
;
1222 // TODO: this mutable getter seems really dodgy. Think up better way.
1223 Visibility
&get_visibility () { return visibility
; }
1224 const Visibility
&get_visibility () const { return visibility
; }
1226 std::vector
<Attribute
> &get_outer_attrs () override
{ return outer_attrs
; }
1227 const std::vector
<Attribute
> &get_outer_attrs () const override
1232 virtual Item::Kind
get_item_kind () const override
= 0;
1235 // forward decl of ExprWithoutBlock
1236 class ExprWithoutBlock
;
1238 // Base expression AST node - abstract
1239 class Expr
: public Visitable
1245 QualifiedPathInExpression
,
1280 ArithmeticOrLogical
,
1288 virtual Kind
get_expr_kind () const = 0;
1290 // Unique pointer custom clone function
1291 std::unique_ptr
<Expr
> clone_expr () const
1293 return std::unique_ptr
<Expr
> (clone_expr_impl ());
1296 /* TODO: public methods that could be useful:
1297 * - get_type() - returns type of expression. set_type() may also be useful
1299 * - evaluate() - evaluates expression if constant? can_evaluate()? */
1301 virtual std::string
as_string () const = 0;
1305 virtual location_t
get_locus () const = 0;
1307 virtual bool is_literal () const { return false; }
1309 // HACK: strictly not needed, but faster than full downcast clone
1310 virtual bool is_expr_without_block () const = 0;
1312 virtual void mark_for_strip () = 0;
1313 virtual bool is_marked_for_strip () const = 0;
1315 virtual NodeId
get_node_id () const { return node_id
; }
1317 virtual void set_node_id (NodeId id
) { node_id
= id
; }
1319 virtual std::vector
<Attribute
> &get_outer_attrs () = 0;
1321 // TODO: think of less hacky way to implement this kind of thing
1322 // Sets outer attributes.
1323 virtual void set_outer_attrs (std::vector
<Attribute
>) = 0;
1327 Expr () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1329 // Clone function implementation as pure virtual method
1330 virtual Expr
*clone_expr_impl () const = 0;
1335 // AST node for an expression without an accompanying block - abstract
1336 class ExprWithoutBlock
: public Expr
1339 // pure virtual clone implementation
1340 virtual ExprWithoutBlock
*clone_expr_without_block_impl () const = 0;
1342 /* Save having to specify two clone methods in derived classes by making
1343 * expr clone return exprwithoutblock clone. Hopefully won't affect
1344 * performance too much. */
1345 ExprWithoutBlock
*clone_expr_impl () const final override
1347 return clone_expr_without_block_impl ();
1350 bool is_expr_without_block () const final override
{ return true; };
1353 // Unique pointer custom clone function
1354 std::unique_ptr
<ExprWithoutBlock
> clone_expr_without_block () const
1356 return std::unique_ptr
<ExprWithoutBlock
> (clone_expr_without_block_impl ());
1360 /* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1362 /* Alternatively, identifiers could just be represented as single-segment
1365 class IdentifierExpr
: public ExprWithoutBlock
1367 std::vector
<Attribute
> outer_attrs
;
1372 IdentifierExpr (Identifier ident
, std::vector
<Attribute
> outer_attrs
,
1374 : outer_attrs (std::move (outer_attrs
)), ident (std::move (ident
)),
1378 std::string
as_string () const override
{ return ident
.as_string (); }
1380 location_t
get_locus () const override final
{ return locus
; }
1382 Identifier
get_ident () const { return ident
; }
1384 void accept_vis (ASTVisitor
&vis
) override
;
1386 // Clones this object.
1387 std::unique_ptr
<IdentifierExpr
> clone_identifier_expr () const
1389 return std::unique_ptr
<IdentifierExpr
> (clone_identifier_expr_impl ());
1392 // "Error state" if ident is empty, so base stripping on this.
1393 void mark_for_strip () override
{ ident
= {""}; }
1394 bool is_marked_for_strip () const override
{ return ident
.empty (); }
1396 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
1397 std::vector
<Attribute
> &get_outer_attrs () override
{ return outer_attrs
; }
1399 void set_outer_attrs (std::vector
<Attribute
> new_attrs
) override
1401 outer_attrs
= std::move (new_attrs
);
1404 Expr::Kind
get_expr_kind () const override
{ return Expr::Kind::Identifier
; }
1407 // Clone method implementation
1408 IdentifierExpr
*clone_expr_without_block_impl () const final override
1410 return clone_identifier_expr_impl ();
1413 IdentifierExpr
*clone_identifier_expr_impl () const
1415 return new IdentifierExpr (*this);
1419 // Pattern base AST node
1420 class Pattern
: public Visitable
1441 // Unique pointer custom clone function
1442 std::unique_ptr
<Pattern
> clone_pattern () const
1444 return std::unique_ptr
<Pattern
> (clone_pattern_impl ());
1447 virtual Kind
get_pattern_kind () = 0;
1449 // possible virtual methods: is_refutable()
1451 virtual ~Pattern () {}
1453 virtual std::string
as_string () const = 0;
1455 // as only one kind of pattern can be stripped, have default of nothing
1456 virtual void mark_for_strip () {}
1457 virtual bool is_marked_for_strip () const { return false; }
1459 virtual location_t
get_locus () const = 0;
1460 virtual NodeId
get_node_id () const = 0;
1463 // Clone pattern implementation as pure virtual method
1464 virtual Pattern
*clone_pattern_impl () const = 0;
1467 // forward decl for Type
1470 // Base class for types as represented in AST - abstract
1471 class Type
: public Visitable
1474 // Unique pointer custom clone function
1475 std::unique_ptr
<Type
> clone_type () const
1477 return std::unique_ptr
<Type
> (clone_type_impl ());
1480 // virtual destructor
1483 virtual std::string
as_string () const = 0;
1485 /* HACK: convert to trait bound. Virtual method overriden by classes that
1487 virtual TraitBound
*to_trait_bound (bool) const { return nullptr; }
1488 /* as pointer, shouldn't require definition beforehand, only forward
1491 // as only two kinds of types can be stripped, have default of nothing
1492 virtual void mark_for_strip () {}
1493 virtual bool is_marked_for_strip () const { return false; }
1495 virtual location_t
get_locus () const = 0;
1497 NodeId
get_node_id () const { return node_id
; }
1500 Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1502 // Clone function implementation as pure virtual method
1503 virtual Type
*clone_type_impl () const = 0;
1508 // A type without parentheses? - abstract
1509 class TypeNoBounds
: public Type
1512 // Unique pointer custom clone function
1513 std::unique_ptr
<TypeNoBounds
> clone_type_no_bounds () const
1515 return std::unique_ptr
<TypeNoBounds
> (clone_type_no_bounds_impl ());
1519 // Clone function implementation as pure virtual method
1520 virtual TypeNoBounds
*clone_type_no_bounds_impl () const = 0;
1522 /* Save having to specify two clone methods in derived classes by making
1523 * type clone return typenobounds clone. Hopefully won't affect performance
1525 TypeNoBounds
*clone_type_impl () const final override
1527 return clone_type_no_bounds_impl ();
1530 TypeNoBounds () : Type () {}
1533 /* Abstract base class representing a type param bound - Lifetime and
1534 * TraitBound extends it */
1535 class TypeParamBound
: public Visitable
1538 enum TypeParamBoundType
1544 virtual ~TypeParamBound () {}
1546 // Unique pointer custom clone function
1547 std::unique_ptr
<TypeParamBound
> clone_type_param_bound () const
1549 return std::unique_ptr
<TypeParamBound
> (clone_type_param_bound_impl ());
1552 virtual std::string
as_string () const = 0;
1554 NodeId
get_node_id () const { return node_id
; }
1556 virtual location_t
get_locus () const = 0;
1558 virtual TypeParamBoundType
get_bound_type () const = 0;
1561 // Clone function implementation as pure virtual method
1562 virtual TypeParamBound
*clone_type_param_bound_impl () const = 0;
1564 TypeParamBound (NodeId node_id
) : node_id (node_id
) {}
1569 // Represents a lifetime (and is also a kind of type param bound)
1570 class Lifetime
: public TypeParamBound
1575 NAMED
, // corresponds to LIFETIME_OR_LABEL
1576 STATIC
, // corresponds to 'static
1577 WILDCARD
// corresponds to '_
1581 LifetimeType lifetime_type
;
1582 std::string lifetime_name
;
1588 Lifetime (LifetimeType type
, std::string name
= std::string (),
1589 location_t locus
= UNDEF_LOCATION
)
1590 : TypeParamBound (Analysis::Mappings::get ().get_next_node_id ()),
1591 lifetime_type (type
), lifetime_name (std::move (name
)), locus (locus
)
1594 Lifetime (NodeId id
, LifetimeType type
, std::string name
= std::string (),
1595 location_t locus
= UNDEF_LOCATION
)
1596 : TypeParamBound (id
), lifetime_type (type
),
1597 lifetime_name (std::move (name
)), locus (locus
)
1600 static Lifetime
elided () { return Lifetime (WILDCARD
, ""); }
1602 // Returns true if the lifetime is in an error state.
1603 std::string
as_string () const override
;
1605 void accept_vis (ASTVisitor
&vis
) override
;
1607 LifetimeType
get_lifetime_type () const { return lifetime_type
; }
1609 location_t
get_locus () const override final
{ return locus
; }
1611 std::string
get_lifetime_name () const { return lifetime_name
; }
1613 TypeParamBoundType
get_bound_type () const override
1615 return TypeParamBound::TypeParamBoundType::LIFETIME
;
1619 /* Use covariance to implement clone function as returning this object
1620 * rather than base */
1621 Lifetime
*clone_type_param_bound_impl () const override
1623 return new Lifetime (node_id
, lifetime_type
, lifetime_name
, locus
);
1627 /* Base generic parameter in AST. Abstract - can be represented by a Lifetime
1629 class GenericParam
: public Visitable
1639 virtual ~GenericParam () {}
1641 // Unique pointer custom clone function
1642 std::unique_ptr
<GenericParam
> clone_generic_param () const
1644 return std::unique_ptr
<GenericParam
> (clone_generic_param_impl ());
1647 virtual std::string
as_string () const = 0;
1649 virtual location_t
get_locus () const = 0;
1651 virtual Kind
get_kind () const = 0;
1653 NodeId
get_node_id () const { return node_id
; }
1656 GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1657 GenericParam (NodeId node_id
) : node_id (node_id
) {}
1659 // Clone function implementation as pure virtual method
1660 virtual GenericParam
*clone_generic_param_impl () const = 0;
1665 // A lifetime generic parameter (as opposed to a type generic parameter)
1666 class LifetimeParam
: public GenericParam
1669 std::vector
<Lifetime
> lifetime_bounds
;
1670 AST::AttrVec outer_attrs
;
1674 Lifetime
get_lifetime () const { return lifetime
; }
1676 Lifetime
&get_lifetime () { return lifetime
; }
1678 AST::AttrVec
&get_outer_attrs () { return outer_attrs
; }
1680 // Returns whether the lifetime param has any lifetime bounds.
1681 bool has_lifetime_bounds () const { return !lifetime_bounds
.empty (); }
1683 std::vector
<Lifetime
> &get_lifetime_bounds () { return lifetime_bounds
; }
1685 const std::vector
<Lifetime
> &get_lifetime_bounds () const
1687 return lifetime_bounds
;
1690 // Returns whether the lifetime param has an outer attribute.
1691 bool has_outer_attribute () const { return !outer_attrs
.empty (); }
1694 LifetimeParam (Lifetime lifetime
, std::vector
<Lifetime
> lifetime_bounds
,
1695 AST::AttrVec outer_attrs
, location_t locus
)
1696 : lifetime (std::move (lifetime
)),
1697 lifetime_bounds (std::move (lifetime_bounds
)),
1698 outer_attrs (std::move (outer_attrs
)), locus (locus
)
1701 std::string
as_string () const override
;
1703 void accept_vis (ASTVisitor
&vis
) override
;
1705 location_t
get_locus () const override final
{ return locus
; }
1707 Kind
get_kind () const override final
{ return Kind::Lifetime
; }
1710 /* Use covariance to implement clone function as returning this object
1711 * rather than base */
1712 LifetimeParam
*clone_generic_param_impl () const override
1714 return new LifetimeParam (*this);
1718 class AssociatedItem
: public Visitable
1721 // Clone function implementation as pure virtual method
1722 virtual AssociatedItem
*clone_associated_item_impl () const = 0;
1725 virtual ~AssociatedItem () {}
1727 std::unique_ptr
<AssociatedItem
> clone_associated_item () const
1729 return std::unique_ptr
<AssociatedItem
> (clone_associated_item_impl ());
1732 virtual std::string
as_string () const = 0;
1734 virtual void mark_for_strip () = 0;
1735 virtual bool is_marked_for_strip () const = 0;
1737 virtual location_t
get_locus () const = 0;
1740 // Item used in trait declarations - abstract base class
1741 class TraitItem
: public AssociatedItem
1744 TraitItem (location_t locus
)
1745 : node_id (Analysis::Mappings::get ().get_next_node_id ()),
1746 vis (Visibility::create_private ()), locus (locus
)
1749 TraitItem (Visibility vis
, location_t locus
)
1750 : node_id (Analysis::Mappings::get ().get_next_node_id ()), vis (vis
),
1754 // Clone function implementation as pure virtual method
1755 virtual TraitItem
*clone_associated_item_impl () const override
= 0;
1762 // Unique pointer custom clone function
1763 std::unique_ptr
<TraitItem
> clone_trait_item () const
1765 return std::unique_ptr
<TraitItem
> (clone_associated_item_impl ());
1768 NodeId
get_node_id () const { return node_id
; }
1769 location_t
get_locus () const override
{ return locus
; }
1772 // Abstract base class for an item used inside an extern block
1773 class ExternalItem
: public Visitable
1776 ExternalItem () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
1778 ExternalItem (NodeId node_id
) : node_id (node_id
) {}
1780 virtual ~ExternalItem () {}
1782 // Unique pointer custom clone function
1783 std::unique_ptr
<ExternalItem
> clone_external_item () const
1785 return std::unique_ptr
<ExternalItem
> (clone_external_item_impl ());
1788 virtual std::string
as_string () const = 0;
1790 virtual void mark_for_strip () = 0;
1791 virtual bool is_marked_for_strip () const = 0;
1793 virtual NodeId
get_node_id () const { return node_id
; }
1796 // Clone function implementation as pure virtual method
1797 virtual ExternalItem
*clone_external_item_impl () const = 0;
1802 /* Data structure to store the data used in macro invocations and macro
1803 * invocations with semicolons. */
1804 struct MacroInvocData
1808 DelimTokenTree token_tree
;
1810 // One way of parsing the macro. Probably not applicable for all macros.
1811 std::vector
<std::unique_ptr
<MetaItemInner
>> parsed_items
;
1812 bool parsed_to_meta_item
= false;
1813 MacroExpander
*expander
= nullptr;
1816 std::string
as_string () const;
1818 MacroInvocData (SimplePath path
, DelimTokenTree token_tree
)
1819 : path (std::move (path
)), token_tree (std::move (token_tree
))
1822 // Copy constructor with vector clone
1823 MacroInvocData (const MacroInvocData
&other
)
1824 : path (other
.path
), token_tree (other
.token_tree
),
1825 parsed_to_meta_item (other
.parsed_to_meta_item
)
1827 parsed_items
.reserve (other
.parsed_items
.size ());
1828 for (const auto &e
: other
.parsed_items
)
1829 parsed_items
.push_back (e
->clone_meta_item_inner ());
1832 // Copy assignment operator with vector clone
1833 MacroInvocData
&operator= (const MacroInvocData
&other
)
1836 token_tree
= other
.token_tree
;
1837 parsed_to_meta_item
= other
.parsed_to_meta_item
;
1838 expander
= other
.expander
;
1840 parsed_items
.reserve (other
.parsed_items
.size ());
1841 for (const auto &e
: other
.parsed_items
)
1842 parsed_items
.push_back (e
->clone_meta_item_inner ());
1847 // Move constructors
1848 MacroInvocData (MacroInvocData
&&other
) = default;
1849 MacroInvocData
&operator= (MacroInvocData
&&other
) = default;
1851 // Invalid if path is empty, so base stripping on that.
1852 void mark_for_strip () { path
= SimplePath::create_empty (); }
1853 bool is_marked_for_strip () const { return path
.is_empty (); }
1855 // Returns whether the macro has been parsed already.
1856 bool is_parsed () const { return parsed_to_meta_item
; }
1857 // TODO: update on other ways of parsing it
1859 // TODO: this mutable getter seems kinda dodgy
1860 DelimTokenTree
&get_delim_tok_tree () { return token_tree
; }
1861 const DelimTokenTree
&get_delim_tok_tree () const { return token_tree
; }
1863 // Set the delim token tree of a macro invocation
1864 void set_delim_tok_tree (DelimTokenTree tree
) { token_tree
= tree
; }
1866 // TODO: this mutable getter seems kinda dodgy
1867 SimplePath
&get_path () { return path
; }
1868 const SimplePath
&get_path () const { return path
; }
1870 void set_expander (MacroExpander
*new_expander
) { expander
= new_expander
; }
1871 MacroExpander
*get_expander ()
1873 rust_assert (expander
);
1878 set_meta_item_output (std::vector
<std::unique_ptr
<MetaItemInner
>> new_items
)
1880 parsed_items
= std::move (new_items
);
1882 // TODO: mutable getter seems kinda dodgy
1883 std::vector
<std::unique_ptr
<MetaItemInner
>> &get_meta_items ()
1885 return parsed_items
;
1887 const std::vector
<std::unique_ptr
<MetaItemInner
>> &get_meta_items () const
1889 return parsed_items
;
1893 class SingleASTNode
: public Visitable
1909 // FIXME make this a union
1910 std::unique_ptr
<Expr
> expr
;
1911 std::unique_ptr
<Item
> item
;
1912 std::unique_ptr
<Stmt
> stmt
;
1913 std::unique_ptr
<ExternalItem
> external_item
;
1914 std::unique_ptr
<AssociatedItem
> assoc_item
;
1915 std::unique_ptr
<Type
> type
;
1918 SingleASTNode (std::unique_ptr
<Expr
> expr
)
1919 : kind (EXPRESSION
), expr (std::move (expr
))
1922 SingleASTNode (std::unique_ptr
<Item
> item
)
1923 : kind (ITEM
), item (std::move (item
))
1926 SingleASTNode (std::unique_ptr
<Stmt
> stmt
)
1927 : kind (STMT
), stmt (std::move (stmt
))
1930 SingleASTNode (std::unique_ptr
<ExternalItem
> item
)
1931 : kind (EXTERN
), external_item (std::move (item
))
1934 SingleASTNode (std::unique_ptr
<AssociatedItem
> item
)
1935 : kind (ASSOC_ITEM
), assoc_item (std::move (item
))
1938 SingleASTNode (std::unique_ptr
<Type
> type
)
1939 : kind (TYPE
), type (std::move (type
))
1942 SingleASTNode (SingleASTNode
const &other
);
1944 SingleASTNode
operator= (SingleASTNode
const &other
);
1946 SingleASTNode (SingleASTNode
&&other
) = default;
1947 SingleASTNode
&operator= (SingleASTNode
&&other
) = default;
1949 NodeType
get_kind () const { return kind
; }
1951 std::unique_ptr
<Expr
> &get_expr ()
1953 rust_assert (kind
== EXPRESSION
);
1957 std::unique_ptr
<Item
> &get_item ()
1959 rust_assert (kind
== ITEM
);
1963 std::unique_ptr
<Stmt
> &get_stmt ()
1965 rust_assert (kind
== STMT
);
1970 * Access the inner nodes and take ownership of them.
1971 * You can only call these functions once per node
1974 std::unique_ptr
<Stmt
> take_stmt ()
1976 rust_assert (!is_error ());
1977 return std::move (stmt
);
1980 std::unique_ptr
<Expr
> take_expr ()
1982 rust_assert (!is_error ());
1983 return std::move (expr
);
1986 std::unique_ptr
<Item
> take_item ()
1988 rust_assert (!is_error ());
1989 return std::move (item
);
1992 std::unique_ptr
<ExternalItem
> take_external_item ()
1994 rust_assert (!is_error ());
1995 return std::move (external_item
);
1998 std::unique_ptr
<AssociatedItem
> take_assoc_item ()
2000 rust_assert (!is_error ());
2001 return std::move (assoc_item
);
2004 std::unique_ptr
<Type
> take_type ()
2006 rust_assert (!is_error ());
2007 return std::move (type
);
2010 void accept_vis (ASTVisitor
&vis
) override
;
2014 std::string
as_string () const;
2017 // A crate AST object - holds all the data for a single compilation unit
2020 std::vector
<Attribute
> inner_attrs
;
2021 // dodgy spacing required here
2022 /* TODO: is it better to have a vector of items here or a module (implicit
2023 * top-level one)? */
2024 std::vector
<std::unique_ptr
<Item
>> items
;
2030 Crate (std::vector
<std::unique_ptr
<Item
>> items
,
2031 std::vector
<Attribute
> inner_attrs
)
2032 : inner_attrs (std::move (inner_attrs
)), items (std::move (items
)),
2033 node_id (Analysis::Mappings::get ().get_next_node_id ())
2036 // Copy constructor with vector clone
2037 Crate (Crate
const &other
)
2038 : inner_attrs (other
.inner_attrs
), node_id (other
.node_id
)
2040 items
.reserve (other
.items
.size ());
2041 for (const auto &e
: other
.items
)
2042 items
.push_back (e
->clone_item ());
2045 ~Crate () = default;
2047 // Overloaded assignment operator with vector clone
2048 Crate
&operator= (Crate
const &other
)
2050 inner_attrs
= other
.inner_attrs
;
2051 node_id
= other
.node_id
;
2053 items
.reserve (other
.items
.size ());
2054 for (const auto &e
: other
.items
)
2055 items
.push_back (e
->clone_item ());
2060 // Move constructors
2061 Crate (Crate
&&other
) = default;
2062 Crate
&operator= (Crate
&&other
) = default;
2064 // Get crate representation as string (e.g. for debugging).
2065 std::string
as_string () const;
2067 // Delete all crate information, e.g. if fails cfg.
2070 inner_attrs
.clear ();
2071 inner_attrs
.shrink_to_fit ();
2074 items
.shrink_to_fit ();
2075 // TODO: is this the best way to do this?
2078 NodeId
get_node_id () const { return node_id
; }
2079 const std::vector
<Attribute
> &get_inner_attrs () const { return inner_attrs
; }
2080 std::vector
<Attribute
> &get_inner_attrs () { return inner_attrs
; }
2082 std::vector
<std::unique_ptr
<AST::Item
>> take_items ()
2084 return std::move (items
);
2087 void set_items (std::vector
<std::unique_ptr
<AST::Item
>> &&new_items
)
2089 items
= std::move (new_items
);
2097 template <> struct less
<Rust::Identifier
>
2099 bool operator() (const Rust::Identifier
&lhs
,
2100 const Rust::Identifier
&rhs
) const
2102 return lhs
.as_string () < rhs
.as_string ();
2106 template <> struct hash
<Rust::Identifier
>
2108 std::size_t operator() (const Rust::Identifier
&k
) const
2114 return hash
<string
> () (k
.as_string ()) ^ (hash
<int> () (k
.get_locus ()));