diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-06-24 18:25:15 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-19 15:32:04 +0100 |
commit | 96cd17a73132873458989c4928e8189a8764e48d (patch) | |
tree | 5c543581749035bbd0273bf172b22434bc5bdcd9 /gcc/rust/ast/rust-path.h | |
parent | 21d5cef96adfb26ea67d03bdfaacbd1fe8742d6e (diff) | |
download | gcc-96cd17a73132873458989c4928e8189a8764e48d.zip gcc-96cd17a73132873458989c4928e8189a8764e48d.tar.gz gcc-96cd17a73132873458989c4928e8189a8764e48d.tar.bz2 |
gccrs: ast: Introduce class hierarchy for lang item paths
Create a base Path class which is derived into two children classes for
regular paths and lang item paths. This allows it to hold either the
segments of a fully formed path, or the node ID of a lang-item path.
This is required in order to create these special paths
which do not have segments, and do not necessarily have a canonical
form - they only depend on where the item was defined.
gcc/rust/ChangeLog:
* ast/rust-ast-full-decls.h (class PathPattern): Rename PathPattern to...
(class Path): ...Path
* ast/rust-ast-collector.cc (TokenCollector::visit): Add required methods
for LangItemPath and RegularPath.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h: Likewise.
* ast/rust-path.cc (PathPattern::as_string): Likewise.
(RegularPath::as_string): Likewise.
(LangItemPath::as_string): Likewise.
(PathPattern::convert_to_simple_path): Likewise.
(RegularPath::convert_to_simple_path): Likewise.
(RegularPath::accept_vis): Likewise.
(LangItemPath::accept_vis): Likewise.
(PathInExpression::as_string): Likewise.
(QualifiedPathInExpression::as_string): Likewise.
* ast/rust-path.h (class PathPattern): Likewise.
(class Path): Likewise.
(class RegularPath): Likewise.
(class LangItemPath): Likewise.
(class PathInExpression): Likewise.
(class QualifiedPathInExpression): Likewise.
* ast/rust-pattern.h (class PathPattern): Likewise.
(class Path): Likewise.
* expand/rust-derive.h: Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
Diffstat (limited to 'gcc/rust/ast/rust-path.h')
-rw-r--r-- | gcc/rust/ast/rust-path.h | 251 |
1 files changed, 215 insertions, 36 deletions
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index bf75801..29163ac 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -22,6 +22,9 @@ * for virtually all AST-related functionality. */ #include "rust-ast.h" +#include "rust-hir-map.h" +#include "rust-mapping-common.h" +#include "rust-system.h" #include "system.h" namespace Rust { @@ -565,45 +568,113 @@ public: // AST node representing a pattern that involves a "path" - abstract base // class -class PathPattern : public Pattern +class Path : public Pattern { - std::vector<PathExprSegment> segments; +public: + enum class Kind + { + LangItem, + Regular, + }; + + virtual Kind get_path_kind () const = 0; + + Pattern::Kind get_pattern_kind () override final + { + return Pattern::Kind::Path; + } + + location_t get_locus () const override final { return locus; } + NodeId get_node_id () const override final { return node_id; } + + std::unique_ptr<Path> clone_path () + { + return std::unique_ptr<Path> (clone_path_impl ()); + } + + Pattern *clone_pattern_impl () const override final + { + return clone_path_impl (); + } protected: - PathPattern (std::vector<PathExprSegment> segments) - : segments (std::move (segments)) + location_t locus; + NodeId node_id; + + Path (location_t locus, NodeId node_id) : locus (locus), node_id (node_id) {} + + virtual Path *clone_path_impl () const = 0; +}; + +class RegularPath : public Path +{ + std::vector<PathExprSegment> segments; + +public: + explicit RegularPath (std::vector<PathExprSegment> &&segments, + location_t locus, NodeId node_id) + : Path (locus, node_id), segments (std::move (segments)) {} + std::string as_string () const override; + // Returns whether path has segments. bool has_segments () const { return !segments.empty (); } - /* Converts path segments to their equivalent SimplePath segments if - * possible, and creates a SimplePath from them. */ - SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const; + std::vector<PathExprSegment> &get_segments () { return segments; } + + const std::vector<PathExprSegment> &get_segments () const { return segments; } -public: /* Returns whether the path is a single segment (excluding qualified path * initial as segment). */ bool is_single_segment () const { return segments.size () == 1; } - std::string as_string () const override; + /* Converts path segments to their equivalent SimplePath segments if + * possible, and creates a SimplePath from them. */ + SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const; - // TODO: this seems kinda dodgy - std::vector<PathExprSegment> &get_segments () { return segments; } - const std::vector<PathExprSegment> &get_segments () const { return segments; } + Path::Kind get_path_kind () const override { return Path::Kind::Regular; } - Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; } + void accept_vis (ASTVisitor &vis) override; + + Path *clone_path_impl () const override + { + return new RegularPath (std::vector<PathExprSegment> (segments), locus, + node_id); + } +}; + +class LangItemPath : public Path +{ + NodeId lang_item; + // TODO: Add LangItemKind or w/ever here as well + + // TODO: This constructor is wrong + explicit LangItemPath (NodeId lang_item, location_t locus) + : Path (locus, lang_item), lang_item (lang_item) + {} + + Path::Kind get_path_kind () const override { return Path::Kind::LangItem; } + + void accept_vis (ASTVisitor &vis) override; + + Path *clone_path_impl () const override + { + return new LangItemPath (lang_item, locus); + } + + std::string as_string () const override; }; /* AST node representing a path-in-expression pattern (path that allows * generic arguments) */ -class PathInExpression : public PathPattern, public ExprWithoutBlock +class PathInExpression : public Pattern, public ExprWithoutBlock { std::vector<Attribute> outer_attrs; bool has_opening_scope_resolution; location_t locus; NodeId _node_id; - + std::unique_ptr<Path> path; bool marked_for_strip; public: @@ -613,13 +684,34 @@ public: PathInExpression (std::vector<PathExprSegment> path_segments, std::vector<Attribute> outer_attrs, location_t locus, bool has_opening_scope_resolution = false) - : PathPattern (std::move (path_segments)), - outer_attrs (std::move (outer_attrs)), + : outer_attrs (std::move (outer_attrs)), has_opening_scope_resolution (has_opening_scope_resolution), locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()), + path (Rust::make_unique<RegularPath> (std::move (path_segments), locus, + _node_id)), marked_for_strip (false) {} + PathInExpression (const PathInExpression &other) + : outer_attrs (other.outer_attrs), + has_opening_scope_resolution (other.has_opening_scope_resolution), + locus (other.locus), _node_id (other._node_id), + path (other.path->clone_path ()), + marked_for_strip (other.marked_for_strip) + {} + + PathInExpression &operator= (const PathInExpression &other) + { + outer_attrs = other.outer_attrs; + has_opening_scope_resolution = other.has_opening_scope_resolution; + locus = other.locus; + _node_id = other._node_id; + path = other.path->clone_path (); + marked_for_strip = other.marked_for_strip; + + return *this; + } + // Creates an error state path in expression. static PathInExpression create_error () { @@ -627,19 +719,26 @@ public: } // Returns whether path in expression is in an error state. - bool is_error () const { return !has_segments (); } + bool is_error () const + { + // FIXME: Cleanup + if (path->get_path_kind () == Path::Kind::Regular) + return !static_cast<RegularPath &> (*path).has_segments (); + + return false; + } /* Converts PathInExpression to SimplePath if possible (i.e. no generic * arguments). Otherwise returns an empty SimplePath. */ SimplePath as_simple_path () const { - /* delegate to parent class as can't access segments. however, - * QualifiedPathInExpression conversion to simple path wouldn't make - * sense, so the method in the parent class should be protected, not - * public. Have to pass in opening scope resolution as parent class has no - * access to it. - */ - return convert_to_simple_path (has_opening_scope_resolution); + // FIXME: Cleanup + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).convert_to_simple_path ( + has_opening_scope_resolution); + else + // FIXME: lang item to simple path? + rust_unreachable (); } location_t get_locus () const override final { return locus; } @@ -666,13 +765,61 @@ public: NodeId get_pattern_node_id () const { return get_node_id (); } - PathExprSegment &get_final_segment () { return get_segments ().back (); } + PathExprSegment &get_final_segment () + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments ().back (); + + // lang item segment? + rust_unreachable (); + } + const PathExprSegment &get_final_segment () const { - return get_segments ().back (); + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments ().back (); + + // lang item segment? + rust_unreachable (); } + const std::vector<PathExprSegment> &get_segments () const + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments (); + + rust_unreachable (); + } + + std::vector<PathExprSegment> &get_segments () + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments (); + + rust_unreachable (); + } + + bool is_single_segment () const + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments ().size () == 1; + + return false; + } + + Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; } + protected: + PathInExpression (std::vector<Attribute> &&outer_attrs, + bool has_opening_scope_resolution, location_t locus, + NodeId node_id, std::unique_ptr<Path> &&path, + bool marked_for_strip) + : outer_attrs (std::move (outer_attrs)), + has_opening_scope_resolution (has_opening_scope_resolution), + locus (locus), _node_id (node_id), path (std::move (path)), + marked_for_strip (marked_for_strip) + {} + /* Use covariance to implement clone function as returning this object * rather than base */ PathInExpression *clone_pattern_impl () const final override @@ -1221,12 +1368,12 @@ public: /* AST node representing a qualified path-in-expression pattern (path that * allows specifying trait functions) */ -class QualifiedPathInExpression : public PathPattern, public ExprWithoutBlock +class QualifiedPathInExpression : public Pattern, public ExprWithoutBlock { std::vector<Attribute> outer_attrs; QualifiedPathType path_type; - location_t locus; - NodeId _node_id; + + std::unique_ptr<Path> path; public: std::string as_string () const override; @@ -1235,10 +1382,16 @@ public: std::vector<PathExprSegment> path_segments, std::vector<Attribute> outer_attrs, location_t locus) - : PathPattern (std::move (path_segments)), - outer_attrs (std::move (outer_attrs)), - path_type (std::move (qual_path_type)), locus (locus), - _node_id (Analysis::Mappings::get ().get_next_node_id ()) + : outer_attrs (std::move (outer_attrs)), + path_type (std::move (qual_path_type)), + path (Rust::make_unique<RegularPath> ( + std::move (path_segments), locus, + Analysis::Mappings::get ().get_next_node_id ())) + {} + + QualifiedPathInExpression (const QualifiedPathInExpression &other) + : outer_attrs (other.outer_attrs), path_type (other.path_type), + path (other.path->clone_path ()) {} /* TODO: maybe make a shortcut constructor that has QualifiedPathType @@ -1254,7 +1407,9 @@ public: {}, UNDEF_LOCATION); } - location_t get_locus () const override final { return locus; } + Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; } + + location_t get_locus () const override final { return path->get_locus (); } void accept_vis (ASTVisitor &vis) override; @@ -1280,7 +1435,31 @@ public: outer_attrs = std::move (new_attrs); } - NodeId get_node_id () const override { return _node_id; } + NodeId get_node_id () const override { return path->get_node_id (); } + + const std::vector<PathExprSegment> &get_segments () const + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments (); + + rust_unreachable (); + } + + std::vector<PathExprSegment> &get_segments () + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments (); + + rust_unreachable (); + } + + bool is_single_segment () const + { + if (path->get_path_kind () == Path::Kind::Regular) + return static_cast<RegularPath &> (*path).get_segments ().size () == 1; + + return false; + } protected: /* Use covariance to implement clone function as returning this object |