// 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 // . #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 ""; 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