| /* General AST-related method implementations for Rust frontend. |
| Copyright (C) 2009-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-system.h" |
| #include "rust-ast-full.h" |
| #include "rust-diagnostics.h" |
| #include "rust-ast-visitor.h" |
| #include "rust-macro.h" |
| #include "rust-lex.h" |
| #include "rust-parse.h" |
| #include "rust-operators.h" |
| |
| namespace Rust { |
| namespace AST { |
| |
| RangeKind |
| tokenid_to_rangekind (TokenId id) |
| { |
| switch (id) |
| { |
| case DOT_DOT_EQ: |
| return RangeKind::INCLUDED; |
| case ELLIPSIS: |
| return RangeKind::ELLIPSIS; |
| case DOT_DOT: |
| return RangeKind::EXCLUDED; |
| default: |
| rust_unreachable (); |
| } |
| } |
| |
| std::string |
| LiteralPattern::as_string () const |
| { |
| return lit.as_string (); |
| } |
| |
| std::string |
| IdentifierPattern::as_string () const |
| { |
| // TODO: maybe rewrite to work with non-linearisable patterns |
| std::string str; |
| |
| if (is_ref) |
| str += "ref "; |
| |
| if (is_mut) |
| str += "mut "; |
| |
| str += variable_ident.as_string (); |
| |
| if (has_pattern_to_bind ()) |
| str += " @ " + to_bind->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| RangePatternBoundLiteral::as_string () const |
| { |
| std::string str; |
| |
| if (has_minus) |
| str += "-"; |
| |
| str += literal.as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| RangePattern::as_string () const |
| { |
| // TODO: maybe rewrite to work with non-linearisable bounds |
| switch (range_kind) |
| { |
| case RangeKind::EXCLUDED: |
| return lower->as_string () + ".." + upper->as_string (); |
| case RangeKind::INCLUDED: |
| return lower->as_string () + "..=" + upper->as_string (); |
| case RangeKind::ELLIPSIS: |
| return lower->as_string () + "..." + upper->as_string (); |
| default: |
| rust_unreachable (); |
| } |
| } |
| |
| std::string |
| ReferencePattern::as_string () const |
| { |
| // TODO: maybe rewrite to work with non-linearisable patterns |
| std::string str ("&"); |
| |
| if (has_two_amps) |
| str += "&"; |
| |
| if (is_mut) |
| str += "mut "; |
| |
| str += pattern->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| StructPatternField::as_string () const |
| { |
| // outer attributes |
| std::string str = append_attributes (outer_attrs, OUTER); |
| |
| return str; |
| } |
| |
| std::string |
| StructPatternFieldTuplePat::as_string () const |
| { |
| // TODO: maybe rewrite to work with non-linearisable patterns |
| std::string str = StructPatternField::as_string (); |
| |
| str += "\n"; |
| |
| str += std::to_string (index) + " : " + tuple_pattern->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| StructPatternFieldIdentPat::as_string () const |
| { |
| // TODO: maybe rewrite to work with non-linearisable patterns |
| std::string str = StructPatternField::as_string (); |
| |
| str += "\n"; |
| |
| str += ident.as_string () + " : " + ident_pattern->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| StructPatternFieldIdent::as_string () const |
| { |
| std::string str = StructPatternField::as_string (); |
| |
| str += "\n"; |
| |
| if (has_ref) |
| str += "ref "; |
| |
| if (has_mut) |
| str += "mut "; |
| |
| str += ident.as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| StructPatternElements::as_string () const |
| { |
| std::string str ("\n Fields: "); |
| |
| if (!has_struct_pattern_fields ()) |
| { |
| str += "none"; |
| } |
| else |
| { |
| for (const auto &field : fields) |
| str += "\n " + field->as_string (); |
| } |
| |
| str += "\n Etc: "; |
| if (has_struct_pattern_etc) |
| str += "true"; |
| else |
| str += "false"; |
| |
| return str; |
| } |
| |
| std::string |
| StructPattern::as_string () const |
| { |
| std::string str ("StructPattern: \n Path: "); |
| |
| str += path.as_string (); |
| |
| str += "\n Struct pattern elems: "; |
| if (!has_struct_pattern_elems ()) |
| str += "none"; |
| else |
| str += elems.as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| TupleStructItemsNoRange::as_string () const |
| { |
| std::string str; |
| |
| for (const auto &pattern : patterns) |
| str += "\n " + pattern->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| TupleStructItemsRange::as_string () const |
| { |
| std::string str ("\n Lower patterns: "); |
| |
| if (lower_patterns.empty ()) |
| { |
| str += "none"; |
| } |
| else |
| { |
| for (const auto &lower : lower_patterns) |
| str += "\n " + lower->as_string (); |
| } |
| |
| str += "\n Upper patterns: "; |
| if (upper_patterns.empty ()) |
| { |
| str += "none"; |
| } |
| else |
| { |
| for (const auto &upper : upper_patterns) |
| str += "\n " + upper->as_string (); |
| } |
| |
| return str; |
| } |
| |
| std::string |
| TupleStructPattern::as_string () const |
| { |
| std::string str ("TupleStructPattern: \n Path: "); |
| |
| str += path.as_string (); |
| |
| str += "\n Tuple struct items: " + items->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| TuplePatternItemsMultiple::as_string () const |
| { |
| std::string str; |
| |
| for (const auto &pattern : patterns) |
| str += "\n " + pattern->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| TuplePatternItemsRanged::as_string () const |
| { |
| std::string str; |
| |
| str += "\n Lower patterns: "; |
| if (lower_patterns.empty ()) |
| { |
| str += "none"; |
| } |
| else |
| { |
| for (const auto &lower : lower_patterns) |
| str += "\n " + lower->as_string (); |
| } |
| |
| str += "\n Upper patterns: "; |
| if (upper_patterns.empty ()) |
| { |
| str += "none"; |
| } |
| else |
| { |
| for (const auto &upper : upper_patterns) |
| str += "\n " + upper->as_string (); |
| } |
| |
| return str; |
| } |
| |
| std::string |
| TuplePattern::as_string () const |
| { |
| return "TuplePattern: " + items->as_string (); |
| } |
| |
| std::string |
| GroupedExpr::as_string () const |
| { |
| std::string str ("Grouped expr:"); |
| |
| // outer attrs |
| str += append_attributes (outer_attrs, OUTER); |
| |
| // inner attributes |
| str += append_attributes (inner_attrs, INNER); |
| |
| str += "\n Expr in parens: " + expr_in_parens->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| SlicePattern::as_string () const |
| { |
| std::string str ("SlicePattern: "); |
| |
| for (const auto &pattern : items) |
| str += "\n " + pattern->as_string (); |
| |
| return str; |
| } |
| |
| std::string |
| AltPattern::as_string () const |
| { |
| std::string str ("AltPattern: "); |
| |
| for (const auto &pattern : alts) |
| str += "\n " + pattern->as_string (); |
| |
| return str; |
| } |
| |
| void |
| AltPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| GroupedPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| GroupedExpr::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| SlicePattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| TuplePatternItemsRanged::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| TuplePattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| TuplePatternItemsMultiple::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| LiteralPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| IdentifierPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| WildcardPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| RestPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| RangePatternBoundLiteral::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| RangePatternBoundPath::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| RangePatternBoundQualPath::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| RangePattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| ReferencePattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| StructPatternFieldTuplePat::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| StructPatternFieldIdentPat::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| StructPatternFieldIdent::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| StructPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| TupleStructItemsNoRange::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| TupleStructItemsRange::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| void |
| TupleStructPattern::accept_vis (ASTVisitor &vis) |
| { |
| vis.visit (*this); |
| } |
| |
| } // namespace AST |
| } // namespace Rust |