| // Copyright (C) 2020-2023 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 |
| { |
| 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, |
| }; |
| |
| 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 Location get_trait_locus () const = 0; |
| |
| 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; |
| |
| virtual std::string get_impl_item_name () 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 |