LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-compile-item.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.6 % 173 162
Test Date: 2026-04-20 14:57:17 Functions: 100.0 % 10 10
Legend: Lines:     hit not hit

            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
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.