// 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