blob: 0076fe9e3b7644099cdccb51aa71810acb9b074c [file] [log] [blame]
// Copyright (C) 2020-2023 Free Software Foundation, Inc.
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#ifndef RUST_TYCHECK_DUMP
#define RUST_TYCHECK_DUMP
#include "rust-hir-type-check-base.h"
#include "rust-hir-full.h"
namespace Rust {
namespace Resolver {
class TypeResolverDump : private TypeCheckBase, private HIR::HIRFullVisitorBase
{
using HIR::HIRFullVisitorBase::visit;
public:
static void go (HIR::Crate &crate, std::ofstream &out)
{
TypeResolverDump dumper;
for (auto &item : crate.items)
{
item->accept_vis (dumper);
dumper.dump += "\n";
}
out << dumper.dump;
}
void visit (HIR::StructStruct &struct_decl) override
{
dump += indent () + "struct " + type_string (struct_decl.get_mappings ())
+ "\n";
}
void visit (HIR::Union &union_decl) override
{
dump
+= indent () + "union " + type_string (union_decl.get_mappings ()) + "\n";
}
void visit (HIR::TupleStruct &struct_decl) override
{
dump += indent () + "struct" + type_string (struct_decl.get_mappings ())
+ "\n";
}
void visit (HIR::ImplBlock &impl_block) override
{
dump += indent () + "impl "
+ type_string (impl_block.get_type ()->get_mappings ()) + " {\n";
indentation_level++;
for (auto &impl_item : impl_block.get_impl_items ())
{
impl_item->accept_vis (*this);
dump += "\n";
}
indentation_level--;
dump += indent () + "}\n";
}
void visit (HIR::ConstantItem &constant) override
{
dump += indent () + "constant " + constant.get_identifier () + ":"
+ type_string (constant.get_mappings ()) + " = ";
constant.get_expr ()->accept_vis (*this);
dump += ";\n";
}
void visit (HIR::Function &function) override
{
dump += indent () + "fn " + function.get_function_name () + " "
+ type_string (function.get_mappings ()) + "\n";
dump += indent () + "{\n";
HIR::BlockExpr *function_body = function.get_definition ().get ();
function_body->accept_vis (*this);
dump += indent () + "}\n";
}
void visit (HIR::BlockExpr &expr) override
{
dump += "{\n";
indentation_level++;
for (auto &s : expr.get_statements ())
{
dump += indent ();
s->accept_vis (*this);
dump += ";\n";
}
if (expr.has_expr ())
{
dump += indent ();
expr.expr->accept_vis (*this);
dump += ";\n";
}
indentation_level--;
dump += "}\n";
}
void visit (HIR::UnsafeBlockExpr &expr) override
{
dump += "unsafe ";
expr.get_block_expr ()->accept_vis (*this);
}
void visit (HIR::LetStmt &stmt) override
{
dump += "let " + stmt.get_pattern ()->as_string () + ":"
+ type_string (stmt.get_pattern ()->get_pattern_mappings ());
if (stmt.has_init_expr ())
{
dump += " = ";
stmt.get_init_expr ()->accept_vis (*this);
}
}
void visit (HIR::ExprStmtWithBlock &stmt) override
{
stmt.get_expr ()->accept_vis (*this);
}
void visit (HIR::ExprStmtWithoutBlock &stmt) override
{
stmt.get_expr ()->accept_vis (*this);
}
void visit (HIR::AssignmentExpr &expr) override
{
expr.get_lhs ()->accept_vis (*this);
dump += " = ";
expr.get_rhs ()->accept_vis (*this);
}
void visit (HIR::LiteralExpr &expr) override
{
dump += expr.get_literal ().as_string () + ":"
+ type_string (expr.get_mappings ());
}
void visit (HIR::ArrayExpr &expr) override
{
dump += type_string (expr.get_mappings ()) + ":[";
HIR::ArrayElems *elements = expr.get_internal_elements ();
elements->accept_vis (*this);
dump += "]";
}
void visit (HIR::ArrayElemsValues &elems) override
{
for (auto &elem : elems.get_values ())
{
elem->accept_vis (*this);
dump += ",";
}
}
void visit (HIR::GroupedExpr &expr) override
{
HIR::Expr *paren_expr = expr.get_expr_in_parens ().get ();
dump += "(";
paren_expr->accept_vis (*this);
dump += ")";
}
void visit (HIR::PathInExpression &expr) override
{
dump += type_string (expr.get_mappings ());
}
void visit (HIR::StructExprStructFields &expr) override
{
dump += "ctor: " + type_string (expr.get_mappings ());
}
protected:
std::string type_string (const Analysis::NodeMapping &mappings)
{
TyTy::BaseType *lookup = nullptr;
if (!context->lookup_type (mappings.get_hirid (), &lookup))
return "<error>";
std::string buf = "[";
for (auto &ref : lookup->get_combined_refs ())
{
buf += std::to_string (ref);
buf += ", ";
}
buf += "]";
std::string repr = lookup->as_string ();
return "<" + repr + " HIRID: " + std::to_string (mappings.get_hirid ())
+ " RF:" + std::to_string (lookup->get_ref ()) + " TF:"
+ std::to_string (lookup->get_ty_ref ()) + +" - " + buf + ">";
}
std::string indent ()
{
std::string buf;
for (size_t i = 0; i < indentation_level; ++i)
buf += " ";
return buf;
}
private:
TypeResolverDump () : TypeCheckBase (), indentation_level (0) {}
std::string dump;
size_t indentation_level;
};
} // namespace Resolver
} // namespace Rust
#endif // RUST_TYCHECK_DUMP