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