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