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