// Copyright (C) 2020-2025 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 // . #ifndef RUST_HIR_ITEM_H #define RUST_HIR_ITEM_H #include "optional.h" #include "rust-abi.h" #include "rust-hir-stmt.h" #include "rust-common.h" #include "rust-hir-visibility.h" #include "rust-hir-generic-param.h" #include "rust-system.h" namespace Rust { namespace HIR { // Rust "item" HIR node (declaration of top-level/module-level allowed stuff) class Item : public Stmt, public WithOuterAttrs { // TODO: should outer attrs be defined here or in each derived class? public: enum class ItemKind { Static, Constant, TypeAlias, Function, UseDeclaration, ExternBlock, ExternCrate, Struct, Union, Enum, EnumItem, // FIXME: ARTHUR: Do we need that? Trait, Impl, Module, }; static std::string item_kind_string (ItemKind kind); virtual ItemKind get_item_kind () const = 0; // Unique pointer custom clone function std::unique_ptr clone_item () const { return std::unique_ptr (clone_item_impl ()); } BaseKind get_hir_kind () override { return Node::BaseKind::ITEM; } std::string as_string () const override; /* Adds crate names to the vector passed by reference, if it can * (polymorphism). */ virtual void add_crate_name (std::vector &names ATTRIBUTE_UNUSED) const {} bool is_item () const override final { return true; } protected: // Constructor Item (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs = AST::AttrVec ()) : Stmt (std::move (mappings)), WithOuterAttrs (std::move (outer_attribs)) {} // Clone function implementation as pure virtual method virtual Item *clone_item_impl () const = 0; /* Save having to specify two clone methods in derived classes by making * statement clone return item clone. Hopefully won't affect performance too * much. */ Item *clone_stmt_impl () const override { return clone_item_impl (); } }; // A type generic parameter (as opposed to a lifetime generic parameter) class TypeParam : public GenericParam { AST::AttrVec outer_attrs; Identifier type_representation; // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; std::vector> type_param_bounds; // inlined form tl::optional> type; location_t locus; public: // Returns whether the type of the type param has been specified. bool has_type () const { return type.has_value (); } // Returns whether the type param has type param bounds. bool has_type_param_bounds () const { return !type_param_bounds.empty (); } // Returns whether the type param has an outer attribute. bool has_outer_attribute () const override { return outer_attrs.size () > 0; } AST::AttrVec &get_outer_attrs () override { return outer_attrs; } TypeParam (Analysis::NodeMapping mappings, Identifier type_representation, location_t locus = UNDEF_LOCATION, std::vector> type_param_bounds = std::vector> (), tl::optional> type = tl::nullopt, AST::AttrVec outer_attrs = std::vector ()); // Copy constructor uses clone TypeParam (TypeParam const &other); // Overloaded assignment operator to clone TypeParam &operator= (TypeParam const &other); // move constructors TypeParam (TypeParam &&other) = default; TypeParam &operator= (TypeParam &&other) = default; std::string as_string () const override; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; Identifier get_type_representation () const { return type_representation; } Type &get_type () { rust_assert (*type); return *type.value (); } Analysis::NodeMapping get_type_mappings () const; std::vector> &get_type_param_bounds (); protected: // Clone function implementation as (not pure) virtual method TypeParam *clone_generic_param_impl () const override { return new TypeParam (*this); } }; /* "where" clause item base. Abstract - use LifetimeWhereClauseItem, * TypeBoundWhereClauseItem */ class WhereClauseItem : public FullVisitable { public: enum ItemType { LIFETIME, TYPE_BOUND, }; 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 (HIRFullVisitor &vis) = 0; virtual Analysis::NodeMapping get_mappings () const = 0; virtual ItemType get_item_type () const = 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; std::vector lifetime_bounds; location_t locus; Analysis::NodeMapping mappings; public: LifetimeWhereClauseItem (Analysis::NodeMapping mappings, Lifetime lifetime, std::vector lifetime_bounds, location_t locus) : lifetime (std::move (lifetime)), lifetime_bounds (std::move (lifetime_bounds)), locus (locus), mappings (std::move (mappings)) {} std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; Lifetime &get_lifetime () { return lifetime; } std::vector &get_lifetime_bounds () { return lifetime_bounds; } Analysis::NodeMapping get_mappings () const override final { return mappings; }; ItemType get_item_type () const override final { return WhereClauseItem::ItemType::LIFETIME; } protected: // Clone function implementation as (not pure) virtual method LifetimeWhereClauseItem *clone_where_clause_item_impl () const override { return new LifetimeWhereClauseItem (*this); } }; // A type bound where clause item class TypeBoundWhereClauseItem : public WhereClauseItem { std::vector for_lifetimes; std::unique_ptr bound_type; std::vector> type_param_bounds; Analysis::NodeMapping mappings; location_t locus; public: // Returns whether the item has ForLifetimes bool has_for_lifetimes () const { return !for_lifetimes.empty (); } // Returns whether the item has type param bounds bool has_type_param_bounds () const { return !type_param_bounds.empty (); } TypeBoundWhereClauseItem ( Analysis::NodeMapping mappings, std::vector for_lifetimes, std::unique_ptr bound_type, std::vector> type_param_bounds, location_t locus); // Copy constructor requires clone TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other); // Overload assignment operator to clone TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other); // move constructors TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default; TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem &&other) = default; location_t get_locus () const { return locus; } std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; std::vector &get_for_lifetimes () { return for_lifetimes; } Type &get_bound_type () { return *bound_type; } std::vector> &get_type_param_bounds (); Analysis::NodeMapping get_mappings () const override final { return mappings; }; ItemType get_item_type () const override final { return WhereClauseItem::ItemType::TYPE_BOUND; } protected: // Clone function implementation as (not pure) virtual method TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override { return new TypeBoundWhereClauseItem (*this); } }; // A where clause struct WhereClause { private: std::vector> where_clause_items; // should this store location info? public: WhereClause (std::vector> where_clause_items) : where_clause_items (std::move (where_clause_items)) {} // copy constructor with vector clone WhereClause (WhereClause const &other) { 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) { 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> ()); } // Returns whether the WhereClause has no items. bool is_empty () const { return where_clause_items.empty (); } std::string as_string () const; std::vector> &get_items () { return where_clause_items; } const std::vector> &get_items () const { return where_clause_items; } }; // A self parameter in a method struct SelfParam { public: enum ImplicitSelfKind { IMM, // self MUT, // mut self IMM_REF, // &self MUT_REF, // &mut self NONE }; private: ImplicitSelfKind self_kind; Lifetime lifetime; std::unique_ptr type; location_t locus; Analysis::NodeMapping mappings; SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind, Lifetime lifetime, Type *type); public: // Type-based self parameter (not ref, no lifetime) SelfParam (Analysis::NodeMapping mappings, std::unique_ptr type, bool is_mut, location_t locus); // Lifetime-based self parameter (is ref, no type) SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool is_mut, location_t locus); // Copy constructor requires clone SelfParam (SelfParam const &other); // Overload assignment operator to use clone SelfParam &operator= (SelfParam const &other); // move constructors SelfParam (SelfParam &&other) = default; SelfParam &operator= (SelfParam &&other) = default; static SelfParam error () { return SelfParam (Analysis::NodeMapping::get_error (), ImplicitSelfKind::NONE, Lifetime::error (), nullptr); } // Returns whether the self-param has a type field. bool has_type () const { return type != nullptr; } // Returns whether the self-param has a valid lifetime. bool has_lifetime () const { return !lifetime.is_error (); } const Lifetime &get_lifetime () const { return lifetime; } // Returns whether the self-param is in an error state. bool is_error () const { return self_kind == ImplicitSelfKind::NONE; } std::string as_string () const; location_t get_locus () const { return locus; } ImplicitSelfKind get_self_kind () const { return self_kind; } Type &get_type () { rust_assert (type); return *type; } Analysis::NodeMapping get_mappings () { return mappings; } Mutability get_mut () const; bool is_mut () const; bool is_ref () const; }; // Qualifiers for function, i.e. const, unsafe, extern etc. struct FunctionQualifiers { private: Async async_status; Const const_status; Unsafety unsafety; bool has_extern; ABI abi; public: FunctionQualifiers (Async async_status, Const const_status, Unsafety unsafety, bool has_extern, ABI abi) : async_status (async_status), const_status (const_status), unsafety (unsafety), has_extern (has_extern), abi (abi) {} std::string as_string () const; Const get_const_status () const { return const_status; } bool is_const () const { return const_status == Const::Yes; } bool is_unsafe () const { return unsafety == Unsafety::Unsafe; } bool is_async () const { return async_status == Async::Yes; } ABI get_abi () const { return abi; } }; // A function parameter struct FunctionParam { std::unique_ptr param_name; std::unique_ptr type; location_t locus; Analysis::NodeMapping mappings; public: FunctionParam (Analysis::NodeMapping mappings, std::unique_ptr param_name, std::unique_ptr param_type, location_t locus); // Copy constructor uses clone FunctionParam (FunctionParam const &other); // Overload assignment operator to use clone FunctionParam &operator= (FunctionParam const &other); // move constructors FunctionParam (FunctionParam &&other) = default; FunctionParam &operator= (FunctionParam &&other) = default; std::string as_string () const; location_t get_locus () const { return locus; } Pattern &get_param_name () { return *param_name; } Type &get_type () { rust_assert (type); return *type; } const Analysis::NodeMapping &get_mappings () const { return mappings; } }; // Item that supports visibility - abstract base class class VisItem : public Item { Visibility visibility; protected: // Visibility constructor VisItem (Analysis::NodeMapping mappings, Visibility visibility, AST::AttrVec outer_attrs = AST::AttrVec ()) : Item (std::move (mappings), std::move (outer_attrs)), visibility (std::move (visibility)) {} // Visibility copy constructor VisItem (VisItem const &other); // Overload assignment operator to clone VisItem &operator= (VisItem const &other); // move constructors VisItem (VisItem &&other) = default; VisItem &operator= (VisItem &&other) = default; public: using HIR::Stmt::accept_vis; BaseKind get_hir_kind () override final { return VIS_ITEM; } /* Does the item have some kind of public visibility (non-default * visibility)? */ bool has_visibility () const { return !visibility.is_error (); } virtual void accept_vis (HIRVisItemVisitor &vis) = 0; Visibility &get_visibility () { return visibility; } const Visibility &get_visibility () const { return visibility; } std::string as_string () const override; }; // Rust module item - abstract base class class Module : public VisItem, public WithInnerAttrs { Identifier module_name; location_t locus; // bool has_items; std::vector> items; public: std::string as_string () const override; // Returns whether the module has items in its body. bool has_items () const { return !items.empty (); } // Full constructor Module (Analysis::NodeMapping mappings, Identifier module_name, location_t locus, std::vector> items, Visibility visibility = Visibility::create_error (), AST::AttrVec inner_attrs = AST::AttrVec (), AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor with vector clone Module (Module const &other); // Overloaded assignment operator with vector clone Module &operator= (Module const &other); // move constructors Module (Module &&other) = default; Module &operator= (Module &&other) = default; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; Identifier get_module_name () const { return module_name; } std::vector> &get_items () { return items; }; /* Override that runs the function recursively on all items contained within * the module. */ void add_crate_name (std::vector &names) const override; location_t get_locus () const override final { return locus; } ItemKind get_item_kind () const override { return ItemKind::Module; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ Module *clone_item_impl () const override { return new Module (*this); } /* Use covariance to implement clone function as returning this object * rather than base */ /*virtual Module* clone_statement_impl() const override { return new Module(*this); }*/ }; // Rust extern crate declaration HIR 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_t locus; /* e.g. "extern crate foo as _" "extern crate foo" "extern crate std as cool_std" */ public: std::string as_string () const override; // Returns whether extern crate declaration has an as clause. bool has_as_clause () const { return !as_clause_name.empty (); } /* Returns whether extern crate declaration references the current crate * (i.e. self). */ bool references_self () const { return referenced_crate == "self"; } // Constructor ExternCrate (Analysis::NodeMapping mappings, std::string referenced_crate, Visibility visibility, AST::AttrVec outer_attrs, location_t locus, std::string as_clause_name = std::string ()) : VisItem (std::move (mappings), std::move (visibility), std::move (outer_attrs)), referenced_crate (std::move (referenced_crate)), as_clause_name (std::move (as_clause_name)), locus (locus) {} location_t get_locus () const override final { return locus; } ItemKind get_item_kind () const override { return ItemKind::ExternCrate; } std::string get_referenced_crate () { return referenced_crate; } std::string get_as_clause_name () { return as_clause_name; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; // Override that adds extern crate name in decl to passed list of names. void add_crate_name (std::vector &names) const override { names.push_back (referenced_crate); } protected: /* Use covariance to implement clone function as returning this object * rather than base */ 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 : public FullVisitable { location_t 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_t get_locus () const { return locus; } protected: // Clone function implementation as pure virtual method virtual UseTree *clone_use_tree_impl () const = 0; UseTree (location_t 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; AST::SimplePath path; public: UseTreeGlob (PathType glob_type, AST::SimplePath path, location_t locus) : UseTree (locus), glob_type (glob_type), path (std::move (path)) { if (this->glob_type != PATH_PREFIXED) { // compiler implementation error if there is a path with a // non-path-prefixed use tree glob gcc_assert (!has_path ()); } // TODO: do path-prefixed paths also have to have a path? If so, have an // assert for that too. } /* Returns whether has path. Should be made redundant by PathType * PATH_PREFIXED. */ bool has_path () const { return !path.is_empty (); } PathType get_glob_type () { return glob_type; } AST::SimplePath get_path () { return path; }; std::string as_string () const override; void accept_vis (HIRFullVisitor &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 */ 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; AST::SimplePath path; std::vector> trees; public: UseTreeList (PathType path_type, AST::SimplePath path, std::vector> trees, location_t locus) : UseTree (locus), path_type (path_type), path (std::move (path)), trees (std::move (trees)) { if (this->path_type != PATH_PREFIXED) { // compiler implementation error if there is a path with a // non-path-prefixed use tree glob gcc_assert (!has_path ()); } // TODO: do path-prefixed paths also have to have a path? If so, have an // assert for that too. } // copy constructor with vector clone UseTreeList (UseTreeList const &other) : UseTree (other), path_type (other.path_type), path (other.path) { 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; 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. bool has_path () const { return !path.is_empty (); } // Returns whether has inner tree elements. bool has_trees () const { return !trees.empty (); } std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; PathType get_path_type () { return path_type; } AST::SimplePath get_path () { return path; } std::vector> &get_trees () { return trees; } // 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 */ 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: AST::SimplePath path; NewBindType bind_type; Identifier identifier; // only if NewBindType is IDENTIFIER public: UseTreeRebind (NewBindType bind_type, AST::SimplePath path, location_t 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). bool has_path () const { return !path.is_empty (); } AST::SimplePath get_path () { return path; } Identifier get_identifier () const { return identifier; } NewBindType get_bind_type () const { return bind_type; } // Returns whether has identifier (or, rather, is allowed to). bool has_identifier () const { return bind_type == IDENTIFIER; } std::string as_string () const override; void accept_vis (HIRFullVisitor &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); } }; std::string enum_to_str (UseTreeRebind::NewBindType); // Rust use declaration (i.e. for modules) HIR node class UseDeclaration : public VisItem { std::unique_ptr use_tree; location_t locus; public: std::string as_string () const override; UseDeclaration (Analysis::NodeMapping mappings, std::unique_ptr use_tree, Visibility visibility, AST::AttrVec outer_attrs, location_t locus) : VisItem (std::move (mappings), 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) {} // 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_t get_locus () const override final { return locus; } ItemKind get_item_kind () const override { return ItemKind::UseDeclaration; } UseTree &get_use_tree () { return *use_tree; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; protected: /* Use covariance to implement clone function as returning this object * rather than base */ 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); }*/ }; class LetStmt; // Rust function declaration HIR node class Function : public VisItem, public ImplItem { FunctionQualifiers qualifiers; Identifier function_name; std::vector> generic_params; std::vector function_params; std::unique_ptr return_type; WhereClause where_clause; std::unique_ptr function_body; SelfParam self; location_t locus; public: std::string as_string () const override; // Returns whether function has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether function has regular parameters. bool has_function_params () const { return !function_params.empty (); } // Returns whether function has return type - if not, it is void. bool has_function_return_type () const { return return_type != nullptr; } // Returns whether function has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } ImplItemType get_impl_item_type () const override final { return ImplItem::ImplItemType::FUNCTION; } ItemKind get_item_kind () const override { return ItemKind::Function; } // Mega-constructor with all possible fields Function (Analysis::NodeMapping mappings, Identifier function_name, FunctionQualifiers qualifiers, std::vector> generic_params, std::vector function_params, std::unique_ptr return_type, WhereClause where_clause, std::unique_ptr function_body, Visibility vis, AST::AttrVec outer_attrs, SelfParam self, location_t locus); // Copy constructor with clone Function (Function const &other); // Overloaded assignment operator to clone Function &operator= (Function const &other); // move constructors Function (Function &&other) = default; Function &operator= (Function &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRImplVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; Analysis::NodeMapping get_impl_mappings () const override { return get_mappings (); }; std::vector &get_function_params () { return function_params; } const std::vector &get_function_params () const { return function_params; } std::vector> &get_generic_params () { return generic_params; } const std::vector> &get_generic_params () const { return generic_params; } // TODO: is this better? Or is a "vis_block" better? BlockExpr &get_definition () { return *function_body; } const FunctionQualifiers &get_qualifiers () const { return qualifiers; } Identifier get_function_name () const { return function_name; } // TODO: is this better? Or is a "vis_block" better? WhereClause &get_where_clause () { return where_clause; } bool has_return_type () const { return return_type != nullptr; } // TODO: is this better? Or is a "vis_block" better? Type &get_return_type () { return *return_type; } bool is_method () const { return !self.is_error (); } SelfParam &get_self_param () { return self; } std::string get_impl_item_name () const override final { return get_function_name ().as_string (); } protected: /* Use covariance to implement clone function as returning this object * rather than base */ Function *clone_item_impl () const override { return new Function (*this); } /* Use covariance to implement clone function as returning this object * rather than base */ Function *clone_inherent_impl_item_impl () const override { return new Function (*this); } }; // Rust type alias (i.e. typedef) HIR node class TypeAlias : public VisItem, public ImplItem { Identifier new_type_name; // bool has_generics; // Generics generic_params; std::vector> generic_params; // inlined // bool has_where_clause; WhereClause where_clause; std::unique_ptr existing_type; location_t locus; public: std::string as_string () const override; // Returns whether type alias has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether type alias has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } ImplItemType get_impl_item_type () const override final { return ImplItem::ImplItemType::TYPE_ALIAS; } // Mega-constructor with all possible fields TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name, std::vector> generic_params, WhereClause where_clause, std::unique_ptr existing_type, Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor TypeAlias (TypeAlias const &other); // Overloaded assignment operator to clone TypeAlias &operator= (TypeAlias const &other); // move constructors TypeAlias (TypeAlias &&other) = default; TypeAlias &operator= (TypeAlias &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRImplVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector> &get_generic_params () { return generic_params; } const std::vector> &get_generic_params () const { return generic_params; } WhereClause &get_where_clause () { return where_clause; } Type &get_type_aliased () { rust_assert (existing_type); return *existing_type; } Identifier get_new_type_name () const { return new_type_name; } ItemKind get_item_kind () const override { return ItemKind::TypeAlias; } Analysis::NodeMapping get_impl_mappings () const override { return get_mappings (); }; std::string get_impl_item_name () const override final { return get_new_type_name ().as_string (); } protected: /* Use covariance to implement clone function as returning this object * rather than base */ TypeAlias *clone_item_impl () const override { return new TypeAlias (*this); } /* Use covariance to implement clone function as returning this object * rather than base */ TypeAlias *clone_inherent_impl_item_impl () const override { return new TypeAlias (*this); } }; // Rust base struct declaration HIR 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> generic_params; // inlined // bool has_where_clause; WhereClause where_clause; location_t locus; public: Identifier get_identifier () const { return struct_name; } // Returns whether struct has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether struct has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } location_t get_locus () const override final { return locus; } ItemKind get_item_kind () const override { return ItemKind::Struct; } std::vector> &get_generic_params () { return generic_params; } WhereClause &get_where_clause () { return where_clause; } protected: Struct (Analysis::NodeMapping mappings, Identifier struct_name, std::vector> generic_params, WhereClause where_clause, Visibility vis, location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ()) : VisItem (std::move (mappings), 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) { 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; 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 // FIXME can't this be a TupleStruct + field_name? class StructField { public: // bool has_outer_attributes; AST::AttrVec outer_attrs; // bool has_visibility; Visibility visibility; Identifier field_name; std::unique_ptr field_type; Analysis::NodeMapping mappings; location_t locus; // Returns whether struct field has any outer attributes. bool has_outer_attributes () const { return !outer_attrs.empty (); } // Returns whether struct field has a non-private (non-default) visibility. bool has_visibility () const { return !visibility.is_error (); } StructField (Analysis::NodeMapping mappings, Identifier field_name, std::unique_ptr field_type, Visibility vis, location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor StructField (StructField const &other); ~StructField () = default; // Overloaded assignment operator to clone StructField &operator= (StructField const &other); // move constructors StructField (StructField &&other) = default; StructField &operator= (StructField &&other) = default; std::string as_string () const; Identifier get_field_name () const { return field_name; } Type &get_field_type () { return *field_type; } Analysis::NodeMapping get_mappings () const { return mappings; } location_t get_locus () { return locus; } AST::AttrVec &get_outer_attrs () { return outer_attrs; } Visibility &get_visibility () { return visibility; } }; // Rust struct declaration with true struct type HIR node class StructStruct : public Struct { public: std::vector fields; bool is_unit; std::string as_string () const override; // Mega-constructor with all possible fields StructStruct (Analysis::NodeMapping mappings, std::vector fields, Identifier struct_name, std::vector> generic_params, WhereClause where_clause, bool is_unit, Visibility vis, AST::AttrVec outer_attrs, location_t locus) : Struct (std::move (mappings), 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 (Analysis::NodeMapping mappings, Identifier struct_name, std::vector> generic_params, WhereClause where_clause, Visibility vis, AST::AttrVec outer_attrs, location_t locus) : Struct (std::move (mappings), 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. */ bool is_unit_struct () const { return is_unit; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector &get_fields () { return fields; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ 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 class TupleField { private: // bool has_outer_attributes; AST::AttrVec outer_attrs; // bool has_visibility; Visibility visibility; std::unique_ptr field_type; location_t locus; Analysis::NodeMapping mappings; public: // Returns whether tuple field has outer attributes. bool has_outer_attributes () const { return !outer_attrs.empty (); } /* Returns whether tuple field has a non-default visibility (i.e. a public * one) */ bool has_visibility () const { return !visibility.is_error (); } // Complete constructor TupleField (Analysis::NodeMapping mapping, std::unique_ptr field_type, Visibility vis, location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor with clone TupleField (TupleField const &other); ~TupleField () = default; // Overloaded assignment operator to clone TupleField &operator= (TupleField const &other); // move constructors TupleField (TupleField &&other) = default; TupleField &operator= (TupleField &&other) = default; // Returns whether tuple field is in an error state. bool is_error () const { return field_type == nullptr; } std::string as_string () const; Analysis::NodeMapping get_mappings () const { return mappings; } Visibility &get_visibility () { return visibility; } location_t get_locus () const { return locus; } AST::AttrVec &get_outer_attrs () { return outer_attrs; } HIR::Type &get_field_type () { return *field_type; } }; // Rust tuple declared using struct keyword HIR node class TupleStruct : public Struct { std::vector fields; public: std::string as_string () const override; // Mega-constructor with all possible fields TupleStruct (Analysis::NodeMapping mappings, std::vector fields, Identifier struct_name, std::vector> generic_params, WhereClause where_clause, Visibility vis, AST::AttrVec outer_attrs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector &get_fields () { return fields; } const std::vector &get_fields () const { return fields; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ 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. Syntactically EnumItem's can have a Visibility. But not Semantically. So check there is no Visibility when lowering and make this an Item, not an VisItem. */ class EnumItem : public Item { Identifier variant_name; location_t locus; public: virtual ~EnumItem () {} enum EnumItemKind { Named, Tuple, Struct, Discriminant, }; EnumItem (Analysis::NodeMapping mappings, Identifier variant_name, AST::AttrVec outer_attrs, location_t locus); // Unique pointer custom clone function std::unique_ptr clone_enum_item () const { return std::unique_ptr (clone_item_impl ()); } virtual std::string as_string () const override; virtual EnumItemKind get_enum_item_kind () const { return Named; }; // not pure virtual as not abstract void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; // void accept_vis (HIRVisItemVisitor &vis) override; location_t get_locus () const override { return locus; } Identifier get_identifier () const { return variant_name; } ItemKind get_item_kind () const override { return ItemKind::EnumItem; } protected: EnumItem *clone_item_impl () const override { 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. bool has_tuple_fields () const { return !tuple_fields.empty (); } EnumItemKind get_enum_item_kind () const override { return EnumItemKind::Tuple; } EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name, std::vector tuple_fields, AST::AttrVec outer_attrs, location_t locus); std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; std::vector &get_tuple_fields () { return tuple_fields; } protected: // Clone function implementation as (not pure) virtual method EnumItemTuple *clone_item_impl () const override { 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. bool has_struct_fields () const { return !struct_fields.empty (); } EnumItemKind get_enum_item_kind () const override { return EnumItemKind::Struct; } EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name, std::vector struct_fields, AST::AttrVec outer_attrs, location_t locus); std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; std::vector &get_struct_fields () { return struct_fields; } protected: // Clone function implementation as (not pure) virtual method EnumItemStruct *clone_item_impl () const override { return new EnumItemStruct (*this); } }; // A discriminant (numbered enum) item used in an "enum" tagged union class EnumItemDiscriminant : public EnumItem { std::unique_ptr expression; public: EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name, std::unique_ptr expr, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone EnumItemDiscriminant (EnumItemDiscriminant const &other); // Overloaded assignment operator to clone EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other); // move constructors EnumItemDiscriminant (EnumItemDiscriminant &&other) = default; EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default; EnumItemKind get_enum_item_kind () const override { return EnumItemKind::Discriminant; } std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; Expr &get_discriminant_expression () { return *expression; } std::unique_ptr take_discriminant_expression () { return std::move (expression); } protected: // Clone function implementation as (not pure) virtual method EnumItemDiscriminant *clone_item_impl () const override { return new EnumItemDiscriminant (*this); } }; // HIR node for Rust "enum" - tagged union class Enum : public VisItem { Identifier enum_name; // bool has_generics; // Generics generic_params; std::vector> generic_params; // inlined // bool has_where_clause; WhereClause where_clause; std::vector> items; location_t locus; public: std::string as_string () const override; // Returns whether "enum" has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether "enum" has a where clause. 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. */ bool is_zero_variant () const { return items.empty (); } // Mega-constructor Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis, std::vector> generic_params, WhereClause where_clause, std::vector> items, AST::AttrVec outer_attrs, location_t locus); // TODO: constructor with less arguments // Copy constructor with vector clone Enum (Enum const &other); // Overloaded assignment operator with vector clone Enum &operator= (Enum const &other); // Move constructors Enum (Enum &&other) = default; Enum &operator= (Enum &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; Identifier get_identifier () const { return enum_name; } ItemKind get_item_kind () const override { return ItemKind::Enum; } std::vector> &get_generic_params () { return generic_params; } const std::vector> &get_variants () const { return items; } std::vector> &get_variants () { return items; } WhereClause &get_where_clause () { return where_clause; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ 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 HIR node class Union : public VisItem { Identifier union_name; // bool has_generics; // Generics generic_params; std::vector> generic_params; // inlined // bool has_where_clause; WhereClause where_clause; std::vector variants; location_t locus; public: std::string as_string () const override; // Returns whether union has generic params. bool has_generics () const { return !generic_params.empty (); } // Returns whether union has where clause. bool has_where_clause () const { return !where_clause.is_empty (); } Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis, std::vector> generic_params, WhereClause where_clause, std::vector variants, AST::AttrVec outer_attrs, location_t locus); // copy constructor with vector clone Union (Union const &other); // overloaded assignment operator with vector clone Union &operator= (Union const &other); // move constructors Union (Union &&other) = default; Union &operator= (Union &&other) = default; std::vector> &get_generic_params () { return generic_params; } Identifier get_identifier () const { return union_name; } location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector &get_variants () { return variants; } WhereClause &get_where_clause () { return where_clause; } ItemKind get_item_kind () const override { return ItemKind::Union; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ Union *clone_item_impl () const override { return new Union (*this); } }; class ConstantItem : public VisItem, public ImplItem { Identifier identifier; std::unique_ptr type; std::unique_ptr const_expr; location_t locus; public: std::string as_string () const override; ConstantItem (Analysis::NodeMapping mappings, Identifier ident, Visibility vis, std::unique_ptr type, std::unique_ptr const_expr, AST::AttrVec outer_attrs, location_t locus); ConstantItem (ConstantItem const &other); // Overload assignment operator to clone ConstantItem &operator= (ConstantItem const &other); // move constructors ConstantItem (ConstantItem &&other) = default; ConstantItem &operator= (ConstantItem &&other) = default; // Returns whether constant item is an "unnamed" (wildcard underscore used // as identifier) constant. bool is_unnamed () const { return identifier.as_string () == std::string ("_"); } location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRImplVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; Type &get_type () { rust_assert (type); return *type; } Expr &get_expr () { return *const_expr; } Identifier get_identifier () const { return identifier; } Analysis::NodeMapping get_impl_mappings () const override { return get_mappings (); }; ImplItemType get_impl_item_type () const override final { return ImplItem::ImplItemType::CONSTANT; } ItemKind get_item_kind () const override { return ItemKind::Constant; } std::string get_impl_item_name () const override final { return get_identifier ().as_string (); } protected: /* Use covariance to implement clone function as returning this object * rather than base */ ConstantItem *clone_item_impl () const override { return new ConstantItem (*this); } /* Use covariance to implement clone function as returning this object * rather than base */ ConstantItem *clone_inherent_impl_item_impl () const override { return new ConstantItem (*this); } }; /* Static item HIR node - items within module scope with fixed storage * duration? */ class StaticItem : public VisItem { Mutability mut; Identifier name; std::unique_ptr type; std::unique_ptr expr; location_t locus; public: std::string as_string () const override; StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut, std::unique_ptr type, std::unique_ptr expr, Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone StaticItem (StaticItem const &other); // Overloaded assignment operator to clone StaticItem &operator= (StaticItem const &other); // move constructors StaticItem (StaticItem &&other) = default; StaticItem &operator= (StaticItem &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; Identifier get_identifier () const { return name; } Mutability get_mut () const { return mut; } bool is_mut () const { return mut == Mutability::Mut; } Expr &get_expr () { rust_assert (expr); return *expr; } Type &get_type () { rust_assert (type); return *type; } ItemKind get_item_kind () const override { return ItemKind::Static; } protected: StaticItem *clone_item_impl () const override { return new StaticItem (*this); } }; // Function declaration in traits class TraitFunctionDecl { private: FunctionQualifiers qualifiers; Identifier function_name; std::vector> generic_params; std::vector function_params; std::unique_ptr return_type; WhereClause where_clause; SelfParam self; public: // Mega-constructor TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers, std::vector> generic_params, SelfParam self, std::vector function_params, std::unique_ptr return_type, WhereClause where_clause); // Copy constructor with clone TraitFunctionDecl (TraitFunctionDecl const &other); ~TraitFunctionDecl () = default; // Overloaded assignment operator with clone TraitFunctionDecl &operator= (TraitFunctionDecl const &other); // move constructors TraitFunctionDecl (TraitFunctionDecl &&other) = default; TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default; std::string as_string () const; // Returns whether function decl has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether function decl has regular parameters. bool has_params () const { return !function_params.empty (); } // Returns whether function has return type (otherwise is void). bool has_return_type () const { return return_type != nullptr; } // Returns whether function has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } WhereClause &get_where_clause () { return where_clause; } bool is_method () const { return !self.is_error (); } SelfParam &get_self () { return self; } Identifier get_function_name () const { return function_name; } std::vector> &get_generic_params () { return generic_params; } Type &get_return_type () { return *return_type; } std::vector &get_function_params () { return function_params; } const FunctionQualifiers &get_qualifiers () const { return qualifiers; } }; // Actual trait item function declaration within traits class TraitItemFunc : public TraitItem { AST::AttrVec outer_attrs; TraitFunctionDecl decl; std::unique_ptr block_expr; location_t locus; public: // Returns whether function has a definition or is just a declaration. bool has_definition () const { return block_expr != nullptr; } TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl, std::unique_ptr block_expr, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone TraitItemFunc (TraitItemFunc const &other); // Overloaded assignment operator to clone TraitItemFunc &operator= (TraitItemFunc const &other); // move constructors TraitItemFunc (TraitItemFunc &&other) = default; TraitItemFunc &operator= (TraitItemFunc &&other) = default; std::string as_string () const override; location_t get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTraitItemVisitor &vis) override; TraitFunctionDecl &get_decl () { return decl; } const TraitFunctionDecl &get_decl () const { return decl; } BlockExpr &get_block_expr () { return *block_expr; } const std::string trait_identifier () const override final { return decl.get_function_name ().as_string (); } TraitItemKind get_item_kind () const override final { return TraitItemKind::FUNC; } AST::AttrVec &get_outer_attrs () override final { return outer_attrs; } const AST::AttrVec &get_outer_attrs () const override final { return outer_attrs; } location_t get_trait_locus () const override { return get_locus (); } protected: // Clone function implementation as (not pure) virtual method TraitItemFunc *clone_trait_item_impl () const override { return new TraitItemFunc (*this); } }; // Constant item within traits class TraitItemConst : public TraitItem { AST::AttrVec outer_attrs; Identifier name; std::unique_ptr type; std::unique_ptr expr; location_t locus; public: // Whether the constant item has an associated expression. bool has_expression () const { return expr != nullptr; } TraitItemConst (Analysis::NodeMapping mappings, Identifier name, std::unique_ptr type, std::unique_ptr expr, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clones TraitItemConst (TraitItemConst const &other); // Overloaded assignment operator to clone TraitItemConst &operator= (TraitItemConst const &other); // move constructors TraitItemConst (TraitItemConst &&other) = default; TraitItemConst &operator= (TraitItemConst &&other) = default; std::string as_string () const override; location_t get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTraitItemVisitor &vis) override; Identifier get_name () const { return name; } bool has_expr () const { return expr != nullptr; } Type &get_type () { rust_assert (type); return *type; } Expr &get_expr () { rust_assert (expr); return *expr; } const std::string trait_identifier () const override final { return name.as_string (); } TraitItemKind get_item_kind () const override final { return TraitItemKind::CONST; } AST::AttrVec &get_outer_attrs () override final { return outer_attrs; } const AST::AttrVec &get_outer_attrs () const override final { return outer_attrs; } location_t get_trait_locus () const override { return get_locus (); } protected: // Clone function implementation as (not pure) virtual method TraitItemConst *clone_trait_item_impl () const override { return new TraitItemConst (*this); } }; // Type items within traits class TraitItemType : public TraitItem { AST::AttrVec outer_attrs; Identifier name; std::vector> type_param_bounds; // inlined form location_t locus; public: // Returns whether trait item type has type param bounds. bool has_type_param_bounds () const { return !type_param_bounds.empty (); } TraitItemType (Analysis::NodeMapping mappings, Identifier name, std::vector> type_param_bounds, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with vector clone TraitItemType (TraitItemType const &other); // Overloaded assignment operator with vector clone TraitItemType &operator= (TraitItemType const &other); // default move constructors TraitItemType (TraitItemType &&other) = default; TraitItemType &operator= (TraitItemType &&other) = default; std::string as_string () const override; location_t get_locus () const { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTraitItemVisitor &vis) override; Identifier get_name () const { return name; } std::vector> &get_type_param_bounds () { return type_param_bounds; } const std::string trait_identifier () const override final { return name.as_string (); } TraitItemKind get_item_kind () const override final { return TraitItemKind::TYPE; } AST::AttrVec &get_outer_attrs () override final { return outer_attrs; } const AST::AttrVec &get_outer_attrs () const override final { return outer_attrs; } location_t get_trait_locus () const override { return get_locus (); } protected: // Clone function implementation as (not pure) virtual method TraitItemType *clone_trait_item_impl () const override { return new TraitItemType (*this); } }; // Rust trait item declaration HIR node class Trait : public VisItem { Unsafety unsafety; Identifier name; std::vector> generic_params; std::vector> type_param_bounds; WhereClause where_clause; std::vector> trait_items; location_t locus; public: std::string as_string () const override; // Returns whether trait has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether trait has type parameter bounds. bool has_type_param_bounds () const { return !type_param_bounds.empty (); } // Returns whether trait has where clause. bool has_where_clause () const { return !where_clause.is_empty (); } // Returns whether trait has trait items. bool has_trait_items () const { return !trait_items.empty (); } std::vector> &get_trait_items () { return trait_items; } WhereClause &get_where_clause () { return where_clause; } Identifier get_name () const { return name; } bool is_unsafe () const { return unsafety == Unsafety::Unsafe; } // Mega-constructor Trait (Analysis::NodeMapping mappings, Identifier name, Unsafety unsafety, std::vector> generic_params, std::vector> type_param_bounds, WhereClause where_clause, std::vector> trait_items, Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with vector clone Trait (Trait const &other); // Overloaded assignment operator with vector clone Trait &operator= (Trait const &other); // default move constructors Trait (Trait &&other) = default; Trait &operator= (Trait &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector> &get_generic_params () { return generic_params; } const std::vector> &get_generic_params () const { return generic_params; } std::vector> &get_type_param_bounds () { return type_param_bounds; } const std::vector> & get_type_param_bounds () const { return type_param_bounds; } ItemKind get_item_kind () const override { return ItemKind::Trait; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ Trait *clone_item_impl () const override { return new Trait (*this); } }; class ImplBlock : public VisItem, public WithInnerAttrs { std::vector> generic_params; std::unique_ptr impl_type; std::unique_ptr trait_ref; WhereClause where_clause; BoundPolarity polarity; location_t locus; std::vector> impl_items; bool unsafe; public: ImplBlock (Analysis::NodeMapping mappings, std::vector> impl_items, std::vector> generic_params, std::unique_ptr impl_type, std::unique_ptr trait_ref, WhereClause where_clause, BoundPolarity polarity, Visibility vis, AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, location_t locus, bool unsafe = false); ImplBlock (ImplBlock const &other); ImplBlock &operator= (ImplBlock const &other); ImplBlock (ImplBlock &&other) = default; ImplBlock &operator= (ImplBlock &&other) = default; std::string as_string () const override; // Returns whether inherent impl block has inherent impl items. bool has_impl_items () const { return !impl_items.empty (); } bool is_unsafe () const { return unsafe; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector> &get_impl_items () { return impl_items; }; const std::vector> &get_impl_items () const { return impl_items; }; // Returns whether impl has generic parameters. bool has_generics () const { return !generic_params.empty (); } // Returns whether impl has where clause. bool has_where_clause () const { return !where_clause.is_empty (); } // Returns the polarity of the impl. BoundPolarity get_polarity () const { return polarity; } location_t get_locus () const override final { return locus; } Type &get_type () { rust_assert (impl_type); return *impl_type; }; bool has_type () { return impl_type != nullptr; } std::vector> &get_generic_params () { return generic_params; } bool has_trait_ref () const { return trait_ref != nullptr; } TypePath &get_trait_ref () { return *trait_ref; } WhereClause &get_where_clause () { return where_clause; } ItemKind get_item_kind () const override { return ItemKind::Impl; } protected: ImplBlock *clone_item_impl () const override { return new ImplBlock (*this); } }; // Abstract base class for an item used inside an extern block class ExternalItem : public Node { Analysis::NodeMapping mappings; AST::AttrVec outer_attrs; Visibility visibility; Identifier item_name; location_t locus; public: enum class ExternKind { Static, Function, Type, }; virtual ~ExternalItem () {} BaseKind get_hir_kind () override final { return EXTERNAL; } virtual ExternKind get_extern_kind () = 0; // Returns whether item has outer attributes. bool has_outer_attrs () const { return !outer_attrs.empty (); } // Returns whether item has non-default visibility. 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_t get_locus () const { return locus; } virtual void accept_vis (HIRFullVisitor &vis) = 0; virtual void accept_vis (HIRExternalItemVisitor &vis) = 0; Visibility &get_visibility () { return visibility; } Analysis::NodeMapping get_mappings () const { return mappings; } Identifier get_item_name () const { return item_name; } AST::AttrVec &get_outer_attrs () { return outer_attrs; } protected: ExternalItem (Analysis::NodeMapping mappings, Identifier item_name, Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor ExternalItem (ExternalItem const &other); // Overloaded assignment operator to clone ExternalItem &operator= (ExternalItem const &other); // 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; }; // A static item used in an extern block class ExternalStaticItem : public ExternalItem { Mutability mut; std::unique_ptr item_type; public: ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name, std::unique_ptr item_type, Mutability mut, Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor ExternalStaticItem (ExternalStaticItem const &other); // Overloaded assignment operator to clone ExternalStaticItem &operator= (ExternalStaticItem const &other); // move constructors ExternalStaticItem (ExternalStaticItem &&other) = default; ExternalStaticItem &operator= (ExternalStaticItem &&other) = default; std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExternalItemVisitor &vis) override; bool is_mut () const { return mut == Mutability::Mut; } Mutability get_mut () { return mut; } Type &get_item_type () { return *item_type; } ExternKind get_extern_kind () override { return ExternKind::Static; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ ExternalStaticItem *clone_external_item_impl () const override { return new ExternalStaticItem (*this); } }; // A named function parameter used in external functions struct NamedFunctionParam { private: Identifier name; std::unique_ptr param_type; Analysis::NodeMapping mappings; public: bool has_name () const { return name.as_string () != "_"; } NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name, std::unique_ptr param_type); // Copy constructor NamedFunctionParam (NamedFunctionParam const &other); ~NamedFunctionParam () = default; // Overloaded assignment operator to clone NamedFunctionParam &operator= (NamedFunctionParam const &other); // move constructors NamedFunctionParam (NamedFunctionParam &&other) = default; NamedFunctionParam &operator= (NamedFunctionParam &&other) = default; std::string as_string () const; Identifier get_param_name () const { return name; } Type &get_type () { rust_assert (param_type); return *param_type; } Analysis::NodeMapping get_mappings () const { return mappings; } }; // A function item used in an extern block class ExternalFunctionItem : public ExternalItem { // bool has_generics; // Generics generic_params; std::vector> 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. bool has_generics () const { return !generic_params.empty (); } // Returns whether item has a return type (otherwise void). bool has_return_type () const { return return_type != nullptr; } // Returns whether item has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } WARN_UNUSED_RESULT const WhereClause &get_where_clause () const { return where_clause; } ExternalFunctionItem ( Analysis::NodeMapping mappings, Identifier item_name, std::vector> generic_params, std::unique_ptr return_type, WhereClause where_clause, std::vector function_params, bool has_variadics, Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone ExternalFunctionItem (ExternalFunctionItem const &other); // Overloaded assignment operator with clone ExternalFunctionItem &operator= (ExternalFunctionItem const &other); // move constructors ExternalFunctionItem (ExternalFunctionItem &&other) = default; ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default; std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExternalItemVisitor &vis) override; std::vector> &get_generic_params () { return generic_params; } Type &get_return_type () { return *return_type; } std::vector &get_function_params () { return function_params; } bool is_variadic () const { return has_variadics; } ExternKind get_extern_kind () override { return ExternKind::Function; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ ExternalFunctionItem *clone_external_item_impl () const override { return new ExternalFunctionItem (*this); } }; class ExternalTypeItem : public ExternalItem { public: ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name, Visibility vis, location_t locus); ExternalTypeItem (ExternalTypeItem const &other); ExternalTypeItem (ExternalTypeItem &&other) = default; ExternalTypeItem &operator= (ExternalTypeItem &&other) = default; ExternalTypeItem &operator= (ExternalTypeItem const &other) = default; std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExternalItemVisitor &vis) override; ExternKind get_extern_kind () override { return ExternKind::Type; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ ExternalTypeItem *clone_external_item_impl () const override { return new ExternalTypeItem (*this); } }; // An extern block HIR node class ExternBlock : public VisItem, public WithInnerAttrs { ABI abi; std::vector> extern_items; location_t locus; public: std::string as_string () const override; // Returns whether extern block has extern items. bool has_extern_items () const { return !extern_items.empty (); } ABI get_abi () const { return abi; } ExternBlock (Analysis::NodeMapping mappings, ABI abi, std::vector> extern_items, Visibility vis, AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with vector clone ExternBlock (ExternBlock const &other); // Overloaded assignment operator with vector clone ExternBlock &operator= (ExternBlock const &other); // move constructors ExternBlock (ExternBlock &&other) = default; ExternBlock &operator= (ExternBlock &&other) = default; location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; std::vector> &get_extern_items () { return extern_items; } ItemKind get_item_kind () const override { return ItemKind::ExternBlock; } protected: /* Use covariance to implement clone function as returning this object * rather than base */ 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); }*/ }; } // namespace HIR } // namespace Rust #endif