diff options
Diffstat (limited to 'gcc/rust/ast')
31 files changed, 2815 insertions, 686 deletions
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index ed10ce7..632f945 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -554,12 +554,12 @@ std::unique_ptr<GenericParam> Builder::new_lifetime_param (LifetimeParam ¶m) { Lifetime l = new_lifetime (param.get_lifetime ()); + std::vector<Lifetime> lifetime_bounds; + lifetime_bounds.reserve (param.get_lifetime_bounds ().size ()); + for (auto b : param.get_lifetime_bounds ()) - { - Lifetime bl = new_lifetime (b); - lifetime_bounds.push_back (bl); - } + lifetime_bounds.emplace_back (new_lifetime (b)); auto p = new LifetimeParam (l, std::move (lifetime_bounds), param.get_outer_attrs (), param.get_locus ()); @@ -605,11 +605,11 @@ Builder::new_type_param ( for (const auto &lifetime : tb.get_for_lifetimes ()) { std::vector<Lifetime> lifetime_bounds; + lifetime_bounds.reserve ( + lifetime.get_lifetime_bounds ().size ()); + for (const auto &b : lifetime.get_lifetime_bounds ()) - { - Lifetime bl = new_lifetime (b); - lifetime_bounds.push_back (std::move (bl)); - } + lifetime_bounds.emplace_back (new_lifetime (b)); Lifetime nl = new_lifetime (lifetime.get_lifetime ()); LifetimeParam p (std::move (nl), std::move (lifetime_bounds), @@ -626,12 +626,11 @@ Builder::new_type_param ( { const TypePathSegment &segment = (const TypePathSegment &) (*seg.get ()); - TypePathSegment *s = new TypePathSegment ( + + segments.emplace_back (new TypePathSegment ( segment.get_ident_segment (), segment.get_separating_scope_resolution (), - segment.get_locus ()); - std::unique_ptr<TypePathSegment> sg (s); - segments.push_back (std::move (sg)); + segment.get_locus ())); } break; @@ -642,11 +641,10 @@ Builder::new_type_param ( GenericArgs args = new_generic_args (generic.get_generic_args ()); - TypePathSegmentGeneric *s = new TypePathSegmentGeneric ( + + segments.emplace_back (new TypePathSegmentGeneric ( generic.get_ident_segment (), false, std::move (args), - generic.get_locus ()); - std::unique_ptr<TypePathSegment> sg (s); - segments.push_back (std::move (sg)); + generic.get_locus ())); } break; @@ -664,12 +662,9 @@ Builder::new_type_param ( TypePath p (std::move (segments), path.get_locus (), path.has_opening_scope_resolution_op ()); - TraitBound *b = new TraitBound (std::move (p), tb.get_locus (), - tb.is_in_parens (), - tb.has_opening_question_mark (), - std::move (for_lifetimes)); - std::unique_ptr<TypeParamBound> bound (b); - type_param_bounds.push_back (std::move (bound)); + type_param_bounds.emplace_back (new TraitBound ( + std::move (p), tb.get_locus (), tb.is_in_parens (), + tb.has_opening_question_mark (), std::move (for_lifetimes))); } break; @@ -677,10 +672,9 @@ Builder::new_type_param ( { const Lifetime &l = (const Lifetime &) *b.get (); - auto bl = new Lifetime (l.get_lifetime_type (), - l.get_lifetime_name (), l.get_locus ()); - std::unique_ptr<TypeParamBound> bound (bl); - type_param_bounds.push_back (std::move (bound)); + type_param_bounds.emplace_back ( + new Lifetime (l.get_lifetime_type (), l.get_lifetime_name (), + l.get_locus ())); } break; } @@ -709,18 +703,14 @@ Builder::new_generic_args (GenericArgs &args) location_t locus = args.get_locus (); for (const auto &lifetime : args.get_lifetime_args ()) - { - Lifetime l = new_lifetime (lifetime); - lifetime_args.push_back (std::move (l)); - } + lifetime_args.push_back (new_lifetime (lifetime)); for (auto &binding : args.get_binding_args ()) { Type &t = *binding.get_type_ptr ().get (); std::unique_ptr<Type> ty = t.reconstruct (); - GenericArgsBinding b (binding.get_identifier (), std::move (ty), - binding.get_locus ()); - binding_args.push_back (std::move (b)); + binding_args.emplace_back (binding.get_identifier (), std::move (ty), + binding.get_locus ()); } for (auto &arg : args.get_generic_args ()) diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 3d9ea78..721d274 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -76,13 +76,13 @@ TokenCollector::trailing_comma () void TokenCollector::newline () { - tokens.push_back ({CollectItem::Kind::Newline}); + tokens.emplace_back (CollectItem::Kind::Newline); } void TokenCollector::indentation () { - tokens.push_back ({indent_level}); + tokens.emplace_back (indent_level); } void @@ -101,7 +101,7 @@ TokenCollector::decrement_indentation () void TokenCollector::comment (std::string comment) { - tokens.push_back ({comment}); + tokens.emplace_back (comment); } void @@ -355,7 +355,8 @@ TokenCollector::visit (MaybeNamedParam ¶m) void TokenCollector::visit (Token &tok) { - std::string data = tok.get_tok_ptr ()->has_str () ? tok.get_str () : ""; + std::string data + = tok.get_tok_ptr ()->should_have_str () ? tok.get_str () : ""; switch (tok.get_id ()) { case IDENTIFIER: @@ -2171,19 +2172,6 @@ TokenCollector::visit (SelfParam ¶m) } void -TokenCollector::visit (TraitItemConst &item) -{ - auto id = item.get_identifier ().as_string (); - indentation (); - push (Rust::Token::make (CONST, item.get_locus ())); - push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); - push (Rust::Token::make (COLON, UNDEF_LOCATION)); - visit (item.get_type ()); - push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); - newline (); -} - -void TokenCollector::visit (TraitItemType &item) { visit_items_as_lines (item.get_outer_attrs ()); @@ -2632,7 +2620,7 @@ TokenCollector::visit (StructPattern &pattern) if (elems.has_struct_pattern_fields ()) { visit_items_joined_by_separator (elems.get_struct_pattern_fields ()); - if (elems.has_etc ()) + if (elems.has_rest ()) { push (Rust::Token::make (COMMA, UNDEF_LOCATION)); visit_items_as_lines (elems.get_etc_outer_attrs ()); @@ -2649,13 +2637,13 @@ TokenCollector::visit (StructPattern &pattern) // void TokenCollector::visit(TupleStructItems& ){} void -TokenCollector::visit (TupleStructItemsNoRange &pattern) +TokenCollector::visit (TupleStructItemsNoRest &pattern) { visit_items_joined_by_separator (pattern.get_patterns ()); } void -TokenCollector::visit (TupleStructItemsRange &pattern) +TokenCollector::visit (TupleStructItemsHasRest &pattern) { for (auto &lower : pattern.get_lower_patterns ()) { @@ -2682,13 +2670,13 @@ TokenCollector::visit (TupleStructPattern &pattern) // {} void -TokenCollector::visit (TuplePatternItemsMultiple &pattern) +TokenCollector::visit (TuplePatternItemsNoRest &pattern) { visit_items_joined_by_separator (pattern.get_patterns (), COMMA); } void -TokenCollector::visit (TuplePatternItemsRanged &pattern) +TokenCollector::visit (TuplePatternItemsHasRest &pattern) { for (auto &lower : pattern.get_lower_patterns ()) { @@ -3009,8 +2997,216 @@ TokenCollector::visit (BareFunctionType &type) void TokenCollector::visit (AST::FormatArgs &fmt) { - rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor", - __FILE__, __LINE__); + push (Rust::Token::make_identifier (fmt.get_locus (), "format_args")); + push (Rust::Token::make (EXCLAM, fmt.get_locus ())); + push (Rust::Token::make (LEFT_PAREN, fmt.get_locus ())); + + std::string reconstructed_template = "\""; + const auto &template_pieces = fmt.get_template (); + + for (const auto &piece : template_pieces.get_pieces ()) + { + if (piece.tag == Fmt::ffi::Piece::Tag::String) + { + std::string literal = piece.string._0.to_string (); + for (char c : literal) + { + if (c == '"' || c == '\\') + { + reconstructed_template += '\\'; + } + else if (c == '\n') + { + reconstructed_template += "\\n"; + continue; + } + else if (c == '\r') + { + reconstructed_template += "\\r"; + continue; + } + else if (c == '\t') + { + reconstructed_template += "\\t"; + continue; + } + reconstructed_template += c; + } + } + else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument) + { + reconstructed_template += "{"; + + const auto &argument = piece.next_argument._0; + const auto &position = argument.position; + + switch (position.tag) + { + case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs: + break; + case Fmt::ffi::Position::Tag::ArgumentIs: + reconstructed_template + += std::to_string (position.argument_is._0); + break; + case Fmt::ffi::Position::Tag::ArgumentNamed: + reconstructed_template += position.argument_named._0.to_string (); + break; + } + + // Add format specifiers if any (like :?, :x, etc.) + const auto &format_spec = argument.format; + + bool has_format_spec = false; + std::string format_part; + + // For now, skipping the complex format specifications that use FFIOpt + // since FFIOpt::get_opt() has a bug. + + // Alignment + if (format_spec.align != Fmt::ffi::Alignment::AlignUnknown) + { + has_format_spec = true; + switch (format_spec.align) + { + case Fmt::ffi::Alignment::AlignLeft: + format_part += "<"; + break; + case Fmt::ffi::Alignment::AlignRight: + format_part += ">"; + break; + case Fmt::ffi::Alignment::AlignCenter: + format_part += "^"; + break; + case Fmt::ffi::Alignment::AlignUnknown: + break; + } + } + + // Alternate flag + if (format_spec.alternate) + { + has_format_spec = true; + format_part += "#"; + } + + // Zero pad flag + if (format_spec.zero_pad) + { + has_format_spec = true; + format_part += "0"; + } + + // Width + if (format_spec.width.tag != Fmt::ffi::Count::Tag::CountImplied) + { + has_format_spec = true; + switch (format_spec.width.tag) + { + case Fmt::ffi::Count::Tag::CountIs: + format_part += std::to_string (format_spec.width.count_is._0); + break; + case Fmt::ffi::Count::Tag::CountIsParam: + format_part + += std::to_string (format_spec.width.count_is_param._0) + + "$"; + break; + case Fmt::ffi::Count::Tag::CountIsName: + format_part + += format_spec.width.count_is_name._0.to_string () + "$"; + break; + case Fmt::ffi::Count::Tag::CountIsStar: + format_part += "*"; + break; + case Fmt::ffi::Count::Tag::CountImplied: + break; + } + } + + // Precision + if (format_spec.precision.tag != Fmt::ffi::Count::Tag::CountImplied) + { + has_format_spec = true; + format_part += "."; + switch (format_spec.precision.tag) + { + case Fmt::ffi::Count::Tag::CountIs: + format_part + += std::to_string (format_spec.precision.count_is._0); + break; + case Fmt::ffi::Count::Tag::CountIsParam: + format_part + += std::to_string (format_spec.precision.count_is_param._0) + + "$"; + break; + case Fmt::ffi::Count::Tag::CountIsName: + format_part + += format_spec.precision.count_is_name._0.to_string () + + "$"; + break; + case Fmt::ffi::Count::Tag::CountIsStar: + format_part += "*"; + break; + case Fmt::ffi::Count::Tag::CountImplied: + break; + } + } + + // Type/trait (like ?, x, X, etc.) + std::string type_str = format_spec.ty.to_string (); + if (!type_str.empty ()) + { + has_format_spec = true; + format_part += type_str; + } + + // Add the format specification if any + if (has_format_spec) + { + reconstructed_template += ":"; + reconstructed_template += format_part; + } + + reconstructed_template += "}"; + } + } + reconstructed_template += "\""; + + push (Rust::Token::make_string (fmt.get_locus (), reconstructed_template)); + + // Visit format arguments if any exist + auto &arguments = fmt.get_arguments (); + if (!arguments.empty ()) + { + push (Rust::Token::make (COMMA, fmt.get_locus ())); + + auto &args = arguments.get_args (); + for (size_t i = 0; i < args.size (); ++i) + { + if (i > 0) + { + push (Rust::Token::make (COMMA, fmt.get_locus ())); + } + + auto kind = args[i].get_kind (); + + // Handle named arguments: name = expr + if (kind.kind == FormatArgumentKind::Kind::Named) + { + auto ident = kind.get_ident ().as_string (); + push (Rust::Token::make_identifier (fmt.get_locus (), + std::move (ident))); + push (Rust::Token::make (EQUAL, fmt.get_locus ())); + } + // Note: Captured arguments are handled implicitly in the template + // reconstruction They don't need explicit "name =" syntax in the + // reconstructed macro call + + auto &expr = args[i].get_expr (); + expr.accept_vis (*this); + } + } + + push (Rust::Token::make (RIGHT_PAREN, fmt.get_locus ())); } void diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h index d3ab18a..3e33476 100644 --- a/gcc/rust/ast/rust-ast-collector.h +++ b/gcc/rust/ast/rust-ast-collector.h @@ -330,7 +330,6 @@ public: void visit (ConstantItem &const_item); void visit (StaticItem &static_item); void visit (SelfParam ¶m); - void visit (TraitItemConst &item); void visit (TraitItemType &item); void visit (Trait &trait); void visit (InherentImpl &impl); @@ -370,12 +369,12 @@ public: void visit (StructPatternFieldIdent &field); void visit (StructPattern &pattern); // void visit(TupleStructItems& tuple_items); - void visit (TupleStructItemsNoRange &tuple_items); - void visit (TupleStructItemsRange &tuple_items); + void visit (TupleStructItemsNoRest &tuple_items); + void visit (TupleStructItemsHasRest &tuple_items); void visit (TupleStructPattern &pattern); // void visit(TuplePatternItems& tuple_items); - void visit (TuplePatternItemsMultiple &tuple_items); - void visit (TuplePatternItemsRanged &tuple_items); + void visit (TuplePatternItemsNoRest &tuple_items); + void visit (TuplePatternItemsHasRest &tuple_items); void visit (TuplePattern &pattern); void visit (GroupedPattern &pattern); void visit (SlicePatternItemsNoRest &items); diff --git a/gcc/rust/ast/rust-ast-formatting.h b/gcc/rust/ast/rust-ast-formatting.h index aace93f..075c51c 100644 --- a/gcc/rust/ast/rust-ast-formatting.h +++ b/gcc/rust/ast/rust-ast-formatting.h @@ -19,6 +19,9 @@ #ifndef RUST_AST_FORMATTING_H #define RUST_AST_FORMATTING_H +#include "rust-ast.h" +#include "rust-system.h" + namespace Rust { namespace AST { diff --git a/gcc/rust/ast/rust-ast-fragment.cc b/gcc/rust/ast/rust-ast-fragment.cc index 076cab3..8a547b4 100644 --- a/gcc/rust/ast/rust-ast-fragment.cc +++ b/gcc/rust/ast/rust-ast-fragment.cc @@ -107,29 +107,42 @@ Fragment::should_expand () const bool Fragment::is_expression_fragment () const { - return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION); + return is_single_fragment_of_kind (SingleASTNode::Kind::Expr); } bool Fragment::is_type_fragment () const { - return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE); + return is_single_fragment_of_kind (SingleASTNode::Kind::Type); +} + +bool +Fragment::is_pattern_fragment () const +{ + return is_single_fragment_of_kind (SingleASTNode::Kind::Pattern); } std::unique_ptr<Expr> Fragment::take_expression_fragment () { - assert_single_fragment (SingleASTNode::NodeType::EXPRESSION); + assert_single_fragment (SingleASTNode::Kind::Expr); return nodes[0].take_expr (); } std::unique_ptr<Type> Fragment::take_type_fragment () { - assert_single_fragment (SingleASTNode::NodeType::TYPE); + assert_single_fragment (SingleASTNode::Kind::Type); return nodes[0].take_type (); } +std::unique_ptr<Pattern> +Fragment::take_pattern_fragment () +{ + assert_single_fragment (SingleASTNode::Kind::Pattern); + return nodes[0].take_pattern (); +} + void Fragment::accept_vis (ASTVisitor &vis) { @@ -144,21 +157,22 @@ Fragment::is_single_fragment () const } bool -Fragment::is_single_fragment_of_kind (SingleASTNode::NodeType expected) const +Fragment::is_single_fragment_of_kind (SingleASTNode::Kind expected) const { return is_single_fragment () && nodes[0].get_kind () == expected; } void -Fragment::assert_single_fragment (SingleASTNode::NodeType expected) const -{ - static const std::map<SingleASTNode::NodeType, const char *> str_map = { - {SingleASTNode::NodeType::ASSOC_ITEM, "associated item"}, - {SingleASTNode::NodeType::ITEM, "item"}, - {SingleASTNode::NodeType::TYPE, "type"}, - {SingleASTNode::NodeType::EXPRESSION, "expr"}, - {SingleASTNode::NodeType::STMT, "stmt"}, - {SingleASTNode::NodeType::EXTERN, "extern"}, +Fragment::assert_single_fragment (SingleASTNode::Kind expected) const +{ + static const std::map<SingleASTNode::Kind, const char *> str_map = { + {SingleASTNode::Kind::Assoc, "associated item"}, + {SingleASTNode::Kind::Item, "item"}, + {SingleASTNode::Kind::Type, "type"}, + {SingleASTNode::Kind::Expr, "expr"}, + {SingleASTNode::Kind::Stmt, "stmt"}, + {SingleASTNode::Kind::Extern, "extern"}, + {SingleASTNode::Kind::Pattern, "pattern"}, }; auto actual = nodes[0].get_kind (); diff --git a/gcc/rust/ast/rust-ast-fragment.h b/gcc/rust/ast/rust-ast-fragment.h index 7d01fd7..23f26d3 100644 --- a/gcc/rust/ast/rust-ast-fragment.h +++ b/gcc/rust/ast/rust-ast-fragment.h @@ -86,9 +86,11 @@ public: bool is_expression_fragment () const; bool is_type_fragment () const; + bool is_pattern_fragment () const; std::unique_ptr<Expr> take_expression_fragment (); std::unique_ptr<Type> take_type_fragment (); + std::unique_ptr<Pattern> take_pattern_fragment (); void accept_vis (ASTVisitor &vis); @@ -119,8 +121,8 @@ private: * one Node will be extracted from the `nodes` vector */ bool is_single_fragment () const; - bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const; - void assert_single_fragment (SingleASTNode::NodeType expected) const; + bool is_single_fragment_of_kind (SingleASTNode::Kind expected) const; + void assert_single_fragment (SingleASTNode::Kind expected) const; }; enum class InvocKind diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h index 09706ce..2903ba7 100644 --- a/gcc/rust/ast/rust-ast-full-decls.h +++ b/gcc/rust/ast/rust-ast-full-decls.h @@ -195,7 +195,6 @@ class Enum; class Union; class ConstantItem; class StaticItem; -class TraitItemConst; class TraitItemType; class Trait; class Impl; @@ -240,12 +239,12 @@ class StructPatternFieldIdent; class StructPatternElements; class StructPattern; class TupleStructItems; -class TupleStructItemsNoRange; -class TupleStructItemsRange; +class TupleStructItemsNoRest; +class TupleStructItemsHasRest; class TupleStructPattern; class TuplePatternItems; -class TuplePatternItemsMultiple; -class TuplePatternItemsRanged; +class TuplePatternItemsNoRest; +class TuplePatternItemsHasRest; class TuplePattern; class GroupedPattern; class SlicePatternItemsNoRest; diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.cc b/gcc/rust/ast/rust-ast-pointer-visitor.cc new file mode 100644 index 0000000..ee1f001 --- /dev/null +++ b/gcc/rust/ast/rust-ast-pointer-visitor.cc @@ -0,0 +1,1475 @@ +// Copyright (C) 2025 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-ast-pointer-visitor.h" +#include "rust-ast-visitor.h" +#include "rust-ast-full.h" + +namespace Rust { +namespace AST { + +void +PointerVisitor::visit (AST::Crate &crate) +{ + visit_inner_attrs (crate); + for (auto &item : crate.items) + reseat (item); +} + +void +PointerVisitor::visit (AST::AttrInputMetaItemContainer &input) +{ + // FIXME: I think we might actually have to reseat sub-items for macro + // invocations within attributes correct? + + for (auto &item : input.get_items ()) + visit (item); +} + +void +PointerVisitor::visit (AST::IdentifierExpr &ident_expr) +{ + visit_outer_attrs (ident_expr); +} + +void +PointerVisitor::visit (AST::LifetimeParam &lifetime_param) +{ + visit_outer_attrs (lifetime_param); + + // Nothing to do for lifetimes right? +} + +void +PointerVisitor::visit (AST::ConstGenericParam &const_param) +{ + visit_outer_attrs (const_param); + if (const_param.has_type ()) + reseat (const_param.get_type_ptr ()); + + if (const_param.has_default_value ()) + visit (const_param.get_default_value_unchecked ()); +} + +void +PointerVisitor::visit (AST::PathInExpression &path) +{ + visit_outer_attrs (path); + + if (!path.is_lang_item ()) + for (auto &segment : path.get_segments ()) + visit (segment); +} + +void +PointerVisitor::visit (GenericArgsBinding &binding) +{ + reseat (binding.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::TypePathSegmentGeneric &segment) +{ + if (segment.has_generic_args ()) + visit (segment.get_generic_args ()); +} + +void +PointerVisitor::visit (AST::TypePathFunction &tpf) +{ + for (auto &input : tpf.get_params ()) + reseat (input); + if (tpf.has_return_type ()) + reseat (tpf.get_return_type_ptr ()); +} + +void +PointerVisitor::visit (AST::TypePathSegmentFunction &segment) +{ + // FIXME: No reseating here correct? No macros possible or desugar? + visit (segment.get_type_path_function ()); + visit (segment.get_ident_segment ()); +} + +void +PointerVisitor::visit (AST::GenericArgs &args) +{ + // Nothing to do for lifetimes? + // for (auto &lifetime : args.get_lifetime_args ()) + // reseat (lifetime); + + // FIXME: Actually this can probably be a macro invocation, so we need to + // reseat them? + for (auto &generic : args.get_generic_args ()) + visit (generic); + + for (auto &binding : args.get_binding_args ()) + visit (binding); +} + +void +PointerVisitor::visit (AST::PathExprSegment &segment) +{ + visit (segment.get_ident_segment ()); + if (segment.has_generic_args ()) + visit (segment.get_generic_args ()); +} +void +PointerVisitor::visit (AST::TypePath &path) +{ + for (auto &segment : path.get_segments ()) + visit (segment); +} + +void +PointerVisitor::visit (AST::QualifiedPathInExpression &path) +{ + visit_outer_attrs (path); + visit (path.get_qualified_path_type ()); + + for (auto &segment : path.get_segments ()) + visit (segment); +} + +void +PointerVisitor::visit (AST::QualifiedPathType &path) +{ + reseat (path.get_type_ptr ()); + if (path.has_as_clause ()) + visit (path.get_as_type_path ()); +} + +void +PointerVisitor::visit (AST::QualifiedPathInType &path) +{ + visit (path.get_qualified_path_type ()); + visit (path.get_associated_segment ()); + + for (auto &segment : path.get_segments ()) + visit (segment); +} + +void +PointerVisitor::visit (AST::LiteralExpr &expr) +{ + visit_outer_attrs (expr); +} + +void +PointerVisitor::visit (AST::AttrInputLiteral &attr_input) +{ + visit (attr_input.get_literal ()); +} + +void +PointerVisitor::visit (AST::AttrInputMacro &attr_input) +{ + visit (attr_input.get_macro ()); +} + +void +PointerVisitor::visit (AST::MetaItemLitExpr &meta_item) +{ + visit (meta_item.get_literal ()); +} + +void +PointerVisitor::visit (AST::SimplePath &path) +{ + for (auto &segment : path.get_segments ()) + visit (segment); +} + +void +PointerVisitor::visit (AST::MetaItemPathExpr &meta_item) +{ + visit (meta_item.get_path ()); + reseat (meta_item.get_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::BorrowExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_borrowed_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::DereferenceExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_dereferenced_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ErrorPropagationExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_propagating_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::NegationExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_negated_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ArithmeticOrLogicalExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_left_expr_ptr ()); + reseat (expr.get_right_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ComparisonExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_left_expr_ptr ()); + reseat (expr.get_right_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::LazyBooleanExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_left_expr_ptr ()); + reseat (expr.get_right_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::TypeCastExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_casted_expr_ptr ()); + reseat (expr.get_type_to_cast_to_ptr ()); +} + +void +PointerVisitor::visit (AST::AssignmentExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_left_expr_ptr ()); + reseat (expr.get_right_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::CompoundAssignmentExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_left_expr_ptr ()); + reseat (expr.get_right_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::GroupedExpr &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + reseat (expr.get_expr_in_parens_ptr ()); +} + +void +PointerVisitor::visit (AST::ArrayElemsValues &elems) +{ + for (auto &value : elems.get_values ()) + reseat (value); +} + +void +PointerVisitor::visit (AST::ArrayElemsCopied &elems) +{ + reseat (elems.get_elem_to_copy_ptr ()); + reseat (elems.get_num_copies_ptr ()); +} + +void +PointerVisitor::visit (AST::ArrayExpr &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + visit (expr.get_array_elems ()); +} + +void +PointerVisitor::visit (AST::ArrayIndexExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_array_expr_ptr ()); + reseat (expr.get_index_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::TupleExpr &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + for (auto &elem : expr.get_tuple_elems ()) + reseat (elem); +} + +void +PointerVisitor::visit (AST::TupleIndexExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_tuple_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::StructExprStruct &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + visit (expr.get_struct_name ()); +} + +void +PointerVisitor::visit (AST::StructExprFieldIdentifier &field) +{} + +void +PointerVisitor::visit (AST::StructExprFieldIdentifierValue &field) +{ + reseat (field.get_value_ptr ()); +} + +void +PointerVisitor::visit (AST::StructExprFieldIndexValue &field) +{ + reseat (field.get_value_ptr ()); +} + +void +PointerVisitor::visit (AST::StructBase &base) +{ + reseat (base.get_base_struct_ptr ()); +} + +void +PointerVisitor::visit (AST::StructExprStructFields &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + visit (expr.get_struct_name ()); + if (expr.has_struct_base ()) + visit (expr.get_struct_base ()); + for (auto &field : expr.get_fields ()) + visit (field); +} + +void +PointerVisitor::visit (AST::StructExprStructBase &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + visit (expr.get_struct_name ()); + visit (expr.get_struct_base ()); +} + +void +PointerVisitor::visit (AST::CallExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_function_expr_ptr ()); + for (auto ¶m : expr.get_params ()) + reseat (param); +} + +void +PointerVisitor::visit (AST::MethodCallExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_receiver_expr_ptr ()); + visit (expr.get_method_name ()); + for (auto ¶m : expr.get_params ()) + reseat (param); +} + +void +PointerVisitor::visit (AST::FieldAccessExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_receiver_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ClosureExprInner &expr) +{ + visit_outer_attrs (expr); + + // TODO: Actually we need to handle macro invocations as closure parameters so + // this needs to be a reseat + for (auto ¶m : expr.get_params ()) + visit (param); + + reseat (expr.get_definition_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::BlockExpr &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + + if (expr.has_label ()) + visit (expr.get_label ()); + + for (auto &stmt : expr.get_statements ()) + reseat (stmt); + + if (expr.has_tail_expr ()) + reseat (expr.get_tail_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ConstBlock &expr) +{ + visit (expr.get_const_expr ()); +} + +void +PointerVisitor::visit (AST::AnonConst &expr) +{ + if (!expr.is_deferred ()) + reseat (expr.get_inner_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ClosureExprInnerTyped &expr) +{ + visit_outer_attrs (expr); + + // TODO: Same as ClosureExprInner + for (auto ¶m : expr.get_params ()) + visit (param); + + reseat (expr.get_return_type_ptr ()); + + reseat (expr.get_definition_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ClosureParam ¶m) +{ + visit_outer_attrs (param); + reseat (param.get_pattern_ptr ()); + if (param.has_type_given ()) + reseat (param.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::ContinueExpr &expr) +{ + visit_outer_attrs (expr); + if (expr.has_label ()) + visit (expr.get_label_unchecked ()); +} + +void +PointerVisitor::visit (AST::BreakExpr &expr) +{ + visit_outer_attrs (expr); + if (expr.has_label ()) + visit (expr.get_label_unchecked ()); + + if (expr.has_break_expr ()) + reseat (expr.get_break_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::RangeFromToExpr &expr) +{ + reseat (expr.get_from_expr_ptr ()); + reseat (expr.get_to_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::RangeFromExpr &expr) +{ + reseat (expr.get_from_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::RangeToExpr &expr) +{ + reseat (expr.get_to_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::RangeFullExpr &expr) +{} + +void +PointerVisitor::visit (AST::RangeFromToInclExpr &expr) +{ + reseat (expr.get_from_expr_ptr ()); + reseat (expr.get_to_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::RangeToInclExpr &expr) +{ + reseat (expr.get_to_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ReturnExpr &expr) +{ + visit_outer_attrs (expr); + if (expr.has_returned_expr ()) + reseat (expr.get_returned_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::TryExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_block_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::BoxExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_boxed_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::UnsafeBlockExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_block_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::LoopLabel &label) +{ + visit (label.get_lifetime ()); +} + +void +PointerVisitor::visit (AST::LoopExpr &expr) +{ + visit_outer_attrs (expr); + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); + reseat (expr.get_loop_block_ptr ()); +} + +void +PointerVisitor::visit (AST::WhileLoopExpr &expr) +{ + visit_outer_attrs (expr); + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); + reseat (expr.get_predicate_expr_ptr ()); + reseat (expr.get_loop_block_ptr ()); +} + +void +PointerVisitor::visit (AST::WhileLetLoopExpr &expr) +{ + visit_outer_attrs (expr); + for (auto &pattern : expr.get_patterns ()) + reseat (pattern); + + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); + + reseat (expr.get_scrutinee_expr_ptr ()); + reseat (expr.get_loop_block_ptr ()); +} + +void +PointerVisitor::visit (AST::ForLoopExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_pattern_ptr ()); + reseat (expr.get_iterator_expr_ptr ()); + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); + reseat (expr.get_loop_block_ptr ()); +} + +void +PointerVisitor::visit (AST::IfExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_condition_expr_ptr ()); + visit (expr.get_if_block ()); +} + +void +PointerVisitor::visit (AST::IfExprConseqElse &expr) +{ + visit (reinterpret_cast<AST::IfExpr &> (expr)); + visit (expr.get_else_block ()); +} + +void +PointerVisitor::visit (AST::IfLetExpr &expr) +{ + visit_outer_attrs (expr); + for (auto &pattern : expr.get_patterns ()) + reseat (pattern); + reseat (expr.get_value_expr_ptr ()); + visit (expr.get_if_block ()); +} + +void +PointerVisitor::visit (AST::IfLetExprConseqElse &expr) +{ + visit (reinterpret_cast<AST::IfLetExpr &> (expr)); + visit (expr.get_else_block ()); +} + +void +PointerVisitor::visit (AST::MatchArm &arm) +{ + visit_outer_attrs (arm); + for (auto &pattern : arm.get_patterns ()) + reseat (pattern); + if (arm.has_match_arm_guard ()) + reseat (arm.get_guard_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::MatchCase &arm) +{ + visit (arm.get_arm ()); + reseat (arm.get_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::MatchExpr &expr) +{ + visit_outer_attrs (expr); + visit_inner_attrs (expr); + reseat (expr.get_scrutinee_expr_ptr ()); + for (auto &arm : expr.get_match_cases ()) + visit (arm); +} + +void +PointerVisitor::visit (AST::AwaitExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_awaited_expr ()); +} + +void +PointerVisitor::visit (AST::AsyncBlockExpr &expr) +{ + visit_outer_attrs (expr); + reseat (expr.get_block_expr ()); +} + +void +PointerVisitor::visit (AST::InlineAsm &expr) +{ + visit_outer_attrs (expr); + using RegisterType = AST::InlineAsmOperand::RegisterType; + for (auto &operand : expr.get_operands ()) + { + switch (operand.get_register_type ()) + { + case RegisterType::In: + { + reseat (operand.get_in ().expr); + break; + } + case RegisterType::Out: + { + reseat (operand.get_out ().expr); + break; + } + case RegisterType::InOut: + { + reseat (operand.get_in_out ().expr); + break; + } + case RegisterType::SplitInOut: + { + auto split = operand.get_split_in_out (); + reseat (split.in_expr); + reseat (split.out_expr); + break; + } + case RegisterType::Const: + { + reseat (operand.get_const ().anon_const.get_inner_expr_ptr ()); + break; + } + case RegisterType::Sym: + { + reseat (operand.get_sym ().expr); + break; + } + case RegisterType::Label: + { + reseat (operand.get_label ().expr); + break; + } + } + } +} + +void +PointerVisitor::visit (AST::LlvmInlineAsm &expr) +{ + for (auto &output : expr.get_outputs ()) + reseat (output.expr); + + for (auto &input : expr.get_inputs ()) + reseat (input.expr); +} + +void +PointerVisitor::visit (AST::TypeParam ¶m) +{ + visit_outer_attrs (param); + // FIXME: Can we do macro expansion here? + for (auto &bound : param.get_type_param_bounds ()) + visit (bound); + if (param.has_type ()) + reseat (param.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::LifetimeWhereClauseItem &item) +{ + visit (item.get_lifetime ()); + for (auto &bound : item.get_lifetime_bounds ()) + visit (bound); +} + +void +PointerVisitor::visit (AST::TypeBoundWhereClauseItem &item) +{ + for (auto &lifetime : item.get_for_lifetimes ()) + visit (lifetime); + reseat (item.get_type_ptr ()); + // FIXME: Likewise? + for (auto ¶m : item.get_type_param_bounds ()) + visit (param); +} + +void +PointerVisitor::visit (AST::Visibility &vis) +{ + if (vis.has_path ()) + visit (vis.get_path ()); +} + +void +PointerVisitor::visit (AST::WhereClause &where) +{ + for (auto &item : where.get_items ()) + visit (item); +} + +void +PointerVisitor::visit (AST::FunctionParam ¶m) +{ + visit_outer_attrs (param); + if (param.has_name ()) + reseat (param.get_pattern_ptr ()); + + reseat (param.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::SelfParam ¶m) +{ + visit_outer_attrs (param); + + if (param.has_lifetime ()) + visit (param.get_lifetime ()); + + if (param.has_type ()) + reseat (param.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::Module &module) +{ + visit_outer_attrs (module); + visit (module.get_visibility ()); + visit_inner_attrs (module); + for (auto &item : module.get_items ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::ExternCrate &crate) +{ + visit_outer_attrs (crate); + visit (crate.get_visibility ()); +} + +void +PointerVisitor::visit (AST::UseTreeGlob &use_tree) +{ + visit (use_tree.get_path ()); +} + +void +PointerVisitor::visit (AST::UseTreeList &use_tree) +{ + visit (use_tree.get_path ()); +} + +void +PointerVisitor::visit (AST::UseTreeRebind &use_tree) +{ + visit (use_tree.get_path ()); +} + +void +PointerVisitor::visit (AST::UseDeclaration &use_decl) +{ + visit (use_decl.get_visibility ()); + visit (use_decl.get_tree ()); +} + +void +PointerVisitor::visit_function_params (AST::Function &function) +{ + for (auto ¶m : function.get_function_params ()) + visit (param); +} + +void +PointerVisitor::visit (AST::Function &function) +{ + visit_outer_attrs (function); + visit (function.get_visibility ()); + visit (function.get_qualifiers ()); + for (auto &generic : function.get_generic_params ()) + visit (generic); + + visit_function_params (function); + + if (function.has_return_type ()) + reseat (function.get_return_type_ptr ()); + if (function.has_where_clause ()) + visit (function.get_where_clause ()); + if (function.has_body ()) + reseat (*function.get_definition ()); +} + +void +PointerVisitor::visit (AST::TypeAlias &type_alias) +{ + visit_outer_attrs (type_alias); + visit (type_alias.get_visibility ()); + for (auto &generic : type_alias.get_generic_params ()) + visit (generic); + if (type_alias.has_where_clause ()) + visit (type_alias.get_where_clause ()); + reseat (type_alias.get_type_aliased_ptr ()); +} + +void +PointerVisitor::visit (AST::StructField &field) +{ + visit_outer_attrs (field); + visit (field.get_visibility ()); + reseat (field.get_field_type_ptr ()); +} + +void +PointerVisitor::visit (AST::StructStruct &struct_item) +{ + visit_outer_attrs (struct_item); + visit (struct_item.get_visibility ()); + for (auto &generic : struct_item.get_generic_params ()) + visit (generic); + if (struct_item.has_where_clause ()) + visit (struct_item.get_where_clause ()); + for (auto &field : struct_item.get_fields ()) + visit (field); +} + +void +PointerVisitor::visit (AST::TupleField &field) +{ + visit_outer_attrs (field); + visit (field.get_visibility ()); + reseat (field.get_field_type_ptr ()); +} + +void +PointerVisitor::visit (AST::TupleStruct &tuple_struct) +{ + visit_outer_attrs (tuple_struct); + visit (tuple_struct.get_visibility ()); + for (auto &generic : tuple_struct.get_generic_params ()) + visit (generic); + if (tuple_struct.has_where_clause ()) + visit (tuple_struct.get_where_clause ()); + for (auto &field : tuple_struct.get_fields ()) + visit (field); +} + +void +PointerVisitor::visit (AST::EnumItem &item) +{ + visit_outer_attrs (item); + visit (item.get_visibility ()); +} + +void +PointerVisitor::visit (AST::EnumItemTuple &item) +{ + PointerVisitor::visit (static_cast<EnumItem &> (item)); + for (auto &field : item.get_tuple_fields ()) + visit (field); +} + +void +PointerVisitor::visit (AST::EnumItemStruct &item) +{ + PointerVisitor::visit (static_cast<EnumItem &> (item)); + for (auto &field : item.get_struct_fields ()) + visit (field); +} + +void +PointerVisitor::visit (AST::EnumItemDiscriminant &item) +{ + PointerVisitor::visit (static_cast<EnumItem &> (item)); + reseat (item.get_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::Enum &enum_item) +{ + visit_outer_attrs (enum_item); + visit (enum_item.get_visibility ()); + for (auto &generic : enum_item.get_generic_params ()) + visit (generic); + if (enum_item.has_where_clause ()) + visit (enum_item.get_where_clause ()); + for (auto &item : enum_item.get_variants ()) + visit (item); +} + +void +PointerVisitor::visit (AST::Union &union_item) +{ + visit_outer_attrs (union_item); + visit (union_item.get_visibility ()); + for (auto &generic : union_item.get_generic_params ()) + visit (generic); + if (union_item.has_where_clause ()) + visit (union_item.get_where_clause ()); + for (auto &variant : union_item.get_variants ()) + visit (variant); +} + +void +PointerVisitor::visit (AST::ConstantItem &const_item) +{ + visit_outer_attrs (const_item); + visit (const_item.get_visibility ()); + reseat (const_item.get_type_ptr ()); + if (const_item.has_expr ()) + reseat (const_item.get_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::StaticItem &static_item) +{ + visit_outer_attrs (static_item); + visit (static_item.get_visibility ()); + reseat (static_item.get_type_ptr ()); + reseat (static_item.get_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::TraitItemType &item) +{ + visit_outer_attrs (item); + for (auto &bound : item.get_type_param_bounds ()) + visit (bound); +} + +void +PointerVisitor::visit (AST::Trait &trait) +{ + visit_outer_attrs (trait); + visit (trait.get_visibility ()); + + visit_inner_attrs (trait); + + visit (trait.get_implicit_self ()); + + for (auto &generic : trait.get_generic_params ()) + visit (generic); + + if (trait.has_where_clause ()) + visit (trait.get_where_clause ()); + + for (auto &bound : trait.get_type_param_bounds ()) + visit (bound); + + for (auto &item : trait.get_trait_items ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::InherentImpl &impl) +{ + visit_outer_attrs (impl); + visit (impl.get_visibility ()); + + for (auto &generic : impl.get_generic_params ()) + visit (generic); + if (impl.has_where_clause ()) + visit (impl.get_where_clause ()); + reseat (impl.get_type_ptr ()); + visit_inner_attrs (impl); + for (auto &item : impl.get_impl_items ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::TraitImpl &impl) +{ + visit_outer_attrs (impl); + visit (impl.get_visibility ()); + + for (auto &generic : impl.get_generic_params ()) + visit (generic); + if (impl.has_where_clause ()) + visit (impl.get_where_clause ()); + reseat (impl.get_type_ptr ()); + visit (impl.get_trait_path ()); + visit_inner_attrs (impl); + for (auto &item : impl.get_impl_items ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::ExternalTypeItem &item) +{ + visit_outer_attrs (item); + visit (item.get_visibility ()); +} + +void +PointerVisitor::visit (AST::ExternalStaticItem &item) +{ + visit_outer_attrs (item); + visit (item.get_visibility ()); + reseat (item.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::ExternBlock &block) +{ + visit_outer_attrs (block); + visit (block.get_visibility ()); + visit_inner_attrs (block); + for (auto &item : block.get_extern_items ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::MacroMatchFragment &match) +{} + +void +PointerVisitor::visit (AST::MacroMatchRepetition &match) +{ + for (auto &m : match.get_matches ()) + visit (m); +} + +void +PointerVisitor::visit (AST::MacroMatcher &matcher) +{ + for (auto &m : matcher.get_matches ()) + visit (m); +} + +void +PointerVisitor::visit (AST::MacroTranscriber &transcriber) +{ + visit (transcriber.get_token_tree ()); +} + +void +PointerVisitor::visit (AST::MacroRule &rule) +{ + visit (rule.get_matcher ()); + visit (rule.get_transcriber ()); +} + +void +PointerVisitor::visit (AST::MacroRulesDefinition &rules_def) +{ + visit_outer_attrs (rules_def); + for (auto &rule : rules_def.get_macro_rules ()) + visit (rule); +} + +void +PointerVisitor::visit (AST::MacroInvocData &data) +{ + visit (data.get_path ()); + visit (data.get_delim_tok_tree ()); +} + +void +PointerVisitor::visit (AST::MacroInvocation ¯o_invoc) +{ + visit_outer_attrs (macro_invoc); + visit (macro_invoc.get_invoc_data ()); +} + +void +PointerVisitor::visit (AST::MetaItemPath &meta_item) +{ + visit (meta_item.get_path ()); +} + +void +PointerVisitor::visit (AST::MetaItemSeq &meta_item) +{ + visit (meta_item.get_path ()); + for (auto &inner : meta_item.get_seq ()) + visit (inner); +} + +void +PointerVisitor::visit (AST::MetaListPaths &meta_item) +{ + for (auto &path : meta_item.get_paths ()) + visit (path); +} + +void +PointerVisitor::visit (AST::MetaListNameValueStr &meta_item) +{ + for (auto &str : meta_item.get_values ()) + visit (str); +} + +void +PointerVisitor::visit (AST::IdentifierPattern &pattern) +{ + if (pattern.has_subpattern ()) + reseat (pattern.get_subpattern_ptr ()); +} + +void +PointerVisitor::visit (AST::RangePatternBoundPath &bound) +{ + visit (bound.get_path ()); +} + +void +PointerVisitor::visit (AST::RangePatternBoundQualPath &bound) +{ + visit (bound.get_qualified_path ()); +} + +void +PointerVisitor::visit (AST::RangePattern &pattern) +{ + // FIXME: So should this be reseat() instead? Can we have macro invocations as + // patterns in range patterns? + if (pattern.get_has_lower_bound ()) + visit (pattern.get_lower_bound ()); + if (pattern.get_has_upper_bound ()) + visit (pattern.get_upper_bound ()); +} + +void +PointerVisitor::visit (AST::ReferencePattern &pattern) +{ + reseat (pattern.get_referenced_pattern_ptr ()); +} + +void +PointerVisitor::visit (AST::StructPatternFieldTuplePat &field) +{ + visit_outer_attrs (field); + reseat (field.get_index_pattern_ptr ()); +} + +void +PointerVisitor::visit (AST::StructPatternFieldIdentPat &field) +{ + visit_outer_attrs (field); + reseat (field.get_ident_pattern_ptr ()); +} + +void +PointerVisitor::visit (AST::StructPatternFieldIdent &field) +{ + visit_outer_attrs (field); +} + +void +PointerVisitor::visit (AST::StructPatternElements &spe) +{ + for (auto &field : spe.get_struct_pattern_fields ()) + visit (field); + for (auto &attribute : spe.get_etc_outer_attrs ()) + visit (attribute); +} + +void +PointerVisitor::visit (AST::StructPattern &pattern) +{ + visit (pattern.get_path ()); + visit (pattern.get_struct_pattern_elems ()); +} + +void +PointerVisitor::visit (AST::TupleStructItemsNoRest &tuple_items) +{ + for (auto &pattern : tuple_items.get_patterns ()) + reseat (pattern); +} + +void +PointerVisitor::visit (AST::TupleStructItemsHasRest &tuple_items) +{ + for (auto &lower : tuple_items.get_lower_patterns ()) + reseat (lower); + for (auto &upper : tuple_items.get_upper_patterns ()) + reseat (upper); +} + +void +PointerVisitor::visit (AST::TupleStructPattern &pattern) +{ + visit (pattern.get_path ()); + visit (pattern.get_items ()); +} + +void +PointerVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items) +{ + for (auto &pattern : tuple_items.get_patterns ()) + reseat (pattern); +} + +void +PointerVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items) +{ + for (auto &lower : tuple_items.get_lower_patterns ()) + reseat (lower); + for (auto &upper : tuple_items.get_upper_patterns ()) + reseat (upper); +} + +void +PointerVisitor::visit (AST::TuplePattern &pattern) +{ + visit (pattern.get_items ()); +} + +void +PointerVisitor::visit (AST::GroupedPattern &pattern) +{ + reseat (pattern.get_pattern_in_parens_ptr ()); +} + +void +PointerVisitor::visit (AST::SlicePatternItemsNoRest &items) +{ + for (auto &item : items.get_patterns ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::SlicePatternItemsHasRest &items) +{ + for (auto &item : items.get_lower_patterns ()) + reseat (item); + for (auto &item : items.get_upper_patterns ()) + reseat (item); +} + +void +PointerVisitor::visit (AST::SlicePattern &pattern) +{ + visit (pattern.get_items ()); +} + +void +PointerVisitor::visit (AST::AltPattern &pattern) +{ + for (auto &alt : pattern.get_alts ()) + reseat (alt); +} + +void +PointerVisitor::visit (AST::EmptyStmt &stmt) +{} + +void +PointerVisitor::visit (AST::LetStmt &stmt) +{ + visit_outer_attrs (stmt); + reseat (stmt.get_pattern_ptr ()); + if (stmt.has_type ()) + reseat (stmt.get_type_ptr ()); + if (stmt.has_init_expr ()) + reseat (stmt.get_init_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::ExprStmt &stmt) +{ + reseat (stmt.get_expr_ptr ()); +} + +void +PointerVisitor::visit (AST::TraitBound &bound) +{ + for (auto &lifetime : bound.get_for_lifetimes ()) + visit (lifetime); + visit (bound.get_type_path ()); +} + +void +PointerVisitor::visit (AST::ImplTraitType &type) +{ + for (auto &bound : type.get_type_param_bounds ()) + visit (bound); +} + +void +PointerVisitor::visit (AST::TraitObjectType &type) +{ + for (auto &bound : type.get_type_param_bounds ()) + visit (bound); +} + +void +PointerVisitor::visit (AST::ParenthesisedType &type) +{ + reseat (type.get_type_in_parens ()); +} + +void +PointerVisitor::visit (AST::ImplTraitTypeOneBound &type) +{ + // FIXME: Do we need to reseat here? + visit (type.get_trait_bound ()); +} + +void +PointerVisitor::visit (AST::TraitObjectTypeOneBound &type) +{ + // FIXME: Do we need to reseat here? + visit (type.get_trait_bound ()); +} + +void +PointerVisitor::visit (AST::TupleType &type) +{ + for (auto &elem : type.get_elems ()) + reseat (elem); +} + +void +PointerVisitor::visit (AST::NeverType &type) +{} + +void +PointerVisitor::visit (AST::RawPointerType &type) +{ + reseat (type.get_type_pointed_to_ptr ()); +} + +void +PointerVisitor::visit (AST::ReferenceType &type) +{ + visit (type.get_lifetime ()); + reseat (type.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::ArrayType &type) +{ + reseat (type.get_elem_type_ptr ()); + visit (type.get_size_expr ()); +} + +void +PointerVisitor::visit (AST::SliceType &type) +{ + reseat (type.get_elem_type_ptr ()); +} + +void +PointerVisitor::visit (AST::InferredType &type) +{} + +void +PointerVisitor::visit (AST::MaybeNamedParam ¶m) +{ + visit_outer_attrs (param); + reseat (param.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::BareFunctionType &type) +{ + for (auto &lifetime : type.get_for_lifetimes ()) + visit (lifetime); + visit (type.get_function_qualifiers ()); + for (auto ¶m : type.get_function_params ()) + visit (param); + if (type.is_variadic ()) + for (auto attr : type.get_variadic_attr ()) + visit (attr); + if (type.has_return_type ()) + reseat (type.get_return_type_ptr ()); +} + +void +PointerVisitor::visit (AST::FormatArgs &) +{ + // FIXME: Do we have anything to do? any subnodes to visit? Probably, right? +} + +void +PointerVisitor::visit (AST::OffsetOf &offset_of) +{ + reseat (offset_of.get_type_ptr ()); +} + +void +PointerVisitor::visit (AST::VariadicParam ¶m) +{ + if (param.has_pattern ()) + reseat (param.get_pattern_ptr ()); +} + +} // namespace AST +} // namespace Rust diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.h b/gcc/rust/ast/rust-ast-pointer-visitor.h new file mode 100644 index 0000000..8c12b4e --- /dev/null +++ b/gcc/rust/ast/rust-ast-pointer-visitor.h @@ -0,0 +1,234 @@ +// Copyright (C) 2025 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_AST_POINTER_VISITOR_H +#define RUST_AST_POINTER_VISITOR_H + +#include "rust-ast-visitor.h" +#include "rust-ast.h" +#include "rust-item.h" + +namespace Rust { +namespace AST { + +/** + * Regular AST visitor which may reseat pointers when necessary. + */ +class PointerVisitor : public DefaultASTVisitor +{ +public: + using DefaultASTVisitor::visit; + + virtual void reseat (std::unique_ptr<AST::Expr> &ptr) { visit (ptr); } + virtual void reseat (std::unique_ptr<AST::BlockExpr> &ptr) { visit (ptr); } + + virtual void reseat (std::unique_ptr<AST::Stmt> &ptr) { visit (ptr); } + + virtual void reseat (std::unique_ptr<AST::Item> &ptr) { visit (ptr); } + + virtual void reseat (std::unique_ptr<AST::AssociatedItem> &ptr) + { + visit (ptr); + } + + virtual void reseat (std::unique_ptr<AST::ExternalItem> &ptr) { visit (ptr); } + + virtual void reseat (std::unique_ptr<AST::Type> &ptr) { visit (ptr); } + + virtual void reseat (std::unique_ptr<AST::TypeNoBounds> &ptr) { visit (ptr); } + + virtual void reseat (std::unique_ptr<AST::Pattern> &ptr) { visit (ptr); } + + void visit (AST::Crate &crate) override; + void visit (AST::AttrInputMetaItemContainer &input) override; + void visit (AST::IdentifierExpr &ident_expr) override; + void visit (AST::LifetimeParam &lifetime_param) override; + void visit (AST::ConstGenericParam &const_param) override; + void visit (AST::PathInExpression &path) override; + void visit (GenericArgsBinding &binding) override; + void visit (AST::TypePathSegmentGeneric &segment) override; + void visit (AST::TypePathFunction &tpf) override; + void visit (AST::TypePathSegmentFunction &segment) override; + void visit (AST::GenericArgs &args) override; + void visit (AST::PathExprSegment &segment) override; + void visit (AST::TypePath &path) override; + void visit (AST::QualifiedPathInExpression &path) override; + void visit (AST::QualifiedPathType &path) override; + void visit (AST::QualifiedPathInType &path) override; + void visit (AST::LiteralExpr &expr) override; + void visit (AST::AttrInputLiteral &attr_input) override; + void visit (AST::AttrInputMacro &attr_input) override; + void visit (AST::MetaItemLitExpr &meta_item) override; + void visit (AST::SimplePath &path) override; + void visit (AST::MetaItemPathExpr &meta_item) override; + void visit (AST::BorrowExpr &expr) override; + void visit (AST::DereferenceExpr &expr) override; + void visit (AST::ErrorPropagationExpr &expr) override; + void visit (AST::NegationExpr &expr) override; + void visit (AST::ArithmeticOrLogicalExpr &expr) override; + void visit (AST::ComparisonExpr &expr) override; + void visit (AST::LazyBooleanExpr &expr) override; + void visit (AST::TypeCastExpr &expr) override; + void visit (AST::AssignmentExpr &expr) override; + void visit (AST::CompoundAssignmentExpr &expr) override; + void visit (AST::GroupedExpr &expr) override; + void visit (AST::ArrayElemsValues &elems) override; + void visit (AST::ArrayElemsCopied &elems) override; + void visit (AST::ArrayExpr &expr) override; + void visit (AST::ArrayIndexExpr &expr) override; + void visit (AST::TupleExpr &expr) override; + void visit (AST::TupleIndexExpr &expr) override; + void visit (AST::StructExprStruct &expr) override; + void visit (AST::StructExprFieldIdentifier &field) override; + void visit (AST::StructExprFieldIdentifierValue &field) override; + void visit (AST::StructExprFieldIndexValue &field) override; + void visit (AST::StructBase &base) override; + void visit (AST::StructExprStructFields &expr) override; + void visit (AST::StructExprStructBase &expr) override; + void visit (AST::CallExpr &expr) override; + void visit (AST::MethodCallExpr &expr) override; + void visit (AST::FieldAccessExpr &expr) override; + void visit (AST::ClosureExprInner &expr) override; + void visit (AST::BlockExpr &expr) override; + void visit (AST::ConstBlock &expr) override; + void visit (AST::AnonConst &expr) override; + void visit (AST::ClosureExprInnerTyped &expr) override; + void visit (AST::ClosureParam ¶m) override; + void visit (AST::ContinueExpr &expr) override; + void visit (AST::BreakExpr &expr) override; + void visit (AST::RangeFromToExpr &expr) override; + void visit (AST::RangeFromExpr &expr) override; + void visit (AST::RangeToExpr &expr) override; + void visit (AST::RangeFullExpr &expr) override; + void visit (AST::RangeFromToInclExpr &expr) override; + void visit (AST::RangeToInclExpr &expr) override; + void visit (AST::ReturnExpr &expr) override; + void visit (AST::TryExpr &expr) override; + void visit (AST::BoxExpr &expr) override; + void visit (AST::UnsafeBlockExpr &expr) override; + void visit (AST::LoopLabel &label) override; + void visit (AST::LoopExpr &expr) override; + void visit (AST::WhileLoopExpr &expr) override; + void visit (AST::WhileLetLoopExpr &expr) override; + void visit (AST::ForLoopExpr &expr) override; + void visit (AST::IfExpr &expr) override; + void visit (AST::IfExprConseqElse &expr) override; + void visit (AST::IfLetExpr &expr) override; + void visit (AST::IfLetExprConseqElse &expr) override; + void visit (AST::MatchArm &arm) override; + void visit (AST::MatchCase &arm) override; + void visit (AST::MatchExpr &expr) override; + void visit (AST::AwaitExpr &expr) override; + void visit (AST::AsyncBlockExpr &expr) override; + void visit (AST::InlineAsm &expr) override; + void visit (AST::LlvmInlineAsm &expr) override; + void visit (AST::TypeParam ¶m) override; + void visit (AST::LifetimeWhereClauseItem &item) override; + void visit (AST::TypeBoundWhereClauseItem &item) override; + void visit (AST::Visibility &vis) override; + void visit (AST::WhereClause &where) override; + void visit (AST::FunctionParam ¶m) override; + void visit (AST::SelfParam ¶m) override; + void visit (AST::Module &module) override; + void visit (AST::ExternCrate &crate) override; + void visit (AST::UseTreeGlob &use_tree) override; + void visit (AST::UseTreeList &use_tree) override; + void visit (AST::UseTreeRebind &use_tree) override; + void visit (AST::UseDeclaration &use_decl) override; + void visit_function_params (AST::Function &function) override; + void visit (AST::Function &function) override; + void visit (AST::TypeAlias &type_alias) override; + void visit (AST::StructField &field) override; + void visit (AST::StructStruct &struct_item) override; + void visit (AST::TupleField &field) override; + void visit (AST::TupleStruct &tuple_struct) override; + void visit (AST::EnumItem &item) override; + void visit (AST::EnumItemTuple &item) override; + void visit (AST::EnumItemStruct &item) override; + void visit (AST::EnumItemDiscriminant &item) override; + void visit (AST::Enum &enum_item) override; + void visit (AST::Union &union_item) override; + void visit (AST::ConstantItem &const_item) override; + void visit (AST::StaticItem &static_item) override; + void visit (AST::TraitItemType &item) override; + void visit (AST::Trait &trait) override; + void visit (AST::InherentImpl &impl) override; + void visit (AST::TraitImpl &impl) override; + void visit (AST::ExternalTypeItem &item) override; + void visit (AST::ExternalStaticItem &item) override; + void visit (AST::ExternBlock &block) override; + void visit (AST::MacroMatchFragment &match) override; + void visit (AST::MacroMatchRepetition &match) override; + void visit (AST::MacroMatcher &matcher) override; + void visit (AST::MacroTranscriber &transcriber) override; + void visit (AST::MacroRule &rule) override; + void visit (AST::MacroRulesDefinition &rules_def) override; + void visit (AST::MacroInvocData &data) override; + void visit (AST::MacroInvocation ¯o_invoc) override; + void visit (AST::MetaItemPath &meta_item) override; + void visit (AST::MetaItemSeq &meta_item) override; + void visit (AST::MetaListPaths &meta_item) override; + void visit (AST::MetaListNameValueStr &meta_item) override; + void visit (AST::IdentifierPattern &pattern) override; + void visit (AST::RangePatternBoundPath &bound) override; + void visit (AST::RangePatternBoundQualPath &bound) override; + void visit (AST::RangePattern &pattern) override; + void visit (AST::ReferencePattern &pattern) override; + void visit (AST::StructPatternFieldTuplePat &field) override; + void visit (AST::StructPatternFieldIdentPat &field) override; + void visit (AST::StructPatternFieldIdent &field) override; + void visit (AST::StructPatternElements &spe) override; + void visit (AST::StructPattern &pattern) override; + void visit (AST::TupleStructItemsNoRest &tuple_items) override; + void visit (AST::TupleStructItemsHasRest &tuple_items) override; + void visit (AST::TupleStructPattern &pattern) override; + void visit (AST::TuplePatternItemsNoRest &tuple_items) override; + void visit (AST::TuplePatternItemsHasRest &tuple_items) override; + void visit (AST::TuplePattern &pattern) override; + void visit (AST::GroupedPattern &pattern) override; + void visit (AST::SlicePatternItemsNoRest &items) override; + void visit (AST::SlicePatternItemsHasRest &items) override; + void visit (AST::SlicePattern &pattern) override; + void visit (AST::AltPattern &pattern) override; + void visit (AST::EmptyStmt &stmt) override; + void visit (AST::LetStmt &stmt) override; + void visit (AST::ExprStmt &stmt) override; + void visit (AST::TraitBound &bound) override; + void visit (AST::ImplTraitType &type) override; + void visit (AST::TraitObjectType &type) override; + void visit (AST::ParenthesisedType &type) override; + void visit (AST::ImplTraitTypeOneBound &type) override; + void visit (AST::TraitObjectTypeOneBound &type) override; + void visit (AST::TupleType &type) override; + void visit (AST::NeverType &type) override; + void visit (AST::RawPointerType &type) override; + void visit (AST::ReferenceType &type) override; + void visit (AST::ArrayType &type) override; + void visit (AST::SliceType &type) override; + void visit (AST::InferredType &type) override; + void visit (AST::MaybeNamedParam ¶m) override; + void visit (AST::BareFunctionType &type) override; + void visit (AST::FormatArgs &) override; + void visit (AST::OffsetOf &offset_of) override; + void visit (AST::VariadicParam ¶m) override; +}; + +} // namespace AST +} // namespace Rust + +#endif diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index ab8cdbe..afdd2b1 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -248,6 +248,7 @@ void DefaultASTVisitor::visit (AST::ErrorPropagationExpr &expr) { visit_outer_attrs (expr); + visit (expr.get_propagating_expr ()); } void @@ -1025,15 +1026,6 @@ DefaultASTVisitor::visit (AST::StaticItem &static_item) } void -DefaultASTVisitor::visit (AST::TraitItemConst &item) -{ - visit_outer_attrs (item); - visit (item.get_type ()); - if (item.has_expr ()) - visit (item.get_expr ()); -} - -void DefaultASTVisitor::visit (AST::TraitItemType &item) { visit_outer_attrs (item); @@ -1296,14 +1288,14 @@ DefaultASTVisitor::visit (AST::StructPattern &pattern) } void -DefaultASTVisitor::visit (AST::TupleStructItemsNoRange &tuple_items) +DefaultASTVisitor::visit (AST::TupleStructItemsNoRest &tuple_items) { for (auto &pattern : tuple_items.get_patterns ()) visit (pattern); } void -DefaultASTVisitor::visit (AST::TupleStructItemsRange &tuple_items) +DefaultASTVisitor::visit (AST::TupleStructItemsHasRest &tuple_items) { for (auto &lower : tuple_items.get_lower_patterns ()) visit (lower); @@ -1319,14 +1311,14 @@ DefaultASTVisitor::visit (AST::TupleStructPattern &pattern) } void -DefaultASTVisitor::visit (AST::TuplePatternItemsMultiple &tuple_items) +DefaultASTVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items) { for (auto &pattern : tuple_items.get_patterns ()) visit (pattern); } void -DefaultASTVisitor::visit (AST::TuplePatternItemsRanged &tuple_items) +DefaultASTVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items) { for (auto &lower : tuple_items.get_lower_patterns ()) visit (lower); diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index 2d81aa1..a7a2ac4 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -164,7 +164,6 @@ public: virtual void visit (Union &union_item) = 0; virtual void visit (ConstantItem &const_item) = 0; virtual void visit (StaticItem &static_item) = 0; - virtual void visit (TraitItemConst &item) = 0; virtual void visit (TraitItemType &item) = 0; virtual void visit (Trait &trait) = 0; virtual void visit (InherentImpl &impl) = 0; @@ -204,12 +203,12 @@ public: virtual void visit (StructPatternFieldIdent &field) = 0; virtual void visit (StructPattern &pattern) = 0; // virtual void visit(TupleStructItems& tuple_items) = 0; - virtual void visit (TupleStructItemsNoRange &tuple_items) = 0; - virtual void visit (TupleStructItemsRange &tuple_items) = 0; + virtual void visit (TupleStructItemsNoRest &tuple_items) = 0; + virtual void visit (TupleStructItemsHasRest &tuple_items) = 0; virtual void visit (TupleStructPattern &pattern) = 0; // virtual void visit(TuplePatternItems& tuple_items) = 0; - virtual void visit (TuplePatternItemsMultiple &tuple_items) = 0; - virtual void visit (TuplePatternItemsRanged &tuple_items) = 0; + virtual void visit (TuplePatternItemsNoRest &tuple_items) = 0; + virtual void visit (TuplePatternItemsHasRest &tuple_items) = 0; virtual void visit (TuplePattern &pattern) = 0; virtual void visit (GroupedPattern &pattern) = 0; virtual void visit (SlicePatternItemsNoRest &items) = 0; @@ -349,7 +348,6 @@ public: virtual void visit (AST::Union &union_item) override; virtual void visit (AST::ConstantItem &const_item) override; virtual void visit (AST::StaticItem &static_item) override; - virtual void visit (AST::TraitItemConst &item) override; virtual void visit (AST::TraitItemType &item) override; virtual void visit (AST::Trait &trait) override; virtual void visit (AST::InherentImpl &impl) override; @@ -381,11 +379,11 @@ public: virtual void visit (AST::StructPatternFieldIdentPat &field) override; virtual void visit (AST::StructPatternFieldIdent &field) override; virtual void visit (AST::StructPattern &pattern) override; - virtual void visit (AST::TupleStructItemsNoRange &tuple_items) override; - virtual void visit (AST::TupleStructItemsRange &tuple_items) override; + virtual void visit (AST::TupleStructItemsNoRest &tuple_items) override; + virtual void visit (AST::TupleStructItemsHasRest &tuple_items) override; virtual void visit (AST::TupleStructPattern &pattern) override; - virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) override; - virtual void visit (AST::TuplePatternItemsRanged &tuple_items) override; + virtual void visit (AST::TuplePatternItemsNoRest &tuple_items) override; + virtual void visit (AST::TuplePatternItemsHasRest &tuple_items) override; virtual void visit (AST::TuplePattern &pattern) override; virtual void visit (AST::GroupedPattern &pattern) override; virtual void visit (AST::SlicePatternItemsNoRest &items) override; diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 8e856fb..337a338 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -48,29 +48,33 @@ SingleASTNode::SingleASTNode (SingleASTNode const &other) kind = other.kind; switch (kind) { - case EXPRESSION: + case Kind::Expr: expr = other.expr->clone_expr (); break; - case ITEM: + case Kind::Item: item = other.item->clone_item (); break; - case STMT: + case Kind::Stmt: stmt = other.stmt->clone_stmt (); break; - case EXTERN: + case Kind::Extern: external_item = other.external_item->clone_external_item (); break; - case ASSOC_ITEM: + case Kind::Assoc: assoc_item = other.assoc_item->clone_associated_item (); break; - case TYPE: + case Kind::Type: type = other.type->clone_type (); break; + + case Kind::Pattern: + pattern = other.pattern->clone_pattern (); + break; } } @@ -80,29 +84,33 @@ SingleASTNode::operator= (SingleASTNode const &other) kind = other.kind; switch (kind) { - case EXPRESSION: + case Kind::Expr: expr = other.expr->clone_expr (); break; - case ITEM: + case Kind::Item: item = other.item->clone_item (); break; - case STMT: + case Kind::Stmt: stmt = other.stmt->clone_stmt (); break; - case EXTERN: + case Kind::Extern: external_item = other.external_item->clone_external_item (); break; - case ASSOC_ITEM: + case Kind::Assoc: assoc_item = other.assoc_item->clone_associated_item (); break; - case TYPE: + case Kind::Type: type = other.type->clone_type (); break; + + case Kind::Pattern: + pattern = other.pattern->clone_pattern (); + break; } return *this; } @@ -112,29 +120,33 @@ SingleASTNode::accept_vis (ASTVisitor &vis) { switch (kind) { - case EXPRESSION: + case Kind::Expr: expr->accept_vis (vis); break; - case ITEM: + case Kind::Item: item->accept_vis (vis); break; - case STMT: + case Kind::Stmt: stmt->accept_vis (vis); break; - case EXTERN: + case Kind::Extern: external_item->accept_vis (vis); break; - case ASSOC_ITEM: + case Kind::Assoc: assoc_item->accept_vis (vis); break; - case TYPE: + case Kind::Type: type->accept_vis (vis); break; + + case Kind::Pattern: + pattern->accept_vis (vis); + break; } } @@ -143,18 +155,20 @@ SingleASTNode::is_error () { switch (kind) { - case EXPRESSION: + case Kind::Expr: return expr == nullptr; - case ITEM: + case Kind::Item: return item == nullptr; - case STMT: + case Kind::Stmt: return stmt == nullptr; - case EXTERN: + case Kind::Extern: return external_item == nullptr; - case ASSOC_ITEM: + case Kind::Assoc: return assoc_item == nullptr; - case TYPE: + case Kind::Type: return type == nullptr; + case Kind::Pattern: + return pattern == nullptr; } rust_unreachable (); @@ -166,18 +180,20 @@ SingleASTNode::as_string () const { switch (kind) { - case EXPRESSION: + case Kind::Expr: return "Expr: " + expr->as_string (); - case ITEM: + case Kind::Item: return "Item: " + item->as_string (); - case STMT: + case Kind::Stmt: return "Stmt: " + stmt->as_string (); - case EXTERN: + case Kind::Extern: return "External Item: " + external_item->as_string (); - case ASSOC_ITEM: + case Kind::Assoc: return "Associated Item: " + assoc_item->as_string (); - case TYPE: + case Kind::Type: return "Type: " + type->as_string (); + case Kind::Pattern: + return "Pattern: " + pattern->as_string (); } rust_unreachable (); @@ -232,7 +248,7 @@ Attribute::as_string () const bool Attribute::is_derive () const { - return has_attr_input () && get_path () == "derive"; + return has_attr_input () && get_path () == Values::Attributes::DERIVE; } /** @@ -389,7 +405,7 @@ DelimTokenTree::as_string () const std::string Token::as_string () const { - if (tok_ref->has_str ()) + if (tok_ref->should_have_str ()) { std::string str = tok_ref->get_str (); @@ -636,14 +652,8 @@ ConstantItem::as_string () const } str += "\n Type: " + type->as_string (); - // DEBUG: null pointer check - if (const_expr == nullptr) - { - rust_debug ("something really terrible has gone wrong - null " - "pointer expr in const item."); - return "NULL_POINTER_MARK"; - } - str += "\n Expression: " + const_expr->as_string (); + if (has_expr ()) + str += "\n Expression: " + const_expr->as_string (); return str + "\n"; } @@ -3034,20 +3044,6 @@ ExternalStaticItem::as_string () const } std::string -TraitItemConst::as_string () const -{ - // TODO: rewrite to work with non-linearisable exprs - std::string str = append_attributes (outer_attrs, OUTER); - - str += "\nconst " + name.as_string () + " : " + type->as_string (); - - if (has_expression ()) - str += " = " + expr->as_string (); - - return str; -} - -std::string TraitItemType::as_string () const { std::string str = append_attributes (outer_attrs, OUTER); @@ -3367,7 +3363,13 @@ void Module::process_file_path () { rust_assert (kind == Module::ModuleKind::UNLOADED); - rust_assert (module_file.empty ()); + + if (!module_file.empty ()) + { + rust_error_at (locus, "error handling module file for %qs", + module_name.as_string ().c_str ()); + return; + } // This corresponds to the path of the file 'including' the module. So the // file that contains the 'mod <file>;' directive @@ -4132,6 +4134,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const for (auto it = items.begin () + 1; it != items.end (); ++it) { + if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem + && static_cast<MetaItem &> (**it).get_item_kind () + == MetaItem::ItemKind::PathExpr + && !static_cast<MetaItemPathExpr &> (**it).get_expr ().is_literal ()) + continue; + Attribute attr = (*it)->to_attribute (); if (attr.is_empty ()) { @@ -4149,11 +4157,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const bool Attribute::check_cfg_predicate (const Session &session) const { + auto string_path = path.as_string (); /* assume that cfg predicate actually can exist, i.e. attribute has cfg or * cfg_attr path */ if (!has_attr_input () - || (path.as_string () != Values::Attributes::CFG - && path.as_string () != Values::Attributes::CFG_ATTR)) + || (string_path != Values::Attributes::CFG + && string_path != Values::Attributes::CFG_ATTR)) { // DEBUG message rust_debug ( @@ -4169,6 +4178,13 @@ Attribute::check_cfg_predicate (const Session &session) const return false; auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input); + if (meta_item.get_items ().empty () + && string_path == Values::Attributes::CFG_ATTR) + { + rust_error_at (path.get_locus (), + "malformed %<cfg_attr%> attribute input"); + return false; + } return meta_item.get_items ().front ()->check_cfg_predicate (session); } @@ -4740,12 +4756,6 @@ StaticItem::accept_vis (ASTVisitor &vis) } void -TraitItemConst::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void TraitItemType::accept_vis (ASTVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 2d2c5d0..8a7e618 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -184,17 +184,6 @@ class Token : public TokenTree, public MacroMatch { // A token is a kind of token tree (except delimiter tokens) // A token is a kind of MacroMatch (except $ and delimiter tokens) -#if 0 - // TODO: improve member variables - current ones are the same as lexer token - // Token kind. - TokenId token_id; - // Token location. - location_t locus; - // Associated text (if any) of token. - std::string str; - // Token type hint (if any). - PrimitiveCoreType type_hint; -#endif const_TokenPtr tok_ref; @@ -209,53 +198,7 @@ public: return std::unique_ptr<Token> (clone_token_impl ()); } -#if 0 - /* constructor from general text - avoid using if lexer const_TokenPtr is - * available */ - Token (TokenId token_id, location_t locus, std::string str, - PrimitiveCoreType type_hint) - : token_id (token_id), locus (locus), str (std::move (str)), - type_hint (type_hint) - {} -#endif - // not doable with new implementation - will have to make a const_TokenPtr - // Constructor from lexer const_TokenPtr -#if 0 - /* TODO: find workaround for std::string being nullptr - probably have to - * introduce new method in lexer Token, or maybe make conversion method - * there */ - Token (const_TokenPtr lexer_token_ptr) - : token_id (lexer_token_ptr->get_id ()), - locus (lexer_token_ptr->get_locus ()), str (""), - type_hint (lexer_token_ptr->get_type_hint ()) - { - // FIXME: change to "should have str" later? - if (lexer_token_ptr->has_str ()) - { - str = lexer_token_ptr->get_str (); - - // DEBUG - rust_debug ("ast token created with str '%s'", str.c_str ()); - } - else - { - // FIXME: is this returning correct thing? - str = lexer_token_ptr->get_token_description (); - - // DEBUG - rust_debug ("ast token created with string '%s'", str.c_str ()); - } - - // DEBUG - if (lexer_token_ptr->should_have_str () && !lexer_token_ptr->has_str ()) - { - rust_debug ( - "BAD: for token '%s', should have string but does not!", - lexer_token_ptr->get_token_description ()); - } - } -#endif Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {} bool is_string_lit () const @@ -283,7 +226,7 @@ public: std::vector<std::unique_ptr<Token>> to_token_stream () const override; TokenId get_id () const { return tok_ref->get_id (); } - bool has_str () const { return tok_ref->has_str (); } + bool should_have_str () const { return tok_ref->should_have_str (); } const std::string &get_str () const { return tok_ref->get_str (); } location_t get_locus () const { return tok_ref->get_locus (); } @@ -1137,7 +1080,9 @@ public: virtual void mark_for_strip () = 0; virtual bool is_marked_for_strip () const = 0; - NodeId get_node_id () const { return node_id; } + + // TODO: put this in a virtual base class? + virtual NodeId get_node_id () const { return node_id; } virtual Kind get_stmt_kind () = 0; @@ -1536,7 +1481,8 @@ public: virtual location_t get_locus () const = 0; - NodeId get_node_id () const { return node_id; } + // TODO: put this in a virtual base class? + virtual NodeId get_node_id () const { return node_id; } virtual Type *reconstruct_impl () const = 0; protected: @@ -1799,6 +1745,8 @@ public: virtual bool is_marked_for_strip () const = 0; virtual location_t get_locus () const = 0; + + virtual NodeId get_node_id () const = 0; }; // Item used in trait declarations - abstract base class @@ -1829,7 +1777,7 @@ public: return std::unique_ptr<TraitItem> (clone_associated_item_impl ()); } - NodeId get_node_id () const { return node_id; } + NodeId get_node_id () const override { return node_id; } location_t get_locus () const override { return locus; } }; @@ -1957,18 +1905,19 @@ public: class SingleASTNode : public Visitable { public: - enum NodeType - { - EXPRESSION, - ITEM, - STMT, - EXTERN, - ASSOC_ITEM, - TYPE, + enum class Kind + { + Expr, + Item, + Stmt, + Extern, + Assoc, + Type, + Pattern, }; private: - NodeType kind; + Kind kind; // FIXME make this a union std::unique_ptr<Expr> expr; @@ -1977,30 +1926,35 @@ private: std::unique_ptr<ExternalItem> external_item; std::unique_ptr<AssociatedItem> assoc_item; std::unique_ptr<Type> type; + std::unique_ptr<Pattern> pattern; public: SingleASTNode (std::unique_ptr<Expr> expr) - : kind (EXPRESSION), expr (std::move (expr)) + : kind (Kind::Expr), expr (std::move (expr)) {} SingleASTNode (std::unique_ptr<Item> item) - : kind (ITEM), item (std::move (item)) + : kind (Kind::Item), item (std::move (item)) {} SingleASTNode (std::unique_ptr<Stmt> stmt) - : kind (STMT), stmt (std::move (stmt)) + : kind (Kind::Stmt), stmt (std::move (stmt)) {} SingleASTNode (std::unique_ptr<ExternalItem> item) - : kind (EXTERN), external_item (std::move (item)) + : kind (Kind::Extern), external_item (std::move (item)) {} SingleASTNode (std::unique_ptr<AssociatedItem> item) - : kind (ASSOC_ITEM), assoc_item (std::move (item)) + : kind (Kind::Assoc), assoc_item (std::move (item)) {} SingleASTNode (std::unique_ptr<Type> type) - : kind (TYPE), type (std::move (type)) + : kind (Kind::Type), type (std::move (type)) + {} + + SingleASTNode (std::unique_ptr<Pattern> pattern) + : kind (Kind::Pattern), pattern (std::move (pattern)) {} SingleASTNode (SingleASTNode const &other); @@ -2010,23 +1964,23 @@ public: SingleASTNode (SingleASTNode &&other) = default; SingleASTNode &operator= (SingleASTNode &&other) = default; - NodeType get_kind () const { return kind; } + Kind get_kind () const { return kind; } std::unique_ptr<Expr> &get_expr () { - rust_assert (kind == EXPRESSION); + rust_assert (kind == Kind::Expr); return expr; } std::unique_ptr<Item> &get_item () { - rust_assert (kind == ITEM); + rust_assert (kind == Kind::Item); return item; } std::unique_ptr<Stmt> &get_stmt () { - rust_assert (kind == STMT); + rust_assert (kind == Kind::Stmt); return stmt; } @@ -2071,6 +2025,12 @@ public: return std::move (type); } + std::unique_ptr<Pattern> take_pattern () + { + rust_assert (!is_error ()); + return std::move (pattern); + } + void accept_vis (ASTVisitor &vis) override; bool is_error (); diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h b/gcc/rust/ast/rust-builtin-ast-nodes.h index 2893e7b..c784ad6 100644 --- a/gcc/rust/ast/rust-builtin-ast-nodes.h +++ b/gcc/rust/ast/rust-builtin-ast-nodes.h @@ -134,6 +134,7 @@ public: FormatArgumentKind get_kind () const { return kind; } const Expr &get_expr () const { return *expr; } + Expr &get_expr () { return *expr; } private: FormatArgument (FormatArgumentKind::Kind kind, tl::optional<Identifier> ident, @@ -164,6 +165,11 @@ public: void push (FormatArgument &&elt) { args.emplace_back (std::move (elt)); } const FormatArgument at (size_t idx) const { return args.at (idx); } + const std::vector<FormatArgument> &get_args () const { return args; } + std::vector<FormatArgument> &get_args () { return args; } + size_t size () const { return args.size (); } + bool empty () const { return args.empty (); } + private: std::vector<FormatArgument> args; }; @@ -200,6 +206,7 @@ public: const Fmt::Pieces &get_template () const { return template_pieces; } const FormatArguments &get_arguments () const { return arguments; } + FormatArguments &get_arguments () { return arguments; } virtual location_t get_locus () const override; Expr::Kind get_expr_kind () const override { return Expr::Kind::FormatArgs; } @@ -255,6 +262,7 @@ public: virtual location_t get_locus () const override { return loc; } const Type &get_type () const { return *type; } Type &get_type () { return *type; } + std::unique_ptr<Type> &get_type_ptr () { return type; } const Identifier &get_field () const { return field; } bool is_expr_without_block () const override { return false; } diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc index 306c6f7..1efe26f 100644 --- a/gcc/rust/ast/rust-collect-lang-items.cc +++ b/gcc/rust/ast/rust-collect-lang-items.cc @@ -43,18 +43,16 @@ get_lang_item_attr (const T &maybe_lang_item) continue; } - bool is_lang_item = str_path == Values::Attributes::LANG - && attr.has_attr_input () - && attr.get_attr_input ().get_attr_input_type () - == AST::AttrInput::AttrInputType::LITERAL; + bool is_lang_item = str_path == Values::Attributes::LANG; if (is_lang_item) { - auto &literal - = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ()); - const auto &lang_item_type_str = literal.get_literal ().as_string (); + auto lang_item_type_str + = Analysis::Attributes::extract_string_literal (attr); - return LangItem::Parse (lang_item_type_str); + rust_assert (lang_item_type_str.has_value ()); + + return LangItem::Parse (*lang_item_type_str); } } diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h index 56a5646..5d5fba5 100644 --- a/gcc/rust/ast/rust-cond-compilation.h +++ b/gcc/rust/ast/rust-cond-compilation.h @@ -91,9 +91,13 @@ class ConfigurationAll : public ConfigurationPredicate predicate_list; // inlined form public: + ConfigurationAll (const ConfigurationAll &) = delete; + + ConfigurationAll (ConfigurationAll &&) = default; + ConfigurationAll ( std::vector<std::unique_ptr<ConfigurationPredicate>> predicate_list) - : predicate_list (predicate_list) + : predicate_list (std::move (predicate_list)) {} void accept_vis (ASTVisitor &vis) override; @@ -103,7 +107,14 @@ protected: * than base */ ConfigurationAll *clone_configuration_predicate_impl () const override { - return new ConfigurationAll (*this); + decltype (predicate_list) predicate_list_clone = {}; + predicate_list_clone.reserve (predicate_list.size ()); + + for (const auto &predicate : predicate_list) + predicate_list_clone.push_back ( + predicate->clone_configuration_predicate ()); + + return new ConfigurationAll (std::move (predicate_list_clone)); } }; @@ -114,9 +125,13 @@ class ConfigurationAny : public ConfigurationPredicate predicate_list; // inlined form public: + ConfigurationAny (const ConfigurationAny &) = delete; + + ConfigurationAny (ConfigurationAny &&) = default; + ConfigurationAny ( std::vector<std::unique_ptr<ConfigurationPredicate>> predicate_list) - : predicate_list (predicate_list) + : predicate_list (std::move (predicate_list)) {} void accept_vis (ASTVisitor &vis) override; @@ -126,7 +141,14 @@ protected: * than base */ ConfigurationAny *clone_configuration_predicate_impl () const override { - return new ConfigurationAny (*this); + decltype (predicate_list) predicate_list_clone = {}; + predicate_list_clone.reserve (predicate_list.size ()); + + for (const auto &predicate : predicate_list) + predicate_list_clone.push_back ( + predicate->clone_configuration_predicate ()); + + return new ConfigurationAny (std::move (predicate_list_clone)); } }; @@ -226,7 +248,7 @@ public: CfgAttrAttribute (CfgAttrAttribute const &other) : config_to_include ( other.config_to_include->clone_configuration_predicate ()), - cfg_attrs (cfg_attrs) + cfg_attrs (other.cfg_attrs) {} // Overloaded assignment operator to clone diff --git a/gcc/rust/ast/rust-desugar-apit.cc b/gcc/rust/ast/rust-desugar-apit.cc index bca14ee..de34e15 100644 --- a/gcc/rust/ast/rust-desugar-apit.cc +++ b/gcc/rust/ast/rust-desugar-apit.cc @@ -188,9 +188,10 @@ public: // Convert to TypePath by creating path segments std::vector<std::unique_ptr<TypePathSegment>> segments; - segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment ( - PathIdentSegment (ident.as_string (), type.get_locus ()), false, - type.get_locus ()))); + segments.emplace_back ( + new TypePathSegment (PathIdentSegment (ident.as_string (), + type.get_locus ()), + false, type.get_locus ())); // Create TypePath from segments auto type_path @@ -198,6 +199,8 @@ public: // Convert bounds from impl trait to generic parameter bounds std::vector<std::unique_ptr<TypeParamBound>> bounds; + bounds.reserve (type.get_type_param_bounds ().size ()); + for (auto &bound : type.get_type_param_bounds ()) bounds.push_back (bound->clone_type_param_bound ()); @@ -228,9 +231,10 @@ public: // Convert to TypePath by creating path segments std::vector<std::unique_ptr<TypePathSegment>> segments; - segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment ( - PathIdentSegment (ident.as_string (), type.get_locus ()), false, - type.get_locus ()))); + segments.emplace_back ( + new TypePathSegment (PathIdentSegment (ident.as_string (), + type.get_locus ()), + false, type.get_locus ())); // Create TypePath from segments auto type_path @@ -407,6 +411,9 @@ private: std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; + type_param_bounds.reserve ( + tp.get_type_param_bounds ().size ()); + for (auto &b : tp.get_type_param_bounds ()) type_param_bounds.push_back (std::move (b)); tp.get_type_param_bounds ().clear (); @@ -459,9 +466,10 @@ private: std::vector<SimplePathSegment> simple_segs = {simple_seg}; auto simple_path = SimplePath (simple_segs, false, ident.get_locus ()); std::vector<std::unique_ptr<TypePathSegment>> segments; - segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment ( - PathIdentSegment (ident.as_string (), ident.get_locus ()), false, - ident.get_locus ()))); + segments.emplace_back ( + new TypePathSegment (PathIdentSegment (ident.as_string (), + ident.get_locus ()), + false, ident.get_locus ())); auto type_path = new TypePath (std::move (segments), ident.get_locus ()); return std::unique_ptr<Type> (type_path); } diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc b/gcc/rust/ast/rust-desugar-for-loops.cc index 5cc1c19..9a12423 100644 --- a/gcc/rust/ast/rust-desugar-for-loops.cc +++ b/gcc/rust/ast/rust-desugar-for-loops.cc @@ -51,7 +51,7 @@ DesugarForLoops::DesugarCtx::make_continue_arm () patterns.emplace_back (std::move (val)); auto pattern_item = std::unique_ptr<TupleStructItems> ( - new TupleStructItemsNoRange (std::move (patterns))); + new TupleStructItemsNoRest (std::move (patterns))); auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern ( builder.path_in_expression (LangItem::Kind::OPTION_SOME), std::move (pattern_item))); diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc b/gcc/rust/ast/rust-desugar-question-mark.cc index 01400d8..20a4903 100644 --- a/gcc/rust/ast/rust-desugar-question-mark.cc +++ b/gcc/rust/ast/rust-desugar-question-mark.cc @@ -55,7 +55,7 @@ ok_case (Builder &builder) patterns.emplace_back (std::move (val)); auto pattern_item = std::unique_ptr<TupleStructItems> ( - new TupleStructItemsNoRange (std::move (patterns))); + new TupleStructItemsNoRest (std::move (patterns))); auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern ( builder.path_in_expression (LangItem::Kind::RESULT_OK), std::move (pattern_item))); @@ -82,7 +82,7 @@ err_case (Builder &builder) patterns.emplace_back (std::move (val)); auto pattern_item = std::unique_ptr<TupleStructItems> ( - new TupleStructItemsNoRange (std::move (patterns))); + new TupleStructItemsNoRest (std::move (patterns))); auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern ( builder.path_in_expression (LangItem::Kind::RESULT_ERR), std::move (pattern_item))); diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 7b0df25..3c36238 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -282,6 +282,8 @@ public: Expr &get_expr () { return *expr; } + std::unique_ptr<Expr> &get_expr_ptr () { return expr; } + std::string as_string () const override { return path.as_string () + " = " + expr->as_string (); @@ -296,7 +298,11 @@ public: // we have no idea use which of them, just simply return UNKNOWN_LOCATION // now. // Maybe we will figure out when we really need the location in the future. - location_t get_locus () const override { return UNKNOWN_LOCATION; } + location_t get_locus () const override + { + rust_unreachable (); + return UNKNOWN_LOCATION; + } void accept_vis (ASTVisitor &vis) override; @@ -414,6 +420,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_borrowed_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + bool has_borrow_expr () const { return main_or_left_expr != nullptr; } bool get_is_mut () const { return mutability == Mutability::Mut; } @@ -455,6 +467,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_dereferenced_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; } protected: @@ -488,6 +506,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_propagating_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::ErrorPropagation; @@ -536,6 +560,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_negated_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; } protected: @@ -865,6 +895,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_casted_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + // TODO: is this better? Or is a "vis_block" better? TypeNoBounds &get_type_to_cast_to () { @@ -872,6 +908,12 @@ public: return *type_to_convert_to; } + std::unique_ptr<TypeNoBounds> &get_type_to_cast_to_ptr () + { + rust_assert (type_to_convert_to != nullptr); + return type_to_convert_to; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; } protected: @@ -1282,6 +1324,12 @@ public: return *elem_to_copy; } + std::unique_ptr<Expr> &get_elem_to_copy_ptr () + { + rust_assert (elem_to_copy != nullptr); + return elem_to_copy; + } + // TODO: is this better? Or is a "vis_block" better? Expr &get_num_copies () { @@ -1289,6 +1337,12 @@ public: return *num_copies; } + std::unique_ptr<Expr> &get_num_copies_ptr () + { + rust_assert (num_copies != nullptr); + return num_copies; + } + protected: ArrayElemsCopied *clone_array_elems_impl () const override { @@ -1468,6 +1522,12 @@ public: return *array_expr; } + std::unique_ptr<Expr> &get_array_expr_ptr () + { + rust_assert (array_expr != nullptr); + return array_expr; + } + // TODO: is this better? Or is a "vis_block" better? Expr &get_index_expr () { @@ -1475,6 +1535,12 @@ public: return *index_expr; } + std::unique_ptr<Expr> &get_index_expr_ptr () + { + rust_assert (index_expr != nullptr); + return index_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -1599,6 +1665,7 @@ class TupleIndexExpr : public ExprWithoutBlock TupleIndex tuple_index; location_t locus; + bool to_strip; // i.e. pair.0 @@ -1610,13 +1677,15 @@ public: TupleIndexExpr (std::unique_ptr<Expr> tuple_expr, TupleIndex index, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), - tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus) + tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus), + to_strip (false) {} // Copy constructor requires a clone for tuple_expr TupleIndexExpr (TupleIndexExpr const &other) : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), - tuple_index (other.tuple_index), locus (other.locus) + tuple_index (other.tuple_index), locus (other.locus), + to_strip (other.to_strip) { // guard to prevent null dereference (only required if error state) if (other.tuple_expr != nullptr) @@ -1630,6 +1699,7 @@ public: tuple_index = other.tuple_index; locus = other.locus; outer_attrs = other.outer_attrs; + to_strip = other.to_strip; // guard to prevent null dereference (only required if error state) if (other.tuple_expr != nullptr) @@ -1649,8 +1719,8 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if tuple expr is null, so base stripping on that. - void mark_for_strip () override { tuple_expr = nullptr; } - bool is_marked_for_strip () const override { return tuple_expr == nullptr; } + void mark_for_strip () override { to_strip = true; } + bool is_marked_for_strip () const override { return to_strip; } // TODO: is this better? Or is a "vis_block" better? Expr &get_tuple_expr () @@ -1659,6 +1729,12 @@ public: return *tuple_expr; } + std::unique_ptr<Expr> &get_tuple_expr_ptr () + { + rust_assert (tuple_expr != nullptr); + return tuple_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -1807,6 +1883,12 @@ public: rust_assert (base_struct != nullptr); return *base_struct; } + + std::unique_ptr<Expr> &get_base_struct_ptr () + { + rust_assert (base_struct != nullptr); + return base_struct; + } }; /* Base AST node for a single struct expression field (in struct instance @@ -1923,6 +2005,12 @@ public: rust_assert (value != nullptr); return *value; } + + std::unique_ptr<Expr> &get_value_ptr () + { + rust_assert (value != nullptr); + return value; + } }; // Identifier and value variant of StructExprField AST node @@ -2293,6 +2381,12 @@ public: return *receiver; } + std::unique_ptr<Expr> &get_receiver_expr_ptr () + { + rust_assert (receiver != nullptr); + return receiver; + } + const PathExprSegment &get_method_name () const { return method_name; } PathExprSegment &get_method_name () { return method_name; } @@ -2381,6 +2475,12 @@ public: return *receiver; } + std::unique_ptr<Expr> &get_receiver_expr_ptr () + { + rust_assert (receiver != nullptr); + return receiver; + } + Identifier get_field_name () const { return field; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } @@ -2480,6 +2580,12 @@ public: return *pattern; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (pattern != nullptr); + return pattern; + } + Type &get_type () { rust_assert (has_type_given ()); @@ -2532,6 +2638,7 @@ public: Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; } virtual Expr &get_definition_expr () = 0; + virtual std::unique_ptr<Expr> &get_definition_expr_ptr () = 0; }; // Represents a non-type-specified closure expression AST node @@ -2597,6 +2704,12 @@ public: return *closure_inner; } + std::unique_ptr<Expr> &get_definition_expr_ptr () override + { + rust_assert (closure_inner != nullptr); + return closure_inner; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2827,6 +2940,12 @@ public: return *expr.value (); } + std::unique_ptr<Expr> &get_inner_expr_ptr () + { + rust_assert (expr.has_value ()); + return expr.value (); + } + NodeId get_node_id () const override { return node_id; } /* FIXME: AnonConst are always "internal" and should not have outer attributes @@ -2922,8 +3041,7 @@ class ClosureExprInnerTyped : public ClosureExpr { // TODO: spec says typenobounds std::unique_ptr<Type> return_type; - std::unique_ptr<BlockExpr> - expr; // only used because may be polymorphic in future + std::unique_ptr<Expr> expr; // only used because may be polymorphic in future public: std::string as_string () const override; @@ -2947,7 +3065,7 @@ public: { // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) - expr = other.expr->clone_block_expr (); + expr = other.expr->clone_expr (); if (other.return_type != nullptr) return_type = other.return_type->clone_type (); } @@ -2962,7 +3080,7 @@ public: // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) - expr = other.expr->clone_block_expr (); + expr = other.expr->clone_expr (); else expr = nullptr; if (other.return_type != nullptr) @@ -2985,12 +3103,19 @@ public: bool is_marked_for_strip () const override { return expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - BlockExpr &get_definition_expr () override + Expr &get_definition_expr () override { rust_assert (expr != nullptr); return *expr; } + std::unique_ptr<Expr> &get_definition_expr_ptr () override + { + rust_assert (expr != nullptr); + + return expr; + } + // TODO: is this better? Or is a "vis_block" better? Type &get_return_type () { @@ -3147,6 +3272,12 @@ public: return *break_expr; } + std::unique_ptr<Expr> &get_break_expr_ptr () + { + rust_assert (has_break_expr ()); + return break_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3274,6 +3405,18 @@ public: return *to; } + std::unique_ptr<Expr> &get_from_expr_ptr () + { + rust_assert (from != nullptr); + return from; + } + + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3335,6 +3478,12 @@ public: return *from; } + std::unique_ptr<Expr> &get_from_expr_ptr () + { + rust_assert (from != nullptr); + return from; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3397,6 +3546,12 @@ public: return *to; } + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3510,6 +3665,18 @@ public: return *to; } + std::unique_ptr<Expr> &get_from_expr_ptr () + { + rust_assert (from != nullptr); + return from; + } + + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3572,6 +3739,12 @@ public: return *to; } + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3645,6 +3818,12 @@ public: return *expr; } + std::unique_ptr<Expr> &get_boxed_expr_ptr () + { + rust_assert (expr != nullptr); + return expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Box; } protected: @@ -3726,6 +3905,12 @@ public: return *return_expr; } + std::unique_ptr<Expr> &get_returned_expr_ptr () + { + rust_assert (return_expr != nullptr); + return return_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3801,6 +3986,7 @@ public: // TODO: is this better? Or is a "vis_block" better? BlockExpr &get_block_expr () { return *block_expr; } + std::unique_ptr<BlockExpr> &get_block_expr_ptr () { return block_expr; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3886,6 +4072,12 @@ public: return *expr; } + std::unique_ptr<BlockExpr> &get_block_expr_ptr () + { + rust_assert (expr != nullptr); + return expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3978,6 +4170,12 @@ public: return *loop_block; } + std::unique_ptr<BlockExpr> &get_loop_block_ptr () + { + rust_assert (loop_block != nullptr); + return loop_block; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -4078,6 +4276,12 @@ public: return *condition; } + std::unique_ptr<Expr> &get_predicate_expr_ptr () + { + rust_assert (condition != nullptr); + return condition; + } + BaseLoopExpr::Kind get_loop_kind () const override { return BaseLoopExpr::Kind::While; @@ -4156,6 +4360,12 @@ public: return *scrutinee; } + std::unique_ptr<Expr> &get_scrutinee_expr_ptr () + { + rust_assert (scrutinee != nullptr); + return scrutinee; + } + // TODO: this mutable getter seems really dodgy. Think up better way. const std::vector<std::unique_ptr<Pattern>> &get_patterns () const { @@ -4233,6 +4443,12 @@ public: return *iterator_expr; } + std::unique_ptr<Expr> &get_iterator_expr_ptr () + { + rust_assert (iterator_expr != nullptr); + return iterator_expr; + } + // TODO: is this better? Or is a "vis_block" better? Pattern &get_pattern () { @@ -4240,6 +4456,12 @@ public: return *pattern; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (pattern != nullptr); + return pattern; + } + BaseLoopExpr::Kind get_loop_kind () const override { return BaseLoopExpr::Kind::For; @@ -4892,6 +5114,12 @@ public: return *branch_value; } + std::unique_ptr<Expr> &get_scrutinee_expr_ptr () + { + rust_assert (branch_value != nullptr); + return branch_value; + } + const std::vector<MatchCase> &get_match_cases () const { return match_arms; } std::vector<MatchCase> &get_match_cases () { return match_arms; } @@ -5494,6 +5722,8 @@ struct InlineAsmTemplatePiece struct TupleClobber { + TupleClobber (std::string symbol, location_t loc) : symbol (symbol), loc (loc) + {} // as gccrs still doesn't contain a symbol class I have put them as strings std::string symbol; location_t loc; @@ -5667,6 +5897,10 @@ public: } std::vector<TupleTemplateStr> &get_templates () { return templates; } + const std::vector<TupleTemplateStr> &get_templates () const + { + return templates; + } Expr::Kind get_expr_kind () const override { @@ -5685,9 +5919,12 @@ public: void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; } std::vector<LlvmOperand> &get_inputs () { return inputs; } + const std::vector<LlvmOperand> &get_inputs () const { return inputs; } std::vector<LlvmOperand> &get_outputs () { return outputs; } + const std::vector<LlvmOperand> &get_outputs () const { return outputs; } std::vector<TupleClobber> &get_clobbers () { return clobbers; } + const std::vector<TupleClobber> &get_clobbers () const { return clobbers; } }; } // namespace AST diff --git a/gcc/rust/ast/rust-expression-yeast.cc b/gcc/rust/ast/rust-expression-yeast.cc index 9f6a62f..7626abc 100644 --- a/gcc/rust/ast/rust-expression-yeast.cc +++ b/gcc/rust/ast/rust-expression-yeast.cc @@ -21,10 +21,8 @@ #include "rust-desugar-question-mark.h" #include "rust-desugar-try-block.h" #include "rust-desugar-for-loops.h" -#include "rust-ast-full.h" #include "rust-desugar-while-let.h" #include "rust-expr.h" -#include "rust-stmt.h" namespace Rust { namespace AST { @@ -32,7 +30,7 @@ namespace AST { void ExpressionYeast::go (AST::Crate &crate) { - DefaultASTVisitor::visit (crate); + PointerVisitor::visit (crate); } void @@ -54,7 +52,7 @@ ExpressionYeast::dispatch_loops (std::unique_ptr<Expr> &loop_expr) } void -ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr) +ExpressionYeast::reseat (std::unique_ptr<Expr> &expr) { switch (expr->get_expr_kind ()) { @@ -71,47 +69,8 @@ ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr) default: break; } -} - -void -ExpressionYeast::visit (ExprStmt &stmt) -{ - dispatch (stmt.get_expr_ptr ()); - - DefaultASTVisitor::visit (stmt); -} - -void -ExpressionYeast::visit (CallExpr &call) -{ - dispatch (call.get_function_expr_ptr ()); - - for (auto &arg : call.get_params ()) - dispatch (arg); - - DefaultASTVisitor::visit (call); -} - -void -ExpressionYeast::visit (BlockExpr &block) -{ - for (auto &stmt : block.get_statements ()) - if (stmt->get_stmt_kind () == Stmt::Kind::Expr) - dispatch (static_cast<ExprStmt &> (*stmt).get_expr_ptr ()); - - if (block.has_tail_expr ()) - dispatch (block.get_tail_expr_ptr ()); - - DefaultASTVisitor::visit (block); -} - -void -ExpressionYeast::visit (LetStmt &stmt) -{ - if (stmt.has_init_expr ()) - dispatch (stmt.get_init_expr_ptr ()); - DefaultASTVisitor::visit (stmt); + visit (expr); } } // namespace AST diff --git a/gcc/rust/ast/rust-expression-yeast.h b/gcc/rust/ast/rust-expression-yeast.h index 855918f..3f64b1d 100644 --- a/gcc/rust/ast/rust-expression-yeast.h +++ b/gcc/rust/ast/rust-expression-yeast.h @@ -19,7 +19,7 @@ #ifndef RUST_EXPRESSION_YEAST #define RUST_EXPRESSION_YEAST -#include "rust-ast-visitor.h" +#include "rust-ast-pointer-visitor.h" #include "rust-ast.h" #include "rust-desugar-question-mark.h" @@ -28,22 +28,19 @@ namespace AST { // This visitor takes care of all the expression desugars: try-blocks, // error-propagation, etc. -class ExpressionYeast : public AST::DefaultASTVisitor +class ExpressionYeast : public AST::PointerVisitor { - using AST::DefaultASTVisitor::visit; + using AST::PointerVisitor::reseat; + using AST::PointerVisitor::visit; public: void go (AST::Crate &); private: // Dispatch to the proper desugar - void dispatch (std::unique_ptr<Expr> &expr); - void dispatch_loops (std::unique_ptr<Expr> &loop_expr); + void reseat (std::unique_ptr<Expr> &expr) override; - void visit (AST::ExprStmt &) override; - void visit (AST::CallExpr &) override; - void visit (AST::LetStmt &) override; - void visit (AST::BlockExpr &) override; + void dispatch_loops (std::unique_ptr<Expr> &loop_expr); }; } // namespace AST diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc index a29c820..21f4f03 100644 --- a/gcc/rust/ast/rust-fmt.cc +++ b/gcc/rust/ast/rust-fmt.cc @@ -32,41 +32,11 @@ Pieces Pieces::collect (const std::string &to_parse, bool append_newline, ffi::ParseMode parse_mode) { - auto handle - = ffi::collect_pieces (to_parse.c_str (), append_newline, parse_mode); - - // this performs multiple copies, can we avoid them maybe? - // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we - // should transform them into the proper C++ type which we can work with. so - // transform all the strings into C++ strings? all the Option<T> into - // tl::optional<T>? - auto pieces_vector = std::vector<ffi::Piece> (handle.piece_slice.base_ptr, - handle.piece_slice.base_ptr - + handle.piece_slice.len); - - return Pieces (handle, std::move (pieces_vector)); -} - -Pieces::~Pieces () { ffi::destroy_pieces (handle); } - -Pieces::Pieces (const Pieces &other) : pieces_vector (other.pieces_vector) -{ - handle = ffi::clone_pieces (other.handle); + Pieces ret (to_parse, ffi::FFIVec<ffi::Piece> ()); + ret.data->second = ffi::collect_pieces (ffi::RustHamster (ret.data->first), + append_newline, parse_mode); + return ret; } -Pieces & -Pieces::operator= (const Pieces &other) -{ - handle = ffi::clone_pieces (other.handle); - pieces_vector = other.pieces_vector; - - return *this; -} - -Pieces::Pieces (Pieces &&other) - : pieces_vector (std::move (other.pieces_vector)), - handle (clone_pieces (other.handle)) -{} - } // namespace Fmt } // namespace Rust diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h index 3722db2..e59bed3 100644 --- a/gcc/rust/ast/rust-fmt.h +++ b/gcc/rust/ast/rust-fmt.h @@ -20,20 +20,171 @@ #define RUST_FMT_H #include "rust-system.h" - -// FIXME: How to encode Option? +#include "optional.h" namespace Rust { namespace Fmt { namespace ffi { +extern "C" { + +unsigned char *rust_ffi_alloc (size_t count, size_t elem_size, size_t align); + +void rust_ffi_dealloc (unsigned char *data, size_t count, size_t elem_size, + size_t align); + +} // extern "C" + +template <typename T> class FFIVec +{ + T *data; + size_t len; + size_t cap; + +public: + FFIVec () : data ((T *) alignof (T)), len (0), cap (0) {} + + FFIVec (const FFIVec &) = delete; + FFIVec &operator= (const FFIVec &) = delete; + + FFIVec (FFIVec &&other) : data (other.data), len (other.len), cap (other.cap) + { + other.data = (T *) alignof (T); + other.len = 0; + other.cap = 0; + } + + FFIVec &operator= (FFIVec &&other) + { + this->~FFIVec (); + new (this) FFIVec (std::move (other)); + return *this; + } + + ~FFIVec () + { + // T can't be zero-sized + if (cap) + rust_ffi_dealloc ((unsigned char *) data, cap, sizeof (T), alignof (T)); + } + + size_t size () const { return len; } + + const T &operator[] (size_t idx) const + { + rust_assert (idx <= len); + return data[idx]; + } + + T *begin () { return data; } + const T *begin () const { return data; } + T *end () { return data + len; } + const T *end () const { return data + len; } +}; + +// https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md +template <typename T, + typename = + typename std::enable_if<std::is_standard_layout<T>::value>::type> +class FFIOpt +{ +public: + template <typename U> + FFIOpt (U &&val) : some{Some::KIND, std::forward<U> (val)} + {} + + FFIOpt () : none{None::KIND} {} + + FFIOpt (const FFIOpt &other) + { + if (other.has_value ()) + new (&some) Some{Some::KIND, other.some.val}; + else + new (&none) None{None::KIND}; + } + + FFIOpt (FFIOpt &&other) + { + if (other.has_value ()) + new (&some) Some{Some::KIND, std::move (other.some.val)}; + else + new (&none) None{None::KIND}; + } + + ~FFIOpt () + { + if (has_value ()) + some.~Some (); + else + none.~None (); + } + + FFIOpt &operator= (const FFIOpt &other) + { + this->~FFIOpt (); + new (this) FFIOpt (other); + return *this; + } + + FFIOpt &operator= (FFIOpt &&other) + { + this->~FFIOpt (); + new (this) FFIOpt (std::move (other)); + return *this; + } + + tl::optional<std::reference_wrapper<T>> get_opt () + { + if (has_value ()) + return std::ref (some.val); + else + return tl::nullopt; + } + + tl::optional<std::reference_wrapper<const T>> get_opt () const + { + if (has_value ()) + return std::ref (some.val); + else + return tl::nullopt; + } + + bool has_value () const { return some.kind == Some::KIND; } + + operator bool () const { return has_value (); } + +private: + struct Some + { + static constexpr uint8_t KIND = 0; + uint8_t kind; + T val; + }; + + struct None + { + static constexpr uint8_t KIND = 1; + uint8_t kind; + }; + + union + { + Some some; + None none; + }; +}; + struct RustHamster { const char *ptr; size_t len; std::string to_string () const; + + explicit RustHamster (const std::string &str) + : ptr (str.data ()), len (str.size ()) + {} }; /// Enum of alignments which are supported. @@ -166,33 +317,33 @@ struct Count struct FormatSpec { /// Optionally specified character to fill alignment with. - const uint32_t *fill; + FFIOpt<uint32_t> fill; /// Span of the optionally specified fill character. - const InnerSpan *fill_span; + FFIOpt<InnerSpan> fill_span; /// Optionally specified alignment. Alignment align; /// The `+` or `-` flag. - const Sign *sign; + FFIOpt<Sign> sign; /// The `#` flag. bool alternate; /// The `0` flag. bool zero_pad; /// The `x` or `X` flag. (Only for `Debug`.) - const DebugHex *debug_hex; + FFIOpt<DebugHex> debug_hex; /// The integer precision to use. Count precision; /// The span of the precision formatting flag (for diagnostics). - const InnerSpan *precision_span; + FFIOpt<InnerSpan> precision_span; /// The string width requested for the resulting format. Count width; /// The span of the width formatting flag (for diagnostics). - const InnerSpan *width_span; + FFIOpt<InnerSpan> width_span; /// The descriptor string representing the name of the format desired for /// this argument, this can be empty or any number of characters, although /// it is required to be one word. RustHamster ty; /// The span of the descriptor string (for diagnostics). - const InnerSpan *ty_span; + FFIOpt<InnerSpan> ty_span; }; /// Representation of an argument specification. @@ -238,26 +389,6 @@ struct Piece }; }; -struct PieceSlice -{ - const Piece *base_ptr; - size_t len; - size_t cap; -}; - -struct RustString -{ - const unsigned char *ptr; - size_t len; - size_t cap; -}; - -struct FormatArgsHandle -{ - PieceSlice piece_slice; - RustString rust_string; -}; - enum ParseMode { Format = 0, @@ -266,12 +397,10 @@ enum ParseMode extern "C" { -FormatArgsHandle collect_pieces (const char *input, bool append_newline, - ParseMode parse_mode); +FFIVec<Piece> collect_pieces (RustHamster input, bool append_newline, + ParseMode parse_mode); -FormatArgsHandle clone_pieces (const FormatArgsHandle &); - -void destroy_pieces (FormatArgsHandle); +FFIVec<Piece> clone_pieces (const FFIVec<Piece> &); } // extern "C" @@ -281,33 +410,20 @@ struct Pieces { static Pieces collect (const std::string &to_parse, bool append_newline, ffi::ParseMode parse_mode); - ~Pieces (); - - Pieces (const Pieces &other); - Pieces &operator= (const Pieces &other); - Pieces (Pieces &&other); - - const std::vector<ffi::Piece> &get_pieces () const { return pieces_vector; } - - // { - // slice = clone_pieces (&other.slice); - // to_parse = other.to_parse; - - // return *this; - // } + const ffi::FFIVec<ffi::Piece> &get_pieces () const { return data->second; } private: - Pieces (ffi::FormatArgsHandle handle, std::vector<ffi::Piece> &&pieces_vector) - : pieces_vector (std::move (pieces_vector)), handle (handle) + Pieces (std::string str, ffi::FFIVec<ffi::Piece> pieces) + : data ( + std::make_shared<decltype (data)::element_type> (std::move (str), + std::move (pieces))) {} - std::vector<ffi::Piece> pieces_vector; - - // this memory is held for FFI reasons - it needs to be released and cloned - // precisely, so try to not access it/modify it if possible. you should - // instead work with `pieces_vector` - ffi::FormatArgsHandle handle; + // makes copying simpler + // also, we'd need to keep the parsed string in a shared_ptr anyways + // since we store pointers into the parsed string + std::shared_ptr<std::pair<std::string, ffi::FFIVec<ffi::Piece>>> data; }; } // namespace Fmt diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index d11eed7..7aea763 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -631,6 +631,12 @@ public: return *param_name; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (param_name != nullptr); + return param_name; + } + const Pattern &get_pattern () const { rust_assert (param_name != nullptr); @@ -714,6 +720,12 @@ public: return *param_name; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (param_name != nullptr); + return param_name; + } + bool has_name () const { return param_name != nullptr; } // TODO: is this better? Or is a "vis_block" better? @@ -1567,6 +1579,9 @@ public: location_t get_locus () const override final { return locus; } + // needed to override AssociatedItem::get_node_id + NodeId get_node_id () const override final { return VisItem::get_node_id (); } + void accept_vis (ASTVisitor &vis) override; // Invalid if existing type is null, so base stripping on that. @@ -1595,6 +1610,12 @@ public: return *existing_type; } + std::unique_ptr<Type> &get_type_aliased_ptr () + { + rust_assert (existing_type != nullptr); + return existing_type; + } + Identifier get_new_type_name () const { return new_type_name; } Item::Kind get_item_kind () const override { return Item::Kind::TypeAlias; } @@ -2515,9 +2536,12 @@ public: location_t get_locus () const override final { return locus; } + // needed to override AssociatedItem::get_node_id + NodeId get_node_id () const override final { return VisItem::get_node_id (); } + void accept_vis (ASTVisitor &vis) override; - // Invalid if type or expression are null, so base stripping on that. + // Invalid if type and expression are null, so base stripping on that. void mark_for_strip () override { type = nullptr; @@ -2528,7 +2552,7 @@ public: return type == nullptr && const_expr == nullptr; } - bool has_expr () { return const_expr != nullptr; } + bool has_expr () const { return const_expr != nullptr; } // TODO: is this better? Or is a "vis_block" better? Expr &get_expr () @@ -2695,123 +2719,6 @@ protected: } }; -// Constant item within traits -class TraitItemConst : public TraitItem -{ - std::vector<Attribute> outer_attrs; - Identifier name; - std::unique_ptr<Type> type; - - // bool has_expression; - std::unique_ptr<Expr> expr; - -public: - // Whether the constant item has an associated expression. - bool has_expression () const { return expr != nullptr; } - - TraitItemConst (Identifier name, std::unique_ptr<Type> type, - std::unique_ptr<Expr> expr, - std::vector<Attribute> outer_attrs, location_t locus) - : TraitItem (locus), outer_attrs (std::move (outer_attrs)), - name (std::move (name)), type (std::move (type)), expr (std::move (expr)) - {} - - // Copy constructor with clones - TraitItemConst (TraitItemConst const &other) - : TraitItem (other.locus), outer_attrs (other.outer_attrs), - name (other.name) - { - node_id = other.node_id; - - // guard to prevent null dereference - if (other.expr != nullptr) - expr = other.expr->clone_expr (); - - // guard to prevent null dereference (only for error state) - if (other.type != nullptr) - type = other.type->clone_type (); - } - - // Overloaded assignment operator to clone - TraitItemConst &operator= (TraitItemConst const &other) - { - TraitItem::operator= (other); - outer_attrs = other.outer_attrs; - name = other.name; - locus = other.locus; - node_id = other.node_id; - - // guard to prevent null dereference - if (other.expr != nullptr) - expr = other.expr->clone_expr (); - else - expr = nullptr; - - // guard to prevent null dereference (only for error state) - if (other.type != nullptr) - type = other.type->clone_type (); - else - type = nullptr; - - return *this; - } - - // move constructors - TraitItemConst (TraitItemConst &&other) = default; - TraitItemConst &operator= (TraitItemConst &&other) = default; - - std::string as_string () const override; - - location_t get_locus () const override { return locus; } - - void accept_vis (ASTVisitor &vis) override; - - // Invalid if type is null, so base stripping on that. - void mark_for_strip () override { type = nullptr; } - bool is_marked_for_strip () const override { return type == nullptr; } - - // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - - bool has_expr () const { return expr != nullptr; } - - // TODO: is this better? Or is a "vis_block" better? - Expr &get_expr () - { - rust_assert (has_expr ()); - return *expr; - } - - std::unique_ptr<Expr> &get_expr_ptr () - { - rust_assert (has_expr ()); - return expr; - } - - // TODO: is this better? Or is a "vis_block" better? - Type &get_type () - { - rust_assert (type != nullptr); - return *type; - } - - std::unique_ptr<Type> &get_type_ptr () - { - rust_assert (type != nullptr); - return type; - } - - Identifier get_identifier () const { return name; } - -protected: - // Clone function implementation as (not pure) virtual method - TraitItemConst *clone_associated_item_impl () const override - { - return new TraitItemConst (*this); - } -}; - // Type items within traits class TraitItemType : public TraitItem { diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc index 793423a..068e364 100644 --- a/gcc/rust/ast/rust-path.cc +++ b/gcc/rust/ast/rust-path.cc @@ -167,14 +167,13 @@ Path::convert_to_simple_path (bool with_opening_scope_resolution) const 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") + if (segment.is_error () || segment.has_generic_args ()) 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 ())); + simple_segments.emplace_back (std::move (segment_str), + segment.get_locus ()); } // kind of a HACK to get locus depending on opening scope resolution @@ -258,8 +257,8 @@ TypePath::as_simple_path () const // 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 ())); + simple_segments.emplace_back (std::move (segment_str), + segment->get_locus ()); } return SimplePath (std::move (simple_segments), has_opening_scope_resolution, diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index a1b19d5..be04882 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -377,6 +377,13 @@ public: return *type; } + std::unique_ptr<AST::Type> &get_type_ptr () + { + rust_assert (has_type ()); + + return type; + } + GenericArg &get_default_value_unchecked () { rust_assert (has_default_value ()); @@ -448,9 +455,7 @@ public: generic_args.clear (); generic_args.reserve (other.generic_args.size ()); for (const auto &arg : other.generic_args) - { - generic_args.push_back (GenericArg (arg)); - } + generic_args.emplace_back (arg); } ~GenericArgs () = default; @@ -465,9 +470,7 @@ public: generic_args.clear (); generic_args.reserve (other.generic_args.size ()); for (const auto &arg : other.generic_args) - { - generic_args.push_back (GenericArg (arg)); - } + generic_args.emplace_back (arg); return *this; } @@ -1252,7 +1255,7 @@ public: TraitBound *to_trait_bound (bool in_parens) const override; location_t get_locus () const override final { return locus; } - NodeId get_node_id () const { return node_id; } + NodeId get_node_id () const override { return node_id; } void mark_for_strip () override {} bool is_marked_for_strip () const override { return false; } diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc index 15ab0b7..a2fe5d5 100644 --- a/gcc/rust/ast/rust-pattern.cc +++ b/gcc/rust/ast/rust-pattern.cc @@ -186,8 +186,8 @@ StructPatternElements::as_string () const str += "\n " + field->as_string (); } - str += "\n Etc: "; - if (has_struct_pattern_etc) + str += "\n Has rest: "; + if (has_rest_pattern) str += "true"; else str += "false"; @@ -212,7 +212,7 @@ StructPattern::as_string () const } std::string -TupleStructItemsNoRange::as_string () const +TupleStructItemsNoRest::as_string () const { std::string str; @@ -223,7 +223,7 @@ TupleStructItemsNoRange::as_string () const } std::string -TupleStructItemsRange::as_string () const +TupleStructItemsHasRest::as_string () const { std::string str ("\n Lower patterns: "); @@ -264,7 +264,7 @@ TupleStructPattern::as_string () const } std::string -TuplePatternItemsMultiple::as_string () const +TuplePatternItemsNoRest::as_string () const { std::string str; @@ -275,7 +275,7 @@ TuplePatternItemsMultiple::as_string () const } std::string -TuplePatternItemsRanged::as_string () const +TuplePatternItemsHasRest::as_string () const { std::string str; @@ -421,7 +421,7 @@ SlicePattern::accept_vis (ASTVisitor &vis) } void -TuplePatternItemsRanged::accept_vis (ASTVisitor &vis) +TuplePatternItemsHasRest::accept_vis (ASTVisitor &vis) { vis.visit (*this); } @@ -433,7 +433,7 @@ TuplePattern::accept_vis (ASTVisitor &vis) } void -TuplePatternItemsMultiple::accept_vis (ASTVisitor &vis) +TuplePatternItemsNoRest::accept_vis (ASTVisitor &vis) { vis.visit (*this); } @@ -517,13 +517,13 @@ StructPattern::accept_vis (ASTVisitor &vis) } void -TupleStructItemsNoRange::accept_vis (ASTVisitor &vis) +TupleStructItemsNoRest::accept_vis (ASTVisitor &vis) { vis.visit (*this); } void -TupleStructItemsRange::accept_vis (ASTVisitor &vis) +TupleStructItemsHasRest::accept_vis (ASTVisitor &vis) { vis.visit (*this); } diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h index 4945ec4..0da1981 100644 --- a/gcc/rust/ast/rust-pattern.h +++ b/gcc/rust/ast/rust-pattern.h @@ -20,6 +20,7 @@ #define RUST_AST_PATTERN_H #include "rust-ast.h" +#include "rust-path.h" namespace Rust { namespace AST { @@ -143,6 +144,12 @@ public: return *subpattern; } + std::unique_ptr<Pattern> &get_subpattern_ptr () + { + rust_assert (has_subpattern ()); + return subpattern; + } + Identifier get_ident () const { return variable_ident; } bool get_is_mut () const { return is_mut; } @@ -518,6 +525,12 @@ public: return *pattern; } + std::unique_ptr<Pattern> &get_referenced_pattern_ptr () + { + rust_assert (pattern != nullptr); + return pattern; + } + bool is_double_reference () const { return has_two_amps; } bool get_is_mut () const { return is_mut; } @@ -681,6 +694,12 @@ public: return *tuple_pattern; } + std::unique_ptr<Pattern> &get_index_pattern_ptr () + { + rust_assert (tuple_pattern != nullptr); + return tuple_pattern; + } + ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; } protected: @@ -761,6 +780,12 @@ public: return *ident_pattern; } + std::unique_ptr<Pattern> &get_ident_pattern_ptr () + { + rust_assert (ident_pattern != nullptr); + return ident_pattern; + } + ItemType get_item_type () const override final { return ItemType::IDENT_PAT; } protected: @@ -818,7 +843,7 @@ class StructPatternElements // bool has_struct_pattern_fields; std::vector<std::unique_ptr<StructPatternField>> fields; - bool has_struct_pattern_etc; + bool has_rest_pattern; std::vector<Attribute> struct_pattern_etc_attrs; // StructPatternEtc etc; @@ -834,29 +859,29 @@ public: * no etc). */ bool is_empty () const { - return !has_struct_pattern_fields () && !has_struct_pattern_etc; + return !has_struct_pattern_fields () && !has_rest_pattern; } - bool has_etc () const { return has_struct_pattern_etc; } + bool has_rest () const { return has_rest_pattern; } // Constructor for StructPatternElements with both (potentially) StructPatternElements ( std::vector<std::unique_ptr<StructPatternField>> fields, std::vector<Attribute> etc_attrs) - : fields (std::move (fields)), has_struct_pattern_etc (true), + : fields (std::move (fields)), has_rest_pattern (true), struct_pattern_etc_attrs (std::move (etc_attrs)) {} // Constructor for StructPatternElements with no StructPatternEtc StructPatternElements ( std::vector<std::unique_ptr<StructPatternField>> fields) - : fields (std::move (fields)), has_struct_pattern_etc (false), + : fields (std::move (fields)), has_rest_pattern (false), struct_pattern_etc_attrs () {} // Copy constructor with vector clone StructPatternElements (StructPatternElements const &other) - : has_struct_pattern_etc (other.has_struct_pattern_etc), + : has_rest_pattern (other.has_rest_pattern), struct_pattern_etc_attrs (other.struct_pattern_etc_attrs) { fields.reserve (other.fields.size ()); @@ -868,7 +893,7 @@ public: StructPatternElements &operator= (StructPatternElements const &other) { struct_pattern_etc_attrs = other.struct_pattern_etc_attrs; - has_struct_pattern_etc = other.has_struct_pattern_etc; + has_rest_pattern = other.has_rest_pattern; fields.clear (); fields.reserve (other.fields.size ()); @@ -913,7 +938,7 @@ public: void strip_etc () { - has_struct_pattern_etc = false; + has_rest_pattern = false; struct_pattern_etc_attrs.clear (); struct_pattern_etc_attrs.shrink_to_fit (); } @@ -975,49 +1000,62 @@ protected: } }; -// Base abstract class for patterns used in TupleStructPattern -class TupleStructItems +// Base abstract class for TupleStructItems, TuplePatternItems & +// SlicePatternItems +class PatternItems { public: enum ItemType { - RANGE, - NO_RANGE + NO_REST, + HAS_REST, }; - virtual ~TupleStructItems () {} + virtual ~PatternItems () {} // TODO: should this store location data? // Unique pointer custom clone function - std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const + std::unique_ptr<PatternItems> clone_pattern_items () const { - return std::unique_ptr<TupleStructItems> (clone_tuple_struct_items_impl ()); + return std::unique_ptr<PatternItems> (clone_pattern_items_impl ()); } virtual std::string as_string () const = 0; - + virtual ItemType get_item_type () const = 0; virtual void accept_vis (ASTVisitor &vis) = 0; - virtual ItemType get_item_type () const = 0; +protected: + virtual PatternItems *clone_pattern_items_impl () const = 0; +}; + +// Base abstract class for patterns used in TupleStructPattern +class TupleStructItems : public PatternItems +{ +public: + // Unique pointer custom clone function + std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const + { + return std::unique_ptr<TupleStructItems> (clone_pattern_items_impl ()); + } protected: // pure virtual clone implementation - virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0; + virtual TupleStructItems *clone_pattern_items_impl () const = 0; }; // Class for non-ranged tuple struct pattern patterns -class TupleStructItemsNoRange : public TupleStructItems +class TupleStructItemsNoRest : public TupleStructItems { std::vector<std::unique_ptr<Pattern>> patterns; public: - TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns) + TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns) : patterns (std::move (patterns)) {} // Copy constructor with vector clone - TupleStructItemsNoRange (TupleStructItemsNoRange const &other) + TupleStructItemsNoRest (TupleStructItemsNoRest const &other) { patterns.reserve (other.patterns.size ()); for (const auto &e : other.patterns) @@ -1025,7 +1063,7 @@ public: } // Overloaded assignment operator with vector clone - TupleStructItemsNoRange &operator= (TupleStructItemsNoRange const &other) + TupleStructItemsNoRest &operator= (TupleStructItemsNoRest const &other) { patterns.clear (); patterns.reserve (other.patterns.size ()); @@ -1036,9 +1074,8 @@ public: } // move constructors - TupleStructItemsNoRange (TupleStructItemsNoRange &&other) = default; - TupleStructItemsNoRange &operator= (TupleStructItemsNoRange &&other) - = default; + TupleStructItemsNoRest (TupleStructItemsNoRest &&other) = default; + TupleStructItemsNoRest &operator= (TupleStructItemsNoRest &&other) = default; std::string as_string () const override; @@ -1051,32 +1088,32 @@ public: return patterns; } - ItemType get_item_type () const override final { return ItemType::NO_RANGE; } + ItemType get_item_type () const override final { return ItemType::NO_REST; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TupleStructItemsNoRange *clone_tuple_struct_items_impl () const override + TupleStructItemsNoRest *clone_pattern_items_impl () const override { - return new TupleStructItemsNoRange (*this); + return new TupleStructItemsNoRest (*this); } }; // Class for ranged tuple struct pattern patterns -class TupleStructItemsRange : public TupleStructItems +class TupleStructItemsHasRest : public TupleStructItems { std::vector<std::unique_ptr<Pattern>> lower_patterns; std::vector<std::unique_ptr<Pattern>> upper_patterns; public: - TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns, - std::vector<std::unique_ptr<Pattern>> upper_patterns) + TupleStructItemsHasRest (std::vector<std::unique_ptr<Pattern>> lower_patterns, + std::vector<std::unique_ptr<Pattern>> upper_patterns) : lower_patterns (std::move (lower_patterns)), upper_patterns (std::move (upper_patterns)) {} // Copy constructor with vector clone - TupleStructItemsRange (TupleStructItemsRange const &other) + TupleStructItemsHasRest (TupleStructItemsHasRest const &other) { lower_patterns.reserve (other.lower_patterns.size ()); for (const auto &e : other.lower_patterns) @@ -1088,7 +1125,7 @@ public: } // Overloaded assignment operator to clone - TupleStructItemsRange &operator= (TupleStructItemsRange const &other) + TupleStructItemsHasRest &operator= (TupleStructItemsHasRest const &other) { lower_patterns.clear (); lower_patterns.reserve (other.lower_patterns.size ()); @@ -1104,8 +1141,9 @@ public: } // move constructors - TupleStructItemsRange (TupleStructItemsRange &&other) = default; - TupleStructItemsRange &operator= (TupleStructItemsRange &&other) = default; + TupleStructItemsHasRest (TupleStructItemsHasRest &&other) = default; + TupleStructItemsHasRest &operator= (TupleStructItemsHasRest &&other) + = default; std::string as_string () const override; @@ -1131,14 +1169,14 @@ public: return upper_patterns; } - ItemType get_item_type () const override final { return ItemType::RANGE; } + ItemType get_item_type () const override final { return ItemType::HAS_REST; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TupleStructItemsRange *clone_tuple_struct_items_impl () const override + TupleStructItemsHasRest *clone_pattern_items_impl () const override { - return new TupleStructItemsRange (*this); + return new TupleStructItemsHasRest (*this); } }; @@ -1221,49 +1259,32 @@ protected: }; // Base abstract class representing TuplePattern patterns -class TuplePatternItems +class TuplePatternItems : public PatternItems { public: - enum TuplePatternItemType - { - MULTIPLE, - RANGED, - }; - - virtual ~TuplePatternItems () {} - - // TODO: should this store location data? - // Unique pointer custom clone function std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const { - return std::unique_ptr<TuplePatternItems> ( - clone_tuple_pattern_items_impl ()); + return std::unique_ptr<TuplePatternItems> (clone_pattern_items_impl ()); } - virtual std::string as_string () const = 0; - - virtual void accept_vis (ASTVisitor &vis) = 0; - - virtual TuplePatternItemType get_pattern_type () const = 0; - protected: // pure virtual clone implementation - virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0; + virtual TuplePatternItems *clone_pattern_items_impl () const = 0; }; -// Class representing TuplePattern patterns where there are multiple patterns -class TuplePatternItemsMultiple : public TuplePatternItems +// Class representing TuplePattern patterns which contains no rest pattern +class TuplePatternItemsNoRest : public TuplePatternItems { std::vector<std::unique_ptr<Pattern>> patterns; public: - TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns) + TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns) : patterns (std::move (patterns)) {} // Copy constructor with vector clone - TuplePatternItemsMultiple (TuplePatternItemsMultiple const &other) + TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other) { patterns.reserve (other.patterns.size ()); for (const auto &e : other.patterns) @@ -1271,7 +1292,7 @@ public: } // Overloaded assignment operator to vector clone - TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple const &other) + TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest const &other) { patterns.clear (); patterns.reserve (other.patterns.size ()); @@ -1282,8 +1303,8 @@ public: } // move constructors - TuplePatternItemsMultiple (TuplePatternItemsMultiple &&other) = default; - TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple &&other) + TuplePatternItemsNoRest (TuplePatternItemsNoRest &&other) = default; + TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest &&other) = default; std::string as_string () const override; @@ -1297,35 +1318,33 @@ public: return patterns; } - TuplePatternItemType get_pattern_type () const override - { - return TuplePatternItemType::MULTIPLE; - } + ItemType get_item_type () const override { return ItemType::NO_REST; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TuplePatternItemsMultiple *clone_tuple_pattern_items_impl () const override + TuplePatternItemsNoRest *clone_pattern_items_impl () const override { - return new TuplePatternItemsMultiple (*this); + return new TuplePatternItemsNoRest (*this); } }; -// Class representing TuplePattern patterns where there are a range of patterns -class TuplePatternItemsRanged : public TuplePatternItems +// Class representing TuplePattern patterns which contains a rest pattern +class TuplePatternItemsHasRest : public TuplePatternItems { std::vector<std::unique_ptr<Pattern>> lower_patterns; std::vector<std::unique_ptr<Pattern>> upper_patterns; public: - TuplePatternItemsRanged (std::vector<std::unique_ptr<Pattern>> lower_patterns, - std::vector<std::unique_ptr<Pattern>> upper_patterns) + TuplePatternItemsHasRest ( + std::vector<std::unique_ptr<Pattern>> lower_patterns, + std::vector<std::unique_ptr<Pattern>> upper_patterns) : lower_patterns (std::move (lower_patterns)), upper_patterns (std::move (upper_patterns)) {} // Copy constructor with vector clone - TuplePatternItemsRanged (TuplePatternItemsRanged const &other) + TuplePatternItemsHasRest (TuplePatternItemsHasRest const &other) { lower_patterns.reserve (other.lower_patterns.size ()); for (const auto &e : other.lower_patterns) @@ -1337,7 +1356,7 @@ public: } // Overloaded assignment operator to clone - TuplePatternItemsRanged &operator= (TuplePatternItemsRanged const &other) + TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest const &other) { lower_patterns.clear (); lower_patterns.reserve (other.lower_patterns.size ()); @@ -1353,8 +1372,8 @@ public: } // move constructors - TuplePatternItemsRanged (TuplePatternItemsRanged &&other) = default; - TuplePatternItemsRanged &operator= (TuplePatternItemsRanged &&other) + TuplePatternItemsHasRest (TuplePatternItemsHasRest &&other) = default; + TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest &&other) = default; std::string as_string () const override; @@ -1381,17 +1400,14 @@ public: return upper_patterns; } - TuplePatternItemType get_pattern_type () const override - { - return TuplePatternItemType::RANGED; - } + ItemType get_item_type () const override { return ItemType::HAS_REST; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - TuplePatternItemsRanged *clone_tuple_pattern_items_impl () const override + TuplePatternItemsHasRest *clone_pattern_items_impl () const override { - return new TuplePatternItemsRanged (*this); + return new TuplePatternItemsHasRest (*this); } }; @@ -1508,6 +1524,12 @@ public: return *pattern_in_parens; } + std::unique_ptr<Pattern> &get_pattern_in_parens_ptr () + { + rust_assert (pattern_in_parens != nullptr); + return pattern_in_parens; + } + NodeId get_node_id () const override { return node_id; } Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Grouped; } @@ -1522,35 +1544,18 @@ protected: }; // Base abstract class representing patterns in a SlicePattern -class SlicePatternItems +class SlicePatternItems : public PatternItems { public: - enum SlicePatternItemType - { - NO_REST, - HAS_REST, - }; - - virtual ~SlicePatternItems () {} - - // TODO: should this store location data? - // Unique pointer custom clone function std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const { - return std::unique_ptr<SlicePatternItems> ( - clone_slice_pattern_items_impl ()); + return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ()); } - virtual std::string as_string () const = 0; - - virtual void accept_vis (ASTVisitor &vis) = 0; - - virtual SlicePatternItemType get_pattern_type () const = 0; - protected: // pure virtual clone implementation - virtual SlicePatternItems *clone_slice_pattern_items_impl () const = 0; + virtual SlicePatternItems *clone_pattern_items_impl () const = 0; }; // Class representing the patterns in a SlicePattern without `..` @@ -1598,15 +1603,12 @@ public: return patterns; } - SlicePatternItemType get_pattern_type () const override - { - return SlicePatternItemType::NO_REST; - } + ItemType get_item_type () const override { return ItemType::NO_REST; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - SlicePatternItemsNoRest *clone_slice_pattern_items_impl () const override + SlicePatternItemsNoRest *clone_pattern_items_impl () const override { return new SlicePatternItemsNoRest (*this); } @@ -1683,15 +1685,12 @@ public: return upper_patterns; } - SlicePatternItemType get_pattern_type () const override - { - return SlicePatternItemType::HAS_REST; - } + ItemType get_item_type () const override { return ItemType::HAS_REST; } protected: /* Use covariance to implement clone function as returning this object rather * than base */ - SlicePatternItemsHasRest *clone_slice_pattern_items_impl () const override + SlicePatternItemsHasRest *clone_pattern_items_impl () const override { return new SlicePatternItemsHasRest (*this); } diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h index f843a79..5fb00ef 100644 --- a/gcc/rust/ast/rust-stmt.h +++ b/gcc/rust/ast/rust-stmt.h @@ -201,6 +201,12 @@ public: return *variables_pattern; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (variables_pattern != nullptr); + return variables_pattern; + } + Type &get_type () { rust_assert (has_type ()); diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index 2a3496b..014963f 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -571,6 +571,12 @@ public: return *type; } + std::unique_ptr<TypeNoBounds> &get_type_pointed_to_ptr () + { + rust_assert (type != nullptr); + return type; + } + // Getter for direct access to the type unique_ptr std::unique_ptr<TypeNoBounds> &get_type_ptr () { return type; } @@ -646,6 +652,12 @@ public: return *type; } + std::unique_ptr<TypeNoBounds> &get_type_referenced_ptr () + { + rust_assert (type != nullptr); + return type; + } + bool get_has_mut () const { return has_mut; } Lifetime &get_lifetime () { return lifetime.value (); } @@ -720,6 +732,12 @@ public: return *elem_type; } + std::unique_ptr<Type> &get_elem_type_ptr () + { + rust_assert (elem_type != nullptr); + return elem_type; + } + // TODO: would a "vis_expr" be better? AnonConst &get_size_expr () { @@ -986,7 +1004,7 @@ public: return_type (std::move (type)), locus (locus) { if (!variadic_attrs.empty ()) - is_variadic = true; + _is_variadic = true; } // Copy constructor with clone @@ -1044,14 +1062,24 @@ public: return *return_type; } + std::unique_ptr<TypeNoBounds> &get_return_type_ptr () + { + rust_assert (has_return_type ()); + return return_type; + } + FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; } BareFunctionType *reconstruct_impl () const override { + std::unique_ptr<TypeNoBounds> ret_type = nullptr; + if (return_type != nullptr) + ret_type = return_type->reconstruct (); + return new BareFunctionType ( for_lifetimes, function_qualifiers, params, /* FIXME: Should params be reconstruct() as well? */ - _is_variadic, variadic_attrs, return_type->reconstruct (), locus); + _is_variadic, variadic_attrs, std::move (ret_type), locus); } protected: |
