diff options
Diffstat (limited to 'gcc/rust/hir/tree')
31 files changed, 5546 insertions, 3836 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-attrs.h b/gcc/rust/hir/tree/rust-hir-attrs.h new file mode 100644 index 0000000..3e2b1d8 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-attrs.h @@ -0,0 +1,56 @@ + +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_ATTRS_H +#define RUST_HIR_ATTRS_H + +#include "rust-ast.h" + +namespace Rust { +namespace HIR { + +class WithOuterAttrs +{ +protected: + AST::AttrVec outer_attrs; + +public: + AST::AttrVec &get_outer_attrs () { return outer_attrs; } + const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } + + WithOuterAttrs (AST::AttrVec outer_attrs) + : outer_attrs (std::move (outer_attrs)){}; +}; + +class WithInnerAttrs +{ +protected: + AST::AttrVec inner_attrs; + +public: + AST::AttrVec get_inner_attrs () const { return inner_attrs; } + + WithInnerAttrs (AST::AttrVec inner_attrs) + : inner_attrs (std::move (inner_attrs)){}; +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-bound-abstract.h b/gcc/rust/hir/tree/rust-hir-bound-abstract.h new file mode 100644 index 0000000..ffc915b --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-bound-abstract.h @@ -0,0 +1,65 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_BOUND_ABSTRACT_H +#define RUST_HIR_BOUND_ABSTRACT_H + +#include "rust-hir-visitable.h" +#include "rust-system.h" +#include "rust-hir-map.h" + +namespace Rust { +namespace HIR { + +/* Abstract base class representing a type param bound - Lifetime and TraitBound + * extends it */ +class TypeParamBound : public FullVisitable +{ +public: + using FullVisitable::accept_vis; + enum BoundType + { + LIFETIME, + TRAITBOUND + }; + + virtual ~TypeParamBound () {} + + // Unique pointer custom clone function + std::unique_ptr<TypeParamBound> clone_type_param_bound () const + { + return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual Analysis::NodeMapping get_mappings () const = 0; + + virtual location_t get_locus () const = 0; + + virtual BoundType get_bound_type () const = 0; + +protected: + // Clone function implementation as pure virtual method + virtual TypeParamBound *clone_type_param_bound_impl () const = 0; +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-bound.h b/gcc/rust/hir/tree/rust-hir-bound.h new file mode 100644 index 0000000..78bb133 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-bound.h @@ -0,0 +1,94 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_BOUND_H +#define RUST_HIR_BOUND_H + +#include "rust-hir-bound-abstract.h" +#include "rust-common.h" +#include "rust-hir-path.h" + +namespace Rust { +namespace HIR { + +// Represents a lifetime (and is also a kind of type param bound) +class Lifetime : public TypeParamBound +{ +private: + AST::Lifetime::LifetimeType lifetime_type; + std::string lifetime_name; + location_t locus; + Analysis::NodeMapping mappings; + +public: + // Constructor + Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type, + std::string name, location_t locus) + : lifetime_type (type), lifetime_name (std::move (name)), locus (locus), + mappings (mapping) + {} + + // Returns true if the lifetime is in an error state. + bool is_error () const + { + return lifetime_type == AST::Lifetime::LifetimeType::NAMED + && lifetime_name.empty (); + } + + static Lifetime error () + { + return Lifetime (Analysis::NodeMapping::get_error (), + AST::Lifetime::LifetimeType::NAMED, "", UNDEF_LOCATION); + } + + std::string as_string () const override; + + void accept_vis (HIRFullVisitor &vis) override; + + WARN_UNUSED_RESULT const std::string &get_name () const + { + return lifetime_name; + } + + AST::Lifetime::LifetimeType get_lifetime_type () const + { + return lifetime_type; + } + + location_t get_locus () const override final { return locus; } + + Analysis::NodeMapping get_mappings () const override final + { + return mappings; + } + + BoundType get_bound_type () const final override { return LIFETIME; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + Lifetime *clone_type_param_bound_impl () const override + { + return new Lifetime (*this); + } +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h b/gcc/rust/hir/tree/rust-hir-expr-abstract.h new file mode 100644 index 0000000..ecf9bd1 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h @@ -0,0 +1,174 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_EXPR_ABSTRACT_H +#define RUST_HIR_EXPR_ABSTRACT_H + +#include "rust-ast.h" +#include "rust-hir-visitable.h" +#include "rust-hir-node.h" + +namespace Rust { +namespace HIR { + +// Base expression HIR node - abstract +class Expr : public Node, virtual public FullVisitable +{ +public: + using FullVisitable::accept_vis; + +protected: + AST::AttrVec outer_attrs; + Analysis::NodeMapping mappings; + +public: + enum BlockType + { + WITH_BLOCK, + WITHOUT_BLOCK, + }; + + enum ExprType + { + Lit, + Operator, + Grouped, + Array, + ArrayIndex, + Tuple, + TupleIdx, + Struct, + Call, + MethodCall, + FieldAccess, + Closure, + Block, + Continue, + Break, + Range, + Return, + UnsafeBlock, + BaseLoop, + If, + IfLet, + Match, + Await, + AsyncBlock, + Path, + InlineAsm, + }; + + BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; } + + const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } + + // Unique pointer custom clone function + std::unique_ptr<Expr> clone_expr () const + { + return std::unique_ptr<Expr> (clone_expr_impl ()); + } + + // TODO: make pure virtual if move out outer attributes to derived classes + virtual std::string as_string () const; + + virtual ~Expr () {} + + virtual location_t get_locus () const = 0; + + const Analysis::NodeMapping &get_mappings () const { return mappings; } + + // Clone function implementation as pure virtual method + virtual Expr *clone_expr_impl () const = 0; + + virtual BlockType get_block_expr_type () const = 0; + + virtual ExprType get_expression_type () const = 0; + + virtual void accept_vis (HIRExpressionVisitor &vis) = 0; + +protected: + // Constructor + Expr (Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs = AST::AttrVec ()); + + // TODO: think of less hacky way to implement this kind of thing + // Sets outer attributes. + void set_outer_attrs (AST::AttrVec outer_attrs_to_set) + { + outer_attrs = std::move (outer_attrs_to_set); + } +}; + +// HIR node for an expression without an accompanying block - abstract +class ExprWithoutBlock : public Expr +{ +protected: + // Constructor + ExprWithoutBlock (Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs = AST::AttrVec ()); + + // pure virtual clone implementation + virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0; + + /* Save having to specify two clone methods in derived classes by making expr + * clone return exprwithoutblock clone. Hopefully won't affect performance too + * much. */ + ExprWithoutBlock *clone_expr_impl () const override + { + return clone_expr_without_block_impl (); + } + +public: + // Unique pointer custom clone function + std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const + { + return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ()); + } + + BlockType get_block_expr_type () const final override + { + return BlockType::WITHOUT_BLOCK; + }; +}; + +// Base path expression HIR node - abstract +class PathExpr : public ExprWithoutBlock +{ +protected: + PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)) + {} + +public: + /* Replaces the outer attributes of this path expression with the given outer + * attributes. */ + void replace_outer_attrs (AST::AttrVec outer_attrs) + { + set_outer_attrs (std::move (outer_attrs)); + } + + ExprType get_expression_type () const final override + { + return ExprType::Path; + } +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc new file mode 100644 index 0000000..2ded789 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -0,0 +1,1484 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-expr.h" +#include "rust-operators.h" +#include "rust-hir-stmt.h" + +namespace Rust { +namespace HIR { + +Expr::Expr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs) + : outer_attrs (std::move (outer_attribs)), mappings (std::move (mappings)) +{} + +ExprWithoutBlock::ExprWithoutBlock (Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs) + : Expr (std::move (mappings), std::move (outer_attribs)) +{} + +LoopLabel::LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label, + location_t locus) + : label (std::move (loop_label)), locus (locus), mappings (mapping) +{} + +ExprWithBlock::ExprWithBlock (Analysis::NodeMapping mappings, + AST::AttrVec outer_attrs) + : Expr (std::move (mappings), std::move (outer_attrs)) +{} + +LiteralExpr::LiteralExpr (Analysis::NodeMapping mappings, + std::string value_as_string, Literal::LitType type, + PrimitiveCoreType type_hint, location_t locus, + AST::AttrVec outer_attrs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)), + literal (std::move (value_as_string), type, type_hint), locus (locus) +{} + +LiteralExpr::LiteralExpr (Analysis::NodeMapping mappings, Literal literal, + location_t locus, AST::AttrVec outer_attrs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)), + literal (std::move (literal)), locus (locus) +{} + +OperatorExpr::OperatorExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> main_or_left_expr, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + locus (locus), main_or_left_expr (std::move (main_or_left_expr)) +{} + +OperatorExpr::OperatorExpr (OperatorExpr const &other) + : ExprWithoutBlock (other), locus (other.locus), + main_or_left_expr (other.main_or_left_expr->clone_expr ()) +{} + +OperatorExpr & +OperatorExpr::operator= (OperatorExpr const &other) +{ + ExprWithoutBlock::operator= (other); + main_or_left_expr = other.main_or_left_expr->clone_expr (); + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +BorrowExpr::BorrowExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> borrow_lvalue, Mutability mut, + AST::AttrVec outer_attribs, location_t locus) + : OperatorExpr (std::move (mappings), std::move (borrow_lvalue), + std::move (outer_attribs), locus), + mut (mut) +{} + +DereferenceExpr::DereferenceExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> deref_lvalue, + AST::AttrVec outer_attribs, location_t locus) + : OperatorExpr (std::move (mappings), std::move (deref_lvalue), + std::move (outer_attribs), locus) +{} + +ErrorPropagationExpr::ErrorPropagationExpr ( + Analysis::NodeMapping mappings, std::unique_ptr<Expr> potential_error_value, + AST::AttrVec outer_attribs, location_t locus) + : OperatorExpr (std::move (mappings), std::move (potential_error_value), + std::move (outer_attribs), locus) +{} + +NegationExpr::NegationExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> negated_value, + ExprType expr_kind, AST::AttrVec outer_attribs, + location_t locus) + : OperatorExpr (std::move (mappings), std::move (negated_value), + std::move (outer_attribs), locus), + expr_type (expr_kind) +{} + +ArithmeticOrLogicalExpr::ArithmeticOrLogicalExpr ( + Analysis::NodeMapping mappings, std::unique_ptr<Expr> left_value, + std::unique_ptr<Expr> right_value, ExprType expr_kind, location_t locus) + : OperatorExpr (std::move (mappings), std::move (left_value), AST::AttrVec (), + locus), + expr_type (expr_kind), right_expr (std::move (right_value)) +{} + +ArithmeticOrLogicalExpr::ArithmeticOrLogicalExpr ( + ArithmeticOrLogicalExpr const &other) + : OperatorExpr (other), expr_type (other.expr_type), + right_expr (other.right_expr->clone_expr ()) +{} + +ArithmeticOrLogicalExpr & +ArithmeticOrLogicalExpr::operator= (ArithmeticOrLogicalExpr const &other) +{ + OperatorExpr::operator= (other); + // main_or_left_expr = other.main_or_left_expr->clone_expr(); + right_expr = other.right_expr->clone_expr (); + expr_type = other.expr_type; + + return *this; +} + +ComparisonExpr::ComparisonExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> left_value, + std::unique_ptr<Expr> right_value, + ExprType comparison_kind, location_t locus) + : OperatorExpr (std::move (mappings), std::move (left_value), AST::AttrVec (), + locus), + expr_type (comparison_kind), right_expr (std::move (right_value)) +{} + +ComparisonExpr::ComparisonExpr (ComparisonExpr const &other) + : OperatorExpr (other), expr_type (other.expr_type), + right_expr (other.right_expr->clone_expr ()) +{} + +ComparisonExpr & +ComparisonExpr::operator= (ComparisonExpr const &other) +{ + OperatorExpr::operator= (other); + // main_or_left_expr = other.main_or_left_expr->clone_expr(); + right_expr = other.right_expr->clone_expr (); + expr_type = other.expr_type; + // outer_attrs = other.outer_attrs; + + return *this; +} + +LazyBooleanExpr::LazyBooleanExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> left_bool_expr, + std::unique_ptr<Expr> right_bool_expr, + ExprType expr_kind, location_t locus) + : OperatorExpr (std::move (mappings), std::move (left_bool_expr), + AST::AttrVec (), locus), + expr_type (expr_kind), right_expr (std::move (right_bool_expr)) +{} + +LazyBooleanExpr::LazyBooleanExpr (LazyBooleanExpr const &other) + : OperatorExpr (other), expr_type (other.expr_type), + right_expr (other.right_expr->clone_expr ()) +{} + +LazyBooleanExpr & +LazyBooleanExpr::operator= (LazyBooleanExpr const &other) +{ + OperatorExpr::operator= (other); + // main_or_left_expr = other.main_or_left_expr->clone_expr(); + right_expr = other.right_expr->clone_expr (); + expr_type = other.expr_type; + + return *this; +} + +TypeCastExpr::TypeCastExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> expr_to_cast, + std::unique_ptr<Type> type_to_cast_to, + location_t locus) + : OperatorExpr (std::move (mappings), std::move (expr_to_cast), + AST::AttrVec (), locus), + type_to_convert_to (std::move (type_to_cast_to)) +{} + +TypeCastExpr::TypeCastExpr (TypeCastExpr const &other) + : OperatorExpr (other), + type_to_convert_to (other.type_to_convert_to->clone_type ()) +{} + +TypeCastExpr & +TypeCastExpr::operator= (TypeCastExpr const &other) +{ + OperatorExpr::operator= (other); + // main_or_left_expr = other.main_or_left_expr->clone_expr(); + type_to_convert_to = other.type_to_convert_to->clone_type (); + + return *this; +} + +AssignmentExpr::AssignmentExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> value_to_assign_to, + std::unique_ptr<Expr> value_to_assign, + location_t locus) + : OperatorExpr (std::move (mappings), std::move (value_to_assign_to), + AST::AttrVec (), locus), + right_expr (std::move (value_to_assign)) +{} + +AssignmentExpr::AssignmentExpr (AssignmentExpr const &other) + : OperatorExpr (other), right_expr (other.right_expr->clone_expr ()) +{} + +AssignmentExpr & +AssignmentExpr::operator= (AssignmentExpr const &other) +{ + OperatorExpr::operator= (other); + // main_or_left_expr = other.main_or_left_expr->clone_expr(); + right_expr = other.right_expr->clone_expr (); + // outer_attrs = other.outer_attrs; + + return *this; +} + +CompoundAssignmentExpr::CompoundAssignmentExpr ( + Analysis::NodeMapping mappings, std::unique_ptr<Expr> value_to_assign_to, + std::unique_ptr<Expr> value_to_assign, ExprType expr_kind, location_t locus) + : OperatorExpr (std::move (mappings), std::move (value_to_assign_to), + AST::AttrVec (), locus), + expr_type (expr_kind), right_expr (std::move (value_to_assign)) +{} + +CompoundAssignmentExpr::CompoundAssignmentExpr ( + CompoundAssignmentExpr const &other) + : OperatorExpr (other), expr_type (other.expr_type), + right_expr (other.right_expr->clone_expr ()) +{} + +CompoundAssignmentExpr & +CompoundAssignmentExpr::operator= (CompoundAssignmentExpr const &other) +{ + OperatorExpr::operator= (other); + // main_or_left_expr = other.main_or_left_expr->clone_expr(); + right_expr = other.right_expr->clone_expr (); + expr_type = other.expr_type; + // outer_attrs = other.outer_attrs; + + return *this; +} + +GroupedExpr::GroupedExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> parenthesised_expr, + AST::AttrVec inner_attribs, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + WithInnerAttrs (std::move (inner_attribs)), + expr_in_parens (std::move (parenthesised_expr)), locus (locus) +{} + +GroupedExpr::GroupedExpr (GroupedExpr const &other) + : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs), + expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus) +{} + +GroupedExpr & +GroupedExpr::operator= (GroupedExpr const &other) +{ + ExprWithoutBlock::operator= (other); + inner_attrs = other.inner_attrs; + expr_in_parens = other.expr_in_parens->clone_expr (); + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +ArrayElemsValues::ArrayElemsValues (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<Expr>> elems) + : ArrayElems (mappings), values (std::move (elems)) +{} + +ArrayElemsValues::ArrayElemsValues (ArrayElemsValues const &other) + : ArrayElems (other) +{ + values.reserve (other.values.size ()); + for (const auto &e : other.values) + values.push_back (e->clone_expr ()); +} + +ArrayElemsValues & +ArrayElemsValues::operator= (ArrayElemsValues const &other) +{ + values.reserve (other.values.size ()); + for (const auto &e : other.values) + values.push_back (e->clone_expr ()); + + return *this; +} + +ArrayElemsCopied::ArrayElemsCopied (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> copied_elem, + std::unique_ptr<Expr> copy_amount) + : ArrayElems (mappings), elem_to_copy (std::move (copied_elem)), + num_copies (std::move (copy_amount)) +{} + +ArrayElemsCopied::ArrayElemsCopied (ArrayElemsCopied const &other) + : ArrayElems (other), elem_to_copy (other.elem_to_copy->clone_expr ()), + num_copies (other.num_copies->clone_expr ()) +{} + +ArrayElemsCopied & +ArrayElemsCopied::operator= (ArrayElemsCopied const &other) +{ + elem_to_copy = other.elem_to_copy->clone_expr (); + num_copies = other.num_copies->clone_expr (); + + return *this; +} + +ArrayExpr::ArrayExpr (Analysis::NodeMapping mappings, + std::unique_ptr<ArrayElems> array_elems, + AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, + location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + WithInnerAttrs (std::move (inner_attribs)), + internal_elements (std::move (array_elems)), locus (locus) +{} + +ArrayExpr::ArrayExpr (ArrayExpr const &other) + : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs), + locus (other.locus) +{ + if (other.has_array_elems ()) + internal_elements = other.internal_elements->clone_array_elems (); +} + +ArrayExpr & +ArrayExpr::operator= (ArrayExpr const &other) +{ + ExprWithoutBlock::operator= (other); + inner_attrs = other.inner_attrs; + if (other.has_array_elems ()) + internal_elements = other.internal_elements->clone_array_elems (); + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +ArrayIndexExpr::ArrayIndexExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> array_expr, + std::unique_ptr<Expr> array_index_expr, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + array_expr (std::move (array_expr)), + index_expr (std::move (array_index_expr)), locus (locus) +{} + +ArrayIndexExpr::ArrayIndexExpr (ArrayIndexExpr const &other) + : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()), + index_expr (other.index_expr->clone_expr ()), locus (other.locus) +{} + +ArrayIndexExpr & +ArrayIndexExpr::operator= (ArrayIndexExpr const &other) +{ + ExprWithoutBlock::operator= (other); + array_expr = other.array_expr->clone_expr (); + index_expr = other.index_expr->clone_expr (); + // outer_attrs = other.outer_attrs; + locus = other.locus; + + return *this; +} + +TupleExpr::TupleExpr (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<Expr>> tuple_elements, + AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, + location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + WithInnerAttrs (std::move (inner_attribs)), + tuple_elems (std::move (tuple_elements)), locus (locus) +{} + +TupleExpr::TupleExpr (TupleExpr const &other) + : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs), + locus (other.locus) +{ + tuple_elems.reserve (other.tuple_elems.size ()); + for (const auto &e : other.tuple_elems) + tuple_elems.push_back (e->clone_expr ()); +} + +TupleExpr & +TupleExpr::operator= (TupleExpr const &other) +{ + ExprWithoutBlock::operator= (other); + inner_attrs = other.inner_attrs; + locus = other.locus; + + tuple_elems.reserve (other.tuple_elems.size ()); + for (const auto &e : other.tuple_elems) + tuple_elems.push_back (e->clone_expr ()); + + return *this; +} + +TupleIndexExpr::TupleIndexExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> tuple_expr, + TupleIndex index, AST::AttrVec outer_attribs, + location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus) +{} + +TupleIndexExpr::TupleIndexExpr (TupleIndexExpr const &other) + : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()), + tuple_index (other.tuple_index), locus (other.locus) +{} + +TupleIndexExpr & +TupleIndexExpr::operator= (TupleIndexExpr const &other) +{ + ExprWithoutBlock::operator= (other); + tuple_expr = other.tuple_expr->clone_expr (); + tuple_index = other.tuple_index; + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +StructExpr::StructExpr (Analysis::NodeMapping mappings, + PathInExpression struct_path, + AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + struct_name (std::move (struct_path)) +{} + +StructExprStruct::StructExprStruct (Analysis::NodeMapping mappings, + PathInExpression struct_path, + AST::AttrVec inner_attribs, + AST::AttrVec outer_attribs, + location_t locus) + : StructExpr (std::move (mappings), std::move (struct_path), + std::move (outer_attribs)), + WithInnerAttrs (std::move (inner_attribs)), locus (locus) +{} + +StructBase::StructBase (std::unique_ptr<Expr> base_struct_ptr) + : base_struct (std::move (base_struct_ptr)) +{} + +StructBase::StructBase (StructBase const &other) +{ + /* HACK: gets around base_struct pointer being null (e.g. if no struct base + * exists) */ + if (other.base_struct != nullptr) + other.base_struct->clone_expr (); +} + +StructBase & +StructBase::operator= (StructBase const &other) +{ + base_struct = other.base_struct->clone_expr (); + + return *this; +} + +StructExprField::StructExprField (Analysis::NodeMapping mapping, + location_t locus) + : mappings (mapping), locus (locus) +{} + +StructExprFieldIdentifier::StructExprFieldIdentifier ( + Analysis::NodeMapping mapping, Identifier field_identifier, location_t locus) + : StructExprField (mapping, locus), field_name (std::move (field_identifier)) +{} + +StructExprFieldWithVal::StructExprFieldWithVal ( + Analysis::NodeMapping mapping, std::unique_ptr<Expr> field_value, + location_t locus) + : StructExprField (mapping, locus), value (std::move (field_value)) +{} + +StructExprFieldWithVal::StructExprFieldWithVal ( + StructExprFieldWithVal const &other) + : StructExprField (other.mappings, other.locus), + value (other.value->clone_expr ()) +{} + +StructExprFieldWithVal & +StructExprFieldWithVal::operator= (StructExprFieldWithVal const &other) +{ + value = other.value->clone_expr (); + mappings = other.mappings; + locus = other.locus; + + return *this; +} + +StructExprFieldIdentifierValue::StructExprFieldIdentifierValue ( + Analysis::NodeMapping mapping, Identifier field_identifier, + std::unique_ptr<Expr> field_value, location_t locus) + : StructExprFieldWithVal (mapping, std::move (field_value), locus), + field_name (std::move (field_identifier)) +{} + +StructExprFieldIndexValue::StructExprFieldIndexValue ( + Analysis::NodeMapping mapping, TupleIndex tuple_index, + std::unique_ptr<Expr> field_value, location_t locus) + : StructExprFieldWithVal (mapping, std::move (field_value), locus), + index (tuple_index) +{} + +StructExprStructFields::StructExprStructFields ( + Analysis::NodeMapping mappings, PathInExpression struct_path, + std::vector<std::unique_ptr<StructExprField>> expr_fields, location_t locus, + tl::optional<std::unique_ptr<StructBase>> base_struct, + AST::AttrVec inner_attribs = AST::AttrVec (), + AST::AttrVec outer_attribs = AST::AttrVec ()) + : StructExprStruct (std::move (mappings), std::move (struct_path), + std::move (inner_attribs), std::move (outer_attribs), + locus), + fields (std::move (expr_fields)), struct_base (std::move (base_struct)) +{} + +StructExprStructFields::StructExprStructFields ( + StructExprStructFields const &other) + : StructExprStruct (other), + struct_base (other.has_struct_base () + ? tl::optional<std::unique_ptr<StructBase>> ( + std::make_unique<StructBase> (*other.struct_base.value ())) + : tl::nullopt), + union_index (other.union_index) +{ + fields.reserve (other.fields.size ()); + for (const auto &e : other.fields) + fields.push_back (e->clone_struct_expr_field ()); +} + +StructExprStructFields & +StructExprStructFields::operator= (StructExprStructFields const &other) +{ + StructExprStruct::operator= (other); + struct_base = other.has_struct_base () + ? tl::optional<std::unique_ptr<StructBase>> ( + std::make_unique<StructBase> (*other.struct_base.value ())) + : tl::nullopt; + union_index = other.union_index; + + fields.reserve (other.fields.size ()); + for (const auto &e : other.fields) + fields.push_back (e->clone_struct_expr_field ()); + + return *this; +} + +StructExprStructBase::StructExprStructBase (Analysis::NodeMapping mappings, + PathInExpression struct_path, + StructBase base_struct, + AST::AttrVec inner_attribs, + AST::AttrVec outer_attribs, + location_t locus) + : StructExprStruct (std::move (mappings), std::move (struct_path), + std::move (inner_attribs), std::move (outer_attribs), + locus), + struct_base (std::move (base_struct)) +{} + +CallExpr::CallExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> function_expr, + std::vector<std::unique_ptr<Expr>> function_params, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + function (std::move (function_expr)), params (std::move (function_params)), + locus (locus) +{} + +CallExpr::CallExpr (CallExpr const &other) + : ExprWithoutBlock (other), function (other.function->clone_expr ()), + locus (other.locus) +/*, params(other.params),*/ { + params.reserve (other.params.size ()); + for (const auto &e : other.params) + params.push_back (e->clone_expr ()); +} + +CallExpr & +CallExpr::operator= (CallExpr const &other) +{ + ExprWithoutBlock::operator= (other); + function = other.function->clone_expr (); + locus = other.locus; + // params = other.params; + // outer_attrs = other.outer_attrs; + + params.reserve (other.params.size ()); + for (const auto &e : other.params) + params.push_back (e->clone_expr ()); + + return *this; +} + +MethodCallExpr::MethodCallExpr ( + Analysis::NodeMapping mappings, std::unique_ptr<Expr> call_receiver, + PathExprSegment method_path, std::vector<std::unique_ptr<Expr>> method_params, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + receiver (std::move (call_receiver)), method_name (std::move (method_path)), + params (std::move (method_params)), locus (locus) +{} + +MethodCallExpr::MethodCallExpr (MethodCallExpr const &other) + : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()), + method_name (other.method_name), locus (other.locus) +/*, params(other.params),*/ { + params.reserve (other.params.size ()); + for (const auto &e : other.params) + params.push_back (e->clone_expr ()); +} + +MethodCallExpr & +MethodCallExpr::operator= (MethodCallExpr const &other) +{ + ExprWithoutBlock::operator= (other); + receiver = other.receiver->clone_expr (); + method_name = other.method_name; + locus = other.locus; + // params = other.params; + // outer_attrs = other.outer_attrs; + + params.reserve (other.params.size ()); + for (const auto &e : other.params) + params.push_back (e->clone_expr ()); + + return *this; +} + +FieldAccessExpr::FieldAccessExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> field_access_receiver, + Identifier field_name, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + receiver (std::move (field_access_receiver)), + field (std::move (field_name)), locus (locus) +{} + +FieldAccessExpr::FieldAccessExpr (FieldAccessExpr const &other) + : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()), + field (other.field), locus (other.locus) +{} + +FieldAccessExpr & +FieldAccessExpr::operator= (FieldAccessExpr const &other) +{ + ExprWithoutBlock::operator= (other); + receiver = other.receiver->clone_expr (); + field = other.field; + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +ClosureParam::ClosureParam (std::unique_ptr<Pattern> param_pattern, + location_t locus, std::unique_ptr<Type> param_type, + std::vector<AST::Attribute> outer_attrs) + : outer_attrs (std::move (outer_attrs)), pattern (std::move (param_pattern)), + type (std::move (param_type)), locus (locus) +{} + +ClosureParam::ClosureParam (ClosureParam const &other) + : pattern (other.pattern->clone_pattern ()) +{ + // guard to protect from null pointer dereference + if (other.pattern != nullptr) + pattern = other.pattern->clone_pattern (); + if (other.type != nullptr) + type = other.type->clone_type (); +} + +ClosureParam & +ClosureParam::operator= (ClosureParam const &other) +{ + outer_attrs = other.outer_attrs; + + // guard to protect from null pointer dereference + if (other.pattern != nullptr) + pattern = other.pattern->clone_pattern (); + else + pattern = nullptr; + if (other.type != nullptr) + type = other.type->clone_type (); + else + type = nullptr; + + return *this; +} + +ClosureExpr::ClosureExpr (Analysis::NodeMapping mappings, + std::vector<ClosureParam> closure_params, + std::unique_ptr<Type> closure_return_type, + std::unique_ptr<Expr> closure_expr, bool has_move, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + has_move (has_move), params (std::move (closure_params)), locus (locus), + return_type (std::move (closure_return_type)), + expr (std::move (closure_expr)) +{} + +ClosureExpr::ClosureExpr (ClosureExpr const &other) + : ExprWithoutBlock (other.get_mappings (), other.get_outer_attrs ()) +{ + return_type + = other.has_return_type () ? other.return_type->clone_type () : nullptr; + expr = other.expr->clone_expr (); + params = other.params; + has_move = other.has_move; +} + +ClosureExpr & +ClosureExpr::operator= (ClosureExpr const &other) +{ + mappings = other.mappings; + return_type + = other.has_return_type () ? other.return_type->clone_type () : nullptr; + expr = other.expr->clone_expr (); + params = other.params; + has_move = other.has_move; + + return *this; +} + +BlockExpr::BlockExpr (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<Stmt>> block_statements, + std::unique_ptr<Expr> block_expr, bool tail_reachable, + AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, + LoopLabel label, location_t start_locus, + location_t end_locus) + : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), + WithInnerAttrs (std::move (inner_attribs)), + statements (std::move (block_statements)), expr (std::move (block_expr)), + tail_reachable (tail_reachable), label (std::move (label)), + start_locus (start_locus), end_locus (end_locus) +{} + +BlockExpr::BlockExpr (BlockExpr const &other) + : ExprWithBlock (other), /*statements(other.statements),*/ + WithInnerAttrs (other.inner_attrs), label (other.label), + start_locus (other.start_locus), end_locus (other.end_locus) +{ + // guard to protect from null pointer dereference + if (other.expr != nullptr) + expr = other.expr->clone_expr (); + + statements.reserve (other.statements.size ()); + for (const auto &e : other.statements) + statements.push_back (e->clone_stmt ()); +} + +BlockExpr & +BlockExpr::operator= (BlockExpr const &other) +{ + ExprWithBlock::operator= (other); + // statements = other.statements; + expr = other.expr->clone_expr (); + inner_attrs = other.inner_attrs; + start_locus = other.end_locus; + end_locus = other.end_locus; + // outer_attrs = other.outer_attrs; + + statements.reserve (other.statements.size ()); + for (const auto &e : other.statements) + statements.push_back (e->clone_stmt ()); + + return *this; +} + +ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus, + Lifetime label, AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + label (std::move (label)), locus (locus) +{} + +BreakExpr::BreakExpr (Analysis::NodeMapping mappings, location_t locus, + Lifetime break_label, std::unique_ptr<Expr> expr_in_break, + AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + label (std::move (break_label)), break_expr (std::move (expr_in_break)), + locus (locus) +{} + +BreakExpr::BreakExpr (BreakExpr const &other) + : ExprWithoutBlock (other), label (other.label), locus (other.locus) +{ + // guard to protect from null pointer dereference + if (other.break_expr != nullptr) + break_expr = other.break_expr->clone_expr (); +} + +BreakExpr & +BreakExpr::operator= (BreakExpr const &other) +{ + ExprWithoutBlock::operator= (other); + label = other.label; + break_expr = other.break_expr->clone_expr (); + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +RangeExpr::RangeExpr (Analysis::NodeMapping mappings, location_t locus) + : ExprWithoutBlock (std::move (mappings), AST::AttrVec ()), locus (locus) +{} + +RangeFromToExpr::RangeFromToExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> range_from, + std::unique_ptr<Expr> range_to, + location_t locus) + : RangeExpr (std::move (mappings), locus), from (std::move (range_from)), + to (std::move (range_to)) +{} + +RangeFromToExpr::RangeFromToExpr (RangeFromToExpr const &other) + : RangeExpr (other), from (other.from->clone_expr ()), + to (other.to->clone_expr ()) +{} + +RangeFromToExpr & +RangeFromToExpr::operator= (RangeFromToExpr const &other) +{ + RangeExpr::operator= (other); + from = other.from->clone_expr (); + to = other.to->clone_expr (); + + return *this; +} + +RangeFromExpr::RangeFromExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> range_from, + location_t locus) + : RangeExpr (std::move (mappings), locus), from (std::move (range_from)) +{} + +RangeFromExpr::RangeFromExpr (RangeFromExpr const &other) + : RangeExpr (other), from (other.from->clone_expr ()) +{} + +RangeFromExpr & +RangeFromExpr::operator= (RangeFromExpr const &other) +{ + RangeExpr::operator= (other); + from = other.from->clone_expr (); + + return *this; +} + +RangeToExpr::RangeToExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> range_to, location_t locus) + : RangeExpr (std::move (mappings), locus), to (std::move (range_to)) +{} + +RangeToExpr::RangeToExpr (RangeToExpr const &other) + : RangeExpr (other), to (other.to->clone_expr ()) +{} + +RangeToExpr & +RangeToExpr::operator= (RangeToExpr const &other) +{ + RangeExpr::operator= (other); + to = other.to->clone_expr (); + + return *this; +} + +RangeFullExpr::RangeFullExpr (Analysis::NodeMapping mappings, location_t locus) + : RangeExpr (std::move (mappings), locus) +{} + +RangeFromToInclExpr::RangeFromToInclExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> range_from, + std::unique_ptr<Expr> range_to, + location_t locus) + : RangeExpr (std::move (mappings), locus), from (std::move (range_from)), + to (std::move (range_to)) +{} + +RangeFromToInclExpr::RangeFromToInclExpr (RangeFromToInclExpr const &other) + : RangeExpr (other), from (other.from->clone_expr ()), + to (other.to->clone_expr ()) +{} + +RangeFromToInclExpr & +RangeFromToInclExpr::operator= (RangeFromToInclExpr const &other) +{ + RangeExpr::operator= (other); + from = other.from->clone_expr (); + to = other.to->clone_expr (); + + return *this; +} + +RangeToInclExpr::RangeToInclExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> range_to, + location_t locus) + : RangeExpr (std::move (mappings), locus), to (std::move (range_to)) +{} + +RangeToInclExpr::RangeToInclExpr (RangeToInclExpr const &other) + : RangeExpr (other), to (other.to->clone_expr ()) +{} + +RangeToInclExpr & +RangeToInclExpr::operator= (RangeToInclExpr const &other) +{ + RangeExpr::operator= (other); + to = other.to->clone_expr (); + + return *this; +} + +ReturnExpr::ReturnExpr (Analysis::NodeMapping mappings, location_t locus, + std::unique_ptr<Expr> returned_expr, + AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + return_expr (std::move (returned_expr)), locus (locus) +{} + +ReturnExpr::ReturnExpr (ReturnExpr const &other) + : ExprWithoutBlock (other), locus (other.locus) +{ + // guard to protect from null pointer dereference + if (other.return_expr != nullptr) + return_expr = other.return_expr->clone_expr (); +} + +ReturnExpr & +ReturnExpr::operator= (ReturnExpr const &other) +{ + ExprWithoutBlock::operator= (other); + return_expr = other.return_expr->clone_expr (); + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +UnsafeBlockExpr::UnsafeBlockExpr (Analysis::NodeMapping mappings, + std::unique_ptr<BlockExpr> block_expr, + AST::AttrVec outer_attribs, location_t locus) + : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), + expr (std::move (block_expr)), locus (locus) +{} + +UnsafeBlockExpr::UnsafeBlockExpr (UnsafeBlockExpr const &other) + : ExprWithBlock (other), expr (other.expr->clone_block_expr ()), + locus (other.locus) +{} + +UnsafeBlockExpr & +UnsafeBlockExpr::operator= (UnsafeBlockExpr const &other) +{ + ExprWithBlock::operator= (other); + expr = other.expr->clone_block_expr (); + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +BaseLoopExpr::BaseLoopExpr (Analysis::NodeMapping mappings, + std::unique_ptr<BlockExpr> loop_block, + location_t locus, LoopLabel loop_label, + AST::AttrVec outer_attribs) + : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), + loop_label (std::move (loop_label)), loop_block (std::move (loop_block)), + locus (locus) +{} + +BaseLoopExpr::BaseLoopExpr (BaseLoopExpr const &other) + : ExprWithBlock (other), loop_label (other.loop_label), + loop_block (other.loop_block->clone_block_expr ()), locus (other.locus) +{} + +BaseLoopExpr & +BaseLoopExpr::operator= (BaseLoopExpr const &other) +{ + ExprWithBlock::operator= (other); + loop_block = other.loop_block->clone_block_expr (); + loop_label = other.loop_label; + locus = other.locus; + // outer_attrs = other.outer_attrs; + + return *this; +} + +LoopExpr::LoopExpr (Analysis::NodeMapping mappings, + std::unique_ptr<BlockExpr> loop_block, location_t locus, + LoopLabel loop_label, AST::AttrVec outer_attribs) + : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, + std::move (loop_label), std::move (outer_attribs)) +{} + +WhileLoopExpr::WhileLoopExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> loop_condition, + std::unique_ptr<BlockExpr> loop_block, + location_t locus, LoopLabel loop_label, + AST::AttrVec outer_attribs) + : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, + std::move (loop_label), std::move (outer_attribs)), + condition (std::move (loop_condition)) +{} + +WhileLoopExpr::WhileLoopExpr (WhileLoopExpr const &other) + : BaseLoopExpr (other), condition (other.condition->clone_expr ()) +{} + +WhileLoopExpr & +WhileLoopExpr::operator= (WhileLoopExpr const &other) +{ + BaseLoopExpr::operator= (other); + condition = other.condition->clone_expr (); + // loop_block = other.loop_block->clone_block_expr(); + // loop_label = other.loop_label; + // outer_attrs = other.outer_attrs; + + return *this; +} + +WhileLetLoopExpr::WhileLetLoopExpr ( + Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block, + location_t locus, LoopLabel loop_label, AST::AttrVec outer_attribs) + : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, + std::move (loop_label), std::move (outer_attribs)), + match_arm_patterns (std::move (match_arm_patterns)), + condition (std::move (condition)) +{} + +WhileLetLoopExpr::WhileLetLoopExpr (WhileLetLoopExpr const &other) + : BaseLoopExpr (other), + /*match_arm_patterns(other.match_arm_patterns),*/ condition ( + other.condition->clone_expr ()) +{ + match_arm_patterns.reserve (other.match_arm_patterns.size ()); + for (const auto &e : other.match_arm_patterns) + match_arm_patterns.push_back (e->clone_pattern ()); +} + +WhileLetLoopExpr & +WhileLetLoopExpr::operator= (WhileLetLoopExpr const &other) +{ + BaseLoopExpr::operator= (other); + // match_arm_patterns = other.match_arm_patterns; + condition = other.condition->clone_expr (); + // loop_block = other.loop_block->clone_block_expr(); + // loop_label = other.loop_label; + // outer_attrs = other.outer_attrs; + + match_arm_patterns.reserve (other.match_arm_patterns.size ()); + for (const auto &e : other.match_arm_patterns) + match_arm_patterns.push_back (e->clone_pattern ()); + + return *this; +} + +IfExpr::IfExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition, + std::unique_ptr<BlockExpr> if_block, location_t locus) + : ExprWithBlock (std::move (mappings), AST::AttrVec ()), + condition (std::move (condition)), if_block (std::move (if_block)), + locus (locus) +{} + +IfExpr::IfExpr (IfExpr const &other) + : ExprWithBlock (other), condition (other.condition->clone_expr ()), + if_block (other.if_block->clone_block_expr ()), locus (other.locus) +{} + +IfExpr & +IfExpr::operator= (IfExpr const &other) +{ + ExprWithBlock::operator= (other); + condition = other.condition->clone_expr (); + if_block = other.if_block->clone_block_expr (); + locus = other.locus; + + return *this; +} + +IfExprConseqElse::IfExprConseqElse (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> condition, + std::unique_ptr<BlockExpr> if_block, + std::unique_ptr<ExprWithBlock> else_block, + location_t locus) + : IfExpr (std::move (mappings), std::move (condition), std::move (if_block), + locus), + else_block (std::move (else_block)) +{} + +IfExprConseqElse::IfExprConseqElse (IfExprConseqElse const &other) + : IfExpr (other), else_block (other.else_block->clone_expr_with_block ()) +{} + +IfExprConseqElse & +IfExprConseqElse::operator= (IfExprConseqElse const &other) +{ + IfExpr::operator= (other); + // condition = other.condition->clone_expr(); + // if_block = other.if_block->clone_block_expr(); + else_block = other.else_block->clone_expr_with_block (); + + return *this; +} + +MatchArm::MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + location_t locus, std::unique_ptr<Expr> guard_expr, + AST::AttrVec outer_attrs) + : outer_attrs (std::move (outer_attrs)), + match_arm_patterns (std::move (match_arm_patterns)), + guard_expr (std::move (guard_expr)), locus (locus) +{} + +MatchArm::MatchArm (MatchArm const &other) : outer_attrs (other.outer_attrs) +{ + // guard to protect from null pointer dereference + if (other.guard_expr != nullptr) + guard_expr = other.guard_expr->clone_expr (); + + match_arm_patterns.reserve (other.match_arm_patterns.size ()); + for (const auto &e : other.match_arm_patterns) + match_arm_patterns.push_back (e->clone_pattern ()); + + locus = other.locus; +} + +MatchArm & +MatchArm::operator= (MatchArm const &other) +{ + outer_attrs = other.outer_attrs; + + if (other.guard_expr != nullptr) + guard_expr = other.guard_expr->clone_expr (); + + match_arm_patterns.clear (); + match_arm_patterns.reserve (other.match_arm_patterns.size ()); + for (const auto &e : other.match_arm_patterns) + match_arm_patterns.push_back (e->clone_pattern ()); + + return *this; +} + +MatchCase::MatchCase (Analysis::NodeMapping mappings, MatchArm arm, + std::unique_ptr<Expr> expr) + : mappings (mappings), arm (std::move (arm)), expr (std::move (expr)) +{} + +MatchCase::MatchCase (const MatchCase &other) + : mappings (other.mappings), arm (other.arm), expr (other.expr->clone_expr ()) +{} + +MatchCase & +MatchCase::operator= (const MatchCase &other) +{ + mappings = other.mappings; + arm = other.arm; + expr = other.expr->clone_expr (); + + return *this; +} + +MatchExpr::MatchExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> branch_value, + std::vector<MatchCase> match_arms, + AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, + location_t locus) + : ExprWithBlock (std::move (mappings), std::move (outer_attrs)), + WithInnerAttrs (std::move (inner_attrs)), + branch_value (std::move (branch_value)), + match_arms (std::move (match_arms)), locus (locus) +{} + +MatchExpr::MatchExpr (MatchExpr const &other) + : ExprWithBlock (other), WithInnerAttrs (other.inner_attrs), + branch_value (other.branch_value->clone_expr ()), + match_arms (other.match_arms), locus (other.locus) +{ + /*match_arms.reserve (other.match_arms.size ()); + for (const auto &e : other.match_arms) + match_arms.push_back (e->clone_match_case ());*/ +} + +MatchExpr & +MatchExpr::operator= (MatchExpr const &other) +{ + ExprWithBlock::operator= (other); + branch_value = other.branch_value->clone_expr (); + inner_attrs = other.inner_attrs; + match_arms = other.match_arms; + // outer_attrs = other.outer_attrs; + locus = other.locus; + + /*match_arms.reserve (other.match_arms.size ()); + for (const auto &e : other.match_arms) + match_arms.push_back (e->clone_match_case ());*/ + + return *this; +} + +AwaitExpr::AwaitExpr (Analysis::NodeMapping mappings, + std::unique_ptr<Expr> awaited_expr, + AST::AttrVec outer_attrs, location_t locus) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)), + awaited_expr (std::move (awaited_expr)), locus (locus) +{} + +AwaitExpr::AwaitExpr (AwaitExpr const &other) + : ExprWithoutBlock (other), awaited_expr (other.awaited_expr->clone_expr ()), + locus (other.locus) +{} + +AwaitExpr & +AwaitExpr::operator= (AwaitExpr const &other) +{ + ExprWithoutBlock::operator= (other); + awaited_expr = other.awaited_expr->clone_expr (); + locus = other.locus; + + return *this; +} + +AsyncBlockExpr::AsyncBlockExpr (Analysis::NodeMapping mappings, + std::unique_ptr<BlockExpr> block_expr, + bool has_move, AST::AttrVec outer_attrs, + location_t locus) + : ExprWithBlock (std::move (mappings), std::move (outer_attrs)), + has_move (has_move), block_expr (std::move (block_expr)), locus (locus) +{} + +AsyncBlockExpr::AsyncBlockExpr (AsyncBlockExpr const &other) + : ExprWithBlock (other), has_move (other.has_move), + block_expr (other.block_expr->clone_block_expr ()), locus (other.locus) +{} + +AsyncBlockExpr & +AsyncBlockExpr::operator= (AsyncBlockExpr const &other) +{ + ExprWithBlock::operator= (other); + has_move = other.has_move; + block_expr = other.block_expr->clone_block_expr (); + locus = other.locus; + + return *this; +} + +OperatorExprMeta::OperatorExprMeta (HIR::CompoundAssignmentExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + +OperatorExprMeta::OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + +OperatorExprMeta::OperatorExprMeta (HIR::NegationExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + +OperatorExprMeta::OperatorExprMeta (HIR::DereferenceExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + +OperatorExprMeta::OperatorExprMeta (HIR::ArrayIndexExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_array_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + +OperatorExprMeta::OperatorExprMeta (HIR::ComparisonExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + +AnonConst::AnonConst (NodeId id, std::unique_ptr<Expr> expr) + : id (id), expr (std::move (expr)) +{ + rust_assert (this->expr != nullptr); +} + +AnonConst::AnonConst (const AnonConst &other) +{ + id = other.id; + expr = other.expr->clone_expr (); +} + +AnonConst +AnonConst::operator= (const AnonConst &other) +{ + id = other.id; + expr = other.expr->clone_expr (); + return *this; +} + +InlineAsmOperand::In::In ( + const tl::optional<struct AST::InlineAsmRegOrRegClass> ®, + std::unique_ptr<Expr> expr) + : reg (reg), expr (std::move (expr)) +{ + rust_assert (this->expr != nullptr); +} + +InlineAsmOperand::In::In (const struct In &other) +{ + reg = other.reg; + + expr = other.expr->clone_expr (); +} + +InlineAsmOperand::In +InlineAsmOperand::In::operator= (const struct In &other) +{ + reg = other.reg; + expr = other.expr->clone_expr (); + + return *this; +} + +InlineAsmOperand::Out::Out ( + tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, + std::unique_ptr<Expr> expr) + : reg (reg), late (late), expr (std::move (expr)) +{ + rust_assert (this->expr != nullptr); +} + +InlineAsmOperand::Out::Out (const struct Out &other) +{ + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); +} + +InlineAsmOperand::Out +InlineAsmOperand::Out::operator= (const struct Out &other) +{ + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); + return *this; +} + +InlineAsmOperand::InOut::InOut ( + tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, + std::unique_ptr<Expr> expr) + : reg (reg), late (late), expr (std::move (expr)) +{ + rust_assert (this->expr != nullptr); +} + +InlineAsmOperand::InOut::InOut (const struct InOut &other) +{ + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); +} + +InlineAsmOperand::InOut +InlineAsmOperand::InOut::operator= (const struct InOut &other) +{ + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); + + return *this; +} + +InlineAsmOperand::SplitInOut::SplitInOut ( + tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, + std::unique_ptr<Expr> in_expr, std::unique_ptr<Expr> out_expr) + : reg (reg), late (late), in_expr (std::move (in_expr)), + out_expr (std::move (out_expr)) +{ + rust_assert (this->in_expr != nullptr); + rust_assert (this->out_expr != nullptr); +} + +InlineAsmOperand::SplitInOut::SplitInOut (const struct SplitInOut &other) +{ + reg = other.reg; + late = other.late; + in_expr = other.in_expr->clone_expr (); + out_expr = other.out_expr->clone_expr (); +} + +InlineAsmOperand::SplitInOut +InlineAsmOperand::SplitInOut::operator= (const struct SplitInOut &other) +{ + reg = other.reg; + late = other.late; + in_expr = other.in_expr->clone_expr (); + out_expr = other.out_expr->clone_expr (); + + return *this; +} + +InlineAsmOperand::Sym::Sym (std::unique_ptr<Expr> expr) + : expr (std::move (expr)) +{ + rust_assert (this->expr != nullptr); +} + +InlineAsmOperand::Sym::Sym (const struct Sym &other) +{ + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); +} + +InlineAsmOperand::Sym +InlineAsmOperand::Sym::operator= (const struct Sym &other) +{ + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); + return *this; +} + +InlineAsmOperand::Label::Label (tl::optional<std::string> label_name, + std::unique_ptr<Expr> expr) + : expr (std::move (expr)) +{ + rust_assert (this->expr != nullptr); + if (label_name.has_value ()) + this->label_name = label_name.value (); +} + +InlineAsmOperand::Label::Label (const struct Label &other) +{ + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); +} + +InlineAsmOperand::Label +InlineAsmOperand::Label::operator= (const struct Label &other) +{ + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); + return *this; +} + +InlineAsm::InlineAsm (location_t locus, bool is_global_asm, + std::vector<AST::InlineAsmTemplatePiece> template_, + std::vector<AST::TupleTemplateStr> template_strs, + std::vector<HIR::InlineAsmOperand> operands, + std::vector<AST::TupleClobber> clobber_abi, + std::set<AST::InlineAsmOption> options, + Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), + locus (locus), is_global_asm (is_global_asm), + template_ (std::move (template_)), + template_strs (std::move (template_strs)), operands (std::move (operands)), + clobber_abi (std::move (clobber_abi)), options (std::move (options)) +{} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 1ee1066..f8f2128 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -19,12 +19,13 @@ #ifndef RUST_HIR_EXPR_H #define RUST_HIR_EXPR_H +#include "rust-hir-expr-abstract.h" +#include "rust-hir-literal.h" #include "rust-common.h" -#include "rust-ast-full-decls.h" -#include "rust-hir.h" -#include "rust-hir-path.h" -#include "rust-operators.h" +#include "rust-hir-bound.h" +#include "rust-hir-attrs.h" #include "rust-expr.h" + namespace Rust { namespace HIR { @@ -32,7 +33,7 @@ namespace HIR { // TODO: inline? class LoopLabel /*: public Node*/ { - Lifetime label; // or type LIFETIME_OR_LABEL + Lifetime label; // of type LIFETIME_OR_LABEL location_t locus; @@ -42,9 +43,7 @@ public: std::string as_string () const; LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label, - location_t locus) - : label (std::move (loop_label)), locus (locus), mappings (mapping) - {} + location_t locus); // Returns whether the LoopLabel is in an error state. bool is_error () const { return label.is_error (); } @@ -62,9 +61,7 @@ class ExprWithBlock : public Expr // TODO: should this mean that a BlockExpr should be a member variable? protected: ExprWithBlock (Analysis::NodeMapping mappings, - AST::AttrVec outer_attrs = AST::AttrVec ()) - : Expr (std::move (mappings), std::move (outer_attrs)) - {} + AST::AttrVec outer_attrs = AST::AttrVec ()); // pure virtual clone implementation virtual ExprWithBlock *clone_expr_with_block_impl () const = 0; @@ -106,16 +103,10 @@ public: LiteralExpr (Analysis::NodeMapping mappings, std::string value_as_string, Literal::LitType type, PrimitiveCoreType type_hint, - location_t locus, AST::AttrVec outer_attrs) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)), - literal (std::move (value_as_string), type, type_hint), locus (locus) - {} + location_t locus, AST::AttrVec outer_attrs); LiteralExpr (Analysis::NodeMapping mappings, Literal literal, - location_t locus, AST::AttrVec outer_attrs) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)), - literal (std::move (literal)), locus (locus) - {} + location_t locus, AST::AttrVec outer_attrs); // Unique pointer custom clone function std::unique_ptr<LiteralExpr> clone_literal_expr () const @@ -180,27 +171,13 @@ protected: // Constructor (only for initialisation of expr purposes) OperatorExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> main_or_left_expr, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - locus (locus), main_or_left_expr (std::move (main_or_left_expr)) - {} + AST::AttrVec outer_attribs, location_t locus); // Copy constructor (only for initialisation of expr purposes) - OperatorExpr (OperatorExpr const &other) - : ExprWithoutBlock (other), locus (other.locus), - main_or_left_expr (other.main_or_left_expr->clone_expr ()) - {} + OperatorExpr (OperatorExpr const &other); // Overload assignment operator to deep copy expr - OperatorExpr &operator= (OperatorExpr const &other) - { - ExprWithoutBlock::operator= (other); - main_or_left_expr = other.main_or_left_expr->clone_expr (); - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + OperatorExpr &operator= (OperatorExpr const &other); // move constructors OperatorExpr (OperatorExpr &&other) = default; @@ -209,7 +186,7 @@ protected: public: location_t get_locus () const override final { return locus; } - std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; } + Expr &get_expr () { return *main_or_left_expr; } ExprType get_expression_type () const override final { @@ -228,11 +205,7 @@ public: BorrowExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> borrow_lvalue, Mutability mut, - AST::AttrVec outer_attribs, location_t locus) - : OperatorExpr (std::move (mappings), std::move (borrow_lvalue), - std::move (outer_attribs), locus), - mut (mut) - {} + AST::AttrVec outer_attribs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -265,10 +238,7 @@ public: // Constructor calls OperatorExpr's protected constructor DereferenceExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> deref_lvalue, - AST::AttrVec outer_attribs, location_t locus) - : OperatorExpr (std::move (mappings), std::move (deref_lvalue), - std::move (outer_attribs), locus) - {} + AST::AttrVec outer_attribs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -298,10 +268,7 @@ public: // Constructor calls OperatorExpr's protected constructor ErrorPropagationExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> potential_error_value, - AST::AttrVec outer_attribs, location_t locus) - : OperatorExpr (std::move (mappings), std::move (potential_error_value), - std::move (outer_attribs), locus) - {} + AST::AttrVec outer_attribs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -342,11 +309,7 @@ public: // Constructor calls OperatorExpr's protected constructor NegationExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> negated_value, ExprType expr_kind, - AST::AttrVec outer_attribs, location_t locus) - : OperatorExpr (std::move (mappings), std::move (negated_value), - std::move (outer_attribs), locus), - expr_type (expr_kind) - {} + AST::AttrVec outer_attribs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -388,29 +351,14 @@ public: ArithmeticOrLogicalExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> left_value, std::unique_ptr<Expr> right_value, - ExprType expr_kind, location_t locus) - : OperatorExpr (std::move (mappings), std::move (left_value), - AST::AttrVec (), locus), - expr_type (expr_kind), right_expr (std::move (right_value)) - {} + ExprType expr_kind, location_t locus); // outer attributes not allowed // Copy constructor - probably required due to unique pointer - ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other) - : OperatorExpr (other), expr_type (other.expr_type), - right_expr (other.right_expr->clone_expr ()) - {} + ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other); // Overload assignment operator - ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - right_expr = other.right_expr->clone_expr (); - expr_type = other.expr_type; - - return *this; - } + ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other); // move constructors ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr &&other) = default; @@ -423,8 +371,8 @@ public: void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); } - std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; } - std::unique_ptr<Expr> &get_rhs () { return right_expr; } + Expr &get_lhs () { return *main_or_left_expr; } + Expr &get_rhs () { return *right_expr; } std::string get_operator_str () const; @@ -465,30 +413,14 @@ public: ComparisonExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> left_value, std::unique_ptr<Expr> right_value, ExprType comparison_kind, - location_t locus) - : OperatorExpr (std::move (mappings), std::move (left_value), - AST::AttrVec (), locus), - expr_type (comparison_kind), right_expr (std::move (right_value)) - {} + location_t locus); // outer attributes not allowed // Copy constructor also calls OperatorExpr's protected constructor - ComparisonExpr (ComparisonExpr const &other) - : OperatorExpr (other), expr_type (other.expr_type), - right_expr (other.right_expr->clone_expr ()) - {} + ComparisonExpr (ComparisonExpr const &other); // Overload assignment operator to deep copy - ComparisonExpr &operator= (ComparisonExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - right_expr = other.right_expr->clone_expr (); - expr_type = other.expr_type; - // outer_attrs = other.outer_attrs; - - return *this; - } + ComparisonExpr &operator= (ComparisonExpr const &other); // move constructors ComparisonExpr (ComparisonExpr &&other) = default; @@ -497,8 +429,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; } - std::unique_ptr<Expr> &get_rhs () { return right_expr; } + Expr &get_lhs () { return *main_or_left_expr; } + Expr &get_rhs () { return *right_expr; } ExprType get_kind () { return expr_type; } @@ -536,29 +468,14 @@ public: LazyBooleanExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> left_bool_expr, std::unique_ptr<Expr> right_bool_expr, ExprType expr_kind, - location_t locus) - : OperatorExpr (std::move (mappings), std::move (left_bool_expr), - AST::AttrVec (), locus), - expr_type (expr_kind), right_expr (std::move (right_bool_expr)) - {} + location_t locus); // outer attributes not allowed // Copy constructor also calls OperatorExpr's protected constructor - LazyBooleanExpr (LazyBooleanExpr const &other) - : OperatorExpr (other), expr_type (other.expr_type), - right_expr (other.right_expr->clone_expr ()) - {} + LazyBooleanExpr (LazyBooleanExpr const &other); // Overload assignment operator to deep copy - LazyBooleanExpr &operator= (LazyBooleanExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - right_expr = other.right_expr->clone_expr (); - expr_type = other.expr_type; - - return *this; - } + LazyBooleanExpr &operator= (LazyBooleanExpr const &other); // move constructors LazyBooleanExpr (LazyBooleanExpr &&other) = default; @@ -571,8 +488,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; } - std::unique_ptr<Expr> &get_rhs () { return right_expr; } + Expr &get_lhs () { return *main_or_left_expr; } + Expr &get_rhs () { return *right_expr; } protected: /* Use covariance to implement clone function as returning this object rather @@ -602,28 +519,14 @@ public: // Constructor requires calling protected constructor of OperatorExpr TypeCastExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr_to_cast, - std::unique_ptr<Type> type_to_cast_to, location_t locus) - : OperatorExpr (std::move (mappings), std::move (expr_to_cast), - AST::AttrVec (), locus), - type_to_convert_to (std::move (type_to_cast_to)) - {} + std::unique_ptr<Type> type_to_cast_to, location_t locus); // outer attributes not allowed // Copy constructor also requires calling protected constructor - TypeCastExpr (TypeCastExpr const &other) - : OperatorExpr (other), - type_to_convert_to (other.type_to_convert_to->clone_type ()) - {} + TypeCastExpr (TypeCastExpr const &other); // Overload assignment operator to deep copy - TypeCastExpr &operator= (TypeCastExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - type_to_convert_to = other.type_to_convert_to->clone_type (); - - return *this; - } + TypeCastExpr &operator= (TypeCastExpr const &other); // move constructors as not supported in c++03 TypeCastExpr (TypeCastExpr &&other) = default; @@ -633,12 +536,9 @@ public: void accept_vis (HIRExpressionVisitor &vis) override; // FIXME: isn't it the same as get_expr() from parent? - std::unique_ptr<Expr> &get_casted_expr () { return main_or_left_expr; } + Expr &get_casted_expr () { return *main_or_left_expr; } - std::unique_ptr<Type> &get_type_to_convert_to () - { - return type_to_convert_to; - } + Type &get_type_to_convert_to () { return *type_to_convert_to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -667,28 +567,14 @@ public: // Call OperatorExpr constructor to initialise left_expr AssignmentExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> value_to_assign_to, - std::unique_ptr<Expr> value_to_assign, location_t locus) - : OperatorExpr (std::move (mappings), std::move (value_to_assign_to), - AST::AttrVec (), locus), - right_expr (std::move (value_to_assign)) - {} + std::unique_ptr<Expr> value_to_assign, location_t locus); // outer attributes not allowed // Call OperatorExpr constructor in copy constructor, as well as clone - AssignmentExpr (AssignmentExpr const &other) - : OperatorExpr (other), right_expr (other.right_expr->clone_expr ()) - {} + AssignmentExpr (AssignmentExpr const &other); // Overload assignment operator to clone unique_ptr right_expr - AssignmentExpr &operator= (AssignmentExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - right_expr = other.right_expr->clone_expr (); - // outer_attrs = other.outer_attrs; - - return *this; - } + AssignmentExpr &operator= (AssignmentExpr const &other); // move constructors AssignmentExpr (AssignmentExpr &&other) = default; @@ -700,8 +586,8 @@ public: void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); } - std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; } - std::unique_ptr<Expr> &get_rhs () { return right_expr; } + Expr &get_lhs () { return *main_or_left_expr; } + Expr &get_rhs () { return *right_expr; } protected: /* Use covariance to implement clone function as returning this object rather @@ -738,30 +624,14 @@ public: CompoundAssignmentExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> value_to_assign_to, std::unique_ptr<Expr> value_to_assign, - ExprType expr_kind, location_t locus) - : OperatorExpr (std::move (mappings), std::move (value_to_assign_to), - AST::AttrVec (), locus), - expr_type (expr_kind), right_expr (std::move (value_to_assign)) - {} + ExprType expr_kind, location_t locus); // outer attributes not allowed // Have clone in copy constructor - CompoundAssignmentExpr (CompoundAssignmentExpr const &other) - : OperatorExpr (other), expr_type (other.expr_type), - right_expr (other.right_expr->clone_expr ()) - {} + CompoundAssignmentExpr (CompoundAssignmentExpr const &other); // Overload assignment operator to clone - CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - right_expr = other.right_expr->clone_expr (); - expr_type = other.expr_type; - // outer_attrs = other.outer_attrs; - - return *this; - } + CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other); // move constructors CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default; @@ -770,9 +640,9 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_lhs () { return main_or_left_expr; } + Expr &get_lhs () { return *main_or_left_expr; } - std::unique_ptr<Expr> &get_rhs () { return right_expr; } + Expr &get_rhs () { return *right_expr; } void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); } @@ -801,29 +671,13 @@ public: GroupedExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> parenthesised_expr, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - WithInnerAttrs (std::move (inner_attribs)), - expr_in_parens (std::move (parenthesised_expr)), locus (locus) - {} + location_t locus); // Copy constructor includes clone for expr_in_parens - GroupedExpr (GroupedExpr const &other) - : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs), - expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus) - {} + GroupedExpr (GroupedExpr const &other); // Overloaded assignment operator to clone expr_in_parens - GroupedExpr &operator= (GroupedExpr const &other) - { - ExprWithoutBlock::operator= (other); - inner_attrs = other.inner_attrs; - expr_in_parens = other.expr_in_parens->clone_expr (); - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + GroupedExpr &operator= (GroupedExpr const &other); // move constructors GroupedExpr (GroupedExpr &&other) = default; @@ -834,7 +688,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_expr_in_parens () { return expr_in_parens; } + Expr &get_expr_in_parens () { return *expr_in_parens; } ExprType get_expression_type () const override final { @@ -896,33 +750,19 @@ protected: // Value array elements class ArrayElemsValues : public ArrayElems { - std::vector<std::unique_ptr<Expr> > values; + std::vector<std::unique_ptr<Expr>> values; // TODO: should this store location data? public: ArrayElemsValues (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Expr> > elems) - : ArrayElems (mappings), values (std::move (elems)) - {} + std::vector<std::unique_ptr<Expr>> elems); // copy constructor with vector clone - ArrayElemsValues (ArrayElemsValues const &other) : ArrayElems (other) - { - values.reserve (other.values.size ()); - for (const auto &e : other.values) - values.push_back (e->clone_expr ()); - } + ArrayElemsValues (ArrayElemsValues const &other); // overloaded assignment operator with vector clone - ArrayElemsValues &operator= (ArrayElemsValues const &other) - { - values.reserve (other.values.size ()); - for (const auto &e : other.values) - values.push_back (e->clone_expr ()); - - return *this; - } + ArrayElemsValues &operator= (ArrayElemsValues const &other); // move constructors ArrayElemsValues (ArrayElemsValues &&other) = default; @@ -934,7 +774,7 @@ public: size_t get_num_elements () const { return values.size (); } - std::vector<std::unique_ptr<Expr> > &get_values () { return values; } + std::vector<std::unique_ptr<Expr>> &get_values () { return values; } ArrayElems::ArrayExprType get_array_expr_type () const override final { @@ -958,25 +798,13 @@ public: // Constructor requires pointers for polymorphism ArrayElemsCopied (Analysis::NodeMapping mappings, std::unique_ptr<Expr> copied_elem, - std::unique_ptr<Expr> copy_amount) - : ArrayElems (mappings), elem_to_copy (std::move (copied_elem)), - num_copies (std::move (copy_amount)) - {} + std::unique_ptr<Expr> copy_amount); // Copy constructor required due to unique_ptr - uses custom clone - ArrayElemsCopied (ArrayElemsCopied const &other) - : ArrayElems (other), elem_to_copy (other.elem_to_copy->clone_expr ()), - num_copies (other.num_copies->clone_expr ()) - {} + ArrayElemsCopied (ArrayElemsCopied const &other); // Overloaded assignment operator for deep copying - ArrayElemsCopied &operator= (ArrayElemsCopied const &other) - { - elem_to_copy = other.elem_to_copy->clone_expr (); - num_copies = other.num_copies->clone_expr (); - - return *this; - } + ArrayElemsCopied &operator= (ArrayElemsCopied const &other); // move constructors ArrayElemsCopied (ArrayElemsCopied &&other) = default; @@ -986,9 +814,9 @@ public: void accept_vis (HIRFullVisitor &vis) override; - std::unique_ptr<Expr> &get_elem_to_copy () { return elem_to_copy; } + Expr &get_elem_to_copy () { return *elem_to_copy; } - std::unique_ptr<Expr> &get_num_copies_expr () { return num_copies; } + Expr &get_num_copies_expr () { return *num_copies; } ArrayElems::ArrayExprType get_array_expr_type () const override final { @@ -1019,33 +847,13 @@ public: ArrayExpr (Analysis::NodeMapping mappings, std::unique_ptr<ArrayElems> array_elems, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - WithInnerAttrs (std::move (inner_attribs)), - internal_elements (std::move (array_elems)), locus (locus) - {} + location_t locus); // Copy constructor requires cloning ArrayElems for polymorphism to hold - ArrayExpr (ArrayExpr const &other) - : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs), - locus (other.locus) - { - if (other.has_array_elems ()) - internal_elements = other.internal_elements->clone_array_elems (); - } + ArrayExpr (ArrayExpr const &other); // Overload assignment operator to clone internal_elements - ArrayExpr &operator= (ArrayExpr const &other) - { - ExprWithoutBlock::operator= (other); - inner_attrs = other.inner_attrs; - if (other.has_array_elems ()) - internal_elements = other.internal_elements->clone_array_elems (); - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + ArrayExpr &operator= (ArrayExpr const &other); // move constructors ArrayExpr (ArrayExpr &&other) = default; @@ -1056,10 +864,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<ArrayElems> &get_internal_elements () - { - return internal_elements; - }; + ArrayElems &get_internal_elements () { return *internal_elements; }; ExprType get_expression_type () const override final { @@ -1092,29 +897,13 @@ public: ArrayIndexExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> array_expr, std::unique_ptr<Expr> array_index_expr, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - array_expr (std::move (array_expr)), - index_expr (std::move (array_index_expr)), locus (locus) - {} + AST::AttrVec outer_attribs, location_t locus); // Copy constructor requires special cloning due to unique_ptr - ArrayIndexExpr (ArrayIndexExpr const &other) - : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()), - index_expr (other.index_expr->clone_expr ()), locus (other.locus) - {} + ArrayIndexExpr (ArrayIndexExpr const &other); // Overload assignment operator to clone unique_ptrs - ArrayIndexExpr &operator= (ArrayIndexExpr const &other) - { - ExprWithoutBlock::operator= (other); - array_expr = other.array_expr->clone_expr (); - index_expr = other.index_expr->clone_expr (); - // outer_attrs = other.outer_attrs; - locus = other.locus; - - return *this; - } + ArrayIndexExpr &operator= (ArrayIndexExpr const &other); // move constructors ArrayIndexExpr (ArrayIndexExpr &&other) = default; @@ -1125,8 +914,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_array_expr () { return array_expr; } - std::unique_ptr<Expr> &get_index_expr () { return index_expr; } + Expr &get_array_expr () { return *array_expr; } + Expr &get_index_expr () { return *index_expr; } ExprType get_expression_type () const override final { @@ -1152,7 +941,7 @@ protected: // HIR representation of a tuple class TupleExpr : public ExprWithoutBlock, public WithInnerAttrs { - std::vector<std::unique_ptr<Expr> > tuple_elems; + std::vector<std::unique_ptr<Expr>> tuple_elems; // replaces (inlined version of) TupleElements location_t locus; @@ -1161,37 +950,15 @@ public: std::string as_string () const override; TupleExpr (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Expr> > tuple_elements, + std::vector<std::unique_ptr<Expr>> tuple_elements, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - WithInnerAttrs (std::move (inner_attribs)), - tuple_elems (std::move (tuple_elements)), locus (locus) - {} + location_t locus); // copy constructor with vector clone - TupleExpr (TupleExpr const &other) - : ExprWithoutBlock (other), WithInnerAttrs (other.inner_attrs), - locus (other.locus) - { - tuple_elems.reserve (other.tuple_elems.size ()); - for (const auto &e : other.tuple_elems) - tuple_elems.push_back (e->clone_expr ()); - } + TupleExpr (TupleExpr const &other); // overloaded assignment operator to vector clone - TupleExpr &operator= (TupleExpr const &other) - { - ExprWithoutBlock::operator= (other); - inner_attrs = other.inner_attrs; - locus = other.locus; - - tuple_elems.reserve (other.tuple_elems.size ()); - for (const auto &e : other.tuple_elems) - tuple_elems.push_back (e->clone_expr ()); - - return *this; - } + TupleExpr &operator= (TupleExpr const &other); // move constructors TupleExpr (TupleExpr &&other) = default; @@ -1205,14 +972,11 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const - { - return tuple_elems; - } - std::vector<std::unique_ptr<Expr> > &get_tuple_elems () + const std::vector<std::unique_ptr<Expr>> &get_tuple_elems () const { return tuple_elems; } + std::vector<std::unique_ptr<Expr>> &get_tuple_elems () { return tuple_elems; } bool is_unit () const { return tuple_elems.size () == 0; } @@ -1247,28 +1011,13 @@ public: TupleIndexExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> tuple_expr, TupleIndex index, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus) - {} + AST::AttrVec outer_attribs, location_t locus); // Copy constructor requires a clone for tuple_expr - TupleIndexExpr (TupleIndexExpr const &other) - : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()), - tuple_index (other.tuple_index), locus (other.locus) - {} + TupleIndexExpr (TupleIndexExpr const &other); // Overload assignment operator in order to clone - TupleIndexExpr &operator= (TupleIndexExpr const &other) - { - ExprWithoutBlock::operator= (other); - tuple_expr = other.tuple_expr->clone_expr (); - tuple_index = other.tuple_index; - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + TupleIndexExpr &operator= (TupleIndexExpr const &other); // move constructors TupleIndexExpr (TupleIndexExpr &&other) = default; @@ -1279,7 +1028,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_tuple_expr () { return tuple_expr; } + Expr &get_tuple_expr () { return *tuple_expr; } ExprType get_expression_type () const override final { @@ -1310,10 +1059,7 @@ protected: // Protected constructor to allow initialising struct_name StructExpr (Analysis::NodeMapping mappings, PathInExpression struct_path, - AST::AttrVec outer_attribs) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - struct_name (std::move (struct_path)) - {} + AST::AttrVec outer_attribs); public: PathInExpression &get_struct_name () { return struct_name; } @@ -1337,11 +1083,7 @@ public: // Constructor has to call protected constructor of base class StructExprStruct (Analysis::NodeMapping mappings, PathInExpression struct_path, AST::AttrVec inner_attribs, - AST::AttrVec outer_attribs, location_t locus) - : StructExpr (std::move (mappings), std::move (struct_path), - std::move (outer_attribs)), - WithInnerAttrs (std::move (inner_attribs)), locus (locus) - {} + AST::AttrVec outer_attribs, location_t locus); location_t get_locus () const override final { return locus; } @@ -1368,33 +1110,21 @@ protected: * struct */ struct StructBase { -public: +private: std::unique_ptr<Expr> base_struct; +public: // TODO: should this store location data? - StructBase (std::unique_ptr<Expr> base_struct_ptr) - : base_struct (std::move (base_struct_ptr)) - {} + StructBase (std::unique_ptr<Expr> base_struct_ptr); // Copy constructor requires clone - StructBase (StructBase const &other) - { - /* HACK: gets around base_struct pointer being null (e.g. if no struct base - * exists) */ - if (other.base_struct != nullptr) - other.base_struct->clone_expr (); - } + StructBase (StructBase const &other); // Destructor ~StructBase () = default; // Overload assignment operator to clone base_struct - StructBase &operator= (StructBase const &other) - { - base_struct = other.base_struct->clone_expr (); - - return *this; - } + StructBase &operator= (StructBase const &other); // move constructors StructBase (StructBase &&other) = default; @@ -1408,7 +1138,7 @@ public: std::string as_string () const; - Expr *get_base () { return base_struct.get (); } + Expr &get_base () { return *base_struct; } }; /* Base HIR node for a single struct expression field (in struct instance @@ -1446,9 +1176,7 @@ protected: // pure virtual clone implementation virtual StructExprField *clone_struct_expr_field_impl () const = 0; - StructExprField (Analysis::NodeMapping mapping, location_t locus) - : mappings (mapping), locus (locus) - {} + StructExprField (Analysis::NodeMapping mapping, location_t locus); Analysis::NodeMapping mappings; location_t locus; @@ -1463,10 +1191,7 @@ private: // TODO: should this store location data? public: StructExprFieldIdentifier (Analysis::NodeMapping mapping, - Identifier field_identifier, location_t locus) - : StructExprField (mapping, locus), - field_name (std::move (field_identifier)) - {} + Identifier field_identifier, location_t locus); std::string as_string () const override { return field_name.as_string (); } @@ -1497,25 +1222,13 @@ class StructExprFieldWithVal : public StructExprField protected: StructExprFieldWithVal (Analysis::NodeMapping mapping, - std::unique_ptr<Expr> field_value, location_t locus) - : StructExprField (mapping, locus), value (std::move (field_value)) - {} + std::unique_ptr<Expr> field_value, location_t locus); // Copy constructor requires clone - StructExprFieldWithVal (StructExprFieldWithVal const &other) - : StructExprField (other.mappings, other.locus), - value (other.value->clone_expr ()) - {} + StructExprFieldWithVal (StructExprFieldWithVal const &other); // Overload assignment operator to clone unique_ptr - StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other) - { - value = other.value->clone_expr (); - mappings = other.mappings; - locus = other.locus; - - return *this; - } + StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other); // move constructors StructExprFieldWithVal (StructExprFieldWithVal &&other) = default; @@ -1524,7 +1237,7 @@ protected: public: std::string as_string () const override; - std::unique_ptr<Expr> &get_value () { return value; } + Expr &get_value () { return *value; } }; // Identifier and value variant of StructExprField HIR node @@ -1538,10 +1251,7 @@ public: StructExprFieldIdentifierValue (Analysis::NodeMapping mapping, Identifier field_identifier, std::unique_ptr<Expr> field_value, - location_t locus) - : StructExprFieldWithVal (mapping, std::move (field_value), locus), - field_name (std::move (field_identifier)) - {} + location_t locus); std::string as_string () const override; @@ -1575,10 +1285,7 @@ public: StructExprFieldIndexValue (Analysis::NodeMapping mapping, TupleIndex tuple_index, std::unique_ptr<Expr> field_value, - location_t locus) - : StructExprFieldWithVal (mapping, std::move (field_value), locus), - index (tuple_index) - {} + location_t locus); std::string as_string () const override; @@ -1604,58 +1311,31 @@ protected: // HIR node of a struct creator with fields class StructExprStructFields : public StructExprStruct { -public: // std::vector<StructExprField> fields; - std::vector<std::unique_ptr<StructExprField> > fields; - - // bool has_struct_base; - // FIXME make unique_ptr - StructBase *struct_base; + std::vector<std::unique_ptr<StructExprField>> fields; + tl::optional<std::unique_ptr<StructBase>> struct_base; +public: // For unions there is just one field, the index // is set when type checking int union_index = -1; std::string as_string () const override; - bool has_struct_base () const { return struct_base != nullptr; } + bool has_struct_base () const { return struct_base.has_value (); } // Constructor for StructExprStructFields when no struct base is used StructExprStructFields ( Analysis::NodeMapping mappings, PathInExpression struct_path, - std::vector<std::unique_ptr<StructExprField> > expr_fields, - location_t locus, StructBase *base_struct, - AST::AttrVec inner_attribs = AST::AttrVec (), - AST::AttrVec outer_attribs = AST::AttrVec ()) - : StructExprStruct (std::move (mappings), std::move (struct_path), - std::move (inner_attribs), std::move (outer_attribs), - locus), - fields (std::move (expr_fields)), struct_base (base_struct) - {} + std::vector<std::unique_ptr<StructExprField>> expr_fields, location_t locus, + tl::optional<std::unique_ptr<StructBase>> base_struct, + AST::AttrVec inner_attribs, AST::AttrVec outer_attribs); // copy constructor with vector clone - StructExprStructFields (StructExprStructFields const &other) - : StructExprStruct (other), struct_base (other.struct_base), - union_index (other.union_index) - { - fields.reserve (other.fields.size ()); - for (const auto &e : other.fields) - fields.push_back (e->clone_struct_expr_field ()); - } + StructExprStructFields (StructExprStructFields const &other); // overloaded assignment operator with vector clone - StructExprStructFields &operator= (StructExprStructFields const &other) - { - StructExprStruct::operator= (other); - struct_base = other.struct_base; - union_index = other.union_index; - - fields.reserve (other.fields.size ()); - for (const auto &e : other.fields) - fields.push_back (e->clone_struct_expr_field ()); - - return *this; - } + StructExprStructFields &operator= (StructExprStructFields const &other); // move constructors StructExprStructFields (StructExprStructFields &&other) = default; @@ -1664,20 +1344,20 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::vector<std::unique_ptr<StructExprField> > &get_fields () + std::vector<std::unique_ptr<StructExprField>> &get_fields () { return fields; }; - const std::vector<std::unique_ptr<StructExprField> > &get_fields () const + const std::vector<std::unique_ptr<StructExprField>> &get_fields () const { return fields; }; - StructBase *get_struct_base () { return struct_base; } + StructBase &get_struct_base () { return *struct_base.value (); } - void set_fields_as_owner ( - std::vector<std::unique_ptr<StructExprField> > new_fields) + void + set_fields_as_owner (std::vector<std::unique_ptr<StructExprField>> new_fields) { fields = std::move (new_fields); } @@ -1704,26 +1384,15 @@ class StructExprStructBase : public StructExprStruct StructBase struct_base; public: - std::string as_string () const override; - - /*inline StructBase get_struct_base() const { - return struct_base; - }*/ - StructExprStructBase (Analysis::NodeMapping mappings, PathInExpression struct_path, StructBase base_struct, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - location_t locus) - : StructExprStruct (std::move (mappings), std::move (struct_path), - std::move (inner_attribs), std::move (outer_attribs), - locus), - struct_base (std::move (base_struct)) - {} + location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - StructBase *get_struct_base () { return &struct_base; } + StructBase &get_struct_base () { return struct_base; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1745,45 +1414,21 @@ protected: class CallExpr : public ExprWithoutBlock { std::unique_ptr<Expr> function; - std::vector<std::unique_ptr<Expr> > params; + std::vector<std::unique_ptr<Expr>> params; location_t locus; public: std::string as_string () const override; CallExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> function_expr, - std::vector<std::unique_ptr<Expr> > function_params, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - function (std::move (function_expr)), - params (std::move (function_params)), locus (locus) - {} + std::vector<std::unique_ptr<Expr>> function_params, + AST::AttrVec outer_attribs, location_t locus); // copy constructor requires clone - CallExpr (CallExpr const &other) - : ExprWithoutBlock (other), function (other.function->clone_expr ()), - locus (other.locus) - /*, params(other.params),*/ { - params.reserve (other.params.size ()); - for (const auto &e : other.params) - params.push_back (e->clone_expr ()); - } + CallExpr (CallExpr const &other); // Overload assignment operator to clone - CallExpr &operator= (CallExpr const &other) - { - ExprWithoutBlock::operator= (other); - function = other.function->clone_expr (); - locus = other.locus; - // params = other.params; - // outer_attrs = other.outer_attrs; - - params.reserve (other.params.size ()); - for (const auto &e : other.params) - params.push_back (e->clone_expr ()); - - return *this; - } + CallExpr &operator= (CallExpr const &other); // move constructors CallExpr (CallExpr &&other) = default; @@ -1797,13 +1442,14 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_fnexpr () { return function; } + bool has_fnexpr () const { return function != nullptr; } + Expr &get_fnexpr () { return *function; } size_t num_params () const { return params.size (); } - std::vector<std::unique_ptr<Expr> > &get_arguments () { return params; } + std::vector<std::unique_ptr<Expr>> &get_arguments () { return params; } - const std::vector<std::unique_ptr<Expr> > &get_arguments () const + const std::vector<std::unique_ptr<Expr>> &get_arguments () const { return params; } @@ -1831,7 +1477,7 @@ class MethodCallExpr : public ExprWithoutBlock { std::unique_ptr<Expr> receiver; PathExprSegment method_name; - std::vector<std::unique_ptr<Expr> > params; + std::vector<std::unique_ptr<Expr>> params; location_t locus; public: @@ -1840,40 +1486,14 @@ public: MethodCallExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> call_receiver, PathExprSegment method_path, - std::vector<std::unique_ptr<Expr> > method_params, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - receiver (std::move (call_receiver)), - method_name (std::move (method_path)), params (std::move (method_params)), - locus (locus) - {} + std::vector<std::unique_ptr<Expr>> method_params, + AST::AttrVec outer_attribs, location_t locus); // copy constructor required due to cloning - MethodCallExpr (MethodCallExpr const &other) - : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()), - method_name (other.method_name), locus (other.locus) - /*, params(other.params),*/ { - params.reserve (other.params.size ()); - for (const auto &e : other.params) - params.push_back (e->clone_expr ()); - } + MethodCallExpr (MethodCallExpr const &other); // Overload assignment operator to clone receiver object - MethodCallExpr &operator= (MethodCallExpr const &other) - { - ExprWithoutBlock::operator= (other); - receiver = other.receiver->clone_expr (); - method_name = other.method_name; - locus = other.locus; - // params = other.params; - // outer_attrs = other.outer_attrs; - - params.reserve (other.params.size ()); - for (const auto &e : other.params) - params.push_back (e->clone_expr ()); - - return *this; - } + MethodCallExpr &operator= (MethodCallExpr const &other); // move constructors MethodCallExpr (MethodCallExpr &&other) = default; @@ -1884,7 +1504,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_receiver () { return receiver; } + Expr &get_receiver () { return *receiver; } PathExprSegment &get_method_name () { return method_name; }; const PathExprSegment &get_method_name () const { return method_name; }; @@ -1892,9 +1512,9 @@ public: bool has_params () const { return !params.empty (); } size_t num_params () const { return params.size (); } - std::vector<std::unique_ptr<Expr> > &get_arguments () { return params; } + std::vector<std::unique_ptr<Expr>> &get_arguments () { return params; } - const std::vector<std::unique_ptr<Expr> > &get_arguments () const + const std::vector<std::unique_ptr<Expr>> &get_arguments () const { return params; } @@ -1935,29 +1555,13 @@ public: FieldAccessExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> field_access_receiver, Identifier field_name, AST::AttrVec outer_attribs, - location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - receiver (std::move (field_access_receiver)), - field (std::move (field_name)), locus (locus) - {} + location_t locus); // Copy constructor required due to unique_ptr cloning - FieldAccessExpr (FieldAccessExpr const &other) - : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()), - field (other.field), locus (other.locus) - {} + FieldAccessExpr (FieldAccessExpr const &other); // Overload assignment operator to clone unique_ptr - FieldAccessExpr &operator= (FieldAccessExpr const &other) - { - ExprWithoutBlock::operator= (other); - receiver = other.receiver->clone_expr (); - field = other.field; - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + FieldAccessExpr &operator= (FieldAccessExpr const &other); // move constructors FieldAccessExpr (FieldAccessExpr &&other) = default; @@ -1968,7 +1572,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_receiver_expr () { return receiver; } + Expr &get_receiver_expr () { return *receiver; } Identifier get_field_name () const { return field; } @@ -2009,42 +1613,15 @@ public: // Constructor for closure parameter ClosureParam (std::unique_ptr<Pattern> param_pattern, location_t locus, std::unique_ptr<Type> param_type = nullptr, - std::vector<AST::Attribute> outer_attrs = {}) - : outer_attrs (std::move (outer_attrs)), - pattern (std::move (param_pattern)), type (std::move (param_type)), - locus (locus) - {} + std::vector<AST::Attribute> outer_attrs = {}); // Copy constructor required due to cloning as a result of unique_ptrs - ClosureParam (ClosureParam const &other) - : pattern (other.pattern->clone_pattern ()) - { - // guard to protect from null pointer dereference - if (other.pattern != nullptr) - pattern = other.pattern->clone_pattern (); - if (other.type != nullptr) - type = other.type->clone_type (); - } + ClosureParam (ClosureParam const &other); ~ClosureParam () = default; // Assignment operator must be overloaded to clone as well - ClosureParam &operator= (ClosureParam const &other) - { - outer_attrs = other.outer_attrs; - - // guard to protect from null pointer dereference - if (other.pattern != nullptr) - pattern = other.pattern->clone_pattern (); - else - pattern = nullptr; - if (other.type != nullptr) - type = other.type->clone_type (); - else - type = nullptr; - - return *this; - } + ClosureParam &operator= (ClosureParam const &other); // move constructors ClosureParam (ClosureParam &&other) = default; @@ -2058,9 +1635,9 @@ public: } std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; } - std::unique_ptr<Pattern> &get_pattern () { return pattern; } + Pattern &get_pattern () { return *pattern; } - std::unique_ptr<Type> &get_type () { return type; } + Type &get_type () { return *type; } location_t get_locus () const { return locus; } }; @@ -2080,36 +1657,13 @@ public: std::vector<ClosureParam> closure_params, std::unique_ptr<Type> closure_return_type, std::unique_ptr<Expr> closure_expr, bool has_move, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - has_move (has_move), params (std::move (closure_params)), locus (locus), - return_type (std::move (closure_return_type)), - expr (std::move (closure_expr)) - {} + AST::AttrVec outer_attribs, location_t locus); // Copy constructor requires cloning - ClosureExpr (ClosureExpr const &other) - : ExprWithoutBlock (other.get_mappings (), other.get_outer_attrs ()) - { - return_type - = other.has_return_type () ? other.return_type->clone_type () : nullptr; - expr = other.expr->clone_expr (); - params = other.params; - has_move = other.has_move; - } + ClosureExpr (ClosureExpr const &other); // Overload assignment operator to clone unique_ptrs - ClosureExpr &operator= (ClosureExpr const &other) - { - mappings = other.mappings; - return_type - = other.has_return_type () ? other.return_type->clone_type () : nullptr; - expr = other.expr->clone_expr (); - params = other.params; - has_move = other.has_move; - - return *this; - } + ClosureExpr &operator= (ClosureExpr const &other); // move constructors ClosureExpr (ClosureExpr &&other) = default; @@ -2128,8 +1682,8 @@ public: bool has_return_type () const { return return_type != nullptr; } - std::unique_ptr<Type> &get_return_type () { return return_type; }; - std::unique_ptr<Expr> &get_expr () { return expr; } + Type &get_return_type () { return *return_type; }; + Expr &get_expr () { return *expr; } bool has_params () const { return !params.empty (); } std::vector<ClosureParam> &get_params () { return params; } @@ -2158,7 +1712,7 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs { // FIXME this should be private + get/set public: - std::vector<std::unique_ptr<Stmt> > statements; + std::vector<std::unique_ptr<Stmt>> statements; std::unique_ptr<Expr> expr; bool tail_reachable; LoopLabel label; @@ -2178,49 +1732,16 @@ public: bool is_tail_reachable () const { return tail_reachable; } BlockExpr (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Stmt> > block_statements, + std::vector<std::unique_ptr<Stmt>> block_statements, std::unique_ptr<Expr> block_expr, bool tail_reachable, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - LoopLabel label, location_t start_locus, location_t end_locus) - : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), - WithInnerAttrs (std::move (inner_attribs)), - statements (std::move (block_statements)), expr (std::move (block_expr)), - tail_reachable (tail_reachable), label (std::move (label)), - start_locus (start_locus), end_locus (end_locus) - {} + LoopLabel label, location_t start_locus, location_t end_locus); // Copy constructor with clone - BlockExpr (BlockExpr const &other) - : ExprWithBlock (other), /*statements(other.statements),*/ - WithInnerAttrs (other.inner_attrs), label (other.label), - start_locus (other.start_locus), end_locus (other.end_locus) - { - // guard to protect from null pointer dereference - if (other.expr != nullptr) - expr = other.expr->clone_expr (); - - statements.reserve (other.statements.size ()); - for (const auto &e : other.statements) - statements.push_back (e->clone_stmt ()); - } + BlockExpr (BlockExpr const &other); // Overloaded assignment operator to clone pointer - BlockExpr &operator= (BlockExpr const &other) - { - ExprWithBlock::operator= (other); - // statements = other.statements; - expr = other.expr->clone_expr (); - inner_attrs = other.inner_attrs; - start_locus = other.end_locus; - end_locus = other.end_locus; - // outer_attrs = other.outer_attrs; - - statements.reserve (other.statements.size ()); - for (const auto &e : other.statements) - statements.push_back (e->clone_stmt ()); - - return *this; - } + BlockExpr &operator= (BlockExpr const &other); // move constructors BlockExpr (BlockExpr &&other) = default; @@ -2243,9 +1764,10 @@ public: bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; } - std::unique_ptr<Expr> &get_final_expr () { return expr; } + bool has_final_expr () { return expr != nullptr; } + Expr &get_final_expr () { return *expr; } - std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; } + std::vector<std::unique_ptr<Stmt>> &get_statements () { return statements; } ExprType get_expression_type () const final override { @@ -2292,10 +1814,7 @@ public: // Constructor for a ContinueExpr with a label. ContinueExpr (Analysis::NodeMapping mappings, location_t locus, - Lifetime label, AST::AttrVec outer_attribs = AST::AttrVec ()) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - label (std::move (label)), locus (locus) - {} + Lifetime label, AST::AttrVec outer_attribs = AST::AttrVec ()); location_t get_locus () const override final { return locus; } @@ -2350,32 +1869,13 @@ public: BreakExpr (Analysis::NodeMapping mappings, location_t locus, Lifetime break_label, std::unique_ptr<Expr> expr_in_break = nullptr, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - label (std::move (break_label)), break_expr (std::move (expr_in_break)), - locus (locus) - {} + AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor defined to use clone for unique pointer - BreakExpr (BreakExpr const &other) - : ExprWithoutBlock (other), label (other.label), locus (other.locus) - { - // guard to protect from null pointer dereference - if (other.break_expr != nullptr) - break_expr = other.break_expr->clone_expr (); - } + BreakExpr (BreakExpr const &other); // Overload assignment operator to clone unique pointer - BreakExpr &operator= (BreakExpr const &other) - { - ExprWithoutBlock::operator= (other); - label = other.label; - break_expr = other.break_expr->clone_expr (); - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + BreakExpr &operator= (BreakExpr const &other); // move constructors BreakExpr (BreakExpr &&other) = default; @@ -2388,7 +1888,7 @@ public: Lifetime &get_label () { return label; } - std::unique_ptr<Expr> &get_expr () { return break_expr; } + Expr &get_expr () { return *break_expr; } ExprType get_expression_type () const override final { @@ -2415,9 +1915,7 @@ class RangeExpr : public ExprWithoutBlock protected: // outer attributes not allowed before range expressions - RangeExpr (Analysis::NodeMapping mappings, location_t locus) - : ExprWithoutBlock (std::move (mappings), AST::AttrVec ()), locus (locus) - {} + RangeExpr (Analysis::NodeMapping mappings, location_t locus); public: location_t get_locus () const override final { return locus; } @@ -2440,26 +1938,13 @@ public: RangeFromToExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> range_from, - std::unique_ptr<Expr> range_to, location_t locus) - : RangeExpr (std::move (mappings), locus), from (std::move (range_from)), - to (std::move (range_to)) - {} + std::unique_ptr<Expr> range_to, location_t locus); // Copy constructor with cloning - RangeFromToExpr (RangeFromToExpr const &other) - : RangeExpr (other), from (other.from->clone_expr ()), - to (other.to->clone_expr ()) - {} + RangeFromToExpr (RangeFromToExpr const &other); // Overload assignment operator to clone unique pointers - RangeFromToExpr &operator= (RangeFromToExpr const &other) - { - RangeExpr::operator= (other); - from = other.from->clone_expr (); - to = other.to->clone_expr (); - - return *this; - } + RangeFromToExpr &operator= (RangeFromToExpr const &other); // move constructors RangeFromToExpr (RangeFromToExpr &&other) = default; @@ -2468,8 +1953,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_from_expr () { return from; } - std::unique_ptr<Expr> &get_to_expr () { return to; } + Expr &get_from_expr () { return *from; } + Expr &get_to_expr () { return *to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2497,23 +1982,13 @@ public: std::string as_string () const override; RangeFromExpr (Analysis::NodeMapping mappings, - std::unique_ptr<Expr> range_from, location_t locus) - : RangeExpr (std::move (mappings), locus), from (std::move (range_from)) - {} + std::unique_ptr<Expr> range_from, location_t locus); // Copy constructor with clone - RangeFromExpr (RangeFromExpr const &other) - : RangeExpr (other), from (other.from->clone_expr ()) - {} + RangeFromExpr (RangeFromExpr const &other); // Overload assignment operator to clone unique_ptr - RangeFromExpr &operator= (RangeFromExpr const &other) - { - RangeExpr::operator= (other); - from = other.from->clone_expr (); - - return *this; - } + RangeFromExpr &operator= (RangeFromExpr const &other); // move constructors RangeFromExpr (RangeFromExpr &&other) = default; @@ -2522,7 +1997,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_from_expr () { return from; } + Expr &get_from_expr () { return *from; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2551,23 +2026,13 @@ public: // outer attributes not allowed RangeToExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> range_to, - location_t locus) - : RangeExpr (std::move (mappings), locus), to (std::move (range_to)) - {} + location_t locus); // Copy constructor with clone - RangeToExpr (RangeToExpr const &other) - : RangeExpr (other), to (other.to->clone_expr ()) - {} + RangeToExpr (RangeToExpr const &other); // Overload assignment operator to clone unique_ptr - RangeToExpr &operator= (RangeToExpr const &other) - { - RangeExpr::operator= (other); - to = other.to->clone_expr (); - - return *this; - } + RangeToExpr &operator= (RangeToExpr const &other); // move constructors RangeToExpr (RangeToExpr &&other) = default; @@ -2576,7 +2041,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_to_expr () { return to; } + Expr &get_to_expr () { return *to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2601,9 +2066,7 @@ class RangeFullExpr : public RangeExpr public: std::string as_string () const override; - RangeFullExpr (Analysis::NodeMapping mappings, location_t locus) - : RangeExpr (std::move (mappings), locus) - {} + RangeFullExpr (Analysis::NodeMapping mappings, location_t locus); // outer attributes not allowed void accept_vis (HIRFullVisitor &vis) override; @@ -2637,27 +2100,14 @@ public: RangeFromToInclExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> range_from, - std::unique_ptr<Expr> range_to, location_t locus) - : RangeExpr (std::move (mappings), locus), from (std::move (range_from)), - to (std::move (range_to)) - {} + std::unique_ptr<Expr> range_to, location_t locus); // outer attributes not allowed // Copy constructor with clone - RangeFromToInclExpr (RangeFromToInclExpr const &other) - : RangeExpr (other), from (other.from->clone_expr ()), - to (other.to->clone_expr ()) - {} + RangeFromToInclExpr (RangeFromToInclExpr const &other); // Overload assignment operator to use clone - RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other) - { - RangeExpr::operator= (other); - from = other.from->clone_expr (); - to = other.to->clone_expr (); - - return *this; - } + RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other); // move constructors RangeFromToInclExpr (RangeFromToInclExpr &&other) = default; @@ -2666,8 +2116,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_from_expr () { return from; } - std::unique_ptr<Expr> &get_to_expr () { return to; } + Expr &get_from_expr () { return *from; } + Expr &get_to_expr () { return *to; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2695,24 +2145,14 @@ public: std::string as_string () const override; RangeToInclExpr (Analysis::NodeMapping mappings, - std::unique_ptr<Expr> range_to, location_t locus) - : RangeExpr (std::move (mappings), locus), to (std::move (range_to)) - {} + std::unique_ptr<Expr> range_to, location_t locus); // outer attributes not allowed // Copy constructor with clone - RangeToInclExpr (RangeToInclExpr const &other) - : RangeExpr (other), to (other.to->clone_expr ()) - {} + RangeToInclExpr (RangeToInclExpr const &other); // Overload assignment operator to clone pointer - RangeToInclExpr &operator= (RangeToInclExpr const &other) - { - RangeExpr::operator= (other); - to = other.to->clone_expr (); - - return *this; - } + RangeToInclExpr &operator= (RangeToInclExpr const &other); // move constructors RangeToInclExpr (RangeToInclExpr &&other) = default; @@ -2721,7 +2161,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_to_expr () { return to; }; + Expr &get_to_expr () { return *to; }; protected: /* Use covariance to implement clone function as returning this object rather @@ -2756,30 +2196,13 @@ public: // Constructor for ReturnExpr. ReturnExpr (Analysis::NodeMapping mappings, location_t locus, std::unique_ptr<Expr> returned_expr = nullptr, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - return_expr (std::move (returned_expr)), locus (locus) - {} + AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor with clone - ReturnExpr (ReturnExpr const &other) - : ExprWithoutBlock (other), locus (other.locus) - { - // guard to protect from null pointer dereference - if (other.return_expr != nullptr) - return_expr = other.return_expr->clone_expr (); - } + ReturnExpr (ReturnExpr const &other); // Overloaded assignment operator to clone return_expr pointer - ReturnExpr &operator= (ReturnExpr const &other) - { - ExprWithoutBlock::operator= (other); - return_expr = other.return_expr->clone_expr (); - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + ReturnExpr &operator= (ReturnExpr const &other); // move constructors ReturnExpr (ReturnExpr &&other) = default; @@ -2790,7 +2213,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_expr () { return return_expr; } + bool has_expr () { return return_expr != nullptr; } + Expr &get_expr () { return *return_expr; } ExprType get_expression_type () const override final { @@ -2825,27 +2249,13 @@ public: UnsafeBlockExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> block_expr, - AST::AttrVec outer_attribs, location_t locus) - : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), - expr (std::move (block_expr)), locus (locus) - {} + AST::AttrVec outer_attribs, location_t locus); // Copy constructor with clone - UnsafeBlockExpr (UnsafeBlockExpr const &other) - : ExprWithBlock (other), expr (other.expr->clone_block_expr ()), - locus (other.locus) - {} + UnsafeBlockExpr (UnsafeBlockExpr const &other); // Overloaded assignment operator to clone - UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other) - { - ExprWithBlock::operator= (other); - expr = other.expr->clone_block_expr (); - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other); // move constructors UnsafeBlockExpr (UnsafeBlockExpr &&other) = default; @@ -2856,7 +2266,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<BlockExpr> &get_block_expr () { return expr; } + BlockExpr &get_block_expr () { return *expr; } ExprType get_expression_type () const override final { @@ -2894,29 +2304,13 @@ protected: BaseLoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> loop_block, location_t locus, LoopLabel loop_label, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), - loop_label (std::move (loop_label)), loop_block (std::move (loop_block)), - locus (locus) - {} + AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor for BaseLoopExpr with clone - BaseLoopExpr (BaseLoopExpr const &other) - : ExprWithBlock (other), loop_label (other.loop_label), - loop_block (other.loop_block->clone_block_expr ()), locus (other.locus) - {} + BaseLoopExpr (BaseLoopExpr const &other); // Overloaded assignment operator to clone - BaseLoopExpr &operator= (BaseLoopExpr const &other) - { - ExprWithBlock::operator= (other); - loop_block = other.loop_block->clone_block_expr (); - loop_label = other.loop_label; - locus = other.locus; - // outer_attrs = other.outer_attrs; - - return *this; - } + BaseLoopExpr &operator= (BaseLoopExpr const &other); // move constructors BaseLoopExpr (BaseLoopExpr &&other) = default; @@ -2932,7 +2326,7 @@ public: location_t get_locus () const override final { return locus; } - std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; }; + HIR::BlockExpr &get_loop_block () { return *loop_block; }; LoopLabel &get_loop_label () { return loop_label; } }; @@ -2946,10 +2340,7 @@ public: // Constructor for LoopExpr LoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label, AST::AttrVec outer_attribs = AST::AttrVec ()) - : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, - std::move (loop_label), std::move (outer_attribs)) - {} + LoopLabel loop_label, AST::AttrVec outer_attribs = AST::AttrVec ()); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -2980,28 +2371,13 @@ public: std::unique_ptr<Expr> loop_condition, std::unique_ptr<BlockExpr> loop_block, location_t locus, LoopLabel loop_label, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, - std::move (loop_label), std::move (outer_attribs)), - condition (std::move (loop_condition)) - {} + AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor with clone - WhileLoopExpr (WhileLoopExpr const &other) - : BaseLoopExpr (other), condition (other.condition->clone_expr ()) - {} + WhileLoopExpr (WhileLoopExpr const &other); // Overloaded assignment operator to clone - WhileLoopExpr &operator= (WhileLoopExpr const &other) - { - BaseLoopExpr::operator= (other); - condition = other.condition->clone_expr (); - // loop_block = other.loop_block->clone_block_expr(); - // loop_label = other.loop_label; - // outer_attrs = other.outer_attrs; - - return *this; - } + WhileLoopExpr &operator= (WhileLoopExpr const &other); // move constructors WhileLoopExpr (WhileLoopExpr &&other) = default; @@ -3010,7 +2386,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_predicate_expr () { return condition; } + Expr &get_predicate_expr () { return *condition; } protected: /* Use covariance to implement clone function as returning this object rather @@ -3032,7 +2408,7 @@ protected: class WhileLetLoopExpr : public BaseLoopExpr { // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined std::unique_ptr<Expr> condition; public: @@ -3040,44 +2416,17 @@ public: // Constructor with a loop label WhileLetLoopExpr (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Pattern> > match_arm_patterns, + std::vector<std::unique_ptr<Pattern>> match_arm_patterns, std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block, location_t locus, LoopLabel loop_label, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, - std::move (loop_label), std::move (outer_attribs)), - match_arm_patterns (std::move (match_arm_patterns)), - condition (std::move (condition)) - {} + AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor with clone - WhileLetLoopExpr (WhileLetLoopExpr const &other) - : BaseLoopExpr (other), - /*match_arm_patterns(other.match_arm_patterns),*/ condition ( - other.condition->clone_expr ()) - { - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - } + WhileLetLoopExpr (WhileLetLoopExpr const &other); // Overloaded assignment operator to clone pointers - WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other) - { - BaseLoopExpr::operator= (other); - // match_arm_patterns = other.match_arm_patterns; - condition = other.condition->clone_expr (); - // loop_block = other.loop_block->clone_block_expr(); - // loop_label = other.loop_label; - // outer_attrs = other.outer_attrs; - - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - - return *this; - } + WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other); // move constructors WhileLetLoopExpr (WhileLetLoopExpr &&other) = default; @@ -3086,8 +2435,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_cond () { return condition; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () + Expr &get_cond () { return *condition; } + std::vector<std::unique_ptr<Pattern>> &get_patterns () { return match_arm_patterns; } @@ -3108,9 +2457,6 @@ protected: } }; -// forward decl for IfExpr -class IfLetExpr; - // Base if expression with no "else" or "if let" HIR node class IfExpr : public ExprWithBlock { @@ -3123,29 +2469,14 @@ public: std::string as_string () const override; IfExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition, - std::unique_ptr<BlockExpr> if_block, location_t locus) - : ExprWithBlock (std::move (mappings), AST::AttrVec ()), - condition (std::move (condition)), if_block (std::move (if_block)), - locus (locus) - {} + std::unique_ptr<BlockExpr> if_block, location_t locus); // outer attributes are never allowed on IfExprs // Copy constructor with clone - IfExpr (IfExpr const &other) - : ExprWithBlock (other), condition (other.condition->clone_expr ()), - if_block (other.if_block->clone_block_expr ()), locus (other.locus) - {} + IfExpr (IfExpr const &other); // Overloaded assignment operator to clone expressions - IfExpr &operator= (IfExpr const &other) - { - ExprWithBlock::operator= (other); - condition = other.condition->clone_expr (); - if_block = other.if_block->clone_block_expr (); - locus = other.locus; - - return *this; - } + IfExpr &operator= (IfExpr const &other); // move constructors IfExpr (IfExpr &&other) = default; @@ -3169,8 +2500,8 @@ public: void vis_if_condition (HIRFullVisitor &vis) { condition->accept_vis (vis); } void vis_if_block (HIRFullVisitor &vis) { if_block->accept_vis (vis); } - std::unique_ptr<Expr> &get_if_condition () { return condition; } - std::unique_ptr<BlockExpr> &get_if_block () { return if_block; } + Expr &get_if_condition () { return *condition; } + BlockExpr &get_if_block () { return *if_block; } ExprType get_expression_type () const final override { return ExprType::If; } @@ -3201,28 +2532,15 @@ public: IfExprConseqElse (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<ExprWithBlock> else_block, location_t locus) - : IfExpr (std::move (mappings), std::move (condition), std::move (if_block), - locus), - else_block (std::move (else_block)) - {} + std::unique_ptr<ExprWithBlock> else_block, + location_t locus); // again, outer attributes not allowed // Copy constructor with clone - IfExprConseqElse (IfExprConseqElse const &other) - : IfExpr (other), else_block (other.else_block->clone_expr_with_block ()) - {} + IfExprConseqElse (IfExprConseqElse const &other); // Overloaded assignment operator with cloning - IfExprConseqElse &operator= (IfExprConseqElse const &other) - { - IfExpr::operator= (other); - // condition = other.condition->clone_expr(); - // if_block = other.if_block->clone_block_expr(); - else_block = other.else_block->clone_expr_with_block (); - - return *this; - } + IfExprConseqElse &operator= (IfExprConseqElse const &other); // move constructors IfExprConseqElse (IfExprConseqElse &&other) = default; @@ -3233,7 +2551,7 @@ public: void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); } - std::unique_ptr<ExprWithBlock> &get_else_block () { return else_block; } + ExprWithBlock &get_else_block () { return *else_block; } protected: /* Use covariance to implement clone function as returning this object rather @@ -3258,183 +2576,12 @@ protected: } }; -// Basic "if let" expression HIR node with no else -class IfLetExpr : public ExprWithBlock -{ - // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined - std::unique_ptr<Expr> value; - std::unique_ptr<BlockExpr> if_block; - - location_t locus; - -public: - std::string as_string () const override; - - IfLetExpr (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Pattern> > match_arm_patterns, - std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - location_t locus) - : ExprWithBlock (std::move (mappings), AST::AttrVec ()), - match_arm_patterns (std::move (match_arm_patterns)), - value (std::move (value)), if_block (std::move (if_block)), locus (locus) - {} - // outer attributes not allowed on if let exprs either - - // copy constructor with clone - IfLetExpr (IfLetExpr const &other) - : ExprWithBlock (other), - /*match_arm_patterns(other.match_arm_patterns),*/ value ( - other.value->clone_expr ()), - if_block (other.if_block->clone_block_expr ()), locus (other.locus) - { - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - } - - // overload assignment operator to clone - IfLetExpr &operator= (IfLetExpr const &other) - { - ExprWithBlock::operator= (other); - // match_arm_patterns = other.match_arm_patterns; - value = other.value->clone_expr (); - if_block = other.if_block->clone_block_expr (); - locus = other.locus; - - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - - return *this; - } - - // move constructors - IfLetExpr (IfLetExpr &&other) = default; - IfLetExpr &operator= (IfLetExpr &&other) = default; - - // Unique pointer custom clone function - std::unique_ptr<IfLetExpr> clone_if_let_expr () const - { - return std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ()); - } - - location_t get_locus () const override final { return locus; } - - void accept_vis (HIRFullVisitor &vis) override; - void accept_vis (HIRExpressionVisitor &vis) override; - - std::unique_ptr<Expr> &get_scrutinee_expr () { return value; } - - std::vector<std::unique_ptr<Pattern> > &get_patterns () - { - return match_arm_patterns; - } - - std::unique_ptr<BlockExpr> &get_if_block () { return if_block; } - - ExprType get_expression_type () const final override - { - return ExprType::IfLet; - } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExpr *clone_expr_impl () const override { return new IfLetExpr (*this); } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExpr *clone_expr_with_block_impl () const override - { - return new IfLetExpr (*this); - } - - // Base clone function but still concrete as concrete base class - virtual IfLetExpr *clone_if_let_expr_impl () const - { - return new IfLetExpr (*this); - } -}; - -/* HIR node representing "if let" expression with an "else" expression at the - * end */ -class IfLetExprConseqElse : public IfLetExpr -{ - std::unique_ptr<ExprWithBlock> else_block; - -public: - std::string as_string () const override; - - IfLetExprConseqElse ( - Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Pattern> > match_arm_patterns, - std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<ExprWithBlock> else_block, location_t locus) - : IfLetExpr (std::move (mappings), std::move (match_arm_patterns), - std::move (value), std::move (if_block), locus), - else_block (std::move (else_block)) - {} - // outer attributes not allowed - - // copy constructor with clone - IfLetExprConseqElse (IfLetExprConseqElse const &other) - : IfLetExpr (other), else_block (other.else_block->clone_expr_with_block ()) - {} - - // overload assignment operator to clone - IfLetExprConseqElse &operator= (IfLetExprConseqElse const &other) - { - IfLetExpr::operator= (other); - // match_arm_patterns = other.match_arm_patterns; - // value = other.value->clone_expr(); - // if_block = other.if_block->clone_block_expr(); - else_block = other.else_block->clone_expr_with_block (); - // outer_attrs = other.outer_attrs; - - return *this; - } - - // move constructors - IfLetExprConseqElse (IfLetExprConseqElse &&other) = default; - IfLetExprConseqElse &operator= (IfLetExprConseqElse &&other) = default; - - void accept_vis (HIRFullVisitor &vis) override; - void accept_vis (HIRExpressionVisitor &vis) override; - - void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); } - - std::unique_ptr<ExprWithBlock> &get_else_block () { return else_block; } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExprConseqElse *clone_expr_impl () const override - { - return new IfLetExprConseqElse (*this); - } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExprConseqElse *clone_expr_with_block_impl () const override - { - return new IfLetExprConseqElse (*this); - } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExprConseqElse *clone_if_let_expr_impl () const override - { - return new IfLetExprConseqElse (*this); - } -}; - // Match arm expression struct MatchArm { private: AST::AttrVec outer_attrs; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; + std::vector<std::unique_ptr<Pattern>> match_arm_patterns; std::unique_ptr<Expr> guard_expr; location_t locus; @@ -3443,45 +2590,17 @@ public: bool has_match_arm_guard () const { return guard_expr != nullptr; } // Constructor for match arm with a guard expression - MatchArm (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, + MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, location_t locus, std::unique_ptr<Expr> guard_expr = nullptr, - AST::AttrVec outer_attrs = AST::AttrVec ()) - : outer_attrs (std::move (outer_attrs)), - match_arm_patterns (std::move (match_arm_patterns)), - guard_expr (std::move (guard_expr)), locus (locus) - {} + AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor with clone - MatchArm (MatchArm const &other) : outer_attrs (other.outer_attrs) - { - // guard to protect from null pointer dereference - if (other.guard_expr != nullptr) - guard_expr = other.guard_expr->clone_expr (); - - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - - locus = other.locus; - } + MatchArm (MatchArm const &other); ~MatchArm () = default; // Overload assignment operator to clone - MatchArm &operator= (MatchArm const &other) - { - outer_attrs = other.outer_attrs; - - if (other.guard_expr != nullptr) - guard_expr = other.guard_expr->clone_expr (); - - match_arm_patterns.clear (); - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - - return *this; - } + MatchArm &operator= (MatchArm const &other); // move constructors MatchArm (MatchArm &&other) = default; @@ -3494,17 +2613,17 @@ public: static MatchArm create_error () { location_t locus = UNDEF_LOCATION; - return MatchArm (std::vector<std::unique_ptr<Pattern> > (), locus); + return MatchArm (std::vector<std::unique_ptr<Pattern>> (), locus); } std::string as_string () const; - std::vector<std::unique_ptr<Pattern> > &get_patterns () + std::vector<std::unique_ptr<Pattern>> &get_patterns () { return match_arm_patterns; } - std::unique_ptr<Expr> &get_guard_expr () { return guard_expr; } + Expr &get_guard_expr () { return *guard_expr; } location_t get_locus () const { return locus; } }; @@ -3520,23 +2639,11 @@ private: public: MatchCase (Analysis::NodeMapping mappings, MatchArm arm, - std::unique_ptr<Expr> expr) - : mappings (mappings), arm (std::move (arm)), expr (std::move (expr)) - {} - - MatchCase (const MatchCase &other) - : mappings (other.mappings), arm (other.arm), - expr (other.expr->clone_expr ()) - {} + std::unique_ptr<Expr> expr); - MatchCase &operator= (const MatchCase &other) - { - mappings = other.mappings; - arm = other.arm; - expr = other.expr->clone_expr (); + MatchCase (const MatchCase &other); - return *this; - } + MatchCase &operator= (const MatchCase &other); MatchCase (MatchCase &&other) = default; MatchCase &operator= (MatchCase &&other) = default; @@ -3548,7 +2655,7 @@ public: Analysis::NodeMapping get_mappings () const { return mappings; } MatchArm &get_arm () { return arm; } - std::unique_ptr<Expr> &get_expr () { return expr; } + Expr &get_expr () { return *expr; } }; // Match expression HIR node @@ -3565,40 +2672,13 @@ public: MatchExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> branch_value, std::vector<MatchCase> match_arms, AST::AttrVec inner_attrs, - AST::AttrVec outer_attrs, location_t locus) - : ExprWithBlock (std::move (mappings), std::move (outer_attrs)), - WithInnerAttrs (std::move (inner_attrs)), - branch_value (std::move (branch_value)), - match_arms (std::move (match_arms)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Copy constructor requires clone due to unique_ptr - MatchExpr (MatchExpr const &other) - : ExprWithBlock (other), WithInnerAttrs (other.inner_attrs), - branch_value (other.branch_value->clone_expr ()), - match_arms (other.match_arms), locus (other.locus) - { - /*match_arms.reserve (other.match_arms.size ()); - for (const auto &e : other.match_arms) - match_arms.push_back (e->clone_match_case ());*/ - } + MatchExpr (MatchExpr const &other); // Overloaded assignment operator to clone due to unique_ptr - MatchExpr &operator= (MatchExpr const &other) - { - ExprWithBlock::operator= (other); - branch_value = other.branch_value->clone_expr (); - inner_attrs = other.inner_attrs; - match_arms = other.match_arms; - // outer_attrs = other.outer_attrs; - locus = other.locus; - - /*match_arms.reserve (other.match_arms.size ()); - for (const auto &e : other.match_arms) - match_arms.push_back (e->clone_match_case ());*/ - - return *this; - } + MatchExpr &operator= (MatchExpr const &other); // move constructors MatchExpr (MatchExpr &&other) = default; @@ -3609,7 +2689,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_scrutinee_expr () { return branch_value; } + Expr &get_scrutinee_expr () { return *branch_value; } AST::AttrVec get_inner_attrs () const { return inner_attrs; } const std::vector<MatchCase> &get_match_cases () const { return match_arms; } std::vector<MatchCase> &get_match_cases () { return match_arms; } @@ -3641,26 +2721,13 @@ class AwaitExpr : public ExprWithoutBlock public: // TODO: ensure outer attributes are actually allowed AwaitExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> awaited_expr, - AST::AttrVec outer_attrs, location_t locus) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)), - awaited_expr (std::move (awaited_expr)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // copy constructor with clone - AwaitExpr (AwaitExpr const &other) - : ExprWithoutBlock (other), - awaited_expr (other.awaited_expr->clone_expr ()), locus (other.locus) - {} + AwaitExpr (AwaitExpr const &other); // overloaded assignment operator with clone - AwaitExpr &operator= (AwaitExpr const &other) - { - ExprWithoutBlock::operator= (other); - awaited_expr = other.awaited_expr->clone_expr (); - locus = other.locus; - - return *this; - } + AwaitExpr &operator= (AwaitExpr const &other); // move constructors AwaitExpr (AwaitExpr &&other) = default; @@ -3673,7 +2740,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - std::unique_ptr<Expr> &get_awaited_expr () { return awaited_expr; } + Expr &get_awaited_expr () { return *awaited_expr; } ExprType get_expression_type () const final override { @@ -3699,27 +2766,13 @@ class AsyncBlockExpr : public ExprWithBlock public: AsyncBlockExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> block_expr, bool has_move, - AST::AttrVec outer_attrs, location_t locus) - : ExprWithBlock (std::move (mappings), std::move (outer_attrs)), - has_move (has_move), block_expr (std::move (block_expr)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // copy constructor with clone - AsyncBlockExpr (AsyncBlockExpr const &other) - : ExprWithBlock (other), has_move (other.has_move), - block_expr (other.block_expr->clone_block_expr ()), locus (other.locus) - {} + AsyncBlockExpr (AsyncBlockExpr const &other); // overloaded assignment operator to clone - AsyncBlockExpr &operator= (AsyncBlockExpr const &other) - { - ExprWithBlock::operator= (other); - has_move = other.has_move; - block_expr = other.block_expr->clone_block_expr (); - locus = other.locus; - - return *this; - } + AsyncBlockExpr &operator= (AsyncBlockExpr const &other); // move constructors AsyncBlockExpr (AsyncBlockExpr &&other) = default; @@ -3730,7 +2783,7 @@ public: location_t get_locus () const override final { return locus; } bool get_has_move () const { return has_move; } - std::unique_ptr<BlockExpr> &get_block_expr () { return block_expr; } + BlockExpr &get_block_expr () { return *block_expr; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -3753,35 +2806,17 @@ protected: class OperatorExprMeta { public: - OperatorExprMeta (HIR::CompoundAssignmentExpr &expr) - : node_mappings (expr.get_mappings ()), - lvalue_mappings (expr.get_expr ()->get_mappings ()), - locus (expr.get_locus ()) - {} + OperatorExprMeta (HIR::CompoundAssignmentExpr &expr); - OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr) - : node_mappings (expr.get_mappings ()), - lvalue_mappings (expr.get_expr ()->get_mappings ()), - locus (expr.get_locus ()) - {} + OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr); - OperatorExprMeta (HIR::NegationExpr &expr) - : node_mappings (expr.get_mappings ()), - lvalue_mappings (expr.get_expr ()->get_mappings ()), - locus (expr.get_locus ()) - {} + OperatorExprMeta (HIR::NegationExpr &expr); - OperatorExprMeta (HIR::DereferenceExpr &expr) - : node_mappings (expr.get_mappings ()), - lvalue_mappings (expr.get_expr ()->get_mappings ()), - locus (expr.get_locus ()) - {} + OperatorExprMeta (HIR::DereferenceExpr &expr); - OperatorExprMeta (HIR::ArrayIndexExpr &expr) - : node_mappings (expr.get_mappings ()), - lvalue_mappings (expr.get_array_expr ()->get_mappings ()), - locus (expr.get_locus ()) - {} + OperatorExprMeta (HIR::ArrayIndexExpr &expr); + + OperatorExprMeta (HIR::ComparisonExpr &expr); const Analysis::NodeMapping &get_mappings () const { return node_mappings; } @@ -3856,25 +2891,13 @@ struct AnonConst { NodeId id; std::unique_ptr<Expr> expr; - AnonConst (NodeId id, std::unique_ptr<Expr> expr) - : id (id), expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - } - AnonConst (const AnonConst &other) - { - id = other.id; - expr = other.expr->clone_expr (); - } - AnonConst operator= (const AnonConst &other) - { - id = other.id; - expr = other.expr->clone_expr (); - return *this; - } + AnonConst (NodeId id, std::unique_ptr<Expr> expr); + + AnonConst (const AnonConst &other); + + AnonConst operator= (const AnonConst &other); }; -; class InlineAsmOperand { @@ -3885,26 +2908,11 @@ public: std::unique_ptr<Expr> expr; In (const tl::optional<struct AST::InlineAsmRegOrRegClass> ®, - std::unique_ptr<Expr> expr) - : reg (reg), expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - } - - In (const struct In &other) - { - reg = other.reg; - - expr = other.expr->clone_expr (); - } - - In operator= (const struct In &other) - { - reg = other.reg; - expr = other.expr->clone_expr (); - - return *this; - } + std::unique_ptr<Expr> expr); + + In (const struct In &other); + + In operator= (const struct In &other); }; struct Out @@ -3914,26 +2922,11 @@ public: std::unique_ptr<Expr> expr; // can be null Out (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, - std::unique_ptr<Expr> expr) - : reg (reg), late (late), expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - } - - Out (const struct Out &other) - { - reg = other.reg; - late = other.late; - expr = other.expr->clone_expr (); - } - - Out operator= (const struct Out &other) - { - reg = other.reg; - late = other.late; - expr = other.expr->clone_expr (); - return *this; - } + std::unique_ptr<Expr> expr); + + Out (const struct Out &other); + + Out operator= (const struct Out &other); }; struct InOut @@ -3943,27 +2936,11 @@ public: std::unique_ptr<Expr> expr; // this can't be null InOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, - std::unique_ptr<Expr> expr) - : reg (reg), late (late), expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - } - - InOut (const struct InOut &other) - { - reg = other.reg; - late = other.late; - expr = other.expr->clone_expr (); - } - - InOut operator= (const struct InOut &other) - { - reg = other.reg; - late = other.late; - expr = other.expr->clone_expr (); - - return *this; - } + std::unique_ptr<Expr> expr); + + InOut (const struct InOut &other); + + InOut operator= (const struct InOut &other); }; struct SplitInOut @@ -3975,31 +2952,11 @@ public: SplitInOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, std::unique_ptr<Expr> in_expr, - std::unique_ptr<Expr> out_expr) - : reg (reg), late (late), in_expr (std::move (in_expr)), - out_expr (std::move (out_expr)) - { - rust_assert (this->in_expr != nullptr); - rust_assert (this->out_expr != nullptr); - } - - SplitInOut (const struct SplitInOut &other) - { - reg = other.reg; - late = other.late; - in_expr = other.in_expr->clone_expr (); - out_expr = other.out_expr->clone_expr (); - } - - SplitInOut operator= (const struct SplitInOut &other) - { - reg = other.reg; - late = other.late; - in_expr = other.in_expr->clone_expr (); - out_expr = other.out_expr->clone_expr (); - - return *this; - } + std::unique_ptr<Expr> out_expr); + + SplitInOut (const struct SplitInOut &other); + + SplitInOut operator= (const struct SplitInOut &other); }; struct Const @@ -4011,20 +2968,11 @@ public: { std::unique_ptr<Expr> expr; - Sym (std::unique_ptr<Expr> expr) : expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - } - Sym (const struct Sym &other) - { - expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); - } - - Sym operator= (const struct Sym &other) - { - expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); - return *this; - } + Sym (std::unique_ptr<Expr> expr); + + Sym (const struct Sym &other); + + Sym operator= (const struct Sym &other); }; struct Label @@ -4032,23 +2980,11 @@ public: std::string label_name; std::unique_ptr<Expr> expr; - Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr) - : expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - if (label_name.has_value ()) - this->label_name = label_name.value (); - } - Label (const struct Label &other) - { - expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); - } - - Label operator= (const struct Label &other) - { - expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); - return *this; - } + Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr); + + Label (const struct Label &other); + + Label operator= (const struct Label &other); }; private: @@ -4062,7 +2998,6 @@ private: tl::optional<struct Const> cnst; tl::optional<struct Sym> sym; tl::optional<struct Label> label; - location_t locus; public: InlineAsmOperand (const InlineAsmOperand &other) @@ -4105,6 +3040,7 @@ public: struct Sym get_sym () const { return sym.value (); } struct Label get_label () const { return label.value (); } }; + // Inline Assembly Node class InlineAsm : public ExprWithoutBlock { @@ -4166,6 +3102,7 @@ public: // INFO: An inline asm is asm!, which is the opposite of a global_asm() return !this->is_global_asm; } + InlineAsm (location_t locus, bool is_global_asm, std::vector<AST::InlineAsmTemplatePiece> template_, std::vector<AST::TupleTemplateStr> template_strs, @@ -4173,16 +3110,9 @@ public: std::vector<AST::TupleClobber> clobber_abi, std::set<AST::InlineAsmOption> options, Analysis::NodeMapping mappings, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), - locus (locus), is_global_asm (is_global_asm), - template_ (std::move (template_)), - template_strs (std::move (template_strs)), - operands (std::move (operands)), clobber_abi (std::move (clobber_abi)), - options (std::move (options)) - - {} + AST::AttrVec outer_attribs = AST::AttrVec ()); }; + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h index 64be7bf..6c19f24 100644 --- a/gcc/rust/hir/tree/rust-hir-full-decls.h +++ b/gcc/rust/hir/tree/rust-hir-full-decls.h @@ -113,8 +113,6 @@ class WhileLoopExpr; class WhileLetLoopExpr; class IfExpr; class IfExprConseqElse; -class IfLetExpr; -class IfLetExprConseqElse; struct MatchArm; // class MatchCase; // class MatchCaseBlockExpr; @@ -213,7 +211,6 @@ class TraitBound; class ImplTraitType; class TraitObjectType; class ParenthesisedType; -class ImplTraitTypeOneBound; class TupleType; class NeverType; class RawPointerType; diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.cc b/gcc/rust/hir/tree/rust-hir-generic-param.cc new file mode 100644 index 0000000..e5afa8e --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-generic-param.cc @@ -0,0 +1,95 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-generic-param.h" + +namespace Rust { +namespace HIR { + +GenericParam::GenericParam (Analysis::NodeMapping mapping, + enum GenericKind kind) + : mappings (mapping), kind (kind) +{} + +LifetimeParam::LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime, + location_t locus, + std::vector<Lifetime> lifetime_bounds, + AST::AttrVec outer_attrs) + : GenericParam (mappings, GenericKind::LIFETIME), + lifetime (std::move (lifetime)), + lifetime_bounds (std::move (lifetime_bounds)), + outer_attrs (std::move (outer_attrs)), locus (locus) +{} + +LifetimeParam::LifetimeParam (LifetimeParam const &other) + : GenericParam (other.mappings, GenericKind::LIFETIME), + lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds), + outer_attrs (other.outer_attrs), locus (other.locus) +{} + +LifetimeParam & +LifetimeParam::operator= (LifetimeParam const &other) +{ + lifetime = other.lifetime; + lifetime_bounds = other.lifetime_bounds; + outer_attrs = other.outer_attrs; + locus = other.locus; + mappings = other.mappings; + + return *this; +} + +ConstGenericParam::ConstGenericParam (std::string name, + std::unique_ptr<Type> type, + std::unique_ptr<Expr> default_expression, + Analysis::NodeMapping mapping, + location_t locus) + : GenericParam (mapping, GenericKind::CONST), name (std::move (name)), + type (std::move (type)), + default_expression (std::move (default_expression)), locus (locus) +{} + +ConstGenericParam::ConstGenericParam (const ConstGenericParam &other) + : GenericParam (other) +{ + name = other.name; + locus = other.locus; + + if (other.type) + type = other.type->clone_type (); + if (other.default_expression) + default_expression = other.default_expression->clone_expr (); +} + +std::string +ConstGenericParam::as_string () const +{ + auto result = "ConstGenericParam: " + name + " : " + type->as_string (); + + if (default_expression) + result += " = " + default_expression->as_string (); + + return result; +} + +void +ConstGenericParam::accept_vis (HIRFullVisitor &) +{} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.h b/gcc/rust/hir/tree/rust-hir-generic-param.h new file mode 100644 index 0000000..a1c59bf --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-generic-param.h @@ -0,0 +1,190 @@ + +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_GENERIC_PARAM_H +#define RUST_HIR_GENERIC_PARAM_H + +#include "rust-hir-visitable.h" +#include "rust-hir-bound.h" + +namespace Rust { +namespace HIR { + +/* Base generic parameter in HIR. Abstract - can be represented by a Lifetime or + * Type param */ +class GenericParam : public FullVisitable +{ +public: + using FullVisitable::accept_vis; + + virtual ~GenericParam () {} + + enum class GenericKind + { + TYPE, + LIFETIME, + CONST, + }; + + virtual AST::AttrVec &get_outer_attrs () = 0; + virtual bool has_outer_attribute () const = 0; + + // Unique pointer custom clone function + std::unique_ptr<GenericParam> clone_generic_param () const + { + return std::unique_ptr<GenericParam> (clone_generic_param_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual location_t get_locus () const = 0; + + Analysis::NodeMapping get_mappings () const { return mappings; } + + enum GenericKind get_kind () const { return kind; } + +protected: + // Clone function implementation as pure virtual method + virtual GenericParam *clone_generic_param_impl () const = 0; + + Analysis::NodeMapping mappings; + + enum GenericKind kind; + + GenericParam (Analysis::NodeMapping mapping, + enum GenericKind kind = GenericKind::TYPE); +}; + +// A lifetime generic parameter (as opposed to a type generic parameter) +class LifetimeParam : public GenericParam +{ + Lifetime lifetime; + + // bool has_lifetime_bounds; + // LifetimeBounds lifetime_bounds; + std::vector<Lifetime> lifetime_bounds; // inlined LifetimeBounds + + AST::AttrVec outer_attrs; + + location_t locus; + +public: + Lifetime get_lifetime () { return lifetime; } + + // Returns whether the lifetime param has any lifetime bounds. + bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); } + + std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; } + + // Returns whether the lifetime param has an outer attribute. + bool has_outer_attribute () const override { return outer_attrs.size () > 1; } + + AST::AttrVec &get_outer_attrs () override { return outer_attrs; } + + // Returns whether the lifetime param is in an error state. + bool is_error () const { return lifetime.is_error (); } + + // Constructor + LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime, + location_t locus = UNDEF_LOCATION, + std::vector<Lifetime> lifetime_bounds + = std::vector<Lifetime> (), + AST::AttrVec outer_attrs = std::vector<AST::Attribute> ()); + + // TODO: remove copy and assignment operator definitions - not required + + // Copy constructor with clone + LifetimeParam (LifetimeParam const &other); + + // Overloaded assignment operator to clone attribute + LifetimeParam &operator= (LifetimeParam const &other); + + // move constructors + LifetimeParam (LifetimeParam &&other) = default; + LifetimeParam &operator= (LifetimeParam &&other) = default; + + std::string as_string () const override; + + void accept_vis (HIRFullVisitor &vis) override; + + location_t get_locus () const override final { return locus; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + LifetimeParam *clone_generic_param_impl () const override + { + return new LifetimeParam (*this); + } +}; + +class ConstGenericParam : public GenericParam +{ +public: + ConstGenericParam (std::string name, std::unique_ptr<Type> type, + std::unique_ptr<Expr> default_expression, + Analysis::NodeMapping mapping, location_t locus); + + ConstGenericParam (const ConstGenericParam &other); + + bool has_outer_attribute () const override { return false; } + + AST::AttrVec &get_outer_attrs () override { return outer_attrs; } + + std::string as_string () const override final; + + void accept_vis (HIRFullVisitor &vis) override final; + + location_t get_locus () const override final { return locus; }; + + bool has_default_expression () { return default_expression != nullptr; } + + std::string get_name () { return name; } + Type &get_type () + { + rust_assert (type); + return *type; + } + Expr &get_default_expression () { return *default_expression; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + ConstGenericParam *clone_generic_param_impl () const override + { + return new ConstGenericParam (*this); + } + +private: + std::string name; + std::unique_ptr<Type> type; + + /* const params have no outer attrs, should be empty */ + AST::AttrVec outer_attrs = std::vector<AST::Attribute> (); + + /* Optional - can be a null pointer if there is no default expression */ + std::unique_ptr<Expr> default_expression; + + location_t locus; +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc new file mode 100644 index 0000000..cff06d3 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-item.cc @@ -0,0 +1,1020 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-item.h" +#include "optional.h" + +namespace Rust { +namespace HIR { + +TypeParam::TypeParam ( + Analysis::NodeMapping mappings, Identifier type_representation, + location_t locus, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs) + : GenericParam (mappings), outer_attrs (std::move (outer_attrs)), + type_representation (std::move (type_representation)), + type_param_bounds (std::move (type_param_bounds)), type (std::move (type)), + locus (locus) +{} + +TypeParam::TypeParam (TypeParam const &other) + : GenericParam (other.mappings), outer_attrs (other.outer_attrs), + type_representation (other.type_representation), locus (other.locus) +{ + // guard to prevent null pointer dereference + if (other.has_type ()) + type = {other.type.value ()->clone_type ()}; + else + type = tl::nullopt; + + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); +} + +TypeParam & +TypeParam::operator= (TypeParam const &other) +{ + type_representation = other.type_representation; + outer_attrs = other.outer_attrs; + locus = other.locus; + mappings = other.mappings; + + // guard to prevent null pointer dereference + if (other.has_type ()) + type = {other.type.value ()->clone_type ()}; + else + type = tl::nullopt; + + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + return *this; +} + +Analysis::NodeMapping +TypeParam::get_type_mappings () const +{ + rust_assert (type.has_value ()); + return type.value ()->get_mappings (); +} + +std::vector<std::unique_ptr<TypeParamBound>> & +TypeParam::get_type_param_bounds () +{ + return type_param_bounds; +} + +TypeBoundWhereClauseItem::TypeBoundWhereClauseItem ( + Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes, + std::unique_ptr<Type> bound_type, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + location_t locus) + : for_lifetimes (std::move (for_lifetimes)), + bound_type (std::move (bound_type)), + type_param_bounds (std::move (type_param_bounds)), + mappings (std::move (mappings)), locus (locus) +{} + +TypeBoundWhereClauseItem::TypeBoundWhereClauseItem ( + TypeBoundWhereClauseItem const &other) + : for_lifetimes (other.for_lifetimes), + bound_type (other.bound_type->clone_type ()), mappings (other.mappings) +{ + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); +} + +TypeBoundWhereClauseItem & +TypeBoundWhereClauseItem::operator= (TypeBoundWhereClauseItem const &other) +{ + mappings = other.mappings; + for_lifetimes = other.for_lifetimes; + bound_type = other.bound_type->clone_type (); + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + return *this; +} + +std::vector<std::unique_ptr<TypeParamBound>> & +TypeBoundWhereClauseItem::get_type_param_bounds () +{ + return type_param_bounds; +} + +SelfParam::SelfParam (Analysis::NodeMapping mappings, + ImplicitSelfKind self_kind, Lifetime lifetime, Type *type) + : self_kind (self_kind), lifetime (std::move (lifetime)), type (type), + mappings (mappings) +{} + +SelfParam::SelfParam (Analysis::NodeMapping mappings, + std::unique_ptr<Type> type, bool is_mut, location_t locus) + : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM), + lifetime ( + Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)), + type (std::move (type)), locus (locus), mappings (mappings) +{} + +SelfParam::SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, + bool is_mut, location_t locus) + : self_kind (is_mut ? ImplicitSelfKind::MUT_REF : ImplicitSelfKind::IMM_REF), + lifetime (std::move (lifetime)), locus (locus), mappings (mappings) +{} + +SelfParam::SelfParam (SelfParam const &other) + : self_kind (other.self_kind), lifetime (other.lifetime), locus (other.locus), + mappings (other.mappings) +{ + if (other.type != nullptr) + type = other.type->clone_type (); +} + +SelfParam & +SelfParam::operator= (SelfParam const &other) +{ + if (other.type != nullptr) + type = other.type->clone_type (); + + self_kind = other.self_kind; + lifetime = other.lifetime; + locus = other.locus; + mappings = other.mappings; + + return *this; +} + +Mutability +SelfParam::get_mut () const +{ + return (self_kind == ImplicitSelfKind::MUT + || self_kind == ImplicitSelfKind::MUT_REF) + ? Mutability::Mut + : Mutability::Imm; +} + +bool +SelfParam::is_mut () const +{ + return self_kind == ImplicitSelfKind::MUT + || self_kind == ImplicitSelfKind::MUT_REF; +} + +bool +SelfParam::is_ref () const +{ + return self_kind == ImplicitSelfKind::IMM_REF + || self_kind == ImplicitSelfKind::MUT_REF; +} + +FunctionParam::FunctionParam (Analysis::NodeMapping mappings, + std::unique_ptr<Pattern> param_name, + std::unique_ptr<Type> param_type, + location_t locus) + : param_name (std::move (param_name)), type (std::move (param_type)), + locus (locus), mappings (mappings) +{} + +FunctionParam::FunctionParam (FunctionParam const &other) + : param_name (other.param_name->clone_pattern ()), + type (other.type->clone_type ()), locus (other.locus), + mappings (other.mappings) +{} + +FunctionParam & +FunctionParam::operator= (FunctionParam const &other) +{ + param_name = other.param_name->clone_pattern (); + type = other.type->clone_type (); + locus = other.locus; + mappings = other.mappings; + + return *this; +} + +VisItem & +VisItem::operator= (VisItem const &other) +{ + Item::operator= (other); + visibility = other.visibility; + // outer_attrs = other.outer_attrs; + + return *this; +} + +VisItem::VisItem (VisItem const &other) + : Item (other), visibility (other.visibility) +{} + +Module::Module (Analysis::NodeMapping mappings, Identifier module_name, + location_t locus, std::vector<std::unique_ptr<Item>> items, + Visibility visibility, AST::AttrVec inner_attrs, + AST::AttrVec outer_attrs) + : VisItem (std::move (mappings), std::move (visibility), + std::move (outer_attrs)), + WithInnerAttrs (std::move (inner_attrs)), module_name (module_name), + locus (locus), items (std::move (items)) +{} + +Module::Module (Module const &other) + : VisItem (other), WithInnerAttrs (other.inner_attrs), module_name ("") +{ + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_item ()); +} + +Module & +Module::operator= (Module const &other) +{ + VisItem::operator= (other); + inner_attrs = other.inner_attrs; + + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_item ()); + + return *this; +} + +Function::Function (Analysis::NodeMapping mappings, Identifier function_name, + FunctionQualifiers qualifiers, + std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<FunctionParam> function_params, + std::unique_ptr<Type> return_type, WhereClause where_clause, + std::unique_ptr<BlockExpr> function_body, Visibility vis, + AST::AttrVec outer_attrs, SelfParam self, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + qualifiers (std::move (qualifiers)), + function_name (std::move (function_name)), + generic_params (std::move (generic_params)), + function_params (std::move (function_params)), + return_type (std::move (return_type)), + where_clause (std::move (where_clause)), + function_body (std::move (function_body)), self (std::move (self)), + locus (locus) +{} + +Function::Function (Function const &other) + : VisItem (other), qualifiers (other.qualifiers), + function_name (other.function_name), + function_params (other.function_params), where_clause (other.where_clause), + function_body (other.function_body->clone_block_expr ()), self (other.self), + locus (other.locus) +{ + // guard to prevent null dereference (always required) + if (other.return_type != nullptr) + return_type = other.return_type->clone_type (); + else + return_type = nullptr; + + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); +} + +Function & +Function::operator= (Function const &other) +{ + VisItem::operator= (other); + function_name = other.function_name; + qualifiers = other.qualifiers; + function_params = other.function_params; + + // guard to prevent null dereference (always required) + if (other.return_type != nullptr) + return_type = other.return_type->clone_type (); + else + return_type = nullptr; + + where_clause = other.where_clause; + function_body = other.function_body->clone_block_expr (); + locus = other.locus; + self = other.self; + + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); + + return *this; +} + +TypeAlias::TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name, + std::vector<std::unique_ptr<GenericParam>> generic_params, + WhereClause where_clause, + std::unique_ptr<Type> existing_type, Visibility vis, + AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + new_type_name (std::move (new_type_name)), + generic_params (std::move (generic_params)), + where_clause (std::move (where_clause)), + existing_type (std::move (existing_type)), locus (locus) +{} + +TypeAlias::TypeAlias (TypeAlias const &other) + : VisItem (other), new_type_name (other.new_type_name), + where_clause (other.where_clause), + existing_type (other.existing_type->clone_type ()), 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 ()); +} + +TypeAlias & +TypeAlias::operator= (TypeAlias const &other) +{ + VisItem::operator= (other); + new_type_name = other.new_type_name; + where_clause = other.where_clause; + existing_type = other.existing_type->clone_type (); + 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; +} + +StructField::StructField (Analysis::NodeMapping mappings, Identifier field_name, + std::unique_ptr<Type> field_type, Visibility vis, + location_t locus, AST::AttrVec outer_attrs) + : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), + field_name (std::move (field_name)), field_type (std::move (field_type)), + mappings (mappings), locus (locus) +{} + +StructField::StructField (StructField const &other) + : outer_attrs (other.outer_attrs), visibility (other.visibility), + field_name (other.field_name), field_type (other.field_type->clone_type ()), + mappings (other.mappings) +{} + +StructField & +StructField::operator= (StructField const &other) +{ + field_name = other.field_name; + field_type = other.field_type->clone_type (); + visibility = other.visibility; + outer_attrs = other.outer_attrs; + mappings = other.mappings; + + return *this; +} + +TupleField::TupleField (Analysis::NodeMapping mapping, + std::unique_ptr<Type> field_type, Visibility vis, + location_t locus, AST::AttrVec outer_attrs) + : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), + field_type (std::move (field_type)), locus (locus), mappings (mapping) +{} + +TupleField::TupleField (TupleField const &other) + : outer_attrs (other.outer_attrs), visibility (other.visibility), + field_type (other.field_type->clone_type ()), locus (other.locus), + mappings (other.mappings) +{} + +TupleField & +TupleField::operator= (TupleField const &other) +{ + field_type = other.field_type->clone_type (); + visibility = other.visibility; + outer_attrs = other.outer_attrs; + locus = other.locus; + mappings = other.mappings; + + return *this; +} + +TupleStruct::TupleStruct ( + Analysis::NodeMapping mappings, std::vector<TupleField> fields, + Identifier struct_name, + std::vector<std::unique_ptr<GenericParam>> 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)), + fields (std::move (fields)) +{} + +EnumItem::EnumItem (Analysis::NodeMapping mappings, Identifier variant_name, + AST::AttrVec outer_attrs, location_t locus) + : Item (std::move (mappings), std::move (outer_attrs)), + variant_name (std::move (variant_name)), locus (locus) +{} + +EnumItemTuple::EnumItemTuple (Analysis::NodeMapping mappings, + Identifier variant_name, + std::vector<TupleField> tuple_fields, + AST::AttrVec outer_attrs, location_t locus) + : EnumItem (std::move (mappings), std::move (variant_name), + std::move (outer_attrs), locus), + tuple_fields (std::move (tuple_fields)) +{} + +EnumItemStruct::EnumItemStruct (Analysis::NodeMapping mappings, + Identifier variant_name, + std::vector<StructField> struct_fields, + AST::AttrVec outer_attrs, location_t locus) + : EnumItem (std::move (mappings), std::move (variant_name), + std::move (outer_attrs), locus), + struct_fields (std::move (struct_fields)) +{} + +EnumItemDiscriminant::EnumItemDiscriminant (Analysis::NodeMapping mappings, + Identifier variant_name, + std::unique_ptr<Expr> expr, + AST::AttrVec outer_attrs, + location_t locus) + : EnumItem (std::move (mappings), std::move (variant_name), + std::move (outer_attrs), locus), + expression (std::move (expr)) +{} + +EnumItemDiscriminant::EnumItemDiscriminant (EnumItemDiscriminant const &other) + : EnumItem (other), expression (other.expression->clone_expr ()) +{} + +EnumItemDiscriminant & +EnumItemDiscriminant::operator= (EnumItemDiscriminant const &other) +{ + EnumItem::operator= (other); + expression = other.expression->clone_expr (); + // variant_name = other.variant_name; + // outer_attrs = other.outer_attrs; + + return *this; +} + +Enum::Enum (Analysis::NodeMapping mappings, Identifier enum_name, + Visibility vis, + std::vector<std::unique_ptr<GenericParam>> generic_params, + WhereClause where_clause, + std::vector<std::unique_ptr<EnumItem>> items, + AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + enum_name (std::move (enum_name)), + generic_params (std::move (generic_params)), + where_clause (std::move (where_clause)), items (std::move (items)), + locus (locus) +{} + +Enum::Enum (Enum const &other) + : VisItem (other), enum_name (other.enum_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 ()); + + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_enum_item ()); +} + +Enum & +Enum::operator= (Enum const &other) +{ + VisItem::operator= (other); + enum_name = other.enum_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 ()); + + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_enum_item ()); + + return *this; +} + +Union::Union (Analysis::NodeMapping mappings, Identifier union_name, + Visibility vis, + std::vector<std::unique_ptr<GenericParam>> generic_params, + WhereClause where_clause, std::vector<StructField> variants, + AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + union_name (std::move (union_name)), + generic_params (std::move (generic_params)), + where_clause (std::move (where_clause)), variants (std::move (variants)), + locus (locus) +{} + +Union::Union (Union const &other) + : VisItem (other), union_name (other.union_name), + where_clause (other.where_clause), variants (other.variants), + 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 ()); +} + +Union & +Union::operator= (Union const &other) +{ + VisItem::operator= (other); + union_name = other.union_name; + where_clause = other.where_clause; + variants = other.variants; + 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; +} + +ConstantItem::ConstantItem (Analysis::NodeMapping mappings, Identifier ident, + Visibility vis, std::unique_ptr<Type> type, + std::unique_ptr<Expr> const_expr, + AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + identifier (std::move (ident)), type (std::move (type)), + const_expr (std::move (const_expr)), locus (locus) +{} + +ConstantItem::ConstantItem (ConstantItem const &other) + : VisItem (other), identifier (other.identifier), + type (other.type->clone_type ()), + const_expr (other.const_expr->clone_expr ()), locus (other.locus) +{} + +ConstantItem & +ConstantItem::operator= (ConstantItem const &other) +{ + VisItem::operator= (other); + identifier = other.identifier; + type = other.type->clone_type (); + const_expr = other.const_expr->clone_expr (); + locus = other.locus; + + return *this; +} + +StaticItem::StaticItem (Analysis::NodeMapping mappings, Identifier name, + Mutability mut, std::unique_ptr<Type> type, + std::unique_ptr<Expr> expr, Visibility vis, + AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + mut (mut), name (std::move (name)), type (std::move (type)), + expr (std::move (expr)), locus (locus) +{} + +StaticItem::StaticItem (StaticItem const &other) + : VisItem (other), mut (other.mut), name (other.name), + type (other.type->clone_type ()), expr (other.expr->clone_expr ()), + locus (other.locus) +{} + +StaticItem & +StaticItem::operator= (StaticItem const &other) +{ + VisItem::operator= (other); + name = other.name; + mut = other.mut; + type = other.type->clone_type (); + expr = other.expr->clone_expr (); + locus = other.locus; + + return *this; +} + +TraitFunctionDecl::TraitFunctionDecl ( + Identifier function_name, FunctionQualifiers qualifiers, + std::vector<std::unique_ptr<GenericParam>> generic_params, SelfParam self, + std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, + WhereClause where_clause) + : qualifiers (std::move (qualifiers)), + function_name (std::move (function_name)), + generic_params (std::move (generic_params)), + function_params (std::move (function_params)), + return_type (std::move (return_type)), + where_clause (std::move (where_clause)), self (std::move (self)) +{} + +TraitFunctionDecl::TraitFunctionDecl (TraitFunctionDecl const &other) + : qualifiers (other.qualifiers), function_name (other.function_name), + function_params (other.function_params), + return_type (other.return_type->clone_type ()), + where_clause (other.where_clause), self (other.self) +{ + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); +} + +TraitFunctionDecl & +TraitFunctionDecl::operator= (TraitFunctionDecl const &other) +{ + function_name = other.function_name; + qualifiers = other.qualifiers; + function_params = other.function_params; + return_type = other.return_type->clone_type (); + where_clause = other.where_clause; + self = other.self; + + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); + + return *this; +} + +TraitItemFunc::TraitItemFunc (Analysis::NodeMapping mappings, + TraitFunctionDecl decl, + std::unique_ptr<BlockExpr> block_expr, + AST::AttrVec outer_attrs, location_t locus) + : TraitItem (mappings), outer_attrs (std::move (outer_attrs)), + decl (std::move (decl)), block_expr (std::move (block_expr)), locus (locus) +{} + +TraitItemFunc::TraitItemFunc (TraitItemFunc const &other) + : TraitItem (other.mappings), outer_attrs (other.outer_attrs), + decl (other.decl), locus (other.locus) +{ + if (other.block_expr != nullptr) + block_expr = other.block_expr->clone_block_expr (); +} + +TraitItemFunc & +TraitItemFunc::operator= (TraitItemFunc const &other) +{ + TraitItem::operator= (other); + outer_attrs = other.outer_attrs; + decl = other.decl; + locus = other.locus; + mappings = other.mappings; + if (other.block_expr != nullptr) + block_expr = other.block_expr->clone_block_expr (); + + return *this; +} + +TraitItemConst::TraitItemConst (Analysis::NodeMapping mappings, Identifier name, + std::unique_ptr<Type> type, + std::unique_ptr<Expr> expr, + AST::AttrVec outer_attrs, location_t locus) + : TraitItem (mappings), outer_attrs (std::move (outer_attrs)), + name (std::move (name)), type (std::move (type)), expr (std::move (expr)), + locus (locus) +{} + +TraitItemConst::TraitItemConst (TraitItemConst const &other) + : TraitItem (other.mappings), outer_attrs (other.outer_attrs), + name (other.name), type (other.type->clone_type ()), + expr (other.expr->clone_expr ()), locus (other.locus) +{} + +TraitItemConst & +TraitItemConst::operator= (TraitItemConst const &other) +{ + TraitItem::operator= (other); + outer_attrs = other.outer_attrs; + name = other.name; + type = other.type->clone_type (); + expr = other.expr->clone_expr (); + locus = other.locus; + mappings = other.mappings; + + return *this; +} + +TraitItemType::TraitItemType ( + Analysis::NodeMapping mappings, Identifier name, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + AST::AttrVec outer_attrs, location_t locus) + : TraitItem (mappings), outer_attrs (std::move (outer_attrs)), + name (std::move (name)), type_param_bounds (std::move (type_param_bounds)), + locus (locus) +{} + +TraitItemType::TraitItemType (TraitItemType const &other) + : TraitItem (other.mappings), outer_attrs (other.outer_attrs), + name (other.name), locus (other.locus) +{ + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); +} + +TraitItemType & +TraitItemType::operator= (TraitItemType const &other) +{ + TraitItem::operator= (other); + outer_attrs = other.outer_attrs; + name = other.name; + locus = other.locus; + mappings = other.mappings; + + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + return *this; +} + +Trait::Trait (Analysis::NodeMapping mappings, Identifier name, + Unsafety unsafety, + std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + WhereClause where_clause, + std::vector<std::unique_ptr<TraitItem>> trait_items, + Visibility vis, AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + unsafety (unsafety), name (std::move (name)), + generic_params (std::move (generic_params)), + type_param_bounds (std::move (type_param_bounds)), + where_clause (std::move (where_clause)), + trait_items (std::move (trait_items)), locus (locus) +{} + +Trait::Trait (Trait const &other) + : VisItem (other), unsafety (other.unsafety), name (other.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 ()); + + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + trait_items.reserve (other.trait_items.size ()); + for (const auto &e : other.trait_items) + trait_items.push_back (e->clone_trait_item ()); +} + +Trait & +Trait::operator= (Trait const &other) +{ + VisItem::operator= (other); + name = other.name; + unsafety = other.unsafety; + 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 ()); + + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + trait_items.reserve (other.trait_items.size ()); + for (const auto &e : other.trait_items) + trait_items.push_back (e->clone_trait_item ()); + + return *this; +} + +ImplBlock::ImplBlock (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<ImplItem>> impl_items, + std::vector<std::unique_ptr<GenericParam>> generic_params, + std::unique_ptr<Type> impl_type, + std::unique_ptr<TypePath> trait_ref, + WhereClause where_clause, BoundPolarity polarity, + Visibility vis, AST::AttrVec inner_attrs, + AST::AttrVec outer_attrs, location_t locus, bool unsafe) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + WithInnerAttrs (std::move (inner_attrs)), + generic_params (std::move (generic_params)), + impl_type (std::move (impl_type)), trait_ref (std::move (trait_ref)), + where_clause (std::move (where_clause)), polarity (polarity), locus (locus), + impl_items (std::move (impl_items)), unsafe (unsafe) +{} + +ImplBlock::ImplBlock (ImplBlock const &other) + : VisItem (other), WithInnerAttrs (other.inner_attrs), + impl_type (other.impl_type->clone_type ()), + where_clause (other.where_clause), polarity (other.polarity), + locus (other.locus), unsafe (other.unsafe) +{ + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); + + impl_items.reserve (other.impl_items.size ()); + for (const auto &e : other.impl_items) + impl_items.push_back (e->clone_inherent_impl_item ()); +} + +ImplBlock & +ImplBlock::operator= (ImplBlock const &other) +{ + VisItem::operator= (other); + impl_type = other.impl_type->clone_type (); + where_clause = other.where_clause; + polarity = other.polarity; + inner_attrs = other.inner_attrs; + locus = other.locus; + unsafe = other.unsafe; + + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); + + impl_items.reserve (other.impl_items.size ()); + for (const auto &e : other.impl_items) + impl_items.push_back (e->clone_inherent_impl_item ()); + + return *this; +} + +ExternalItem::ExternalItem (Analysis::NodeMapping mappings, + Identifier item_name, Visibility vis, + AST::AttrVec outer_attrs, location_t locus) + : mappings (mappings), outer_attrs (std::move (outer_attrs)), + visibility (std::move (vis)), item_name (std::move (item_name)), + locus (locus) +{} + +ExternalItem::ExternalItem (ExternalItem const &other) + : mappings (other.mappings), outer_attrs (other.outer_attrs), + visibility (other.visibility), item_name (other.item_name), + locus (other.locus) +{} + +ExternalItem & +ExternalItem::operator= (ExternalItem const &other) +{ + mappings = other.mappings; + item_name = other.item_name; + visibility = other.visibility; + outer_attrs = other.outer_attrs; + locus = other.locus; + + return *this; +} + +ExternalStaticItem::ExternalStaticItem (Analysis::NodeMapping mappings, + Identifier item_name, + std::unique_ptr<Type> item_type, + Mutability mut, Visibility vis, + AST::AttrVec outer_attrs, + location_t locus) + : ExternalItem (std::move (mappings), std::move (item_name), std::move (vis), + std::move (outer_attrs), locus), + mut (mut), item_type (std::move (item_type)) +{} + +ExternalStaticItem::ExternalStaticItem (ExternalStaticItem const &other) + : ExternalItem (other), mut (other.mut), + item_type (other.item_type->clone_type ()) +{} + +ExternalStaticItem & +ExternalStaticItem::operator= (ExternalStaticItem const &other) +{ + ExternalItem::operator= (other); + item_type = other.item_type->clone_type (); + mut = other.mut; + + return *this; +} + +NamedFunctionParam::NamedFunctionParam (Analysis::NodeMapping mappings, + Identifier name, + std::unique_ptr<Type> param_type) + : name (std::move (name)), param_type (std::move (param_type)), + mappings (std::move (mappings)) +{} + +NamedFunctionParam::NamedFunctionParam (NamedFunctionParam const &other) + : name (other.name), param_type (other.param_type->clone_type ()), + mappings (other.mappings) +{} + +NamedFunctionParam & +NamedFunctionParam::operator= (NamedFunctionParam const &other) +{ + mappings = other.mappings; + name = other.name; + param_type = other.param_type->clone_type (); + // has_name = other.has_name; + + return *this; +} + +ExternalFunctionItem::ExternalFunctionItem ( + Analysis::NodeMapping mappings, Identifier item_name, + std::vector<std::unique_ptr<GenericParam>> generic_params, + std::unique_ptr<Type> return_type, WhereClause where_clause, + std::vector<NamedFunctionParam> function_params, bool has_variadics, + Visibility vis, AST::AttrVec outer_attrs, location_t locus) + : ExternalItem (std::move (mappings), std::move (item_name), std::move (vis), + std::move (outer_attrs), locus), + generic_params (std::move (generic_params)), + return_type (std::move (return_type)), + where_clause (std::move (where_clause)), + function_params (std::move (function_params)), has_variadics (has_variadics) +{} + +ExternalFunctionItem::ExternalFunctionItem (ExternalFunctionItem const &other) + : ExternalItem (other), where_clause (other.where_clause), + function_params (other.function_params), has_variadics (other.has_variadics) +{ + if (other.return_type) + return_type = other.return_type->clone_type (); + + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); +} + +ExternalFunctionItem & +ExternalFunctionItem::operator= (ExternalFunctionItem const &other) +{ + ExternalItem::operator= (other); + + where_clause = other.where_clause; + function_params = other.function_params; + has_variadics = other.has_variadics; + + if (other.return_type) + return_type = other.return_type->clone_type (); + + generic_params.reserve (other.generic_params.size ()); + for (const auto &e : other.generic_params) + generic_params.push_back (e->clone_generic_param ()); + + return *this; +} + +ExternalTypeItem::ExternalTypeItem (Analysis::NodeMapping mappings, + Identifier item_name, Visibility vis, + location_t locus) + : ExternalItem (std::move (mappings), std::move (item_name), + Visibility (std::move (vis)), + /* FIXME: Is that correct? */ + {}, locus) +{} + +ExternalTypeItem::ExternalTypeItem (ExternalTypeItem const &other) + : ExternalItem (other) +{} + +ExternBlock::ExternBlock ( + Analysis::NodeMapping mappings, ABI abi, + std::vector<std::unique_ptr<ExternalItem>> extern_items, Visibility vis, + AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, location_t locus) + : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), + WithInnerAttrs (std::move (inner_attrs)), abi (abi), + extern_items (std::move (extern_items)), locus (locus) +{} + +ExternBlock::ExternBlock (ExternBlock const &other) + : VisItem (other), WithInnerAttrs (other.inner_attrs), abi (other.abi), + locus (other.locus) +{ + extern_items.reserve (other.extern_items.size ()); + for (const auto &e : other.extern_items) + extern_items.push_back (e->clone_external_item ()); +} + +ExternBlock & +ExternBlock::operator= (ExternBlock const &other) +{ + VisItem::operator= (other); + abi = other.abi; + inner_attrs = other.inner_attrs; + locus = other.locus; + + extern_items.reserve (other.extern_items.size ()); + for (const auto &e : other.extern_items) + extern_items.push_back (e->clone_external_item ()); + + return *this; +} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index 1f53e85..4744717 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -19,18 +19,77 @@ #ifndef RUST_HIR_ITEM_H #define RUST_HIR_ITEM_H +#include "optional.h" #include "rust-abi.h" -#include "rust-ast-full-decls.h" +#include "rust-hir-stmt.h" #include "rust-common.h" -#include "rust-hir-expr.h" -#include "rust-hir.h" -#include "rust-hir-path.h" +#include "rust-hir-visibility.h" +#include "rust-hir-generic-param.h" +#include "rust-system.h" namespace Rust { namespace HIR { -// forward decls -class BlockExpr; -class TypePath; + +// 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<Item> clone_item () const + { + return std::unique_ptr<Item> (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<std::string> &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 @@ -44,14 +103,13 @@ class TypeParam : public GenericParam std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; // inlined form - // bool has_type; - std::unique_ptr<Type> type; + tl::optional<std::unique_ptr<Type>> type; location_t locus; public: // Returns whether the type of the type param has been specified. - bool has_type () const { return type != nullptr; } + 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 (); } @@ -64,50 +122,18 @@ public: location_t locus = UNDEF_LOCATION, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds = std::vector<std::unique_ptr<TypeParamBound>> (), - std::unique_ptr<Type> type = nullptr, - AST::AttrVec outer_attrs = std::vector<AST::Attribute> ()) - : GenericParam (mappings), outer_attrs (std::move (outer_attrs)), - type_representation (std::move (type_representation)), - type_param_bounds (std::move (type_param_bounds)), - type (std::move (type)), locus (locus) - {} + tl::optional<std::unique_ptr<Type>> type = tl::nullopt, + AST::AttrVec outer_attrs = std::vector<AST::Attribute> ()); // Copy constructor uses clone - TypeParam (TypeParam const &other) - : GenericParam (other.mappings), outer_attrs (other.outer_attrs), - type_representation (other.type_representation), locus (other.locus) - { - // guard to prevent null pointer dereference - if (other.type != nullptr) - type = other.type->clone_type (); - - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - } + TypeParam (TypeParam const &other); // Overloaded assignment operator to clone - TypeParam &operator= (TypeParam const &other) - { - type_representation = other.type_representation; - outer_attrs = other.outer_attrs; - locus = other.locus; - mappings = other.mappings; - - // guard to prevent null pointer dereference - if (other.type != nullptr) - type = other.type->clone_type (); - else - type = nullptr; + TypeParam &operator= (TypeParam const &other); - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - return *this; - } // move constructors TypeParam (TypeParam &&other) = default; + TypeParam &operator= (TypeParam &&other) = default; std::string as_string () const override; @@ -118,18 +144,15 @@ public: Identifier get_type_representation () const { return type_representation; } - std::unique_ptr<Type> &get_type () { return type; } - - Analysis::NodeMapping get_type_mappings () const + Type &get_type () { - rust_assert (type != nullptr); - return type->get_mappings (); + rust_assert (*type); + return *type.value (); } - std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds () - { - return type_param_bounds; - } + Analysis::NodeMapping get_type_mappings () const; + + std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds (); protected: // Clone function implementation as (not pure) virtual method @@ -234,35 +257,13 @@ public: Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes, std::unique_ptr<Type> bound_type, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, - location_t locus) - : for_lifetimes (std::move (for_lifetimes)), - bound_type (std::move (bound_type)), - type_param_bounds (std::move (type_param_bounds)), - mappings (std::move (mappings)), locus (locus) - {} + location_t locus); // Copy constructor requires clone - TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other) - : for_lifetimes (other.for_lifetimes), - bound_type (other.bound_type->clone_type ()), mappings (other.mappings) - { - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - } + TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other); // Overload assignment operator to clone - TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other) - { - mappings = other.mappings; - for_lifetimes = other.for_lifetimes; - bound_type = other.bound_type->clone_type (); - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - return *this; - } + TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other); // move constructors TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default; @@ -277,12 +278,9 @@ public: std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; } - std::unique_ptr<Type> &get_bound_type () { return bound_type; } + Type &get_bound_type () { return *bound_type; } - std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds () - { - return type_param_bounds; - } + std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds (); Analysis::NodeMapping get_mappings () const override final { @@ -379,51 +377,22 @@ private: Analysis::NodeMapping mappings; SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind, - Lifetime lifetime, Type *type) - : self_kind (self_kind), lifetime (std::move (lifetime)), type (type), - mappings (mappings) - {} + Lifetime lifetime, Type *type); public: // Type-based self parameter (not ref, no lifetime) SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, - bool is_mut, location_t locus) - : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM), - lifetime ( - Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)), - type (std::move (type)), locus (locus), mappings (mappings) - {} + 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) - : self_kind (is_mut ? ImplicitSelfKind::MUT_REF - : ImplicitSelfKind::IMM_REF), - lifetime (std::move (lifetime)), locus (locus), mappings (mappings) - {} + location_t locus); // Copy constructor requires clone - SelfParam (SelfParam const &other) - : self_kind (other.self_kind), lifetime (other.lifetime), - locus (other.locus), mappings (other.mappings) - { - if (other.type != nullptr) - type = other.type->clone_type (); - } + SelfParam (SelfParam const &other); // Overload assignment operator to use clone - SelfParam &operator= (SelfParam const &other) - { - if (other.type != nullptr) - type = other.type->clone_type (); - - self_kind = other.self_kind; - lifetime = other.lifetime; - locus = other.locus; - mappings = other.mappings; - - return *this; - } + SelfParam &operator= (SelfParam const &other); // move constructors SelfParam (SelfParam &&other) = default; @@ -452,29 +421,19 @@ public: ImplicitSelfKind get_self_kind () const { return self_kind; } - std::unique_ptr<Type> &get_type () { return type; } + Type &get_type () + { + rust_assert (type); + return *type; + } Analysis::NodeMapping get_mappings () { return mappings; } - Mutability get_mut () const - { - return (self_kind == ImplicitSelfKind::MUT - || self_kind == ImplicitSelfKind::MUT_REF) - ? Mutability::Mut - : Mutability::Imm; - } + Mutability get_mut () const; - bool is_mut () const - { - return self_kind == ImplicitSelfKind::MUT - || self_kind == ImplicitSelfKind::MUT_REF; - } + bool is_mut () const; - bool is_ref () const - { - return self_kind == ImplicitSelfKind::IMM_REF - || self_kind == ImplicitSelfKind::MUT_REF; - } + bool is_ref () const; }; // Qualifiers for function, i.e. const, unsafe, extern etc. @@ -516,28 +475,13 @@ struct FunctionParam public: FunctionParam (Analysis::NodeMapping mappings, std::unique_ptr<Pattern> param_name, - std::unique_ptr<Type> param_type, location_t locus) - : param_name (std::move (param_name)), type (std::move (param_type)), - locus (locus), mappings (mappings) - {} + std::unique_ptr<Type> param_type, location_t locus); // Copy constructor uses clone - FunctionParam (FunctionParam const &other) - : param_name (other.param_name->clone_pattern ()), - type (other.type->clone_type ()), locus (other.locus), - mappings (other.mappings) - {} + FunctionParam (FunctionParam const &other); // Overload assignment operator to use clone - FunctionParam &operator= (FunctionParam const &other) - { - param_name = other.param_name->clone_pattern (); - type = other.type->clone_type (); - locus = other.locus; - mappings = other.mappings; - - return *this; - } + FunctionParam &operator= (FunctionParam const &other); // move constructors FunctionParam (FunctionParam &&other) = default; @@ -547,63 +491,15 @@ public: location_t get_locus () const { return locus; } - std::unique_ptr<Pattern> &get_param_name () { return param_name; } - - std::unique_ptr<Type> &get_type () { return type; } - - const Analysis::NodeMapping &get_mappings () const { return mappings; } -}; - -// Visibility of an item -struct Visibility -{ -public: - enum VisType - { - PRIVATE, - PUBLIC, - RESTRICTED, - ERROR, - }; - -private: - VisType vis_type; - HIR::SimplePath path; - location_t locus; + Pattern &get_param_name () { return *param_name; } - // should this store location info? - -public: - Visibility (VisType vis_type, - HIR::SimplePath path = HIR::SimplePath::create_empty (), - location_t locus = UNDEF_LOCATION) - : vis_type (vis_type), path (std::move (path)), locus (locus) - {} - - // Returns whether visibility is in an error state. - bool is_error () const { return vis_type == ERROR; } - - // Does the current visibility refer to a simple `pub <item>` entirely public - bool is_public () const { return vis_type == PUBLIC; } - - // Is the current visibility public restricted to a certain path - bool is_restricted () const { return vis_type == RESTRICTED; } - - // Creates an error visibility. - static Visibility create_error () + Type &get_type () { - return Visibility (ERROR, HIR::SimplePath::create_empty ()); + rust_assert (type); + return *type; } - VisType get_vis_type () const { return vis_type; } - - const HIR::SimplePath &get_path () const - { - rust_assert (!is_error ()); - return path; - } - - std::string as_string () const; + const Analysis::NodeMapping &get_mappings () const { return mappings; } }; // Item that supports visibility - abstract base class @@ -620,18 +516,10 @@ protected: {} // Visibility copy constructor - VisItem (VisItem const &other) : Item (other), visibility (other.visibility) - {} + VisItem (VisItem const &other); // Overload assignment operator to clone - VisItem &operator= (VisItem const &other) - { - Item::operator= (other); - visibility = other.visibility; - // outer_attrs = other.outer_attrs; - - return *this; - } + VisItem &operator= (VisItem const &other); // move constructors VisItem (VisItem &&other) = default; @@ -673,34 +561,13 @@ public: location_t locus, std::vector<std::unique_ptr<Item>> items, Visibility visibility = Visibility::create_error (), AST::AttrVec inner_attrs = AST::AttrVec (), - AST::AttrVec outer_attrs = AST::AttrVec ()) - : VisItem (std::move (mappings), std::move (visibility), - std::move (outer_attrs)), - WithInnerAttrs (std::move (inner_attrs)), module_name (module_name), - locus (locus), items (std::move (items)) - {} + AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor with vector clone - Module (Module const &other) - : VisItem (other), WithInnerAttrs (other.inner_attrs), module_name ("") - { - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_item ()); - } + Module (Module const &other); // Overloaded assignment operator with vector clone - Module &operator= (Module const &other) - { - VisItem::operator= (other); - inner_attrs = other.inner_attrs; - - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_item ()); - - return *this; - } + Module &operator= (Module const &other); // move constructors Module (Module &&other) = default; @@ -1056,7 +923,7 @@ public: location_t get_locus () const override final { return locus; } ItemKind get_item_kind () const override { return ItemKind::UseDeclaration; } - std::unique_ptr<UseTree> &get_use_tree () { return use_tree; } + 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; @@ -1120,63 +987,13 @@ public: std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, - AST::AttrVec outer_attrs, SelfParam self, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - qualifiers (std::move (qualifiers)), - function_name (std::move (function_name)), - generic_params (std::move (generic_params)), - function_params (std::move (function_params)), - return_type (std::move (return_type)), - where_clause (std::move (where_clause)), - function_body (std::move (function_body)), self (std::move (self)), - locus (locus) - {} + AST::AttrVec outer_attrs, SelfParam self, location_t locus); // Copy constructor with clone - Function (Function const &other) - : VisItem (other), qualifiers (other.qualifiers), - function_name (other.function_name), - function_params (other.function_params), - where_clause (other.where_clause), - function_body (other.function_body->clone_block_expr ()), - self (other.self), locus (other.locus) - { - // guard to prevent null dereference (always required) - if (other.return_type != nullptr) - return_type = other.return_type->clone_type (); - else - return_type = nullptr; - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - } + Function (Function const &other); // Overloaded assignment operator to clone - Function &operator= (Function const &other) - { - VisItem::operator= (other); - function_name = other.function_name; - qualifiers = other.qualifiers; - function_params = other.function_params; - - // guard to prevent null dereference (always required) - if (other.return_type != nullptr) - return_type = other.return_type->clone_type (); - else - return_type = nullptr; - - where_clause = other.where_clause; - function_body = other.function_body->clone_block_expr (); - locus = other.locus; - self = other.self; - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - return *this; - } + Function &operator= (Function const &other); // move constructors Function (Function &&other) = default; @@ -1210,7 +1027,7 @@ public: } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_definition () { return function_body; } + BlockExpr &get_definition () { return *function_body; } const FunctionQualifiers &get_qualifiers () const { return qualifiers; } @@ -1222,7 +1039,7 @@ public: bool has_return_type () const { return return_type != nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { return return_type; } + Type &get_return_type () { return *return_type; } bool is_method () const { return !self.is_error (); } @@ -1280,40 +1097,13 @@ public: TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name, std::vector<std::unique_ptr<GenericParam>> generic_params, WhereClause where_clause, std::unique_ptr<Type> existing_type, - Visibility vis, AST::AttrVec outer_attrs, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - new_type_name (std::move (new_type_name)), - generic_params (std::move (generic_params)), - where_clause (std::move (where_clause)), - existing_type (std::move (existing_type)), locus (locus) - {} + Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor - TypeAlias (TypeAlias const &other) - : VisItem (other), new_type_name (other.new_type_name), - where_clause (other.where_clause), - existing_type (other.existing_type->clone_type ()), 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 ()); - } + TypeAlias (TypeAlias const &other); // Overloaded assignment operator to clone - TypeAlias &operator= (TypeAlias const &other) - { - VisItem::operator= (other); - new_type_name = other.new_type_name; - where_clause = other.where_clause; - existing_type = other.existing_type->clone_type (); - 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; - } + TypeAlias &operator= (TypeAlias const &other); // move constructors TypeAlias (TypeAlias &&other) = default; @@ -1337,7 +1127,11 @@ public: WhereClause &get_where_clause () { return where_clause; } - std::unique_ptr<Type> &get_type_aliased () { return existing_type; } + Type &get_type_aliased () + { + rust_assert (existing_type); + return *existing_type; + } Identifier get_new_type_name () const { return new_type_name; } @@ -1468,32 +1262,15 @@ public: StructField (Analysis::NodeMapping mappings, Identifier field_name, std::unique_ptr<Type> field_type, Visibility vis, - location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ()) - : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), - field_name (std::move (field_name)), field_type (std::move (field_type)), - mappings (mappings), locus (locus) - {} + location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor - StructField (StructField const &other) - : outer_attrs (other.outer_attrs), visibility (other.visibility), - field_name (other.field_name), - field_type (other.field_type->clone_type ()), mappings (other.mappings) - {} + StructField (StructField const &other); ~StructField () = default; // Overloaded assignment operator to clone - StructField &operator= (StructField const &other) - { - field_name = other.field_name; - field_type = other.field_type->clone_type (); - visibility = other.visibility; - outer_attrs = other.outer_attrs; - mappings = other.mappings; - - return *this; - } + StructField &operator= (StructField const &other); // move constructors StructField (StructField &&other) = default; @@ -1503,7 +1280,7 @@ public: Identifier get_field_name () const { return field_name; } - std::unique_ptr<Type> &get_field_type () { return field_type; } + Type &get_field_type () { return *field_type; } Analysis::NodeMapping get_mappings () const { return mappings; } @@ -1598,31 +1375,15 @@ public: // Complete constructor TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type, Visibility vis, location_t locus, - AST::AttrVec outer_attrs = AST::AttrVec ()) - : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), - field_type (std::move (field_type)), locus (locus), mappings (mapping) - {} + AST::AttrVec outer_attrs = AST::AttrVec ()); // Copy constructor with clone - TupleField (TupleField const &other) - : outer_attrs (other.outer_attrs), visibility (other.visibility), - field_type (other.field_type->clone_type ()), locus (other.locus), - mappings (other.mappings) - {} + TupleField (TupleField const &other); ~TupleField () = default; // Overloaded assignment operator to clone - TupleField &operator= (TupleField const &other) - { - field_type = other.field_type->clone_type (); - visibility = other.visibility; - outer_attrs = other.outer_attrs; - locus = other.locus; - mappings = other.mappings; - - return *this; - } + TupleField &operator= (TupleField const &other); // move constructors TupleField (TupleField &&other) = default; @@ -1640,7 +1401,7 @@ public: location_t get_locus () const { return locus; } AST::AttrVec &get_outer_attrs () { return outer_attrs; } - std::unique_ptr<HIR::Type> &get_field_type () { return field_type; } + HIR::Type &get_field_type () { return *field_type; } }; // Rust tuple declared using struct keyword HIR node @@ -1656,12 +1417,7 @@ public: Identifier struct_name, std::vector<std::unique_ptr<GenericParam>> 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)), - fields (std::move (fields)) - {} + AST::AttrVec outer_attrs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; @@ -1706,10 +1462,7 @@ public: }; EnumItem (Analysis::NodeMapping mappings, Identifier variant_name, - AST::AttrVec outer_attrs, location_t locus) - : Item (std::move (mappings), std::move (outer_attrs)), - variant_name (std::move (variant_name)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Unique pointer custom clone function std::unique_ptr<EnumItem> clone_enum_item () const @@ -1752,11 +1505,7 @@ public: EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name, std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs, - location_t locus) - : EnumItem (std::move (mappings), std::move (variant_name), - std::move (outer_attrs), locus), - tuple_fields (std::move (tuple_fields)) - {} + location_t locus); std::string as_string () const override; @@ -1790,11 +1539,7 @@ public: EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name, std::vector<StructField> struct_fields, - AST::AttrVec outer_attrs, location_t locus) - : EnumItem (std::move (mappings), std::move (variant_name), - std::move (outer_attrs), locus), - struct_fields (std::move (struct_fields)) - {} + AST::AttrVec outer_attrs, location_t locus); std::string as_string () const override; @@ -1819,27 +1564,13 @@ class EnumItemDiscriminant : public EnumItem public: EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name, std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs, - location_t locus) - : EnumItem (std::move (mappings), std::move (variant_name), - std::move (outer_attrs), locus), - expression (std::move (expr)) - {} + location_t locus); // Copy constructor with clone - EnumItemDiscriminant (EnumItemDiscriminant const &other) - : EnumItem (other), expression (other.expression->clone_expr ()) - {} + EnumItemDiscriminant (EnumItemDiscriminant const &other); // Overloaded assignment operator to clone - EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other) - { - EnumItem::operator= (other); - expression = other.expression->clone_expr (); - // variant_name = other.variant_name; - // outer_attrs = other.outer_attrs; - - return *this; - } + EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other); // move constructors EnumItemDiscriminant (EnumItemDiscriminant &&other) = default; @@ -1855,7 +1586,12 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRStmtVisitor &vis) override; - std::unique_ptr<Expr> &get_discriminant_expression () { return expression; } + Expr &get_discriminant_expression () { return *expression; } + + std::unique_ptr<Expr> take_discriminant_expression () + { + return std::move (expression); + } protected: // Clone function implementation as (not pure) virtual method @@ -1898,48 +1634,15 @@ public: Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis, std::vector<std::unique_ptr<GenericParam>> generic_params, WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items, - AST::AttrVec outer_attrs, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - enum_name (std::move (enum_name)), - generic_params (std::move (generic_params)), - where_clause (std::move (where_clause)), items (std::move (items)), - locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // TODO: constructor with less arguments // Copy constructor with vector clone - Enum (Enum const &other) - : VisItem (other), enum_name (other.enum_name), - where_clause (other.where_clause), locus (other.locus) - { - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_enum_item ()); - } + Enum (Enum const &other); // Overloaded assignment operator with vector clone - Enum &operator= (Enum const &other) - { - VisItem::operator= (other); - enum_name = other.enum_name; - where_clause = other.where_clause; - locus = other.locus; - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_enum_item ()); - - return *this; - } + Enum &operator= (Enum const &other); // Move constructors Enum (Enum &&other) = default; @@ -2007,40 +1710,13 @@ public: Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis, std::vector<std::unique_ptr<GenericParam>> generic_params, WhereClause where_clause, std::vector<StructField> variants, - AST::AttrVec outer_attrs, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - union_name (std::move (union_name)), - generic_params (std::move (generic_params)), - where_clause (std::move (where_clause)), variants (std::move (variants)), - locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // copy constructor with vector clone - Union (Union const &other) - : VisItem (other), union_name (other.union_name), - where_clause (other.where_clause), variants (other.variants), - locus (other.locus) - { - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - } + Union (Union const &other); // overloaded assignment operator with vector clone - Union &operator= (Union const &other) - { - VisItem::operator= (other); - union_name = other.union_name; - where_clause = other.where_clause; - variants = other.variants; - locus = other.locus; - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - return *this; - } + Union &operator= (Union const &other); // move constructors Union (Union &&other) = default; @@ -2084,29 +1760,12 @@ public: ConstantItem (Analysis::NodeMapping mappings, Identifier ident, Visibility vis, std::unique_ptr<Type> type, std::unique_ptr<Expr> const_expr, AST::AttrVec outer_attrs, - location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - identifier (std::move (ident)), type (std::move (type)), - const_expr (std::move (const_expr)), locus (locus) - {} + location_t locus); - ConstantItem (ConstantItem const &other) - : VisItem (other), identifier (other.identifier), - type (other.type->clone_type ()), - const_expr (other.const_expr->clone_expr ()), locus (other.locus) - {} + ConstantItem (ConstantItem const &other); // Overload assignment operator to clone - ConstantItem &operator= (ConstantItem const &other) - { - VisItem::operator= (other); - identifier = other.identifier; - type = other.type->clone_type (); - const_expr = other.const_expr->clone_expr (); - locus = other.locus; - - return *this; - } + ConstantItem &operator= (ConstantItem const &other); // move constructors ConstantItem (ConstantItem &&other) = default; @@ -2126,9 +1785,13 @@ public: void accept_vis (HIRImplVisitor &vis) override; void accept_vis (HIRVisItemVisitor &vis) override; - std::unique_ptr<Type> &get_type () { return type; } + Type &get_type () + { + rust_assert (type); + return *type; + } - std::unique_ptr<Expr> &get_expr () { return const_expr; } + Expr &get_expr () { return *const_expr; } Identifier get_identifier () const { return identifier; } @@ -2180,31 +1843,13 @@ public: StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut, std::unique_ptr<Type> type, std::unique_ptr<Expr> expr, - Visibility vis, AST::AttrVec outer_attrs, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - mut (mut), name (std::move (name)), type (std::move (type)), - expr (std::move (expr)), locus (locus) - {} + Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone - StaticItem (StaticItem const &other) - : VisItem (other), mut (other.mut), name (other.name), - type (other.type->clone_type ()), expr (other.expr->clone_expr ()), - locus (other.locus) - {} + StaticItem (StaticItem const &other); // Overloaded assignment operator to clone - StaticItem &operator= (StaticItem const &other) - { - VisItem::operator= (other); - name = other.name; - mut = other.mut; - type = other.type->clone_type (); - expr = other.expr->clone_expr (); - locus = other.locus; - - return *this; - } + StaticItem &operator= (StaticItem const &other); // move constructors StaticItem (StaticItem &&other) = default; @@ -2222,9 +1867,17 @@ public: bool is_mut () const { return mut == Mutability::Mut; } - std::unique_ptr<Expr> &get_expr () { return expr; } + Expr &get_expr () + { + rust_assert (expr); + return *expr; + } - std::unique_ptr<Type> &get_type () { return type; } + Type &get_type () + { + rust_assert (type); + return *type; + } ItemKind get_item_kind () const override { return ItemKind::Static; } @@ -2253,45 +1906,15 @@ public: std::vector<std::unique_ptr<GenericParam>> generic_params, SelfParam self, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, - WhereClause where_clause) - : qualifiers (std::move (qualifiers)), - function_name (std::move (function_name)), - generic_params (std::move (generic_params)), - function_params (std::move (function_params)), - return_type (std::move (return_type)), - where_clause (std::move (where_clause)), self (std::move (self)) - {} + WhereClause where_clause); // Copy constructor with clone - TraitFunctionDecl (TraitFunctionDecl const &other) - : qualifiers (other.qualifiers), function_name (other.function_name), - function_params (other.function_params), - return_type (other.return_type->clone_type ()), - where_clause (other.where_clause), self (other.self) - { - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - } + TraitFunctionDecl (TraitFunctionDecl const &other); ~TraitFunctionDecl () = default; // Overloaded assignment operator with clone - TraitFunctionDecl &operator= (TraitFunctionDecl const &other) - { - function_name = other.function_name; - qualifiers = other.qualifiers; - function_params = other.function_params; - return_type = other.return_type->clone_type (); - where_clause = other.where_clause; - self = other.self; - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - return *this; - } + TraitFunctionDecl &operator= (TraitFunctionDecl const &other); // move constructors TraitFunctionDecl (TraitFunctionDecl &&other) = default; @@ -2324,7 +1947,7 @@ public: return generic_params; } - std::unique_ptr<Type> &get_return_type () { return return_type; } + Type &get_return_type () { return *return_type; } std::vector<FunctionParam> &get_function_params () { return function_params; } @@ -2345,34 +1968,13 @@ public: TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl, std::unique_ptr<BlockExpr> block_expr, - AST::AttrVec outer_attrs, location_t locus) - : TraitItem (mappings), outer_attrs (std::move (outer_attrs)), - decl (std::move (decl)), block_expr (std::move (block_expr)), - locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone - TraitItemFunc (TraitItemFunc const &other) - : TraitItem (other.mappings), outer_attrs (other.outer_attrs), - decl (other.decl), locus (other.locus) - { - if (other.block_expr != nullptr) - block_expr = other.block_expr->clone_block_expr (); - } + TraitItemFunc (TraitItemFunc const &other); // Overloaded assignment operator to clone - TraitItemFunc &operator= (TraitItemFunc const &other) - { - TraitItem::operator= (other); - outer_attrs = other.outer_attrs; - decl = other.decl; - locus = other.locus; - mappings = other.mappings; - if (other.block_expr != nullptr) - block_expr = other.block_expr->clone_block_expr (); - - return *this; - } + TraitItemFunc &operator= (TraitItemFunc const &other); // move constructors TraitItemFunc (TraitItemFunc &&other) = default; @@ -2389,9 +1991,7 @@ public: const TraitFunctionDecl &get_decl () const { return decl; } - bool has_block_defined () const { return block_expr != nullptr; } - - std::unique_ptr<BlockExpr> &get_block_expr () { return block_expr; } + BlockExpr &get_block_expr () { return *block_expr; } const std::string trait_identifier () const override final { @@ -2434,32 +2034,13 @@ public: TraitItemConst (Analysis::NodeMapping mappings, Identifier name, std::unique_ptr<Type> type, std::unique_ptr<Expr> expr, - AST::AttrVec outer_attrs, location_t locus) - : TraitItem (mappings), outer_attrs (std::move (outer_attrs)), - name (std::move (name)), type (std::move (type)), expr (std::move (expr)), - locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clones - TraitItemConst (TraitItemConst const &other) - : TraitItem (other.mappings), outer_attrs (other.outer_attrs), - name (other.name), type (other.type->clone_type ()), - expr (other.expr->clone_expr ()), locus (other.locus) - {} + TraitItemConst (TraitItemConst const &other); // Overloaded assignment operator to clone - TraitItemConst &operator= (TraitItemConst const &other) - { - TraitItem::operator= (other); - outer_attrs = other.outer_attrs; - name = other.name; - type = other.type->clone_type (); - expr = other.expr->clone_expr (); - locus = other.locus; - mappings = other.mappings; - - return *this; - } + TraitItemConst &operator= (TraitItemConst const &other); // move constructors TraitItemConst (TraitItemConst &&other) = default; @@ -2476,9 +2057,17 @@ public: bool has_expr () const { return expr != nullptr; } - std::unique_ptr<Type> &get_type () { return type; } + Type &get_type () + { + rust_assert (type); + return *type; + } - std::unique_ptr<Expr> &get_expr () { return expr; } + Expr &get_expr () + { + rust_assert (expr); + return *expr; + } const std::string trait_identifier () const override final { @@ -2522,37 +2111,13 @@ public: TraitItemType (Analysis::NodeMapping mappings, Identifier name, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, - AST::AttrVec outer_attrs, location_t locus) - : TraitItem (mappings), outer_attrs (std::move (outer_attrs)), - name (std::move (name)), - type_param_bounds (std::move (type_param_bounds)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Copy constructor with vector clone - TraitItemType (TraitItemType const &other) - : TraitItem (other.mappings), outer_attrs (other.outer_attrs), - name (other.name), locus (other.locus) - { - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - } + TraitItemType (TraitItemType const &other); // Overloaded assignment operator with vector clone - TraitItemType &operator= (TraitItemType const &other) - { - TraitItem::operator= (other); - outer_attrs = other.outer_attrs; - name = other.name; - locus = other.locus; - mappings = other.mappings; - - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - return *this; - } + TraitItemType &operator= (TraitItemType const &other); // default move constructors TraitItemType (TraitItemType &&other) = default; @@ -2640,56 +2205,13 @@ public: std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, WhereClause where_clause, std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis, - AST::AttrVec outer_attrs, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - unsafety (unsafety), name (std::move (name)), - generic_params (std::move (generic_params)), - type_param_bounds (std::move (type_param_bounds)), - where_clause (std::move (where_clause)), - trait_items (std::move (trait_items)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Copy constructor with vector clone - Trait (Trait const &other) - : VisItem (other), unsafety (other.unsafety), name (other.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 ()); - - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - trait_items.reserve (other.trait_items.size ()); - for (const auto &e : other.trait_items) - trait_items.push_back (e->clone_trait_item ()); - } + Trait (Trait const &other); // Overloaded assignment operator with vector clone - Trait &operator= (Trait const &other) - { - VisItem::operator= (other); - name = other.name; - unsafety = other.unsafety; - 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 ()); - - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - trait_items.reserve (other.trait_items.size ()); - for (const auto &e : other.trait_items) - trait_items.push_back (e->clone_trait_item ()); - - return *this; - } + Trait &operator= (Trait const &other); // default move constructors Trait (Trait &&other) = default; @@ -2748,50 +2270,11 @@ public: std::unique_ptr<Type> impl_type, std::unique_ptr<TypePath> trait_ref, WhereClause where_clause, BoundPolarity polarity, Visibility vis, AST::AttrVec inner_attrs, - AST::AttrVec outer_attrs, location_t locus, bool unsafe = false) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - WithInnerAttrs (std::move (inner_attrs)), - generic_params (std::move (generic_params)), - impl_type (std::move (impl_type)), trait_ref (std::move (trait_ref)), - where_clause (std::move (where_clause)), polarity (polarity), - locus (locus), impl_items (std::move (impl_items)), unsafe (unsafe) - {} - - ImplBlock (ImplBlock const &other) - : VisItem (other), WithInnerAttrs (other.inner_attrs), - impl_type (other.impl_type->clone_type ()), - where_clause (other.where_clause), polarity (other.polarity), - locus (other.locus), unsafe (other.unsafe) - { - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - impl_items.reserve (other.impl_items.size ()); - for (const auto &e : other.impl_items) - impl_items.push_back (e->clone_inherent_impl_item ()); - } - - ImplBlock &operator= (ImplBlock const &other) - { - VisItem::operator= (other); - impl_type = other.impl_type->clone_type (); - where_clause = other.where_clause; - polarity = other.polarity; - inner_attrs = other.inner_attrs; - locus = other.locus; - unsafe = other.unsafe; + AST::AttrVec outer_attrs, location_t locus, bool unsafe = false); - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); + ImplBlock (ImplBlock const &other); - impl_items.reserve (other.impl_items.size ()); - for (const auto &e : other.impl_items) - impl_items.push_back (e->clone_inherent_impl_item ()); - - return *this; - } + ImplBlock &operator= (ImplBlock const &other); ImplBlock (ImplBlock &&other) = default; ImplBlock &operator= (ImplBlock &&other) = default; @@ -2828,7 +2311,13 @@ public: location_t get_locus () const override final { return locus; } - std::unique_ptr<Type> &get_type () { return impl_type; }; + Type &get_type () + { + rust_assert (impl_type); + return *impl_type; + }; + + bool has_type () { return impl_type != nullptr; } std::vector<std::unique_ptr<GenericParam>> &get_generic_params () { @@ -2837,7 +2326,7 @@ public: bool has_trait_ref () const { return trait_ref != nullptr; } - std::unique_ptr<TypePath> &get_trait_ref () { return trait_ref; } + TypePath &get_trait_ref () { return *trait_ref; } WhereClause &get_where_clause () { return where_clause; } @@ -2898,30 +2387,13 @@ public: protected: ExternalItem (Analysis::NodeMapping mappings, Identifier item_name, - Visibility vis, AST::AttrVec outer_attrs, location_t locus) - : mappings (mappings), outer_attrs (std::move (outer_attrs)), - visibility (std::move (vis)), item_name (std::move (item_name)), - locus (locus) - {} + Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor - ExternalItem (ExternalItem const &other) - : mappings (other.mappings), outer_attrs (other.outer_attrs), - visibility (other.visibility), item_name (other.item_name), - locus (other.locus) - {} + ExternalItem (ExternalItem const &other); // Overloaded assignment operator to clone - ExternalItem &operator= (ExternalItem const &other) - { - mappings = other.mappings; - item_name = other.item_name; - visibility = other.visibility; - outer_attrs = other.outer_attrs; - locus = other.locus; - - return *this; - } + ExternalItem &operator= (ExternalItem const &other); // move constructors ExternalItem (ExternalItem &&other) = default; @@ -2941,27 +2413,13 @@ public: ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name, std::unique_ptr<Type> item_type, Mutability mut, Visibility vis, AST::AttrVec outer_attrs, - location_t locus) - : ExternalItem (std::move (mappings), std::move (item_name), - std::move (vis), std::move (outer_attrs), locus), - mut (mut), item_type (std::move (item_type)) - {} + location_t locus); // Copy constructor - ExternalStaticItem (ExternalStaticItem const &other) - : ExternalItem (other), mut (other.mut), - item_type (other.item_type->clone_type ()) - {} + ExternalStaticItem (ExternalStaticItem const &other); // Overloaded assignment operator to clone - ExternalStaticItem &operator= (ExternalStaticItem const &other) - { - ExternalItem::operator= (other); - item_type = other.item_type->clone_type (); - mut = other.mut; - - return *this; - } + ExternalStaticItem &operator= (ExternalStaticItem const &other); // move constructors ExternalStaticItem (ExternalStaticItem &&other) = default; @@ -2976,7 +2434,7 @@ public: Mutability get_mut () { return mut; } - std::unique_ptr<Type> &get_item_type () { return item_type; } + Type &get_item_type () { return *item_type; } ExternKind get_extern_kind () override { return ExternKind::Static; } @@ -3001,29 +2459,15 @@ public: bool has_name () const { return name.as_string () != "_"; } NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name, - std::unique_ptr<Type> param_type) - : name (std::move (name)), param_type (std::move (param_type)), - mappings (std::move (mappings)) - {} + std::unique_ptr<Type> param_type); // Copy constructor - NamedFunctionParam (NamedFunctionParam const &other) - : name (other.name), param_type (other.param_type->clone_type ()), - mappings (other.mappings) - {} + NamedFunctionParam (NamedFunctionParam const &other); ~NamedFunctionParam () = default; // Overloaded assignment operator to clone - NamedFunctionParam &operator= (NamedFunctionParam const &other) - { - mappings = other.mappings; - name = other.name; - param_type = other.param_type->clone_type (); - // has_name = other.has_name; - - return *this; - } + NamedFunctionParam &operator= (NamedFunctionParam const &other); // move constructors NamedFunctionParam (NamedFunctionParam &&other) = default; @@ -3033,7 +2477,11 @@ public: Identifier get_param_name () const { return name; } - std::unique_ptr<Type> &get_type () { return param_type; } + Type &get_type () + { + rust_assert (param_type); + return *param_type; + } Analysis::NodeMapping get_mappings () const { return mappings; } }; @@ -3075,48 +2523,13 @@ public: std::vector<std::unique_ptr<GenericParam>> generic_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::vector<NamedFunctionParam> function_params, bool has_variadics, - Visibility vis, AST::AttrVec outer_attrs, location_t locus) - : ExternalItem (std::move (mappings), std::move (item_name), - std::move (vis), std::move (outer_attrs), locus), - generic_params (std::move (generic_params)), - return_type (std::move (return_type)), - where_clause (std::move (where_clause)), - function_params (std::move (function_params)), - has_variadics (has_variadics) - {} + Visibility vis, AST::AttrVec outer_attrs, location_t locus); // Copy constructor with clone - ExternalFunctionItem (ExternalFunctionItem const &other) - : ExternalItem (other), where_clause (other.where_clause), - function_params (other.function_params), - has_variadics (other.has_variadics) - { - if (other.return_type) - return_type = other.return_type->clone_type (); - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - } + ExternalFunctionItem (ExternalFunctionItem const &other); // Overloaded assignment operator with clone - ExternalFunctionItem &operator= (ExternalFunctionItem const &other) - { - ExternalItem::operator= (other); - - where_clause = other.where_clause; - function_params = other.function_params; - has_variadics = other.has_variadics; - - if (other.return_type) - return_type = other.return_type->clone_type (); - - generic_params.reserve (other.generic_params.size ()); - for (const auto &e : other.generic_params) - generic_params.push_back (e->clone_generic_param ()); - - return *this; - } + ExternalFunctionItem &operator= (ExternalFunctionItem const &other); // move constructors ExternalFunctionItem (ExternalFunctionItem &&other) = default; @@ -3132,7 +2545,7 @@ public: return generic_params; } - std::unique_ptr<Type> &get_return_type () { return return_type; } + Type &get_return_type () { return *return_type; } std::vector<NamedFunctionParam> &get_function_params () { @@ -3156,14 +2569,9 @@ class ExternalTypeItem : public ExternalItem { public: ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name, - Visibility vis, location_t locus) - : ExternalItem (std::move (mappings), std::move (item_name), - Visibility (std::move (vis)), - /* FIXME: Is that correct? */ - {}, locus) - {} + Visibility vis, location_t locus); - ExternalTypeItem (ExternalTypeItem const &other) : ExternalItem (other) {} + ExternalTypeItem (ExternalTypeItem const &other); ExternalTypeItem (ExternalTypeItem &&other) = default; ExternalTypeItem &operator= (ExternalTypeItem &&other) = default; @@ -3203,36 +2611,13 @@ public: ExternBlock (Analysis::NodeMapping mappings, ABI abi, std::vector<std::unique_ptr<ExternalItem>> extern_items, Visibility vis, AST::AttrVec inner_attrs, - AST::AttrVec outer_attrs, location_t locus) - : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), - WithInnerAttrs (std::move (inner_attrs)), abi (abi), - extern_items (std::move (extern_items)), locus (locus) - {} + AST::AttrVec outer_attrs, location_t locus); // Copy constructor with vector clone - ExternBlock (ExternBlock const &other) - : VisItem (other), WithInnerAttrs (other.inner_attrs), abi (other.abi), - locus (other.locus) - { - extern_items.reserve (other.extern_items.size ()); - for (const auto &e : other.extern_items) - extern_items.push_back (e->clone_external_item ()); - } + ExternBlock (ExternBlock const &other); // Overloaded assignment operator with vector clone - ExternBlock &operator= (ExternBlock const &other) - { - VisItem::operator= (other); - abi = other.abi; - inner_attrs = other.inner_attrs; - locus = other.locus; - - extern_items.reserve (other.extern_items.size ()); - for (const auto &e : other.extern_items) - extern_items.push_back (e->clone_external_item ()); - - return *this; - } + ExternBlock &operator= (ExternBlock const &other); // move constructors ExternBlock (ExternBlock &&other) = default; diff --git a/gcc/rust/hir/tree/rust-hir-literal.h b/gcc/rust/hir/tree/rust-hir-literal.h new file mode 100644 index 0000000..9a97e71 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-literal.h @@ -0,0 +1,78 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_LITERAL_H +#define RUST_HIR_LITERAL_H + +#include "rust-token.h" + +namespace Rust { +namespace HIR { +// A literal - value with a type. Used in LiteralExpr and LiteralPattern. +struct Literal +{ +public: + enum LitType + { + CHAR, + STRING, + BYTE, + BYTE_STRING, + INT, + FLOAT, + BOOL + }; + +private: + std::string value_as_string; + LitType type; + PrimitiveCoreType type_hint; + +public: + std::string as_string () const { return value_as_string; } + + LitType get_lit_type () const { return type; } + + PrimitiveCoreType get_type_hint () const { return type_hint; } + + Literal (std::string value_as_string, LitType type, + PrimitiveCoreType type_hint) + : value_as_string (std::move (value_as_string)), type (type), + type_hint (type_hint) + {} + + static Literal create_error () + { + return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN); + } + + void set_lit_type (LitType lt) { type = lt; } + + // Returns whether literal is in an invalid state. + bool is_error () const { return value_as_string == ""; } + + bool is_equal (Literal &other) + { + return value_as_string == other.value_as_string && type == other.type + && type_hint == other.type_hint; + } +}; +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-node.h b/gcc/rust/hir/tree/rust-hir-node.h new file mode 100644 index 0000000..4010c23 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-node.h @@ -0,0 +1,63 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_NODE_H +#define RUST_HIR_NODE_H + +namespace Rust { + +namespace HIR { + +class Node +{ +public: + // Kind for downcasting various HIR nodes to other base classes when visiting + // them + enum BaseKind + { + /* class ExternalItem */ + EXTERNAL, + /* class TraitItem */ + TRAIT_ITEM, + /* class VisItem */ + VIS_ITEM, + /* class Item */ + ITEM, + /* class ImplItem */ + IMPL, + /* class Type */ + TYPE, + /* class Stmt */ + STMT, + /* class Expr */ + EXPR, + /* class Pattern */ + PATTERN, + }; + + /** + * Get the kind of HIR node we are dealing with. This is useful for + * downcasting to more precise types when necessary, i.e going from an `Item*` + * to a `VisItem*` + */ + virtual BaseKind get_hir_kind () = 0; +}; + +} // namespace HIR +} // namespace Rust +#endif diff --git a/gcc/rust/hir/tree/rust-hir-path.cc b/gcc/rust/hir/tree/rust-hir-path.cc new file mode 100644 index 0000000..ee4a572 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-path.cc @@ -0,0 +1,420 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-path.h" +#include "optional.h" +#include "rust-hir-bound.h" + +namespace Rust { +namespace HIR { + +GenericArgsBinding::GenericArgsBinding (Identifier ident, + std::unique_ptr<Type> type_ptr, + location_t locus) + : identifier (std::move (ident)), type (std::move (type_ptr)), locus (locus) +{} + +GenericArgsBinding::GenericArgsBinding (GenericArgsBinding const &other) + : identifier (other.identifier), type (other.type->clone_type ()), + locus (other.locus) +{} + +GenericArgsBinding & +GenericArgsBinding::operator= (GenericArgsBinding const &other) +{ + identifier = other.identifier; + type = other.type->clone_type (); + locus = other.locus; + return *this; +} + +ConstGenericArg::ConstGenericArg (std::unique_ptr<Expr> expression, + location_t locus) + : expression (std::move (expression)), locus (locus) +{} + +ConstGenericArg::ConstGenericArg (const ConstGenericArg &other) + : locus (other.locus) +{ + expression = other.expression->clone_expr (); +} + +ConstGenericArg +ConstGenericArg::operator= (const ConstGenericArg &other) +{ + expression = other.expression->clone_expr (); + locus = other.locus; + + return *this; +} + +GenericArgs & +GenericArgs::operator= (GenericArgs const &other) +{ + lifetime_args = other.lifetime_args; + binding_args = other.binding_args; + const_args = other.const_args; + locus = other.locus; + + type_args.clear (); + type_args.reserve (other.type_args.size ()); + for (const auto &e : other.type_args) + type_args.push_back (e->clone_type ()); + + return *this; +} + +GenericArgs::GenericArgs (std::vector<Lifetime> lifetime_args, + std::vector<std::unique_ptr<Type> > type_args, + std::vector<GenericArgsBinding> binding_args, + std::vector<ConstGenericArg> const_args, + location_t locus) + : lifetime_args (std::move (lifetime_args)), + type_args (std::move (type_args)), binding_args (std::move (binding_args)), + const_args (std::move (const_args)), locus (locus) +{} + +GenericArgs::GenericArgs (GenericArgs const &other) + : lifetime_args (other.lifetime_args), binding_args (other.binding_args), + const_args (other.const_args), locus (other.locus) +{ + type_args.clear (); + type_args.reserve (other.type_args.size ()); + + for (const auto &e : other.type_args) + type_args.push_back (e->clone_type ()); +} + +bool +GenericArgs::is_empty () const +{ + return lifetime_args.size () == 0 && type_args.size () == 0 + && binding_args.size () == 0; +} + +PathExprSegment::PathExprSegment (Analysis::NodeMapping mappings, + PathIdentSegment segment_name, + location_t locus, GenericArgs generic_args) + : mappings (std::move (mappings)), segment_name (std::move (segment_name)), + generic_args (std::move (generic_args)), locus (locus) +{} + +PathExprSegment::PathExprSegment (PathExprSegment const &other) + : mappings (other.mappings), segment_name (other.segment_name), + generic_args (other.generic_args), locus (other.locus) +{} + +PathExprSegment & +PathExprSegment::operator= (PathExprSegment const &other) +{ + mappings = other.mappings; + segment_name = other.segment_name; + generic_args = other.generic_args; + locus = other.locus; + + return *this; +} + +void +PathPattern::iterate_path_segments (std::function<bool (PathExprSegment &)> cb) +{ + rust_assert (kind == Kind::Segmented); + + for (auto it = segments.begin (); it != segments.end (); it++) + { + if (!cb (*it)) + return; + } +} + +PathInExpression::PathInExpression (Analysis::NodeMapping mappings, + std::vector<PathExprSegment> path_segments, + location_t locus, + bool has_opening_scope_resolution, + std::vector<AST::Attribute> outer_attrs) + : PathPattern (std::move (path_segments)), + PathExpr (std::move (mappings), std::move (outer_attrs)), + has_opening_scope_resolution (has_opening_scope_resolution), locus (locus) +{} + +PathInExpression::PathInExpression (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, location_t locus, + bool has_opening_scope_resolution, + std::vector<AST::Attribute> outer_attrs) + : PathPattern (lang_item), + PathExpr (std::move (mappings), std::move (outer_attrs)), + has_opening_scope_resolution (has_opening_scope_resolution), locus (locus) +{} + +bool +PathInExpression::is_self () const + +{ + if (!is_single_segment ()) + return false; + + return get_final_segment ().get_segment ().as_string ().compare ("self") == 0; +} + +TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings, + PathIdentSegment ident_segment, + bool has_separating_scope_resolution, + location_t locus) + : mappings (std::move (mappings)), ident_segment (std::move (ident_segment)), + lang_item (tl::nullopt), locus (locus), + has_separating_scope_resolution (has_separating_scope_resolution), + type (SegmentType::REG) +{} + +TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, location_t locus) + : mappings (std::move (mappings)), ident_segment (tl::nullopt), + lang_item (lang_item), locus (locus), + has_separating_scope_resolution (false), type (SegmentType::REG) +{} + +TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings, + std::string segment_name, + bool has_separating_scope_resolution, + location_t locus) + : mappings (std::move (mappings)), + ident_segment (PathIdentSegment (std::move (segment_name))), + lang_item (tl::nullopt), locus (locus), + has_separating_scope_resolution (has_separating_scope_resolution), + type (SegmentType::REG) +{} + +TypePathSegmentGeneric::TypePathSegmentGeneric ( + Analysis::NodeMapping mappings, PathIdentSegment ident_segment, + bool has_separating_scope_resolution, GenericArgs generic_args, + location_t locus) + : TypePathSegment (std::move (mappings), std::move (ident_segment), + has_separating_scope_resolution, locus), + generic_args (std::move (generic_args)) +{} + +TypePathSegmentGeneric::TypePathSegmentGeneric (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, + GenericArgs generic_args, + location_t locus) + : TypePathSegment (std::move (mappings), lang_item, locus), + generic_args (std::move (generic_args)) +{} + +TypePathSegmentGeneric::TypePathSegmentGeneric ( + Analysis::NodeMapping mappings, std::string segment_name, + bool has_separating_scope_resolution, std::vector<Lifetime> lifetime_args, + std::vector<std::unique_ptr<Type> > type_args, + std::vector<GenericArgsBinding> binding_args, + std::vector<ConstGenericArg> const_args, location_t locus) + : TypePathSegment (std::move (mappings), std::move (segment_name), + has_separating_scope_resolution, locus), + generic_args (GenericArgs (std::move (lifetime_args), std::move (type_args), + std::move (binding_args), std::move (const_args), + locus)) +{} + +TypePathFunction::TypePathFunction (std::vector<std::unique_ptr<Type> > inputs, + std::unique_ptr<Type> type) + : inputs (std::move (inputs)), return_type (std::move (type)) +{} + +TypePathFunction::TypePathFunction (TypePathFunction const &other) +{ + return_type = other.has_return_type () + ? other.get_return_type ().clone_type () + : nullptr; + + inputs.reserve (other.inputs.size ()); + for (const auto &e : other.inputs) + inputs.push_back (e->clone_type ()); +} + +TypePathFunction & +TypePathFunction::operator= (TypePathFunction const &other) +{ + return_type = other.has_return_type () + ? other.get_return_type ().clone_type () + : nullptr; + + inputs.reserve (other.inputs.size ()); + for (const auto &e : other.inputs) + inputs.push_back (e->clone_type ()); + + return *this; +} + +TypePathSegmentFunction::TypePathSegmentFunction ( + Analysis::NodeMapping mappings, PathIdentSegment ident_segment, + bool has_separating_scope_resolution, TypePathFunction function_path, + location_t locus) + : TypePathSegment (std::move (mappings), std::move (ident_segment), + has_separating_scope_resolution, locus), + function_path (std::move (function_path)) +{} + +TypePathSegmentFunction::TypePathSegmentFunction ( + Analysis::NodeMapping mappings, std::string segment_name, + bool has_separating_scope_resolution, TypePathFunction function_path, + location_t locus) + : TypePathSegment (std::move (mappings), std::move (segment_name), + has_separating_scope_resolution, locus), + function_path (std::move (function_path)) +{} + +TypePath::TypePath (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<TypePathSegment> > segments, + location_t locus, bool has_opening_scope_resolution) + : TypeNoBounds (mappings, locus), + has_opening_scope_resolution (has_opening_scope_resolution), + segments (std::move (segments)) +{} + +TypePath::TypePath (TypePath const &other) + : TypeNoBounds (other.mappings, other.locus), + has_opening_scope_resolution (other.has_opening_scope_resolution) +{ + segments.reserve (other.segments.size ()); + for (const auto &e : other.segments) + segments.push_back (e->clone_type_path_segment ()); +} + +TypePath & +TypePath::operator= (TypePath const &other) +{ + has_opening_scope_resolution = other.has_opening_scope_resolution; + locus = other.locus; + mappings = other.mappings; + + segments.reserve (other.segments.size ()); + for (const auto &e : other.segments) + segments.push_back (e->clone_type_path_segment ()); + + return *this; +} + +QualifiedPathType::QualifiedPathType (Analysis::NodeMapping mappings, + std::unique_ptr<Type> type, + std::unique_ptr<TypePath> trait, + location_t locus) + : type (std::move (type)), trait (std::move (trait)), locus (locus), + mappings (mappings) +{} + +QualifiedPathType::QualifiedPathType (QualifiedPathType const &other) + : type (other.type->clone_type ()), + trait (other.has_as_clause () + ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait)) + : nullptr), + locus (other.locus), mappings (other.mappings) +{} + +QualifiedPathType & +QualifiedPathType::operator= (QualifiedPathType const &other) +{ + type = other.type->clone_type (); + locus = other.locus; + mappings = other.mappings; + trait = other.has_as_clause () + ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait)) + : nullptr; + + return *this; +} + +bool +QualifiedPathType::trait_has_generic_args () const +{ + rust_assert (has_as_clause ()); + bool is_generic_seg = trait->get_final_segment ().get_type () + == TypePathSegment::SegmentType::GENERIC; + if (!is_generic_seg) + return false; + + auto &seg + = static_cast<TypePathSegmentGeneric &> (trait->get_final_segment ()); + return seg.has_generic_args (); +} + +GenericArgs & +QualifiedPathType::get_trait_generic_args () +{ + rust_assert (trait_has_generic_args ()); + auto &seg + = static_cast<TypePathSegmentGeneric &> (trait->get_final_segment ()); + return seg.get_generic_args (); +} + +QualifiedPathInExpression::QualifiedPathInExpression ( + Analysis::NodeMapping mappings, QualifiedPathType qual_path_type, + std::vector<PathExprSegment> path_segments, location_t locus, + std::vector<AST::Attribute> outer_attrs) + : PathPattern (std::move (path_segments)), + PathExpr (std::move (mappings), std::move (outer_attrs)), + path_type (std::move (qual_path_type)), locus (locus) +{} + +QualifiedPathInExpression::QualifiedPathInExpression ( + Analysis::NodeMapping mappings, QualifiedPathType qual_path_type, + LangItem::Kind lang_item, location_t locus, + std::vector<AST::Attribute> outer_attrs) + : PathPattern (lang_item), + PathExpr (std::move (mappings), std::move (outer_attrs)), + path_type (std::move (qual_path_type)), locus (locus) +{} + +QualifiedPathInType::QualifiedPathInType ( + Analysis::NodeMapping mappings, QualifiedPathType qual_path_type, + std::unique_ptr<TypePathSegment> associated_segment, + std::vector<std::unique_ptr<TypePathSegment> > path_segments, + location_t locus) + : TypeNoBounds (mappings, locus), path_type (std::move (qual_path_type)), + associated_segment (std::move (associated_segment)), + segments (std::move (path_segments)) +{} + +QualifiedPathInType::QualifiedPathInType (QualifiedPathInType const &other) + : TypeNoBounds (other.mappings, other.locus), path_type (other.path_type) +{ + auto seg = other.associated_segment->clone_type_path_segment_impl (); + associated_segment = std::unique_ptr<TypePathSegment> (seg); + + segments.reserve (other.segments.size ()); + for (const auto &e : other.segments) + segments.push_back (e->clone_type_path_segment ()); +} + +QualifiedPathInType & +QualifiedPathInType::operator= (QualifiedPathInType const &other) +{ + auto seg = other.associated_segment->clone_type_path_segment_impl (); + associated_segment = std::unique_ptr<TypePathSegment> (seg); + + path_type = other.path_type; + locus = other.locus; + mappings = other.mappings; + + segments.reserve (other.segments.size ()); + for (const auto &e : other.segments) + segments.push_back (e->clone_type_path_segment ()); + + return *this; +} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index e406d53..3ce2662 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -19,7 +19,11 @@ #ifndef RUST_HIR_PATH_H #define RUST_HIR_PATH_H -#include "rust-hir.h" +#include "rust-hir-map.h" +#include "rust-hir-simple-path.h" +#include "rust-hir-type-no-bounds.h" +#include "rust-hir-pattern-abstract.h" +#include "rust-hir-expr-abstract.h" namespace Rust { namespace HIR { @@ -76,27 +80,16 @@ public: // Pointer type for type in constructor to enable polymorphism GenericArgsBinding (Identifier ident, std::unique_ptr<Type> type_ptr, - location_t locus = UNDEF_LOCATION) - : identifier (std::move (ident)), type (std::move (type_ptr)), locus (locus) - {} + location_t locus = UNDEF_LOCATION); // Copy constructor has to deep copy the type as it is a unique pointer - GenericArgsBinding (GenericArgsBinding const &other) - : identifier (other.identifier), type (other.type->clone_type ()), - locus (other.locus) - {} + GenericArgsBinding (GenericArgsBinding const &other); // default destructor ~GenericArgsBinding () = default; // Overload assignment operator to deep copy the pointed-to type - GenericArgsBinding &operator= (GenericArgsBinding const &other) - { - identifier = other.identifier; - type = other.type->clone_type (); - locus = other.locus; - return *this; - } + GenericArgsBinding &operator= (GenericArgsBinding const &other); // move constructors GenericArgsBinding (GenericArgsBinding &&other) = default; @@ -107,8 +100,16 @@ public: Identifier &get_identifier () { return identifier; } const Identifier &get_identifier () const { return identifier; } - std::unique_ptr<Type> &get_type () { return type; } - const std::unique_ptr<Type> &get_type () const { return type; } + Type &get_type () + { + rust_assert (type); + return *type; + } + const Type &get_type () const + { + rust_assert (type); + return *type; + } location_t get_locus () const { return locus; } }; @@ -119,22 +120,11 @@ class ConstGenericArg // at name-resolution, hence no need for ambiguities here public: - ConstGenericArg (std::unique_ptr<Expr> expression, location_t locus) - : expression (std::move (expression)), locus (locus) - {} - - ConstGenericArg (const ConstGenericArg &other) : locus (other.locus) - { - expression = other.expression->clone_expr (); - } + ConstGenericArg (std::unique_ptr<Expr> expression, location_t locus); - ConstGenericArg operator= (const ConstGenericArg &other) - { - expression = other.expression->clone_expr (); - locus = other.locus; + ConstGenericArg (const ConstGenericArg &other); - return *this; - } + ConstGenericArg operator= (const ConstGenericArg &other); std::unique_ptr<Expr> &get_expression () { return expression; } @@ -162,42 +152,15 @@ public: GenericArgs (std::vector<Lifetime> lifetime_args, std::vector<std::unique_ptr<Type> > type_args, std::vector<GenericArgsBinding> binding_args, - std::vector<ConstGenericArg> const_args, location_t locus) - : lifetime_args (std::move (lifetime_args)), - type_args (std::move (type_args)), - binding_args (std::move (binding_args)), - const_args (std::move (const_args)), locus (locus) - {} + std::vector<ConstGenericArg> const_args, location_t locus); // copy constructor with vector clone - GenericArgs (GenericArgs const &other) - : lifetime_args (other.lifetime_args), binding_args (other.binding_args), - const_args (other.const_args), locus (other.locus) - { - type_args.clear (); - type_args.reserve (other.type_args.size ()); - - for (const auto &e : other.type_args) - type_args.push_back (e->clone_type ()); - } + GenericArgs (GenericArgs const &other); ~GenericArgs () = default; // overloaded assignment operator to vector clone - GenericArgs &operator= (GenericArgs const &other) - { - lifetime_args = other.lifetime_args; - binding_args = other.binding_args; - const_args = other.const_args; - locus = other.locus; - - type_args.clear (); - type_args.reserve (other.type_args.size ()); - for (const auto &e : other.type_args) - type_args.push_back (e->clone_type ()); - - return *this; - } + GenericArgs &operator= (GenericArgs const &other); // move constructors GenericArgs (GenericArgs &&other) = default; @@ -209,11 +172,7 @@ public: return GenericArgs ({}, {}, {}, {}, locus); } - bool is_empty () const - { - return lifetime_args.size () == 0 && type_args.size () == 0 - && binding_args.size () == 0; - } + bool is_empty () const; std::string as_string () const; @@ -245,25 +204,11 @@ private: public: PathExprSegment (Analysis::NodeMapping mappings, PathIdentSegment segment_name, location_t locus, - GenericArgs generic_args) - : mappings (std::move (mappings)), segment_name (std::move (segment_name)), - generic_args (std::move (generic_args)), locus (locus) - {} + GenericArgs generic_args); - PathExprSegment (PathExprSegment const &other) - : mappings (other.mappings), segment_name (other.segment_name), - generic_args (other.generic_args), locus (other.locus) - {} + PathExprSegment (PathExprSegment const &other); - PathExprSegment &operator= (PathExprSegment const &other) - { - mappings = other.mappings; - segment_name = other.segment_name; - generic_args = other.generic_args; - locus = other.locus; - - return *this; - } + PathExprSegment &operator= (PathExprSegment const &other); // move constructors PathExprSegment (PathExprSegment &&other) = default; @@ -286,15 +231,34 @@ public: // HIR node representing a pattern that involves a "path" - abstract base class class PathPattern : public Pattern { +public: + enum class Kind + { + Segmented, + LangItem + }; + +private: std::vector<PathExprSegment> segments; + tl::optional<LangItem::Kind> lang_item; + Kind kind; protected: PathPattern (std::vector<PathExprSegment> segments) - : segments (std::move (segments)) + : segments (std::move (segments)), lang_item (tl::nullopt), + kind (Kind::Segmented) + {} + + PathPattern (LangItem::Kind lang_item) + : segments ({}), lang_item (lang_item), kind (Kind::LangItem) {} // Returns whether path has segments. - bool has_segments () const { return !segments.empty (); } + bool has_segments () const + { + rust_assert (kind == Kind::Segmented); + return !segments.empty (); + } /* Converts path segments to their equivalent SimplePath segments if possible, * and creates a SimplePath from them. */ @@ -304,33 +268,61 @@ protected: public: /* Returns whether the path is a single segment (excluding qualified path * initial as segment). */ - bool is_single_segment () const { return segments.size () == 1; } + bool is_single_segment () const + { + rust_assert (kind == Kind::Segmented); + return segments.size () == 1; + } std::string as_string () const override; - void iterate_path_segments (std::function<bool (PathExprSegment &)> cb) + void iterate_path_segments (std::function<bool (PathExprSegment &)> cb); + + size_t get_num_segments () const { - for (auto it = segments.begin (); it != segments.end (); it++) - { - if (!cb (*it)) - return; - } + rust_assert (kind == Kind::Segmented); + return segments.size (); } - size_t get_num_segments () const { return segments.size (); } + std::vector<PathExprSegment> &get_segments () + { + rust_assert (kind == Kind::Segmented); + return segments; + } + + const std::vector<PathExprSegment> &get_segments () const + { + rust_assert (kind == Kind::Segmented); + return segments; + } - std::vector<PathExprSegment> &get_segments () { return segments; } + PathExprSegment &get_root_seg () + { + rust_assert (kind == Kind::Segmented); + return segments.at (0); + } - const std::vector<PathExprSegment> &get_segments () const { return segments; } + const PathExprSegment &get_final_segment () const + { + rust_assert (kind == Kind::Segmented); + return segments.back (); + } - PathExprSegment &get_root_seg () { return segments.at (0); } + LangItem::Kind get_lang_item () const + { + rust_assert (kind == Kind::LangItem); - const PathExprSegment &get_final_segment () const { return segments.back (); } + return *lang_item; + } PatternType get_pattern_type () const override final { return PatternType::PATH; } + + bool is_lang_item () const { return kind == Kind::LangItem; } + + Kind get_path_kind () const { return kind; } }; /* HIR node representing a path-in-expression pattern (path that allows generic @@ -349,11 +341,14 @@ public: location_t locus = UNDEF_LOCATION, bool has_opening_scope_resolution = false, std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> ()) - : PathPattern (std::move (path_segments)), - PathExpr (std::move (mappings), std::move (outer_attrs)), - has_opening_scope_resolution (has_opening_scope_resolution), locus (locus) - {} + = std::vector<AST::Attribute> ()); + + // lang-item Constructor + PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind, + location_t locus = UNDEF_LOCATION, + bool has_opening_scope_resolution = false, + std::vector<AST::Attribute> outer_attrs + = std::vector<AST::Attribute> ()); // Creates an error state path in expression. static PathInExpression create_error () @@ -385,14 +380,7 @@ public: bool opening_scope_resolution () { return has_opening_scope_resolution; } - bool is_self () const - { - if (!is_single_segment ()) - return false; - - return get_final_segment ().get_segment ().as_string ().compare ("self") - == 0; - } + bool is_self () const; const Analysis::NodeMapping &get_mappings () const override final { @@ -429,7 +417,8 @@ public: private: Analysis::NodeMapping mappings; - PathIdentSegment ident_segment; + tl::optional<PathIdentSegment> ident_segment; + tl::optional<LangItem::Kind> lang_item; location_t locus; protected: @@ -456,27 +445,29 @@ public: TypePathSegment (Analysis::NodeMapping mappings, PathIdentSegment ident_segment, - bool has_separating_scope_resolution, location_t locus) - : mappings (std::move (mappings)), - ident_segment (std::move (ident_segment)), locus (locus), - has_separating_scope_resolution (has_separating_scope_resolution), - type (SegmentType::REG) - {} + bool has_separating_scope_resolution, location_t locus); + + TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item, + location_t locus); TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name, - bool has_separating_scope_resolution, location_t locus) - : mappings (std::move (mappings)), - ident_segment (PathIdentSegment (std::move (segment_name))), - locus (locus), - has_separating_scope_resolution (has_separating_scope_resolution), - type (SegmentType::REG) - {} + bool has_separating_scope_resolution, location_t locus); - virtual std::string as_string () const { return ident_segment.as_string (); } + virtual std::string as_string () const + { + if (ident_segment) + return ident_segment->as_string (); + + return LangItem::PrettyString (*lang_item); + } /* Returns whether the type path segment is in an error state. May be virtual * in future. */ - bool is_error () const { return ident_segment.is_error (); } + bool is_error () const + { + rust_assert (ident_segment); + return ident_segment->is_error (); + } /* Returns whether segment is identifier only (as opposed to generic args or * function). Overriden in derived classes with other segments. */ @@ -489,12 +480,24 @@ public: const Analysis::NodeMapping &get_mappings () const { return mappings; } - const PathIdentSegment &get_ident_segment () const { return ident_segment; } + const PathIdentSegment &get_ident_segment () const + { + rust_assert (ident_segment); + return *ident_segment; + } + + const LangItem::Kind &get_lang_item () const + { + rust_assert (lang_item); + return *lang_item; + } bool is_generic_segment () const { return get_type () == SegmentType::GENERIC; } + + bool is_lang_item () const { return lang_item.has_value (); } }; // Segment used in type path with generic args @@ -511,11 +514,11 @@ public: TypePathSegmentGeneric (Analysis::NodeMapping mappings, PathIdentSegment ident_segment, bool has_separating_scope_resolution, - GenericArgs generic_args, location_t locus) - : TypePathSegment (std::move (mappings), std::move (ident_segment), - has_separating_scope_resolution, locus), - generic_args (std::move (generic_args)) - {} + GenericArgs generic_args, location_t locus); + + TypePathSegmentGeneric (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, GenericArgs generic_args, + location_t locus); // Constructor from segment name and all args TypePathSegmentGeneric (Analysis::NodeMapping mappings, @@ -525,13 +528,7 @@ public: std::vector<std::unique_ptr<Type> > type_args, std::vector<GenericArgsBinding> binding_args, std::vector<ConstGenericArg> const_args, - location_t locus) - : TypePathSegment (std::move (mappings), std::move (segment_name), - has_separating_scope_resolution, locus), - generic_args ( - GenericArgs (std::move (lifetime_args), std::move (type_args), - std::move (binding_args), std::move (const_args), locus)) - {} + location_t locus); std::string as_string () const override; @@ -566,37 +563,15 @@ public: // Constructor TypePathFunction (std::vector<std::unique_ptr<Type> > inputs, - std::unique_ptr<Type> type) - : inputs (std::move (inputs)), return_type (std::move (type)) - {} + std::unique_ptr<Type> type); // Copy constructor with clone - TypePathFunction (TypePathFunction const &other) - { - return_type = other.has_return_type () - ? other.get_return_type ()->clone_type () - : nullptr; - - inputs.reserve (other.inputs.size ()); - for (const auto &e : other.inputs) - inputs.push_back (e->clone_type ()); - } + TypePathFunction (TypePathFunction const &other); ~TypePathFunction () = default; // Overloaded assignment operator to clone type - TypePathFunction &operator= (TypePathFunction const &other) - { - return_type = other.has_return_type () - ? other.get_return_type ()->clone_type () - : nullptr; - - inputs.reserve (other.inputs.size ()); - for (const auto &e : other.inputs) - inputs.push_back (e->clone_type ()); - - return *this; - } + TypePathFunction &operator= (TypePathFunction const &other); // move constructors TypePathFunction (TypePathFunction &&other) = default; @@ -610,8 +585,8 @@ public: }; std::vector<std::unique_ptr<Type> > &get_params () { return inputs; }; - const std::unique_ptr<Type> &get_return_type () const { return return_type; }; - std::unique_ptr<Type> &get_return_type () { return return_type; }; + const Type &get_return_type () const { return *return_type; }; + Type &get_return_type () { return *return_type; }; }; // Segment used in type path with a function argument @@ -624,21 +599,13 @@ public: TypePathSegmentFunction (Analysis::NodeMapping mappings, PathIdentSegment ident_segment, bool has_separating_scope_resolution, - TypePathFunction function_path, location_t locus) - : TypePathSegment (std::move (mappings), std::move (ident_segment), - has_separating_scope_resolution, locus), - function_path (std::move (function_path)) - {} + TypePathFunction function_path, location_t locus); // Constructor with segment name and TypePathFn TypePathSegmentFunction (Analysis::NodeMapping mappings, std::string segment_name, bool has_separating_scope_resolution, - TypePathFunction function_path, location_t locus) - : TypePathSegment (std::move (mappings), std::move (segment_name), - has_separating_scope_resolution, locus), - function_path (std::move (function_path)) - {} + TypePathFunction function_path, location_t locus); std::string as_string () const override; @@ -698,35 +665,13 @@ public: // Constructor TypePath (Analysis::NodeMapping mappings, std::vector<std::unique_ptr<TypePathSegment> > segments, - location_t locus, bool has_opening_scope_resolution = false) - : TypeNoBounds (mappings, locus), - has_opening_scope_resolution (has_opening_scope_resolution), - segments (std::move (segments)) - {} + location_t locus, bool has_opening_scope_resolution = false); // Copy constructor with vector clone - TypePath (TypePath const &other) - : TypeNoBounds (other.mappings, other.locus), - has_opening_scope_resolution (other.has_opening_scope_resolution) - { - segments.reserve (other.segments.size ()); - for (const auto &e : other.segments) - segments.push_back (e->clone_type_path_segment ()); - } + TypePath (TypePath const &other); // Overloaded assignment operator with clone - TypePath &operator= (TypePath const &other) - { - has_opening_scope_resolution = other.has_opening_scope_resolution; - locus = other.locus; - mappings = other.mappings; - - segments.reserve (other.segments.size ()); - for (const auto &e : other.segments) - segments.push_back (e->clone_type_path_segment ()); - - return *this; - } + TypePath &operator= (TypePath const &other); // move constructors TypePath (TypePath &&other) = default; @@ -739,7 +684,7 @@ public: AST::SimplePath as_simple_path () const; // Creates a trait bound with a clone of this type path as its only element. - TraitBound *to_trait_bound (bool in_parens) const override; + std::unique_ptr<TraitBound> to_trait_bound (bool in_parens) const override; void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; @@ -751,10 +696,7 @@ public: return segments; } - std::unique_ptr<TypePathSegment> &get_final_segment () - { - return segments.back (); - } + TypePathSegment &get_final_segment () { return *segments.back (); } }; class QualifiedPathType @@ -767,36 +709,16 @@ class QualifiedPathType public: // Constructor QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, - std::unique_ptr<TypePath> trait, location_t locus) - : type (std::move (type)), trait (std::move (trait)), locus (locus), - mappings (mappings) - {} + std::unique_ptr<TypePath> trait, location_t locus); // Copy constructor uses custom deep copy for Type to preserve polymorphism - QualifiedPathType (QualifiedPathType const &other) - : type (other.type->clone_type ()), - trait (other.has_as_clause () ? std::unique_ptr<HIR::TypePath> ( - new HIR::TypePath (*other.trait)) - : nullptr), - locus (other.locus), mappings (other.mappings) - {} + QualifiedPathType (QualifiedPathType const &other); // default destructor ~QualifiedPathType () = default; // overload assignment operator to use custom clone method - QualifiedPathType &operator= (QualifiedPathType const &other) - { - type = other.type->clone_type (); - locus = other.locus; - mappings = other.mappings; - trait - = other.has_as_clause () - ? std::unique_ptr<HIR::TypePath> (new HIR::TypePath (*other.trait)) - : nullptr; - - return *this; - } + QualifiedPathType &operator= (QualifiedPathType const &other); // move constructor QualifiedPathType (QualifiedPathType &&other) = default; @@ -811,30 +733,24 @@ public: Analysis::NodeMapping get_mappings () const { return mappings; } - std::unique_ptr<Type> &get_type () { return type; } - - std::unique_ptr<TypePath> &get_trait () { return trait; } + bool has_type () { return type != nullptr; } + bool has_trait () { return trait != nullptr; } - bool trait_has_generic_args () const + Type &get_type () { - rust_assert (has_as_clause ()); - bool is_generic_seg = trait->get_final_segment ()->get_type () - == TypePathSegment::SegmentType::GENERIC; - if (!is_generic_seg) - return false; - - TypePathSegmentGeneric *seg = static_cast<TypePathSegmentGeneric *> ( - trait->get_final_segment ().get ()); - return seg->has_generic_args (); + rust_assert (type); + return *type; } - GenericArgs &get_trait_generic_args () + TypePath &get_trait () { - rust_assert (trait_has_generic_args ()); - TypePathSegmentGeneric *seg = static_cast<TypePathSegmentGeneric *> ( - trait->get_final_segment ().get ()); - return seg->get_generic_args (); + rust_assert (trait); + return *trait; } + + bool trait_has_generic_args () const; + + GenericArgs &get_trait_generic_args (); }; /* HIR node representing a qualified path-in-expression pattern (path that @@ -852,11 +768,15 @@ public: std::vector<PathExprSegment> path_segments, location_t locus = UNDEF_LOCATION, std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> ()) - : PathPattern (std::move (path_segments)), - PathExpr (std::move (mappings), std::move (outer_attrs)), - path_type (std::move (qual_path_type)), locus (locus) - {} + = std::vector<AST::Attribute> ()); + + // lang-item constructor + QualifiedPathInExpression (Analysis::NodeMapping mappings, + QualifiedPathType qual_path_type, + LangItem::Kind lang_item, + location_t locus = UNDEF_LOCATION, + std::vector<AST::Attribute> outer_attrs + = std::vector<AST::Attribute> ()); location_t get_locus () const override final { return locus; } @@ -917,40 +837,13 @@ public: Analysis::NodeMapping mappings, QualifiedPathType qual_path_type, std::unique_ptr<TypePathSegment> associated_segment, std::vector<std::unique_ptr<TypePathSegment> > path_segments, - location_t locus = UNDEF_LOCATION) - : TypeNoBounds (mappings, locus), path_type (std::move (qual_path_type)), - associated_segment (std::move (associated_segment)), - segments (std::move (path_segments)) - {} + location_t locus = UNDEF_LOCATION); // Copy constructor with vector clone - QualifiedPathInType (QualifiedPathInType const &other) - : TypeNoBounds (other.mappings, other.locus), path_type (other.path_type) - { - auto seg = other.associated_segment->clone_type_path_segment_impl (); - associated_segment = std::unique_ptr<TypePathSegment> (seg); - - segments.reserve (other.segments.size ()); - for (const auto &e : other.segments) - segments.push_back (e->clone_type_path_segment ()); - } + QualifiedPathInType (QualifiedPathInType const &other); // Overloaded assignment operator with vector clone - QualifiedPathInType &operator= (QualifiedPathInType const &other) - { - auto seg = other.associated_segment->clone_type_path_segment_impl (); - associated_segment = std::unique_ptr<TypePathSegment> (seg); - - path_type = other.path_type; - locus = other.locus; - mappings = other.mappings; - - segments.reserve (other.segments.size ()); - for (const auto &e : other.segments) - segments.push_back (e->clone_type_path_segment ()); - - return *this; - } + QualifiedPathInType &operator= (QualifiedPathInType const &other); // move constructors QualifiedPathInType (QualifiedPathInType &&other) = default; @@ -963,10 +856,7 @@ public: QualifiedPathType &get_path_type () { return path_type; } - std::unique_ptr<TypePathSegment> &get_associated_segment () - { - return associated_segment; - } + TypePathSegment &get_associated_segment () { return *associated_segment; } std::vector<std::unique_ptr<TypePathSegment> > &get_segments () { @@ -974,40 +864,6 @@ public: } }; -class SimplePathSegment -{ - Analysis::NodeMapping mappings; - -public: - SimplePathSegment (Analysis::NodeMapping mappings) : mappings (mappings) {} - - const Analysis::NodeMapping &get_mappings () const { return mappings; } -}; - -class SimplePath -{ - std::vector<SimplePathSegment> segments; - Analysis::NodeMapping mappings; - location_t locus; - -public: - SimplePath (std::vector<SimplePathSegment> segments, - Analysis::NodeMapping mappings, location_t locus) - : segments (std::move (segments)), mappings (mappings), locus (locus) - {} - - static HIR::SimplePath create_empty () - { - return HIR::SimplePath ({}, Analysis::NodeMapping::get_error (), - UNDEF_LOCATION); - } - - bool is_error () const { return segments.empty (); } - - const Analysis::NodeMapping &get_mappings () const { return mappings; } - location_t get_locus () const { return locus; } -}; - } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-pattern-abstract.h b/gcc/rust/hir/tree/rust-hir-pattern-abstract.h new file mode 100644 index 0000000..b156a80 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-pattern-abstract.h @@ -0,0 +1,82 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_PATTERN_ABSTRACT_H +#define RUST_HIR_PATTERN_ABSTRACT_H + +#include "rust-hir-visitable.h" +#include "rust-hir-visitor.h" +#include "rust-hir-node.h" +#include "rust-system.h" + +namespace Rust { +namespace HIR { + +// Pattern base HIR node +class Pattern : public Node, virtual public FullVisitable +{ +public: + using FullVisitable::accept_vis; + + enum PatternType + { + PATH, + LITERAL, + IDENTIFIER, + WILDCARD, + RANGE, + REFERENCE, + STRUCT, + TUPLE_STRUCT, + TUPLE, + GROUPED, + SLICE, + ALT + }; + + BaseKind get_hir_kind () override final { return PATTERN; } + + // Unique pointer custom clone function + std::unique_ptr<Pattern> clone_pattern () const + { + return std::unique_ptr<Pattern> (clone_pattern_impl ()); + } + + // possible virtual methods: is_refutable() + + virtual ~Pattern () {} + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRPatternVisitor &vis) = 0; + + virtual const Analysis::NodeMapping &get_mappings () const = 0; + + virtual location_t get_locus () const = 0; + + virtual PatternType get_pattern_type () const = 0; + +protected: + // Clone pattern implementation as pure virtual method + virtual Pattern *clone_pattern_impl () const = 0; +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h index e5d8371..5cc5c95 100644 --- a/gcc/rust/hir/tree/rust-hir-pattern.h +++ b/gcc/rust/hir/tree/rust-hir-pattern.h @@ -19,12 +19,13 @@ #ifndef RUST_HIR_PATTERN_H #define RUST_HIR_PATTERN_H +#include "rust-hir-pattern-abstract.h" #include "rust-common.h" -#include "rust-hir.h" +#include "rust-hir-literal.h" +#include "rust-hir-path.h" namespace Rust { namespace HIR { - // Literal pattern HIR node (comparing to a literal) class LiteralPattern : public Pattern { @@ -132,7 +133,7 @@ public: bool is_mut () const { return mut == Mutability::Mut; } bool get_is_ref () const { return is_ref; } - std::unique_ptr<Pattern> &get_to_bind () { return to_bind; } + Pattern &get_to_bind () { return *to_bind; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRPatternVisitor &vis) override; @@ -405,9 +406,9 @@ public: return PatternType::RANGE; } - std::unique_ptr<RangePatternBound> &get_lower_bound () { return lower; } + RangePatternBound &get_lower_bound () { return *lower; } - std::unique_ptr<RangePatternBound> &get_upper_bound () { return upper; } + RangePatternBound &get_upper_bound () { return *upper; } protected: /* Use covariance to implement clone function as returning this object rather @@ -476,7 +477,7 @@ public: return PatternType::REFERENCE; } - std::unique_ptr<Pattern> &get_referenced_pattern () { return pattern; } + Pattern &get_referenced_pattern () { return *pattern; } protected: /* Use covariance to implement clone function as returning this object rather @@ -572,7 +573,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; TupleIndex get_index () { return index; } - std::unique_ptr<Pattern> &get_tuple_pattern () { return tuple_pattern; } + Pattern &get_tuple_pattern () { return *tuple_pattern; } ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; } @@ -630,7 +631,7 @@ public: Identifier get_identifier () const { return ident; } - std::unique_ptr<Pattern> &get_pattern () { return ident_pattern; } + Pattern &get_pattern () { return *ident_pattern; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1002,7 +1003,7 @@ public: PathInExpression &get_path () { return path; } - std::unique_ptr<TupleStructItems> &get_items () { return items; } + TupleStructItems &get_items () { return *items; } const Analysis::NodeMapping &get_mappings () const override final { @@ -1221,8 +1222,8 @@ public: return PatternType::TUPLE; } - std::unique_ptr<TuplePatternItems> &get_items () { return items; } - const std::unique_ptr<TuplePatternItems> &get_items () const { return items; } + TuplePatternItems &get_items () { return *items; } + const TuplePatternItems &get_items () const { return *items; } protected: /* Use covariance to implement clone function as returning this object rather diff --git a/gcc/rust/hir/tree/rust-hir-simple-path.h b/gcc/rust/hir/tree/rust-hir-simple-path.h new file mode 100644 index 0000000..7f832ff --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-simple-path.h @@ -0,0 +1,64 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_SIMPLE_PATH_H +#define RUST_HIR_SIMPLE_PATH_H + +#include "rust-hir-map.h" + +namespace Rust { +namespace HIR { + +class SimplePathSegment +{ + Analysis::NodeMapping mappings; + +public: + SimplePathSegment (Analysis::NodeMapping mappings) : mappings (mappings) {} + + const Analysis::NodeMapping &get_mappings () const { return mappings; } +}; + +class SimplePath +{ + std::vector<SimplePathSegment> segments; + Analysis::NodeMapping mappings; + location_t locus; + +public: + SimplePath (std::vector<SimplePathSegment> segments, + Analysis::NodeMapping mappings, location_t locus) + : segments (std::move (segments)), mappings (mappings), locus (locus) + {} + + static HIR::SimplePath create_empty () + { + return HIR::SimplePath ({}, Analysis::NodeMapping::get_error (), + UNDEF_LOCATION); + } + + bool is_error () const { return segments.empty (); } + + const Analysis::NodeMapping &get_mappings () const { return mappings; } + location_t get_locus () const { return locus; } +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-stmt.cc b/gcc/rust/hir/tree/rust-hir-stmt.cc new file mode 100644 index 0000000..025f67e --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-stmt.cc @@ -0,0 +1,104 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-stmt.h" +#include "optional.h" +#include "rust-system.h" + +namespace Rust { +namespace HIR { + +LetStmt::LetStmt (Analysis::NodeMapping mappings, + std::unique_ptr<Pattern> variables_pattern, + tl::optional<std::unique_ptr<Expr>> init_expr, + tl::optional<std::unique_ptr<Type>> type, + AST::AttrVec outer_attrs, location_t locus) + : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)), + variables_pattern (std::move (variables_pattern)), type (std::move (type)), + init_expr (std::move (init_expr)), locus (locus) +{} + +LetStmt::LetStmt (LetStmt const &other) + : Stmt (other.mappings), outer_attrs (other.outer_attrs), locus (other.locus) +{ + // guard to prevent null dereference (only required if error state) + if (other.variables_pattern != nullptr) + variables_pattern = other.variables_pattern->clone_pattern (); + + // guard to prevent null dereference (always required) + if (other.has_init_expr ()) + init_expr = other.get_init_expr ().clone_expr (); + + if (other.has_type ()) + type = other.get_type ().clone_type (); + else + type = tl::nullopt; +} + +LetStmt & +LetStmt::operator= (LetStmt const &other) +{ + outer_attrs = other.outer_attrs; + locus = other.locus; + + // guard to prevent null dereference (only required if error state) + if (other.variables_pattern != nullptr) + variables_pattern = other.variables_pattern->clone_pattern (); + else + variables_pattern = nullptr; + + // guard to prevent null dereference (always required) + if (other.has_init_expr ()) + init_expr = other.get_init_expr ().clone_expr (); + else + init_expr = nullptr; + if (other.has_type ()) + type = other.get_type ().clone_type (); + else + type = tl::nullopt; + + return *this; +} + +ExprStmt::ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr, + location_t locus, bool must_be_unit) + : Stmt (std::move (mappings)), expr (std::move (expr)), locus (locus), + must_be_unit (must_be_unit) +{} + +ExprStmt::ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr, + location_t locus) + : ExprStmt (std::move (mappings), std::move (expr), locus, false) +{} + +ExprStmt::ExprStmt (ExprStmt const &other) + : Stmt (other), expr (other.expr->clone_expr ()), locus (other.locus) +{} + +ExprStmt & +ExprStmt::operator= (ExprStmt const &other) +{ + Stmt::operator= (other); + expr = other.expr->clone_expr (); + locus = other.locus; + + return *this; +} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h index e6e844f..3db1728 100644 --- a/gcc/rust/hir/tree/rust-hir-stmt.h +++ b/gcc/rust/hir/tree/rust-hir-stmt.h @@ -22,9 +22,48 @@ #include "rust-hir.h" #include "rust-hir-path.h" #include "rust-hir-expr.h" +#include "rust-system.h" namespace Rust { namespace HIR { +/* Base statement abstract class. Note that most "statements" are not allowed in + * top-level module scope - only a subclass of statements called "items" are. */ +class Stmt : public Node, public FullVisitable +{ +public: + using FullVisitable::accept_vis; + + // Unique pointer custom clone function + std::unique_ptr<Stmt> clone_stmt () const + { + return std::unique_ptr<Stmt> (clone_stmt_impl ()); + } + + BaseKind get_hir_kind () override { return STMT; } + + virtual ~Stmt () {} + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRStmtVisitor &vis) = 0; + + virtual location_t get_locus () const = 0; + + virtual bool is_unit_check_needed () const { return false; } + + const Analysis::NodeMapping &get_mappings () const { return mappings; } + + virtual bool is_item () const = 0; + +protected: + Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {} + + // Clone function implementation as pure virtual method + virtual Stmt *clone_stmt_impl () const = 0; + + Analysis::NodeMapping mappings; +}; + // Just a semi-colon, which apparently is a statement. class EmptyStmt : public Stmt { @@ -59,11 +98,9 @@ class LetStmt : public Stmt std::unique_ptr<Pattern> variables_pattern; - // bool has_type; - std::unique_ptr<Type> type; + tl::optional<std::unique_ptr<Type>> type; - // bool has_init_expr; - std::unique_ptr<Expr> init_expr; + tl::optional<std::unique_ptr<Expr>> init_expr; location_t locus; @@ -72,62 +109,24 @@ public: bool has_outer_attrs () const { return !outer_attrs.empty (); } // Returns whether let statement has a given return type. - bool has_type () const { return type != nullptr; } + bool has_type () const { return type.has_value (); } // Returns whether let statement has an initialisation expression. - bool has_init_expr () const { return init_expr != nullptr; } + bool has_init_expr () const { return init_expr.has_value (); } std::string as_string () const override; LetStmt (Analysis::NodeMapping mappings, std::unique_ptr<Pattern> variables_pattern, - std::unique_ptr<Expr> init_expr, std::unique_ptr<Type> type, - AST::AttrVec outer_attrs, location_t locus) - : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)), - variables_pattern (std::move (variables_pattern)), - type (std::move (type)), init_expr (std::move (init_expr)), locus (locus) - {} + tl::optional<std::unique_ptr<Expr>> init_expr, + tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs, + location_t locus); // Copy constructor with clone - LetStmt (LetStmt const &other) - : Stmt (other.mappings), outer_attrs (other.outer_attrs), - locus (other.locus) - { - // guard to prevent null dereference (only required if error state) - if (other.variables_pattern != nullptr) - variables_pattern = other.variables_pattern->clone_pattern (); - - // guard to prevent null dereference (always required) - if (other.init_expr != nullptr) - init_expr = other.init_expr->clone_expr (); - if (other.type != nullptr) - type = other.type->clone_type (); - } + LetStmt (LetStmt const &other); // Overloaded assignment operator to clone - LetStmt &operator= (LetStmt const &other) - { - outer_attrs = other.outer_attrs; - locus = other.locus; - - // guard to prevent null dereference (only required if error state) - if (other.variables_pattern != nullptr) - variables_pattern = other.variables_pattern->clone_pattern (); - else - variables_pattern = nullptr; - - // guard to prevent null dereference (always required) - if (other.init_expr != nullptr) - init_expr = other.init_expr->clone_expr (); - else - init_expr = nullptr; - if (other.type != nullptr) - type = other.type->clone_type (); - else - type = nullptr; - - return *this; - } + LetStmt &operator= (LetStmt const &other); // move constructors LetStmt (LetStmt &&other) = default; @@ -144,11 +143,31 @@ public: } std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; } - std::unique_ptr<HIR::Type> &get_type () { return type; } + HIR::Type &get_type () + { + rust_assert (*type); + return *type.value (); + } + + const HIR::Type &get_type () const + { + rust_assert (*type); + return *type.value (); + } + + HIR::Expr &get_init_expr () + { + rust_assert (*init_expr); + return *init_expr.value (); + } - std::unique_ptr<HIR::Expr> &get_init_expr () { return init_expr; } + const HIR::Expr &get_init_expr () const + { + rust_assert (*init_expr); + return *init_expr.value (); + } - std::unique_ptr<HIR::Pattern> &get_pattern () { return variables_pattern; } + HIR::Pattern &get_pattern () { return *variables_pattern; } bool is_item () const override final { return false; } @@ -167,15 +186,10 @@ class ExprStmt : public Stmt public: ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr, - location_t locus, bool must_be_unit) - : Stmt (std::move (mappings)), expr (std::move (expr)), locus (locus), - must_be_unit (must_be_unit) - {} + location_t locus, bool must_be_unit); ExprStmt (Analysis::NodeMapping mappings, std::unique_ptr<Expr> expr, - location_t locus) - : ExprStmt (std::move (mappings), std::move (expr), locus, false) - {} + location_t locus); std::string as_string () const override; @@ -186,22 +200,13 @@ public: bool is_item () const override final { return false; } - std::unique_ptr<Expr> &get_expr () { return expr; } + Expr &get_expr () { return *expr; } // Copy constructor with clone - ExprStmt (ExprStmt const &other) - : Stmt (other), expr (other.expr->clone_expr ()), locus (other.locus) - {} + ExprStmt (ExprStmt const &other); // Overloaded assignment operator to clone - ExprStmt &operator= (ExprStmt const &other) - { - Stmt::operator= (other); - expr = other.expr->clone_expr (); - locus = other.locus; - - return *this; - } + ExprStmt &operator= (ExprStmt const &other); // move constructors ExprStmt (ExprStmt &&other) = default; diff --git a/gcc/rust/hir/tree/rust-hir-trait-bound.h b/gcc/rust/hir/tree/rust-hir-trait-bound.h new file mode 100644 index 0000000..d20fa79 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-trait-bound.h @@ -0,0 +1,87 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_TRAIT_BOUND_H +#define RUST_HIR_TRAIT_BOUND_H + +#include "rust-hir-bound-abstract.h" +#include "rust-hir-path.h" +#include "rust-hir-generic-param.h" + +namespace Rust { +namespace HIR { + +// A trait bound +class TraitBound : public TypeParamBound +{ + bool in_parens; + BoundPolarity polarity; + std::vector<LifetimeParam> for_lifetimes; + TypePath type_path; + location_t locus; + + Analysis::NodeMapping mappings; + +public: + // Returns whether trait bound has "for" lifetimes + bool has_for_lifetimes () const { return !for_lifetimes.empty (); } + + TraitBound (Analysis::NodeMapping mapping, TypePath type_path, + location_t locus, bool in_parens = false, + BoundPolarity polarity = BoundPolarity::RegularBound, + std::vector<LifetimeParam> for_lifetimes + = std::vector<LifetimeParam> ()) + : in_parens (in_parens), polarity (polarity), + for_lifetimes (std::move (for_lifetimes)), + type_path (std::move (type_path)), locus (locus), mappings (mapping) + {} + + std::string as_string () const override; + + location_t get_locus () const override final { return locus; } + + void accept_vis (HIRFullVisitor &vis) override; + + Analysis::NodeMapping get_mappings () const override final + { + return mappings; + } + + std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; } + bool get_in_parens () { return in_parens; } + BoundPolarity get_polarity () { return polarity; } + + BoundType get_bound_type () const final override { return TRAITBOUND; } + + TypePath &get_path () { return type_path; } + + const TypePath &get_path () const { return type_path; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + TraitBound *clone_type_param_bound_impl () const override + { + return new TraitBound (*this); + } +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-type-abstract.cc b/gcc/rust/hir/tree/rust-hir-type-abstract.cc new file mode 100644 index 0000000..901c603 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-type-abstract.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-type-abstract.h" +#include "rust-hir-trait-bound.h" + +namespace Rust { +namespace HIR { + +std::unique_ptr<TraitBound> +Type::to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const +{ + return std::unique_ptr<TraitBound> (nullptr); +} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-type-abstract.h b/gcc/rust/hir/tree/rust-hir-type-abstract.h new file mode 100644 index 0000000..6142d88 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-type-abstract.h @@ -0,0 +1,80 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_TYPE_ABSTRACT_H +#define RUST_HIR_TYPE_ABSTRACT_H + +#include "rust-hir-node.h" +#include "rust-hir-visitable.h" +#include "rust-system.h" +#include "rust-hir-map.h" + +namespace Rust { +namespace HIR { + +class TraitBound; + +// Base class for types as represented in HIR - abstract +class Type : public Node, public FullVisitable +{ +public: + using FullVisitable::accept_vis; + // Unique pointer custom clone function + std::unique_ptr<Type> clone_type () const + { + return std::unique_ptr<Type> (clone_type_impl ()); + } + + // virtual destructor + virtual ~Type () {} + + BaseKind get_hir_kind () override final { return TYPE; } + + virtual std::string as_string () const = 0; + + /* HACK: convert to trait bound. Virtual method overriden by classes that + * enable this. */ + virtual std::unique_ptr<TraitBound> + to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const; + /* as pointer, shouldn't require definition beforehand, only forward + * declaration. */ + + virtual void accept_vis (HIRTypeVisitor &vis) = 0; + + virtual const Analysis::NodeMapping &get_mappings () const + { + return mappings; + } + virtual location_t get_locus () const { return locus; } + +protected: + Type (Analysis::NodeMapping mappings, location_t locus) + : mappings (mappings), locus (locus) + {} + + // Clone function implementation as pure virtual method + virtual Type *clone_type_impl () const = 0; + + Analysis::NodeMapping mappings; + location_t locus; +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-type-no-bounds.h b/gcc/rust/hir/tree/rust-hir-type-no-bounds.h new file mode 100644 index 0000000..b86ff30 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-type-no-bounds.h @@ -0,0 +1,58 @@ + +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_TYPE_NO_BOUNDS_H +#define RUST_HIR_TYPE_NO_BOUNDS_H + +#include "rust-hir-type-abstract.h" + +namespace Rust { +namespace HIR { + +// A type without parentheses? - abstract +class TypeNoBounds : public Type +{ +public: + // Unique pointer custom clone function + std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const + { + return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ()); + } + +protected: + TypeNoBounds (Analysis::NodeMapping mappings, location_t locus) + : Type (mappings, locus) + {} + + // Clone function implementation as pure virtual method + virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0; + + /* Save having to specify two clone methods in derived classes by making type + * clone return typenobounds clone. Hopefully won't affect performance too + * much. */ + TypeNoBounds *clone_type_impl () const override + { + return clone_type_no_bounds_impl (); + } +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-type.cc b/gcc/rust/hir/tree/rust-hir-type.cc new file mode 100644 index 0000000..689d86b --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-type.cc @@ -0,0 +1,289 @@ + +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-type.h" + +namespace Rust { +namespace HIR { + +ImplTraitType::ImplTraitType ( + Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + location_t locus) + : Type (mappings, locus), type_param_bounds (std::move (type_param_bounds)) +{} + +ImplTraitType::ImplTraitType (ImplTraitType const &other) + : Type (other.mappings, other.locus) +{ + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); +} + +ImplTraitType & +ImplTraitType::operator= (ImplTraitType const &other) +{ + locus = other.locus; + mappings = other.mappings; + + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + return *this; +} + +TraitObjectType::TraitObjectType ( + Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + location_t locus, bool is_dyn_dispatch) + : Type (mappings, locus), has_dyn (is_dyn_dispatch), + type_param_bounds (std::move (type_param_bounds)) +{} + +TraitObjectType::TraitObjectType (TraitObjectType const &other) + : Type (other.mappings, other.locus), has_dyn (other.has_dyn) +{ + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); +} + +TraitObjectType & +TraitObjectType::operator= (TraitObjectType const &other) +{ + mappings = other.mappings; + has_dyn = other.has_dyn; + locus = other.locus; + type_param_bounds.reserve (other.type_param_bounds.size ()); + for (const auto &e : other.type_param_bounds) + type_param_bounds.push_back (e->clone_type_param_bound ()); + + return *this; +} + +ParenthesisedType::ParenthesisedType (Analysis::NodeMapping mappings, + std::unique_ptr<Type> type_inside_parens, + location_t locus) + : TypeNoBounds (mappings, locus), + type_in_parens (std::move (type_inside_parens)) +{} + +ParenthesisedType::ParenthesisedType (ParenthesisedType const &other) + : TypeNoBounds (other.mappings, other.locus), + type_in_parens (other.type_in_parens->clone_type ()) +{} + +ParenthesisedType & +ParenthesisedType::operator= (ParenthesisedType const &other) +{ + mappings = other.mappings; + type_in_parens = other.type_in_parens->clone_type (); + locus = other.locus; + return *this; +} + +std::unique_ptr<TraitBound> +ParenthesisedType::to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const +{ + /* NOTE: obviously it is unknown whether the internal type is a trait bound + * due to polymorphism, so just let the internal type handle it. As + * parenthesised type, it must be in parentheses. */ + return type_in_parens->to_trait_bound (true); +} + +TupleType::TupleType (Analysis::NodeMapping mappings, + std::vector<std::unique_ptr<Type>> elems, + location_t locus) + : TypeNoBounds (mappings, locus), elems (std::move (elems)) +{} + +TupleType::TupleType (TupleType const &other) + : TypeNoBounds (other.mappings, other.locus) +{ + mappings = other.mappings; + elems.reserve (other.elems.size ()); + for (const auto &e : other.elems) + elems.push_back (e->clone_type ()); +} + +TupleType & +TupleType::operator= (TupleType const &other) +{ + locus = other.locus; + + elems.reserve (other.elems.size ()); + for (const auto &e : other.elems) + elems.push_back (e->clone_type ()); + + return *this; +} + +NeverType::NeverType (Analysis::NodeMapping mappings, location_t locus) + : TypeNoBounds (mappings, locus) +{} + +RawPointerType::RawPointerType (Analysis::NodeMapping mappings, Mutability mut, + std::unique_ptr<Type> type, location_t locus) + : TypeNoBounds (mappings, locus), mut (mut), type (std::move (type)) +{} + +RawPointerType::RawPointerType (RawPointerType const &other) + : TypeNoBounds (other.mappings, other.locus), mut (other.mut), + type (other.type->clone_type ()) +{} + +RawPointerType & +RawPointerType::operator= (RawPointerType const &other) +{ + mappings = other.mappings; + mut = other.mut; + type = other.type->clone_type (); + locus = other.locus; + return *this; +} + +ReferenceType::ReferenceType (Analysis::NodeMapping mappings, Mutability mut, + std::unique_ptr<Type> type_no_bounds, + location_t locus, Lifetime lifetime) + : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)), mut (mut), + type (std::move (type_no_bounds)) +{} + +ReferenceType::ReferenceType (ReferenceType const &other) + : TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime), + mut (other.mut), type (other.type->clone_type ()) +{} + +ReferenceType & +ReferenceType::operator= (ReferenceType const &other) +{ + mappings = other.mappings; + lifetime = other.lifetime; + mut = other.mut; + type = other.type->clone_type (); + locus = other.locus; + + return *this; +} + +ArrayType::ArrayType (Analysis::NodeMapping mappings, + std::unique_ptr<Type> type, + std::unique_ptr<Expr> array_size, location_t locus) + : TypeNoBounds (mappings, locus), elem_type (std::move (type)), + size (std::move (array_size)) +{} + +ArrayType::ArrayType (ArrayType const &other) + : TypeNoBounds (other.mappings, other.locus), + elem_type (other.elem_type->clone_type ()), size (other.size->clone_expr ()) +{} + +ArrayType & +ArrayType::operator= (ArrayType const &other) +{ + mappings = other.mappings; + elem_type = other.elem_type->clone_type (); + size = other.size->clone_expr (); + locus = other.locus; + return *this; +} + +SliceType::SliceType (Analysis::NodeMapping mappings, + std::unique_ptr<Type> type, location_t locus) + : TypeNoBounds (mappings, locus), elem_type (std::move (type)) +{} + +SliceType::SliceType (SliceType const &other) + : TypeNoBounds (other.mappings, other.locus), + elem_type (other.elem_type->clone_type ()) +{} + +SliceType & +SliceType::operator= (SliceType const &other) +{ + mappings = other.mappings; + elem_type = other.elem_type->clone_type (); + locus = other.locus; + + return *this; +} + +InferredType::InferredType (Analysis::NodeMapping mappings, location_t locus) + : TypeNoBounds (mappings, locus) +{} + +MaybeNamedParam::MaybeNamedParam (Identifier name, ParamKind param_kind, + std::unique_ptr<Type> param_type, + location_t locus) + : param_type (std::move (param_type)), param_kind (param_kind), + name (std::move (name)), locus (locus) +{} + +MaybeNamedParam::MaybeNamedParam (MaybeNamedParam const &other) + : param_type (other.param_type->clone_type ()), param_kind (other.param_kind), + name (other.name), locus (other.locus) +{} + +MaybeNamedParam & +MaybeNamedParam::operator= (MaybeNamedParam const &other) +{ + name = other.name; + param_kind = other.param_kind; + param_type = other.param_type->clone_type (); + locus = other.locus; + + return *this; +} + +BareFunctionType::BareFunctionType ( + Analysis::NodeMapping mappings, std::vector<LifetimeParam> lifetime_params, + FunctionQualifiers qualifiers, std::vector<MaybeNamedParam> named_params, + bool is_variadic, std::unique_ptr<Type> type, location_t locus) + : TypeNoBounds (mappings, locus), for_lifetimes (std::move (lifetime_params)), + function_qualifiers (std::move (qualifiers)), + params (std::move (named_params)), is_variadic (is_variadic), + return_type (std::move (type)) +{} + +BareFunctionType::BareFunctionType (BareFunctionType const &other) + : TypeNoBounds (other.mappings, other.locus), + for_lifetimes (other.for_lifetimes), + function_qualifiers (other.function_qualifiers), params (other.params), + is_variadic (other.is_variadic), + return_type (other.return_type->clone_type ()) +{} + +BareFunctionType & +BareFunctionType::operator= (BareFunctionType const &other) +{ + mappings = other.mappings; + for_lifetimes = other.for_lifetimes; + function_qualifiers = other.function_qualifiers; + params = other.params; + is_variadic = other.is_variadic; + return_type = other.return_type->clone_type (); + locus = other.locus; + + return *this; +} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index e4a9754..bd0f2b6 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -19,73 +19,13 @@ #ifndef RUST_HIR_TYPE_H #define RUST_HIR_TYPE_H +#include "rust-hir-type-abstract.h" #include "rust-common.h" -#include "rust-hir.h" -#include "rust-hir-path.h" +#include "rust-hir-trait-bound.h" +#include "rust-hir-item.h" namespace Rust { namespace HIR { -// definitions moved to rust-ast.h -class TypeParamBound; -class Lifetime; - -// A trait bound -class TraitBound : public TypeParamBound -{ - bool in_parens; - BoundPolarity polarity; - std::vector<LifetimeParam> for_lifetimes; - TypePath type_path; - location_t locus; - - Analysis::NodeMapping mappings; - -public: - // Returns whether trait bound has "for" lifetimes - bool has_for_lifetimes () const { return !for_lifetimes.empty (); } - - TraitBound (Analysis::NodeMapping mapping, TypePath type_path, - location_t locus, bool in_parens = false, - BoundPolarity polarity = BoundPolarity::RegularBound, - std::vector<LifetimeParam> for_lifetimes - = std::vector<LifetimeParam> ()) - : in_parens (in_parens), polarity (polarity), - for_lifetimes (std::move (for_lifetimes)), - type_path (std::move (type_path)), locus (locus), mappings (mapping) - {} - - std::string as_string () const override; - - location_t get_locus () const override final { return locus; } - - void accept_vis (HIRFullVisitor &vis) override; - - Analysis::NodeMapping get_mappings () const override final - { - return mappings; - } - - std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; } - bool get_in_parens () { return in_parens; } - BoundPolarity get_polarity () { return polarity; } - - BoundType get_bound_type () const final override { return TRAITBOUND; } - - TypePath &get_path () { return type_path; } - - const TypePath &get_path () const { return type_path; } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - TraitBound *clone_type_param_bound_impl () const override - { - return new TraitBound (*this); - } -}; - -// definition moved to rust-ast.h -class TypeNoBounds; // An impl trait? Poor reference material here. class ImplTraitType : public Type @@ -105,31 +45,13 @@ protected: public: ImplTraitType (Analysis::NodeMapping mappings, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, - location_t locus) - : Type (mappings, locus), type_param_bounds (std::move (type_param_bounds)) - {} + location_t locus); // copy constructor with vector clone - ImplTraitType (ImplTraitType const &other) - : Type (other.mappings, other.locus) - { - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - } + ImplTraitType (ImplTraitType const &other); // overloaded assignment operator to clone - ImplTraitType &operator= (ImplTraitType const &other) - { - locus = other.locus; - mappings = other.mappings; - - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - return *this; - } + ImplTraitType &operator= (ImplTraitType const &other); // move constructors ImplTraitType (ImplTraitType &&other) = default; @@ -162,32 +84,13 @@ public: TraitObjectType ( Analysis::NodeMapping mappings, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, - location_t locus, bool is_dyn_dispatch) - : Type (mappings, locus), has_dyn (is_dyn_dispatch), - type_param_bounds (std::move (type_param_bounds)) - {} + location_t locus, bool is_dyn_dispatch); // copy constructor with vector clone - TraitObjectType (TraitObjectType const &other) - : Type (other.mappings, other.locus), has_dyn (other.has_dyn) - { - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - } + TraitObjectType (TraitObjectType const &other); // overloaded assignment operator to clone - TraitObjectType &operator= (TraitObjectType const &other) - { - mappings = other.mappings; - has_dyn = other.has_dyn; - locus = other.locus; - type_param_bounds.reserve (other.type_param_bounds.size ()); - for (const auto &e : other.type_param_bounds) - type_param_bounds.push_back (e->clone_type_param_bound ()); - - return *this; - } + TraitObjectType &operator= (TraitObjectType const &other); // move constructors TraitObjectType (TraitObjectType &&other) = default; @@ -233,26 +136,15 @@ protected: public: // Constructor uses Type pointer for polymorphism ParenthesisedType (Analysis::NodeMapping mappings, - std::unique_ptr<Type> type_inside_parens, location_t locus) - : TypeNoBounds (mappings, locus), - type_in_parens (std::move (type_inside_parens)) - {} + std::unique_ptr<Type> type_inside_parens, + location_t locus); /* Copy constructor uses custom deep copy method for type to preserve * polymorphism */ - ParenthesisedType (ParenthesisedType const &other) - : TypeNoBounds (other.mappings, other.locus), - type_in_parens (other.type_in_parens->clone_type ()) - {} + ParenthesisedType (ParenthesisedType const &other); // overload assignment operator to use custom clone method - ParenthesisedType &operator= (ParenthesisedType const &other) - { - mappings = other.mappings; - type_in_parens = other.type_in_parens->clone_type (); - locus = other.locus; - return *this; - } + ParenthesisedType &operator= (ParenthesisedType const &other); // default move semantics ParenthesisedType (ParenthesisedType &&other) = default; @@ -264,52 +156,14 @@ public: } // Creates a trait bound (clone of this one's trait bound) - HACK - TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override - { - /* NOTE: obviously it is unknown whether the internal type is a trait bound - * due to polymorphism, so just let the internal type handle it. As - * parenthesised type, it must be in parentheses. */ - return type_in_parens->to_trait_bound (true); - } - std::unique_ptr<Type> &get_type_in_parens () { return type_in_parens; } - void accept_vis (HIRFullVisitor &vis) override; - void accept_vis (HIRTypeVisitor &vis) override; -}; - -// Impl trait with a single bound? Poor reference material here. -class ImplTraitTypeOneBound : public TypeNoBounds -{ - TraitBound trait_bound; - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - ImplTraitTypeOneBound *clone_type_impl () const override - { - return new ImplTraitTypeOneBound (*this); - } + std::unique_ptr<TraitBound> + to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override; - /* Use covariance to implement clone function as returning this object rather - * than base */ - ImplTraitTypeOneBound *clone_type_no_bounds_impl () const override - { - return new ImplTraitTypeOneBound (*this); - } - -public: - ImplTraitTypeOneBound (Analysis::NodeMapping mappings, TraitBound trait_bound, - location_t locus) - : TypeNoBounds (mappings, locus), trait_bound (std::move (trait_bound)) - {} - - std::string as_string () const override; - TraitBound &get_trait_bound () { return trait_bound; } + Type &get_type_in_parens () { return *type_in_parens; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; }; -class TypePath; // definition moved to "rust-path.h" - /* A type consisting of the "product" of others (the tuple's elements) in a * specific order */ class TupleType : public TypeNoBounds @@ -321,31 +175,13 @@ public: bool is_unit_type () const { return elems.empty (); } TupleType (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Type>> elems, location_t locus) - : TypeNoBounds (mappings, locus), elems (std::move (elems)) - {} + std::vector<std::unique_ptr<Type>> elems, location_t locus); // copy constructor with vector clone - TupleType (TupleType const &other) - : TypeNoBounds (other.mappings, other.locus) - { - mappings = other.mappings; - elems.reserve (other.elems.size ()); - for (const auto &e : other.elems) - elems.push_back (e->clone_type ()); - } + TupleType (TupleType const &other); // overloaded assignment operator to clone - TupleType &operator= (TupleType const &other) - { - locus = other.locus; - - elems.reserve (other.elems.size ()); - for (const auto &e : other.elems) - elems.push_back (e->clone_type ()); - - return *this; - } + TupleType &operator= (TupleType const &other); // move constructors TupleType (TupleType &&other) = default; @@ -390,9 +226,7 @@ protected: } public: - NeverType (Analysis::NodeMapping mappings, location_t locus) - : TypeNoBounds (mappings, locus) - {} + NeverType (Analysis::NodeMapping mappings, location_t locus); std::string as_string () const override { return "! (never type)"; } @@ -410,25 +244,13 @@ private: public: // Constructor requires pointer for polymorphism reasons RawPointerType (Analysis::NodeMapping mappings, Mutability mut, - std::unique_ptr<Type> type, location_t locus) - : TypeNoBounds (mappings, locus), mut (mut), type (std::move (type)) - {} + std::unique_ptr<Type> type, location_t locus); // Copy constructor calls custom polymorphic clone function - RawPointerType (RawPointerType const &other) - : TypeNoBounds (other.mappings, other.locus), mut (other.mut), - type (other.type->clone_type ()) - {} + RawPointerType (RawPointerType const &other); // overload assignment operator to use custom clone method - RawPointerType &operator= (RawPointerType const &other) - { - mappings = other.mappings; - mut = other.mut; - type = other.type->clone_type (); - locus = other.locus; - return *this; - } + RawPointerType &operator= (RawPointerType const &other); // default move semantics RawPointerType (RawPointerType &&other) = default; @@ -439,7 +261,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; - std::unique_ptr<Type> &get_type () { return type; } + Type &get_type () { return *type; } Mutability get_mut () const { return mut; } @@ -447,7 +269,7 @@ public: bool is_const () const { return mut == Mutability::Imm; } - std::unique_ptr<Type> &get_base_type () { return type; } + Type &get_base_type () { return *type; } protected: /* Use covariance to implement clone function as returning this object rather @@ -484,28 +306,13 @@ public: // Constructor ReferenceType (Analysis::NodeMapping mappings, Mutability mut, std::unique_ptr<Type> type_no_bounds, location_t locus, - Lifetime lifetime) - : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)), - mut (mut), type (std::move (type_no_bounds)) - {} + Lifetime lifetime); // Copy constructor with custom clone method - ReferenceType (ReferenceType const &other) - : TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime), - mut (other.mut), type (other.type->clone_type ()) - {} + ReferenceType (ReferenceType const &other); // Operator overload assignment operator to custom clone the unique pointer - ReferenceType &operator= (ReferenceType const &other) - { - mappings = other.mappings; - lifetime = other.lifetime; - mut = other.mut; - type = other.type->clone_type (); - locus = other.locus; - - return *this; - } + ReferenceType &operator= (ReferenceType const &other); // move constructors ReferenceType (ReferenceType &&other) = default; @@ -520,7 +327,7 @@ public: Mutability get_mut () const { return mut; } - std::unique_ptr<Type> &get_base_type () { return type; } + Type &get_base_type () { return *type; } protected: /* Use covariance to implement clone function as returning this object rather @@ -547,27 +354,13 @@ class ArrayType : public TypeNoBounds public: // Constructor requires pointers for polymorphism ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, - std::unique_ptr<Expr> array_size, location_t locus) - : TypeNoBounds (mappings, locus), elem_type (std::move (type)), - size (std::move (array_size)) - {} + std::unique_ptr<Expr> array_size, location_t locus); // Copy constructor requires deep copies of both unique pointers - ArrayType (ArrayType const &other) - : TypeNoBounds (other.mappings, other.locus), - elem_type (other.elem_type->clone_type ()), - size (other.size->clone_expr ()) - {} + ArrayType (ArrayType const &other); // Overload assignment operator to deep copy pointers - ArrayType &operator= (ArrayType const &other) - { - mappings = other.mappings; - elem_type = other.elem_type->clone_type (); - size = other.size->clone_expr (); - locus = other.locus; - return *this; - } + ArrayType &operator= (ArrayType const &other); // move constructors ArrayType (ArrayType &&other) = default; @@ -578,9 +371,9 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; - std::unique_ptr<Type> &get_element_type () { return elem_type; } + Type &get_element_type () { return *elem_type; } - std::unique_ptr<Expr> &get_size_expr () { return size; } + Expr &get_size_expr () { return *size; } protected: /* Use covariance to implement clone function as returning this object rather @@ -604,25 +397,13 @@ class SliceType : public TypeNoBounds public: // Constructor requires pointer for polymorphism SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, - location_t locus) - : TypeNoBounds (mappings, locus), elem_type (std::move (type)) - {} + location_t locus); // Copy constructor requires deep copy of Type smart pointer - SliceType (SliceType const &other) - : TypeNoBounds (other.mappings, other.locus), - elem_type (other.elem_type->clone_type ()) - {} + SliceType (SliceType const &other); // Overload assignment operator to deep copy - SliceType &operator= (SliceType const &other) - { - mappings = other.mappings; - elem_type = other.elem_type->clone_type (); - locus = other.locus; - - return *this; - } + SliceType &operator= (SliceType const &other); // move constructors SliceType (SliceType &&other) = default; @@ -633,7 +414,7 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; - std::unique_ptr<Type> &get_element_type () { return elem_type; } + Type &get_element_type () { return *elem_type; } protected: /* Use covariance to implement clone function as returning this object rather @@ -669,9 +450,7 @@ protected: } public: - InferredType (Analysis::NodeMapping mappings, location_t locus) - : TypeNoBounds (mappings, locus) - {} + InferredType (Analysis::NodeMapping mappings, location_t locus); std::string as_string () const override; @@ -679,8 +458,6 @@ public: void accept_vis (HIRTypeVisitor &vis) override; }; -class QualifiedPathInType; // definition moved to "rust-path.h" - // A possibly named param used in a BaseFunctionType struct MaybeNamedParam { @@ -702,29 +479,15 @@ private: public: MaybeNamedParam (Identifier name, ParamKind param_kind, - std::unique_ptr<Type> param_type, location_t locus) - : param_type (std::move (param_type)), param_kind (param_kind), - name (std::move (name)), locus (locus) - {} + std::unique_ptr<Type> param_type, location_t locus); // Copy constructor with clone - MaybeNamedParam (MaybeNamedParam const &other) - : param_type (other.param_type->clone_type ()), - param_kind (other.param_kind), name (other.name), locus (other.locus) - {} + MaybeNamedParam (MaybeNamedParam const &other); ~MaybeNamedParam () = default; // Overloaded assignment operator with clone - MaybeNamedParam &operator= (MaybeNamedParam const &other) - { - name = other.name; - param_kind = other.param_kind; - param_type = other.param_type->clone_type (); - locus = other.locus; - - return *this; - } + MaybeNamedParam &operator= (MaybeNamedParam const &other); // move constructors MaybeNamedParam (MaybeNamedParam &&other) = default; @@ -743,7 +506,7 @@ public: location_t get_locus () const { return locus; } - std::unique_ptr<Type> &get_type () { return param_type; } + Type &get_type () { return *param_type; } ParamKind get_param_kind () const { return param_kind; } @@ -777,36 +540,13 @@ public: std::vector<LifetimeParam> lifetime_params, FunctionQualifiers qualifiers, std::vector<MaybeNamedParam> named_params, bool is_variadic, - std::unique_ptr<Type> type, location_t locus) - : TypeNoBounds (mappings, locus), - for_lifetimes (std::move (lifetime_params)), - function_qualifiers (std::move (qualifiers)), - params (std::move (named_params)), is_variadic (is_variadic), - return_type (std::move (type)) - {} + std::unique_ptr<Type> type, location_t locus); // Copy constructor with clone - BareFunctionType (BareFunctionType const &other) - : TypeNoBounds (other.mappings, other.locus), - for_lifetimes (other.for_lifetimes), - function_qualifiers (other.function_qualifiers), params (other.params), - is_variadic (other.is_variadic), - return_type (other.return_type->clone_type ()) - {} + BareFunctionType (BareFunctionType const &other); // Overload assignment operator to deep copy - BareFunctionType &operator= (BareFunctionType const &other) - { - mappings = other.mappings; - for_lifetimes = other.for_lifetimes; - function_qualifiers = other.function_qualifiers; - params = other.params; - is_variadic = other.is_variadic; - return_type = other.return_type->clone_type (); - locus = other.locus; - - return *this; - } + BareFunctionType &operator= (BareFunctionType const &other); // move constructors BareFunctionType (BareFunctionType &&other) = default; @@ -828,7 +568,7 @@ public: } // TODO: would a "vis_type" be better? - std::unique_ptr<Type> &get_return_type () { return return_type; } + Type &get_return_type () { return *return_type; } protected: /* Use covariance to implement clone function as returning this object rather diff --git a/gcc/rust/hir/tree/rust-hir-visibility.h b/gcc/rust/hir/tree/rust-hir-visibility.h new file mode 100644 index 0000000..a750d88 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-visibility.h @@ -0,0 +1,80 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_VISIBILITY_H +#define RUST_HIR_VISIBILITY_H + +#include "rust-hir-simple-path.h" + +namespace Rust { +namespace HIR { +// Visibility of an item +struct Visibility +{ +public: + enum VisType + { + PRIVATE, + PUBLIC, + RESTRICTED, + ERROR, + }; + +private: + VisType vis_type; + HIR::SimplePath path; + location_t locus; + + // should this store location info? + +public: + Visibility (VisType vis_type, + HIR::SimplePath path = HIR::SimplePath::create_empty (), + location_t locus = UNDEF_LOCATION) + : vis_type (vis_type), path (std::move (path)), locus (locus) + {} + + // Returns whether visibility is in an error state. + bool is_error () const { return vis_type == ERROR; } + + // Does the current visibility refer to a simple `pub <item>` entirely public + bool is_public () const { return vis_type == PUBLIC; } + + // Is the current visibility public restricted to a certain path + bool is_restricted () const { return vis_type == RESTRICTED; } + + // Creates an error visibility. + static Visibility create_error () + { + return Visibility (ERROR, HIR::SimplePath::create_empty ()); + } + + VisType get_vis_type () const { return vis_type; } + + const HIR::SimplePath &get_path () const + { + rust_assert (!is_error ()); + return path; + } + + std::string as_string () const; +}; +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-visitable.h b/gcc/rust/hir/tree/rust-hir-visitable.h new file mode 100644 index 0000000..9c05cbf --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-visitable.h @@ -0,0 +1,41 @@ +// Copyright (C) 2020-2024 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_VISITABLE_H +#define RUST_HIR_VISITABLE_H + +namespace Rust { +namespace HIR { + +class HIRFullVisitor; +class HIRTraitItemVisitor; +class HIRImplVisitor; +class HIRStmtVisitor; +class HIRExpressionVisitor; +class HIRTypeVisitor; +class HIRPatternVisitor; + +class FullVisitable +{ +public: + virtual void accept_vis (HIRFullVisitor &vis) = 0; +}; +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h index e69e951..800e647 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.h +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -19,7 +19,6 @@ #ifndef RUST_HIR_VISITOR_H #define RUST_HIR_VISITOR_H -#include "rust-hir-expr.h" #include "rust-hir-full-decls.h" namespace Rust { @@ -81,8 +80,6 @@ public: virtual void visit (WhileLetLoopExpr &expr) = 0; virtual void visit (IfExpr &expr) = 0; virtual void visit (IfExprConseqElse &expr) = 0; - virtual void visit (IfLetExpr &expr) = 0; - virtual void visit (IfLetExprConseqElse &expr) = 0; virtual void visit (MatchExpr &expr) = 0; virtual void visit (AwaitExpr &expr) = 0; virtual void visit (AsyncBlockExpr &expr) = 0; @@ -145,7 +142,6 @@ public: virtual void visit (ImplTraitType &type) = 0; virtual void visit (TraitObjectType &type) = 0; virtual void visit (ParenthesisedType &type) = 0; - virtual void visit (ImplTraitTypeOneBound &type) = 0; virtual void visit (TupleType &type) = 0; virtual void visit (NeverType &type) = 0; virtual void visit (RawPointerType &type) = 0; @@ -219,8 +215,6 @@ public: virtual void visit (WhileLetLoopExpr &) override {} virtual void visit (IfExpr &) override {} virtual void visit (IfExprConseqElse &) override {} - virtual void visit (IfLetExpr &) override {} - virtual void visit (IfLetExprConseqElse &) override {} virtual void visit (MatchExpr &) override {} virtual void visit (AwaitExpr &) override {} @@ -295,7 +289,6 @@ public: virtual void visit (ImplTraitType &) override {} virtual void visit (TraitObjectType &) override {} virtual void visit (ParenthesisedType &) override {} - virtual void visit (ImplTraitTypeOneBound &) override {} virtual void visit (TupleType &) override {} virtual void visit (NeverType &) override {} virtual void visit (RawPointerType &) override {} @@ -359,7 +352,6 @@ public: virtual void visit (ImplTraitType &type) = 0; virtual void visit (TraitObjectType &type) = 0; virtual void visit (ParenthesisedType &type) = 0; - virtual void visit (ImplTraitTypeOneBound &type) = 0; virtual void visit (TupleType &type) = 0; virtual void visit (NeverType &type) = 0; virtual void visit (RawPointerType &type) = 0; @@ -448,8 +440,6 @@ public: virtual void visit (WhileLetLoopExpr &expr) = 0; virtual void visit (IfExpr &expr) = 0; virtual void visit (IfExprConseqElse &expr) = 0; - virtual void visit (IfLetExpr &expr) = 0; - virtual void visit (IfLetExprConseqElse &expr) = 0; virtual void visit (InlineAsm &expr) = 0; virtual void visit (MatchExpr &expr) = 0; virtual void visit (AwaitExpr &expr) = 0; diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc index f05e506..822eaff 100644 --- a/gcc/rust/hir/tree/rust-hir.cc +++ b/gcc/rust/hir/tree/rust-hir.cc @@ -19,6 +19,7 @@ #include "rust-ast-full.h" #include "rust-hir-expr.h" #include "rust-hir-full.h" +#include "rust-hir-path.h" #include "rust-hir-visitor.h" #include "rust-diagnostics.h" @@ -70,6 +71,33 @@ get_string_in_delims (std::string str_input, AST::DelimType delim_type) rust_unreachable (); } +Crate::Crate (std::vector<std::unique_ptr<Item>> items, + AST::AttrVec inner_attrs, Analysis::NodeMapping mappings) + : WithInnerAttrs (std::move (inner_attrs)), items (std::move (items)), + mappings (mappings) +{} + +Crate::Crate (Crate const &other) + : WithInnerAttrs (other.inner_attrs), mappings (other.mappings) +{ + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_item ()); +} + +Crate & +Crate::operator= (Crate const &other) +{ + inner_attrs = other.inner_attrs; + mappings = other.mappings; + + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_item ()); + + return *this; +} + std::string Crate::as_string () const { @@ -1183,6 +1211,9 @@ ClosureExpr::as_string () const std::string PathPattern::as_string () const { + if (is_lang_item ()) + return LangItem::PrettyString (*lang_item); + std::string str; for (const auto &segment : segments) @@ -1572,41 +1603,6 @@ IfExprConseqElse::as_string () const } std::string -IfLetExpr::as_string () const -{ - std::string str ("IfLetExpr: "); - - str += "\n Condition match arm patterns: "; - if (match_arm_patterns.empty ()) - { - str += "none"; - } - else - { - for (const auto &pattern : match_arm_patterns) - { - str += "\n " + pattern->as_string (); - } - } - - str += "\n Scrutinee expr: " + value->as_string (); - - str += "\n If let block expr: " + if_block->as_string (); - - return str; -} - -std::string -IfLetExprConseqElse::as_string () const -{ - std::string str = IfLetExpr::as_string (); - - str += "\n Else expr: " + else_block->as_string (); - - return str; -} - -std::string RangeFromToInclExpr::as_string () const { return from->as_string () + "..=" + to->as_string (); @@ -2186,7 +2182,7 @@ TypeParam::as_string () const } else { - str += type->as_string (); + str += type.value ()->as_string (); } return str; @@ -2195,6 +2191,8 @@ TypeParam::as_string () const AST::SimplePath PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const { + rust_assert (kind == Kind::Segmented); + if (!has_segments ()) { return AST::SimplePath::create_empty (); @@ -2677,12 +2675,12 @@ LetStmt::as_string () const if (has_type ()) { - str += " : " + type->as_string (); + str += " : " + get_type ().as_string (); } if (has_init_expr ()) { - str += " = " + init_expr->as_string (); + str += " = " + get_init_expr ().as_string (); } return str; @@ -2712,14 +2710,14 @@ Expr::as_string () const } // hopefully definition here will prevent circular dependency issue -TraitBound * +std::unique_ptr<TraitBound> TypePath::to_trait_bound (bool in_parens) const { // create clone FIXME is this required? or is copy constructor automatically // called? TypePath copy (*this); - return new TraitBound (mappings, std::move (copy), copy.get_locus (), - in_parens); + return std::make_unique<TraitBound> (mappings, std::move (copy), + copy.get_locus (), in_parens); } std::string @@ -2868,14 +2866,6 @@ BareFunctionType::as_string () const } std::string -ImplTraitTypeOneBound::as_string () const -{ - std::string str ("ImplTraitTypeOneBound: \n TraitBound: "); - - return str + trait_bound.as_string (); -} - -std::string TypePathSegmentGeneric::as_string () const { return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">"; @@ -3047,7 +3037,7 @@ StructExprStructFields::as_string () const } else { - str += struct_base->as_string (); + str += (*struct_base)->as_string (); } return str; @@ -4030,6 +4020,12 @@ StructExprStructBase::accept_vis (HIRFullVisitor &vis) } void +StructExprStructBase::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void CallExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); @@ -4150,18 +4146,6 @@ IfExprConseqElse::accept_vis (HIRFullVisitor &vis) } void -IfLetExpr::accept_vis (HIRFullVisitor &vis) -{ - vis.visit (*this); -} - -void -IfLetExprConseqElse::accept_vis (HIRFullVisitor &vis) -{ - vis.visit (*this); -} - -void MatchExpr::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); @@ -4534,12 +4518,6 @@ ParenthesisedType::accept_vis (HIRFullVisitor &vis) } void -ImplTraitTypeOneBound::accept_vis (HIRFullVisitor &vis) -{ - vis.visit (*this); -} - -void TupleType::accept_vis (HIRFullVisitor &vis) { vis.visit (*this); @@ -4732,12 +4710,6 @@ ArrayType::accept_vis (HIRTypeVisitor &vis) } void -ImplTraitTypeOneBound::accept_vis (HIRTypeVisitor &vis) -{ - vis.visit (*this); -} - -void BareFunctionType::accept_vis (HIRTypeVisitor &vis) { vis.visit (*this); @@ -4912,18 +4884,6 @@ RangeFromToInclExpr::accept_vis (HIRExpressionVisitor &vis) } void -IfLetExprConseqElse::accept_vis (HIRExpressionVisitor &vis) -{ - vis.visit (*this); -} - -void -IfLetExpr::accept_vis (HIRExpressionVisitor &vis) -{ - vis.visit (*this); -} - -void IfExprConseqElse::accept_vis (HIRExpressionVisitor &vis) { vis.visit (*this); @@ -5211,20 +5171,5 @@ StaticItem::accept_vis (HIRVisItemVisitor &vis) vis.visit (*this); } -std::string -ConstGenericParam::as_string () const -{ - auto result = "ConstGenericParam: " + name + " : " + type->as_string (); - - if (default_expression) - result += " = " + default_expression->as_string (); - - return result; -} - -void -ConstGenericParam::accept_vis (HIRFullVisitor &) -{} - } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index f8eb22d..ffab5ff 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -19,779 +19,24 @@ #ifndef RUST_HIR_BASE_H #define RUST_HIR_BASE_H -#include "rust-ast.h" #include "rust-system.h" +#include "rust-ast.h" +#include "rust-hir-visitable.h" +#include "rust-hir-attrs.h" + #include "rust-token.h" + #include "rust-location.h" + #include "rust-hir-map.h" #include "rust-diagnostics.h" +#include "rust-hir-bound.h" namespace Rust { + typedef int TupleIndex; namespace HIR { -// foward decl: ast visitor -class HIRFullVisitor; -class HIRStmtVisitor; -class HIRTraitItemVisitor; -class HIRExternalItemVisitor; -class HIRVisItemVisitor; -class HIRExpressionVisitor; -class HIRPatternVisitor; -class HIRImplVisitor; -class HIRTypeVisitor; - -class WithOuterAttrs -{ -protected: - AST::AttrVec outer_attrs; - -public: - AST::AttrVec &get_outer_attrs () { return outer_attrs; } - const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } - - WithOuterAttrs (AST::AttrVec outer_attrs) - : outer_attrs (std::move (outer_attrs)){}; -}; - -class WithInnerAttrs -{ -protected: - AST::AttrVec inner_attrs; - -public: - AST::AttrVec get_inner_attrs () const { return inner_attrs; } - WithInnerAttrs (AST::AttrVec inner_attrs) - : inner_attrs (std::move (inner_attrs)){}; -}; - -class FullVisitable -{ -public: - virtual void accept_vis (HIRFullVisitor &vis) = 0; -}; - -// forward decl for use in token tree method -class Token; - -class Node -{ -public: - // Kind for downcasting various HIR nodes to other base classes when visiting - // them - enum BaseKind - { - /* class ExternalItem */ - EXTERNAL, - /* class TraitItem */ - TRAIT_ITEM, - /* class VisItem */ - VIS_ITEM, - /* class Item */ - ITEM, - /* class ImplItem */ - IMPL, - /* class Type */ - TYPE, - /* class Stmt */ - STMT, - /* class Expr */ - EXPR, - /* class Pattern */ - PATTERN, - }; - - /** - * Get the kind of HIR node we are dealing with. This is useful for - * downcasting to more precise types when necessary, i.e going from an `Item*` - * to a `VisItem*` - */ - virtual BaseKind get_hir_kind () = 0; -}; - -// A literal - value with a type. Used in LiteralExpr and LiteralPattern. -struct Literal -{ -public: - enum LitType - { - CHAR, - STRING, - BYTE, - BYTE_STRING, - INT, - FLOAT, - BOOL - }; - -private: - std::string value_as_string; - LitType type; - PrimitiveCoreType type_hint; - -public: - std::string as_string () const { return value_as_string; } - - LitType get_lit_type () const { return type; } - - PrimitiveCoreType get_type_hint () const { return type_hint; } - - Literal (std::string value_as_string, LitType type, - PrimitiveCoreType type_hint) - : value_as_string (std::move (value_as_string)), type (type), - type_hint (type_hint) - {} - - static Literal create_error () - { - return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN); - } - - void set_lit_type (LitType lt) { type = lt; } - - // Returns whether literal is in an invalid state. - bool is_error () const { return value_as_string == ""; } - - bool is_equal (Literal &other) - { - return value_as_string == other.value_as_string && type == other.type - && type_hint == other.type_hint; - } -}; - -/* Base statement abstract class. Note that most "statements" are not allowed in - * top-level module scope - only a subclass of statements called "items" are. */ -class Stmt : public Node, public FullVisitable -{ -public: - using FullVisitable::accept_vis; - - // Unique pointer custom clone function - std::unique_ptr<Stmt> clone_stmt () const - { - return std::unique_ptr<Stmt> (clone_stmt_impl ()); - } - - BaseKind get_hir_kind () override { return STMT; } - - virtual ~Stmt () {} - - virtual std::string as_string () const = 0; - - virtual void accept_vis (HIRStmtVisitor &vis) = 0; - - virtual location_t get_locus () const = 0; - - virtual bool is_unit_check_needed () const { return false; } - - const Analysis::NodeMapping &get_mappings () const { return mappings; } - - virtual bool is_item () const = 0; - -protected: - Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {} - - // Clone function implementation as pure virtual method - virtual Stmt *clone_stmt_impl () const = 0; - - Analysis::NodeMapping mappings; -}; - -// 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<Item> clone_item () const - { - return std::unique_ptr<Item> (clone_item_impl ()); - } - - BaseKind get_hir_kind () override { return 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<std::string> &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 (); } -}; - -// forward decl of ExprWithoutBlock -class ExprWithoutBlock; - -// Base expression HIR node - abstract -class Expr : public Node, virtual public FullVisitable -{ -public: - using FullVisitable::accept_vis; - -protected: - AST::AttrVec outer_attrs; - Analysis::NodeMapping mappings; - -public: - enum BlockType - { - WITH_BLOCK, - WITHOUT_BLOCK, - }; - - enum ExprType - { - Lit, - Operator, - Grouped, - Array, - ArrayIndex, - Tuple, - TupleIdx, - Struct, - Call, - MethodCall, - FieldAccess, - Closure, - Block, - Continue, - Break, - Range, - Return, - UnsafeBlock, - BaseLoop, - If, - IfLet, - Match, - Await, - AsyncBlock, - Path, - InlineAsm, - }; - - BaseKind get_hir_kind () override final { return EXPR; } - - const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } - - // Unique pointer custom clone function - std::unique_ptr<Expr> clone_expr () const - { - return std::unique_ptr<Expr> (clone_expr_impl ()); - } - - // TODO: make pure virtual if move out outer attributes to derived classes - virtual std::string as_string () const; - - virtual ~Expr () {} - - virtual location_t get_locus () const = 0; - - const Analysis::NodeMapping &get_mappings () const { return mappings; } - - // Clone function implementation as pure virtual method - virtual Expr *clone_expr_impl () const = 0; - - virtual BlockType get_block_expr_type () const = 0; - - virtual ExprType get_expression_type () const = 0; - - virtual void accept_vis (HIRExpressionVisitor &vis) = 0; - -protected: - // Constructor - Expr (Analysis::NodeMapping mappings, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : outer_attrs (std::move (outer_attribs)), mappings (std::move (mappings)) - {} - - // TODO: think of less hacky way to implement this kind of thing - // Sets outer attributes. - void set_outer_attrs (AST::AttrVec outer_attrs_to_set) - { - outer_attrs = std::move (outer_attrs_to_set); - } -}; - -// HIR node for an expression without an accompanying block - abstract -class ExprWithoutBlock : public Expr -{ -protected: - // Constructor - ExprWithoutBlock (Analysis::NodeMapping mappings, - AST::AttrVec outer_attribs = AST::AttrVec ()) - : Expr (std::move (mappings), std::move (outer_attribs)) - {} - - // pure virtual clone implementation - virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0; - - /* Save having to specify two clone methods in derived classes by making expr - * clone return exprwithoutblock clone. Hopefully won't affect performance too - * much. */ - ExprWithoutBlock *clone_expr_impl () const override - { - return clone_expr_without_block_impl (); - } - -public: - // Unique pointer custom clone function - std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const - { - return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ()); - } - - BlockType get_block_expr_type () const final override - { - return BlockType::WITHOUT_BLOCK; - }; -}; - -// Pattern base HIR node -class Pattern : public Node, virtual public FullVisitable -{ -public: - using FullVisitable::accept_vis; - - enum PatternType - { - PATH, - LITERAL, - IDENTIFIER, - WILDCARD, - RANGE, - REFERENCE, - STRUCT, - TUPLE_STRUCT, - TUPLE, - GROUPED, - SLICE, - ALT - }; - - BaseKind get_hir_kind () override final { return PATTERN; } - - // Unique pointer custom clone function - std::unique_ptr<Pattern> clone_pattern () const - { - return std::unique_ptr<Pattern> (clone_pattern_impl ()); - } - - // possible virtual methods: is_refutable() - - virtual ~Pattern () {} - - virtual std::string as_string () const = 0; - - virtual void accept_vis (HIRPatternVisitor &vis) = 0; - - virtual const Analysis::NodeMapping &get_mappings () const = 0; - - virtual location_t get_locus () const = 0; - - virtual PatternType get_pattern_type () const = 0; - -protected: - // Clone pattern implementation as pure virtual method - virtual Pattern *clone_pattern_impl () const = 0; -}; - -// forward decl for Type -class TraitBound; - -// Base class for types as represented in HIR - abstract -class Type : public Node, public FullVisitable -{ -public: - using FullVisitable::accept_vis; - // Unique pointer custom clone function - std::unique_ptr<Type> clone_type () const - { - return std::unique_ptr<Type> (clone_type_impl ()); - } - - // virtual destructor - virtual ~Type () {} - - BaseKind get_hir_kind () override final { return TYPE; } - - virtual std::string as_string () const = 0; - - /* HACK: convert to trait bound. Virtual method overriden by classes that - * enable this. */ - virtual TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const - { - return nullptr; - } - /* as pointer, shouldn't require definition beforehand, only forward - * declaration. */ - - virtual void accept_vis (HIRTypeVisitor &vis) = 0; - - virtual Analysis::NodeMapping get_mappings () const { return mappings; } - virtual location_t get_locus () const { return locus; } - -protected: - Type (Analysis::NodeMapping mappings, location_t locus) - : mappings (mappings), locus (locus) - {} - - // Clone function implementation as pure virtual method - virtual Type *clone_type_impl () const = 0; - - Analysis::NodeMapping mappings; - location_t locus; -}; - -// A type without parentheses? - abstract -class TypeNoBounds : public Type -{ -public: - // Unique pointer custom clone function - std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const - { - return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ()); - } - -protected: - TypeNoBounds (Analysis::NodeMapping mappings, location_t locus) - : Type (mappings, locus) - {} - - // Clone function implementation as pure virtual method - virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0; - - /* Save having to specify two clone methods in derived classes by making type - * clone return typenobounds clone. Hopefully won't affect performance too - * much. */ - TypeNoBounds *clone_type_impl () const override - { - return clone_type_no_bounds_impl (); - } -}; - -/* Abstract base class representing a type param bound - Lifetime and TraitBound - * extends it */ -class TypeParamBound : public FullVisitable -{ -public: - using FullVisitable::accept_vis; - enum BoundType - { - LIFETIME, - TRAITBOUND - }; - - virtual ~TypeParamBound () {} - - // Unique pointer custom clone function - std::unique_ptr<TypeParamBound> clone_type_param_bound () const - { - return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ()); - } - - virtual std::string as_string () const = 0; - - virtual Analysis::NodeMapping get_mappings () const = 0; - - virtual location_t get_locus () const = 0; - - virtual BoundType get_bound_type () const = 0; - -protected: - // Clone function implementation as pure virtual method - virtual TypeParamBound *clone_type_param_bound_impl () const = 0; -}; - -// Represents a lifetime (and is also a kind of type param bound) -class Lifetime : public TypeParamBound -{ -private: - AST::Lifetime::LifetimeType lifetime_type; - std::string lifetime_name; - location_t locus; - Analysis::NodeMapping mappings; - -public: - // Constructor - Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type, - std::string name, location_t locus) - : lifetime_type (type), lifetime_name (std::move (name)), locus (locus), - mappings (mapping) - {} - - // Returns true if the lifetime is in an error state. - bool is_error () const - { - return lifetime_type == AST::Lifetime::LifetimeType::NAMED - && lifetime_name.empty (); - } - - static Lifetime error () - { - return Lifetime (Analysis::NodeMapping::get_error (), - AST::Lifetime::LifetimeType::NAMED, "", UNDEF_LOCATION); - } - - std::string as_string () const override; - - void accept_vis (HIRFullVisitor &vis) override; - - WARN_UNUSED_RESULT const std::string &get_name () const - { - return lifetime_name; - } - - AST::Lifetime::LifetimeType get_lifetime_type () const - { - return lifetime_type; - } - - location_t get_locus () const override final { return locus; } - - Analysis::NodeMapping get_mappings () const override final - { - return mappings; - } - - BoundType get_bound_type () const final override { return LIFETIME; } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - Lifetime *clone_type_param_bound_impl () const override - { - return new Lifetime (*this); - } -}; - -/* Base generic parameter in HIR. Abstract - can be represented by a Lifetime or - * Type param */ -class GenericParam : public FullVisitable -{ -public: - using FullVisitable::accept_vis; - - virtual ~GenericParam () {} - - enum class GenericKind - { - TYPE, - LIFETIME, - CONST, - }; - - virtual AST::AttrVec &get_outer_attrs () = 0; - virtual bool has_outer_attribute () const = 0; - - // Unique pointer custom clone function - std::unique_ptr<GenericParam> clone_generic_param () const - { - return std::unique_ptr<GenericParam> (clone_generic_param_impl ()); - } - - virtual std::string as_string () const = 0; - - virtual location_t get_locus () const = 0; - - Analysis::NodeMapping get_mappings () const { return mappings; } - - enum GenericKind get_kind () const { return kind; } - -protected: - // Clone function implementation as pure virtual method - virtual GenericParam *clone_generic_param_impl () const = 0; - - Analysis::NodeMapping mappings; - - enum GenericKind kind; - - GenericParam (Analysis::NodeMapping mapping, - enum GenericKind kind = GenericKind::TYPE) - : mappings (mapping), kind (kind) - {} -}; - -// A lifetime generic parameter (as opposed to a type generic parameter) -class LifetimeParam : public GenericParam -{ - Lifetime lifetime; - - // bool has_lifetime_bounds; - // LifetimeBounds lifetime_bounds; - std::vector<Lifetime> lifetime_bounds; // inlined LifetimeBounds - - AST::AttrVec outer_attrs; - - location_t locus; - -public: - Lifetime get_lifetime () { return lifetime; } - - // Returns whether the lifetime param has any lifetime bounds. - bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); } - - std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; } - - // Returns whether the lifetime param has an outer attribute. - bool has_outer_attribute () const override { return outer_attrs.size () > 1; } - - AST::AttrVec &get_outer_attrs () { return outer_attrs; } - - // Returns whether the lifetime param is in an error state. - bool is_error () const { return lifetime.is_error (); } - - // Constructor - LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime, - location_t locus = UNDEF_LOCATION, - std::vector<Lifetime> lifetime_bounds - = std::vector<Lifetime> (), - AST::AttrVec outer_attrs = std::vector<AST::Attribute> ()) - : GenericParam (mappings, GenericKind::LIFETIME), - lifetime (std::move (lifetime)), - lifetime_bounds (std::move (lifetime_bounds)), - outer_attrs (std::move (outer_attrs)), locus (locus) - {} - - // TODO: remove copy and assignment operator definitions - not required - - // Copy constructor with clone - LifetimeParam (LifetimeParam const &other) - : GenericParam (other.mappings, GenericKind::LIFETIME), - lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds), - outer_attrs (other.outer_attrs), locus (other.locus) - {} - - // Overloaded assignment operator to clone attribute - LifetimeParam &operator= (LifetimeParam const &other) - { - lifetime = other.lifetime; - lifetime_bounds = other.lifetime_bounds; - outer_attrs = other.outer_attrs; - locus = other.locus; - mappings = other.mappings; - - return *this; - } - - // move constructors - LifetimeParam (LifetimeParam &&other) = default; - LifetimeParam &operator= (LifetimeParam &&other) = default; - - std::string as_string () const override; - - void accept_vis (HIRFullVisitor &vis) override; - - location_t get_locus () const override final { return locus; } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - LifetimeParam *clone_generic_param_impl () const override - { - return new LifetimeParam (*this); - } -}; - -class ConstGenericParam : public GenericParam -{ -public: - ConstGenericParam (std::string name, std::unique_ptr<Type> type, - std::unique_ptr<Expr> default_expression, - Analysis::NodeMapping mapping, location_t locus) - : GenericParam (mapping, GenericKind::CONST), name (std::move (name)), - type (std::move (type)), - default_expression (std::move (default_expression)), locus (locus) - {} - - ConstGenericParam (const ConstGenericParam &other) : GenericParam (other) - { - name = other.name; - locus = other.locus; - - if (other.type) - type = other.type->clone_type (); - if (other.default_expression) - default_expression = other.default_expression->clone_expr (); - } - - bool has_outer_attribute () const override { return false; } - - AST::AttrVec &get_outer_attrs () override { return outer_attrs; } - - std::string as_string () const override final; - - void accept_vis (HIRFullVisitor &vis) override final; - - location_t get_locus () const override final { return locus; }; - - bool has_default_expression () { return default_expression != nullptr; } - - std::string get_name () { return name; } - std::unique_ptr<Type> &get_type () { return type; } - std::unique_ptr<Expr> &get_default_expression () - { - return default_expression; - } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - ConstGenericParam *clone_generic_param_impl () const override - { - return new ConstGenericParam (*this); - } - -private: - std::string name; - std::unique_ptr<Type> type; - - /* const params have no outer attrs, should be empty */ - AST::AttrVec outer_attrs = std::vector<AST::Attribute> (); - - /* Optional - can be a null pointer if there is no default expression */ - std::unique_ptr<Expr> default_expression; - - location_t locus; -}; // Item used in trait declarations - abstract base class class TraitItem : public Node, public FullVisitable @@ -892,34 +137,15 @@ class Crate : public WithInnerAttrs public: // Constructor Crate (std::vector<std::unique_ptr<Item>> items, AST::AttrVec inner_attrs, - Analysis::NodeMapping mappings) - : WithInnerAttrs (std::move (inner_attrs)), items (std::move (items)), - mappings (mappings) - {} + Analysis::NodeMapping mappings); // Copy constructor with vector clone - Crate (Crate const &other) - : WithInnerAttrs (other.inner_attrs), mappings (other.mappings) - { - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_item ()); - } + Crate (Crate const &other); ~Crate () = default; // Overloaded assignment operator with vector clone - Crate &operator= (Crate const &other) - { - inner_attrs = other.inner_attrs; - mappings = other.mappings; - - items.reserve (other.items.size ()); - for (const auto &e : other.items) - items.push_back (e->clone_item ()); - - return *this; - } + Crate &operator= (Crate const &other); // Move constructors Crate (Crate &&other) = default; @@ -932,27 +158,6 @@ public: std::vector<std::unique_ptr<Item>> &get_items () { return items; } }; -// Base path expression HIR node - abstract -class PathExpr : public ExprWithoutBlock -{ -protected: - PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs) - : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)) - {} - -public: - /* Replaces the outer attributes of this path expression with the given outer - * attributes. */ - void replace_outer_attrs (AST::AttrVec outer_attrs) - { - set_outer_attrs (std::move (outer_attrs)); - } - - ExprType get_expression_type () const final override - { - return ExprType::Path; - } -}; } // namespace HIR } // namespace Rust |