diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-10-21 13:45:38 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-12-13 14:00:04 +0100 |
commit | 7641eaead409ad3a80b6c92900199af352549fe4 (patch) | |
tree | b73aaf69350a272924f4ed9c5d123f9053b660f4 /gcc/rust/hir/tree/rust-hir.h | |
parent | 8ad1d56d68a998fdc662a944f461e7bcb125920e (diff) | |
download | gcc-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.h | 921 |
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 |