Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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_COMPILE_CONTEXT
20 : : #define RUST_COMPILE_CONTEXT
21 : :
22 : : #include "rust-system.h"
23 : : #include "rust-hir-map.h"
24 : : #include "rust-name-resolver.h"
25 : : #include "rust-hir-type-check.h"
26 : : #include "rust-backend.h"
27 : : #include "rust-hir-full.h"
28 : : #include "rust-mangle.h"
29 : : #include "rust-tree.h"
30 : :
31 : : namespace Rust {
32 : : namespace Compile {
33 : :
34 : : struct fncontext
35 : : {
36 : : tree fndecl;
37 : : ::Bvariable *ret_addr;
38 : : TyTy::BaseType *retty;
39 : : };
40 : :
41 : 0 : struct CustomDeriveInfo
42 : : {
43 : : tree fndecl;
44 : : std::string trait_name;
45 : : std::vector<std::string> attributes;
46 : : };
47 : :
48 : : class Context
49 : : {
50 : : public:
51 : : Context ();
52 : :
53 : : void setup_builtins ();
54 : :
55 : : bool lookup_compiled_types (tree t, tree *type)
56 : : {
57 : : hashval_t h = type_hasher (t);
58 : : auto it = compiled_type_map.find (h);
59 : : if (it == compiled_type_map.end ())
60 : : return false;
61 : :
62 : : *type = it->second;
63 : : return true;
64 : : }
65 : :
66 : 160074 : tree insert_compiled_type (tree type)
67 : : {
68 : 160074 : hashval_t h = type_hasher (type);
69 : 160074 : auto it = compiled_type_map.find (h);
70 : 160074 : if (it != compiled_type_map.end ())
71 : 96585 : return it->second;
72 : :
73 : 63489 : compiled_type_map.insert ({h, type});
74 : 126978 : push_type (type);
75 : 63489 : return type;
76 : : }
77 : :
78 : 9219 : tree insert_main_variant (tree type)
79 : : {
80 : 9219 : hashval_t h = type_hasher (type);
81 : 9219 : auto it = main_variants.find (h);
82 : 9219 : if (it != main_variants.end ())
83 : 5778 : return it->second;
84 : :
85 : 3441 : main_variants.insert ({h, type});
86 : 3441 : return type;
87 : : }
88 : :
89 : 23574 : Resolver::Resolver *get_resolver () { return resolver; }
90 : 168538 : Resolver::TypeCheckContext *get_tyctx () { return tyctx; }
91 : 92437 : Analysis::Mappings *get_mappings () { return mappings; }
92 : :
93 : 14909 : void push_block (tree scope)
94 : : {
95 : 14909 : scope_stack.push_back (scope);
96 : 14909 : statements.push_back ({});
97 : 14909 : }
98 : :
99 : 14895 : tree pop_block ()
100 : : {
101 : 14895 : auto block = scope_stack.back ();
102 : 14895 : scope_stack.pop_back ();
103 : :
104 : 14895 : auto stmts = statements.back ();
105 : 14895 : statements.pop_back ();
106 : :
107 : 14895 : Backend::block_add_statements (block, stmts);
108 : :
109 : 29790 : return block;
110 : 14895 : }
111 : :
112 : 17197 : tree peek_enclosing_scope ()
113 : : {
114 : 17197 : if (scope_stack.size () == 0)
115 : : return nullptr;
116 : :
117 : 17197 : return scope_stack.back ();
118 : : }
119 : :
120 : : void add_statement_to_enclosing_scope (tree stmt)
121 : : {
122 : : statements.at (statements.size () - 2).push_back (stmt);
123 : : }
124 : :
125 : 50899 : void add_statement (tree stmt) { statements.back ().push_back (stmt); }
126 : :
127 : 14831 : void insert_var_decl (HirId id, ::Bvariable *decl)
128 : : {
129 : 14831 : compiled_var_decls[id] = decl;
130 : : }
131 : :
132 : 31122 : bool lookup_var_decl (HirId id, ::Bvariable **decl)
133 : : {
134 : 31122 : auto it = compiled_var_decls.find (id);
135 : 31122 : if (it == compiled_var_decls.end ())
136 : : return false;
137 : :
138 : 24607 : *decl = it->second;
139 : 24607 : return true;
140 : : }
141 : :
142 : 9091 : void insert_function_decl (const TyTy::FnType *ref, tree fn)
143 : : {
144 : 9091 : auto id = ref->get_ty_ref ();
145 : 9091 : auto dId = ref->get_id ();
146 : :
147 : 9091 : rust_assert (compiled_fn_map.find (id) == compiled_fn_map.end ());
148 : 9091 : compiled_fn_map[id] = fn;
149 : :
150 : 9091 : auto it = mono_fns.find (dId);
151 : 9091 : if (it == mono_fns.end ())
152 : 8909 : mono_fns[dId] = {};
153 : :
154 : 9091 : mono_fns[dId].push_back ({ref, fn});
155 : 9091 : }
156 : :
157 : 52 : void insert_closure_decl (const TyTy::ClosureType *ref, tree fn)
158 : : {
159 : 52 : auto dId = ref->get_def_id ();
160 : 52 : auto it = mono_closure_fns.find (dId);
161 : 52 : if (it == mono_closure_fns.end ())
162 : 52 : mono_closure_fns[dId] = {};
163 : :
164 : 52 : mono_closure_fns[dId].push_back ({ref, fn});
165 : 52 : }
166 : :
167 : : tree lookup_closure_decl (const TyTy::ClosureType *ref)
168 : : {
169 : : auto dId = ref->get_def_id ();
170 : : auto it = mono_closure_fns.find (dId);
171 : : if (it == mono_closure_fns.end ())
172 : : return error_mark_node;
173 : :
174 : : for (auto &i : it->second)
175 : : {
176 : : const TyTy::ClosureType *t = i.first;
177 : : tree fn = i.second;
178 : :
179 : : if (ref->is_equal (*t))
180 : : return fn;
181 : : }
182 : :
183 : : return error_mark_node;
184 : : }
185 : :
186 : 17891 : bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
187 : : const TyTy::BaseType *ref = nullptr,
188 : : const std::string &asm_name = std::string ())
189 : : {
190 : : // for for any monomorphized fns
191 : 17891 : if (ref != nullptr)
192 : : {
193 : 11655 : rust_assert (dId != UNKNOWN_DEFID);
194 : :
195 : 11655 : auto it = mono_fns.find (dId);
196 : 11655 : if (it == mono_fns.end ())
197 : : return false;
198 : :
199 : 1428 : for (auto &e : mono_fns[dId])
200 : : {
201 : 1253 : const TyTy::BaseType *r = e.first;
202 : 1253 : tree f = e.second;
203 : :
204 : 1253 : if (ref->is_equal (*r))
205 : : {
206 : 991 : *fn = f;
207 : 991 : return true;
208 : : }
209 : :
210 : 262 : if (DECL_ASSEMBLER_NAME_SET_P (f) && !asm_name.empty ())
211 : : {
212 : 234 : tree raw = DECL_ASSEMBLER_NAME_RAW (f);
213 : 234 : const char *rptr = IDENTIFIER_POINTER (raw);
214 : :
215 : 234 : bool lengths_match_p
216 : 234 : = IDENTIFIER_LENGTH (raw) == asm_name.size ();
217 : 234 : if (lengths_match_p
218 : 234 : && strncmp (rptr, asm_name.c_str (),
219 : 233 : IDENTIFIER_LENGTH (raw))
220 : : == 0)
221 : : {
222 : 0 : *fn = f;
223 : 0 : return true;
224 : : }
225 : : }
226 : : }
227 : : return false;
228 : : }
229 : :
230 : 6236 : auto it = compiled_fn_map.find (id);
231 : 6236 : if (it == compiled_fn_map.end ())
232 : : return false;
233 : :
234 : 3512 : *fn = it->second;
235 : 3512 : return true;
236 : : }
237 : :
238 : 451 : void insert_const_decl (HirId id, tree expr) { compiled_consts[id] = expr; }
239 : :
240 : 23719 : bool lookup_const_decl (HirId id, tree *expr)
241 : : {
242 : 23719 : auto it = compiled_consts.find (id);
243 : 23719 : if (it == compiled_consts.end ())
244 : : return false;
245 : :
246 : 764 : *expr = it->second;
247 : 764 : return true;
248 : : }
249 : :
250 : 29 : void insert_label_decl (HirId id, tree label) { compiled_labels[id] = label; }
251 : :
252 : 15 : bool lookup_label_decl (HirId id, tree *label)
253 : : {
254 : 15 : auto it = compiled_labels.find (id);
255 : 15 : if (it == compiled_labels.end ())
256 : : return false;
257 : :
258 : 15 : *label = it->second;
259 : 15 : return true;
260 : : }
261 : :
262 : 215 : void insert_pattern_binding (HirId id, tree binding)
263 : : {
264 : 215 : implicit_pattern_bindings[id] = binding;
265 : : }
266 : :
267 : 6477 : bool lookup_pattern_binding (HirId id, tree *binding)
268 : : {
269 : 6477 : auto it = implicit_pattern_bindings.find (id);
270 : 6477 : if (it == implicit_pattern_bindings.end ())
271 : : return false;
272 : :
273 : 185 : *binding = it->second;
274 : 185 : return true;
275 : : }
276 : :
277 : 8509 : void push_fn (tree fn, ::Bvariable *ret_addr, TyTy::BaseType *retty)
278 : : {
279 : 8509 : fn_stack.push_back (fncontext{fn, ret_addr, retty});
280 : : }
281 : 8509 : void pop_fn () { fn_stack.pop_back (); }
282 : :
283 : 2913 : bool in_fn () { return fn_stack.size () != 0; }
284 : :
285 : : // Note: it is undefined behavior to call peek_fn () if fn_stack is empty.
286 : 28724 : fncontext peek_fn ()
287 : : {
288 : 28724 : rust_assert (!fn_stack.empty ());
289 : 28724 : return fn_stack.back ();
290 : : }
291 : :
292 : 63489 : void push_type (tree t) { type_decls.push_back (t); }
293 : 38 : void push_var (::Bvariable *v) { var_decls.push_back (v); }
294 : 451 : void push_const (tree c) { const_decls.push_back (c); }
295 : 9680 : void push_function (tree f) { func_decls.push_back (f); }
296 : :
297 : 3313 : void write_to_backend ()
298 : : {
299 : 3313 : Backend::write_global_definitions (type_decls, const_decls, func_decls,
300 : : var_decls);
301 : : }
302 : :
303 : 0 : bool function_completed (tree fn)
304 : : {
305 : 0 : for (auto it = func_decls.begin (); it != func_decls.end (); it++)
306 : : {
307 : 0 : tree i = (*it);
308 : 0 : if (i == fn)
309 : : {
310 : : return true;
311 : : }
312 : : }
313 : : return false;
314 : : }
315 : :
316 : 88 : void push_loop_context (Bvariable *var) { loop_value_stack.push_back (var); }
317 : :
318 : 15 : Bvariable *peek_loop_context () { return loop_value_stack.back (); }
319 : :
320 : 88 : Bvariable *pop_loop_context ()
321 : : {
322 : 88 : auto back = loop_value_stack.back ();
323 : 88 : loop_value_stack.pop_back ();
324 : 88 : return back;
325 : : }
326 : :
327 : 121 : void push_loop_begin_label (tree label)
328 : : {
329 : 121 : loop_begin_labels.push_back (label);
330 : : }
331 : :
332 : 7 : tree peek_loop_begin_label () { return loop_begin_labels.back (); }
333 : :
334 : 121 : tree pop_loop_begin_label ()
335 : : {
336 : 121 : tree pop = loop_begin_labels.back ();
337 : 121 : loop_begin_labels.pop_back ();
338 : 121 : return pop;
339 : : }
340 : :
341 : 3346 : void push_const_context (void) { const_context++; }
342 : 3346 : void pop_const_context (void)
343 : : {
344 : 3346 : if (const_context > 0)
345 : 3346 : const_context--;
346 : : }
347 : 2864 : bool const_context_p (void) { return (const_context > 0); }
348 : :
349 : 17068 : std::string mangle_item (const TyTy::BaseType *ty,
350 : : const Resolver::CanonicalPath &path)
351 : : {
352 : 17068 : return mangler.mangle_item (this, ty, path);
353 : : }
354 : :
355 : : void push_closure_context (HirId id);
356 : : void pop_closure_context ();
357 : : void insert_closure_binding (HirId id, tree expr);
358 : : bool lookup_closure_binding (HirId id, tree *expr);
359 : :
360 : : std::vector<tree> &get_type_decls () { return type_decls; }
361 : 6558 : std::vector<::Bvariable *> &get_var_decls () { return var_decls; }
362 : 6558 : std::vector<tree> &get_const_decls () { return const_decls; }
363 : 6558 : std::vector<tree> &get_func_decls () { return func_decls; }
364 : :
365 : : static hashval_t type_hasher (tree type);
366 : :
367 : 0 : void collect_attribute_proc_macro (tree fndecl)
368 : : {
369 : 0 : attribute_macros.push_back (fndecl);
370 : : }
371 : :
372 : 0 : void collect_bang_proc_macro (tree fndecl) { bang_macros.push_back (fndecl); }
373 : :
374 : 0 : void collect_derive_proc_macro (CustomDeriveInfo macro)
375 : : {
376 : 0 : custom_derive_macros.push_back (macro);
377 : : }
378 : :
379 : 0 : const std::vector<tree> &get_bang_proc_macros () const { return bang_macros; }
380 : : const std::vector<tree> &get_attribute_proc_macros () const
381 : : {
382 : 0 : return attribute_macros;
383 : : }
384 : : const std::vector<CustomDeriveInfo> &get_derive_proc_macros () const
385 : : {
386 : 0 : return custom_derive_macros;
387 : : }
388 : :
389 : : private:
390 : : Resolver::Resolver *resolver;
391 : : Resolver::TypeCheckContext *tyctx;
392 : : Analysis::Mappings *mappings;
393 : : Mangler mangler;
394 : :
395 : : // state
396 : : std::vector<fncontext> fn_stack;
397 : : std::map<HirId, ::Bvariable *> compiled_var_decls;
398 : : std::map<hashval_t, tree> compiled_type_map;
399 : : std::map<HirId, tree> compiled_fn_map;
400 : : std::map<HirId, tree> compiled_consts;
401 : : std::map<HirId, tree> compiled_labels;
402 : : std::vector<::std::vector<tree>> statements;
403 : : std::vector<tree> scope_stack;
404 : : std::vector<::Bvariable *> loop_value_stack;
405 : : std::vector<tree> loop_begin_labels;
406 : : std::map<DefId, std::vector<std::pair<const TyTy::BaseType *, tree>>>
407 : : mono_fns;
408 : : std::map<DefId, std::vector<std::pair<const TyTy::ClosureType *, tree>>>
409 : : mono_closure_fns;
410 : : std::map<HirId, tree> implicit_pattern_bindings;
411 : : std::map<hashval_t, tree> main_variants;
412 : :
413 : : std::vector<CustomDeriveInfo> custom_derive_macros;
414 : : std::vector<tree> attribute_macros;
415 : : std::vector<tree> bang_macros;
416 : :
417 : : // closure bindings
418 : : std::vector<HirId> closure_scope_bindings;
419 : : std::map<HirId, std::map<HirId, tree>> closure_bindings;
420 : :
421 : : // To GCC middle-end
422 : : std::vector<tree> type_decls;
423 : : std::vector<::Bvariable *> var_decls;
424 : : std::vector<tree> const_decls;
425 : : std::vector<tree> func_decls;
426 : :
427 : : // Nonzero iff we are currently compiling something inside a constant context.
428 : : unsigned int const_context = 0;
429 : : };
430 : :
431 : : } // namespace Compile
432 : : } // namespace Rust
433 : :
434 : : #endif // RUST_COMPILE_CONTEXT
|