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 61 : CompileItem::visit (HIR::StaticItem &var)
32 : {
33 : // have we already compiled this?
34 61 : Bvariable *static_decl_ref = nullptr;
35 61 : 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 54 : HIR::Expr &const_value_expr = var.get_expr ();
42 :
43 54 : TyTy::BaseType *resolved_type = nullptr;
44 54 : TyTy::BaseType *expr_type = nullptr;
45 54 : bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
46 : &resolved_type);
47 54 : rust_assert (ok);
48 54 : ok = ctx->get_tyctx ()->lookup_type (
49 54 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
50 54 : rust_assert (ok);
51 :
52 54 : tree type = TyTyResolveCompile::compile (ctx, resolved_type);
53 :
54 54 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
55 :
56 54 : Resolver::CanonicalPath canonical_path
57 54 : = nr_ctx.to_canonical_path (var.get_mappings ().get_nodeid (),
58 54 : Resolver2_0::Namespace::Values);
59 :
60 54 : ctx->push_const_context ();
61 54 : tree value
62 54 : = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
63 : resolved_type, canonical_path, const_value_expr,
64 54 : var.get_locus (), const_value_expr.get_locus ());
65 54 : ctx->pop_const_context ();
66 :
67 54 : std::string name = canonical_path.get ();
68 54 : std::string asm_name = ctx->mangle_item (resolved_type, canonical_path);
69 :
70 54 : bool is_external = false;
71 54 : bool is_hidden = false;
72 54 : bool in_unique_section = true;
73 :
74 54 : Bvariable *static_global
75 54 : = Backend::global_variable (name, asm_name, type, is_external, is_hidden,
76 : in_unique_section, var.get_locus ());
77 :
78 54 : tree init = value == error_mark_node ? error_mark_node : DECL_INITIAL (value);
79 54 : Backend::global_variable_set_init (static_global, init);
80 :
81 54 : ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global);
82 54 : ctx->push_var (static_global);
83 :
84 54 : reference = Backend::var_expression (static_global, ref_locus);
85 54 : }
86 :
87 : void
88 616 : CompileItem::visit (HIR::ConstantItem &constant)
89 : {
90 616 : HIR::Expr &const_value_expr = constant.get_expr ();
91 616 : auto &mappings = constant.get_mappings ();
92 :
93 616 : if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
94 81 : return;
95 :
96 : // resolve the type
97 563 : TyTy::BaseType *constant_type = nullptr;
98 563 : TyTy::BaseType *expr_type = nullptr;
99 :
100 563 : bool ok
101 1126 : = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
102 563 : rust_assert (ok);
103 563 : ok = ctx->get_tyctx ()->lookup_type (
104 563 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
105 563 : rust_assert (ok);
106 :
107 563 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
108 :
109 : // canonical path
110 563 : Resolver::CanonicalPath canonical_path
111 : = nr_ctx.to_canonical_path (mappings.get_nodeid (),
112 563 : Resolver2_0::Namespace::Values);
113 563 : 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 535 : ctx->push_const_context ();
126 535 : tree const_expr
127 535 : = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
128 : canonical_path, const_value_expr,
129 : constant.get_locus (),
130 535 : const_value_expr.get_locus ());
131 535 : ctx->pop_const_context ();
132 :
133 535 : if (const_expr != error_mark_node)
134 : {
135 527 : ctx->push_const (const_expr);
136 527 : ctx->insert_const_decl (mappings.get_hirid (), const_expr);
137 : }
138 535 : reference = const_expr;
139 563 : }
140 :
141 : void
142 20113 : CompileItem::visit (HIR::Function &function)
143 : {
144 20113 : TyTy::BaseType *fntype_tyty;
145 20113 : 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 6149 : return;
151 : }
152 :
153 20113 : rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
154 20113 : TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
155 20113 : 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 3907 : if (concrete == nullptr)
160 : return;
161 :
162 1961 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
163 1961 : TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
164 1961 : bool is_trait_item_concrete
165 1961 : = ctx->get_mappings ()
166 1961 : .lookup_trait_item_defid (concrete_fnty->get_id ())
167 1961 : .has_value ();
168 1961 : if (!is_trait_item_concrete)
169 : {
170 1913 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
171 1913 : fntype = static_cast<TyTy::FnType *> (concrete);
172 : }
173 : else
174 : {
175 48 : TyTy::BaseType *infer
176 48 : = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
177 48 : TyTy::BaseType *resolved
178 48 : = Resolver::unify_site (function.get_mappings ().get_hirid (),
179 48 : TyTy::TyWithLocation (infer),
180 48 : TyTy::TyWithLocation (concrete),
181 : function.get_locus ());
182 :
183 48 : if (!resolved->is<TyTy::FnType> ())
184 : return;
185 :
186 47 : fntype = resolved->as<TyTy::FnType> ();
187 : }
188 :
189 1960 : fntype->monomorphize ();
190 : }
191 :
192 18166 : Resolver::AssociatedImplTrait *impl = nullptr;
193 18166 : HirId id = function.get_mappings ().get_hirid ();
194 18166 : if (auto impl_item = ctx->get_mappings ().lookup_hir_implitem (id))
195 : {
196 11386 : ctx->get_tyctx ()->lookup_associated_trait_impl (impl_item->second,
197 : &impl);
198 : }
199 :
200 18166 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
201 :
202 18166 : tl::optional<Resolver::ImplTraitFrameGuard> guard;
203 18166 : if (impl)
204 6753 : guard.emplace (impl->get_frame ());
205 :
206 18166 : Resolver::CanonicalPath canonical_path
207 18166 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
208 18166 : Resolver2_0::Namespace::Values);
209 :
210 18166 : 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 18166 : tree lookup = NULL_TREE;
215 18166 : if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
216 : fntype->get_id (), fntype, asm_name))
217 : {
218 4202 : reference = address_expression (lookup, ref_locus);
219 4202 : return;
220 : }
221 :
222 13964 : if (fntype->has_substitutions_defined ())
223 : {
224 : // override the Hir Lookups for the substituions in this context
225 1654 : fntype->override_context ();
226 : }
227 :
228 13964 : if (function.get_qualifiers ().is_const ())
229 817 : ctx->push_const_context ();
230 :
231 13964 : auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
232 13964 : function.get_mappings ().get_hirid ());
233 13964 : bool is_root_item = lookup_root_item.has_value ();
234 13964 : tree fndecl
235 13964 : = compile_function (is_root_item,
236 13964 : 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 13964 : &function.get_definition (), canonical_path, fntype);
242 13962 : reference = address_expression (fndecl, ref_locus);
243 :
244 13962 : if (function.get_qualifiers ().is_const ())
245 14779 : ctx->pop_const_context ();
246 26864 : }
247 :
248 : void
249 6250 : CompileItem::visit (HIR::ImplBlock &impl_block)
250 : {
251 6250 : TyTy::BaseType *self_lookup = nullptr;
252 12500 : if (!ctx->get_tyctx ()->lookup_type (
253 6250 : 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 15421 : for (auto &impl_item : impl_block.get_impl_items ())
260 9171 : CompileInherentImplItem::Compile (impl_item.get (), ctx);
261 : }
262 :
263 : void
264 1680 : CompileItem::visit (HIR::ExternBlock &extern_block)
265 : {
266 4316 : for (auto &item : extern_block.get_extern_items ())
267 : {
268 2636 : CompileExternItem::compile (item.get (), ctx, concrete);
269 : }
270 1680 : }
271 :
272 : void
273 1222 : CompileItem::visit (HIR::Module &module)
274 : {
275 5324 : for (auto &item : module.get_items ())
276 4102 : CompileItem::compile (item.get (), ctx);
277 1222 : }
278 :
279 : void
280 817 : CompileItem::visit (HIR::TupleStruct &tuple_struct_decl)
281 : {
282 817 : TyTy::BaseType *lookup = nullptr;
283 817 : if (!ctx->get_tyctx ()->lookup_type (
284 817 : 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 817 : if (lookup->is_concrete ())
291 525 : TyTyResolveCompile::compile (ctx, lookup);
292 : }
293 :
294 : void
295 511 : CompileItem::visit (HIR::Enum &enum_decl)
296 : {
297 511 : TyTy::BaseType *lookup = nullptr;
298 511 : 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 511 : if (lookup->is_concrete ())
306 272 : 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 1463 : CompileItem::visit (HIR::StructStruct &struct_decl)
326 : {
327 1463 : TyTy::BaseType *lookup = nullptr;
328 1463 : 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 1463 : if (lookup->is_concrete ())
336 1019 : TyTyResolveCompile::compile (ctx, lookup);
337 : }
338 :
339 : } // namespace Compile
340 : } // namespace Rust
|