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