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:  | 
