aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/hir/tree/rust-hir.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-10-21 13:45:38 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-12-13 14:00:04 +0100
commit7641eaead409ad3a80b6c92900199af352549fe4 (patch)
treeb73aaf69350a272924f4ed9c5d123f9053b660f4 /gcc/rust/hir/tree/rust-hir.h
parent8ad1d56d68a998fdc662a944f461e7bcb125920e (diff)
downloadgcc-7641eaead409ad3a80b6c92900199af352549fe4.zip
gcc-7641eaead409ad3a80b6c92900199af352549fe4.tar.gz
gcc-7641eaead409ad3a80b6c92900199af352549fe4.tar.bz2
gccrs: Add HIR definitions and visitor framework
This patch implements the classes mentioned in the previous HIR patch, as well as a set of visitor frameworks used in handling that HIR. gcc/rust/ * hir/tree/rust-hir-full-decls.h: New. * hir/tree/rust-hir-full-test.cc: New. * hir/tree/rust-hir-full.h: New. * hir/tree/rust-hir-visitor.h: New. * hir/tree/rust-hir.h: New.
Diffstat (limited to 'gcc/rust/hir/tree/rust-hir.h')
-rw-r--r--gcc/rust/hir/tree/rust-hir.h921
1 files changed, 921 insertions, 0 deletions
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
new file mode 100644
index 0000000..927ac06
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -0,0 +1,921 @@
+// Copyright (C) 2020-2022 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_BASE_H
+#define RUST_HIR_BASE_H
+
+#include "rust-ast.h"
+#include "rust-system.h"
+#include "rust-token.h"
+#include "rust-location.h"
+#include "rust-hir-map.h"
+#include "rust-diagnostics.h"
+
+namespace Rust {
+typedef std::string Identifier;
+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;
+
+// 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:
+ // 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 (HIRFullVisitor &vis) = 0;
+ virtual void accept_vis (HIRStmtVisitor &vis) = 0;
+
+ virtual Location 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
+{
+ AST::AttrVec outer_attrs;
+
+ // 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,
+ };
+
+ 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
+ {}
+
+ AST::AttrVec &get_outer_attrs () { return outer_attrs; }
+ const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
+
+ bool is_item () const override final { return true; }
+
+protected:
+ // Constructor
+ Item (Analysis::NodeMapping mappings,
+ AST::AttrVec outer_attribs = AST::AttrVec ())
+ : Stmt (std::move (mappings)), outer_attrs (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
+{
+ 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,
+ };
+
+ 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 ());
+ }
+
+ /* HACK: downcasting without dynamic_cast (if possible) via polymorphism -
+ * overrided in subclasses of ExprWithoutBlock */
+ virtual ExprWithoutBlock *as_expr_without_block () const { return nullptr; }
+
+ // TODO: make pure virtual if move out outer attributes to derived classes
+ virtual std::string as_string () const;
+
+ virtual ~Expr () {}
+
+ virtual Location 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;
+ virtual void accept_vis (HIRFullVisitor &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 ());
+ }
+
+ /* downcasting hack from expr to use pratt parsing with
+ * parse_expr_without_block */
+ ExprWithoutBlock *as_expr_without_block () const override
+ {
+ return 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
+{
+public:
+ enum PatternType
+ {
+ PATH,
+ LITERAL,
+ IDENTIFIER,
+ WILDCARD,
+ RANGE,
+ REFERENCE,
+ STRUCT,
+ TUPLE_STRUCT,
+ TUPLE,
+ GROUPED,
+ SLICE,
+ };
+
+ 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 (HIRFullVisitor &vis) = 0;
+ virtual void accept_vis (HIRPatternVisitor &vis) = 0;
+
+ virtual Analysis::NodeMapping get_pattern_mappings () const = 0;
+
+ virtual Location 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:
+ // 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 (HIRFullVisitor &vis) = 0;
+ virtual void accept_vis (HIRTypeVisitor &vis) = 0;
+
+ virtual Analysis::NodeMapping get_mappings () const { return mappings; }
+ virtual Location get_locus () const { return locus; }
+
+protected:
+ Type (Analysis::NodeMapping mappings, Location locus)
+ : mappings (mappings), locus (locus)
+ {}
+
+ // Clone function implementation as pure virtual method
+ virtual Type *clone_type_impl () const = 0;
+
+ Analysis::NodeMapping mappings;
+ Location 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 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:
+ 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 void accept_vis (HIRFullVisitor &vis) = 0;
+
+ virtual Analysis::NodeMapping get_mappings () const = 0;
+
+ virtual Location 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 locus;
+ Analysis::NodeMapping mappings;
+
+public:
+ // Constructor
+ Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type,
+ std::string name, Location 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, "", Location ());
+ }
+
+ std::string as_string () const override;
+
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ std::string get_name () const { return lifetime_name; }
+
+ AST::Lifetime::LifetimeType get_lifetime_type () const
+ {
+ return lifetime_type;
+ }
+
+ Location 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:
+ virtual ~GenericParam () {}
+
+ enum class GenericKind
+ {
+ TYPE,
+ LIFETIME,
+ CONST,
+ };
+
+ // 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 void accept_vis (HIRFullVisitor &vis) = 0;
+
+ virtual Location 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
+
+ // bool has_outer_attribute;
+ // std::unique_ptr<Attribute> outer_attr;
+ AST::Attribute outer_attr;
+
+ Location 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 (); }
+
+ // Returns whether the lifetime param has an outer attribute.
+ bool has_outer_attribute () const { return !outer_attr.is_empty (); }
+
+ // 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 locus = Location (),
+ std::vector<Lifetime> lifetime_bounds
+ = std::vector<Lifetime> (),
+ AST::Attribute outer_attr = AST::Attribute::create_empty ())
+ : GenericParam (mappings, GenericKind::LIFETIME),
+ lifetime (std::move (lifetime)),
+ lifetime_bounds (std::move (lifetime_bounds)),
+ outer_attr (std::move (outer_attr)), 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_attr (other.outer_attr), locus (other.locus)
+ {}
+
+ // Overloaded assignment operator to clone attribute
+ LifetimeParam &operator= (LifetimeParam const &other)
+ {
+ lifetime = other.lifetime;
+ lifetime_bounds = other.lifetime_bounds;
+ outer_attr = other.outer_attr;
+ 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 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 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 ();
+ }
+
+ std::string as_string () const override final;
+
+ void accept_vis (HIRFullVisitor &vis) override final;
+
+ Location get_locus () const override final { return locus; };
+
+ bool has_default_expression () { return default_expression != nullptr; }
+
+ std::unique_ptr<Type> &get_type () { return type; }
+ std::unique_ptr<Expr> &get_default_expression ()
+ {
+ rust_assert (has_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;
+
+ /* Optional - can be a null pointer if there is no default expression */
+ std::unique_ptr<Expr> default_expression;
+
+ Location locus;
+};
+
+// Item used in trait declarations - abstract base class
+class TraitItem : public Node
+{
+public:
+ enum TraitItemKind
+ {
+ FUNC,
+ CONST,
+ TYPE
+ };
+
+ BaseKind get_hir_kind () override final { return TRAIT_ITEM; }
+
+protected:
+ // Constructor
+ TraitItem (Analysis::NodeMapping mappings) : mappings (mappings) {}
+
+ // Clone function implementation as pure virtual method
+ virtual TraitItem *clone_trait_item_impl () const = 0;
+
+ Analysis::NodeMapping mappings;
+
+public:
+ virtual ~TraitItem () {}
+
+ std::unique_ptr<TraitItem> clone_trait_item () const
+ {
+ return std::unique_ptr<TraitItem> (clone_trait_item_impl ());
+ }
+
+ virtual std::string as_string () const = 0;
+
+ virtual void accept_vis (HIRTraitItemVisitor &vis) = 0;
+ virtual void accept_vis (HIRFullVisitor &vis) = 0;
+
+ virtual const std::string trait_identifier () const = 0;
+
+ const Analysis::NodeMapping get_mappings () const { return mappings; }
+
+ virtual TraitItemKind get_item_kind () const = 0;
+
+ virtual AST::AttrVec &get_outer_attrs () = 0;
+ virtual const AST::AttrVec &get_outer_attrs () const = 0;
+};
+
+class ImplItem : public Node
+{
+public:
+ enum ImplItemType
+ {
+ FUNCTION,
+ TYPE_ALIAS,
+ CONSTANT
+ };
+
+ virtual ~ImplItem () {}
+
+ BaseKind get_hir_kind () override final { return IMPL; }
+
+ // Unique pointer custom clone function
+ std::unique_ptr<ImplItem> clone_inherent_impl_item () const
+ {
+ return std::unique_ptr<ImplItem> (clone_inherent_impl_item_impl ());
+ }
+
+ virtual std::string as_string () const = 0;
+
+ virtual void accept_vis (HIRImplVisitor &vis) = 0;
+ virtual void accept_vis (HIRFullVisitor &vis) = 0;
+ virtual void accept_vis (HIRStmtVisitor &vis) = 0;
+
+ virtual Analysis::NodeMapping get_impl_mappings () const = 0;
+
+ virtual Location get_locus () const = 0;
+
+ virtual ImplItemType get_impl_item_type () const = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual ImplItem *clone_inherent_impl_item_impl () const = 0;
+};
+
+// A crate HIR object - holds all the data for a single compilation unit
+struct Crate
+{
+ AST::AttrVec inner_attrs;
+ // dodgy spacing required here
+ /* TODO: is it better to have a vector of items here or a module (implicit
+ * top-level one)? */
+ std::vector<std::unique_ptr<Item> > items;
+
+ Analysis::NodeMapping mappings;
+
+public:
+ // Constructor
+ Crate (std::vector<std::unique_ptr<Item> > items, AST::AttrVec inner_attrs,
+ Analysis::NodeMapping mappings)
+ : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
+ mappings (mappings)
+ {}
+
+ // Copy constructor with vector clone
+ Crate (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 ());
+ }
+
+ ~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;
+ }
+
+ // Move constructors
+ Crate (Crate &&other) = default;
+ Crate &operator= (Crate &&other) = default;
+
+ // Get crate representation as string (e.g. for debugging).
+ std::string as_string () const;
+
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+};
+
+// 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