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 : 587 : CompileItem::visit (HIR::ConstantItem &constant)
88 : : {
89 : 587 : HIR::Expr &const_value_expr = constant.get_expr ();
90 : 587 : auto &mappings = constant.get_mappings ();
91 : :
92 : 587 : if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
93 : 81 : return;
94 : :
95 : : // resolve the type
96 : 534 : TyTy::BaseType *constant_type = nullptr;
97 : 534 : TyTy::BaseType *expr_type = nullptr;
98 : :
99 : 534 : bool ok
100 : 534 : = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
101 : 534 : rust_assert (ok);
102 : 534 : ok = ctx->get_tyctx ()->lookup_type (
103 : 534 : const_value_expr.get_mappings ().get_hirid (), &expr_type);
104 : 534 : rust_assert (ok);
105 : :
106 : 534 : auto &nr_ctx
107 : 534 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
108 : :
109 : : // canonical path
110 : 534 : Resolver::CanonicalPath canonical_path
111 : 534 : = nr_ctx.to_canonical_path (mappings.get_nodeid ());
112 : 534 : 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 : 506 : ctx->push_const_context ();
125 : 506 : tree const_expr
126 : 506 : = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
127 : : canonical_path, const_value_expr,
128 : : constant.get_locus (),
129 : 506 : const_value_expr.get_locus ());
130 : 506 : ctx->pop_const_context ();
131 : :
132 : 506 : ctx->push_const (const_expr);
133 : 506 : ctx->insert_const_decl (mappings.get_hirid (), const_expr);
134 : 506 : reference = const_expr;
135 : 534 : }
136 : :
137 : : void
138 : 18021 : CompileItem::visit (HIR::Function &function)
139 : : {
140 : 18021 : TyTy::BaseType *fntype_tyty;
141 : 18021 : if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
142 : : &fntype_tyty))
143 : : {
144 : 0 : rust_fatal_error (function.get_locus (),
145 : : "failed to lookup function type");
146 : 5603 : return;
147 : : }
148 : :
149 : 18021 : rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
150 : 18021 : TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
151 : 18021 : if (fntype->has_substitutions_defined ())
152 : : {
153 : : // we cant do anything for this only when it is used and a concrete type
154 : : // is given
155 : 3534 : if (concrete == nullptr)
156 : : return;
157 : :
158 : 1762 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
159 : 1762 : TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
160 : 1762 : bool is_trait_item_concrete
161 : 1762 : = ctx->get_mappings ()
162 : 1762 : .lookup_trait_item_defid (concrete_fnty->get_id ())
163 : 1762 : .has_value ();
164 : 1762 : if (!is_trait_item_concrete)
165 : : {
166 : 1722 : rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
167 : 1722 : fntype = static_cast<TyTy::FnType *> (concrete);
168 : : }
169 : : else
170 : : {
171 : 40 : TyTy::BaseType *infer
172 : 40 : = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
173 : 40 : TyTy::BaseType *resolved
174 : 40 : = Resolver::unify_site (function.get_mappings ().get_hirid (),
175 : 40 : TyTy::TyWithLocation (infer),
176 : 40 : TyTy::TyWithLocation (concrete),
177 : : function.get_locus ());
178 : :
179 : 40 : rust_assert (resolved->is<TyTy::FnType> ());
180 : 40 : fntype = resolved->as<TyTy::FnType> ();
181 : : }
182 : :
183 : 1762 : fntype->monomorphize ();
184 : : }
185 : : else
186 : : {
187 : : // if this is part of a trait impl block which is not generic we need to
188 : : // ensure associated types are setup
189 : 14487 : HirId id = function.get_mappings ().get_hirid ();
190 : 14487 : if (auto impl_item = ctx->get_mappings ().lookup_hir_implitem (id))
191 : : {
192 : 9040 : Resolver::AssociatedImplTrait *impl = nullptr;
193 : 9040 : bool found = ctx->get_tyctx ()->lookup_associated_trait_impl (
194 : 9040 : impl_item->second, &impl);
195 : 9040 : if (found)
196 : 5534 : impl->setup_raw_associated_types ();
197 : : }
198 : : }
199 : :
200 : 16249 : auto &nr_ctx
201 : 16249 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
202 : :
203 : 16249 : Resolver::CanonicalPath canonical_path
204 : 16249 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
205 : :
206 : 16249 : const std::string asm_name = ctx->mangle_item (fntype, canonical_path);
207 : :
208 : : // items can be forward compiled which means we may not need to invoke this
209 : : // code. We might also have already compiled this generic function as well.
210 : 16249 : tree lookup = NULL_TREE;
211 : 16249 : if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
212 : : fntype->get_id (), fntype, asm_name))
213 : : {
214 : 3831 : reference = address_expression (lookup, ref_locus);
215 : 3831 : return;
216 : : }
217 : :
218 : 12418 : if (fntype->has_substitutions_defined ())
219 : : {
220 : : // override the Hir Lookups for the substituions in this context
221 : 1502 : fntype->override_context ();
222 : : }
223 : :
224 : 12418 : if (function.get_qualifiers ().is_const ())
225 : 664 : ctx->push_const_context ();
226 : :
227 : 12418 : auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
228 : 12418 : function.get_mappings ().get_hirid ());
229 : 12418 : bool is_root_item = lookup_root_item.has_value ();
230 : 12418 : tree fndecl
231 : 12418 : = compile_function (is_root_item,
232 : 12418 : function.get_function_name ().as_string (),
233 : : function.get_self_param (),
234 : : function.get_function_params (),
235 : : function.get_qualifiers (), function.get_visibility (),
236 : : function.get_outer_attrs (), function.get_locus (),
237 : 12418 : &function.get_definition (), canonical_path, fntype);
238 : 12418 : reference = address_expression (fndecl, ref_locus);
239 : :
240 : 12418 : if (function.get_qualifiers ().is_const ())
241 : 13082 : ctx->pop_const_context ();
242 : 16249 : }
243 : :
244 : : void
245 : 5518 : CompileItem::visit (HIR::ImplBlock &impl_block)
246 : : {
247 : 5518 : TyTy::BaseType *self_lookup = nullptr;
248 : 11036 : if (!ctx->get_tyctx ()->lookup_type (
249 : 5518 : impl_block.get_type ().get_mappings ().get_hirid (), &self_lookup))
250 : : {
251 : 0 : rust_error_at (impl_block.get_locus (), "failed to resolve type of impl");
252 : 0 : return;
253 : : }
254 : :
255 : 13496 : for (auto &impl_item : impl_block.get_impl_items ())
256 : 7978 : CompileInherentImplItem::Compile (impl_item.get (), ctx);
257 : : }
258 : :
259 : : void
260 : 1436 : CompileItem::visit (HIR::ExternBlock &extern_block)
261 : : {
262 : 3613 : for (auto &item : extern_block.get_extern_items ())
263 : : {
264 : 2177 : CompileExternItem::compile (item.get (), ctx, concrete);
265 : : }
266 : 1436 : }
267 : :
268 : : void
269 : 1170 : CompileItem::visit (HIR::Module &module)
270 : : {
271 : 5050 : for (auto &item : module.get_items ())
272 : 3880 : CompileItem::compile (item.get (), ctx);
273 : 1170 : }
274 : :
275 : : void
276 : 784 : CompileItem::visit (HIR::TupleStruct &tuple_struct_decl)
277 : : {
278 : 784 : TyTy::BaseType *lookup = nullptr;
279 : 784 : if (!ctx->get_tyctx ()->lookup_type (
280 : 784 : tuple_struct_decl.get_mappings ().get_hirid (), &lookup))
281 : : {
282 : 0 : rust_error_at (tuple_struct_decl.get_locus (), "failed to resolve type");
283 : 0 : return;
284 : : }
285 : :
286 : 784 : if (lookup->is_concrete ())
287 : 504 : TyTyResolveCompile::compile (ctx, lookup);
288 : : }
289 : :
290 : : void
291 : 474 : CompileItem::visit (HIR::Enum &enum_decl)
292 : : {
293 : 474 : TyTy::BaseType *lookup = nullptr;
294 : 474 : if (!ctx->get_tyctx ()->lookup_type (enum_decl.get_mappings ().get_hirid (),
295 : : &lookup))
296 : : {
297 : 0 : rust_error_at (enum_decl.get_locus (), "failed to resolve type");
298 : 0 : return;
299 : : }
300 : :
301 : 474 : if (lookup->is_concrete ())
302 : 251 : TyTyResolveCompile::compile (ctx, lookup);
303 : : }
304 : :
305 : : void
306 : 96 : CompileItem::visit (HIR::Union &union_decl)
307 : : {
308 : 96 : TyTy::BaseType *lookup = nullptr;
309 : 96 : if (!ctx->get_tyctx ()->lookup_type (union_decl.get_mappings ().get_hirid (),
310 : : &lookup))
311 : : {
312 : 0 : rust_error_at (union_decl.get_locus (), "failed to resolve type");
313 : 0 : return;
314 : : }
315 : :
316 : 96 : if (lookup->is_concrete ())
317 : 23 : TyTyResolveCompile::compile (ctx, lookup);
318 : : }
319 : :
320 : : void
321 : 1299 : CompileItem::visit (HIR::StructStruct &struct_decl)
322 : : {
323 : 1299 : TyTy::BaseType *lookup = nullptr;
324 : 1299 : if (!ctx->get_tyctx ()->lookup_type (struct_decl.get_mappings ().get_hirid (),
325 : : &lookup))
326 : : {
327 : 0 : rust_error_at (struct_decl.get_locus (), "failed to resolve type");
328 : 0 : return;
329 : : }
330 : :
331 : 1299 : if (lookup->is_concrete ())
332 : 895 : TyTyResolveCompile::compile (ctx, lookup);
333 : : }
334 : :
335 : : } // namespace Compile
336 : : } // namespace Rust
|