1 // Copyright (C) 2020-2024 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_ITEM_H
20 #define RUST_AST_ITEM_H
23 #include "rust-path.h"
24 #include "rust-common.h"
25 #include "rust-expr.h"
35 // Technically is meant to be STRING_LITERAL
38 // Returns whether abi name is empty, i.e. doesn't exist.
39 bool is_empty() const {
40 return abi_name.empty();
43 AbiName(std::string name) : abi_name(std::move(name)) {}
45 // Empty AbiName constructor
49 // A type generic parameter (as opposed to a lifetime generic parameter)
50 class TypeParam
: public GenericParam
52 // bool has_outer_attribute;
53 // std::unique_ptr<Attribute> outer_attr;
56 Identifier type_representation
;
58 // bool has_type_param_bounds;
59 // TypeParamBounds type_param_bounds;
60 std::vector
<std::unique_ptr
<TypeParamBound
>>
61 type_param_bounds
; // inlined form
64 std::unique_ptr
<Type
> type
;
69 Identifier
get_type_representation () const { return type_representation
; }
71 // Returns whether the type of the type param has been specified.
72 bool has_type () const { return type
!= nullptr; }
74 // Returns whether the type param has type param bounds.
75 bool has_type_param_bounds () const { return !type_param_bounds
.empty (); }
77 // Returns whether the type param has an outer attribute.
78 bool has_outer_attribute () const { return !outer_attr
.is_empty (); }
80 TypeParam (Identifier type_representation
, Location locus
= Location (),
81 std::vector
<std::unique_ptr
<TypeParamBound
>> type_param_bounds
82 = std::vector
<std::unique_ptr
<TypeParamBound
>> (),
83 std::unique_ptr
<Type
> type
= nullptr,
84 Attribute outer_attr
= Attribute::create_empty ())
85 : GenericParam (Analysis::Mappings::get ()->get_next_node_id ()),
86 outer_attr (std::move (outer_attr
)),
87 type_representation (std::move (type_representation
)),
88 type_param_bounds (std::move (type_param_bounds
)),
89 type (std::move (type
)), locus (locus
)
92 // Copy constructor uses clone
93 TypeParam (TypeParam
const &other
)
94 : GenericParam (other
.node_id
), outer_attr (other
.outer_attr
),
95 type_representation (other
.type_representation
), locus (other
.locus
)
97 // guard to prevent null pointer dereference
98 if (other
.type
!= nullptr)
99 type
= other
.type
->clone_type ();
101 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
102 for (const auto &e
: other
.type_param_bounds
)
103 type_param_bounds
.push_back (e
->clone_type_param_bound ());
106 // Overloaded assignment operator to clone
107 TypeParam
&operator= (TypeParam
const &other
)
109 type_representation
= other
.type_representation
;
110 outer_attr
= other
.outer_attr
;
112 node_id
= other
.node_id
;
114 // guard to prevent null pointer dereference
115 if (other
.type
!= nullptr)
116 type
= other
.type
->clone_type ();
120 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
121 for (const auto &e
: other
.type_param_bounds
)
122 type_param_bounds
.push_back (e
->clone_type_param_bound ());
128 TypeParam (TypeParam
&&other
) = default;
129 TypeParam
&operator= (TypeParam
&&other
) = default;
131 std::string
as_string () const override
;
133 Location
get_locus () const override final
{ return locus
; }
135 Kind
get_kind () const override final
{ return Kind::Type
; }
137 void accept_vis (ASTVisitor
&vis
) override
;
139 // TODO: is this better? Or is a "vis_block" better?
140 std::unique_ptr
<Type
> &get_type ()
142 rust_assert (type
!= nullptr);
146 // TODO: mutable getter seems kinda dodgy
147 std::vector
<std::unique_ptr
<TypeParamBound
>> &get_type_param_bounds ()
149 return type_param_bounds
;
151 const std::vector
<std::unique_ptr
<TypeParamBound
>> &
152 get_type_param_bounds () const
154 return type_param_bounds
;
158 // Clone function implementation as virtual method
159 TypeParam
*clone_generic_param_impl () const override
161 return new TypeParam (*this);
165 /* "where" clause item base. Abstract - use LifetimeWhereClauseItem,
166 * TypeBoundWhereClauseItem */
167 class WhereClauseItem
170 virtual ~WhereClauseItem () {}
172 // Unique pointer custom clone function
173 std::unique_ptr
<WhereClauseItem
> clone_where_clause_item () const
175 return std::unique_ptr
<WhereClauseItem
> (clone_where_clause_item_impl ());
178 virtual std::string
as_string () const = 0;
180 virtual void accept_vis (ASTVisitor
&vis
) = 0;
182 virtual NodeId
get_node_id () const = 0;
185 // Clone function implementation as pure virtual method
186 virtual WhereClauseItem
*clone_where_clause_item_impl () const = 0;
189 // A lifetime where clause item
190 class LifetimeWhereClauseItem
: public WhereClauseItem
193 std::vector
<Lifetime
> lifetime_bounds
;
198 LifetimeWhereClauseItem (Lifetime lifetime
,
199 std::vector
<Lifetime
> lifetime_bounds
,
201 : lifetime (std::move (lifetime
)),
202 lifetime_bounds (std::move (lifetime_bounds
)), locus (locus
),
203 node_id (Analysis::Mappings::get ()->get_next_node_id ())
206 std::string
as_string () const override
;
208 void accept_vis (ASTVisitor
&vis
) override
;
210 NodeId
get_node_id () const override final
{ return node_id
; }
212 Lifetime
&get_lifetime () { return lifetime
; }
214 std::vector
<Lifetime
> &get_lifetime_bounds () { return lifetime_bounds
; }
216 Location
get_locus () const { return locus
; }
219 // Clone function implementation as (not pure) virtual method
220 LifetimeWhereClauseItem
*clone_where_clause_item_impl () const override
222 return new LifetimeWhereClauseItem (*this);
226 // A type bound where clause item
227 class TypeBoundWhereClauseItem
: public WhereClauseItem
229 std::vector
<LifetimeParam
> for_lifetimes
;
230 std::unique_ptr
<Type
> bound_type
;
231 std::vector
<std::unique_ptr
<TypeParamBound
>> type_param_bounds
;
236 // Returns whether the item has ForLifetimes
237 bool has_for_lifetimes () const { return !for_lifetimes
.empty (); }
239 std::vector
<LifetimeParam
> &get_for_lifetimes () { return for_lifetimes
; }
241 // Returns whether the item has type param bounds
242 bool has_type_param_bounds () const { return !type_param_bounds
.empty (); }
244 TypeBoundWhereClauseItem (
245 std::vector
<LifetimeParam
> for_lifetimes
, std::unique_ptr
<Type
> bound_type
,
246 std::vector
<std::unique_ptr
<TypeParamBound
>> type_param_bounds
,
248 : for_lifetimes (std::move (for_lifetimes
)),
249 bound_type (std::move (bound_type
)),
250 type_param_bounds (std::move (type_param_bounds
)),
251 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus
)
254 // Copy constructor requires clone
255 TypeBoundWhereClauseItem (TypeBoundWhereClauseItem
const &other
)
256 : for_lifetimes (other
.for_lifetimes
),
257 bound_type (other
.bound_type
->clone_type ())
259 node_id
= other
.node_id
;
260 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
261 for (const auto &e
: other
.type_param_bounds
)
262 type_param_bounds
.push_back (e
->clone_type_param_bound ());
265 // Overload assignment operator to clone
266 TypeBoundWhereClauseItem
&operator= (TypeBoundWhereClauseItem
const &other
)
268 node_id
= other
.node_id
;
269 for_lifetimes
= other
.for_lifetimes
;
270 bound_type
= other
.bound_type
->clone_type ();
271 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
272 for (const auto &e
: other
.type_param_bounds
)
273 type_param_bounds
.push_back (e
->clone_type_param_bound ());
279 TypeBoundWhereClauseItem (TypeBoundWhereClauseItem
&&other
) = default;
280 TypeBoundWhereClauseItem
&operator= (TypeBoundWhereClauseItem
&&other
)
283 std::string
as_string () const override
;
285 void accept_vis (ASTVisitor
&vis
) override
;
287 std::unique_ptr
<Type
> &get_type ()
289 rust_assert (bound_type
!= nullptr);
293 // TODO: this mutable getter seems really dodgy. Think up better way.
294 std::vector
<std::unique_ptr
<TypeParamBound
>> &get_type_param_bounds ()
296 return type_param_bounds
;
299 const std::vector
<std::unique_ptr
<TypeParamBound
>> &
300 get_type_param_bounds () const
302 return type_param_bounds
;
305 NodeId
get_node_id () const override final
{ return node_id
; }
307 Location
get_locus () const { return locus
; }
310 // Clone function implementation as (not pure) virtual method
311 TypeBoundWhereClauseItem
*clone_where_clause_item_impl () const override
313 return new TypeBoundWhereClauseItem (*this);
321 std::vector
<std::unique_ptr
<WhereClauseItem
>> where_clause_items
;
325 WhereClause (std::vector
<std::unique_ptr
<WhereClauseItem
>> where_clause_items
)
326 : where_clause_items (std::move (where_clause_items
)),
327 node_id (Analysis::Mappings::get ()->get_next_node_id ())
330 // copy constructor with vector clone
331 WhereClause (WhereClause
const &other
)
333 node_id
= other
.node_id
;
334 where_clause_items
.reserve (other
.where_clause_items
.size ());
335 for (const auto &e
: other
.where_clause_items
)
336 where_clause_items
.push_back (e
->clone_where_clause_item ());
339 // overloaded assignment operator with vector clone
340 WhereClause
&operator= (WhereClause
const &other
)
342 node_id
= other
.node_id
;
343 where_clause_items
.reserve (other
.where_clause_items
.size ());
344 for (const auto &e
: other
.where_clause_items
)
345 where_clause_items
.push_back (e
->clone_where_clause_item ());
351 WhereClause (WhereClause
&&other
) = default;
352 WhereClause
&operator= (WhereClause
&&other
) = default;
354 // Creates a WhereClause with no items.
355 static WhereClause
create_empty ()
357 return WhereClause (std::vector
<std::unique_ptr
<WhereClauseItem
>> ());
360 // Returns whether the WhereClause has no items.
361 bool is_empty () const { return where_clause_items
.empty (); }
363 std::string
as_string () const;
365 NodeId
get_node_id () const { return node_id
; }
367 // TODO: this mutable getter seems kinda dodgy
368 std::vector
<std::unique_ptr
<WhereClauseItem
>> &get_items ()
370 return where_clause_items
;
372 const std::vector
<std::unique_ptr
<WhereClauseItem
>> &get_items () const
374 return where_clause_items
;
378 // A self parameter in a method
384 // bool has_lifetime; // only possible if also ref
387 // bool has_type; // only possible if not ref
388 std::unique_ptr
<Type
> type
;
394 // Unrestricted constructor used for error state
395 SelfParam (Lifetime lifetime
, bool has_ref
, bool is_mut
, Type
*type
)
396 : has_ref (has_ref
), is_mut (is_mut
), lifetime (std::move (lifetime
)),
397 type (type
), node_id (Analysis::Mappings::get ()->get_next_node_id ())
399 // this is ok as no outside classes can ever call this
401 // TODO: self param can have outer attributes
404 // Returns whether the self-param has a type field.
405 bool has_type () const { return type
!= nullptr; }
407 // Returns whether the self-param has a valid lifetime.
408 bool has_lifetime () const { return !lifetime
.is_error (); }
410 // Returns whether the self-param is in an error state.
411 bool is_error () const
413 return (has_type () && has_lifetime ()) || (has_lifetime () && !has_ref
);
414 // not having either is not an error
417 // Creates an error state self-param.
418 static SelfParam
create_error ()
420 // cannot have no ref but have a lifetime at the same time
421 return SelfParam (Lifetime (Lifetime::STATIC
), false, false, nullptr);
424 // Type-based self parameter (not ref, no lifetime)
425 SelfParam (std::unique_ptr
<Type
> type
, bool is_mut
, Location locus
)
426 : has_ref (false), is_mut (is_mut
), lifetime (Lifetime::error ()),
427 type (std::move (type
)),
428 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus
)
431 // Lifetime-based self parameter (is ref, no type)
432 SelfParam (Lifetime lifetime
, bool is_mut
, Location locus
)
433 : has_ref (true), is_mut (is_mut
), lifetime (std::move (lifetime
)),
434 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus
)
437 // Copy constructor requires clone
438 SelfParam (SelfParam
const &other
)
439 : has_ref (other
.has_ref
), is_mut (other
.is_mut
), lifetime (other
.lifetime
),
440 node_id (Analysis::Mappings::get ()->get_next_node_id ()),
443 node_id
= other
.node_id
;
444 if (other
.type
!= nullptr)
445 type
= other
.type
->clone_type ();
448 // Overload assignment operator to use clone
449 SelfParam
&operator= (SelfParam
const &other
)
451 is_mut
= other
.is_mut
;
452 has_ref
= other
.has_ref
;
453 lifetime
= other
.lifetime
;
455 node_id
= other
.node_id
;
457 if (other
.type
!= nullptr)
458 type
= other
.type
->clone_type ();
466 SelfParam (SelfParam
&&other
) = default;
467 SelfParam
&operator= (SelfParam
&&other
) = default;
469 std::string
as_string () const;
471 Location
get_locus () const { return locus
; }
473 bool get_has_ref () const { return has_ref
; };
474 bool get_is_mut () const { return is_mut
; }
476 Lifetime
get_lifetime () const { return lifetime
; }
478 NodeId
get_node_id () const { return node_id
; }
480 // TODO: is this better? Or is a "vis_block" better?
481 std::unique_ptr
<Type
> &get_type ()
483 rust_assert (has_type ());
488 // Qualifiers for function, i.e. const, unsafe, extern etc.
489 struct FunctionQualifiers
492 AsyncConstStatus const_status
;
495 std::string extern_abi
;
499 FunctionQualifiers (Location locus
, AsyncConstStatus const_status
,
500 bool has_unsafe
, bool has_extern
= false,
501 std::string extern_abi
= std::string ())
502 : const_status (const_status
), has_unsafe (has_unsafe
),
503 has_extern (has_extern
), extern_abi (std::move (extern_abi
)),
506 if (!this->extern_abi
.empty ())
508 // having extern is required; not having it is an implementation error
509 rust_assert (has_extern
);
513 std::string
as_string () const;
515 AsyncConstStatus
get_const_status () const { return const_status
; }
516 bool is_unsafe () const { return has_unsafe
; }
517 bool is_extern () const { return has_extern
; }
518 std::string
get_extern_abi () const { return extern_abi
; }
519 bool has_abi () const { return !extern_abi
.empty (); }
521 Location
get_locus () const { return locus
; }
524 // A function parameter
528 std::vector
<Attribute
> outer_attrs
;
530 std::unique_ptr
<Pattern
> param_name
;
531 std::unique_ptr
<Type
> type
;
534 FunctionParam (std::unique_ptr
<Pattern
> param_name
,
535 std::unique_ptr
<Type
> param_type
,
536 std::vector
<Attribute
> outer_attrs
, Location locus
)
537 : outer_attrs (std::move (outer_attrs
)), locus (locus
),
538 param_name (std::move (param_name
)), type (std::move (param_type
)),
539 node_id (Analysis::Mappings::get ()->get_next_node_id ())
542 // Copy constructor uses clone
543 FunctionParam (FunctionParam
const &other
)
544 : locus (other
.locus
), node_id (other
.node_id
)
546 // guard to prevent nullptr dereference
547 if (other
.param_name
!= nullptr)
548 param_name
= other
.param_name
->clone_pattern ();
549 if (other
.type
!= nullptr)
550 type
= other
.type
->clone_type ();
553 // Overload assignment operator to use clone
554 FunctionParam
&operator= (FunctionParam
const &other
)
557 node_id
= other
.node_id
;
559 // guard to prevent nullptr dereference
560 if (other
.param_name
!= nullptr)
561 param_name
= other
.param_name
->clone_pattern ();
563 param_name
= nullptr;
564 if (other
.type
!= nullptr)
565 type
= other
.type
->clone_type ();
573 FunctionParam (FunctionParam
&&other
) = default;
574 FunctionParam
&operator= (FunctionParam
&&other
) = default;
576 // Returns whether FunctionParam is in an invalid state.
577 bool is_error () const { return param_name
== nullptr || type
== nullptr; }
579 // Creates an error FunctionParam.
580 static FunctionParam
create_error ()
582 return FunctionParam (nullptr, nullptr, {}, Location ());
585 std::string
as_string () const;
587 Location
get_locus () const { return locus
; }
589 // TODO: seems kinda dodgy. Think of better way.
590 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
591 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
593 // TODO: is this better? Or is a "vis_block" better?
594 std::unique_ptr
<Pattern
> &get_pattern ()
596 rust_assert (param_name
!= nullptr);
600 // TODO: is this better? Or is a "vis_block" better?
601 std::unique_ptr
<Type
> &get_type ()
603 rust_assert (type
!= nullptr);
606 NodeId
get_node_id () const { return node_id
; }
612 // Visibility of item - if the item has it, then it is some form of public
628 // Only assigned if vis_type is IN_PATH
632 // should this store location info?
635 // Creates a Visibility - TODO make constructor protected or private?
636 Visibility (VisType vis_type
, SimplePath in_path
, Location locus
)
637 : vis_type (vis_type
), in_path (std::move (in_path
)), locus (locus
)
640 VisType
get_vis_type () const { return vis_type
; }
642 // Returns whether visibility is in an error state.
643 bool is_error () const
645 return vis_type
== PUB_IN_PATH
&& in_path
.is_empty ();
648 // Returns whether a visibility has a path
649 bool has_path () const { return !(is_error ()) && vis_type
== PUB_IN_PATH
; }
651 // Returns whether visibility is public or not.
652 bool is_public () const { return vis_type
!= PRIV
&& !is_error (); }
654 Location
get_locus () const { return locus
; }
657 // Creates an error visibility.
658 static Visibility
create_error ()
660 return Visibility (PUB_IN_PATH
, SimplePath::create_empty (), Location ());
663 // Unique pointer custom clone function
664 /*std::unique_ptr<Visibility> clone_visibility() const {
665 return std::unique_ptr<Visibility>(clone_visibility_impl());
668 /* TODO: think of a way to only allow valid Visibility states - polymorphism
669 * is one idea but may be too resource-intensive. */
671 // Creates a public visibility with no further features/arguments.
673 static Visibility
create_public (Location pub_vis_location
)
675 return Visibility (PUB
, SimplePath::create_empty (), pub_vis_location
);
678 // Creates a public visibility with crate-relative paths
679 static Visibility
create_crate (Location crate_tok_location
,
680 Location crate_vis_location
)
682 return Visibility (PUB_CRATE
,
683 SimplePath::from_str ("crate", crate_tok_location
),
687 // Creates a public visibility with self-relative paths
688 static Visibility
create_self (Location self_tok_location
,
689 Location self_vis_location
)
691 return Visibility (PUB_SELF
,
692 SimplePath::from_str ("self", self_tok_location
),
696 // Creates a public visibility with parent module-relative paths
697 static Visibility
create_super (Location super_tok_location
,
698 Location super_vis_location
)
700 return Visibility (PUB_SUPER
,
701 SimplePath::from_str ("super", super_tok_location
),
705 // Creates a private visibility
706 static Visibility
create_private ()
708 return Visibility (PRIV
, SimplePath::create_empty (), Location ());
711 // Creates a public visibility with a given path or whatever.
712 static Visibility
create_in_path (SimplePath in_path
,
713 Location in_path_vis_location
)
715 return Visibility (PUB_IN_PATH
, std::move (in_path
), in_path_vis_location
);
718 std::string
as_string () const;
719 const SimplePath
&get_path () const { return in_path
; }
720 SimplePath
&get_path () { return in_path
; }
723 // Clone function implementation - not currently virtual but may be if
725 /*virtual*/ Visibility
*clone_visibility_impl () const
727 return new Visibility (*this);
731 // A method (function belonging to a type)
732 class Method
: public InherentImplItem
, public TraitImplItem
734 std::vector
<Attribute
> outer_attrs
;
736 FunctionQualifiers qualifiers
;
737 Identifier method_name
;
738 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
;
739 SelfParam self_param
;
740 std::vector
<FunctionParam
> function_params
;
741 std::unique_ptr
<Type
> return_type
;
742 WhereClause where_clause
;
743 std::unique_ptr
<BlockExpr
> function_body
;
748 // Returns whether the method is in an error state.
749 bool is_error () const
751 return function_body
== nullptr || method_name
.empty ()
752 || self_param
.is_error ();
755 // Creates an error state method.
756 static Method
create_error ()
758 return Method ("", FunctionQualifiers (Location (), NONE
, true),
759 std::vector
<std::unique_ptr
<GenericParam
>> (),
760 SelfParam::create_error (), std::vector
<FunctionParam
> (),
761 nullptr, WhereClause::create_empty (), nullptr,
762 Visibility::create_error (), std::vector
<Attribute
> (), {});
765 // Returns whether the method has generic parameters.
766 bool has_generics () const { return !generic_params
.empty (); }
768 // Returns whether the method has parameters.
769 bool has_params () const { return !function_params
.empty (); }
771 // Returns whether the method has a return type (void otherwise).
772 bool has_return_type () const { return return_type
!= nullptr; }
774 // Returns whether the where clause exists (i.e. has items)
775 bool has_where_clause () const { return !where_clause
.is_empty (); }
777 // Returns whether method has a non-default visibility.
778 bool has_visibility () const { return !vis
.is_error (); }
780 // Mega-constructor with all possible fields
781 Method (Identifier method_name
, FunctionQualifiers qualifiers
,
782 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
783 SelfParam self_param
, std::vector
<FunctionParam
> function_params
,
784 std::unique_ptr
<Type
> return_type
, WhereClause where_clause
,
785 std::unique_ptr
<BlockExpr
> function_body
, Visibility vis
,
786 std::vector
<Attribute
> outer_attrs
, Location locus
)
787 : outer_attrs (std::move (outer_attrs
)), vis (std::move (vis
)),
788 qualifiers (std::move (qualifiers
)),
789 method_name (std::move (method_name
)),
790 generic_params (std::move (generic_params
)),
791 self_param (std::move (self_param
)),
792 function_params (std::move (function_params
)),
793 return_type (std::move (return_type
)),
794 where_clause (std::move (where_clause
)),
795 function_body (std::move (function_body
)), locus (locus
),
796 node_id (Analysis::Mappings::get ()->get_next_node_id ())
799 // TODO: add constructor with less fields
801 // Copy constructor with clone
802 Method (Method
const &other
)
803 : outer_attrs (other
.outer_attrs
), vis (other
.vis
),
804 qualifiers (other
.qualifiers
), method_name (other
.method_name
),
805 self_param (other
.self_param
), function_params (other
.function_params
),
806 where_clause (other
.where_clause
), locus (other
.locus
)
808 // guard to prevent null dereference (always required)
809 if (other
.return_type
!= nullptr)
810 return_type
= other
.return_type
->clone_type ();
812 // guard to prevent null dereference (only required if error state)
813 if (other
.function_body
!= nullptr)
814 function_body
= other
.function_body
->clone_block_expr ();
816 generic_params
.reserve (other
.generic_params
.size ());
817 for (const auto &e
: other
.generic_params
)
818 generic_params
.push_back (e
->clone_generic_param ());
820 node_id
= other
.node_id
;
823 // Overloaded assignment operator to clone
824 Method
&operator= (Method
const &other
)
826 method_name
= other
.method_name
;
827 outer_attrs
= other
.outer_attrs
;
829 qualifiers
= other
.qualifiers
;
830 self_param
= other
.self_param
;
831 function_params
= other
.function_params
;
832 where_clause
= other
.where_clause
;
835 // guard to prevent null dereference (always required)
836 if (other
.return_type
!= nullptr)
837 return_type
= other
.return_type
->clone_type ();
839 return_type
= nullptr;
841 // guard to prevent null dereference (only required if error state)
842 if (other
.function_body
!= nullptr)
843 function_body
= other
.function_body
->clone_block_expr ();
845 function_body
= nullptr;
847 generic_params
.reserve (other
.generic_params
.size ());
848 for (const auto &e
: other
.generic_params
)
849 generic_params
.push_back (e
->clone_generic_param ());
851 node_id
= other
.node_id
;
857 Method (Method
&&other
) = default;
858 Method
&operator= (Method
&&other
) = default;
860 std::string
as_string () const override
;
862 void accept_vis (ASTVisitor
&vis
) override
;
864 // Invalid if block is null, so base stripping on that.
865 void mark_for_strip () override
{ function_body
= nullptr; }
866 bool is_marked_for_strip () const override
868 return function_body
== nullptr;
871 // TODO: this mutable getter seems really dodgy. Think up better way.
872 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
873 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
875 std::vector
<FunctionParam
> &get_function_params () { return function_params
; }
876 const std::vector
<FunctionParam
> &get_function_params () const
878 return function_params
;
881 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
883 return generic_params
;
885 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
887 return generic_params
;
890 // TODO: is this better? Or is a "vis_block" better?
891 std::unique_ptr
<BlockExpr
> &get_definition ()
893 rust_assert (function_body
!= nullptr);
894 return function_body
;
897 SelfParam
&get_self_param () { return self_param
; }
898 const SelfParam
&get_self_param () const { return self_param
; }
900 // TODO: is this better? Or is a "vis_block" better?
901 std::unique_ptr
<Type
> &get_return_type ()
903 rust_assert (has_return_type ());
907 // TODO: is this better? Or is a "vis_block" better?
908 WhereClause
&get_where_clause () { return where_clause
; }
910 Identifier
get_method_name () const { return method_name
; }
912 NodeId
get_node_id () const { return node_id
; }
914 Location
get_locus () const override final
{ return locus
; }
916 FunctionQualifiers
get_qualifiers () { return qualifiers
; }
918 Visibility
&get_visibility () { return vis
; }
919 const Visibility
&get_visibility () const { return vis
; }
922 /* Use covariance to implement clone function as returning this object
923 * rather than base */
924 Method
*clone_inherent_impl_item_impl () const final override
926 return clone_method_impl ();
929 /* Use covariance to implement clone function as returning this object
930 * rather than base */
931 Method
*clone_trait_impl_item_impl () const final override
933 return clone_method_impl ();
936 /*virtual*/ Method
*clone_method_impl () const { return new Method (*this); }
939 // Item that supports visibility - abstract base class
940 class VisItem
: public Item
942 Visibility visibility
;
943 std::vector
<Attribute
> outer_attrs
;
946 // Visibility constructor
947 VisItem (Visibility visibility
,
948 std::vector
<Attribute
> outer_attrs
= std::vector
<Attribute
> ())
949 : visibility (std::move (visibility
)), outer_attrs (std::move (outer_attrs
))
952 // Visibility copy constructor
953 VisItem (VisItem
const &other
)
954 : visibility (other
.visibility
), outer_attrs (other
.outer_attrs
)
957 // Overload assignment operator to clone
958 VisItem
&operator= (VisItem
const &other
)
960 visibility
= other
.visibility
;
961 outer_attrs
= other
.outer_attrs
;
967 VisItem (VisItem
&&other
) = default;
968 VisItem
&operator= (VisItem
&&other
) = default;
971 /* Does the item have some kind of public visibility (non-default
973 bool has_visibility () const { return visibility
.is_public (); }
975 std::string
as_string () const override
;
977 // TODO: this mutable getter seems really dodgy. Think up better way.
978 Visibility
&get_visibility () { return visibility
; }
979 const Visibility
&get_visibility () const { return visibility
; }
981 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
982 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
985 // Rust module item - abstract base class
986 class Module
: public VisItem
989 // Type of the current module. A module can be either loaded or unloaded,
990 // meaning that the items of the module can already be present or not. For
991 // example, the following module would be loaded: `mod foo { fn bar() {} }`.
992 // However, the module would be unloaded if it refers to an external file (i.e
993 // `mod foo;`) and then become loaded upon expansion.
1000 Identifier
get_name () const { return module_name
; }
1003 Identifier module_name
;
1007 // Name of the file including the module
1008 std::string outer_filename
;
1009 // bool has_inner_attrs;
1010 std::vector
<Attribute
> inner_attrs
;
1012 std::vector
<std::unique_ptr
<Item
>> items
;
1013 // Names of including inline modules (immediate parent is last in the list)
1014 std::vector
<std::string
> module_scope
;
1016 // Filename the module refers to. Empty string on LOADED modules or if an
1017 // error occured when dealing with UNLOADED modules
1018 std::string module_file
;
1020 void clone_items (const std::vector
<std::unique_ptr
<Item
>> &other_items
)
1022 items
.reserve (other_items
.size ());
1023 for (const auto &e
: other_items
)
1024 items
.push_back (e
->clone_item ());
1028 // Returns whether the module has items in its body.
1029 bool has_items () const { return !items
.empty (); }
1031 // Returns whether the module has any inner attributes.
1032 bool has_inner_attrs () const { return !inner_attrs
.empty (); }
1034 // Unloaded module constructor
1035 Module (Identifier module_name
, Visibility visibility
,
1036 std::vector
<Attribute
> outer_attrs
, Location locus
,
1037 std::string outer_filename
, std::vector
<std::string
> module_scope
)
1038 : VisItem (std::move (visibility
), std::move (outer_attrs
)),
1039 module_name (module_name
), locus (locus
), kind (ModuleKind::UNLOADED
),
1040 outer_filename (outer_filename
), inner_attrs (std::vector
<Attribute
> ()),
1041 items (std::vector
<std::unique_ptr
<Item
>> ()),
1042 module_scope (std::move (module_scope
))
1045 // Loaded module constructor, with items
1046 Module (Identifier name
, Location locus
,
1047 std::vector
<std::unique_ptr
<Item
>> items
,
1048 Visibility visibility
= Visibility::create_error (),
1049 std::vector
<Attribute
> inner_attrs
= std::vector
<Attribute
> (),
1050 std::vector
<Attribute
> outer_attrs
= std::vector
<Attribute
> ())
1051 : VisItem (std::move (visibility
), std::move (outer_attrs
)),
1052 module_name (name
), locus (locus
), kind (ModuleKind::LOADED
),
1053 outer_filename (std::string ()), inner_attrs (std::move (inner_attrs
)),
1054 items (std::move (items
))
1057 // Copy constructor with vector clone
1058 Module (Module
const &other
)
1059 : VisItem (other
), module_name (other
.module_name
), locus (other
.locus
),
1060 kind (other
.kind
), inner_attrs (other
.inner_attrs
),
1061 module_scope (other
.module_scope
)
1063 // We need to check whether we are copying a loaded module or an unloaded
1064 // one. In the second case, clear the `items` vector.
1065 if (other
.kind
== LOADED
)
1066 clone_items (other
.items
);
1071 // Overloaded assignment operator with vector clone
1072 Module
&operator= (Module
const &other
)
1074 VisItem::operator= (other
);
1076 module_name
= other
.module_name
;
1077 locus
= other
.locus
;
1079 inner_attrs
= other
.inner_attrs
;
1080 module_scope
= other
.module_scope
;
1082 // Likewise, we need to clear the `items` vector in case the other module is
1085 clone_items (other
.items
);
1092 // Search for the filename associated with an external module, storing it in
1094 void process_file_path ();
1095 // Load the items contained in an external module
1098 void accept_vis (ASTVisitor
&vis
) override
;
1100 /* Override that runs the function recursively on all items contained within
1102 void add_crate_name (std::vector
<std::string
> &names
) const override
;
1104 // Returns the kind of the module
1105 enum ModuleKind
get_kind () const { return kind
; }
1107 // TODO: think of better way to do this - mutable getter seems dodgy
1108 const std::vector
<Attribute
> &get_inner_attrs () const { return inner_attrs
; }
1109 std::vector
<Attribute
> &get_inner_attrs () { return inner_attrs
; }
1111 const std::vector
<std::unique_ptr
<Item
>> &get_items () const { return items
; }
1112 std::vector
<std::unique_ptr
<Item
>> &get_items () { return items
; }
1114 // move constructors
1115 Module (Module
&&other
) = default;
1116 Module
&operator= (Module
&&other
) = default;
1118 std::string
as_string () const override
;
1120 Location
get_locus () const override final
{ return locus
; }
1122 // Invalid if name is empty, so base stripping on that.
1123 void mark_for_strip () override
{ module_name
= ""; }
1124 bool is_marked_for_strip () const override
{ return module_name
.empty (); }
1127 /* Use covariance to implement clone function as returning this object
1128 * rather than base */
1129 Module
*clone_item_impl () const override
{ return new Module (*this); }
1132 // Rust extern crate declaration AST node
1133 class ExternCrate
: public VisItem
1135 // this is either an identifier or "self", with self parsed to string
1136 std::string referenced_crate
;
1137 // bool has_as_clause;
1138 // AsClause as_clause;
1139 // this is either an identifier or "_", with _ parsed to string
1140 std::string as_clause_name
;
1145 "extern crate foo as _"
1147 "extern crate std as cool_std" */
1149 std::string
as_string () const override
;
1151 // Returns whether extern crate declaration has an as clause.
1152 bool has_as_clause () const { return !as_clause_name
.empty (); }
1154 /* Returns whether extern crate declaration references the current crate
1156 bool references_self () const { return referenced_crate
== "self"; }
1159 ExternCrate (std::string referenced_crate
, Visibility visibility
,
1160 std::vector
<Attribute
> outer_attrs
, Location locus
,
1161 std::string as_clause_name
= std::string ())
1162 : VisItem (std::move (visibility
), std::move (outer_attrs
)),
1163 referenced_crate (std::move (referenced_crate
)),
1164 as_clause_name (std::move (as_clause_name
)), locus (locus
)
1167 Location
get_locus () const override final
{ return locus
; }
1169 void accept_vis (ASTVisitor
&vis
) override
;
1171 const std::string
&get_referenced_crate () const { return referenced_crate
; }
1172 const std::string
&get_as_clause () const { return as_clause_name
; }
1174 // Override that adds extern crate name in decl to passed list of names.
1175 void add_crate_name (std::vector
<std::string
> &names
) const override
1177 names
.push_back (referenced_crate
);
1180 // Invalid if crate name is empty, so base stripping on that.
1181 void mark_for_strip () override
{ referenced_crate
= ""; }
1182 bool is_marked_for_strip () const override
1184 return referenced_crate
.empty ();
1188 /* Use covariance to implement clone function as returning this object
1189 * rather than base */
1190 ExternCrate
*clone_item_impl () const override
1192 return new ExternCrate (*this);
1196 // The path-ish thing referred to in a use declaration - abstract base class
1209 virtual ~UseTree () {}
1211 // Overload assignment operator to clone
1212 UseTree
&operator= (UseTree
const &other
)
1214 locus
= other
.locus
;
1219 UseTree (const UseTree
&other
) = default;
1221 // move constructors
1222 UseTree (UseTree
&&other
) = default;
1223 UseTree
&operator= (UseTree
&&other
) = default;
1225 // Unique pointer custom clone function
1226 std::unique_ptr
<UseTree
> clone_use_tree () const
1228 return std::unique_ptr
<UseTree
> (clone_use_tree_impl ());
1231 virtual std::string
as_string () const = 0;
1232 virtual Kind
get_kind () const = 0;
1234 Location
get_locus () const { return locus
; }
1236 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1239 // Clone function implementation as pure virtual method
1240 virtual UseTree
*clone_use_tree_impl () const = 0;
1242 UseTree (Location locus
) : locus (locus
) {}
1245 // Use tree with a glob (wildcard) operator
1246 class UseTreeGlob
: public UseTree
1261 UseTreeGlob (PathType glob_type
, SimplePath path
, Location locus
)
1262 : UseTree (locus
), glob_type (glob_type
), path (std::move (path
))
1264 if (this->glob_type
!= PATH_PREFIXED
)
1266 // compiler implementation error if there is a path with a
1267 // non-path-prefixed use tree glob
1268 rust_assert (!has_path ());
1270 // TODO: do path-prefixed paths also have to have a path? If so, have an
1271 // assert for that too.
1274 /* Returns whether has path. Should be made redundant by PathType
1276 bool has_path () const { return !path
.is_empty (); }
1278 std::string
as_string () const override
;
1280 void accept_vis (ASTVisitor
&vis
) override
;
1282 Kind
get_kind () const override
{ return Glob
; }
1284 SimplePath
get_path () const
1286 rust_assert (has_path ());
1290 /* TODO: find way to ensure only PATH_PREFIXED glob_type has path - factory
1293 /* Use covariance to implement clone function as returning this object
1294 * rather than base */
1295 UseTreeGlob
*clone_use_tree_impl () const override
1297 return new UseTreeGlob (*this);
1301 // Use tree with a list of paths with a common prefix
1302 class UseTreeList
: public UseTree
1316 std::vector
<std::unique_ptr
<UseTree
>> trees
;
1319 UseTreeList (PathType path_type
, SimplePath path
,
1320 std::vector
<std::unique_ptr
<UseTree
>> trees
, Location locus
)
1321 : UseTree (locus
), path_type (path_type
), path (std::move (path
)),
1322 trees (std::move (trees
))
1324 if (this->path_type
!= PATH_PREFIXED
)
1326 // compiler implementation error if there is a path with a
1327 // non-path-prefixed use tree glob
1328 rust_assert (!has_path ());
1330 // TODO: do path-prefixed paths also have to have a path? If so, have an
1331 // assert for that too.
1334 // copy constructor with vector clone
1335 UseTreeList (UseTreeList
const &other
)
1336 : UseTree (other
), path_type (other
.path_type
), path (other
.path
)
1338 trees
.reserve (other
.trees
.size ());
1339 for (const auto &e
: other
.trees
)
1340 trees
.push_back (e
->clone_use_tree ());
1343 // overloaded assignment operator with vector clone
1344 UseTreeList
&operator= (UseTreeList
const &other
)
1346 UseTree::operator= (other
);
1347 path_type
= other
.path_type
;
1350 trees
.reserve (other
.trees
.size ());
1351 for (const auto &e
: other
.trees
)
1352 trees
.push_back (e
->clone_use_tree ());
1357 // move constructors
1358 UseTreeList (UseTreeList
&&other
) = default;
1359 UseTreeList
&operator= (UseTreeList
&&other
) = default;
1361 // Returns whether has path. Should be made redundant by path_type.
1362 bool has_path () const { return !path
.is_empty (); }
1364 // Returns whether has inner tree elements.
1365 bool has_trees () const { return !trees
.empty (); }
1367 std::string
as_string () const override
;
1369 void accept_vis (ASTVisitor
&vis
) override
;
1371 Kind
get_kind () const override
{ return List
; }
1372 SimplePath
get_path () const
1374 rust_assert (has_path ());
1378 const std::vector
<std::unique_ptr
<UseTree
>> &get_trees () const
1383 // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
1386 /* Use covariance to implement clone function as returning this object
1387 * rather than base */
1388 UseTreeList
*clone_use_tree_impl () const override
1390 return new UseTreeList (*this);
1394 // Use tree where it rebinds the module name as something else
1395 class UseTreeRebind
: public UseTree
1408 NewBindType bind_type
;
1409 Identifier identifier
; // only if NewBindType is IDENTIFIER
1412 UseTreeRebind (NewBindType bind_type
, SimplePath path
, Location locus
,
1413 Identifier identifier
= std::string ())
1414 : UseTree (locus
), path (std::move (path
)), bind_type (bind_type
),
1415 identifier (std::move (identifier
))
1418 // Returns whether has path (this should always be true).
1419 bool has_path () const { return !path
.is_empty (); }
1421 // Returns whether has identifier (or, rather, is allowed to).
1422 bool has_identifier () const { return bind_type
== IDENTIFIER
; }
1424 std::string
as_string () const override
;
1426 void accept_vis (ASTVisitor
&vis
) override
;
1428 Kind
get_kind () const override
{ return Rebind
; }
1430 SimplePath
get_path () const
1432 rust_assert (has_path ());
1436 const Identifier
&get_identifier () const
1438 rust_assert (has_identifier ());
1442 // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
1445 /* Use covariance to implement clone function as returning this object
1446 * rather than base */
1447 virtual UseTreeRebind
*clone_use_tree_impl () const override
1449 return new UseTreeRebind (*this);
1453 // Rust use declaration (i.e. for modules) AST node
1454 class UseDeclaration
: public VisItem
1456 std::unique_ptr
<UseTree
> use_tree
;
1460 std::string
as_string () const override
;
1462 UseDeclaration (std::unique_ptr
<UseTree
> use_tree
, Visibility visibility
,
1463 std::vector
<Attribute
> outer_attrs
, Location locus
)
1464 : VisItem (std::move (visibility
), std::move (outer_attrs
)),
1465 use_tree (std::move (use_tree
)), locus (locus
)
1468 // Copy constructor with clone
1469 UseDeclaration (UseDeclaration
const &other
)
1470 : VisItem (other
), locus (other
.locus
)
1472 // guard to prevent null dereference (only required if error state)
1473 if (other
.use_tree
!= nullptr)
1474 use_tree
= other
.use_tree
->clone_use_tree ();
1477 // Overloaded assignment operator to clone
1478 UseDeclaration
&operator= (UseDeclaration
const &other
)
1480 VisItem::operator= (other
);
1481 // visibility = other.visibility->clone_visibility();
1482 // outer_attrs = other.outer_attrs;
1483 locus
= other
.locus
;
1485 // guard to prevent null dereference (only required if error state)
1486 if (other
.use_tree
!= nullptr)
1487 use_tree
= other
.use_tree
->clone_use_tree ();
1494 // move constructors
1495 UseDeclaration (UseDeclaration
&&other
) = default;
1496 UseDeclaration
&operator= (UseDeclaration
&&other
) = default;
1498 Location
get_locus () const override final
{ return locus
; }
1499 const std::unique_ptr
<UseTree
> &get_tree () const { return use_tree
; }
1501 void accept_vis (ASTVisitor
&vis
) override
;
1503 // Invalid if use tree is null, so base stripping on that.
1504 void mark_for_strip () override
{ use_tree
= nullptr; }
1505 bool is_marked_for_strip () const override
{ return use_tree
== nullptr; }
1508 /* Use covariance to implement clone function as returning this object
1509 * rather than base */
1510 UseDeclaration
*clone_item_impl () const override
1512 return new UseDeclaration (*this);
1518 // Rust function declaration AST node
1519 class Function
: public VisItem
, public InherentImplItem
, public TraitImplItem
1521 FunctionQualifiers qualifiers
;
1522 Identifier function_name
;
1523 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
;
1524 std::vector
<FunctionParam
> function_params
;
1525 std::unique_ptr
<Type
> return_type
;
1526 WhereClause where_clause
;
1527 std::unique_ptr
<BlockExpr
> function_body
;
1531 std::string
as_string () const override
;
1533 // Returns whether function has generic parameters.
1534 bool has_generics () const { return !generic_params
.empty (); }
1536 // Returns whether function has regular parameters.
1537 bool has_function_params () const { return !function_params
.empty (); }
1539 // Returns whether function has return type - if not, it is void.
1540 bool has_return_type () const { return return_type
!= nullptr; }
1542 // Returns whether function has a where clause.
1543 bool has_where_clause () const { return !where_clause
.is_empty (); }
1545 // Mega-constructor with all possible fields
1546 Function (Identifier function_name
, FunctionQualifiers qualifiers
,
1547 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
1548 std::vector
<FunctionParam
> function_params
,
1549 std::unique_ptr
<Type
> return_type
, WhereClause where_clause
,
1550 std::unique_ptr
<BlockExpr
> function_body
, Visibility vis
,
1551 std::vector
<Attribute
> outer_attrs
, Location locus
)
1552 : VisItem (std::move (vis
), std::move (outer_attrs
)),
1553 qualifiers (std::move (qualifiers
)),
1554 function_name (std::move (function_name
)),
1555 generic_params (std::move (generic_params
)),
1556 function_params (std::move (function_params
)),
1557 return_type (std::move (return_type
)),
1558 where_clause (std::move (where_clause
)),
1559 function_body (std::move (function_body
)), locus (locus
)
1562 // TODO: add constructor with less fields
1564 // Copy constructor with clone
1565 Function (Function
const &other
)
1566 : VisItem (other
), qualifiers (other
.qualifiers
),
1567 function_name (other
.function_name
),
1568 function_params (other
.function_params
),
1569 where_clause (other
.where_clause
), locus (other
.locus
)
1571 // guard to prevent null dereference (always required)
1572 if (other
.return_type
!= nullptr)
1573 return_type
= other
.return_type
->clone_type ();
1575 // guard to prevent null dereference (only required if error state)
1576 if (other
.function_body
!= nullptr)
1577 function_body
= other
.function_body
->clone_block_expr ();
1579 generic_params
.reserve (other
.generic_params
.size ());
1580 for (const auto &e
: other
.generic_params
)
1581 generic_params
.push_back (e
->clone_generic_param ());
1584 // Overloaded assignment operator to clone
1585 Function
&operator= (Function
const &other
)
1587 VisItem::operator= (other
);
1588 function_name
= other
.function_name
;
1589 qualifiers
= other
.qualifiers
;
1590 function_params
= other
.function_params
;
1591 where_clause
= other
.where_clause
;
1592 // visibility = other.visibility->clone_visibility();
1593 // outer_attrs = other.outer_attrs;
1594 locus
= other
.locus
;
1596 // guard to prevent null dereference (always required)
1597 if (other
.return_type
!= nullptr)
1598 return_type
= other
.return_type
->clone_type ();
1600 return_type
= nullptr;
1602 // guard to prevent null dereference (only required if error state)
1603 if (other
.function_body
!= nullptr)
1604 function_body
= other
.function_body
->clone_block_expr ();
1606 function_body
= nullptr;
1608 generic_params
.reserve (other
.generic_params
.size ());
1609 for (const auto &e
: other
.generic_params
)
1610 generic_params
.push_back (e
->clone_generic_param ());
1615 // move constructors
1616 Function (Function
&&other
) = default;
1617 Function
&operator= (Function
&&other
) = default;
1619 Location
get_locus () const override final
{ return locus
; }
1621 void accept_vis (ASTVisitor
&vis
) override
;
1623 // Invalid if block is null, so base stripping on that.
1624 void mark_for_strip () override
{ function_body
= nullptr; }
1625 bool is_marked_for_strip () const override
1627 return function_body
== nullptr;
1630 std::vector
<FunctionParam
> &get_function_params () { return function_params
; }
1631 const std::vector
<FunctionParam
> &get_function_params () const
1633 return function_params
;
1636 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
1638 return generic_params
;
1640 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
1642 return generic_params
;
1645 // TODO: is this better? Or is a "vis_block" better?
1646 std::unique_ptr
<BlockExpr
> &get_definition ()
1648 rust_assert (function_body
!= nullptr);
1649 return function_body
;
1652 const FunctionQualifiers
&get_qualifiers () const { return qualifiers
; }
1654 Identifier
get_function_name () const { return function_name
; }
1656 // TODO: is this better? Or is a "vis_block" better?
1657 WhereClause
&get_where_clause () { return where_clause
; }
1659 // TODO: is this better? Or is a "vis_block" better?
1660 std::unique_ptr
<Type
> &get_return_type ()
1662 rust_assert (has_return_type ());
1667 /* Use covariance to implement clone function as returning this object
1668 * rather than base */
1669 Function
*clone_item_impl () const override
{ return new Function (*this); }
1671 /* Use covariance to implement clone function as returning this object
1672 * rather than base */
1673 Function
*clone_inherent_impl_item_impl () const override
1675 return new Function (*this);
1678 /* Use covariance to implement clone function as returning this object
1679 * rather than base */
1680 Function
*clone_trait_impl_item_impl () const override
1682 return new Function (*this);
1686 // Rust type alias (i.e. typedef) AST node
1687 class TypeAlias
: public VisItem
, public TraitImplItem
1689 Identifier new_type_name
;
1691 // bool has_generics;
1692 // Generics generic_params;
1693 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
1695 // bool has_where_clause;
1696 WhereClause where_clause
;
1698 std::unique_ptr
<Type
> existing_type
;
1703 std::string
as_string () const override
;
1705 // Returns whether type alias has generic parameters.
1706 bool has_generics () const { return !generic_params
.empty (); }
1708 // Returns whether type alias has a where clause.
1709 bool has_where_clause () const { return !where_clause
.is_empty (); }
1711 // Mega-constructor with all possible fields
1712 TypeAlias (Identifier new_type_name
,
1713 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
1714 WhereClause where_clause
, std::unique_ptr
<Type
> existing_type
,
1715 Visibility vis
, std::vector
<Attribute
> outer_attrs
, Location locus
)
1716 : VisItem (std::move (vis
), std::move (outer_attrs
)),
1717 new_type_name (std::move (new_type_name
)),
1718 generic_params (std::move (generic_params
)),
1719 where_clause (std::move (where_clause
)),
1720 existing_type (std::move (existing_type
)), locus (locus
)
1724 TypeAlias (TypeAlias
const &other
)
1725 : VisItem (other
), new_type_name (other
.new_type_name
),
1726 where_clause (other
.where_clause
), locus (other
.locus
)
1728 // guard to prevent null dereference (only required if error state)
1729 if (other
.existing_type
!= nullptr)
1730 existing_type
= other
.existing_type
->clone_type ();
1732 generic_params
.reserve (other
.generic_params
.size ());
1733 for (const auto &e
: other
.generic_params
)
1734 generic_params
.push_back (e
->clone_generic_param ());
1737 // Overloaded assignment operator to clone
1738 TypeAlias
&operator= (TypeAlias
const &other
)
1740 VisItem::operator= (other
);
1741 new_type_name
= other
.new_type_name
;
1742 where_clause
= other
.where_clause
;
1743 // visibility = other.visibility->clone_visibility();
1744 // outer_attrs = other.outer_attrs;
1745 locus
= other
.locus
;
1747 // guard to prevent null dereference (only required if error state)
1748 if (other
.existing_type
!= nullptr)
1749 existing_type
= other
.existing_type
->clone_type ();
1751 existing_type
= nullptr;
1753 generic_params
.reserve (other
.generic_params
.size ());
1754 for (const auto &e
: other
.generic_params
)
1755 generic_params
.push_back (e
->clone_generic_param ());
1760 // move constructors
1761 TypeAlias (TypeAlias
&&other
) = default;
1762 TypeAlias
&operator= (TypeAlias
&&other
) = default;
1764 Location
get_locus () const override final
{ return locus
; }
1766 void accept_vis (ASTVisitor
&vis
) override
;
1768 // Invalid if existing type is null, so base stripping on that.
1769 void mark_for_strip () override
{ existing_type
= nullptr; }
1770 bool is_marked_for_strip () const override
1772 return existing_type
== nullptr;
1775 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
1777 return generic_params
;
1779 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
1781 return generic_params
;
1784 // TODO: is this better? Or is a "vis_block" better?
1785 WhereClause
&get_where_clause () { return where_clause
; }
1787 // TODO: is this better? Or is a "vis_block" better?
1788 std::unique_ptr
<Type
> &get_type_aliased ()
1790 rust_assert (existing_type
!= nullptr);
1791 return existing_type
;
1794 Identifier
get_new_type_name () const { return new_type_name
; }
1797 /* Use covariance to implement clone function as returning this object
1798 * rather than base */
1799 TypeAlias
*clone_item_impl () const override
{ return new TypeAlias (*this); }
1801 /* Use covariance to implement clone function as returning this object
1802 * rather than base */
1803 TypeAlias
*clone_trait_impl_item_impl () const override
1805 return new TypeAlias (*this);
1809 // Rust base struct declaration AST node - abstract base class
1810 class Struct
: public VisItem
1813 // protected to enable access by derived classes - allows better as_string
1814 Identifier struct_name
;
1816 // bool has_generics;
1817 // Generics generic_params;
1818 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
1820 // bool has_where_clause;
1821 WhereClause where_clause
;
1827 // Returns whether struct has generic parameters.
1828 bool has_generics () const { return !generic_params
.empty (); }
1830 // Returns whether struct has a where clause.
1831 bool has_where_clause () const { return !where_clause
.is_empty (); }
1833 Location
get_locus () const override final
{ return locus
; }
1835 // Invalid if name is empty, so base stripping on that.
1836 void mark_for_strip () override
{ struct_name
= ""; }
1837 bool is_marked_for_strip () const override
{ return struct_name
.empty (); }
1839 Identifier
get_struct_name () const { return struct_name
; }
1841 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
1843 return generic_params
;
1845 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
1847 return generic_params
;
1850 // TODO: is this better? Or is a "vis_block" better?
1851 WhereClause
&get_where_clause () { return where_clause
; }
1853 Identifier
get_identifier () const { return struct_name
; }
1856 Struct (Identifier struct_name
,
1857 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
1858 WhereClause where_clause
, Visibility vis
, Location locus
,
1859 std::vector
<Attribute
> outer_attrs
= std::vector
<Attribute
> ())
1860 : VisItem (std::move (vis
), std::move (outer_attrs
)),
1861 struct_name (std::move (struct_name
)),
1862 generic_params (std::move (generic_params
)),
1863 where_clause (std::move (where_clause
)), locus (locus
)
1866 // Copy constructor with vector clone
1867 Struct (Struct
const &other
)
1868 : VisItem (other
), struct_name (other
.struct_name
),
1869 where_clause (other
.where_clause
), locus (other
.locus
)
1871 generic_params
.reserve (other
.generic_params
.size ());
1872 for (const auto &e
: other
.generic_params
)
1873 generic_params
.push_back (e
->clone_generic_param ());
1876 // Overloaded assignment operator with vector clone
1877 Struct
&operator= (Struct
const &other
)
1879 VisItem::operator= (other
);
1880 struct_name
= other
.struct_name
;
1881 where_clause
= other
.where_clause
;
1882 locus
= other
.locus
;
1884 generic_params
.reserve (other
.generic_params
.size ());
1885 for (const auto &e
: other
.generic_params
)
1886 generic_params
.push_back (e
->clone_generic_param ());
1891 // move constructors
1892 Struct (Struct
&&other
) = default;
1893 Struct
&operator= (Struct
&&other
) = default;
1896 // A single field in a struct
1900 // bool has_outer_attributes;
1901 std::vector
<Attribute
> outer_attrs
;
1903 // bool has_visibility;
1904 Visibility visibility
;
1906 Identifier field_name
;
1907 std::unique_ptr
<Type
> field_type
;
1914 // Returns whether struct field has any outer attributes.
1915 bool has_outer_attributes () const { return !outer_attrs
.empty (); }
1917 // Returns whether struct field has a non-private (non-default) visibility.
1918 bool has_visibility () const { return !visibility
.is_error (); }
1920 StructField (Identifier field_name
, std::unique_ptr
<Type
> field_type
,
1921 Visibility vis
, Location locus
,
1922 std::vector
<Attribute
> outer_attrs
= std::vector
<Attribute
> ())
1923 : outer_attrs (std::move (outer_attrs
)), visibility (std::move (vis
)),
1924 field_name (std::move (field_name
)), field_type (std::move (field_type
)),
1925 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus
)
1929 StructField (StructField
const &other
)
1930 : outer_attrs (other
.outer_attrs
), visibility (other
.visibility
),
1931 field_name (other
.field_name
), node_id (other
.node_id
),
1934 // guard to prevent null dereference
1935 if (other
.field_type
!= nullptr)
1936 field_type
= other
.field_type
->clone_type ();
1939 ~StructField () = default;
1941 // Overloaded assignment operator to clone
1942 StructField
&operator= (StructField
const &other
)
1944 field_name
= other
.field_name
;
1945 visibility
= other
.visibility
;
1946 outer_attrs
= other
.outer_attrs
;
1947 node_id
= other
.node_id
;
1949 // guard to prevent null dereference
1950 if (other
.field_type
!= nullptr)
1951 field_type
= other
.field_type
->clone_type ();
1953 field_type
= nullptr;
1958 // move constructors
1959 StructField (StructField
&&other
) = default;
1960 StructField
&operator= (StructField
&&other
) = default;
1962 // Returns whether struct field is in an error state.
1963 bool is_error () const
1965 return field_name
.empty () && field_type
== nullptr;
1966 // this should really be an or since neither are allowed
1969 // Creates an error state struct field.
1970 static StructField
create_error ()
1972 return StructField (std::string (""), nullptr, Visibility::create_error (),
1976 std::string
as_string () const;
1978 // TODO: this mutable getter seems really dodgy. Think up better way.
1979 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
1980 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
1982 Identifier
get_field_name () const { return field_name
; }
1984 Location
get_locus () const { return locus
; }
1986 // TODO: is this better? Or is a "vis_block" better?
1987 std::unique_ptr
<Type
> &get_field_type ()
1989 rust_assert (field_type
!= nullptr);
1993 Visibility
&get_visibility () { return visibility
; }
1994 const Visibility
&get_visibility () const { return visibility
; }
1996 NodeId
get_node_id () const { return node_id
; }
1999 // Rust struct declaration with true struct type AST node
2000 class StructStruct
: public Struct
2002 std::vector
<StructField
> fields
;
2006 std::string
as_string () const override
;
2008 // Mega-constructor with all possible fields
2009 StructStruct (std::vector
<StructField
> fields
, Identifier struct_name
,
2010 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
2011 WhereClause where_clause
, bool is_unit
, Visibility vis
,
2012 std::vector
<Attribute
> outer_attrs
, Location locus
)
2013 : Struct (std::move (struct_name
), std::move (generic_params
),
2014 std::move (where_clause
), std::move (vis
), locus
,
2015 std::move (outer_attrs
)),
2016 fields (std::move (fields
)), is_unit (is_unit
)
2019 // Unit struct constructor
2020 StructStruct (Identifier struct_name
,
2021 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
2022 WhereClause where_clause
, Visibility vis
,
2023 std::vector
<Attribute
> outer_attrs
, Location locus
)
2024 : Struct (std::move (struct_name
), std::move (generic_params
),
2025 std::move (where_clause
), std::move (vis
), locus
,
2026 std::move (outer_attrs
)),
2030 /* Returns whether the struct is a unit struct - struct defined without
2031 * fields. This is important because it also means an implicit constant of its
2032 * type is defined. */
2033 bool is_unit_struct () const { return is_unit
; }
2035 void accept_vis (ASTVisitor
&vis
) override
;
2037 // TODO: this mutable getter seems really dodgy. Think up better way.
2038 std::vector
<StructField
> &get_fields () { return fields
; }
2039 const std::vector
<StructField
> &get_fields () const { return fields
; }
2042 /* Use covariance to implement clone function as returning this object
2043 * rather than base */
2044 StructStruct
*clone_item_impl () const override
2046 return new StructStruct (*this);
2050 // A single field in a tuple
2054 // bool has_outer_attributes;
2055 std::vector
<Attribute
> outer_attrs
;
2057 // bool has_visibility;
2058 Visibility visibility
;
2060 std::unique_ptr
<Type
> field_type
;
2067 // Returns whether tuple field has outer attributes.
2068 bool has_outer_attributes () const { return !outer_attrs
.empty (); }
2070 /* Returns whether tuple field has a non-default visibility (i.e. a public
2072 bool has_visibility () const { return !visibility
.is_error (); }
2074 // Complete constructor
2075 TupleField (std::unique_ptr
<Type
> field_type
, Visibility vis
, Location locus
,
2076 std::vector
<Attribute
> outer_attrs
= std::vector
<Attribute
> ())
2077 : outer_attrs (std::move (outer_attrs
)), visibility (std::move (vis
)),
2078 field_type (std::move (field_type
)),
2079 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus
)
2082 // Copy constructor with clone
2083 TupleField (TupleField
const &other
)
2084 : outer_attrs (other
.outer_attrs
), visibility (other
.visibility
),
2085 node_id (other
.node_id
), locus (other
.locus
)
2087 // guard to prevent null dereference (only required if error)
2088 if (other
.field_type
!= nullptr)
2089 field_type
= other
.field_type
->clone_type ();
2092 ~TupleField () = default;
2094 // Overloaded assignment operator to clone
2095 TupleField
&operator= (TupleField
const &other
)
2097 visibility
= other
.visibility
;
2098 outer_attrs
= other
.outer_attrs
;
2099 node_id
= other
.node_id
;
2100 locus
= other
.locus
;
2102 // guard to prevent null dereference (only required if error)
2103 if (other
.field_type
!= nullptr)
2104 field_type
= other
.field_type
->clone_type ();
2106 field_type
= nullptr;
2111 // move constructors
2112 TupleField (TupleField
&&other
) = default;
2113 TupleField
&operator= (TupleField
&&other
) = default;
2115 // Returns whether tuple field is in an error state.
2116 bool is_error () const { return field_type
== nullptr; }
2118 // Creates an error state tuple field.
2119 static TupleField
create_error ()
2121 return TupleField (nullptr, Visibility::create_error (), Location ());
2124 std::string
as_string () const;
2126 NodeId
get_node_id () const { return node_id
; }
2128 Visibility
&get_visibility () { return visibility
; }
2129 const Visibility
&get_visibility () const { return visibility
; }
2131 Location
get_locus () const { return locus
; }
2133 // TODO: this mutable getter seems really dodgy. Think up better way.
2134 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
2135 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
2137 // TODO: is this better? Or is a "vis_block" better?
2138 std::unique_ptr
<Type
> &get_field_type ()
2140 rust_assert (field_type
!= nullptr);
2145 // Rust tuple declared using struct keyword AST node
2146 class TupleStruct
: public Struct
2148 std::vector
<TupleField
> fields
;
2151 std::string
as_string () const override
;
2153 // Mega-constructor with all possible fields
2154 TupleStruct (std::vector
<TupleField
> fields
, Identifier struct_name
,
2155 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
2156 WhereClause where_clause
, Visibility vis
,
2157 std::vector
<Attribute
> outer_attrs
, Location locus
)
2158 : Struct (std::move (struct_name
), std::move (generic_params
),
2159 std::move (where_clause
), std::move (vis
), locus
,
2160 std::move (outer_attrs
)),
2161 fields (std::move (fields
))
2164 void accept_vis (ASTVisitor
&vis
) override
;
2166 // TODO: this mutable getter seems really dodgy. Think up better way.
2167 std::vector
<TupleField
> &get_fields () { return fields
; }
2168 const std::vector
<TupleField
> &get_fields () const { return fields
; }
2171 /* Use covariance to implement clone function as returning this object
2172 * rather than base */
2173 TupleStruct
*clone_item_impl () const override
2175 return new TupleStruct (*this);
2179 /* An item used in an "enum" tagged union - not abstract: base represents a
2180 * name-only enum. EnumItems (variants) syntactically allow a Visibility
2182 class EnumItem
: public VisItem
2184 Identifier variant_name
;
2189 virtual ~EnumItem () {}
2191 EnumItem (Identifier variant_name
, Visibility vis
,
2192 std::vector
<Attribute
> outer_attrs
, Location locus
)
2193 : VisItem (std::move (vis
), std::move (outer_attrs
)),
2194 variant_name (std::move (variant_name
)), locus (locus
)
2197 // Unique pointer custom clone function
2198 std::unique_ptr
<EnumItem
> clone_enum_item () const
2200 return std::unique_ptr
<EnumItem
> (clone_item_impl ());
2203 virtual std::string
as_string () const;
2205 // not pure virtual as not abstract
2206 virtual void accept_vis (ASTVisitor
&vis
);
2208 Location
get_locus () const { return locus
; }
2210 Identifier
get_identifier () const { return variant_name
; }
2212 // Based on idea that name is never empty.
2213 void mark_for_strip () { variant_name
= ""; }
2214 bool is_marked_for_strip () const { return variant_name
.empty (); }
2217 EnumItem
*clone_item_impl () const override
{ return new EnumItem (*this); }
2220 // A tuple item used in an "enum" tagged union
2221 class EnumItemTuple
: public EnumItem
2223 // bool has_tuple_fields;
2224 std::vector
<TupleField
> tuple_fields
;
2227 // Returns whether tuple enum item has tuple fields.
2228 bool has_tuple_fields () const { return !tuple_fields
.empty (); }
2230 EnumItemTuple (Identifier variant_name
, Visibility vis
,
2231 std::vector
<TupleField
> tuple_fields
,
2232 std::vector
<Attribute
> outer_attrs
, Location locus
)
2233 : EnumItem (std::move (variant_name
), std::move (vis
),
2234 std::move (outer_attrs
), locus
),
2235 tuple_fields (std::move (tuple_fields
))
2238 std::string
as_string () const override
;
2240 void accept_vis (ASTVisitor
&vis
) override
;
2242 // TODO: this mutable getter seems really dodgy. Think up better way.
2243 std::vector
<TupleField
> &get_tuple_fields () { return tuple_fields
; }
2244 const std::vector
<TupleField
> &get_tuple_fields () const
2246 return tuple_fields
;
2250 // Clone function implementation as (not pure) virtual method
2251 EnumItemTuple
*clone_item_impl () const override
2253 return new EnumItemTuple (*this);
2257 // A struct item used in an "enum" tagged union
2258 class EnumItemStruct
: public EnumItem
2260 // bool has_struct_fields;
2261 std::vector
<StructField
> struct_fields
;
2264 // Returns whether struct enum item has struct fields.
2265 bool has_struct_fields () const { return !struct_fields
.empty (); }
2267 EnumItemStruct (Identifier variant_name
, Visibility vis
,
2268 std::vector
<StructField
> struct_fields
,
2269 std::vector
<Attribute
> outer_attrs
, Location locus
)
2270 : EnumItem (std::move (variant_name
), std::move (vis
),
2271 std::move (outer_attrs
), locus
),
2272 struct_fields (std::move (struct_fields
))
2275 std::string
as_string () const override
;
2277 void accept_vis (ASTVisitor
&vis
) override
;
2279 // TODO: this mutable getter seems really dodgy. Think up better way.
2280 std::vector
<StructField
> &get_struct_fields () { return struct_fields
; }
2281 const std::vector
<StructField
> &get_struct_fields () const
2283 return struct_fields
;
2287 // Clone function implementation as (not pure) virtual method
2288 EnumItemStruct
*clone_item_impl () const override
2290 return new EnumItemStruct (*this);
2294 // A discriminant (numbered enum) item used in an "enum" tagged union
2295 class EnumItemDiscriminant
: public EnumItem
2297 std::unique_ptr
<Expr
> expression
;
2300 EnumItemDiscriminant (Identifier variant_name
, Visibility vis
,
2301 std::unique_ptr
<Expr
> expr
,
2302 std::vector
<Attribute
> outer_attrs
, Location locus
)
2303 : EnumItem (std::move (variant_name
), std::move (vis
),
2304 std::move (outer_attrs
), locus
),
2305 expression (std::move (expr
))
2308 // Copy constructor with clone
2309 EnumItemDiscriminant (EnumItemDiscriminant
const &other
)
2310 : EnumItem (other
), expression (other
.expression
->clone_expr ())
2313 // Overloaded assignment operator to clone
2314 EnumItemDiscriminant
&operator= (EnumItemDiscriminant
const &other
)
2316 EnumItem::operator= (other
);
2317 expression
= other
.expression
->clone_expr ();
2318 // variant_name = other.variant_name;
2319 // outer_attrs = other.outer_attrs;
2324 // move constructors
2325 EnumItemDiscriminant (EnumItemDiscriminant
&&other
) = default;
2326 EnumItemDiscriminant
&operator= (EnumItemDiscriminant
&&other
) = default;
2328 std::string
as_string () const override
;
2330 void accept_vis (ASTVisitor
&vis
) override
;
2332 // TODO: is this better? Or is a "vis_block" better?
2333 std::unique_ptr
<Expr
> &get_expr ()
2335 rust_assert (expression
!= nullptr);
2340 // Clone function implementation as (not pure) virtual method
2341 EnumItemDiscriminant
*clone_item_impl () const override
2343 return new EnumItemDiscriminant (*this);
2347 // AST node for Rust "enum" - tagged union
2348 class Enum
: public VisItem
2350 Identifier enum_name
;
2352 // bool has_generics;
2353 // Generics generic_params;
2354 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
2356 // bool has_where_clause;
2357 WhereClause where_clause
;
2359 std::vector
<std::unique_ptr
<EnumItem
>> items
;
2364 std::string
as_string () const override
;
2366 // Returns whether "enum" has generic parameters.
2367 bool has_generics () const { return !generic_params
.empty (); }
2369 // Returns whether "enum" has a where clause.
2370 bool has_where_clause () const { return !where_clause
.is_empty (); }
2372 /* Returns whether enum is a "zero-variant" (no possible variant) enum,
2373 * which cannot be instantiated. */
2374 bool is_zero_variant () const { return items
.empty (); }
2377 Enum (Identifier enum_name
, Visibility vis
,
2378 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
2379 WhereClause where_clause
, std::vector
<std::unique_ptr
<EnumItem
>> items
,
2380 std::vector
<Attribute
> outer_attrs
, Location locus
)
2381 : VisItem (std::move (vis
), std::move (outer_attrs
)),
2382 enum_name (std::move (enum_name
)),
2383 generic_params (std::move (generic_params
)),
2384 where_clause (std::move (where_clause
)), items (std::move (items
)),
2388 // TODO: constructor with less arguments
2390 // Copy constructor with vector clone
2391 Enum (Enum
const &other
)
2392 : VisItem (other
), enum_name (other
.enum_name
),
2393 where_clause (other
.where_clause
), locus (other
.locus
)
2395 generic_params
.reserve (other
.generic_params
.size ());
2396 for (const auto &e
: other
.generic_params
)
2397 generic_params
.push_back (e
->clone_generic_param ());
2399 items
.reserve (other
.items
.size ());
2400 for (const auto &e
: other
.items
)
2401 items
.push_back (e
->clone_enum_item ());
2404 // Overloaded assignment operator with vector clone
2405 Enum
&operator= (Enum
const &other
)
2407 VisItem::operator= (other
);
2408 enum_name
= other
.enum_name
;
2409 where_clause
= other
.where_clause
;
2410 locus
= other
.locus
;
2412 generic_params
.reserve (other
.generic_params
.size ());
2413 for (const auto &e
: other
.generic_params
)
2414 generic_params
.push_back (e
->clone_generic_param ());
2416 items
.reserve (other
.items
.size ());
2417 for (const auto &e
: other
.items
)
2418 items
.push_back (e
->clone_enum_item ());
2423 // Move constructors
2424 Enum (Enum
&&other
) = default;
2425 Enum
&operator= (Enum
&&other
) = default;
2427 Location
get_locus () const override final
{ return locus
; }
2429 void accept_vis (ASTVisitor
&vis
) override
;
2431 Identifier
get_identifier () const { return enum_name
; }
2433 // Invalid if name is empty, so base stripping on that.
2434 void mark_for_strip () override
{ enum_name
= ""; }
2435 bool is_marked_for_strip () const override
{ return enum_name
.empty (); }
2437 // TODO: this mutable getter seems really dodgy. Think up better way.
2438 std::vector
<std::unique_ptr
<EnumItem
>> &get_variants () { return items
; }
2439 const std::vector
<std::unique_ptr
<EnumItem
>> &get_variants () const
2444 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
2446 return generic_params
;
2448 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
2450 return generic_params
;
2453 // TODO: is this better? Or is a "vis_block" better?
2454 WhereClause
&get_where_clause () { return where_clause
; }
2457 /* Use covariance to implement clone function as returning this object
2458 * rather than base */
2459 Enum
*clone_item_impl () const override
{ return new Enum (*this); }
2462 // Rust untagged union used for C compat AST node
2463 class Union
: public VisItem
2465 Identifier union_name
;
2467 // bool has_generics;
2468 // Generics generic_params;
2469 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
2471 // bool has_where_clause;
2472 WhereClause where_clause
;
2474 std::vector
<StructField
> variants
;
2479 std::string
as_string () const override
;
2481 // Returns whether union has generic params.
2482 bool has_generics () const { return !generic_params
.empty (); }
2484 // Returns whether union has where clause.
2485 bool has_where_clause () const { return !where_clause
.is_empty (); }
2487 Union (Identifier union_name
, Visibility vis
,
2488 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
2489 WhereClause where_clause
, std::vector
<StructField
> variants
,
2490 std::vector
<Attribute
> outer_attrs
, Location locus
)
2491 : VisItem (std::move (vis
), std::move (outer_attrs
)),
2492 union_name (std::move (union_name
)),
2493 generic_params (std::move (generic_params
)),
2494 where_clause (std::move (where_clause
)), variants (std::move (variants
)),
2498 // copy constructor with vector clone
2499 Union (Union
const &other
)
2500 : VisItem (other
), union_name (other
.union_name
),
2501 where_clause (other
.where_clause
), variants (other
.variants
),
2504 generic_params
.reserve (other
.generic_params
.size ());
2505 for (const auto &e
: other
.generic_params
)
2506 generic_params
.push_back (e
->clone_generic_param ());
2509 // overloaded assignment operator with vector clone
2510 Union
&operator= (Union
const &other
)
2512 VisItem::operator= (other
);
2513 union_name
= other
.union_name
;
2514 where_clause
= other
.where_clause
;
2515 variants
= other
.variants
;
2516 locus
= other
.locus
;
2518 generic_params
.reserve (other
.generic_params
.size ());
2519 for (const auto &e
: other
.generic_params
)
2520 generic_params
.push_back (e
->clone_generic_param ());
2525 // move constructors
2526 Union (Union
&&other
) = default;
2527 Union
&operator= (Union
&&other
) = default;
2529 Location
get_locus () const override final
{ return locus
; }
2531 void accept_vis (ASTVisitor
&vis
) override
;
2533 // Invalid if name is empty, so base stripping on that.
2534 void mark_for_strip () override
{ union_name
= ""; }
2535 bool is_marked_for_strip () const override
{ return union_name
.empty (); }
2537 // TODO: this mutable getter seems really dodgy. Think up better way.
2538 std::vector
<StructField
> &get_variants () { return variants
; }
2539 const std::vector
<StructField
> &get_variants () const { return variants
; }
2541 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
2543 return generic_params
;
2545 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
2547 return generic_params
;
2550 // TODO: is this better? Or is a "vis_block" better?
2551 WhereClause
&get_where_clause () { return where_clause
; }
2553 Identifier
get_identifier () const { return union_name
; }
2556 /* Use covariance to implement clone function as returning this object
2557 * rather than base */
2558 Union
*clone_item_impl () const override
{ return new Union (*this); }
2561 /* "Constant item" AST node - used for constant, compile-time expressions
2562 * within module scope (like constexpr) */
2563 class ConstantItem
: public VisItem
,
2564 public InherentImplItem
,
2565 public TraitImplItem
2567 // either has an identifier or "_" - maybe handle in identifier?
2568 // bool identifier_is_underscore;
2569 // if no identifier declared, identifier will be "_"
2570 std::string identifier
;
2572 std::unique_ptr
<Type
> type
;
2573 std::unique_ptr
<Expr
> const_expr
;
2578 std::string
as_string () const override
;
2580 ConstantItem (std::string ident
, Visibility vis
, std::unique_ptr
<Type
> type
,
2581 std::unique_ptr
<Expr
> const_expr
,
2582 std::vector
<Attribute
> outer_attrs
, Location locus
)
2583 : VisItem (std::move (vis
), std::move (outer_attrs
)),
2584 identifier (std::move (ident
)), type (std::move (type
)),
2585 const_expr (std::move (const_expr
)), locus (locus
)
2588 ConstantItem (ConstantItem
const &other
)
2589 : VisItem (other
), identifier (other
.identifier
), locus (other
.locus
)
2591 // guard to prevent null dereference (only required if error state)
2592 if (other
.type
!= nullptr)
2593 type
= other
.type
->clone_type ();
2594 if (other
.const_expr
!= nullptr)
2595 const_expr
= other
.const_expr
->clone_expr ();
2598 // Overload assignment operator to clone
2599 ConstantItem
&operator= (ConstantItem
const &other
)
2601 VisItem::operator= (other
);
2602 identifier
= other
.identifier
;
2603 locus
= other
.locus
;
2605 // guard to prevent null dereference (only required if error state)
2606 if (other
.type
!= nullptr)
2607 type
= other
.type
->clone_type ();
2610 if (other
.const_expr
!= nullptr)
2611 const_expr
= other
.const_expr
->clone_expr ();
2613 const_expr
= nullptr;
2618 // move constructors
2619 ConstantItem (ConstantItem
&&other
) = default;
2620 ConstantItem
&operator= (ConstantItem
&&other
) = default;
2622 /* Returns whether constant item is an "unnamed" (wildcard underscore used
2623 * as identifier) constant. */
2624 bool is_unnamed () const { return identifier
== "_"; }
2626 Location
get_locus () const override final
{ return locus
; }
2628 void accept_vis (ASTVisitor
&vis
) override
;
2630 // Invalid if type or expression are null, so base stripping on that.
2631 void mark_for_strip () override
2634 const_expr
= nullptr;
2636 bool is_marked_for_strip () const override
2638 return type
== nullptr && const_expr
== nullptr;
2641 // TODO: is this better? Or is a "vis_block" better?
2642 std::unique_ptr
<Expr
> &get_expr ()
2644 rust_assert (const_expr
!= nullptr);
2648 // TODO: is this better? Or is a "vis_block" better?
2649 std::unique_ptr
<Type
> &get_type ()
2651 rust_assert (type
!= nullptr);
2655 std::string
get_identifier () const { return identifier
; }
2658 /* Use covariance to implement clone function as returning this object
2659 * rather than base */
2660 ConstantItem
*clone_item_impl () const override
2662 return new ConstantItem (*this);
2665 /* Use covariance to implement clone function as returning this object
2666 * rather than base */
2667 ConstantItem
*clone_inherent_impl_item_impl () const override
2669 return new ConstantItem (*this);
2672 /* Use covariance to implement clone function as returning this object
2673 * rather than base */
2674 ConstantItem
*clone_trait_impl_item_impl () const override
2676 return new ConstantItem (*this);
2680 /* Static item AST node - items within module scope with fixed storage
2682 class StaticItem
: public VisItem
2686 std::unique_ptr
<Type
> type
;
2687 std::unique_ptr
<Expr
> expr
;
2691 std::string
as_string () const override
;
2693 StaticItem (Identifier name
, bool is_mut
, std::unique_ptr
<Type
> type
,
2694 std::unique_ptr
<Expr
> expr
, Visibility vis
,
2695 std::vector
<Attribute
> outer_attrs
, Location locus
)
2696 : VisItem (std::move (vis
), std::move (outer_attrs
)), has_mut (is_mut
),
2697 name (std::move (name
)), type (std::move (type
)), expr (std::move (expr
)),
2701 // Copy constructor with clone
2702 StaticItem (StaticItem
const &other
)
2703 : VisItem (other
), has_mut (other
.has_mut
), name (other
.name
),
2706 // guard to prevent null dereference (only required if error state)
2707 if (other
.type
!= nullptr)
2708 type
= other
.type
->clone_type ();
2709 if (other
.expr
!= nullptr)
2710 expr
= other
.expr
->clone_expr ();
2713 // Overloaded assignment operator to clone
2714 StaticItem
&operator= (StaticItem
const &other
)
2716 VisItem::operator= (other
);
2718 has_mut
= other
.has_mut
;
2719 locus
= other
.locus
;
2721 // guard to prevent null dereference (only required if error state)
2722 if (other
.type
!= nullptr)
2723 type
= other
.type
->clone_type ();
2726 if (other
.expr
!= nullptr)
2727 expr
= other
.expr
->clone_expr ();
2734 // move constructors
2735 StaticItem (StaticItem
&&other
) = default;
2736 StaticItem
&operator= (StaticItem
&&other
) = default;
2738 Location
get_locus () const override final
{ return locus
; }
2740 void accept_vis (ASTVisitor
&vis
) override
;
2742 // Invalid if type or expression are null, so base stripping on that.
2743 void mark_for_strip () override
2748 bool is_marked_for_strip () const override
2750 return type
== nullptr && expr
== nullptr;
2753 // TODO: is this better? Or is a "vis_block" better?
2754 std::unique_ptr
<Expr
> &get_expr ()
2756 rust_assert (expr
!= nullptr);
2760 // TODO: is this better? Or is a "vis_block" better?
2761 std::unique_ptr
<Type
> &get_type ()
2763 rust_assert (type
!= nullptr);
2767 bool is_mutable () const { return has_mut
; }
2769 Identifier
get_identifier () const { return name
; }
2772 /* Use covariance to implement clone function as returning this object
2773 * rather than base */
2774 StaticItem
*clone_item_impl () const override
2776 return new StaticItem (*this);
2780 // Function declaration in traits
2781 struct TraitFunctionDecl
2784 // TODO: delete and replace with Function decl item? no as no body in this.
2785 FunctionQualifiers qualifiers
;
2786 Identifier function_name
;
2788 // bool has_generics;
2789 // Generics generic_params;
2790 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
2793 // FunctionParams function_params;
2794 std::vector
<FunctionParam
> function_params
; // inlined
2796 // bool has_return_type;
2797 std::unique_ptr
<Type
> return_type
;
2799 // bool has_where_clause;
2800 WhereClause where_clause
;
2802 // should this store location info?
2805 // Returns whether function decl has generic parameters.
2806 bool has_generics () const { return !generic_params
.empty (); }
2808 // Returns whether function decl has regular parameters.
2809 bool has_params () const { return !function_params
.empty (); }
2811 // Returns whether function has return type (otherwise is void).
2812 bool has_return_type () const { return return_type
!= nullptr; }
2814 // Returns whether function has a where clause.
2815 bool has_where_clause () const { return !where_clause
.is_empty (); }
2817 Identifier
get_identifier () const { return function_name
; }
2820 TraitFunctionDecl (Identifier function_name
, FunctionQualifiers qualifiers
,
2821 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
2822 std::vector
<FunctionParam
> function_params
,
2823 std::unique_ptr
<Type
> return_type
,
2824 WhereClause where_clause
)
2825 : qualifiers (std::move (qualifiers
)),
2826 function_name (std::move (function_name
)),
2827 generic_params (std::move (generic_params
)),
2828 function_params (std::move (function_params
)),
2829 return_type (std::move (return_type
)),
2830 where_clause (std::move (where_clause
))
2833 // Copy constructor with clone
2834 TraitFunctionDecl (TraitFunctionDecl
const &other
)
2835 : qualifiers (other
.qualifiers
), function_name (other
.function_name
),
2836 function_params (other
.function_params
), where_clause (other
.where_clause
)
2838 // guard to prevent nullptr dereference
2839 if (other
.return_type
!= nullptr)
2840 return_type
= other
.return_type
->clone_type ();
2842 generic_params
.reserve (other
.generic_params
.size ());
2843 for (const auto &e
: other
.generic_params
)
2844 generic_params
.push_back (e
->clone_generic_param ());
2847 ~TraitFunctionDecl () = default;
2849 // Overloaded assignment operator with clone
2850 TraitFunctionDecl
&operator= (TraitFunctionDecl
const &other
)
2852 function_name
= other
.function_name
;
2853 qualifiers
= other
.qualifiers
;
2854 function_params
= other
.function_params
;
2855 where_clause
= other
.where_clause
;
2857 // guard to prevent nullptr dereference
2858 if (other
.return_type
!= nullptr)
2859 return_type
= other
.return_type
->clone_type ();
2861 return_type
= nullptr;
2863 generic_params
.reserve (other
.generic_params
.size ());
2864 for (const auto &e
: other
.generic_params
)
2865 generic_params
.push_back (e
->clone_generic_param ());
2870 // move constructors
2871 TraitFunctionDecl (TraitFunctionDecl
&&other
) = default;
2872 TraitFunctionDecl
&operator= (TraitFunctionDecl
&&other
) = default;
2874 std::string
as_string () const;
2876 // Invalid if function name is empty, so base stripping on that.
2877 void mark_for_strip () { function_name
= ""; }
2878 bool is_marked_for_strip () const { return function_name
.empty (); }
2880 // TODO: this mutable getter seems really dodgy. Think up better way.
2881 std::vector
<FunctionParam
> &get_function_params () { return function_params
; }
2882 const std::vector
<FunctionParam
> &get_function_params () const
2884 return function_params
;
2887 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
2889 return generic_params
;
2891 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
2893 return generic_params
;
2896 // TODO: is this better? Or is a "vis_block" better?
2897 std::unique_ptr
<Type
> &get_return_type () { return return_type
; }
2899 // TODO: is this better? Or is a "vis_block" better?
2900 WhereClause
&get_where_clause () { return where_clause
; }
2902 FunctionQualifiers
get_qualifiers () { return qualifiers
; }
2905 // Actual trait item function declaration within traits
2906 class TraitItemFunc
: public TraitItem
2908 std::vector
<Attribute
> outer_attrs
;
2909 TraitFunctionDecl decl
;
2910 std::unique_ptr
<BlockExpr
> block_expr
;
2913 // Returns whether function has a definition or is just a declaration.
2914 bool has_definition () const { return block_expr
!= nullptr; }
2916 TraitItemFunc (TraitFunctionDecl decl
, std::unique_ptr
<BlockExpr
> block_expr
,
2917 std::vector
<Attribute
> outer_attrs
, Location locus
)
2918 : TraitItem (locus
), outer_attrs (std::move (outer_attrs
)),
2919 decl (std::move (decl
)), block_expr (std::move (block_expr
))
2922 // Copy constructor with clone
2923 TraitItemFunc (TraitItemFunc
const &other
)
2924 : TraitItem (other
.locus
), outer_attrs (other
.outer_attrs
),
2927 node_id
= other
.node_id
;
2929 // guard to prevent null dereference
2930 if (other
.block_expr
!= nullptr)
2931 block_expr
= other
.block_expr
->clone_block_expr ();
2934 // Overloaded assignment operator to clone
2935 TraitItemFunc
&operator= (TraitItemFunc
const &other
)
2937 TraitItem::operator= (other
);
2938 outer_attrs
= other
.outer_attrs
;
2940 locus
= other
.locus
;
2941 node_id
= other
.node_id
;
2943 // guard to prevent null dereference
2944 if (other
.block_expr
!= nullptr)
2945 block_expr
= other
.block_expr
->clone_block_expr ();
2947 block_expr
= nullptr;
2952 // move constructors
2953 TraitItemFunc (TraitItemFunc
&&other
) = default;
2954 TraitItemFunc
&operator= (TraitItemFunc
&&other
) = default;
2956 std::string
as_string () const override
;
2958 void accept_vis (ASTVisitor
&vis
) override
;
2960 // Invalid if trait decl is empty, so base stripping on that.
2961 void mark_for_strip () override
{ decl
.mark_for_strip (); }
2962 bool is_marked_for_strip () const override
2964 return decl
.is_marked_for_strip ();
2967 // TODO: this mutable getter seems really dodgy. Think up better way.
2968 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
2969 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
2971 // TODO: is this better? Or is a "vis_block" better?
2972 std::unique_ptr
<BlockExpr
> &get_definition () { return block_expr
; }
2974 // TODO: is this better? Or is a "vis_block" better?
2975 TraitFunctionDecl
&get_trait_function_decl ()
2977 // TODO: maybe only allow access if not marked for strip?
2982 // Clone function implementation as (not pure) virtual method
2983 TraitItemFunc
*clone_trait_item_impl () const override
2985 return new TraitItemFunc (*this);
2989 // Method declaration within traits
2990 struct TraitMethodDecl
2993 // TODO: delete and replace with Function decl item? no as no body.
2994 FunctionQualifiers qualifiers
;
2995 Identifier function_name
;
2997 // bool has_generics;
2998 // Generics generic_params;
2999 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
3001 SelfParam self_param
;
3004 // FunctionParams function_params;
3005 std::vector
<FunctionParam
> function_params
; // inlined
3007 // bool has_return_type;
3008 std::unique_ptr
<Type
> return_type
;
3010 // bool has_where_clause;
3011 WhereClause where_clause
;
3013 // should this store location info?
3016 // Returns whether method decl has generic parameters.
3017 bool has_generics () const { return !generic_params
.empty (); }
3019 // Returns whether method decl has regular parameters.
3020 bool has_params () const { return !function_params
.empty (); }
3022 // Returns whether method has return type (otherwise is void).
3023 bool has_return_type () const { return return_type
!= nullptr; }
3025 // Returns whether method has a where clause.
3026 bool has_where_clause () const { return !where_clause
.is_empty (); }
3028 Identifier
get_identifier () const { return function_name
; }
3031 TraitMethodDecl (Identifier function_name
, FunctionQualifiers qualifiers
,
3032 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
3033 SelfParam self_param
,
3034 std::vector
<FunctionParam
> function_params
,
3035 std::unique_ptr
<Type
> return_type
, WhereClause where_clause
)
3036 : qualifiers (std::move (qualifiers
)),
3037 function_name (std::move (function_name
)),
3038 generic_params (std::move (generic_params
)),
3039 self_param (std::move (self_param
)),
3040 function_params (std::move (function_params
)),
3041 return_type (std::move (return_type
)),
3042 where_clause (std::move (where_clause
))
3045 // Copy constructor with clone
3046 TraitMethodDecl (TraitMethodDecl
const &other
)
3047 : qualifiers (other
.qualifiers
), function_name (other
.function_name
),
3048 self_param (other
.self_param
), function_params (other
.function_params
),
3049 where_clause (other
.where_clause
)
3051 // guard to prevent nullptr dereference
3052 if (other
.return_type
!= nullptr)
3053 return_type
= other
.return_type
->clone_type ();
3055 generic_params
.reserve (other
.generic_params
.size ());
3056 for (const auto &e
: other
.generic_params
)
3057 generic_params
.push_back (e
->clone_generic_param ());
3060 ~TraitMethodDecl () = default;
3062 // Overloaded assignment operator with clone
3063 TraitMethodDecl
&operator= (TraitMethodDecl
const &other
)
3065 function_name
= other
.function_name
;
3066 qualifiers
= other
.qualifiers
;
3067 self_param
= other
.self_param
;
3068 function_params
= other
.function_params
;
3069 where_clause
= other
.where_clause
;
3071 // guard to prevent nullptr dereference
3072 if (other
.return_type
!= nullptr)
3073 return_type
= other
.return_type
->clone_type ();
3075 return_type
= nullptr;
3077 generic_params
.reserve (other
.generic_params
.size ());
3078 for (const auto &e
: other
.generic_params
)
3079 generic_params
.push_back (e
->clone_generic_param ());
3084 // move constructors
3085 TraitMethodDecl (TraitMethodDecl
&&other
) = default;
3086 TraitMethodDecl
&operator= (TraitMethodDecl
&&other
) = default;
3088 std::string
as_string () const;
3090 // Invalid if method name is empty, so base stripping on that.
3091 void mark_for_strip () { function_name
= ""; }
3092 bool is_marked_for_strip () const { return function_name
.empty (); }
3094 // TODO: this mutable getter seems really dodgy. Think up better way.
3095 std::vector
<FunctionParam
> &get_function_params () { return function_params
; }
3096 const std::vector
<FunctionParam
> &get_function_params () const
3098 return function_params
;
3101 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
3103 return generic_params
;
3105 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
3107 return generic_params
;
3110 // TODO: is this better? Or is a "vis_block" better?
3111 std::unique_ptr
<Type
> &get_return_type () { return return_type
; }
3113 // TODO: is this better? Or is a "vis_block" better?
3114 WhereClause
&get_where_clause () { return where_clause
; }
3116 SelfParam
&get_self_param () { return self_param
; }
3117 const SelfParam
&get_self_param () const { return self_param
; }
3119 FunctionQualifiers
get_qualifiers () { return qualifiers
; }
3122 // Actual trait item method declaration within traits
3123 class TraitItemMethod
: public TraitItem
3125 std::vector
<Attribute
> outer_attrs
;
3126 TraitMethodDecl decl
;
3127 std::unique_ptr
<BlockExpr
> block_expr
;
3130 // Returns whether method has a definition or is just a declaration.
3131 bool has_definition () const { return block_expr
!= nullptr; }
3133 TraitItemMethod (TraitMethodDecl decl
, std::unique_ptr
<BlockExpr
> block_expr
,
3134 std::vector
<Attribute
> outer_attrs
, Location locus
)
3135 : TraitItem (locus
), outer_attrs (std::move (outer_attrs
)),
3136 decl (std::move (decl
)), block_expr (std::move (block_expr
))
3139 // Copy constructor with clone
3140 TraitItemMethod (TraitItemMethod
const &other
)
3141 : TraitItem (other
.locus
), outer_attrs (other
.outer_attrs
),
3144 node_id
= other
.node_id
;
3146 // guard to prevent null dereference
3147 if (other
.block_expr
!= nullptr)
3148 block_expr
= other
.block_expr
->clone_block_expr ();
3151 // Overloaded assignment operator to clone
3152 TraitItemMethod
&operator= (TraitItemMethod
const &other
)
3154 TraitItem::operator= (other
);
3155 outer_attrs
= other
.outer_attrs
;
3157 locus
= other
.locus
;
3158 node_id
= other
.node_id
;
3160 // guard to prevent null dereference
3161 if (other
.block_expr
!= nullptr)
3162 block_expr
= other
.block_expr
->clone_block_expr ();
3164 block_expr
= nullptr;
3169 // move constructors
3170 TraitItemMethod (TraitItemMethod
&&other
) = default;
3171 TraitItemMethod
&operator= (TraitItemMethod
&&other
) = default;
3173 std::string
as_string () const override
;
3175 void accept_vis (ASTVisitor
&vis
) override
;
3177 // Invalid if trait decl is empty, so base stripping on that.
3178 void mark_for_strip () override
{ decl
.mark_for_strip (); }
3179 bool is_marked_for_strip () const override
3181 return decl
.is_marked_for_strip ();
3184 // TODO: this mutable getter seems really dodgy. Think up better way.
3185 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
3186 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
3188 // TODO: is this better? Or is a "vis_block" better?
3189 TraitMethodDecl
&get_trait_method_decl ()
3191 // TODO: maybe only allow access if not marked for strip?
3195 // TODO: is this better? Or is a "vis_block" better?
3196 std::unique_ptr
<BlockExpr
> &get_definition () { return block_expr
; }
3199 // Clone function implementation as (not pure) virtual method
3200 TraitItemMethod
*clone_trait_item_impl () const override
3202 return new TraitItemMethod (*this);
3206 // Constant item within traits
3207 class TraitItemConst
: public TraitItem
3209 std::vector
<Attribute
> outer_attrs
;
3211 std::unique_ptr
<Type
> type
;
3213 // bool has_expression;
3214 std::unique_ptr
<Expr
> expr
;
3217 // Whether the constant item has an associated expression.
3218 bool has_expression () const { return expr
!= nullptr; }
3220 TraitItemConst (Identifier name
, std::unique_ptr
<Type
> type
,
3221 std::unique_ptr
<Expr
> expr
,
3222 std::vector
<Attribute
> outer_attrs
, Location locus
)
3223 : TraitItem (locus
), outer_attrs (std::move (outer_attrs
)),
3224 name (std::move (name
)), type (std::move (type
)), expr (std::move (expr
))
3227 // Copy constructor with clones
3228 TraitItemConst (TraitItemConst
const &other
)
3229 : TraitItem (other
.locus
), outer_attrs (other
.outer_attrs
),
3232 node_id
= other
.node_id
;
3234 // guard to prevent null dereference
3235 if (other
.expr
!= nullptr)
3236 expr
= other
.expr
->clone_expr ();
3238 // guard to prevent null dereference (only for error state)
3239 if (other
.type
!= nullptr)
3240 type
= other
.type
->clone_type ();
3243 // Overloaded assignment operator to clone
3244 TraitItemConst
&operator= (TraitItemConst
const &other
)
3246 TraitItem::operator= (other
);
3247 outer_attrs
= other
.outer_attrs
;
3249 locus
= other
.locus
;
3250 node_id
= other
.node_id
;
3252 // guard to prevent null dereference
3253 if (other
.expr
!= nullptr)
3254 expr
= other
.expr
->clone_expr ();
3258 // guard to prevent null dereference (only for error state)
3259 if (other
.type
!= nullptr)
3260 type
= other
.type
->clone_type ();
3267 // move constructors
3268 TraitItemConst (TraitItemConst
&&other
) = default;
3269 TraitItemConst
&operator= (TraitItemConst
&&other
) = default;
3271 std::string
as_string () const override
;
3273 Location
get_locus () const { return locus
; }
3275 void accept_vis (ASTVisitor
&vis
) override
;
3277 // Invalid if type is null, so base stripping on that.
3278 void mark_for_strip () override
{ type
= nullptr; }
3279 bool is_marked_for_strip () const override
{ return type
== nullptr; }
3281 // TODO: this mutable getter seems really dodgy. Think up better way.
3282 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
3283 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
3285 bool has_expr () const { return expr
!= nullptr; }
3287 // TODO: is this better? Or is a "vis_block" better?
3288 std::unique_ptr
<Expr
> &get_expr ()
3290 rust_assert (has_expr ());
3294 // TODO: is this better? Or is a "vis_block" better?
3295 std::unique_ptr
<Type
> &get_type ()
3297 rust_assert (type
!= nullptr);
3301 Identifier
get_identifier () const { return name
; }
3304 // Clone function implementation as (not pure) virtual method
3305 TraitItemConst
*clone_trait_item_impl () const override
3307 return new TraitItemConst (*this);
3311 // Type items within traits
3312 class TraitItemType
: public TraitItem
3314 std::vector
<Attribute
> outer_attrs
;
3318 // bool has_type_param_bounds;
3319 // TypeParamBounds type_param_bounds;
3320 std::vector
<std::unique_ptr
<TypeParamBound
>>
3321 type_param_bounds
; // inlined form
3324 // Returns whether trait item type has type param bounds.
3325 bool has_type_param_bounds () const { return !type_param_bounds
.empty (); }
3327 TraitItemType (Identifier name
,
3328 std::vector
<std::unique_ptr
<TypeParamBound
>> type_param_bounds
,
3329 std::vector
<Attribute
> outer_attrs
, Location locus
)
3330 : TraitItem (locus
), outer_attrs (std::move (outer_attrs
)),
3331 name (std::move (name
)), type_param_bounds (std::move (type_param_bounds
))
3334 // Copy constructor with vector clone
3335 TraitItemType (TraitItemType
const &other
)
3336 : TraitItem (other
.locus
), outer_attrs (other
.outer_attrs
),
3339 node_id
= other
.node_id
;
3340 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
3341 for (const auto &e
: other
.type_param_bounds
)
3342 type_param_bounds
.push_back (e
->clone_type_param_bound ());
3345 // Overloaded assignment operator with vector clone
3346 TraitItemType
&operator= (TraitItemType
const &other
)
3348 TraitItem::operator= (other
);
3349 outer_attrs
= other
.outer_attrs
;
3351 locus
= other
.locus
;
3352 node_id
= other
.node_id
;
3354 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
3355 for (const auto &e
: other
.type_param_bounds
)
3356 type_param_bounds
.push_back (e
->clone_type_param_bound ());
3361 // default move constructors
3362 TraitItemType (TraitItemType
&&other
) = default;
3363 TraitItemType
&operator= (TraitItemType
&&other
) = default;
3365 std::string
as_string () const override
;
3367 void accept_vis (ASTVisitor
&vis
) override
;
3369 // Invalid if name is empty, so base stripping on that.
3370 void mark_for_strip () override
{ name
= ""; }
3371 bool is_marked_for_strip () const override
{ return name
.empty (); }
3373 // TODO: this mutable getter seems really dodgy. Think up better way.
3374 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
3375 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
3377 // TODO: mutable getter seems kinda dodgy
3378 std::vector
<std::unique_ptr
<TypeParamBound
>> &get_type_param_bounds ()
3380 return type_param_bounds
;
3382 const std::vector
<std::unique_ptr
<TypeParamBound
>> &
3383 get_type_param_bounds () const
3385 return type_param_bounds
;
3388 Identifier
get_identifier () const { return name
; }
3391 // Clone function implementation as (not pure) virtual method
3392 TraitItemType
*clone_trait_item_impl () const override
3394 return new TraitItemType (*this);
3398 // Rust trait item declaration AST node
3399 class Trait
: public VisItem
3403 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
;
3404 std::vector
<std::unique_ptr
<TypeParamBound
>> type_param_bounds
;
3405 WhereClause where_clause
;
3406 std::vector
<Attribute
> inner_attrs
;
3407 std::vector
<std::unique_ptr
<TraitItem
>> trait_items
;
3411 std::string
as_string () const override
;
3413 // Returns whether trait has generic parameters.
3414 bool has_generics () const { return !generic_params
.empty (); }
3416 // Returns whether trait has type parameter bounds.
3417 bool has_type_param_bounds () const { return !type_param_bounds
.empty (); }
3419 // Returns whether trait has where clause.
3420 bool has_where_clause () const { return !where_clause
.is_empty (); }
3422 // Returns whether trait has trait items.
3423 bool has_trait_items () const { return !trait_items
.empty (); }
3425 // Returns whether trait has inner attributes.
3426 bool has_inner_attrs () const { return !inner_attrs
.empty (); }
3428 Identifier
get_identifier () const { return name
; }
3430 bool is_unsafe () const { return has_unsafe
; }
3433 Trait (Identifier name
, bool is_unsafe
,
3434 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
3435 std::vector
<std::unique_ptr
<TypeParamBound
>> type_param_bounds
,
3436 WhereClause where_clause
,
3437 std::vector
<std::unique_ptr
<TraitItem
>> trait_items
, Visibility vis
,
3438 std::vector
<Attribute
> outer_attrs
, std::vector
<Attribute
> inner_attrs
,
3440 : VisItem (std::move (vis
), std::move (outer_attrs
)),
3441 has_unsafe (is_unsafe
), name (std::move (name
)),
3442 generic_params (std::move (generic_params
)),
3443 type_param_bounds (std::move (type_param_bounds
)),
3444 where_clause (std::move (where_clause
)),
3445 inner_attrs (std::move (inner_attrs
)),
3446 trait_items (std::move (trait_items
)), locus (locus
)
3449 // Copy constructor with vector clone
3450 Trait (Trait
const &other
)
3451 : VisItem (other
), has_unsafe (other
.has_unsafe
), name (other
.name
),
3452 where_clause (other
.where_clause
), inner_attrs (other
.inner_attrs
),
3455 generic_params
.reserve (other
.generic_params
.size ());
3456 for (const auto &e
: other
.generic_params
)
3457 generic_params
.push_back (e
->clone_generic_param ());
3459 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
3460 for (const auto &e
: other
.type_param_bounds
)
3461 type_param_bounds
.push_back (e
->clone_type_param_bound ());
3463 trait_items
.reserve (other
.trait_items
.size ());
3464 for (const auto &e
: other
.trait_items
)
3465 trait_items
.push_back (e
->clone_trait_item ());
3468 // Overloaded assignment operator with vector clone
3469 Trait
&operator= (Trait
const &other
)
3471 VisItem::operator= (other
);
3473 has_unsafe
= other
.has_unsafe
;
3474 where_clause
= other
.where_clause
;
3475 inner_attrs
= other
.inner_attrs
;
3476 locus
= other
.locus
;
3478 generic_params
.reserve (other
.generic_params
.size ());
3479 for (const auto &e
: other
.generic_params
)
3480 generic_params
.push_back (e
->clone_generic_param ());
3482 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
3483 for (const auto &e
: other
.type_param_bounds
)
3484 type_param_bounds
.push_back (e
->clone_type_param_bound ());
3486 trait_items
.reserve (other
.trait_items
.size ());
3487 for (const auto &e
: other
.trait_items
)
3488 trait_items
.push_back (e
->clone_trait_item ());
3493 // default move constructors
3494 Trait (Trait
&&other
) = default;
3495 Trait
&operator= (Trait
&&other
) = default;
3497 Location
get_locus () const override final
{ return locus
; }
3499 void accept_vis (ASTVisitor
&vis
) override
;
3501 // Invalid if trait name is empty, so base stripping on that.
3502 void mark_for_strip () override
{ name
= ""; }
3503 bool is_marked_for_strip () const override
{ return name
.empty (); }
3505 // TODO: think of better way to do this
3506 const std::vector
<Attribute
> &get_inner_attrs () const { return inner_attrs
; }
3507 std::vector
<Attribute
> &get_inner_attrs () { return inner_attrs
; }
3509 const std::vector
<std::unique_ptr
<TraitItem
>> &get_trait_items () const
3513 std::vector
<std::unique_ptr
<TraitItem
>> &get_trait_items ()
3518 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
3520 return generic_params
;
3522 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
3524 return generic_params
;
3527 std::vector
<std::unique_ptr
<TypeParamBound
>> &get_type_param_bounds ()
3529 return type_param_bounds
;
3531 const std::vector
<std::unique_ptr
<TypeParamBound
>> &
3532 get_type_param_bounds () const
3534 return type_param_bounds
;
3537 WhereClause
&get_where_clause () { return where_clause
; }
3539 void insert_implict_self (std::unique_ptr
<AST::GenericParam
> &¶m
)
3541 std::vector
<std::unique_ptr
<GenericParam
>> new_list
;
3542 new_list
.reserve (generic_params
.size () + 1);
3544 new_list
.push_back (std::move (param
));
3545 for (auto &p
: generic_params
)
3547 new_list
.push_back (std::move (p
));
3550 generic_params
= std::move (new_list
);
3554 /* Use covariance to implement clone function as returning this object
3555 * rather than base */
3556 Trait
*clone_item_impl () const override
{ return new Trait (*this); }
3559 // Implementation item declaration AST node - abstract base class
3560 class Impl
: public VisItem
3562 // must be protected to allow subclasses to access them properly
3564 // bool has_generics;
3565 // Generics generic_params;
3566 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
3568 std::unique_ptr
<Type
> trait_type
;
3570 // bool has_where_clause;
3571 WhereClause where_clause
;
3573 // bool has_inner_attrs;
3574 std::vector
<Attribute
> inner_attrs
;
3577 // doesn't really need to be protected as write access probably not needed
3581 // Returns whether impl has generic parameters.
3582 bool has_generics () const { return !generic_params
.empty (); }
3584 // Returns whether impl has where clause.
3585 bool has_where_clause () const { return !where_clause
.is_empty (); }
3587 // Returns whether impl has inner attributes.
3588 bool has_inner_attrs () const { return !inner_attrs
.empty (); }
3590 Location
get_locus () const override final
{ return locus
; }
3592 // Invalid if trait type is null, so base stripping on that.
3593 void mark_for_strip () override
{ trait_type
= nullptr; }
3594 bool is_marked_for_strip () const override
{ return trait_type
== nullptr; }
3596 // TODO: think of better way to do this
3597 const std::vector
<Attribute
> &get_inner_attrs () const { return inner_attrs
; }
3598 std::vector
<Attribute
> &get_inner_attrs () { return inner_attrs
; }
3600 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
3602 return generic_params
;
3604 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
3606 return generic_params
;
3609 // TODO: is this better? Or is a "vis_block" better?
3610 WhereClause
&get_where_clause () { return where_clause
; }
3612 // TODO: is this better? Or is a "vis_block" better?
3613 std::unique_ptr
<Type
> &get_type ()
3615 rust_assert (trait_type
!= nullptr);
3621 Impl (std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
3622 std::unique_ptr
<Type
> trait_type
, WhereClause where_clause
,
3623 Visibility vis
, std::vector
<Attribute
> inner_attrs
,
3624 std::vector
<Attribute
> outer_attrs
, Location locus
)
3625 : VisItem (std::move (vis
), std::move (outer_attrs
)),
3626 generic_params (std::move (generic_params
)),
3627 trait_type (std::move (trait_type
)),
3628 where_clause (std::move (where_clause
)),
3629 inner_attrs (std::move (inner_attrs
)), locus (locus
)
3633 Impl (Impl
const &other
)
3634 : VisItem (other
), where_clause (other
.where_clause
),
3635 inner_attrs (other
.inner_attrs
), locus (other
.locus
)
3637 // guard to prevent null dereference (only required if error state)
3638 if (other
.trait_type
!= nullptr)
3639 trait_type
= other
.trait_type
->clone_type ();
3641 generic_params
.reserve (other
.generic_params
.size ());
3642 for (const auto &e
: other
.generic_params
)
3643 generic_params
.push_back (e
->clone_generic_param ());
3646 // Assignment operator overload with cloning
3647 Impl
&operator= (Impl
const &other
)
3649 VisItem::operator= (other
);
3650 where_clause
= other
.where_clause
;
3651 inner_attrs
= other
.inner_attrs
;
3652 locus
= other
.locus
;
3654 // guard to prevent null dereference (only required if error state)
3655 if (other
.trait_type
!= nullptr)
3656 trait_type
= other
.trait_type
->clone_type ();
3658 trait_type
= nullptr;
3660 generic_params
.reserve (other
.generic_params
.size ());
3661 for (const auto &e
: other
.generic_params
)
3662 generic_params
.push_back (e
->clone_generic_param ());
3667 // move constructors
3668 Impl (Impl
&&other
) = default;
3669 Impl
&operator= (Impl
&&other
) = default;
3672 // Regular "impl foo" impl block declaration AST node
3673 class InherentImpl
: public Impl
3675 // bool has_impl_items;
3676 std::vector
<std::unique_ptr
<InherentImplItem
>> impl_items
;
3679 std::string
as_string () const override
;
3681 // Returns whether inherent impl block has inherent impl items.
3682 bool has_impl_items () const { return !impl_items
.empty (); }
3685 InherentImpl (std::vector
<std::unique_ptr
<InherentImplItem
>> impl_items
,
3686 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
3687 std::unique_ptr
<Type
> trait_type
, WhereClause where_clause
,
3688 Visibility vis
, std::vector
<Attribute
> inner_attrs
,
3689 std::vector
<Attribute
> outer_attrs
, Location locus
)
3690 : Impl (std::move (generic_params
), std::move (trait_type
),
3691 std::move (where_clause
), std::move (vis
), std::move (inner_attrs
),
3692 std::move (outer_attrs
), locus
),
3693 impl_items (std::move (impl_items
))
3696 // Copy constructor with vector clone
3697 InherentImpl (InherentImpl
const &other
) : Impl (other
)
3699 impl_items
.reserve (other
.impl_items
.size ());
3700 for (const auto &e
: other
.impl_items
)
3701 impl_items
.push_back (e
->clone_inherent_impl_item ());
3704 // Overloaded assignment operator with vector clone
3705 InherentImpl
&operator= (InherentImpl
const &other
)
3707 Impl::operator= (other
);
3709 impl_items
.reserve (other
.impl_items
.size ());
3710 for (const auto &e
: other
.impl_items
)
3711 impl_items
.push_back (e
->clone_inherent_impl_item ());
3716 // default move constructors
3717 InherentImpl (InherentImpl
&&other
) = default;
3718 InherentImpl
&operator= (InherentImpl
&&other
) = default;
3720 void accept_vis (ASTVisitor
&vis
) override
;
3722 // TODO: think of better way to do this
3723 const std::vector
<std::unique_ptr
<InherentImplItem
>> &get_impl_items () const
3727 std::vector
<std::unique_ptr
<InherentImplItem
>> &get_impl_items ()
3733 /* Use covariance to implement clone function as returning this object
3734 * rather than base */
3735 InherentImpl
*clone_item_impl () const override
3737 return new InherentImpl (*this);
3741 // The "impl footrait for foo" impl block declaration AST node
3742 class TraitImpl
: public Impl
3746 TypePath trait_path
;
3748 // bool has_impl_items;
3749 std::vector
<std::unique_ptr
<TraitImplItem
>> impl_items
;
3752 std::string
as_string () const override
;
3754 // Returns whether trait impl has impl items.
3755 bool has_impl_items () const { return !impl_items
.empty (); }
3758 TraitImpl (TypePath trait_path
, bool is_unsafe
, bool has_exclam
,
3759 std::vector
<std::unique_ptr
<TraitImplItem
>> impl_items
,
3760 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
3761 std::unique_ptr
<Type
> trait_type
, WhereClause where_clause
,
3762 Visibility vis
, std::vector
<Attribute
> inner_attrs
,
3763 std::vector
<Attribute
> outer_attrs
, Location locus
)
3764 : Impl (std::move (generic_params
), std::move (trait_type
),
3765 std::move (where_clause
), std::move (vis
), std::move (inner_attrs
),
3766 std::move (outer_attrs
), locus
),
3767 has_unsafe (is_unsafe
), has_exclam (has_exclam
),
3768 trait_path (std::move (trait_path
)), impl_items (std::move (impl_items
))
3771 // Copy constructor with vector clone
3772 TraitImpl (TraitImpl
const &other
)
3773 : Impl (other
), has_unsafe (other
.has_unsafe
),
3774 has_exclam (other
.has_exclam
), trait_path (other
.trait_path
)
3776 impl_items
.reserve (other
.impl_items
.size ());
3777 for (const auto &e
: other
.impl_items
)
3778 impl_items
.push_back (e
->clone_trait_impl_item ());
3781 // Overloaded assignment operator with vector clone
3782 TraitImpl
&operator= (TraitImpl
const &other
)
3784 Impl::operator= (other
);
3785 trait_path
= other
.trait_path
;
3786 has_unsafe
= other
.has_unsafe
;
3787 has_exclam
= other
.has_exclam
;
3789 impl_items
.reserve (other
.impl_items
.size ());
3790 for (const auto &e
: other
.impl_items
)
3791 impl_items
.push_back (e
->clone_trait_impl_item ());
3796 // move constructors
3797 TraitImpl (TraitImpl
&&other
) = default;
3798 TraitImpl
&operator= (TraitImpl
&&other
) = default;
3800 void accept_vis (ASTVisitor
&vis
) override
;
3802 bool is_unsafe () const { return has_unsafe
; };
3803 bool is_exclam () const { return has_exclam
; }
3805 // TODO: think of better way to do this
3806 const std::vector
<std::unique_ptr
<TraitImplItem
>> &get_impl_items () const
3810 std::vector
<std::unique_ptr
<TraitImplItem
>> &get_impl_items ()
3815 // TODO: is this better? Or is a "vis_block" better?
3816 TypePath
&get_trait_path ()
3818 // TODO: assert that trait path is not empty?
3823 /* Use covariance to implement clone function as returning this object
3824 * rather than base */
3825 TraitImpl
*clone_item_impl () const override
{ return new TraitImpl (*this); }
3829 // Abstract base class for an item used inside an extern block
3832 // bool has_outer_attrs;
3833 std::vector
<Attribute
> outer_attrs
;
3835 // bool has_visibility;
3836 Visibility visibility
;
3838 Identifier item_name
;
3842 virtual ~ExternalItem () {}
3844 /* TODO: spec syntax rules state that "MacroInvocationSemi" can be used as
3845 * ExternalItem, but text body isn't so clear. Adding MacroInvocationSemi
3846 * support would require a lot of refactoring. */
3848 // Returns whether item has outer attributes.
3849 bool has_outer_attrs () const { return !outer_attrs
.empty (); }
3851 // Returns whether item has non-default visibility.
3852 bool has_visibility () const { return !visibility
.is_error (); }
3854 // Unique pointer custom clone function
3855 std::unique_ptr
<ExternalItem
> clone_external_item () const
3857 return std::unique_ptr
<ExternalItem
> (clone_external_item_impl ());
3860 virtual std::string
as_string () const;
3862 Location
get_locus () const override final
{ return locus
; }
3864 virtual void accept_vis (ASTVisitor
&vis
) = 0;
3866 // TODO: make virtual? Would be more flexible.
3867 // Based on idea that name should never be empty.
3868 void mark_for_strip () { item_name
= ""; };
3869 bool is_marked_for_strip () const { return item_name
.empty (); };
3872 ExternalItem (Identifier item_name
, Visibility vis
,
3873 std::vector
<Attribute
> outer_attrs
, Location locus
)
3874 : outer_attrs (std::move (outer_attrs
)), visibility (std::move (vis
)),
3875 item_name (std::move (item_name
)), locus (locus
)
3879 ExternalItem (ExternalItem
const &other
)
3880 : outer_attrs (other
.outer_attrs
), visibility (other
.visibility
),
3881 item_name (other
.item_name
), locus (other
.locus
)
3884 // Overloaded assignment operator to clone
3885 ExternalItem
&operator= (ExternalItem
const &other
)
3887 item_name
= other
.item_name
;
3888 visibility
= other
.visibility
;
3889 outer_attrs
= other
.outer_attrs
;
3890 locus
= other
.locus
;
3895 // move constructors
3896 ExternalItem (ExternalItem
&&other
) = default;
3897 ExternalItem
&operator= (ExternalItem
&&other
) = default;
3899 // Clone function implementation as pure virtual method
3900 virtual ExternalItem
*clone_external_item_impl () const = 0;
3902 // possibly make this public if required
3903 std::string
get_item_name () const { return item_name
; }
3907 // A static item used in an extern block
3908 class ExternalStaticItem
: public ExternalItem
3910 // bool has_outer_attrs;
3911 std::vector
<Attribute
> outer_attrs
;
3913 // bool has_visibility;
3914 Visibility visibility
;
3916 Identifier item_name
;
3920 std::unique_ptr
<Type
> item_type
;
3923 ExternalStaticItem (Identifier item_name
, std::unique_ptr
<Type
> item_type
,
3924 bool is_mut
, Visibility vis
,
3925 std::vector
<Attribute
> outer_attrs
, Location locus
)
3926 : ExternalItem (), outer_attrs (std::move (outer_attrs
)),
3927 visibility (std::move (vis
)), item_name (std::move (item_name
)),
3928 locus (locus
), has_mut (is_mut
), item_type (std::move (item_type
))
3932 ExternalStaticItem (ExternalStaticItem
const &other
)
3933 : outer_attrs (other
.outer_attrs
), visibility (other
.visibility
),
3934 item_name (other
.item_name
), locus (other
.locus
), has_mut (other
.has_mut
)
3936 node_id
= other
.node_id
;
3937 // guard to prevent null dereference (only required if error state)
3938 if (other
.item_type
!= nullptr)
3939 item_type
= other
.item_type
->clone_type ();
3942 // Overloaded assignment operator to clone
3943 ExternalStaticItem
&operator= (ExternalStaticItem
const &other
)
3945 node_id
= other
.node_id
;
3946 outer_attrs
= other
.outer_attrs
;
3947 visibility
= other
.visibility
;
3948 item_name
= other
.item_name
;
3949 locus
= other
.locus
;
3950 has_mut
= other
.has_mut
;
3952 // guard to prevent null dereference (only required if error state)
3953 if (other
.item_type
!= nullptr)
3954 item_type
= other
.item_type
->clone_type ();
3956 item_type
= nullptr;
3961 // move constructors
3962 ExternalStaticItem (ExternalStaticItem
&&other
) = default;
3963 ExternalStaticItem
&operator= (ExternalStaticItem
&&other
) = default;
3965 std::string
as_string () const override
;
3967 void accept_vis (ASTVisitor
&vis
) override
;
3969 // Returns whether item has outer attributes.
3970 bool has_outer_attrs () const { return !outer_attrs
.empty (); }
3972 // Returns whether item has non-default visibility.
3973 bool has_visibility () const { return !visibility
.is_error (); }
3975 Location
get_locus () const { return locus
; }
3977 // Based on idea that type should never be null.
3978 void mark_for_strip () override
{ item_type
= nullptr; };
3979 bool is_marked_for_strip () const override
{ return item_type
== nullptr; };
3981 // TODO: this mutable getter seems really dodgy. Think up better way.
3982 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
3983 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
3985 // TODO: is this better? Or is a "vis_block" better?
3986 std::unique_ptr
<Type
> &get_type ()
3988 rust_assert (item_type
!= nullptr);
3992 Identifier
get_identifier () const { return item_name
; }
3994 const Visibility
&get_visibility () const { return visibility
; }
3996 bool is_mut () const { return has_mut
; }
3999 /* Use covariance to implement clone function as returning this object
4000 * rather than base */
4001 ExternalStaticItem
*clone_external_item_impl () const override
4003 return new ExternalStaticItem (*this);
4007 // A named function parameter used in external functions
4008 struct NamedFunctionParam
4011 // bool has_name; // otherwise is _
4014 std::unique_ptr
<Type
> param_type
;
4016 // seemingly new since writing this node
4017 std::vector
<Attribute
> outer_attrs
;
4023 /* Returns whether the named function parameter has a name (i.e. name is not
4025 bool has_name () const { return name
!= "_"; }
4027 bool has_outer_attrs () const { return !outer_attrs
.empty (); }
4029 // Returns whether the named function parameter is in an error state.
4030 bool is_error () const
4032 // also if identifier is "" but that is probably more costly to compute
4033 return param_type
== nullptr;
4036 std::string
get_name () const { return name
; }
4038 // Creates an error state named function parameter.
4039 static NamedFunctionParam
create_error ()
4041 return NamedFunctionParam ("", nullptr, {}, Location ());
4044 NamedFunctionParam (std::string name
, std::unique_ptr
<Type
> param_type
,
4045 std::vector
<Attribute
> outer_attrs
, Location locus
)
4046 : name (std::move (name
)), param_type (std::move (param_type
)),
4047 outer_attrs (std::move (outer_attrs
)),
4048 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus
)
4052 NamedFunctionParam (NamedFunctionParam
const &other
)
4053 : name (other
.name
), outer_attrs (other
.outer_attrs
)
4055 node_id
= other
.node_id
;
4056 // guard to prevent null dereference (only required if error state)
4057 if (other
.param_type
!= nullptr)
4058 param_type
= other
.param_type
->clone_type ();
4061 ~NamedFunctionParam () = default;
4063 // Overloaded assignment operator to clone
4064 NamedFunctionParam
&operator= (NamedFunctionParam
const &other
)
4066 node_id
= other
.node_id
;
4068 // has_name = other.has_name;
4069 outer_attrs
= other
.outer_attrs
;
4071 // guard to prevent null dereference (only required if error state)
4072 if (other
.param_type
!= nullptr)
4073 param_type
= other
.param_type
->clone_type ();
4075 param_type
= nullptr;
4080 // move constructors
4081 NamedFunctionParam (NamedFunctionParam
&&other
) = default;
4082 NamedFunctionParam
&operator= (NamedFunctionParam
&&other
) = default;
4084 std::string
as_string () const;
4086 // Based on idea that nane should never be empty.
4087 void mark_for_strip () { param_type
= nullptr; };
4088 bool is_marked_for_strip () const { return is_error (); };
4090 // TODO: this mutable getter seems really dodgy. Think up better way.
4091 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
4092 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
4094 // TODO: is this better? Or is a "vis_block" better?
4095 std::unique_ptr
<Type
> &get_type ()
4097 rust_assert (param_type
!= nullptr);
4101 NodeId
get_node_id () const { return node_id
; }
4104 // A function item used in an extern block
4105 class ExternalFunctionItem
: public ExternalItem
4107 // bool has_outer_attrs;
4108 std::vector
<Attribute
> outer_attrs
;
4110 // bool has_visibility;
4111 Visibility visibility
;
4113 Identifier item_name
;
4116 // bool has_generics;
4117 // Generics generic_params;
4118 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
; // inlined
4120 // bool has_return_type;
4121 // FunctionReturnType return_type;
4122 std::unique_ptr
<Type
> return_type
; // inlined
4124 // bool has_where_clause;
4125 WhereClause where_clause
;
4127 std::vector
<NamedFunctionParam
> function_params
;
4129 std::vector
<Attribute
> variadic_outer_attrs
;
4132 // Returns whether item has generic parameters.
4133 bool has_generics () const { return !generic_params
.empty (); }
4135 // Returns whether item has a return type (otherwise void).
4136 bool has_return_type () const { return return_type
!= nullptr; }
4138 // Returns whether item has a where clause.
4139 bool has_where_clause () const { return !where_clause
.is_empty (); }
4141 // Returns whether item has outer attributes.
4142 bool has_outer_attrs () const { return !outer_attrs
.empty (); }
4144 // Returns whether item has non-default visibility.
4145 bool has_visibility () const { return !visibility
.is_error (); }
4147 // Returns whether item has variadic parameters.
4148 bool is_variadic () const { return has_variadics
; }
4150 // Returns whether item has outer attributes on its variadic parameters.
4151 bool has_variadic_outer_attrs () const
4153 return !variadic_outer_attrs
.empty ();
4156 Location
get_locus () const { return locus
; }
4158 Visibility
&get_visibility () { return visibility
; }
4159 const Visibility
&get_visibility () const { return visibility
; }
4161 ExternalFunctionItem (
4162 Identifier item_name
,
4163 std::vector
<std::unique_ptr
<GenericParam
>> generic_params
,
4164 std::unique_ptr
<Type
> return_type
, WhereClause where_clause
,
4165 std::vector
<NamedFunctionParam
> function_params
, bool has_variadics
,
4166 std::vector
<Attribute
> variadic_outer_attrs
, Visibility vis
,
4167 std::vector
<Attribute
> outer_attrs
, Location locus
)
4168 : ExternalItem (), outer_attrs (std::move (outer_attrs
)),
4169 visibility (std::move (vis
)), item_name (std::move (item_name
)),
4170 locus (locus
), generic_params (std::move (generic_params
)),
4171 return_type (std::move (return_type
)),
4172 where_clause (std::move (where_clause
)),
4173 function_params (std::move (function_params
)),
4174 has_variadics (has_variadics
),
4175 variadic_outer_attrs (std::move (variadic_outer_attrs
))
4177 // TODO: assert that if has variadic outer attrs, then has_variadics is
4181 // Copy constructor with clone
4182 ExternalFunctionItem (ExternalFunctionItem
const &other
)
4183 : outer_attrs (other
.outer_attrs
), visibility (other
.visibility
),
4184 item_name (other
.item_name
), locus (other
.locus
),
4185 where_clause (other
.where_clause
),
4186 function_params (other
.function_params
),
4187 has_variadics (other
.has_variadics
),
4188 variadic_outer_attrs (other
.variadic_outer_attrs
)
4190 node_id
= other
.node_id
;
4191 // guard to prevent null pointer dereference
4192 if (other
.return_type
!= nullptr)
4193 return_type
= other
.return_type
->clone_type ();
4195 generic_params
.reserve (other
.generic_params
.size ());
4196 for (const auto &e
: other
.generic_params
)
4197 generic_params
.push_back (e
->clone_generic_param ());
4200 // Overloaded assignment operator with clone
4201 ExternalFunctionItem
&operator= (ExternalFunctionItem
const &other
)
4203 outer_attrs
= other
.outer_attrs
;
4204 visibility
= other
.visibility
;
4205 item_name
= other
.item_name
;
4206 locus
= other
.locus
;
4207 where_clause
= other
.where_clause
;
4208 function_params
= other
.function_params
;
4209 has_variadics
= other
.has_variadics
;
4210 variadic_outer_attrs
= other
.variadic_outer_attrs
;
4211 node_id
= other
.node_id
;
4213 // guard to prevent null pointer dereference
4214 if (other
.return_type
!= nullptr)
4215 return_type
= other
.return_type
->clone_type ();
4217 return_type
= nullptr;
4219 generic_params
.reserve (other
.generic_params
.size ());
4220 for (const auto &e
: other
.generic_params
)
4221 generic_params
.push_back (e
->clone_generic_param ());
4226 // move constructors
4227 ExternalFunctionItem (ExternalFunctionItem
&&other
) = default;
4228 ExternalFunctionItem
&operator= (ExternalFunctionItem
&&other
) = default;
4230 std::string
as_string () const override
;
4232 void accept_vis (ASTVisitor
&vis
) override
;
4234 // Based on idea that nane should never be empty.
4235 void mark_for_strip () override
{ item_name
= ""; };
4236 bool is_marked_for_strip () const override
{ return item_name
.empty (); };
4238 // TODO: this mutable getter seems really dodgy. Think up better way.
4239 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
4240 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
4242 std::vector
<NamedFunctionParam
> &get_function_params ()
4244 return function_params
;
4246 const std::vector
<NamedFunctionParam
> &get_function_params () const
4248 return function_params
;
4251 std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params ()
4253 return generic_params
;
4255 const std::vector
<std::unique_ptr
<GenericParam
>> &get_generic_params () const
4257 return generic_params
;
4260 // TODO: is this better? Or is a "vis_block" better?
4261 WhereClause
&get_where_clause () { return where_clause
; }
4263 // TODO: is this better? Or is a "vis_block" better?
4264 std::unique_ptr
<Type
> &get_return_type ()
4266 rust_assert (has_return_type ());
4270 Identifier
get_identifier () const { return item_name
; };
4273 /* Use covariance to implement clone function as returning this object
4274 * rather than base */
4275 ExternalFunctionItem
*clone_external_item_impl () const override
4277 return new ExternalFunctionItem (*this);
4281 // An extern block AST node
4282 class ExternBlock
: public VisItem
4287 // bool has_inner_attrs;
4288 std::vector
<Attribute
> inner_attrs
;
4290 // bool has_extern_items;
4291 std::vector
<std::unique_ptr
<ExternalItem
>> extern_items
;
4295 // TODO: find another way to store this to save memory?
4296 bool marked_for_strip
= false;
4299 std::string
as_string () const override
;
4301 // Returns whether extern block has inner attributes.
4302 bool has_inner_attrs () const { return !inner_attrs
.empty (); }
4304 // Returns whether extern block has extern items.
4305 bool has_extern_items () const { return !extern_items
.empty (); }
4307 // Returns whether extern block has ABI name.
4308 bool has_abi () const { return !abi
.empty (); }
4310 std::string
get_abi () const { return abi
; }
4312 ExternBlock (std::string abi
,
4313 std::vector
<std::unique_ptr
<ExternalItem
>> extern_items
,
4314 Visibility vis
, std::vector
<Attribute
> inner_attrs
,
4315 std::vector
<Attribute
> outer_attrs
, Location locus
)
4316 : VisItem (std::move (vis
), std::move (outer_attrs
)), abi (std::move (abi
)),
4317 inner_attrs (std::move (inner_attrs
)),
4318 extern_items (std::move (extern_items
)), locus (locus
)
4321 // Copy constructor with vector clone
4322 ExternBlock (ExternBlock
const &other
)
4323 : VisItem (other
), abi (other
.abi
), inner_attrs (other
.inner_attrs
),
4324 locus (other
.locus
), marked_for_strip (other
.marked_for_strip
)
4326 extern_items
.reserve (other
.extern_items
.size ());
4327 for (const auto &e
: other
.extern_items
)
4328 extern_items
.push_back (e
->clone_external_item ());
4331 // Overloaded assignment operator with vector clone
4332 ExternBlock
&operator= (ExternBlock
const &other
)
4334 VisItem::operator= (other
);
4336 inner_attrs
= other
.inner_attrs
;
4337 locus
= other
.locus
;
4338 marked_for_strip
= other
.marked_for_strip
;
4340 extern_items
.reserve (other
.extern_items
.size ());
4341 for (const auto &e
: other
.extern_items
)
4342 extern_items
.push_back (e
->clone_external_item ());
4347 // move constructors
4348 ExternBlock (ExternBlock
&&other
) = default;
4349 ExternBlock
&operator= (ExternBlock
&&other
) = default;
4351 Location
get_locus () const override final
{ return locus
; }
4353 void accept_vis (ASTVisitor
&vis
) override
;
4355 // Can't think of any invalid invariants, so store boolean.
4356 void mark_for_strip () override
{ marked_for_strip
= true; }
4357 bool is_marked_for_strip () const override
{ return marked_for_strip
; }
4359 // TODO: think of better way to do this
4360 const std::vector
<std::unique_ptr
<ExternalItem
>> &get_extern_items () const
4362 return extern_items
;
4364 std::vector
<std::unique_ptr
<ExternalItem
>> &get_extern_items ()
4366 return extern_items
;
4369 // TODO: think of better way to do this
4370 const std::vector
<Attribute
> &get_inner_attrs () const { return inner_attrs
; }
4371 std::vector
<Attribute
> &get_inner_attrs () { return inner_attrs
; }
4374 /* Use covariance to implement clone function as returning this object
4375 * rather than base */
4376 ExternBlock
*clone_item_impl () const override
4378 return new ExternBlock (*this);
4382 class MacroRulesDefinition
;