diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-04-03 17:22:57 +0200 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2023-04-04 12:05:02 +0000 |
commit | 8b017829f1d22ea6ef0cd9cb05c29e04b5776de0 (patch) | |
tree | 19d1558c1912441768a50e1d729ef6bf82fcd079 /gcc | |
parent | b99448f4b02957c71ceb1adc3fb8cfa2a7602ab9 (diff) | |
download | gcc-8b017829f1d22ea6ef0cd9cb05c29e04b5776de0.zip gcc-8b017829f1d22ea6ef0cd9cb05c29e04b5776de0.tar.gz gcc-8b017829f1d22ea6ef0cd9cb05c29e04b5776de0.tar.bz2 |
ast: Move rust-path implementation out of rust-ast
Move rust-path implementation details out of rust-ast.cc file. This will
hopefully decrease compile time and make things clearer.
gcc/rust/ChangeLog:
* Make-lang.in: Add new file for rust-path implementation.
* ast/rust-ast.cc (PathInExpression::as_string): Move function
to the new file.
(PathPattern::as_string): Likewise.
(QualifiedPathInExpression::as_string): Likewise.
(ConstGenericParam::as_string): Likewise.
(QualifiedPathInType::as_string): Likewise.
(TypePath::as_string): Likewise.
(PathPattern::convert_to_simple_path): Likewise.
(TypePath::as_simple_path): Likewise.
(PathExprSegment::as_string): Likewise.
(GenericArgs::as_string): Likewise.
(GenericArgsBinding::as_string): Likewise.
(TypePath::to_trait_bound): Likewise.
(TypePathSegmentGeneric::as_string): Likewise.
(TypePathFunction::as_string): Likewise.
(TypePathSegmentFunction::as_string): Likewise.
(ConstGenericParam::accept_vis): Likewise.
(PathInExpression::accept_vis): Likewise.
(TypePathSegment::accept_vis): Likewise.
(TypePathSegmentGeneric::accept_vis): Likewise.
(TypePathSegmentFunction::accept_vis): Likewise.
(TypePath::accept_vis): Likewise.
(QualifiedPathInExpression::accept_vis): Likewise.
(QualifiedPathInType::accept_vis): Likewise.
(GenericArg::disambiguate_to_const): Likewise.
(GenericArg::disambiguate_to_type): Likewise.
* ast/rust-path.cc: New file.
Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/Make-lang.in | 1 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.cc | 326 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.cc | 360 |
3 files changed, 361 insertions, 326 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index f7f2813..6b5861a 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -73,6 +73,7 @@ GRS_OBJS = \ rust/rust-cfg-parser.o \ rust/rust-parse.o \ rust/rust-ast.o \ + rust/rust-path.o \ rust/rust-ast-fragment.o \ rust/rust-ast-dump.o \ rust/rust-ast-tokenstream.o \ diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index dd73e5e..c0a54a5 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1357,17 +1357,6 @@ MacroInvocData::as_string () const } std::string -PathInExpression::as_string () const -{ - std::string str; - - if (has_opening_scope_resolution) - str = "::"; - - return str + PathPattern::as_string (); -} - -std::string ExprStmtWithBlock::as_string () const { std::string str = indent_spaces (enter) + "ExprStmtWithBlock: \n"; @@ -1438,20 +1427,6 @@ ClosureExprInnerTyped::as_string () const } std::string -PathPattern::as_string () const -{ - std::string str; - - for (const auto &segment : segments) - str += segment.as_string () + "::"; - - // basically a hack - remove last two characters of string (remove final ::) - str.erase (str.length () - 2); - - return str; -} - -std::string QualifiedPathType::as_string () const { std::string str ("<"); @@ -1464,12 +1439,6 @@ QualifiedPathType::as_string () const } std::string -QualifiedPathInExpression::as_string () const -{ - return path_type.as_string () + "::" + PathPattern::as_string (); -} - -std::string BorrowExpr::as_string () const { /* TODO: find way to incorporate outer attrs - may have to represent in @@ -2373,38 +2342,12 @@ LifetimeParam::as_string () const } std::string -ConstGenericParam::as_string () const -{ - std::string str ("ConstGenericParam: "); - str += "const " + name + ": " + type->as_string (); - - if (has_default_value ()) - str += " = " + get_default_value ().as_string (); - - return str; -} - -std::string MacroMatchFragment::as_string () const { return "$" + ident + ": " + frag_spec.as_string (); } std::string -QualifiedPathInType::as_string () const -{ - /* TODO: this may need adjusting if segments (e.g. with functions) can't be - * literalised */ - std::string str = path_type.as_string (); - - str += "::" + associated_segment->as_string (); - for (const auto &segment : segments) - str += "::" + segment->as_string (); - - return str; -} - -std::string MacroMatchRepetition::as_string () const { std::string str ("Macro match repetition: "); @@ -2468,25 +2411,6 @@ Lifetime::as_string () const } std::string -TypePath::as_string () const -{ - /* TODO: this may need to be rewritten if a segment (e.g. function) can't be - * literalised */ - std::string str; - - if (has_opening_scope_resolution) - str = "::"; - - for (const auto &segment : segments) - str += segment->as_string () + "::"; - - // kinda hack - remove last 2 '::' characters - str.erase (str.length () - 2); - - return str; -} - -std::string TypeParam::as_string () const { std::string str ("TypeParam: "); @@ -2519,136 +2443,6 @@ TypeParam::as_string () const return str; } -SimplePath -PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const -{ - if (!has_segments ()) - return SimplePath::create_empty (); - - // create vector of reserved size (to minimise reallocations) - std::vector<SimplePathSegment> simple_segments; - simple_segments.reserve (segments.size ()); - - for (const auto &segment : segments) - { - // return empty path if doesn't meet simple path segment requirements - if (segment.is_error () || segment.has_generic_args () - || segment.as_string () == "Self") - return SimplePath::create_empty (); - - // create segment and add to vector - std::string segment_str = segment.as_string (); - simple_segments.push_back ( - SimplePathSegment (std::move (segment_str), segment.get_locus ())); - } - - // kind of a HACK to get locus depending on opening scope resolution - Location locus = Linemap::unknown_location (); - if (with_opening_scope_resolution) - locus = simple_segments[0].get_locus () - 2; // minus 2 chars for :: - else - locus = simple_segments[0].get_locus (); - // FIXME: this hack probably doesn't actually work - - return SimplePath (std::move (simple_segments), with_opening_scope_resolution, - locus); -} - -SimplePath -TypePath::as_simple_path () const -{ - if (segments.empty ()) - return SimplePath::create_empty (); - - // create vector of reserved size (to minimise reallocations) - std::vector<SimplePathSegment> simple_segments; - simple_segments.reserve (segments.size ()); - - for (const auto &segment : segments) - { - // return empty path if doesn't meet simple path segment requirements - if (segment == nullptr || segment->is_error () - || !segment->is_ident_only () || segment->as_string () == "Self") - return SimplePath::create_empty (); - - // create segment and add to vector - std::string segment_str = segment->as_string (); - simple_segments.push_back ( - SimplePathSegment (std::move (segment_str), segment->get_locus ())); - } - - return SimplePath (std::move (simple_segments), has_opening_scope_resolution, - locus); -} - -std::string -PathExprSegment::as_string () const -{ - // TODO: rewrite dump to work with non-literalisable types - std::string ident_str = segment_name.as_string (); - if (has_generic_args ()) - ident_str += "::<" + generic_args.as_string () + ">"; - - return ident_str; -} - -std::string -GenericArgs::as_string () const -{ - std::string args; - - // lifetime args - if (!lifetime_args.empty ()) - { - auto i = lifetime_args.begin (); - auto e = lifetime_args.end (); - - for (; i != e; i++) - { - args += (*i).as_string (); - if (e != i + 1) - args += ", "; - } - } - - // type args - if (!generic_args.empty ()) - { - auto i = generic_args.begin (); - auto e = generic_args.end (); - - for (; i != e; i++) - { - args += (*i).as_string (); - if (e != i + 1) - args += ", "; - } - } - - // binding args - if (!binding_args.empty ()) - { - auto i = binding_args.begin (); - auto e = binding_args.end (); - - for (; i != e; i++) - { - args += (*i).as_string (); - if (e != i + 1) - args += ", "; - } - } - - return args; -} - -std::string -GenericArgsBinding::as_string () const -{ - // TODO: rewrite to work with non-literalisable types - return identifier + " = " + type->as_string (); -} - std::string ForLoopExpr::as_string () const { @@ -2968,13 +2762,6 @@ LetStmt::as_string () const return str; } -// hopefully definition here will prevent circular dependency issue -TraitBound * -TypePath::to_trait_bound (bool in_parens) const -{ - return new TraitBound (TypePath (*this), get_locus (), in_parens); -} - std::string InferredType::as_string () const { @@ -3123,13 +2910,6 @@ ImplTraitTypeOneBound::as_string () const } std::string -TypePathSegmentGeneric::as_string () const -{ - // TODO: rewrite to work with non-linearisable types - return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">"; -} - -std::string TraitObjectTypeOneBound::as_string () const { std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: "); @@ -3145,40 +2925,6 @@ TraitObjectTypeOneBound::as_string () const } std::string -TypePathFunction::as_string () const -{ - // TODO: rewrite to work with non-linearisable types - std::string str ("("); - - if (has_inputs ()) - { - auto i = inputs.begin (); - auto e = inputs.end (); - - for (; i != e; i++) - { - str += (*i)->as_string (); - if (e != i + 1) - str += ", "; - } - } - - str += ")"; - - if (has_return_type ()) - str += " -> " + return_type->as_string (); - - return str; -} - -std::string -TypePathSegmentFunction::as_string () const -{ - // TODO: rewrite to work with non-linearisable types - return TypePathSegment::as_string () + function_path.as_string (); -} - -std::string ArrayType::as_string () const { // TODO: rewrite to work with non-linearisable types and exprs @@ -4934,54 +4680,6 @@ LifetimeParam::accept_vis (ASTVisitor &vis) } void -ConstGenericParam::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -PathInExpression::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -TypePathSegment::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -TypePathSegmentGeneric::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -TypePathSegmentFunction::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -TypePath::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -QualifiedPathInExpression::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -QualifiedPathInType::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void LiteralExpr::accept_vis (ASTVisitor &vis) { vis.visit (*this); @@ -5839,29 +5537,5 @@ MetaWord::accept_vis (ASTVisitor &vis) vis.visit (*this); } -GenericArg -GenericArg::disambiguate_to_const () const -{ - rust_assert (get_kind () == Kind::Either); - - // FIXME: is it fine to have no outer attributes? - return GenericArg::create_const ( - std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus))); -} - -GenericArg -GenericArg::disambiguate_to_type () const -{ - rust_assert (get_kind () == Kind::Either); - - auto segment = std::unique_ptr<TypePathSegment> ( - new TypePathSegment (path, false, locus)); - auto segments = std::vector<std::unique_ptr<TypePathSegment>> (); - segments.emplace_back (std::move (segment)); - - return GenericArg::create_type ( - std::unique_ptr<Type> (new TypePath (std::move (segments), locus))); -} - } // namespace AST } // namespace Rust diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc new file mode 100644 index 0000000..9a3489b --- /dev/null +++ b/gcc/rust/ast/rust-path.cc @@ -0,0 +1,360 @@ +/* General AST-related method implementations for Rust frontend. + Copyright (C) 2009-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/>. */ + +#include "rust-system.h" +#include "rust-ast-full.h" +#include "rust-diagnostics.h" +#include "rust-ast-visitor.h" +#include "rust-macro.h" +#include "rust-session-manager.h" +#include "rust-lex.h" +#include "rust-parse.h" +#include "rust-operators.h" + +namespace Rust { +namespace AST { + +std::string +GenericArgs::as_string () const +{ + std::string args; + + // lifetime args + if (!lifetime_args.empty ()) + { + auto i = lifetime_args.begin (); + auto e = lifetime_args.end (); + + for (; i != e; i++) + { + args += (*i).as_string (); + if (e != i + 1) + args += ", "; + } + } + + // type args + if (!generic_args.empty ()) + { + auto i = generic_args.begin (); + auto e = generic_args.end (); + + for (; i != e; i++) + { + args += (*i).as_string (); + if (e != i + 1) + args += ", "; + } + } + + // binding args + if (!binding_args.empty ()) + { + auto i = binding_args.begin (); + auto e = binding_args.end (); + + for (; i != e; i++) + { + args += (*i).as_string (); + if (e != i + 1) + args += ", "; + } + } + + return args; +} + +GenericArg +GenericArg::disambiguate_to_const () const +{ + rust_assert (get_kind () == Kind::Either); + + // FIXME: is it fine to have no outer attributes? + return GenericArg::create_const ( + std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus))); +} + +GenericArg +GenericArg::disambiguate_to_type () const +{ + rust_assert (get_kind () == Kind::Either); + + auto segment = std::unique_ptr<TypePathSegment> ( + new TypePathSegment (path, false, locus)); + auto segments = std::vector<std::unique_ptr<TypePathSegment>> (); + segments.emplace_back (std::move (segment)); + + return GenericArg::create_type ( + std::unique_ptr<Type> (new TypePath (std::move (segments), locus))); +} + +std::string +GenericArgsBinding::as_string () const +{ + // TODO: rewrite to work with non-literalisable types + return identifier + " = " + type->as_string (); +} + +std::string +ConstGenericParam::as_string () const +{ + std::string str ("ConstGenericParam: "); + str += "const " + name + ": " + type->as_string (); + + if (has_default_value ()) + str += " = " + get_default_value ().as_string (); + + return str; +} + +std::string +PathExprSegment::as_string () const +{ + // TODO: rewrite dump to work with non-literalisable types + std::string ident_str = segment_name.as_string (); + if (has_generic_args ()) + ident_str += "::<" + generic_args.as_string () + ">"; + + return ident_str; +} + +std::string +PathPattern::as_string () const +{ + std::string str; + + for (const auto &segment : segments) + str += segment.as_string () + "::"; + + // basically a hack - remove last two characters of string (remove final ::) + str.erase (str.length () - 2); + + return str; +} + +SimplePath +PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const +{ + if (!has_segments ()) + return SimplePath::create_empty (); + + // create vector of reserved size (to minimise reallocations) + std::vector<SimplePathSegment> simple_segments; + simple_segments.reserve (segments.size ()); + + for (const auto &segment : segments) + { + // return empty path if doesn't meet simple path segment requirements + if (segment.is_error () || segment.has_generic_args () + || segment.as_string () == "Self") + return SimplePath::create_empty (); + + // create segment and add to vector + std::string segment_str = segment.as_string (); + simple_segments.push_back ( + SimplePathSegment (std::move (segment_str), segment.get_locus ())); + } + + // kind of a HACK to get locus depending on opening scope resolution + Location locus = Linemap::unknown_location (); + if (with_opening_scope_resolution) + locus = simple_segments[0].get_locus () - 2; // minus 2 chars for :: + else + locus = simple_segments[0].get_locus (); + // FIXME: this hack probably doesn't actually work + + return SimplePath (std::move (simple_segments), with_opening_scope_resolution, + locus); +} + +void +PathInExpression::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +std::string +PathInExpression::as_string () const +{ + std::string str; + + if (has_opening_scope_resolution) + str = "::"; + + return str + PathPattern::as_string (); +} + +std::string +TypePathSegmentGeneric::as_string () const +{ + // TODO: rewrite to work with non-linearisable types + return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">"; +} + +std::string +TypePathSegmentFunction::as_string () const +{ + // TODO: rewrite to work with non-linearisable types + return TypePathSegment::as_string () + function_path.as_string (); +} + +std::string +TypePath::as_string () const +{ + /* TODO: this may need to be rewritten if a segment (e.g. function) can't be + * literalised */ + std::string str; + + if (has_opening_scope_resolution) + str = "::"; + + for (const auto &segment : segments) + str += segment->as_string () + "::"; + + // kinda hack - remove last 2 '::' characters + str.erase (str.length () - 2); + + return str; +} + +SimplePath +TypePath::as_simple_path () const +{ + if (segments.empty ()) + return SimplePath::create_empty (); + + // create vector of reserved size (to minimise reallocations) + std::vector<SimplePathSegment> simple_segments; + simple_segments.reserve (segments.size ()); + + for (const auto &segment : segments) + { + // return empty path if doesn't meet simple path segment requirements + if (segment == nullptr || segment->is_error () + || !segment->is_ident_only () || segment->as_string () == "Self") + return SimplePath::create_empty (); + + // create segment and add to vector + std::string segment_str = segment->as_string (); + simple_segments.push_back ( + SimplePathSegment (std::move (segment_str), segment->get_locus ())); + } + + return SimplePath (std::move (simple_segments), has_opening_scope_resolution, + locus); +} + +// hopefully definition here will prevent circular dependency issue +TraitBound * +TypePath::to_trait_bound (bool in_parens) const +{ + return new TraitBound (TypePath (*this), get_locus (), in_parens); +} + +std::string +TypePathFunction::as_string () const +{ + // TODO: rewrite to work with non-linearisable types + std::string str ("("); + + if (has_inputs ()) + { + auto i = inputs.begin (); + auto e = inputs.end (); + + for (; i != e; i++) + { + str += (*i)->as_string (); + if (e != i + 1) + str += ", "; + } + } + + str += ")"; + + if (has_return_type ()) + str += " -> " + return_type->as_string (); + + return str; +} + +std::string +QualifiedPathInExpression::as_string () const +{ + return path_type.as_string () + "::" + PathPattern::as_string (); +} + +std::string +QualifiedPathInType::as_string () const +{ + /* TODO: this may need adjusting if segments (e.g. with functions) can't be + * literalised */ + std::string str = path_type.as_string (); + + str += "::" + associated_segment->as_string (); + for (const auto &segment : segments) + str += "::" + segment->as_string (); + + return str; +} + +void +ConstGenericParam::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePathSegment::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePathSegmentGeneric::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePathSegmentFunction::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePath::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInExpression::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInType::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +} // namespace AST +} // namespace Rust |