Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / rust / ast / rust-item.h
blob3e66b19724ead471c92e11190df03a733a9c866a
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
8 // version.
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #ifndef RUST_AST_ITEM_H
20 #define RUST_AST_ITEM_H
22 #include "rust-ast.h"
23 #include "rust-path.h"
24 #include "rust-common.h"
25 #include "rust-expr.h"
27 namespace Rust {
28 namespace AST {
29 // forward decls
30 class TypePath;
32 // TODO: inline?
33 /*struct AbiName {
34 std::string abi_name;
35 // Technically is meant to be STRING_LITERAL
37 public:
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
46 AbiName() {}
47 };*/
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;
54 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
63 // bool has_type;
64 std::unique_ptr<Type> type;
66 Location locus;
68 public:
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;
111 locus = other.locus;
112 node_id = other.node_id;
114 // guard to prevent null pointer dereference
115 if (other.type != nullptr)
116 type = other.type->clone_type ();
117 else
118 type = nullptr;
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 ());
124 return *this;
127 // move constructors
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);
143 return type;
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;
157 protected:
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
169 public:
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;
184 protected:
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
192 Lifetime lifetime;
193 std::vector<Lifetime> lifetime_bounds;
194 Location locus;
195 NodeId node_id;
197 public:
198 LifetimeWhereClauseItem (Lifetime lifetime,
199 std::vector<Lifetime> lifetime_bounds,
200 Location locus)
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; }
218 protected:
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;
232 NodeId node_id;
233 Location locus;
235 public:
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,
247 Location locus)
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 ());
275 return *this;
278 // move constructors
279 TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default;
280 TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem &&other)
281 = default;
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);
290 return bound_type;
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; }
309 protected:
310 // Clone function implementation as (not pure) virtual method
311 TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
313 return new TypeBoundWhereClauseItem (*this);
317 // A where clause
318 struct WhereClause
320 private:
321 std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items;
322 NodeId node_id;
324 public:
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 ());
347 return *this;
350 // move constructors
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
379 struct SelfParam
381 private:
382 bool has_ref;
383 bool is_mut;
384 // bool has_lifetime; // only possible if also ref
385 Lifetime lifetime;
387 // bool has_type; // only possible if not ref
388 std::unique_ptr<Type> type;
390 NodeId node_id;
392 Location locus;
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
403 public:
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 ()),
441 locus (other.locus)
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;
454 locus = other.locus;
455 node_id = other.node_id;
457 if (other.type != nullptr)
458 type = other.type->clone_type ();
459 else
460 type = nullptr;
462 return *this;
465 // move constructors
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 ());
484 return type;
488 // Qualifiers for function, i.e. const, unsafe, extern etc.
489 struct FunctionQualifiers
491 private:
492 AsyncConstStatus const_status;
493 bool has_unsafe;
494 bool has_extern;
495 std::string extern_abi;
496 Location locus;
498 public:
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)),
504 locus (locus)
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
525 struct FunctionParam
527 private:
528 std::vector<Attribute> outer_attrs;
529 Location locus;
530 std::unique_ptr<Pattern> param_name;
531 std::unique_ptr<Type> type;
533 public:
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)
556 locus = other.locus;
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 ();
562 else
563 param_name = nullptr;
564 if (other.type != nullptr)
565 type = other.type->clone_type ();
566 else
567 type = nullptr;
569 return *this;
572 // move constructors
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);
597 return param_name;
600 // TODO: is this better? Or is a "vis_block" better?
601 std::unique_ptr<Type> &get_type ()
603 rust_assert (type != nullptr);
604 return type;
606 NodeId get_node_id () const { return node_id; }
608 protected:
609 NodeId node_id;
612 // Visibility of item - if the item has it, then it is some form of public
613 struct Visibility
615 public:
616 enum VisType
618 PRIV,
619 PUB,
620 PUB_CRATE,
621 PUB_SELF,
622 PUB_SUPER,
623 PUB_IN_PATH
626 private:
627 VisType vis_type;
628 // Only assigned if vis_type is IN_PATH
629 SimplePath in_path;
630 Location locus;
632 // should this store location info?
634 public:
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; }
656 // empty?
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.
672 // empty?
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),
684 crate_vis_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),
693 self_vis_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),
702 super_vis_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; }
722 protected:
723 // Clone function implementation - not currently virtual but may be if
724 // polymorphism used
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;
735 Visibility vis;
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;
744 Location locus;
745 NodeId node_id;
747 public:
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;
828 vis = other.vis;
829 qualifiers = other.qualifiers;
830 self_param = other.self_param;
831 function_params = other.function_params;
832 where_clause = other.where_clause;
833 locus = other.locus;
835 // guard to prevent null dereference (always required)
836 if (other.return_type != nullptr)
837 return_type = other.return_type->clone_type ();
838 else
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 ();
844 else
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;
853 return *this;
856 // move constructors
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 ());
904 return 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; }
921 protected:
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;
945 protected:
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;
963 return *this;
966 // move constructors
967 VisItem (VisItem &&other) = default;
968 VisItem &operator= (VisItem &&other) = default;
970 public:
971 /* Does the item have some kind of public visibility (non-default
972 * visibility)? */
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
988 public:
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.
994 enum ModuleKind
996 LOADED,
997 UNLOADED,
1000 Identifier get_name () const { return module_name; }
1002 private:
1003 Identifier module_name;
1004 Location locus;
1005 ModuleKind kind;
1007 // Name of the file including the module
1008 std::string outer_filename;
1009 // bool has_inner_attrs;
1010 std::vector<Attribute> inner_attrs;
1011 // bool has_items;
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 ());
1027 public:
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);
1067 else
1068 items.clear ();
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;
1078 kind = other.kind;
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
1083 // unloaded
1084 if (kind == LOADED)
1085 clone_items (other.items);
1086 else
1087 items.clear ();
1089 return *this;
1092 // Search for the filename associated with an external module, storing it in
1093 // module_file
1094 void process_file_path ();
1095 // Load the items contained in an external module
1096 void load_items ();
1098 void accept_vis (ASTVisitor &vis) override;
1100 /* Override that runs the function recursively on all items contained within
1101 * the module. */
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 (); }
1126 protected:
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;
1142 Location locus;
1144 /* e.g.
1145 "extern crate foo as _"
1146 "extern crate foo"
1147 "extern crate std as cool_std" */
1148 public:
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
1155 * (i.e. self). */
1156 bool references_self () const { return referenced_crate == "self"; }
1158 // Constructor
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 ();
1187 protected:
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
1197 class UseTree
1199 Location locus;
1201 public:
1202 enum Kind
1204 Glob,
1205 Rebind,
1206 List,
1209 virtual ~UseTree () {}
1211 // Overload assignment operator to clone
1212 UseTree &operator= (UseTree const &other)
1214 locus = other.locus;
1216 return *this;
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;
1238 protected:
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
1248 public:
1249 enum PathType
1251 NO_PATH,
1252 GLOBAL,
1253 PATH_PREFIXED
1256 private:
1257 PathType glob_type;
1258 SimplePath path;
1260 public:
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
1275 * PATH_PREFIXED. */
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 ());
1287 return path;
1290 /* TODO: find way to ensure only PATH_PREFIXED glob_type has path - factory
1291 * methods? */
1292 protected:
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
1304 public:
1305 enum PathType
1307 NO_PATH,
1308 GLOBAL,
1309 PATH_PREFIXED
1312 private:
1313 PathType path_type;
1314 SimplePath path;
1316 std::vector<std::unique_ptr<UseTree>> trees;
1318 public:
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;
1348 path = other.path;
1350 trees.reserve (other.trees.size ());
1351 for (const auto &e : other.trees)
1352 trees.push_back (e->clone_use_tree ());
1354 return *this;
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 ());
1375 return path;
1378 const std::vector<std::unique_ptr<UseTree>> &get_trees () const
1380 return trees;
1383 // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
1384 // methods?
1385 protected:
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
1397 public:
1398 enum NewBindType
1400 NONE,
1401 IDENTIFIER,
1402 WILDCARD
1405 private:
1406 SimplePath path;
1408 NewBindType bind_type;
1409 Identifier identifier; // only if NewBindType is IDENTIFIER
1411 public:
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 ());
1433 return path;
1436 const Identifier &get_identifier () const
1438 rust_assert (has_identifier ());
1439 return identifier;
1442 // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
1443 // methods?
1444 protected:
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;
1457 Location locus;
1459 public:
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 ();
1488 else
1489 use_tree = nullptr;
1491 return *this;
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; }
1507 protected:
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);
1516 class LetStmt;
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;
1528 Location locus;
1530 public:
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 ();
1599 else
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 ();
1605 else
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 ());
1612 return *this;
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 ());
1663 return return_type;
1666 protected:
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;
1700 Location locus;
1702 public:
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)
1723 // Copy constructor
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 ();
1750 else
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 ());
1757 return *this;
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; }
1796 protected:
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
1812 protected:
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;
1823 private:
1824 Location locus;
1826 public:
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; }
1855 protected:
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 ());
1888 return *this;
1891 // move constructors
1892 Struct (Struct &&other) = default;
1893 Struct &operator= (Struct &&other) = default;
1896 // A single field in a struct
1897 struct StructField
1899 private:
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;
1909 NodeId node_id;
1911 Location locus;
1913 public:
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)
1928 // Copy constructor
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),
1932 locus (other.locus)
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 ();
1952 else
1953 field_type = nullptr;
1955 return *this;
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 (),
1973 Location ());
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);
1990 return field_type;
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;
2003 bool is_unit;
2005 public:
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)),
2027 is_unit (true)
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; }
2041 protected:
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
2051 struct TupleField
2053 private:
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;
2062 NodeId node_id;
2064 Location locus;
2066 public:
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
2071 * one) */
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 ();
2105 else
2106 field_type = nullptr;
2108 return *this;
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);
2141 return field_type;
2145 // Rust tuple declared using struct keyword AST node
2146 class TupleStruct : public Struct
2148 std::vector<TupleField> fields;
2150 public:
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; }
2170 protected:
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
2181 * annotation. */
2182 class EnumItem : public VisItem
2184 Identifier variant_name;
2186 Location locus;
2188 public:
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 (); }
2216 protected:
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;
2226 public:
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;
2249 protected:
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;
2263 public:
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;
2286 protected:
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;
2299 public:
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;
2321 return *this;
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);
2336 return expression;
2339 protected:
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;
2361 Location locus;
2363 public:
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 (); }
2376 // Mega-constructor
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)),
2385 locus (locus)
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 ());
2420 return *this;
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
2441 return items;
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; }
2456 protected:
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;
2476 Location locus;
2478 public:
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)),
2495 locus (locus)
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),
2502 locus (other.locus)
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 ());
2522 return *this;
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; }
2555 protected:
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;
2575 Location locus;
2577 public:
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 ();
2608 else
2609 type = nullptr;
2610 if (other.const_expr != nullptr)
2611 const_expr = other.const_expr->clone_expr ();
2612 else
2613 const_expr = nullptr;
2615 return *this;
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
2633 type = nullptr;
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);
2645 return const_expr;
2648 // TODO: is this better? Or is a "vis_block" better?
2649 std::unique_ptr<Type> &get_type ()
2651 rust_assert (type != nullptr);
2652 return type;
2655 std::string get_identifier () const { return identifier; }
2657 protected:
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
2681 * duration? */
2682 class StaticItem : public VisItem
2684 bool has_mut;
2685 Identifier name;
2686 std::unique_ptr<Type> type;
2687 std::unique_ptr<Expr> expr;
2688 Location locus;
2690 public:
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)),
2698 locus (locus)
2701 // Copy constructor with clone
2702 StaticItem (StaticItem const &other)
2703 : VisItem (other), has_mut (other.has_mut), name (other.name),
2704 locus (other.locus)
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);
2717 name = other.name;
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 ();
2724 else
2725 type = nullptr;
2726 if (other.expr != nullptr)
2727 expr = other.expr->clone_expr ();
2728 else
2729 expr = nullptr;
2731 return *this;
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
2745 type = nullptr;
2746 expr = nullptr;
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);
2757 return expr;
2760 // TODO: is this better? Or is a "vis_block" better?
2761 std::unique_ptr<Type> &get_type ()
2763 rust_assert (type != nullptr);
2764 return type;
2767 bool is_mutable () const { return has_mut; }
2769 Identifier get_identifier () const { return name; }
2771 protected:
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
2783 private:
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
2792 // bool has_params;
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?
2804 public:
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; }
2819 // Mega-constructor
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 ();
2860 else
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 ());
2867 return *this;
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;
2912 public:
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),
2925 decl (other.decl)
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;
2939 decl = other.decl;
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 ();
2946 else
2947 block_expr = nullptr;
2949 return *this;
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?
2978 return decl;
2981 protected:
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
2992 private:
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;
3003 // bool has_params;
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?
3015 public:
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; }
3030 // Mega-constructor
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 ();
3074 else
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 ());
3081 return *this;
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;
3129 public:
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),
3142 decl (other.decl)
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;
3156 decl = other.decl;
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 ();
3163 else
3164 block_expr = nullptr;
3166 return *this;
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?
3192 return decl;
3195 // TODO: is this better? Or is a "vis_block" better?
3196 std::unique_ptr<BlockExpr> &get_definition () { return block_expr; }
3198 protected:
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;
3210 Identifier name;
3211 std::unique_ptr<Type> type;
3213 // bool has_expression;
3214 std::unique_ptr<Expr> expr;
3216 public:
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),
3230 name (other.name)
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;
3248 name = other.name;
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 ();
3255 else
3256 expr = nullptr;
3258 // guard to prevent null dereference (only for error state)
3259 if (other.type != nullptr)
3260 type = other.type->clone_type ();
3261 else
3262 type = nullptr;
3264 return *this;
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 ());
3291 return expr;
3294 // TODO: is this better? Or is a "vis_block" better?
3295 std::unique_ptr<Type> &get_type ()
3297 rust_assert (type != nullptr);
3298 return type;
3301 Identifier get_identifier () const { return name; }
3303 protected:
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;
3316 Identifier name;
3318 // bool has_type_param_bounds;
3319 // TypeParamBounds type_param_bounds;
3320 std::vector<std::unique_ptr<TypeParamBound>>
3321 type_param_bounds; // inlined form
3323 public:
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),
3337 name (other.name)
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;
3350 name = other.name;
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 ());
3358 return *this;
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; }
3390 protected:
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
3401 bool has_unsafe;
3402 Identifier name;
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;
3408 Location locus;
3410 public:
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; }
3432 // Mega-constructor
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,
3439 Location locus)
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),
3453 locus (other.locus)
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);
3472 name = other.name;
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 ());
3490 return *this;
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
3511 return trait_items;
3513 std::vector<std::unique_ptr<TraitItem>> &get_trait_items ()
3515 return 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> &&param)
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);
3553 protected:
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
3563 protected:
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;
3576 private:
3577 // doesn't really need to be protected as write access probably not needed
3578 Location locus;
3580 public:
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);
3616 return trait_type;
3619 protected:
3620 // Mega-constructor
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)
3632 // Copy constructor
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 ();
3657 else
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 ());
3664 return *this;
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;
3678 public:
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 (); }
3684 // Mega-constructor
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 ());
3713 return *this;
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
3725 return impl_items;
3727 std::vector<std::unique_ptr<InherentImplItem>> &get_impl_items ()
3729 return impl_items;
3732 protected:
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
3744 bool has_unsafe;
3745 bool has_exclam;
3746 TypePath trait_path;
3748 // bool has_impl_items;
3749 std::vector<std::unique_ptr<TraitImplItem>> impl_items;
3751 public:
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 (); }
3757 // Mega-constructor
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 ());
3793 return *this;
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
3808 return impl_items;
3810 std::vector<std::unique_ptr<TraitImplItem>> &get_impl_items ()
3812 return 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?
3819 return trait_path;
3822 protected:
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); }
3828 #if 0
3829 // Abstract base class for an item used inside an extern block
3830 class ExternalItem
3832 // bool has_outer_attrs;
3833 std::vector<Attribute> outer_attrs;
3835 // bool has_visibility;
3836 Visibility visibility;
3838 Identifier item_name;
3839 Location locus;
3841 public:
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 (); };
3871 protected:
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)
3878 // Copy constructor
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;
3892 return *this;
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; }
3905 #endif
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;
3917 Location locus;
3919 bool has_mut;
3920 std::unique_ptr<Type> item_type;
3922 public:
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))
3931 // Copy constructor
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 ();
3955 else
3956 item_type = nullptr;
3958 return *this;
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);
3989 return item_type;
3992 Identifier get_identifier () const { return item_name; }
3994 const Visibility &get_visibility () const { return visibility; }
3996 bool is_mut () const { return has_mut; }
3998 protected:
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
4010 private:
4011 // bool has_name; // otherwise is _
4012 std::string name;
4014 std::unique_ptr<Type> param_type;
4016 // seemingly new since writing this node
4017 std::vector<Attribute> outer_attrs;
4019 NodeId node_id;
4020 Location locus;
4022 public:
4023 /* Returns whether the named function parameter has a name (i.e. name is not
4024 * '_'). */
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)
4051 // Copy constructor
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;
4067 name = other.name;
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 ();
4074 else
4075 param_type = nullptr;
4077 return *this;
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);
4098 return param_type;
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;
4114 Location locus;
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;
4128 bool has_variadics;
4129 std::vector<Attribute> variadic_outer_attrs;
4131 public:
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
4178 // true?
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 ();
4216 else
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 ());
4223 return *this;
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 ());
4267 return return_type;
4270 Identifier get_identifier () const { return item_name; };
4272 protected:
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
4284 // bool has_abi;
4285 std::string abi;
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;
4293 Location locus;
4295 // TODO: find another way to store this to save memory?
4296 bool marked_for_strip = false;
4298 public:
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);
4335 abi = other.abi;
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 ());
4344 return *this;
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; }
4373 protected:
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;
4383 } // namespace AST
4384 } // namespace Rust
4386 #endif