1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2
3 // This file is part of GCC.
4
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
8 // version.
9
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
18
19 #ifndef RUST_TYCHECK_DUMP
20 #define RUST_TYCHECK_DUMP
21
22 #include "rust-hir-type-check-base.h"
23 #include "rust-hir-full.h"
24
25 namespace Rust {
26 namespace Resolver {
27
28 class TypeResolverDump : private TypeCheckBase, private HIR::HIRFullVisitorBase
29 {
30 using HIR::HIRFullVisitorBase::visit;
31
32 public:
33 static void go (HIR::Crate &crate, std::ofstream &out)
34 {
35 TypeResolverDump dumper;
36 for (auto &item : crate.items)
37 {
38 item->accept_vis (dumper);
39 dumper.dump += "\n";
40 }
41
42 out << dumper.dump;
43 }
44
45 void visit (HIR::StructStruct &struct_decl) override
46 {
47 dump += indent () + "struct " + type_string (struct_decl.get_mappings ())
48 + "\n";
49 }
50
51 void visit (HIR::Union &union_decl) override
52 {
53 dump
54 += indent () + "union " + type_string (union_decl.get_mappings ()) + "\n";
55 }
56
57 void visit (HIR::TupleStruct &struct_decl) override
58 {
59 dump += indent () + "struct" + type_string (struct_decl.get_mappings ())
60 + "\n";
61 }
62
63 void visit (HIR::ImplBlock &impl_block) override
64 {
65 dump += indent () + "impl "
66 + type_string (impl_block.get_type ()->get_mappings ()) + " {\n";
67 indentation_level++;
68
69 for (auto &impl_item : impl_block.get_impl_items ())
70 {
71 impl_item->accept_vis (*this);
72 dump += "\n";
73 }
74
75 indentation_level--;
76 dump += indent () + "}\n";
77 }
78
79 void visit (HIR::ConstantItem &constant) override
80 {
81 dump += indent () + "constant " + constant.get_identifier () + ":"
82 + type_string (constant.get_mappings ()) + " = ";
83 constant.get_expr ()->accept_vis (*this);
84 dump += ";\n";
85 }
86
87 void visit (HIR::Function &function) override
88 {
89 dump += indent () + "fn " + function.get_function_name () + " "
90 + type_string (function.get_mappings ()) + "\n";
91 dump += indent () + "{\n";
92
93 HIR::BlockExpr *function_body = function.get_definition ().get ();
94 function_body->accept_vis (*this);
95
96 dump += indent () + "}\n";
97 }
98
99 void visit (HIR::BlockExpr &expr) override
100 {
101 dump += "{\n";
102 indentation_level++;
103
104 for (auto &s : expr.get_statements ())
105 {
106 dump += indent ();
107 s->accept_vis (*this);
108 dump += ";\n";
109 }
110
111 if (expr.has_expr ())
112 {
113 dump += indent ();
114 expr.expr->accept_vis (*this);
115 dump += ";\n";
116 }
117
118 indentation_level--;
119 dump += "}\n";
120 }
121
122 void visit (HIR::UnsafeBlockExpr &expr) override
123 {
124 dump += "unsafe ";
125 expr.get_block_expr ()->accept_vis (*this);
126 }
127
128 void visit (HIR::LetStmt &stmt) override
129 {
130 dump += "let " + stmt.get_pattern ()->as_string () + ":"
131 + type_string (stmt.get_pattern ()->get_pattern_mappings ());
132 if (stmt.has_init_expr ())
133 {
134 dump += " = ";
135 stmt.get_init_expr ()->accept_vis (*this);
136 }
137 }
138
139 void visit (HIR::ExprStmtWithBlock &stmt) override
140 {
141 stmt.get_expr ()->accept_vis (*this);
142 }
143
144 void visit (HIR::ExprStmtWithoutBlock &stmt) override
145 {
146 stmt.get_expr ()->accept_vis (*this);
147 }
148
149 void visit (HIR::AssignmentExpr &expr) override
150 {
151 expr.get_lhs ()->accept_vis (*this);
152 dump += " = ";
153 expr.get_rhs ()->accept_vis (*this);
154 }
155
156 void visit (HIR::LiteralExpr &expr) override
157 {
158 dump += expr.get_literal ().as_string () + ":"
159 + type_string (expr.get_mappings ());
160 }
161
162 void visit (HIR::ArrayExpr &expr) override
163 {
164 dump += type_string (expr.get_mappings ()) + ":[";
165
166 HIR::ArrayElems *elements = expr.get_internal_elements ();
167 elements->accept_vis (*this);
168
169 dump += "]";
170 }
171
172 void visit (HIR::ArrayElemsValues &elems) override
173 {
174 for (auto &elem : elems.get_values ())
175 {
176 elem->accept_vis (*this);
177 dump += ",";
178 }
179 }
180
181 void visit (HIR::GroupedExpr &expr) override
182 {
183 HIR::Expr *paren_expr = expr.get_expr_in_parens ().get ();
184 dump += "(";
185 paren_expr->accept_vis (*this);
186 dump += ")";
187 }
188
189 void visit (HIR::PathInExpression &expr) override
190 {
191 dump += type_string (expr.get_mappings ());
192 }
193
194 void visit (HIR::StructExprStructFields &expr) override
195 {
196 dump += "ctor: " + type_string (expr.get_mappings ());
197 }
198
199 protected:
200 std::string type_string (const Analysis::NodeMapping &mappings)
201 {
202 TyTy::BaseType *lookup = nullptr;
203 if (!context->lookup_type (mappings.get_hirid (), &lookup))
204 return "<error>";
205
206 std::string buf = "[";
207 for (auto &ref : lookup->get_combined_refs ())
208 {
209 buf += std::to_string (ref);
210 buf += ", ";
211 }
212 buf += "]";
213
214 std::string repr = lookup->as_string ();
215 return "<" + repr + " HIRID: " + std::to_string (mappings.get_hirid ())
216 + " RF:" + std::to_string (lookup->get_ref ()) + " TF:"
217 + std::to_string (lookup->get_ty_ref ()) + +" - " + buf + ">";
218 }
219
220 std::string indent ()
221 {
222 std::string buf;
223 for (size_t i = 0; i < indentation_level; ++i)
224 buf += " ";
225
226 return buf;
227 }
228
229 private:
230 TypeResolverDump () : TypeCheckBase (), indentation_level (0) {}
231
232 std::string dump;
233 size_t indentation_level;
234 };
235
236 } // namespace Resolver
237 } // namespace Rust
238
239 #endif // RUST_TYCHECK_DUMP