LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-compile-item.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 98.1 % 156 153
Test Date: 2025-07-12 13:27:34 Functions: 100.0 % 6 6
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                 :          63 : CompileItem::visit (HIR::StaticItem &var)
      31                 :             : {
      32                 :             :   // have we already compiled this?
      33                 :          63 :   Bvariable *static_decl_ref = nullptr;
      34                 :          63 :   if (ctx->lookup_var_decl (var.get_mappings ().get_hirid (), &static_decl_ref))
      35                 :             :     {
      36                 :           8 :       reference = Backend::var_expression (static_decl_ref, ref_locus);
      37                 :           8 :       return;
      38                 :             :     }
      39                 :             : 
      40                 :          55 :   HIR::Expr &const_value_expr = var.get_expr ();
      41                 :             : 
      42                 :          55 :   TyTy::BaseType *resolved_type = nullptr;
      43                 :          55 :   TyTy::BaseType *expr_type = nullptr;
      44                 :          55 :   bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
      45                 :             :                                             &resolved_type);
      46                 :          55 :   rust_assert (ok);
      47                 :          55 :   ok = ctx->get_tyctx ()->lookup_type (
      48                 :          55 :     const_value_expr.get_mappings ().get_hirid (), &expr_type);
      49                 :          55 :   rust_assert (ok);
      50                 :             : 
      51                 :          55 :   tree type = TyTyResolveCompile::compile (ctx, resolved_type);
      52                 :             : 
      53                 :          55 :   tl::optional<Resolver::CanonicalPath> canonical_path;
      54                 :             : 
      55                 :          55 :   if (flag_name_resolution_2_0)
      56                 :             :     {
      57                 :          11 :       auto &nr_ctx
      58                 :          11 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
      59                 :             : 
      60                 :          11 :       canonical_path
      61                 :          22 :         = nr_ctx.values.to_canonical_path (var.get_mappings ().get_nodeid ());
      62                 :             :     }
      63                 :             :   else
      64                 :             :     {
      65                 :          88 :       canonical_path = ctx->get_mappings ().lookup_canonical_path (
      66                 :          44 :         var.get_mappings ().get_nodeid ());
      67                 :             :     }
      68                 :             : 
      69                 :          55 :   rust_assert (canonical_path.has_value ());
      70                 :             : 
      71                 :          55 :   ctx->push_const_context ();
      72                 :          55 :   tree value
      73                 :          55 :     = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
      74                 :          55 :                              resolved_type, *canonical_path, const_value_expr,
      75                 :          55 :                              var.get_locus (), const_value_expr.get_locus ());
      76                 :          55 :   ctx->pop_const_context ();
      77                 :             : 
      78                 :          55 :   std::string name = canonical_path->get ();
      79                 :          55 :   std::string asm_name = ctx->mangle_item (resolved_type, *canonical_path);
      80                 :             : 
      81                 :          55 :   bool is_external = false;
      82                 :          55 :   bool is_hidden = false;
      83                 :          55 :   bool in_unique_section = true;
      84                 :             : 
      85                 :          55 :   Bvariable *static_global
      86                 :          55 :     = Backend::global_variable (name, asm_name, type, is_external, is_hidden,
      87                 :             :                                 in_unique_section, var.get_locus ());
      88                 :             : 
      89                 :          55 :   tree init = value == error_mark_node ? error_mark_node : DECL_INITIAL (value);
      90                 :          55 :   Backend::global_variable_set_init (static_global, init);
      91                 :             : 
      92                 :          55 :   ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global);
      93                 :          55 :   ctx->push_var (static_global);
      94                 :             : 
      95                 :          55 :   reference = Backend::var_expression (static_global, ref_locus);
      96                 :         110 : }
      97                 :             : 
      98                 :             : void
      99                 :         551 : CompileItem::visit (HIR::ConstantItem &constant)
     100                 :             : {
     101                 :         551 :   HIR::Expr &const_value_expr = constant.get_expr ();
     102                 :         551 :   auto &mappings = constant.get_mappings ();
     103                 :             : 
     104                 :         551 :   if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
     105                 :           8 :     return;
     106                 :             : 
     107                 :             :   // resolve the type
     108                 :         543 :   TyTy::BaseType *constant_type = nullptr;
     109                 :         543 :   TyTy::BaseType *expr_type = nullptr;
     110                 :             : 
     111                 :         543 :   bool ok
     112                 :         543 :     = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
     113                 :         543 :   rust_assert (ok);
     114                 :         543 :   ok = ctx->get_tyctx ()->lookup_type (
     115                 :         543 :     const_value_expr.get_mappings ().get_hirid (), &expr_type);
     116                 :         543 :   rust_assert (ok);
     117                 :             : 
     118                 :             :   // canonical path
     119                 :         543 :   Resolver::CanonicalPath canonical_path
     120                 :         543 :     = Resolver::CanonicalPath::create_empty ();
     121                 :             : 
     122                 :         543 :   if (flag_name_resolution_2_0)
     123                 :             :     {
     124                 :          90 :       auto &nr_ctx
     125                 :          90 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     126                 :             : 
     127                 :          90 :       canonical_path
     128                 :         180 :         = nr_ctx.values.to_canonical_path (mappings.get_nodeid ()).value ();
     129                 :             :     }
     130                 :             :   else
     131                 :             :     {
     132                 :         453 :       canonical_path = ctx->get_mappings ()
     133                 :         453 :                          .lookup_canonical_path (mappings.get_nodeid ())
     134                 :         453 :                          .value ();
     135                 :             :     }
     136                 :             : 
     137                 :         543 :   ctx->push_const_context ();
     138                 :         543 :   tree const_expr
     139                 :         543 :     = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
     140                 :             :                              canonical_path, const_value_expr,
     141                 :             :                              constant.get_locus (),
     142                 :         543 :                              const_value_expr.get_locus ());
     143                 :         543 :   ctx->pop_const_context ();
     144                 :             : 
     145                 :         543 :   ctx->push_const (const_expr);
     146                 :         543 :   ctx->insert_const_decl (mappings.get_hirid (), const_expr);
     147                 :         543 :   reference = const_expr;
     148                 :         543 : }
     149                 :             : 
     150                 :             : void
     151                 :       15091 : CompileItem::visit (HIR::Function &function)
     152                 :             : {
     153                 :       15091 :   TyTy::BaseType *fntype_tyty;
     154                 :       15091 :   if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
     155                 :             :                                        &fntype_tyty))
     156                 :             :     {
     157                 :           0 :       rust_fatal_error (function.get_locus (),
     158                 :             :                         "failed to lookup function type");
     159                 :        3596 :       return;
     160                 :             :     }
     161                 :             : 
     162                 :       15091 :   rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
     163                 :       15091 :   TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
     164                 :       15091 :   if (fntype->has_substitutions_defined ())
     165                 :             :     {
     166                 :             :       // we cant do anything for this only when it is used and a concrete type
     167                 :             :       // is given
     168                 :        3439 :       if (concrete == nullptr)
     169                 :             :         return;
     170                 :             : 
     171                 :        1670 :       rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
     172                 :        1670 :       TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
     173                 :        1670 :       bool is_trait_item_concrete
     174                 :        1670 :         = ctx->get_mappings ()
     175                 :        1670 :             .lookup_trait_item_defid (concrete_fnty->get_id ())
     176                 :        1670 :             .has_value ();
     177                 :        1670 :       if (!is_trait_item_concrete)
     178                 :             :         {
     179                 :        1627 :           rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
     180                 :        1627 :           fntype = static_cast<TyTy::FnType *> (concrete);
     181                 :             :         }
     182                 :             :       else
     183                 :             :         {
     184                 :          43 :           TyTy::BaseType *infer
     185                 :          43 :             = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
     186                 :          43 :           TyTy::BaseType *resolved
     187                 :          43 :             = Resolver::unify_site (function.get_mappings ().get_hirid (),
     188                 :          43 :                                     TyTy::TyWithLocation (infer),
     189                 :          43 :                                     TyTy::TyWithLocation (concrete),
     190                 :             :                                     function.get_locus ());
     191                 :             : 
     192                 :          43 :           rust_assert (resolved->is<TyTy::FnType> ());
     193                 :          43 :           fntype = resolved->as<TyTy::FnType> ();
     194                 :             :         }
     195                 :             : 
     196                 :        1670 :       fntype->monomorphize ();
     197                 :             :     }
     198                 :             :   else
     199                 :             :     {
     200                 :             :       // if this is part of a trait impl block which is not generic we need to
     201                 :             :       // ensure associated types are setup
     202                 :       11652 :       HirId id = function.get_mappings ().get_hirid ();
     203                 :       11652 :       if (auto impl_item = ctx->get_mappings ().lookup_hir_implitem (id))
     204                 :             :         {
     205                 :        6026 :           Resolver::AssociatedImplTrait *impl = nullptr;
     206                 :        6026 :           bool found = ctx->get_tyctx ()->lookup_associated_trait_impl (
     207                 :        6026 :             impl_item->second, &impl);
     208                 :        6026 :           if (found)
     209                 :        3139 :             impl->setup_raw_associated_types ();
     210                 :             :         }
     211                 :             :     }
     212                 :             : 
     213                 :       13322 :   Resolver::CanonicalPath canonical_path
     214                 :       13322 :     = Resolver::CanonicalPath::create_empty ();
     215                 :             : 
     216                 :       13322 :   if (flag_name_resolution_2_0)
     217                 :             :     {
     218                 :        1695 :       auto &nr_ctx
     219                 :        1695 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     220                 :             : 
     221                 :        1695 :       auto path = nr_ctx.values.to_canonical_path (
     222                 :        1695 :         function.get_mappings ().get_nodeid ());
     223                 :             : 
     224                 :        1695 :       canonical_path = path.value ();
     225                 :        1695 :     }
     226                 :             :   else
     227                 :             :     {
     228                 :       11627 :       auto path = ctx->get_mappings ().lookup_canonical_path (
     229                 :       11627 :         function.get_mappings ().get_nodeid ());
     230                 :             : 
     231                 :       11627 :       canonical_path = *path;
     232                 :             :     }
     233                 :             : 
     234                 :       13322 :   const std::string asm_name = ctx->mangle_item (fntype, canonical_path);
     235                 :             : 
     236                 :             :   // items can be forward compiled which means we may not need to invoke this
     237                 :             :   // code. We might also have already compiled this generic function as well.
     238                 :       13322 :   tree lookup = NULL_TREE;
     239                 :       13322 :   if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
     240                 :             :                                  fntype->get_id (), fntype, asm_name))
     241                 :             :     {
     242                 :        1827 :       reference = address_expression (lookup, ref_locus);
     243                 :        1827 :       return;
     244                 :             :     }
     245                 :             : 
     246                 :       11495 :   if (fntype->has_substitutions_defined ())
     247                 :             :     {
     248                 :             :       // override the Hir Lookups for the substituions in this context
     249                 :        1469 :       fntype->override_context ();
     250                 :             :     }
     251                 :             : 
     252                 :       11495 :   if (function.get_qualifiers ().is_const ())
     253                 :         711 :     ctx->push_const_context ();
     254                 :             : 
     255                 :       11495 :   auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
     256                 :       11495 :     function.get_mappings ().get_hirid ());
     257                 :       11495 :   bool is_root_item = lookup_root_item.has_value ();
     258                 :       11495 :   tree fndecl
     259                 :       11495 :     = compile_function (is_root_item,
     260                 :       11495 :                         function.get_function_name ().as_string (),
     261                 :             :                         function.get_self_param (),
     262                 :             :                         function.get_function_params (),
     263                 :             :                         function.get_qualifiers (), function.get_visibility (),
     264                 :             :                         function.get_outer_attrs (), function.get_locus (),
     265                 :       11495 :                         &function.get_definition (), canonical_path, fntype);
     266                 :       11494 :   reference = address_expression (fndecl, ref_locus);
     267                 :             : 
     268                 :       11494 :   if (function.get_qualifiers ().is_const ())
     269                 :       12205 :     ctx->pop_const_context ();
     270                 :       13321 : }
     271                 :             : 
     272                 :             : void
     273                 :        4806 : CompileItem::visit (HIR::ImplBlock &impl_block)
     274                 :             : {
     275                 :        4806 :   TyTy::BaseType *self_lookup = nullptr;
     276                 :        9612 :   if (!ctx->get_tyctx ()->lookup_type (
     277                 :        4806 :         impl_block.get_type ().get_mappings ().get_hirid (), &self_lookup))
     278                 :             :     {
     279                 :           0 :       rust_error_at (impl_block.get_locus (), "failed to resolve type of impl");
     280                 :           0 :       return;
     281                 :             :     }
     282                 :             : 
     283                 :       11718 :   for (auto &impl_item : impl_block.get_impl_items ())
     284                 :        6912 :     CompileInherentImplItem::Compile (impl_item.get (), ctx);
     285                 :             : }
     286                 :             : 
     287                 :             : void
     288                 :        1225 : CompileItem::visit (HIR::ExternBlock &extern_block)
     289                 :             : {
     290                 :        3275 :   for (auto &item : extern_block.get_extern_items ())
     291                 :             :     {
     292                 :        2050 :       CompileExternItem::compile (item.get (), ctx, concrete);
     293                 :             :     }
     294                 :        1225 : }
     295                 :             : 
     296                 :             : void
     297                 :         863 : CompileItem::visit (HIR::Module &module)
     298                 :             : {
     299                 :        3855 :   for (auto &item : module.get_items ())
     300                 :        2992 :     CompileItem::compile (item.get (), ctx);
     301                 :         863 : }
     302                 :             : 
     303                 :             : } // namespace Compile
     304                 :             : } // 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.