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 57 : CompileItem::visit (HIR::StaticItem &var)
32 : {
33 : // have we already compiled this?
34 57 : Bvariable *static_decl_ref = nullptr;
35 57 : 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 50 : HIR::Expr &const_value_expr = var.get_expr ();
42 :
43 50 : TyTy::BaseType *resolved_type = nullptr;
44 50 : TyTy::BaseType *expr_type = nullptr;
45 50 : bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
46 : &resolved_type);
47 50 : rust_assert (ok);
48 50 : ok = ctx->get_tyctx ()->lookup_type (
49 50 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
50 50 : rust_assert (ok);
51 :
52 50 : tree type = TyTyResolveCompile::compile (ctx, resolved_type);
53 :
54 50 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
55 :
56 50 : Resolver::CanonicalPath canonical_path
57 50 : = nr_ctx.to_canonical_path (var.get_mappings ().get_nodeid (),
58 50 : Resolver2_0::Namespace::Values);
59 :
60 50 : ctx->push_const_context ();
61 50 : tree value
62 50 : = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
63 : resolved_type, canonical_path, const_value_expr,
64 50 : var.get_locus (), const_value_expr.get_locus ());
65 50 : ctx->pop_const_context ();
66 :
67 50 : std::string name = canonical_path.get ();
68 50 : std::string asm_name = ctx->mangle_item (resolved_type, canonical_path);
69 :
70 50 : bool is_external = false;
71 50 : bool is_hidden = false;
72 50 : bool in_unique_section = true;
73 :
74 50 : Bvariable *static_global
75 50 : = Backend::global_variable (name, asm_name, type, is_external, is_hidden,
76 : in_unique_section, var.get_locus ());
77 :
78 50 : tree init = value == error_mark_node ? error_mark_node : DECL_INITIAL (value);
79 50 : Backend::global_variable_set_init (static_global, init);
80 :
81 50 : ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global);
82 50 : ctx->push_var (static_global);
83 :
84 50 : reference = Backend::var_expression (static_global, ref_locus);
85 50 : }
86 :
87 : void
88 597 : CompileItem::visit (HIR::ConstantItem &constant)
89 : {
90 597 : HIR::Expr &const_value_expr = constant.get_expr ();
91 597 : auto &mappings = constant.get_mappings ();
92 :
93 597 : if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
94 81 : return;
95 :
96 : // resolve the type
97 544 : TyTy::BaseType *constant_type = nullptr;
98 544 : TyTy::BaseType *expr_type = nullptr;
99 :
100 544 : bool ok
101 544 : = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
102 544 : rust_assert (ok);
103 544 : ok = ctx->get_tyctx ()->lookup_type (
104 544 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
105 544 : rust_assert (ok);
106 :
107 544 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
108 :
109 : // canonical path
110 544 : Resolver::CanonicalPath canonical_path
111 : = nr_ctx.to_canonical_path (mappings.get_nodeid (),
112 544 : Resolver2_0::Namespace::Values);
113 544 : 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 516 : ctx->push_const_context ();
126 516 : tree const_expr
127 516 : = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
128 : canonical_path, const_value_expr,
129 : constant.get_locus (),
130 516 : const_value_expr.get_locus ());
131 516 : ctx->pop_const_context ();
132 :
133 516 : if (const_expr != error_mark_node)
134 : {
135 508 : ctx->push_const (const_expr);
136 508 : ctx->insert_const_decl (mappings.get_hirid (), const_expr);
137 : }
138 516 : reference = const_expr;
139 544 : }
140 :
141 : void
142 18488 : CompileItem::visit (HIR::Function &function)
143 : {
144 18488 : TyTy::BaseType *fntype_tyty;
145 18488 : 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 5697 : return;
151 : }
152 :
153 18488 : rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
154 18488 : TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
155 18488 : 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 3594 : if (concrete == nullptr)
160 : return;
161 :
162 1787 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
163 1787 : TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
164 1787 : bool is_trait_item_concrete
165 1787 : = ctx->get_mappings ()
166 1787 : .lookup_trait_item_defid (concrete_fnty->get_id ())
167 1787 : .has_value ();
168 1787 : if (!is_trait_item_concrete)
169 : {
170 1746 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
171 1746 : 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 1786 : fntype->monomorphize ();
190 : }
191 :
192 16680 : Resolver::AssociatedImplTrait *impl = nullptr;
193 16680 : HirId id = function.get_mappings ().get_hirid ();
194 16680 : if (auto impl_item = ctx->get_mappings ().lookup_hir_implitem (id))
195 : {
196 10245 : ctx->get_tyctx ()->lookup_associated_trait_impl (impl_item->second,
197 : &impl);
198 : }
199 :
200 16680 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
201 :
202 16680 : tl::optional<Resolver::ImplTraitFrameGuard> guard;
203 16680 : if (impl)
204 6128 : guard.emplace (impl->get_frame ());
205 :
206 16680 : Resolver::CanonicalPath canonical_path
207 16680 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
208 16680 : Resolver2_0::Namespace::Values);
209 :
210 16680 : 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 16680 : tree lookup = NULL_TREE;
215 16680 : if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
216 : fntype->get_id (), fntype, asm_name))
217 : {
218 3889 : reference = address_expression (lookup, ref_locus);
219 3889 : return;
220 : }
221 :
222 12791 : if (fntype->has_substitutions_defined ())
223 : {
224 : // override the Hir Lookups for the substituions in this context
225 1525 : fntype->override_context ();
226 : }
227 :
228 12791 : if (function.get_qualifiers ().is_const ())
229 695 : ctx->push_const_context ();
230 :
231 12791 : auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
232 12791 : function.get_mappings ().get_hirid ());
233 12791 : bool is_root_item = lookup_root_item.has_value ();
234 12791 : tree fndecl
235 12791 : = compile_function (is_root_item,
236 12791 : 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 12791 : &function.get_definition (), canonical_path, fntype);
242 12791 : reference = address_expression (fndecl, ref_locus);
243 :
244 12791 : if (function.get_qualifiers ().is_const ())
245 13486 : ctx->pop_const_context ();
246 22808 : }
247 :
248 : void
249 5615 : CompileItem::visit (HIR::ImplBlock &impl_block)
250 : {
251 5615 : TyTy::BaseType *self_lookup = nullptr;
252 11230 : if (!ctx->get_tyctx ()->lookup_type (
253 5615 : 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 13700 : for (auto &impl_item : impl_block.get_impl_items ())
260 8085 : CompileInherentImplItem::Compile (impl_item.get (), ctx);
261 : }
262 :
263 : void
264 1615 : CompileItem::visit (HIR::ExternBlock &extern_block)
265 : {
266 4112 : for (auto &item : extern_block.get_extern_items ())
267 : {
268 2497 : CompileExternItem::compile (item.get (), ctx, concrete);
269 : }
270 1615 : }
271 :
272 : void
273 1184 : CompileItem::visit (HIR::Module &module)
274 : {
275 5085 : for (auto &item : module.get_items ())
276 3901 : CompileItem::compile (item.get (), ctx);
277 1184 : }
278 :
279 : void
280 795 : CompileItem::visit (HIR::TupleStruct &tuple_struct_decl)
281 : {
282 795 : TyTy::BaseType *lookup = nullptr;
283 795 : if (!ctx->get_tyctx ()->lookup_type (
284 795 : 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 795 : if (lookup->is_concrete ())
291 513 : TyTyResolveCompile::compile (ctx, lookup);
292 : }
293 :
294 : void
295 485 : CompileItem::visit (HIR::Enum &enum_decl)
296 : {
297 485 : TyTy::BaseType *lookup = nullptr;
298 485 : 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 485 : if (lookup->is_concrete ())
306 261 : TyTyResolveCompile::compile (ctx, lookup);
307 : }
308 :
309 : void
310 100 : CompileItem::visit (HIR::Union &union_decl)
311 : {
312 100 : TyTy::BaseType *lookup = nullptr;
313 100 : 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 100 : if (lookup->is_concrete ())
321 27 : TyTyResolveCompile::compile (ctx, lookup);
322 : }
323 :
324 : void
325 1363 : CompileItem::visit (HIR::StructStruct &struct_decl)
326 : {
327 1363 : TyTy::BaseType *lookup = nullptr;
328 1363 : 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 1363 : if (lookup->is_concrete ())
336 953 : TyTyResolveCompile::compile (ctx, lookup);
337 : }
338 :
339 : } // namespace Compile
340 : } // namespace Rust
|