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: 2025-11-22 14:42:49 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                 :         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                 :       18021 : CompileItem::visit (HIR::Function &function)
     139                 :             : {
     140                 :       18021 :   TyTy::BaseType *fntype_tyty;
     141                 :       18021 :   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                 :        5603 :       return;
     147                 :             :     }
     148                 :             : 
     149                 :       18021 :   rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
     150                 :       18021 :   TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
     151                 :       18021 :   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                 :        3534 :       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                 :       14487 :       HirId id = function.get_mappings ().get_hirid ();
     190                 :       14487 :       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                 :       16249 :   auto &nr_ctx
     201                 :       16249 :     = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     202                 :             : 
     203                 :       16249 :   Resolver::CanonicalPath canonical_path
     204                 :       16249 :     = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
     205                 :             : 
     206                 :       16249 :   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                 :       16249 :   tree lookup = NULL_TREE;
     211                 :       16249 :   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                 :       12418 :   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                 :       12418 :   if (function.get_qualifiers ().is_const ())
     225                 :         664 :     ctx->push_const_context ();
     226                 :             : 
     227                 :       12418 :   auto lookup_root_item = ctx->get_mappings ().lookup_hir_item (
     228                 :       12418 :     function.get_mappings ().get_hirid ());
     229                 :       12418 :   bool is_root_item = lookup_root_item.has_value ();
     230                 :       12418 :   tree fndecl
     231                 :       12418 :     = compile_function (is_root_item,
     232                 :       12418 :                         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                 :       12418 :                         &function.get_definition (), canonical_path, fntype);
     238                 :       12418 :   reference = address_expression (fndecl, ref_locus);
     239                 :             : 
     240                 :       12418 :   if (function.get_qualifiers ().is_const ())
     241                 :       13082 :     ctx->pop_const_context ();
     242                 :       16249 : }
     243                 :             : 
     244                 :             : void
     245                 :        5518 : CompileItem::visit (HIR::ImplBlock &impl_block)
     246                 :             : {
     247                 :        5518 :   TyTy::BaseType *self_lookup = nullptr;
     248                 :       11036 :   if (!ctx->get_tyctx ()->lookup_type (
     249                 :        5518 :         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                 :       13496 :   for (auto &impl_item : impl_block.get_impl_items ())
     256                 :        7978 :     CompileInherentImplItem::Compile (impl_item.get (), ctx);
     257                 :             : }
     258                 :             : 
     259                 :             : void
     260                 :        1436 : CompileItem::visit (HIR::ExternBlock &extern_block)
     261                 :             : {
     262                 :        3613 :   for (auto &item : extern_block.get_extern_items ())
     263                 :             :     {
     264                 :        2177 :       CompileExternItem::compile (item.get (), ctx, concrete);
     265                 :             :     }
     266                 :        1436 : }
     267                 :             : 
     268                 :             : void
     269                 :        1170 : CompileItem::visit (HIR::Module &module)
     270                 :             : {
     271                 :        5050 :   for (auto &item : module.get_items ())
     272                 :        3880 :     CompileItem::compile (item.get (), ctx);
     273                 :        1170 : }
     274                 :             : 
     275                 :             : void
     276                 :         784 : CompileItem::visit (HIR::TupleStruct &tuple_struct_decl)
     277                 :             : {
     278                 :         784 :   TyTy::BaseType *lookup = nullptr;
     279                 :         784 :   if (!ctx->get_tyctx ()->lookup_type (
     280                 :         784 :         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                 :         784 :   if (lookup->is_concrete ())
     287                 :         504 :     TyTyResolveCompile::compile (ctx, lookup);
     288                 :             : }
     289                 :             : 
     290                 :             : void
     291                 :         474 : CompileItem::visit (HIR::Enum &enum_decl)
     292                 :             : {
     293                 :         474 :   TyTy::BaseType *lookup = nullptr;
     294                 :         474 :   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                 :         474 :   if (lookup->is_concrete ())
     302                 :         251 :     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                 :        1299 : CompileItem::visit (HIR::StructStruct &struct_decl)
     322                 :             : {
     323                 :        1299 :   TyTy::BaseType *lookup = nullptr;
     324                 :        1299 :   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                 :        1299 :   if (lookup->is_concrete ())
     332                 :         895 :     TyTyResolveCompile::compile (ctx, lookup);
     333                 :             : }
     334                 :             : 
     335                 :             : } // namespace Compile
     336                 :             : } // 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.