#ifndef RUST_AST_ITEM_H #define RUST_AST_ITEM_H /* Copyright (C) 2009-2020 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "rust-ast.h" #include "rust-path.h" namespace Rust { namespace AST { // forward decls // struct Lifetime; // struct LifetimeBounds; // struct TypeParamBounds; class BlockExpr; // class Expr; // class Type; class TypePath; // class Pattern; class MacroInvocationSemi; // TODO: inline? /*struct AbiName { ::std::string abi_name; // Technically is meant to be STRING_LITERAL or RAW_STRING_LITERAL public: // Returns whether abi name is empty, i.e. doesn't exist. inline bool is_empty() const { return abi_name.empty(); } AbiName(::std::string name) : abi_name(::std::move(name)) {} // Empty AbiName constructor AbiName() {} };*/ // A type generic parameter (as opposed to a lifetime generic parameter) class TypeParam : public GenericParam { // bool has_outer_attribute; //::std::unique_ptr outer_attr; Attribute outer_attr; Identifier type_representation; // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; ::std::vector< ::std::unique_ptr > type_param_bounds; // inlined form // bool has_type; // Type type; ::std::unique_ptr type; Location locus; public: // Returns whether the type of the type param has been specified. inline bool has_type () const { return type != NULL; } // Returns whether the type param has type param bounds. inline bool has_type_param_bounds () const { return !type_param_bounds.empty (); } // Returns whether the type param has an outer attribute. inline bool has_outer_attribute () const { return !outer_attr.is_empty (); } TypeParam ( Identifier type_representation, Location locus = Location (), ::std::vector< ::std::unique_ptr > type_param_bounds = ::std::vector< ::std::unique_ptr > (), ::std::unique_ptr type = NULL, Attribute outer_attr = Attribute::create_empty ()) : outer_attr (::std::move (outer_attr)), type_representation (::std::move (type_representation)), type_param_bounds (::std::move (type_param_bounds)), type (::std::move (type)), locus (locus) {} // Copy constructor uses clone TypeParam (TypeParam const &other) : outer_attr (other.outer_attr), type_representation (other.type_representation), /*type_param_bounds(other.type_param_bounds),*/ type ( other.type->clone_type ()), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } } // Destructor - define here if required // Overloaded assignment operator to clone TypeParam &operator= (TypeParam const &other) { type_representation = other.type_representation; // type_param_bounds = other.type_param_bounds; type = other.type->clone_type (); outer_attr = other.outer_attr; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } return *this; } // move constructors TypeParam (TypeParam &&other) = default; TypeParam &operator= (TypeParam &&other) = default; ::std::string as_string () const; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual TypeParam *clone_generic_param_impl () const { return new TypeParam (*this); } }; // "where" clause item base. Abstract - use LifetimeWhereClauseItem, // TypeBoundWhereClauseItem class WhereClauseItem { public: virtual ~WhereClauseItem () {} // Unique pointer custom clone function ::std::unique_ptr clone_where_clause_item () const { return ::std::unique_ptr (clone_where_clause_item_impl ()); } virtual ::std::string as_string () const = 0; virtual void accept_vis (ASTVisitor &vis) = 0; protected: // Clone function implementation as pure virtual method virtual WhereClauseItem *clone_where_clause_item_impl () const = 0; }; // A lifetime where clause item class LifetimeWhereClauseItem : public WhereClauseItem { Lifetime lifetime; // LifetimeBounds lifetime_bounds; ::std::vector lifetime_bounds; // inlined lifetime bounds // should this store location info? public: LifetimeWhereClauseItem (Lifetime lifetime, ::std::vector lifetime_bounds) : lifetime (::std::move (lifetime)), lifetime_bounds (::std::move (lifetime_bounds)) {} ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual LifetimeWhereClauseItem *clone_where_clause_item_impl () const { return new LifetimeWhereClauseItem (*this); } }; // A type bound where clause item class TypeBoundWhereClauseItem : public WhereClauseItem { // bool has_for_lifetimes; // LifetimeParams for_lifetimes; ::std::vector for_lifetimes; // inlined // Type bound_type; ::std::unique_ptr bound_type; // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; ::std::vector< ::std::unique_ptr > type_param_bounds; // inlined form // should this store location info? public: // Returns whether the item has ForLifetimes inline bool has_for_lifetimes () const { return !for_lifetimes.empty (); } // Returns whether the item has type param bounds inline bool has_type_param_bounds () const { return !type_param_bounds.empty (); } TypeBoundWhereClauseItem ( ::std::vector for_lifetimes, ::std::unique_ptr bound_type, ::std::vector< ::std::unique_ptr > type_param_bounds) : for_lifetimes (::std::move (for_lifetimes)), bound_type (::std::move (bound_type)), type_param_bounds (::std::move (type_param_bounds)) {} // Copy constructor requires clone TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other) : for_lifetimes (other.for_lifetimes), bound_type (other.bound_type->clone_type ()) /*, type_param_bounds(other.type_param_bounds)*/ { // crappy vector unique pointer clone - TODO is there a better way of // doing this? type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } } // Destructor - define here if required // Overload assignment operator to clone TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other) { for_lifetimes = other.for_lifetimes; bound_type = other.bound_type->clone_type (); // type_param_bounds = other.type_param_bounds; // crappy vector unique pointer clone - TODO is there a better way of // doing this? type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } return *this; } // move constructors TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default; TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem &&other) = default; ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual TypeBoundWhereClauseItem *clone_where_clause_item_impl () const { return new TypeBoundWhereClauseItem (*this); } }; // A where clause struct WhereClause { private: //::std::vector where_clause_items; ::std::vector< ::std::unique_ptr > where_clause_items; // should this store location info? public: WhereClause ( ::std::vector< ::std::unique_ptr > where_clause_items) : where_clause_items (::std::move (where_clause_items)) {} // copy constructor with vector clone WhereClause (WhereClause const &other) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? where_clause_items.reserve (other.where_clause_items.size ()); for (const auto &e : other.where_clause_items) { where_clause_items.push_back (e->clone_where_clause_item ()); } } // overloaded assignment operator with vector clone WhereClause &operator= (WhereClause const &other) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? where_clause_items.reserve (other.where_clause_items.size ()); for (const auto &e : other.where_clause_items) { where_clause_items.push_back (e->clone_where_clause_item ()); } return *this; } // move constructors WhereClause (WhereClause &&other) = default; WhereClause &operator= (WhereClause &&other) = default; // Creates a WhereClause with no items. static WhereClause create_empty () { return WhereClause (::std::vector< ::std::unique_ptr > ()); } // Returns whether the WhereClause has no items. inline bool is_empty () const { return where_clause_items.empty (); } ::std::string as_string () const; }; // A self parameter in a method struct SelfParam { private: bool has_ref; bool is_mut; // bool has_lifetime; // only possible if also ref Lifetime lifetime; // bool has_type; // only possible if not ref // Type type; ::std::unique_ptr type; Location locus; // Unrestricted constructor used for error state SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type) : has_ref (has_ref), is_mut (is_mut), lifetime (::std::move (lifetime)), type (type) {} // this is ok as no outside classes can ever call this public: // Returns whether the self-param has a type field. inline bool has_type () const { return type != NULL; } // Returns whether the self-param has a valid lifetime. inline bool has_lifetime () const { return !lifetime.is_error (); } // Returns whether the self-param is in an error state. inline bool is_error () const { return has_type () && has_lifetime (); // not having either is not an error } // Creates an error state self-param. static SelfParam create_error () { /* HACK: creates a dummy type. Since it's a unique pointer, it should * clean it up, but it still allocates memory, which is not ideal. */ return SelfParam (Lifetime (Lifetime::STATIC), false, false, new QualifiedPathInType ( QualifiedPathInType::create_error ())); } // Type-based self parameter (not ref, no lifetime) SelfParam (::std::unique_ptr type, bool is_mut, Location locus) : has_ref (false), is_mut (is_mut), lifetime (Lifetime::error ()), type (::std::move (type)), locus (locus) {} // Lifetime-based self parameter (is ref, no type) SelfParam (Lifetime lifetime, bool is_mut, Location locus) : /*type(NULL), */ has_ref (true), is_mut (is_mut), lifetime (::std::move (lifetime)), locus (locus) {} // Copy constructor requires clone SelfParam (SelfParam const &other) : has_ref (other.has_ref), is_mut (other.is_mut), lifetime (other.lifetime), type (other.type->clone_type ()), locus (other.locus) {} // Destructor - define here if required // Overload assignment operator to use clone SelfParam &operator= (SelfParam const &other) { type = other.type->clone_type (); is_mut = other.is_mut; has_ref = other.has_ref; lifetime = other.lifetime; locus = other.locus; return *this; } // move constructors SelfParam (SelfParam &&other) = default; SelfParam &operator= (SelfParam &&other) = default; ::std::string as_string () const; Location get_locus () const { return locus; } }; // Qualifiers for function, i.e. const, unsafe, extern etc. struct FunctionQualifiers { public: // Whether the function is neither const nor async, const only, or async // only. enum AsyncConstStatus { NONE, CONST, ASYNC }; private: AsyncConstStatus const_status; bool has_unsafe; bool has_extern; ::std::string extern_abi; // e.g. extern "C" fn() -> i32 {} // TODO: maybe ensure that extern_abi only exists if extern exists? // should this store location info? public: // Constructor with no extern (and hence no extern abi) FunctionQualifiers (AsyncConstStatus const_status, bool has_unsafe) : const_status (const_status), has_unsafe (has_unsafe), has_extern (false), extern_abi (::std::string ("")) {} // Constructor with extern abi (and thus extern) FunctionQualifiers (AsyncConstStatus const_status, bool has_unsafe, ::std::string extern_abi) : const_status (const_status), has_unsafe (has_unsafe), has_extern (true), extern_abi (::std::move (extern_abi)) {} // Constructor with all possible options (DON'T HAVE EXTERN_ABI WITHOUT // EXTERN!) FunctionQualifiers (AsyncConstStatus const_status, bool has_unsafe, bool has_extern, ::std::string extern_abi) : const_status (const_status), has_unsafe (has_unsafe), has_extern (has_extern), extern_abi (::std::move (extern_abi)) {} ::std::string as_string () const; }; // Forward decl FunctionParams // struct FunctionParams; // A function parameter struct FunctionParam { public: // Pattern* param_name; ::std::unique_ptr param_name; // Type type; ::std::unique_ptr type; Location locus; FunctionParam (::std::unique_ptr param_name, ::std::unique_ptr param_type, Location locus) : param_name (::std::move (param_name)), type (::std::move (param_type)), locus (locus) {} // Copy constructor uses clone FunctionParam (FunctionParam const &other) : param_name (other.param_name->clone_pattern ()), type (other.type->clone_type ()), locus (other.locus) {} // Destructor - define here if required // Overload assignment operator to use clone FunctionParam &operator= (FunctionParam const &other) { param_name = other.param_name->clone_pattern (); type = other.type->clone_type (); locus = other.locus; return *this; } // move constructors FunctionParam (FunctionParam &&other) = default; FunctionParam &operator= (FunctionParam &&other) = default; // Returns whether FunctionParam is in an invalid state. inline bool is_error () const { return param_name == NULL || type == NULL; } // Creates an error FunctionParam. static FunctionParam create_error () { return FunctionParam (NULL, NULL, Location ()); } ::std::string as_string () const; Location get_locus () const { return locus; } }; // Visibility of item - if the item has it, then it is some form of public struct Visibility { public: enum PublicVisType { NONE, CRATE, SELF, SUPER, IN_PATH }; private: // bool is_pub; // if vis is public, one of these PublicVisType public_vis_type; // Only assigned if public_vis_type is IN_PATH SimplePath in_path; // should this store location info? public: // Creates a Visibility - TODO make constructor protected or private? Visibility (PublicVisType public_vis_type, SimplePath in_path) : public_vis_type (public_vis_type), in_path (::std::move (in_path)) { if (public_vis_type != IN_PATH && !in_path.is_empty ()) { // error - invalid state // just ignore path if vis type is not that } } // Returns whether visibility is in an error state. inline bool is_error () const { return public_vis_type == IN_PATH && in_path.is_empty (); } // Creates an error visibility. static Visibility create_error () { return Visibility (IN_PATH, SimplePath::create_empty ()); } // Unique pointer custom clone function /*::std::unique_ptr clone_visibility() const { return ::std::unique_ptr(clone_visibility_impl()); }*/ /* TODO: think of a way to only allow valid Visibility states - polymorphism * is one idea but may be too resource-intensive. */ // Creates a public visibility with no further features/arguments. static Visibility create_public () { return Visibility (NONE, SimplePath::create_empty ()); } // Creates a public visibility with crate-relative paths or whatever. static Visibility create_crate () { return Visibility (CRATE, SimplePath::create_empty ()); } // Creates a public visibility with self-relative paths or whatever. static Visibility create_self () { return Visibility (SELF, SimplePath::create_empty ()); } // Creates a public visibility with parent module-relative paths or // whatever. static Visibility create_super () { return Visibility (SUPER, SimplePath::create_empty ()); } // Creates a public visibility with a given path or whatever. static Visibility create_in_path (SimplePath in_path) { return Visibility (IN_PATH, ::std::move (in_path)); } ::std::string as_string () const; protected: // Clone function implementation - not currently virtual but may be if // polymorphism used /*virtual*/ Visibility *clone_visibility_impl () const { return new Visibility (*this); } }; // A method (function belonging to a type) class Method : public InherentImplItem, public TraitImplItem { // moved from impl items for consistency ::std::vector outer_attrs; Visibility vis; FunctionQualifiers qualifiers; Identifier method_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined SelfParam self_param; // bool has_params; // FunctionParams function_params; ::std::vector function_params; // inlined // bool has_return_type; // FunctionReturnType return_type; ::std::unique_ptr return_type; // inlined // bool has_where_clause; WhereClause where_clause; // BlockExpr* expr; ::std::unique_ptr expr; Location locus; public: /*~Method() { delete expr; }*/ // Returns whether the method is in an error state. inline bool is_error () const { return expr == NULL || method_name.empty () || self_param.is_error (); } // Creates an error state method. static Method create_error () { return Method ("", FunctionQualifiers (FunctionQualifiers::NONE, true), ::std::vector< ::std::unique_ptr > (), SelfParam::create_error (), ::std::vector (), NULL, WhereClause::create_empty (), NULL, Visibility::create_error (), ::std::vector ()); } // Returns whether the method has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether the method has parameters. inline bool has_params () const { return !function_params.empty (); } // Returns whether the method has a return type (void otherwise). inline bool has_return_type () const { return return_type != NULL; } // Returns whether the where clause exists (i.e. has items) inline bool has_where_clause () const { return !where_clause.is_empty (); } // Returns whether method has a non-default visibility. inline bool has_visibility () const { return !vis.is_error (); } // Mega-constructor with all possible fields Method (Identifier method_name, FunctionQualifiers qualifiers, ::std::vector< ::std::unique_ptr > generic_params, SelfParam self_param, ::std::vector function_params, ::std::unique_ptr return_type, WhereClause where_clause, ::std::unique_ptr function_body, Visibility vis, ::std::vector outer_attrs, Location locus = Location ()) : outer_attrs (::std::move (outer_attrs)), vis (::std::move (vis)), qualifiers (::std::move (qualifiers)), method_name (::std::move (method_name)), generic_params (::std::move (generic_params)), self_param (::std::move (self_param)), function_params (::std::move (function_params)), return_type (::std::move (return_type)), where_clause (::std::move (where_clause)), expr (::std::move (function_body)), locus (locus) {} // TODO: add constructor with less fields // Copy constructor with clone Method (Method const &other) : outer_attrs (other.outer_attrs), vis (other.vis), qualifiers (other.qualifiers), method_name (other.method_name), /*generic_params(other.generic_params),*/ self_param (other.self_param), function_params (other.function_params), return_type (other.return_type->clone_type ()), where_clause (other.where_clause), expr (other.expr->clone_block_expr ()), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } //~Method() = default; // Overloaded assignment operator to clone Method &operator= (Method const &other) { method_name = other.method_name; outer_attrs = other.outer_attrs; vis = other.vis; qualifiers = other.qualifiers; // generic_params = other.generic_params; self_param = other.self_param; function_params = other.function_params; return_type = other.return_type->clone_type (); where_clause = other.where_clause; expr = other.expr->clone_block_expr (); locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors Method (Method &&other) = default; Method &operator= (Method &&other) = default; ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual Method *clone_inherent_impl_item_impl () const OVERRIDE { return new Method (*this); } // Use covariance to implement clone function as returning this object // rather than base virtual Method *clone_trait_impl_item_impl () const OVERRIDE { return new Method (*this); } }; // Item that supports visibility - abstract base class class VisItem : public Item { Visibility visibility; protected: // Visibility constructor VisItem (Visibility visibility, ::std::vector outer_attrs = ::std::vector ()) : Item (::std::move (outer_attrs)), visibility (::std::move (visibility)) {} // Visibility copy constructor VisItem (VisItem const &other) : Item (other), visibility (other.visibility) {} // Destructor - define here if required // Overload assignment operator to clone VisItem &operator= (VisItem const &other) { Item::operator= (other); visibility = other.visibility; // outer_attrs = other.outer_attrs; return *this; } // move constructors VisItem (VisItem &&other) = default; VisItem &operator= (VisItem &&other) = default; public: // Does the item have some kind of public visibility (non-default // visibility)? inline bool has_visibility () const { return !visibility.is_error (); } virtual ::std::string as_string () const; }; // Rust module item - abstract base class class Module : public VisItem { Identifier module_name; Location locus; protected: // Protected constructor Module (Identifier module_name, Visibility visibility, Location locus, ::std::vector outer_attrs = ::std::vector ()) : VisItem (::std::move (visibility), ::std::move (outer_attrs)), module_name (module_name), locus (locus) {} public: virtual ::std::string as_string () const; Location get_locus () const { return locus; } }; // Module with a body, defined in file class ModuleBodied : public Module { // bool has_inner_attrs; ::std::vector inner_attrs; // bool has_items; //::std::vector items; ::std::vector< ::std::unique_ptr > items; public: virtual ::std::string as_string () const; // Returns whether the module has items in its body. inline bool has_items () const { return !items.empty (); } // Returns whether the module has any inner attributes. inline bool has_inner_attrs () const { return !inner_attrs.empty (); } // Full constructor ModuleBodied (Identifier name, Location locus, ::std::vector< ::std::unique_ptr > items = ::std::vector< ::std::unique_ptr > (), Visibility visibility = Visibility::create_error (), ::std::vector inner_attrs = ::std::vector (), ::std::vector outer_attrs = ::std::vector ()) : Module (::std::move (name), ::std::move (visibility), locus, ::std::move (outer_attrs)), inner_attrs (::std::move (inner_attrs)), items (::std::move (items)) {} // Copy constructor with vector clone ModuleBodied (ModuleBodied const &other) : Module (other), inner_attrs (other.inner_attrs) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? items.reserve (other.items.size ()); for (const auto &e : other.items) { items.push_back (e->clone_item ()); } } // Overloaded assignment operator with vector clone ModuleBodied &operator= (ModuleBodied const &other) { Module::operator= (other); inner_attrs = other.inner_attrs; // crappy vector unique pointer clone - TODO is there a better way of // doing this? items.reserve (other.items.size ()); for (const auto &e : other.items) { items.push_back (e->clone_item ()); } return *this; } // move constructors ModuleBodied (ModuleBodied &&other) = default; ModuleBodied &operator= (ModuleBodied &&other) = default; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; // Override that runs the function recursively on all items contained within // the module. virtual void add_crate_name (::std::vector< ::std::string> &names) const OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual ModuleBodied *clone_item_impl () const OVERRIDE { return new ModuleBodied (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual ModuleBodied* clone_statement_impl() const OVERRIDE { return new ModuleBodied(*this); }*/ }; // Module without a body, loaded from external file class ModuleNoBody : public Module { public: ::std::string as_string () const; // Full constructor ModuleNoBody (Identifier name, Visibility visibility, ::std::vector outer_attrs, Location locus) : Module (::std::move (name), ::std::move (visibility), locus, ::std::move (outer_attrs)) {} virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual ModuleNoBody *clone_item_impl () const OVERRIDE { return new ModuleNoBody (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual ModuleNoBody* clone_statement_impl() const OVERRIDE { return new ModuleNoBody(*this); }*/ }; // Rust extern crate declaration AST node class ExternCrate : public VisItem { // this is either an identifier or "self", with self parsed to string ::std::string referenced_crate; // bool has_as_clause; // AsClause as_clause; // this is either an identifier or "_", with _ parsed to string ::std::string as_clause_name; Location locus; /* e.g. "extern crate foo as _" "extern crate foo" "extern crate std as cool_std" */ public: ::std::string as_string () const; // Returns whether extern crate declaration has an as clause. inline bool has_as_clause () const { return !as_clause_name.empty (); } // Returns whether extern crate declaration references the current crate // (i.e. self). inline bool references_self () const { return referenced_crate == "self"; } // Constructor ExternCrate (::std::string referenced_crate, Visibility visibility, ::std::vector outer_attrs, Location locus, ::std::string as_clause_name = ::std::string ()) : VisItem (::std::move (visibility), ::std::move (outer_attrs)), referenced_crate (::std::move (referenced_crate)), as_clause_name (::std::move (as_clause_name)), locus (locus) {} Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; // Override that adds extern crate name in decl to passed list of names. virtual void add_crate_name (::std::vector< ::std::string> &names) const OVERRIDE { names.push_back (referenced_crate); } protected: // Use covariance to implement clone function as returning this object // rather than base virtual ExternCrate *clone_item_impl () const OVERRIDE { return new ExternCrate (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual ExternCrate* clone_statement_impl() const OVERRIDE { return new ExternCrate(*this); }*/ }; // The path-ish thing referred to in a use declaration - abstract base class class UseTree { Location locus; public: virtual ~UseTree () {} // Unique pointer custom clone function ::std::unique_ptr clone_use_tree () const { return ::std::unique_ptr (clone_use_tree_impl ()); } virtual ::std::string as_string () const = 0; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) = 0; protected: // Clone function implementation as pure virtual method virtual UseTree *clone_use_tree_impl () const = 0; UseTree (Location locus) : locus (locus) {} }; // Use tree with a glob (wildcard) operator class UseTreeGlob : public UseTree { public: enum PathType { NO_PATH, GLOBAL, PATH_PREFIXED }; private: PathType glob_type; SimplePath path; public: UseTreeGlob (PathType glob_type, SimplePath path, Location locus) : UseTree (locus), glob_type (glob_type), path (::std::move (path)) {} // Returns whether has path. Should be made redundant by PathType // PATH_PREFIXED. inline bool has_path () const { return !path.is_empty (); } ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; // TODO: find way to ensure only PATH_PREFIXED glob_type has path - factory // methods? protected: // Use covariance to implement clone function as returning this object // rather than base virtual UseTreeGlob *clone_use_tree_impl () const OVERRIDE { return new UseTreeGlob (*this); } }; // Use tree with a list of paths with a common prefix class UseTreeList : public UseTree { public: enum PathType { NO_PATH, GLOBAL, PATH_PREFIXED }; private: PathType path_type; SimplePath path; ::std::vector< ::std::unique_ptr > trees; public: UseTreeList (PathType path_type, SimplePath path, ::std::vector< ::std::unique_ptr > trees, Location locus) : UseTree (locus), path_type (path_type), path (::std::move (path)), trees (::std::move (trees)) {} // copy constructor with vector clone UseTreeList (UseTreeList const &other) : UseTree (other), path_type (other.path_type), path (other.path) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? trees.reserve (other.trees.size ()); for (const auto &e : other.trees) { trees.push_back (e->clone_use_tree ()); } } // overloaded assignment operator with vector clone UseTreeList &operator= (UseTreeList const &other) { UseTree::operator= (other); path_type = other.path_type; path = other.path; // crappy vector unique pointer clone - TODO is there a better way of // doing this? trees.reserve (other.trees.size ()); for (const auto &e : other.trees) { trees.push_back (e->clone_use_tree ()); } return *this; } // move constructors UseTreeList (UseTreeList &&other) = default; UseTreeList &operator= (UseTreeList &&other) = default; // Returns whether has path. Should be made redundant by path_type. inline bool has_path () const { return !path.is_empty (); } // Returns whether has inner tree elements. inline bool has_trees () const { return !trees.empty (); } ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory // methods? protected: // Use covariance to implement clone function as returning this object // rather than base virtual UseTreeList *clone_use_tree_impl () const OVERRIDE { return new UseTreeList (*this); } }; // Use tree where it rebinds the module name as something else class UseTreeRebind : public UseTree { public: enum NewBindType { NONE, IDENTIFIER, WILDCARD }; private: SimplePath path; NewBindType bind_type; Identifier identifier; // only if NewBindType is IDENTIFIER public: UseTreeRebind (NewBindType bind_type, SimplePath path, Location locus, Identifier identifier = ::std::string ()) : UseTree (locus), path (::std::move (path)), bind_type (bind_type), identifier (::std::move (identifier)) {} // Returns whether has path (this should always be true). inline bool has_path () const { return !path.is_empty (); } // Returns whether has identifier (or, rather, is allowed to). inline bool has_identifier () const { return bind_type == IDENTIFIER; } ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory // methods? protected: // Use covariance to implement clone function as returning this object // rather than base virtual UseTreeRebind *clone_use_tree_impl () const OVERRIDE { return new UseTreeRebind (*this); } }; // Rust use declaration (i.e. for modules) AST node class UseDeclaration : public VisItem { ::std::unique_ptr use_tree; Location locus; public: ::std::string as_string () const; UseDeclaration (::std::unique_ptr use_tree, Visibility visibility, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (visibility), ::std::move (outer_attrs)), use_tree (::std::move (use_tree)), locus (locus) {} // Copy constructor with clone UseDeclaration (UseDeclaration const &other) : VisItem (other), use_tree (other.use_tree->clone_use_tree ()), locus (other.locus) {} // Destructor - define here if required // Overloaded assignment operator to clone UseDeclaration &operator= (UseDeclaration const &other) { VisItem::operator= (other); use_tree = other.use_tree->clone_use_tree (); // visibility = other.visibility->clone_visibility(); // outer_attrs = other.outer_attrs; locus = other.locus; return *this; } // move constructors UseDeclaration (UseDeclaration &&other) = default; UseDeclaration &operator= (UseDeclaration &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual UseDeclaration *clone_item_impl () const OVERRIDE { return new UseDeclaration (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual UseDeclaration* clone_statement_impl() const OVERRIDE { return new UseDeclaration(*this); }*/ }; // Parameters used in a function - TODO inline? /*struct FunctionParams { ::std::vector function_params; };*/ class LetStmt; // Rust function declaration AST node class Function : public VisItem, public InherentImplItem, public TraitImplItem { public: FunctionQualifiers qualifiers; Identifier function_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_function_params; // FunctionParams function_params; ::std::vector function_params; // inlined // bool has_function_return_type; // Type return_type; ::std::unique_ptr return_type; // bool has_where_clause; WhereClause where_clause; // BlockExpr* function_body; ::std::unique_ptr function_body; Location locus; ::std::vector locals; /*~Function() { delete function_body; }*/ ::std::string as_string () const; // Returns whether function has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether function has regular parameters. inline bool has_function_params () const { return !function_params.empty (); } // Returns whether function has return type - if not, it is void. inline bool has_function_return_type () const { return return_type != NULL; } // Returns whether function has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } // Mega-constructor with all possible fields Function (Identifier function_name, FunctionQualifiers qualifiers, ::std::vector< ::std::unique_ptr > generic_params, ::std::vector function_params, ::std::unique_ptr return_type, WhereClause where_clause, ::std::unique_ptr function_body, Visibility vis, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), qualifiers (::std::move (qualifiers)), function_name (::std::move (function_name)), generic_params (::std::move (generic_params)), function_params (::std::move (function_params)), return_type (::std::move (return_type)), where_clause (::std::move (where_clause)), function_body (::std::move (function_body)), locus (locus) {} // TODO: add constructor with less fields // Copy constructor with clone Function (Function const &other) : VisItem (other), qualifiers (other.qualifiers), function_name (other.function_name), /*generic_params(other.generic_params),*/ function_params ( other.function_params), return_type (other.return_type->clone_type ()), where_clause (other.where_clause), function_body (other.function_body->clone_block_expr ()), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } // Destructor - define here if required // Overloaded assignment operator to clone Function &operator= (Function const &other) { VisItem::operator= (other); function_name = other.function_name; qualifiers = other.qualifiers; // generic_params = other.generic_params; function_params = other.function_params; return_type = other.return_type->clone_type (); where_clause = other.where_clause; function_body = other.function_body->clone_block_expr (); // visibility = other.visibility->clone_visibility(); // outer_attrs = other.outer_attrs; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors Function (Function &&other) = default; Function &operator= (Function &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual Function *clone_item_impl () const OVERRIDE { return new Function (*this); } // Use covariance to implement clone function as returning this object // rather than base virtual Function *clone_inherent_impl_item_impl () const OVERRIDE { return new Function (*this); } // Use covariance to implement clone function as returning this object // rather than base virtual Function *clone_trait_impl_item_impl () const OVERRIDE { return new Function (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual Function* clone_statement_impl() const OVERRIDE { return new Function(*this); }*/ }; // Rust type alias (i.e. typedef) AST node class TypeAlias : public VisItem, public TraitImplItem { Identifier new_type_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; // Type exiting_type; ::std::unique_ptr existing_type; Location locus; public: ::std::string as_string () const; // Returns whether type alias has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether type alias has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } // Mega-constructor with all possible fields TypeAlias (Identifier new_type_name, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, ::std::unique_ptr existing_type, Visibility vis, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), new_type_name (::std::move (new_type_name)), generic_params (::std::move (generic_params)), where_clause (::std::move (where_clause)), existing_type (::std::move (existing_type)), locus (locus) {} // Copy constructor TypeAlias (TypeAlias const &other) : VisItem (other), new_type_name ( other.new_type_name), /*generic_params(other.generic_params),*/ where_clause (other.where_clause), existing_type (other.existing_type->clone_type ()), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } // Destructor - define here if required // Overloaded assignment operator to clone TypeAlias &operator= (TypeAlias const &other) { VisItem::operator= (other); new_type_name = other.new_type_name; // generic_params = other.generic_params; where_clause = other.where_clause; existing_type = other.existing_type->clone_type (); // visibility = other.visibility->clone_visibility(); // outer_attrs = other.outer_attrs; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors TypeAlias (TypeAlias &&other) = default; TypeAlias &operator= (TypeAlias &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual TypeAlias *clone_item_impl () const OVERRIDE { return new TypeAlias (*this); } // Use covariance to implement clone function as returning this object // rather than base virtual TypeAlias *clone_trait_impl_item_impl () const OVERRIDE { return new TypeAlias (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual TypeAlias* clone_statement_impl() const OVERRIDE { return new TypeAlias(*this); }*/ }; // Rust base struct declaration AST node - abstract base class class Struct : public VisItem { protected: // protected to enable access by derived classes - allows better as_string Identifier struct_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; Location locus; public: // Returns whether struct has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether struct has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } Location get_locus () const { return locus; } protected: Struct (Identifier struct_name, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, Visibility vis, Location locus, ::std::vector outer_attrs = ::std::vector ()) : VisItem (::std::move (vis), ::std::move (outer_attrs)), struct_name (::std::move (struct_name)), generic_params (::std::move (generic_params)), where_clause (::std::move (where_clause)), locus (locus) {} // Copy constructor with vector clone Struct (Struct const &other) : VisItem (other), struct_name (other.struct_name), where_clause (other.where_clause), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } // Overloaded assignment operator with vector clone Struct &operator= (Struct const &other) { VisItem::operator= (other); struct_name = other.struct_name; where_clause = other.where_clause; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors Struct (Struct &&other) = default; Struct &operator= (Struct &&other) = default; }; // A single field in a struct struct StructField { private: // bool has_outer_attributes; ::std::vector outer_attrs; // bool has_visibility; Visibility visibility; Identifier field_name; // Type field_type; ::std::unique_ptr field_type; // should this store location info? public: // Returns whether struct field has any outer attributes. inline bool has_outer_attributes () const { return !outer_attrs.empty (); } // Returns whether struct field has a non-private (non-default) visibility. inline bool has_visibility () const { return !visibility.is_error (); } StructField (Identifier field_name, ::std::unique_ptr field_type, Visibility vis, ::std::vector outer_attrs = ::std::vector ()) : outer_attrs (::std::move (outer_attrs)), visibility (::std::move (vis)), field_name (::std::move (field_name)), field_type (::std::move (field_type)) {} // Copy constructor StructField (StructField const &other) : outer_attrs (other.outer_attrs), visibility (other.visibility), field_name (other.field_name), field_type (other.field_type->clone_type ()) {} ~StructField () = default; // Overloaded assignment operator to clone StructField &operator= (StructField const &other) { field_name = other.field_name; field_type = other.field_type->clone_type (); visibility = other.visibility; outer_attrs = other.outer_attrs; return *this; } // move constructors StructField (StructField &&other) = default; StructField &operator= (StructField &&other) = default; // Returns whether struct field is in an error state. inline bool is_error () const { return field_name.empty () && field_type == NULL; // this should really be an or since neither are allowed } // Creates an error state struct field. static StructField create_error () { return StructField (::std::string (""), NULL, Visibility::create_error ()); } ::std::string as_string () const; }; // Rust struct declaration with true struct type AST node class StructStruct : public Struct { ::std::vector fields; bool is_unit; public: ::std::string as_string () const; // Mega-constructor with all possible fields StructStruct (::std::vector fields, Identifier struct_name, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, bool is_unit, Visibility vis, ::std::vector outer_attrs, Location locus) : Struct (::std::move (struct_name), ::std::move (generic_params), ::std::move (where_clause), ::std::move (vis), locus, ::std::move (outer_attrs)), fields (::std::move (fields)), is_unit (is_unit) {} // Unit struct constructor StructStruct (Identifier struct_name, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, Visibility vis, ::std::vector outer_attrs, Location locus) : Struct (::std::move (struct_name), ::std::move (generic_params), ::std::move (where_clause), ::std::move (vis), locus, ::std::move (outer_attrs)), is_unit (true) {} // TODO: can a unit struct have generic fields? assuming yes for now. /* Returns whether the struct is a unit struct - struct defined without * fields. This is * important because it also means an implicit constant of its type is * defined. */ inline bool is_unit_struct () const { return is_unit; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual StructStruct *clone_item_impl () const OVERRIDE { return new StructStruct (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual StructStruct* clone_statement_impl() const OVERRIDE { return new StructStruct(*this); }*/ }; // A single field in a tuple struct TupleField { private: // bool has_outer_attributes; ::std::vector outer_attrs; // bool has_visibility; Visibility visibility; // Type field_type; ::std::unique_ptr field_type; // should this store location info? public: // Returns whether tuple field has outer attributes. inline bool has_outer_attributes () const { return !outer_attrs.empty (); } // Returns whether tuple field has a non-default visibility (i.e. a public // one) inline bool has_visibility () const { return !visibility.is_error (); } // Complete constructor TupleField (::std::unique_ptr field_type, Visibility vis, ::std::vector outer_attrs = ::std::vector ()) : outer_attrs (::std::move (outer_attrs)), visibility (::std::move (vis)), field_type (::std::move (field_type)) {} // Copy constructor with clone TupleField (TupleField const &other) : outer_attrs (other.outer_attrs), visibility (other.visibility), field_type (other.field_type->clone_type ()) {} ~TupleField () = default; // Overloaded assignment operator to clone TupleField &operator= (TupleField const &other) { field_type = other.field_type->clone_type (); visibility = other.visibility; outer_attrs = other.outer_attrs; return *this; } // move constructors TupleField (TupleField &&other) = default; TupleField &operator= (TupleField &&other) = default; // Returns whether tuple field is in an error state. inline bool is_error () const { return field_type == NULL; } // Creates an error state tuple field. static TupleField create_error () { return TupleField (NULL, Visibility::create_error ()); } ::std::string as_string () const; }; // Rust tuple declared using struct keyword AST node class TupleStruct : public Struct { ::std::vector fields; public: ::std::string as_string () const; // Mega-constructor with all possible fields TupleStruct (::std::vector fields, Identifier struct_name, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, Visibility vis, ::std::vector outer_attrs, Location locus) : Struct (::std::move (struct_name), ::std::move (generic_params), ::std::move (where_clause), ::std::move (vis), locus, ::std::move (outer_attrs)), fields (::std::move (fields)) {} virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual TupleStruct *clone_item_impl () const OVERRIDE { return new TupleStruct (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual TupleStruct* clone_statement_impl() const OVERRIDE { return new TupleStruct(*this); }*/ }; // An item used in an "enum" tagged union - not abstract: base represents a // name-only enum class EnumItem { // bool has_attrs; ::std::vector outer_attrs; Identifier variant_name; Location locus; public: virtual ~EnumItem () {} // Returns whether enum item has outer attributes. inline bool has_outer_attrs () const { return !outer_attrs.empty (); } EnumItem (Identifier variant_name, ::std::vector outer_attrs, Location locus) : outer_attrs (::std::move (outer_attrs)), variant_name (::std::move (variant_name)), locus (locus) {} // Unique pointer custom clone function ::std::unique_ptr clone_enum_item () const { return ::std::unique_ptr (clone_enum_item_impl ()); } virtual ::std::string as_string () const; // not pure virtual as not abstract virtual void accept_vis (ASTVisitor &vis); protected: // Clone function implementation as (not pure) virtual method virtual EnumItem *clone_enum_item_impl () const { return new EnumItem (*this); } }; // A tuple item used in an "enum" tagged union class EnumItemTuple : public EnumItem { // bool has_tuple_fields; ::std::vector tuple_fields; public: // Returns whether tuple enum item has tuple fields. inline bool has_tuple_fields () const { return !tuple_fields.empty (); } EnumItemTuple (Identifier variant_name, ::std::vector tuple_fields, ::std::vector outer_attrs, Location locus) : EnumItem (::std::move (variant_name), ::std::move (outer_attrs), locus), tuple_fields (::std::move (tuple_fields)) {} ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual EnumItemTuple *clone_enum_item_impl () const { return new EnumItemTuple (*this); } }; // A struct item used in an "enum" tagged union class EnumItemStruct : public EnumItem { // bool has_struct_fields; ::std::vector struct_fields; public: // Returns whether struct enum item has struct fields. inline bool has_struct_fields () const { return !struct_fields.empty (); } EnumItemStruct (Identifier variant_name, ::std::vector struct_fields, ::std::vector outer_attrs, Location locus) : EnumItem (::std::move (variant_name), ::std::move (outer_attrs), locus), struct_fields (::std::move (struct_fields)) {} ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual EnumItemStruct *clone_enum_item_impl () const { return new EnumItemStruct (*this); } }; // A discriminant (numbered enum) item used in an "enum" tagged union class EnumItemDiscriminant : public EnumItem { // Expr* expression; ::std::unique_ptr expression; public: /*~EnumItemDiscriminant() { delete expression; }*/ EnumItemDiscriminant (Identifier variant_name, ::std::unique_ptr expr, ::std::vector outer_attrs, Location locus) : EnumItem (::std::move (variant_name), ::std::move (outer_attrs), locus), expression (::std::move (expr)) {} // Copy constructor with clone EnumItemDiscriminant (EnumItemDiscriminant const &other) : EnumItem (other), expression (other.expression->clone_expr ()) {} // Destructor - define here if required // Overloaded assignment operator to clone EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other) { EnumItem::operator= (other); expression = other.expression->clone_expr (); // variant_name = other.variant_name; // outer_attrs = other.outer_attrs; return *this; } // move constructors EnumItemDiscriminant (EnumItemDiscriminant &&other) = default; EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default; ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual EnumItemDiscriminant *clone_enum_item_impl () const { return new EnumItemDiscriminant (*this); } }; // AST node for Rust "enum" - tagged union class Enum : public VisItem { Identifier enum_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; ::std::vector< ::std::unique_ptr > items; Location locus; public: ::std::string as_string () const; // Returns whether "enum" has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether "enum" has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } /* Returns whether enum is a "zero-variant" (no possible variant) enum, * which cannot be instantiated.*/ inline bool is_zero_variant () const { return items.empty (); } // Mega-constructor Enum (Identifier enum_name, Visibility vis, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, ::std::vector< ::std::unique_ptr > items, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), enum_name (::std::move (enum_name)), generic_params (::std::move (generic_params)), where_clause (::std::move (where_clause)), items (::std::move (items)), locus (locus) {} // TODO: constructor with less arguments // Copy constructor with vector clone Enum (Enum const &other) : VisItem (other), enum_name (other.enum_name), where_clause (other.where_clause), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } // crappy vector unique pointer clone - TODO is there a better way of // doing this? items.reserve (other.items.size ()); for (const auto &e : other.items) { items.push_back (e->clone_enum_item ()); } } // Overloaded assignment operator with vector clone Enum &operator= (Enum const &other) { VisItem::operator= (other); enum_name = other.enum_name; where_clause = other.where_clause; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } // crappy vector unique pointer clone - TODO is there a better way of // doing this? items.reserve (other.items.size ()); for (const auto &e : other.items) { items.push_back (e->clone_enum_item ()); } return *this; } // Move constructors Enum (Enum &&other) = default; Enum &operator= (Enum &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual Enum *clone_item_impl () const OVERRIDE { return new Enum (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual Enum* clone_statement_impl() const OVERRIDE { return new Enum(*this); }*/ }; // Rust untagged union used for C compat AST node class Union : public VisItem { Identifier union_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; ::std::vector variants; Location locus; public: ::std::string as_string () const; // Returns whether union has generic params. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether union has where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } Union (Identifier union_name, Visibility vis, ::std::vector< ::std::unique_ptr > generic_params, WhereClause where_clause, ::std::vector variants, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), union_name (::std::move (union_name)), generic_params (::std::move (generic_params)), where_clause (::std::move (where_clause)), variants (::std::move (variants)), locus (locus) {} // copy constructor with vector clone Union (Union const &other) : VisItem (other), union_name (other.union_name), where_clause (other.where_clause), variants (other.variants), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } // overloaded assignment operator with vector clone Union &operator= (Union const &other) { VisItem::operator= (other); union_name = other.union_name; where_clause = other.where_clause; variants = other.variants; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors Union (Union &&other) = default; Union &operator= (Union &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual Union *clone_item_impl () const OVERRIDE { return new Union (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual Union* clone_statement_impl() const OVERRIDE { return new Union(*this); }*/ }; // "Constant item" AST node - used for constant, compile-time expressions // within module scope class ConstantItem : public VisItem, public InherentImplItem, public TraitImplItem { // either has an identifier or "_" - maybe handle in identifier? // bool identifier_is_underscore; // if no identifier declared, identifier will be "_" Identifier identifier; // Type type; ::std::unique_ptr type; // Expr* const_expr; ::std::unique_ptr const_expr; Location locus; public: /*~ConstantItem() { delete const_expr; }*/ ::std::string as_string () const; ConstantItem (Identifier ident, Visibility vis, ::std::unique_ptr type, ::std::unique_ptr const_expr, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), identifier (::std::move (ident)), type (::std::move (type)), const_expr (::std::move (const_expr)), locus (locus) {} ConstantItem (ConstantItem const &other) : VisItem (other), identifier (other.identifier), type (other.type->clone_type ()), const_expr (other.const_expr->clone_expr ()), locus (other.locus) {} // Destructor - define here if required // Overload assignment operator to clone ConstantItem &operator= (ConstantItem const &other) { VisItem::operator= (other); identifier = other.identifier; type = other.type->clone_type (); const_expr = other.const_expr->clone_expr (); locus = other.locus; return *this; } // move constructors ConstantItem (ConstantItem &&other) = default; ConstantItem &operator= (ConstantItem &&other) = default; /* Returns whether constant item is an "unnamed" (wildcard underscore used * as identifier) constant. */ inline bool is_unnamed () const { return identifier == ::std::string ("_"); } Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual ConstantItem *clone_item_impl () const OVERRIDE { return new ConstantItem (*this); } // Use covariance to implement clone function as returning this object // rather than base virtual ConstantItem *clone_inherent_impl_item_impl () const OVERRIDE { return new ConstantItem (*this); } // Use covariance to implement clone function as returning this object // rather than base virtual ConstantItem *clone_trait_impl_item_impl () const OVERRIDE { return new ConstantItem (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual ConstantItem* clone_statement_impl() const OVERRIDE { return new ConstantItem(*this); }*/ }; // Static item AST node - items within module scope with fixed storage // duration? class StaticItem : public VisItem { bool has_mut; Identifier name; // Type type; ::std::unique_ptr type; // Expr* expr; ::std::unique_ptr expr; Location locus; public: /*~StaticItem() { delete expr; }*/ ::std::string as_string () const; StaticItem (Identifier name, bool is_mut, ::std::unique_ptr type, ::std::unique_ptr expr, Visibility vis, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), has_mut (is_mut), name (::std::move (name)), type (::std::move (type)), expr (::std::move (expr)), locus (locus) {} // Copy constructor with clone StaticItem (StaticItem const &other) : VisItem (other), has_mut (other.has_mut), name (other.name), type (other.type->clone_type ()), expr (other.expr->clone_expr ()), locus (other.locus) {} // Destructor - define here if required // Overloaded assignment operator to clone StaticItem &operator= (StaticItem const &other) { VisItem::operator= (other); name = other.name; has_mut = other.has_mut; type = other.type->clone_type (); expr = other.expr->clone_expr (); locus = other.locus; return *this; } // move constructors StaticItem (StaticItem &&other) = default; StaticItem &operator= (StaticItem &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual StaticItem *clone_item_impl () const OVERRIDE { return new StaticItem (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual StaticItem* clone_statement_impl() const OVERRIDE { return new StaticItem(*this); }*/ }; // Function declaration in traits struct TraitFunctionDecl { private: // TODO: delete and replace with Function decl item? no as no body in this. FunctionQualifiers qualifiers; Identifier function_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_params; // FunctionParams function_params; ::std::vector function_params; // inlined // bool has_return_type; // Type return_type; ::std::unique_ptr return_type; // bool has_where_clause; WhereClause where_clause; // should this store location info? public: // Returns whether function decl has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether function decl has regular parameters. inline bool has_params () const { return !function_params.empty (); } // Returns whether function has return type (otherwise is void). inline bool has_return_type () const { return return_type != NULL; } // Returns whether function has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } // Mega-constructor TraitFunctionDecl ( Identifier function_name, FunctionQualifiers qualifiers, ::std::vector< ::std::unique_ptr > generic_params, ::std::vector function_params, ::std::unique_ptr return_type, WhereClause where_clause) : qualifiers (::std::move (qualifiers)), function_name (::std::move (function_name)), generic_params (::std::move (generic_params)), function_params (::std::move (function_params)), return_type (::std::move (return_type)), where_clause (::std::move (where_clause)) {} // Copy constructor with clone TraitFunctionDecl (TraitFunctionDecl const &other) : qualifiers (other.qualifiers), function_name (other.function_name), /*generic_params(other.generic_params),*/ function_params ( other.function_params), return_type (other.return_type->clone_type ()), where_clause (other.where_clause) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } ~TraitFunctionDecl () = default; // Overloaded assignment operator with clone TraitFunctionDecl &operator= (TraitFunctionDecl const &other) { function_name = other.function_name; qualifiers = other.qualifiers; // generic_params = other.generic_params; function_params = other.function_params; return_type = other.return_type->clone_type (); where_clause = other.where_clause; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors TraitFunctionDecl (TraitFunctionDecl &&other) = default; TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default; ::std::string as_string () const; }; // Actual trait item function declaration within traits class TraitItemFunc : public TraitItem { ::std::vector outer_attrs; TraitFunctionDecl decl; // BlockExpr* block_expr; ::std::unique_ptr block_expr; Location locus; public: /*~TraitItemFunc() { delete block_expr; }*/ // Returns whether function has a definition or is just a declaration. inline bool has_definition () const { return block_expr != NULL; } TraitItemFunc (TraitFunctionDecl decl, ::std::unique_ptr block_expr, ::std::vector outer_attrs, Location locus) : outer_attrs (::std::move (outer_attrs)), decl (::std::move (decl)), block_expr (::std::move (block_expr)), locus (locus) {} // Copy constructor with clone TraitItemFunc (TraitItemFunc const &other) : outer_attrs (other.outer_attrs), decl (other.decl) /*, block_expr(other.block_expr->clone_block_expr())*/, locus (other.locus) { if (other.block_expr != NULL) { block_expr = other.block_expr->clone_block_expr (); } } // Destructor - define here if required // Overloaded assignment operator to clone TraitItemFunc &operator= (TraitItemFunc const &other) { TraitItem::operator= (other); outer_attrs = other.outer_attrs; decl = other.decl; locus = other.locus; if (other.block_expr != NULL) { block_expr = other.block_expr->clone_block_expr (); } return *this; } // move constructors TraitItemFunc (TraitItemFunc &&other) = default; TraitItemFunc &operator= (TraitItemFunc &&other) = default; ::std::string as_string () const; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual TraitItemFunc *clone_trait_item_impl () const { return new TraitItemFunc (*this); } }; // Method declaration within traits struct TraitMethodDecl { private: // TODO: delete and replace with Function decl item? no as no body. FunctionQualifiers qualifiers; Identifier function_name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined SelfParam self_param; // bool has_params; // FunctionParams function_params; ::std::vector function_params; // inlined // bool has_return_type; // Type return_type; ::std::unique_ptr return_type; // bool has_where_clause; WhereClause where_clause; // should this store location info? public: // Returns whether method decl has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether method decl has regular parameters. inline bool has_params () const { return !function_params.empty (); } // Returns whether method has return type (otherwise is void). inline bool has_return_type () const { return return_type != NULL; } // Returns whether method has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } // Mega-constructor TraitMethodDecl ( Identifier function_name, FunctionQualifiers qualifiers, ::std::vector< ::std::unique_ptr > generic_params, SelfParam self_param, ::std::vector function_params, ::std::unique_ptr return_type, WhereClause where_clause) : qualifiers (::std::move (qualifiers)), function_name (::std::move (function_name)), generic_params (::std::move (generic_params)), self_param (::std::move (self_param)), function_params (::std::move (function_params)), return_type (::std::move (return_type)), where_clause (::std::move (where_clause)) {} // Copy constructor with clone TraitMethodDecl (TraitMethodDecl const &other) : qualifiers (other.qualifiers), function_name (other.function_name), /*generic_params(other.generic_params),*/ self_param (other.self_param), function_params (other.function_params), return_type (other.return_type->clone_type ()), where_clause (other.where_clause) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } ~TraitMethodDecl () = default; // Overloaded assignment operator with clone TraitMethodDecl &operator= (TraitMethodDecl const &other) { function_name = other.function_name; qualifiers = other.qualifiers; // generic_params = other.generic_params; self_param = other.self_param; function_params = other.function_params; return_type = other.return_type->clone_type (); where_clause = other.where_clause; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors TraitMethodDecl (TraitMethodDecl &&other) = default; TraitMethodDecl &operator= (TraitMethodDecl &&other) = default; ::std::string as_string () const; }; // Actual trait item method declaration within traits class TraitItemMethod : public TraitItem { ::std::vector outer_attrs; TraitMethodDecl decl; // BlockExpr* block_expr; ::std::unique_ptr block_expr; Location locus; public: /*~TraitItemMethod() { delete block_expr; }*/ // Returns whether method has a definition or is just a declaration. inline bool has_definition () const { return block_expr != NULL; } TraitItemMethod (TraitMethodDecl decl, ::std::unique_ptr block_expr, ::std::vector outer_attrs, Location locus) : outer_attrs (::std::move (outer_attrs)), decl (::std::move (decl)), block_expr (::std::move (block_expr)), locus (locus) {} // Copy constructor with clone TraitItemMethod (TraitItemMethod const &other) : outer_attrs (other.outer_attrs), decl (other.decl), block_expr (other.block_expr->clone_block_expr ()), locus (other.locus) {} // Destructor - define here if required // Overloaded assignment operator to clone TraitItemMethod &operator= (TraitItemMethod const &other) { TraitItem::operator= (other); outer_attrs = other.outer_attrs; decl = other.decl; block_expr = other.block_expr->clone_block_expr (); locus = other.locus; return *this; } // move constructors TraitItemMethod (TraitItemMethod &&other) = default; TraitItemMethod &operator= (TraitItemMethod &&other) = default; ::std::string as_string () const; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual TraitItemMethod *clone_trait_item_impl () const { return new TraitItemMethod (*this); } }; // Constant item within traits class TraitItemConst : public TraitItem { ::std::vector outer_attrs; Identifier name; // Type type; ::std::unique_ptr type; // bool has_expression; // Expr* expr; ::std::unique_ptr expr; Location locus; public: /*~TraitItemConst() { delete expr; }*/ // Whether the constant item has an associated expression. inline bool has_expression () const { return expr != NULL; } TraitItemConst (Identifier name, ::std::unique_ptr type, ::std::unique_ptr expr, ::std::vector outer_attrs, Location locus) : outer_attrs (::std::move (outer_attrs)), name (::std::move (name)), type (::std::move (type)), expr (::std::move (expr)), locus (locus) {} // Copy constructor with clones TraitItemConst (TraitItemConst const &other) : outer_attrs (other.outer_attrs), name (other.name), type (other.type->clone_type ()), expr (other.expr->clone_expr ()), locus (other.locus) {} // Destructor - define here if required // Overloaded assignment operator to clone TraitItemConst &operator= (TraitItemConst const &other) { TraitItem::operator= (other); outer_attrs = other.outer_attrs; name = other.name; type = other.type->clone_type (); expr = other.expr->clone_expr (); locus = other.locus; return *this; } // move constructors TraitItemConst (TraitItemConst &&other) = default; TraitItemConst &operator= (TraitItemConst &&other) = default; ::std::string as_string () const; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual TraitItemConst *clone_trait_item_impl () const { return new TraitItemConst (*this); } }; // Type items within traits class TraitItemType : public TraitItem { ::std::vector outer_attrs; Identifier name; // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; ::std::vector< ::std::unique_ptr > type_param_bounds; // inlined form Location locus; public: // Returns whether trait item type has type param bounds. inline bool has_type_param_bounds () const { return !type_param_bounds.empty (); } TraitItemType ( Identifier name, ::std::vector< ::std::unique_ptr > type_param_bounds, ::std::vector outer_attrs, Location locus) : outer_attrs (::std::move (outer_attrs)), name (::std::move (name)), type_param_bounds (::std::move (type_param_bounds)), locus (locus) {} // Copy constructor with vector clone TraitItemType (TraitItemType const &other) : outer_attrs (other.outer_attrs), name (other.name), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } } // Overloaded assignment operator with vector clone TraitItemType &operator= (TraitItemType const &other) { TraitItem::operator= (other); outer_attrs = other.outer_attrs; name = other.name; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } return *this; } // default move constructors TraitItemType (TraitItemType &&other) = default; TraitItemType &operator= (TraitItemType &&other) = default; ::std::string as_string () const; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Clone function implementation as (not pure) virtual method virtual TraitItemType *clone_trait_item_impl () const { return new TraitItemType (*this); } }; // Macro invocation items within traits - TODO is this approach better or is // making MacroInvocationSemi itself implement TraitItem better? Leaning // toward latter. /*class TraitItemMacroInvoc : public TraitItem { MacroInvocationSemi macro_invoc; public: TraitItemMacroInvoc( MacroInvocationSemi macro_invoc, ::std::vector outer_attrs) : macro_invoc(macro_invoc), TraitItem(outer_attrs) {} };*/ // replaced with MacroInvocationSemi implementing TraitItem // Rust trait item declaration AST node class Trait : public VisItem { bool has_unsafe; Identifier name; // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; ::std::vector< ::std::unique_ptr > type_param_bounds; // inlined form // bool has_where_clause; WhereClause where_clause; // bool has_trait_items; ::std::vector< ::std::unique_ptr > trait_items; Location locus; public: ::std::string as_string () const; // Returns whether trait has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether trait has type parameter bounds. inline bool has_type_param_bounds () const { return !type_param_bounds.empty (); } // Returns whether trait has where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } // Returns whether trait has trait items. inline bool has_trait_items () const { return !trait_items.empty (); } // Mega-constructor Trait (Identifier name, bool is_unsafe, ::std::vector< ::std::unique_ptr > generic_params, ::std::vector< ::std::unique_ptr > type_param_bounds, WhereClause where_clause, ::std::vector< ::std::unique_ptr > trait_items, Visibility vis, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), has_unsafe (is_unsafe), name (::std::move (name)), generic_params (::std::move (generic_params)), type_param_bounds (::std::move (type_param_bounds)), where_clause (::std::move (where_clause)), trait_items (::std::move (trait_items)), locus (locus) {} // Copy constructor with vector clone Trait (Trait const &other) : VisItem (other), has_unsafe (other.has_unsafe), name (other.name), where_clause (other.where_clause), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } // again for type param bounds type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } // again for trait items trait_items.reserve (other.trait_items.size ()); for (const auto &e : other.trait_items) { trait_items.push_back (e->clone_trait_item ()); } } // Overloaded assignment operator with vector clone Trait &operator= (Trait const &other) { VisItem::operator= (other); name = other.name; has_unsafe = other.has_unsafe; where_clause = other.where_clause; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } // again for type param bounds type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) { type_param_bounds.push_back (e->clone_type_param_bound ()); } // again for trait items trait_items.reserve (other.trait_items.size ()); for (const auto &e : other.trait_items) { trait_items.push_back (e->clone_trait_item ()); } return *this; } // default move constructors Trait (Trait &&other) = default; Trait &operator= (Trait &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual Trait *clone_item_impl () const OVERRIDE { return new Trait (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual Trait* clone_statement_impl() const OVERRIDE { return new Trait(*this); }*/ }; // Implementation item declaration AST node - abstract base class class Impl : public VisItem { // must be protected to allow subclasses to access them properly protected: // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // Type trait_type; ::std::unique_ptr trait_type; // bool has_where_clause; WhereClause where_clause; // bool has_inner_attrs; ::std::vector inner_attrs; private: // doesn't really need to be protected as write access probably not needed Location locus; public: // Returns whether impl has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether impl has where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } // Returns whether impl has inner attributes. inline bool has_inner_attrs () const { return !inner_attrs.empty (); } Location get_locus () const { return locus; } protected: // Mega-constructor Impl (::std::vector< ::std::unique_ptr > generic_params, ::std::unique_ptr trait_type, WhereClause where_clause, Visibility vis, ::std::vector inner_attrs, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), generic_params (::std::move (generic_params)), trait_type (::std::move (trait_type)), where_clause (::std::move (where_clause)), inner_attrs (::std::move (inner_attrs)), locus (locus) {} // Copy constructor Impl (Impl const &other) : VisItem (other), /*generic_params(other.generic_params),*/ trait_type ( other.trait_type->clone_type ()), where_clause (other.where_clause), inner_attrs (other.inner_attrs), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } // Destructor - define here if required // Assignment operator overload with cloning Impl &operator= (Impl const &other) { VisItem::operator= (other); // generic_params = other.generic_params; trait_type = other.trait_type->clone_type (); where_clause = other.where_clause; inner_attrs = other.inner_attrs; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors Impl (Impl &&other) = default; Impl &operator= (Impl &&other) = default; }; // Regular "impl foo" impl block declaration AST node class InherentImpl : public Impl { // bool has_impl_items; ::std::vector< ::std::unique_ptr > impl_items; public: ::std::string as_string () const; // Returns whether inherent impl block has inherent impl items. inline bool has_impl_items () const { return !impl_items.empty (); } // Mega-constructor InherentImpl (::std::vector< ::std::unique_ptr > impl_items, ::std::vector< ::std::unique_ptr > generic_params, ::std::unique_ptr trait_type, WhereClause where_clause, Visibility vis, ::std::vector inner_attrs, ::std::vector outer_attrs, Location locus) : Impl (::std::move (generic_params), ::std::move (trait_type), ::std::move (where_clause), ::std::move (vis), ::std::move (inner_attrs), ::std::move (outer_attrs), locus), impl_items (::std::move (impl_items)) {} // Copy constructor with vector clone InherentImpl (InherentImpl const &other) : Impl (other) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? impl_items.reserve (other.impl_items.size ()); for (const auto &e : other.impl_items) { impl_items.push_back (e->clone_inherent_impl_item ()); } } // Overloaded assignment operator with vector clone InherentImpl &operator= (InherentImpl const &other) { Impl::operator= (other); // crappy vector unique pointer clone - TODO is there a better way of // doing this? impl_items.reserve (other.impl_items.size ()); for (const auto &e : other.impl_items) { impl_items.push_back (e->clone_inherent_impl_item ()); } return *this; } // default move constructors InherentImpl (InherentImpl &&other) = default; InherentImpl &operator= (InherentImpl &&other) = default; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual InherentImpl *clone_item_impl () const OVERRIDE { return new InherentImpl (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual InherentImpl* clone_statement_impl() const OVERRIDE { return new InherentImpl(*this); }*/ }; // The "impl footrait for foo" impl block declaration AST node class TraitImpl : public Impl { bool has_unsafe; bool has_exclam; TypePath trait_path; // bool has_impl_items; ::std::vector< ::std::unique_ptr > impl_items; public: ::std::string as_string () const; // Returns whether trait impl has impl items. inline bool has_impl_items () const { return !impl_items.empty (); } // Mega-constructor TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam, ::std::vector< ::std::unique_ptr > impl_items, ::std::vector< ::std::unique_ptr > generic_params, ::std::unique_ptr trait_type, WhereClause where_clause, Visibility vis, ::std::vector inner_attrs, ::std::vector outer_attrs, Location locus) : Impl (::std::move (generic_params), ::std::move (trait_type), ::std::move (where_clause), ::std::move (vis), ::std::move (inner_attrs), ::std::move (outer_attrs), locus), has_unsafe (is_unsafe), has_exclam (has_exclam), trait_path (::std::move (trait_path)), impl_items (::std::move (impl_items)) {} // TODO: constructors with less params // Copy constructor with vector clone TraitImpl (TraitImpl const &other) : Impl (other), has_unsafe (other.has_unsafe), has_exclam (other.has_exclam), trait_path (other.trait_path) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? impl_items.reserve (other.impl_items.size ()); for (const auto &e : other.impl_items) { impl_items.push_back (e->clone_trait_impl_item ()); } } // Overloaded assignment operator with vector clone TraitImpl &operator= (TraitImpl const &other) { Impl::operator= (other); trait_path = other.trait_path; has_unsafe = other.has_unsafe; has_exclam = other.has_exclam; // crappy vector unique pointer clone - TODO is there a better way of // doing this? impl_items.reserve (other.impl_items.size ()); for (const auto &e : other.impl_items) { impl_items.push_back (e->clone_trait_impl_item ()); } return *this; } // move constructors TraitImpl (TraitImpl &&other) = default; TraitImpl &operator= (TraitImpl &&other) = default; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual TraitImpl *clone_item_impl () const OVERRIDE { return new TraitImpl (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual TraitImpl* clone_statement_impl() const OVERRIDE { return new TraitImpl(*this); }*/ }; // Abstract base class for an item used inside an extern block class ExternalItem { // bool has_outer_attrs; ::std::vector outer_attrs; // bool has_visibility; Visibility visibility; Identifier item_name; Location locus; public: virtual ~ExternalItem () {} // Returns whether item has outer attributes. inline bool has_outer_attrs () const { return !outer_attrs.empty (); } // Returns whether item has non-default visibility. inline bool has_visibility () const { return !visibility.is_error (); } // Unique pointer custom clone function ::std::unique_ptr clone_external_item () const { return ::std::unique_ptr (clone_external_item_impl ()); } virtual ::std::string as_string () const; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) = 0; protected: ExternalItem (Identifier item_name, Visibility vis, ::std::vector outer_attrs, Location locus) : outer_attrs (::std::move (outer_attrs)), visibility (::std::move (vis)), item_name (::std::move (item_name)), locus (locus) {} // Copy constructor ExternalItem (ExternalItem const &other) : outer_attrs (other.outer_attrs), visibility (other.visibility), item_name (other.item_name), locus (other.locus) {} // Overloaded assignment operator to clone ExternalItem &operator= (ExternalItem const &other) { item_name = other.item_name; visibility = other.visibility; outer_attrs = other.outer_attrs; locus = other.locus; return *this; } // move constructors ExternalItem (ExternalItem &&other) = default; ExternalItem &operator= (ExternalItem &&other) = default; // Clone function implementation as pure virtual method virtual ExternalItem *clone_external_item_impl () const = 0; // possibly make this public if required ::std::string get_item_name () const { return item_name; } }; // A static item used in an extern block class ExternalStaticItem : public ExternalItem { bool has_mut; // Type item_type; ::std::unique_ptr item_type; public: ExternalStaticItem (Identifier item_name, ::std::unique_ptr item_type, bool is_mut, Visibility vis, ::std::vector outer_attrs, Location locus) : ExternalItem (::std::move (item_name), ::std::move (vis), ::std::move (outer_attrs), locus), has_mut (is_mut), item_type (::std::move (item_type)) {} // Copy constructor ExternalStaticItem (ExternalStaticItem const &other) : ExternalItem (other), has_mut (other.has_mut), item_type (other.item_type->clone_type ()) {} // Destructor - define here if required // Overloaded assignment operator to clone ExternalStaticItem &operator= (ExternalStaticItem const &other) { ExternalItem::operator= (other); item_type = other.item_type->clone_type (); has_mut = other.has_mut; return *this; } // move constructors ExternalStaticItem (ExternalStaticItem &&other) = default; ExternalStaticItem &operator= (ExternalStaticItem &&other) = default; ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual ExternalStaticItem *clone_external_item_impl () const OVERRIDE { return new ExternalStaticItem (*this); } }; // A named function parameter used in external functions struct NamedFunctionParam { private: // bool has_name; // otherwise is _ Identifier name; // TODO: handle wildcard in identifier? // Type param_type; ::std::unique_ptr param_type; // TODO: should this store location data? public: // Returns whether the named function parameter has a name (i.e. name is not // '_'). inline bool has_name () const { return name != "_"; } // Returns whether the named function parameter is in an error state. inline bool is_error () const { // also if identifier is "" but that is probably more costly to compute return param_type == NULL; } // Creates an error state named function parameter. static NamedFunctionParam create_error () { return NamedFunctionParam ("", NULL); } NamedFunctionParam (Identifier name, ::std::unique_ptr param_type) : name (::std::move (name)), param_type (::std::move (param_type)) {} // Copy constructor NamedFunctionParam (NamedFunctionParam const &other) : name (other.name), param_type (other.param_type->clone_type ()) {} ~NamedFunctionParam () = default; // Overloaded assignment operator to clone NamedFunctionParam &operator= (NamedFunctionParam const &other) { name = other.name; param_type = other.param_type->clone_type (); // has_name = other.has_name; return *this; } // move constructors NamedFunctionParam (NamedFunctionParam &&other) = default; NamedFunctionParam &operator= (NamedFunctionParam &&other) = default; ::std::string as_string () const; }; // A function item used in an extern block class ExternalFunctionItem : public ExternalItem { // bool has_generics; // Generics generic_params; ::std::vector< ::std::unique_ptr > generic_params; // inlined // bool has_return_type; // FunctionReturnType return_type; ::std::unique_ptr return_type; // inlined // bool has_where_clause; WhereClause where_clause; ::std::vector function_params; bool has_variadics; public: // Returns whether item has generic parameters. inline bool has_generics () const { return !generic_params.empty (); } // Returns whether item has a return type (otherwise void). inline bool has_return_type () const { return return_type != NULL; } // Returns whether item has a where clause. inline bool has_where_clause () const { return !where_clause.is_empty (); } ExternalFunctionItem ( Identifier item_name, ::std::vector< ::std::unique_ptr > generic_params, ::std::unique_ptr return_type, WhereClause where_clause, ::std::vector function_params, bool has_variadics, Visibility vis, ::std::vector outer_attrs, Location locus) : ExternalItem (::std::move (item_name), ::std::move (vis), ::std::move (outer_attrs), locus), generic_params (::std::move (generic_params)), return_type (::std::move (return_type)), where_clause (::std::move (where_clause)), function_params (::std::move (function_params)), has_variadics (has_variadics) {} // Copy constructor with clone ExternalFunctionItem (ExternalFunctionItem const &other) : ExternalItem (other), /*generic_params(other.generic_params),*/ return_type ( other.return_type->clone_type ()), where_clause (other.where_clause), function_params (other.function_params), has_variadics (other.has_variadics) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } } // Destructor - define here if required // Overloaded assignment operator with clone ExternalFunctionItem &operator= (ExternalFunctionItem const &other) { ExternalItem::operator= (other); // generic_params = other.generic_params; return_type = other.return_type->clone_type (); where_clause = other.where_clause; function_params = other.function_params; has_variadics = other.has_variadics; // crappy vector unique pointer clone - TODO is there a better way of // doing this? generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) { generic_params.push_back (e->clone_generic_param ()); } return *this; } // move constructors ExternalFunctionItem (ExternalFunctionItem &&other) = default; ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default; ::std::string as_string () const; virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual ExternalFunctionItem *clone_external_item_impl () const OVERRIDE { return new ExternalFunctionItem (*this); } }; // An extern block AST node class ExternBlock : public VisItem { // bool has_abi; ::std::string abi; // bool has_inner_attrs; ::std::vector inner_attrs; // bool has_extern_items; ::std::vector< ::std::unique_ptr > extern_items; Location locus; public: ::std::string as_string () const; // Returns whether extern block has inner attributes. inline bool has_inner_attrs () const { return !inner_attrs.empty (); } // Returns whether extern block has extern items. inline bool has_extern_items () const { return !extern_items.empty (); } // Returns whether extern block has ABI name. inline bool has_abi () const { return !abi.empty (); } ExternBlock (::std::string abi, ::std::vector< ::std::unique_ptr > extern_items, Visibility vis, ::std::vector inner_attrs, ::std::vector outer_attrs, Location locus) : VisItem (::std::move (vis), ::std::move (outer_attrs)), abi (::std::move (abi)), inner_attrs (::std::move (inner_attrs)), extern_items (::std::move (extern_items)), locus (locus) {} // Copy constructor with vector clone ExternBlock (ExternBlock const &other) : VisItem (other), abi (other.abi), inner_attrs (other.inner_attrs), locus (other.locus) { // crappy vector unique pointer clone - TODO is there a better way of // doing this? extern_items.reserve (other.extern_items.size ()); for (const auto &e : other.extern_items) { extern_items.push_back (e->clone_external_item ()); } } // Overloaded assignment operator with vector clone ExternBlock &operator= (ExternBlock const &other) { VisItem::operator= (other); abi = other.abi; inner_attrs = other.inner_attrs; locus = other.locus; // crappy vector unique pointer clone - TODO is there a better way of // doing this? extern_items.reserve (other.extern_items.size ()); for (const auto &e : other.extern_items) { extern_items.push_back (e->clone_external_item ()); } return *this; } // move constructors ExternBlock (ExternBlock &&other) = default; ExternBlock &operator= (ExternBlock &&other) = default; Location get_locus () const { return locus; } virtual void accept_vis (ASTVisitor &vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object // rather than base virtual ExternBlock *clone_item_impl () const OVERRIDE { return new ExternBlock (*this); } // Use covariance to implement clone function as returning this object // rather than base /*virtual ExternBlock* clone_statement_impl() const OVERRIDE { return new ExternBlock(*this); }*/ }; // Replaced with forward decls - defined in "rust-macro.h" class MacroItem; class MacroInvocationSemi; class MacroRulesDefinition; } // namespace AST } // namespace Rust #endif