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.3 % 165 154
Test Date: 2025-09-20 13:40:47 Functions: 100.0 % 10 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             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
        

Generated by: LCOV version 2.1-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.