blob: fc7b6107be0e02caf5f0abc1be060f2d62e17876 [file] [log] [blame]
/* 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