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 % 172 161
Test Date: 2026-02-28 14:20:25 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          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        18079 : CompileItem::visit (HIR::Function &function)
     139              : {
     140        18079 :   TyTy::BaseType *fntype_tyty;
     141        18079 :   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         5604 :       return;
     147              :     }
     148              : 
     149        18079 :   rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
     150        18079 :   TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
     151        18079 :   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         3535 :       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        14544 :       HirId id = function.get_mappings ().get_hirid ();
     190        14544 :       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        16306 :   auto &nr_ctx
     201        16306 :     = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     202              : 
     203        16306 :   Resolver::CanonicalPath canonical_path
     204        16306 :     = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
     205              : 
     206        16306 :   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        16306 :   tree lookup = NULL_TREE;
     211        16306 :   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        12475 :   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        12475 :   if (function.get_qualifiers ().is_const ())
     225          664 :     ctx->push_const_context ();
     226              : 
     227        12475 :   auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
     228        12475 :     function.get_mappings ().get_hirid ());
     229        12475 :   bool is_root_item = lookup_root_item.has_value ();
     230        12475 :   tree fndecl
     231        12475 :     = compile_function (is_root_item,
     232        12475 :                         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        12475 :                         &function.get_definition (), canonical_path, fntype);
     238        12475 :   reference = address_expression (fndecl, ref_locus);
     239              : 
     240        12475 :   if (function.get_qualifiers ().is_const ())
     241        13139 :     ctx->pop_const_context ();
     242        16306 : }
     243              : 
     244              : void
     245         5525 : CompileItem::visit (HIR::ImplBlock &impl_block)
     246              : {
     247         5525 :   TyTy::BaseType *self_lookup = nullptr;
     248        11050 :   if (!ctx->get_tyctx ()->lookup_type (
     249         5525 :         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        13510 :   for (auto &impl_item : impl_block.get_impl_items ())
     256         7985 :     CompileInherentImplItem::Compile (impl_item.get (), ctx);
     257              : }
     258              : 
     259              : void
     260         1438 : CompileItem::visit (HIR::ExternBlock &extern_block)
     261              : {
     262         3617 :   for (auto &item : extern_block.get_extern_items ())
     263              :     {
     264         2179 :       CompileExternItem::compile (item.get (), ctx, concrete);
     265              :     }
     266         1438 : }
     267              : 
     268              : void
     269         1173 : CompileItem::visit (HIR::Module &module)
     270              : {
     271         5054 :   for (auto &item : module.get_items ())
     272         3881 :     CompileItem::compile (item.get (), ctx);
     273         1173 : }
     274              : 
     275              : void
     276          792 : CompileItem::visit (HIR::TupleStruct &tuple_struct_decl)
     277              : {
     278          792 :   TyTy::BaseType *lookup = nullptr;
     279          792 :   if (!ctx->get_tyctx ()->lookup_type (
     280          792 :         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          792 :   if (lookup->is_concrete ())
     287          512 :     TyTyResolveCompile::compile (ctx, lookup);
     288              : }
     289              : 
     290              : void
     291          477 : CompileItem::visit (HIR::Enum &enum_decl)
     292              : {
     293          477 :   TyTy::BaseType *lookup = nullptr;
     294          477 :   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          477 :   if (lookup->is_concrete ())
     302          254 :     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         1308 : CompileItem::visit (HIR::StructStruct &struct_decl)
     322              : {
     323         1308 :   TyTy::BaseType *lookup = nullptr;
     324         1308 :   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         1308 :   if (lookup->is_concrete ())
     332          904 :     TyTyResolveCompile::compile (ctx, lookup);
     333              : }
     334              : 
     335              : } // namespace Compile
     336              : } // 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.