Line data Source code
1 : // Copyright (C) 2020-2026 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 : #include "rust-compile-item.h"
20 : #include "rust-compile-implitem.h"
21 : #include "rust-compile-extern.h"
22 : #include "rust-rib.h"
23 : #include "rust-substitution-mapper.h"
24 : #include "rust-type-util.h"
25 : #include "rust-finalized-name-resolution-context.h"
26 :
27 : namespace Rust {
28 : namespace Compile {
29 :
30 : void
31 58 : CompileItem::visit (HIR::StaticItem &var)
32 : {
33 : // have we already compiled this?
34 58 : Bvariable *static_decl_ref = nullptr;
35 58 : if (ctx->lookup_var_decl (var.get_mappings ().get_hirid (), &static_decl_ref))
36 : {
37 7 : reference = Backend::var_expression (static_decl_ref, ref_locus);
38 7 : return;
39 : }
40 :
41 51 : HIR::Expr &const_value_expr = var.get_expr ();
42 :
43 51 : TyTy::BaseType *resolved_type = nullptr;
44 51 : TyTy::BaseType *expr_type = nullptr;
45 51 : bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
46 : &resolved_type);
47 51 : rust_assert (ok);
48 51 : ok = ctx->get_tyctx ()->lookup_type (
49 51 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
50 51 : rust_assert (ok);
51 :
52 51 : tree type = TyTyResolveCompile::compile (ctx, resolved_type);
53 :
54 51 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
55 :
56 51 : Resolver::CanonicalPath canonical_path
57 51 : = nr_ctx.to_canonical_path (var.get_mappings ().get_nodeid (),
58 51 : Resolver2_0::Namespace::Values);
59 :
60 51 : ctx->push_const_context ();
61 51 : tree value
62 51 : = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
63 : resolved_type, canonical_path, const_value_expr,
64 51 : var.get_locus (), const_value_expr.get_locus ());
65 51 : ctx->pop_const_context ();
66 :
67 51 : std::string name = canonical_path.get ();
68 51 : std::string asm_name = ctx->mangle_item (resolved_type, canonical_path);
69 :
70 51 : bool is_external = false;
71 51 : bool is_hidden = false;
72 51 : bool in_unique_section = true;
73 :
74 51 : Bvariable *static_global
75 51 : = Backend::global_variable (name, asm_name, type, is_external, is_hidden,
76 : in_unique_section, var.get_locus ());
77 :
78 51 : tree init = value == error_mark_node ? error_mark_node : DECL_INITIAL (value);
79 51 : Backend::global_variable_set_init (static_global, init);
80 :
81 51 : ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global);
82 51 : ctx->push_var (static_global);
83 :
84 51 : reference = Backend::var_expression (static_global, ref_locus);
85 51 : }
86 :
87 : void
88 600 : CompileItem::visit (HIR::ConstantItem &constant)
89 : {
90 600 : HIR::Expr &const_value_expr = constant.get_expr ();
91 600 : auto &mappings = constant.get_mappings ();
92 :
93 600 : if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
94 81 : return;
95 :
96 : // resolve the type
97 547 : TyTy::BaseType *constant_type = nullptr;
98 547 : TyTy::BaseType *expr_type = nullptr;
99 :
100 547 : bool ok
101 1094 : = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
102 547 : rust_assert (ok);
103 547 : ok = ctx->get_tyctx ()->lookup_type (
104 547 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
105 547 : rust_assert (ok);
106 :
107 547 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
108 :
109 : // canonical path
110 547 : Resolver::CanonicalPath canonical_path
111 : = nr_ctx.to_canonical_path (mappings.get_nodeid (),
112 547 : Resolver2_0::Namespace::Values);
113 547 : if (constant_type->is<const TyTy::FnType> ())
114 : {
115 56 : if (concrete == nullptr)
116 28 : return;
117 :
118 28 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
119 28 : TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
120 :
121 28 : concrete_fnty->override_context ();
122 28 : constant_type = expr_type = concrete_fnty->get_return_type ();
123 : }
124 :
125 519 : ctx->push_const_context ();
126 519 : tree const_expr
127 519 : = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
128 : canonical_path, const_value_expr,
129 : constant.get_locus (),
130 519 : const_value_expr.get_locus ());
131 519 : ctx->pop_const_context ();
132 :
133 519 : if (const_expr != error_mark_node)
134 : {
135 511 : ctx->push_const (const_expr);
136 511 : ctx->insert_const_decl (mappings.get_hirid (), const_expr);
137 : }
138 519 : reference = const_expr;
139 547 : }
140 :
141 : void
142 18650 : CompileItem::visit (HIR::Function &function)
143 : {
144 18650 : TyTy::BaseType *fntype_tyty;
145 18650 : if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
146 : &fntype_tyty))
147 : {
148 0 : rust_fatal_error (function.get_locus (),
149 : "failed to lookup function type");
150 5724 : return;
151 : }
152 :
153 18650 : rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
154 18650 : TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
155 18650 : if (fntype->has_substitutions_defined ())
156 : {
157 : // we cant do anything for this only when it is used and a concrete type
158 : // is given
159 3616 : if (concrete == nullptr)
160 : return;
161 :
162 1795 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
163 1795 : TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
164 1795 : bool is_trait_item_concrete
165 1795 : = ctx->get_mappings ()
166 1795 : .lookup_trait_item_defid (concrete_fnty->get_id ())
167 1795 : .has_value ();
168 1795 : if (!is_trait_item_concrete)
169 : {
170 1754 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
171 1754 : fntype = static_cast<TyTy::FnType *> (concrete);
172 : }
173 : else
174 : {
175 41 : TyTy::BaseType *infer
176 41 : = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
177 41 : TyTy::BaseType *resolved
178 41 : = Resolver::unify_site (function.get_mappings ().get_hirid (),
179 41 : TyTy::TyWithLocation (infer),
180 41 : TyTy::TyWithLocation (concrete),
181 : function.get_locus ());
182 :
183 41 : if (!resolved->is<TyTy::FnType> ())
184 : return;
185 :
186 40 : fntype = resolved->as<TyTy::FnType> ();
187 : }
188 :
189 1794 : fntype->monomorphize ();
190 : }
191 :
192 16828 : Resolver::AssociatedImplTrait *impl = nullptr;
193 16828 : HirId id = function.get_mappings ().get_hirid ();
194 16828 : if (auto impl_item = ctx->get_mappings ().lookup_hir_implitem (id))
195 : {
196 10275 : ctx->get_tyctx ()->lookup_associated_trait_impl (impl_item->second,
197 : &impl);
198 : }
199 :
200 16828 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
201 :
202 16828 : tl::optional<Resolver::ImplTraitFrameGuard> guard;
203 16828 : if (impl)
204 6149 : guard.emplace (impl->get_frame ());
205 :
206 16828 : Resolver::CanonicalPath canonical_path
207 16828 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
208 16828 : Resolver2_0::Namespace::Values);
209 :
210 16828 : const std::string asm_name = ctx->mangle_item (fntype, canonical_path);
211 :
212 : // items can be forward compiled which means we may not need to invoke this
213 : // code. We might also have already compiled this generic function as well.
214 16828 : tree lookup = NULL_TREE;
215 16828 : if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
216 : fntype->get_id (), fntype, asm_name))
217 : {
218 3902 : reference = address_expression (lookup, ref_locus);
219 3902 : return;
220 : }
221 :
222 12926 : if (fntype->has_substitutions_defined ())
223 : {
224 : // override the Hir Lookups for the substituions in this context
225 1533 : fntype->override_context ();
226 : }
227 :
228 12926 : if (function.get_qualifiers ().is_const ())
229 703 : ctx->push_const_context ();
230 :
231 12926 : auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
232 12926 : function.get_mappings ().get_hirid ());
233 12926 : bool is_root_item = lookup_root_item.has_value ();
234 12926 : tree fndecl
235 12926 : = compile_function (is_root_item,
236 12926 : function.get_function_name ().as_string (),
237 : function.get_self_param (),
238 : function.get_function_params (),
239 : function.get_qualifiers (), function.get_visibility (),
240 : function.get_outer_attrs (), function.get_locus (),
241 12926 : &function.get_definition (), canonical_path, fntype);
242 12924 : reference = address_expression (fndecl, ref_locus);
243 :
244 12924 : if (function.get_qualifiers ().is_const ())
245 13627 : ctx->pop_const_context ();
246 24797 : }
247 :
248 : void
249 5633 : CompileItem::visit (HIR::ImplBlock &impl_block)
250 : {
251 5633 : TyTy::BaseType *self_lookup = nullptr;
252 11266 : if (!ctx->get_tyctx ()->lookup_type (
253 5633 : impl_block.get_type ().get_mappings ().get_hirid (), &self_lookup))
254 : {
255 0 : rust_error_at (impl_block.get_locus (), "failed to resolve type of impl");
256 0 : return;
257 : }
258 :
259 13738 : for (auto &impl_item : impl_block.get_impl_items ())
260 8105 : CompileInherentImplItem::Compile (impl_item.get (), ctx);
261 : }
262 :
263 : void
264 1643 : CompileItem::visit (HIR::ExternBlock &extern_block)
265 : {
266 4168 : for (auto &item : extern_block.get_extern_items ())
267 : {
268 2525 : CompileExternItem::compile (item.get (), ctx, concrete);
269 : }
270 1643 : }
271 :
272 : void
273 1160 : CompileItem::visit (HIR::Module &module)
274 : {
275 4950 : for (auto &item : module.get_items ())
276 3790 : CompileItem::compile (item.get (), ctx);
277 1160 : }
278 :
279 : void
280 797 : CompileItem::visit (HIR::TupleStruct &tuple_struct_decl)
281 : {
282 797 : TyTy::BaseType *lookup = nullptr;
283 797 : if (!ctx->get_tyctx ()->lookup_type (
284 797 : tuple_struct_decl.get_mappings ().get_hirid (), &lookup))
285 : {
286 0 : rust_error_at (tuple_struct_decl.get_locus (), "failed to resolve type");
287 0 : return;
288 : }
289 :
290 797 : if (lookup->is_concrete ())
291 514 : TyTyResolveCompile::compile (ctx, lookup);
292 : }
293 :
294 : void
295 490 : CompileItem::visit (HIR::Enum &enum_decl)
296 : {
297 490 : TyTy::BaseType *lookup = nullptr;
298 490 : if (!ctx->get_tyctx ()->lookup_type (enum_decl.get_mappings ().get_hirid (),
299 : &lookup))
300 : {
301 0 : rust_error_at (enum_decl.get_locus (), "failed to resolve type");
302 0 : return;
303 : }
304 :
305 490 : if (lookup->is_concrete ())
306 266 : TyTyResolveCompile::compile (ctx, lookup);
307 : }
308 :
309 : void
310 101 : CompileItem::visit (HIR::Union &union_decl)
311 : {
312 101 : TyTy::BaseType *lookup = nullptr;
313 101 : if (!ctx->get_tyctx ()->lookup_type (union_decl.get_mappings ().get_hirid (),
314 : &lookup))
315 : {
316 0 : rust_error_at (union_decl.get_locus (), "failed to resolve type");
317 0 : return;
318 : }
319 :
320 101 : if (lookup->is_concrete ())
321 27 : TyTyResolveCompile::compile (ctx, lookup);
322 : }
323 :
324 : void
325 1385 : CompileItem::visit (HIR::StructStruct &struct_decl)
326 : {
327 1385 : TyTy::BaseType *lookup = nullptr;
328 1385 : if (!ctx->get_tyctx ()->lookup_type (struct_decl.get_mappings ().get_hirid (),
329 : &lookup))
330 : {
331 0 : rust_error_at (struct_decl.get_locus (), "failed to resolve type");
332 0 : return;
333 : }
334 :
335 1385 : if (lookup->is_concrete ())
336 973 : TyTyResolveCompile::compile (ctx, lookup);
337 : }
338 :
339 : } // namespace Compile
340 : } // namespace Rust
|