LCOV - code coverage report
Current view: top level - gcc/rust/util - rust-hir-map.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.7 % 583 494
Test Date: 2026-10-24 16:24:59 Functions: 86.0 % 107 92
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-hir-map.h"
      20              : #include "optional.h"
      21              : #include "rust-ast-full.h"
      22              : #include "rust-ast.h"
      23              : #include "rust-diagnostics.h"
      24              : #include "rust-hir-full.h"
      25              : #include "rust-item.h"
      26              : #include "rust-macro-builtins.h"
      27              : #include "rust-mapping-common.h"
      28              : #include "rust-attribute-values.h"
      29              : #include "rust-finalized-name-resolution-context.h"
      30              : 
      31              : namespace Rust {
      32              : namespace Analysis {
      33              : 
      34              : NodeMapping
      35        80252 : NodeMapping::get_error ()
      36              : {
      37        80252 :   return NodeMapping (UNKNOWN_CRATENUM, UNKNOWN_NODEID, UNKNOWN_HIRID,
      38        80252 :                       UNKNOWN_LOCAL_DEFID);
      39              : }
      40              : 
      41              : CrateNum
      42       792654 : NodeMapping::get_crate_num () const
      43              : {
      44       792654 :   return crateNum;
      45              : }
      46              : 
      47              : NodeId
      48      2714693 : NodeMapping::get_nodeid () const
      49              : {
      50      2714693 :   return nodeId;
      51              : }
      52              : 
      53              : HirId
      54      5393816 : NodeMapping::get_hirid () const
      55              : {
      56      5393816 :   return hirId;
      57              : }
      58              : 
      59              : LocalDefId
      60       787014 : NodeMapping::get_local_defid () const
      61              : {
      62       787014 :   return localDefId;
      63              : }
      64              : 
      65              : DefId
      66       784137 : NodeMapping::get_defid () const
      67              : {
      68       784137 :   return get_defid (get_crate_num (), get_local_defid ());
      69              : }
      70              : 
      71              : DefId
      72       784137 : NodeMapping::get_defid (CrateNum crate_num, LocalDefId local_defid)
      73              : {
      74       784137 :   return DefId{crate_num, local_defid};
      75              : }
      76              : 
      77              : std::string
      78          227 : NodeMapping::as_string () const
      79              : {
      80          227 :   std::ostringstream ss;
      81          227 :   ss << "["
      82          227 :      << "C: " << get_crate_num ();
      83          227 :   if (get_nodeid () != UNKNOWN_NODEID)
      84          227 :     ss << " Nid: " << get_nodeid ();
      85              : 
      86          227 :   if (get_hirid () != UNKNOWN_HIRID)
      87          227 :     ss << " Hid: " << get_hirid ();
      88              : 
      89          227 :   if (get_local_defid () != UNKNOWN_LOCAL_DEFID)
      90          227 :     ss << " Lid: " << get_local_defid ();
      91              : 
      92          227 :   ss << "]";
      93          227 :   return ss.str ();
      94          227 : }
      95              : 
      96              : // Mappings Class now
      97              : static const HirId kDefaultNodeIdBegin = 1;
      98              : static const HirId kDefaultHirIdBegin = 1;
      99              : static const HirId kDefaultCrateNumBegin = 0;
     100              : 
     101         5192 : CrateMappings::CrateMappings ()
     102         5192 :   : crate_num_itr (kDefaultCrateNumBegin), current_crate_num (UNKNOWN_CRATENUM)
     103         5192 : {}
     104              : 
     105         5192 : Mappings::Mappings ()
     106         5192 :   : hirIdIter (kDefaultHirIdBegin), nodeIdIter (kDefaultNodeIdBegin),
     107        10384 :     hirImplIndexesBuilt (false)
     108              : {
     109         5192 :   Analysis::NodeMapping node (0, 0, 0, 0);
     110         5192 :   builtinMarker
     111        10384 :     = new HIR::ImplBlock (node, {}, {}, nullptr, nullptr, HIR::WhereClause ({}),
     112              :                           BoundPolarity::RegularBound,
     113        10384 :                           HIR::Visibility (HIR::Visibility::VisType::Public),
     114        10384 :                           {}, {}, UNDEF_LOCATION);
     115         5192 : }
     116              : 
     117        10384 : Mappings::~Mappings () { delete builtinMarker; }
     118              : 
     119              : Mappings &
     120     22721349 : Mappings::get ()
     121              : {
     122     22726541 :   static Mappings instance{};
     123     22721349 :   return instance;
     124              : }
     125              : 
     126              : CrateNum
     127         5123 : CrateMappings::get_next_crate_num (const std::string &name)
     128              : {
     129         5123 :   auto id = crate_num_itr;
     130         5123 :   crate_num_itr++;
     131        10246 :   crate_names.insert (id, name);
     132         5123 :   return id;
     133              : }
     134              : 
     135              : void
     136         5243 : CrateMappings::set_current_crate (CrateNum crateNum)
     137              : {
     138         5243 :   current_crate_num = crateNum;
     139         5243 : }
     140              : 
     141              : CrateNum
     142      1965643 : CrateMappings::get_current_crate () const
     143              : {
     144      1965643 :   return current_crate_num;
     145              : }
     146              : 
     147              : tl::optional<CrateNum>
     148       106509 : CrateMappings::lookup_crate_num (NodeId node_id) const
     149              : {
     150       106509 :   auto it = crate_node_to_crate_num.find (node_id);
     151       106509 :   if (it == crate_node_to_crate_num.end ())
     152        53369 :     return tl::nullopt;
     153              : 
     154        53140 :   return it->second;
     155              : }
     156              : 
     157              : const std::string &
     158        13392 : CrateMappings::get_current_crate_name () const
     159              : {
     160        13392 :   return crate_names.lookup (get_current_crate ()).value ();
     161              : }
     162              : 
     163              : tl::optional<CrateNum>
     164          608 : CrateMappings::lookup_crate_name (const std::string &crate_name) const
     165              : {
     166          672 :   for (const auto &it : crate_names.get_storage ())
     167              :     {
     168          608 :       if (it.second.compare (crate_name) == 0)
     169          544 :         return it.first;
     170              :     }
     171           64 :   return tl::nullopt;
     172              : }
     173              : 
     174              : tl::optional<NodeId>
     175        20472 : CrateMappings::crate_num_to_nodeid (const CrateNum &crate_num) const
     176              : {
     177        20472 :   auto it = ast_crate.find (crate_num);
     178        20472 :   if (it == ast_crate.end ())
     179            0 :     return tl::nullopt;
     180              : 
     181        20472 :   return it->second->get_node_id ();
     182              : }
     183              : 
     184              : bool
     185        58515 : CrateMappings::node_is_crate (NodeId node_id) const
     186              : {
     187        58515 :   return lookup_crate_num (node_id).has_value ();
     188              : }
     189              : 
     190              : NodeId
     191      7216154 : Mappings::get_next_node_id ()
     192              : {
     193      7216154 :   auto it = nodeIdIter;
     194      7216154 :   if (UNLIKELY (it > MAX_NODEID))
     195            0 :     rust_fatal_error (UNKNOWN_LOCATION, "out of node ids");
     196      7216154 :   nodeIdIter++;
     197      7216154 :   return it;
     198              : }
     199              : 
     200              : HirId
     201      1906058 : Mappings::get_next_hir_id (CrateNum crateNum)
     202              : {
     203      1906058 :   auto id = hirIdIter;
     204      1906058 :   hirIdIter++;
     205              : 
     206      1906058 :   auto it = hirNodesWithinCrate.find (crateNum);
     207      1906058 :   if (it == hirNodesWithinCrate.end ())
     208              :     {
     209         5098 :       hirNodesWithinCrate.insert ({crateNum, {}});
     210              :     }
     211              : 
     212      1906058 :   hirNodesWithinCrate[crateNum].insert (id);
     213      1906058 :   return id;
     214              : }
     215              : 
     216              : LocalDefId
     217       301456 : Mappings::get_next_localdef_id (CrateNum crateNum)
     218              : {
     219       301456 :   auto it = localIdIter.find (crateNum);
     220       301456 :   if (it == localIdIter.end ())
     221              :     {
     222         4787 :       localIdIter.insert ({crateNum, 1});
     223              :     }
     224              : 
     225       301456 :   it = localIdIter.find (crateNum);
     226       301456 :   rust_assert (it != localIdIter.end ());
     227              : 
     228       301456 :   LocalDefId id = it->second;
     229       301456 :   localIdIter[crateNum] = id + 1;
     230       301456 :   return id;
     231              : }
     232              : 
     233              : AST::Crate &
     234         9707 : CrateMappings::get_ast_crate (CrateNum crateNum)
     235              : {
     236         9707 :   auto it = ast_crate.find (crateNum);
     237         9707 :   rust_assert (it != ast_crate.end ());
     238         9707 :   return *it->second;
     239              : }
     240              : 
     241              : AST::Crate &
     242            0 : Mappings::get_ast_crate_by_node_id (NodeId id)
     243              : {
     244            0 :   return *crate.get_ast_crate_by_node_id_raw (id);
     245              : }
     246              : 
     247              : AST::Crate *
     248         5098 : CrateMappings::get_ast_crate_by_node_id_raw (NodeId id)
     249              : {
     250         5098 :   CrateNum crateNum = lookup_crate_num (id).value ();
     251         5098 :   auto it = ast_crate.find (crateNum);
     252         5098 :   rust_assert (it != ast_crate.end ());
     253         5098 :   return it->second;
     254              : }
     255              : 
     256              : AST::Crate &
     257         5123 : CrateMappings::insert_ast_crate (std::unique_ptr<AST::Crate> &&crate,
     258              :                                  CrateNum crate_num)
     259              : {
     260         5123 :   auto it = ast_crate.find (crate_num);
     261         5123 :   rust_assert (it == ast_crate.end ());
     262              : 
     263              :   // store it
     264         5123 :   crate_node_to_crate_num.insert ({crate->get_node_id (), crate_num});
     265         5123 :   ast_crate.insert ({crate_num, crate.release ()});
     266              : 
     267              :   // return the reference to it
     268         5123 :   it = ast_crate.find (crate_num);
     269         5123 :   rust_assert (it != ast_crate.end ());
     270         5123 :   return *it->second;
     271              : }
     272              : 
     273              : HIR::Crate &
     274            0 : Mappings::get_hir_crate (CrateNum crateNum)
     275              : {
     276            0 :   auto it = hir_crate_mappings.find (crateNum);
     277            0 :   rust_assert (it != hir_crate_mappings.end ());
     278            0 :   return *it->second;
     279              : }
     280              : 
     281              : bool
     282       118920 : Mappings::is_local_hirid_crate (HirId crateNum)
     283              : {
     284       236293 :   for (const auto &it : hir_crate_mappings)
     285              :     {
     286       119136 :       const auto &crate = it.second;
     287       119136 :       if (crate->get_mappings ().get_hirid () == crateNum)
     288       118920 :         return true;
     289              :     }
     290              :   return false;
     291              : }
     292              : 
     293              : HIR::Crate &
     294         4822 : Mappings::insert_hir_crate (std::unique_ptr<HIR::Crate> &&crate)
     295              : {
     296         4822 :   CrateNum crateNum = crate->get_mappings ().get_crate_num ();
     297         4822 :   auto it = hir_crate_mappings.find (crateNum);
     298         4822 :   rust_assert (it == hir_crate_mappings.end ());
     299              : 
     300         4814 :   insert_node_to_hir (crate->get_mappings ().get_nodeid (),
     301         4814 :                       crate->get_mappings ().get_hirid ());
     302         4814 :   hir_crate_mappings.insert ({crateNum, crate.release ()});
     303              : 
     304         4814 :   it = hir_crate_mappings.find (crateNum);
     305         4814 :   rust_assert (it != hir_crate_mappings.end ());
     306         4814 :   return *it->second;
     307              : }
     308              : 
     309              : void
     310        61960 : Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
     311              : {
     312        61960 :   CrateNum crate_num = id.crateNum;
     313        61960 :   LocalDefId local_def_id = id.localDefId;
     314              : 
     315        61960 :   rust_assert (!lookup_defid (id));
     316        61960 :   rust_assert (!lookup_local_defid (crate_num, local_def_id));
     317        61960 :   rust_assert (!lookup_trait_item_defid (id));
     318              : 
     319        61960 :   defIdMappings[id] = item;
     320        61960 :   insert_local_defid_mapping (crate_num, local_def_id, item);
     321        61960 : }
     322              : 
     323              : tl::optional<HIR::Item *>
     324       162707 : Mappings::lookup_defid (DefId id)
     325              : {
     326       162707 :   auto it = defIdMappings.find (id);
     327       162707 :   if (it == defIdMappings.end ())
     328        74183 :     return tl::nullopt;
     329              : 
     330        88524 :   return it->second;
     331              : }
     332              : 
     333              : void
     334         4211 : Mappings::insert_defid_mapping (DefId id, HIR::TraitItem *item)
     335              : {
     336         4211 :   CrateNum crate_num = id.crateNum;
     337         4211 :   LocalDefId local_def_id = id.localDefId;
     338              : 
     339         4211 :   rust_assert (!lookup_defid (id));
     340         4211 :   rust_assert (!lookup_local_defid (crate_num, local_def_id));
     341         4211 :   rust_assert (!lookup_trait_item_defid (id));
     342              : 
     343         4211 :   defIdTraitItemMappings[id] = item;
     344         4211 : }
     345              : 
     346              : tl::optional<HIR::TraitItem *>
     347        69148 : Mappings::lookup_trait_item_defid (DefId id)
     348              : {
     349        69148 :   auto it = defIdTraitItemMappings.find (id);
     350        69148 :   if (it == defIdTraitItemMappings.end ())
     351        68086 :     return tl::nullopt;
     352              : 
     353         1062 :   return it->second;
     354              : }
     355              : 
     356              : void
     357         1498 : Mappings::insert_hir_enumitem (HIR::Enum *parent, HIR::EnumItem *item)
     358              : {
     359         1498 :   auto id = item->get_mappings ().get_hirid ();
     360         1498 :   auto result = lookup_hir_enumitem (id);
     361         1498 :   rust_assert (result.first == nullptr);
     362              : 
     363         1498 :   hirEnumItemMappings[id] = {parent, item};
     364         1498 :   insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
     365         1498 : }
     366              : 
     367              : std::pair<HIR::Enum *, HIR::EnumItem *>
     368        69178 : Mappings::lookup_hir_enumitem (HirId id)
     369              : {
     370        69178 :   auto it = hirEnumItemMappings.find (id);
     371        69178 :   if (it == hirEnumItemMappings.end ())
     372        59979 :     return {nullptr, nullptr};
     373              : 
     374         9199 :   return it->second;
     375              : }
     376              : 
     377              : void
     378         3535 : Mappings::insert_hir_extern_item (HIR::ExternalItem *item, HirId parent_block)
     379              : {
     380         3535 :   auto id = item->get_mappings ().get_hirid ();
     381         3535 :   rust_assert (!lookup_hir_extern_item (id));
     382              : 
     383         3535 :   hirExternItemMappings[id] = {item, parent_block};
     384         3535 :   insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
     385         3535 : }
     386              : 
     387              : tl::optional<std::pair<HIR::ExternalItem *, HirId>>
     388        52186 : Mappings::lookup_hir_extern_item (HirId id)
     389              : {
     390        52186 :   auto it = hirExternItemMappings.find (id);
     391        52186 :   if (it == hirExternItemMappings.end ())
     392        45464 :     return tl::nullopt;
     393              : 
     394         6722 :   return it->second;
     395              : }
     396              : 
     397              : void
     398        14611 : Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
     399              : {
     400        14611 :   auto id = item->get_mappings ().get_hirid ();
     401        14611 :   rust_assert (!lookup_hir_impl_block (id));
     402              : 
     403        14611 :   HirId impl_type_id = item->get_type ().get_mappings ().get_hirid ();
     404        14611 :   hirImplBlockMappings[id] = item;
     405        14611 :   if (item->has_trait_ref ())
     406        13097 :     hirTraitImplBlockMappings[id] = item;
     407              :   else
     408              :     {
     409         7565 :       for (auto &impl_item : item->get_impl_items ())
     410              :         {
     411         6051 :           if (impl_item->get_impl_item_type ()
     412              :               != HIR::ImplItem::ImplItemType::FUNCTION)
     413         1665 :             continue;
     414              : 
     415         5910 :           auto *function = static_cast<HIR::Function *> (impl_item.get ());
     416         5910 :           if (!function->is_method ())
     417         1524 :             continue;
     418              : 
     419         8772 :           auto name = function->get_function_name ().as_string ();
     420         4386 :           hirInherentImplItemMappings[name].emplace_back (impl_item.get (),
     421              :                                                           item);
     422         4386 :         }
     423              :     }
     424        14611 :   hirImplBlockTypeMappings[impl_type_id] = item;
     425        14611 :   insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
     426        14611 : }
     427              : 
     428              : tl::optional<HIR::ImplBlock *>
     429        16662 : Mappings::lookup_hir_impl_block (HirId id)
     430              : {
     431        16662 :   auto it = hirImplBlockMappings.find (id);
     432        16662 :   if (it == hirImplBlockMappings.end ())
     433        14611 :     return tl::nullopt;
     434              : 
     435         2051 :   return it->second;
     436              : }
     437              : 
     438              : tl::optional<HIR::ImplBlock *>
     439          522 : Mappings::lookup_impl_block_type (HirId id)
     440              : {
     441          522 :   auto it = hirImplBlockTypeMappings.find (id);
     442          522 :   if (it == hirImplBlockTypeMappings.end ())
     443           56 :     return tl::nullopt;
     444              : 
     445          466 :   return it->second;
     446              : }
     447              : 
     448              : void
     449        23033 : Mappings::insert_hir_implitem (HirId parent_impl_id, HIR::ImplItem *item)
     450              : {
     451        23033 :   auto id = item->get_impl_mappings ().get_hirid ();
     452        23033 :   rust_assert (!lookup_hir_implitem (id));
     453              : 
     454        23033 :   hirImplItemMappings[id]
     455        23033 :     = std::pair<HirId, HIR::ImplItem *> (parent_impl_id, item);
     456        23033 :   insert_node_to_hir (item->get_impl_mappings ().get_nodeid (), id);
     457        23033 : }
     458              : 
     459              : tl::optional<std::pair<HIR::ImplItem *, HirId>>
     460       118650 : Mappings::lookup_hir_implitem (HirId id)
     461              : {
     462       118650 :   auto it = hirImplItemMappings.find (id);
     463       118650 :   if (it == hirImplItemMappings.end ())
     464        96470 :     return tl::nullopt;
     465              : 
     466        22180 :   return std::make_pair (it->second.second, it->second.first);
     467              : }
     468              : 
     469              : void
     470        61960 : Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
     471              :                                       HIR::Item *item)
     472              : {
     473        61960 :   rust_assert (!lookup_local_defid (crateNum, id));
     474        61960 :   localDefIdMappings[crateNum][id] = item;
     475        61960 : }
     476              : 
     477              : tl::optional<HIR::Item *>
     478       128131 : Mappings::lookup_local_defid (CrateNum crateNum, LocalDefId id)
     479              : {
     480       128131 :   auto it = localDefIdMappings.find (crateNum);
     481       128131 :   if (it == localDefIdMappings.end ())
     482         9617 :     return tl::nullopt;
     483              : 
     484       118514 :   auto iy = it->second.find (id);
     485       118514 :   if (iy == it->second.end ())
     486       118514 :     return tl::nullopt;
     487              : 
     488            0 :   return iy->second;
     489              : }
     490              : 
     491              : void
     492            0 : Mappings::walk_local_defids_for_crate (CrateNum crateNum,
     493              :                                        std::function<bool (HIR::Item *)> cb)
     494              : {
     495            0 :   auto it = localDefIdMappings.find (crateNum);
     496            0 :   if (it == localDefIdMappings.end ())
     497              :     return;
     498              : 
     499            0 :   for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
     500              :     {
     501            0 :       if (!cb (iy->second))
     502            0 :         return;
     503              :     }
     504              : }
     505              : 
     506              : void
     507      1479803 : Mappings::insert_node_to_hir (NodeId id, HirId ref)
     508              : {
     509      1479803 :   nodeIdToHirMappings[id] = ref;
     510      1479803 :   hirIdToNodeMappings[ref] = id;
     511      1479803 : }
     512              : 
     513              : tl::optional<HirId>
     514       716820 : Mappings::lookup_node_to_hir (NodeId id)
     515              : {
     516       716820 :   auto it = nodeIdToHirMappings.find (id);
     517       716820 :   if (it == nodeIdToHirMappings.end ())
     518            0 :     return tl::nullopt;
     519              : 
     520       716820 :   return {it->second};
     521              : }
     522              : 
     523              : tl::optional<NodeId>
     524         8050 : Mappings::lookup_hir_to_node (HirId id)
     525              : {
     526         8050 :   auto it = hirIdToNodeMappings.find (id);
     527         8050 :   if (it == hirIdToNodeMappings.end ())
     528            0 :     return tl::nullopt;
     529              : 
     530         8050 :   return {it->second};
     531              : }
     532              : 
     533              : void
     534      2138412 : Mappings::insert_location (HirId id, location_t locus)
     535              : {
     536      2138412 :   locations[id] = locus;
     537      2138412 : }
     538              : 
     539              : location_t
     540      1244884 : Mappings::lookup_location (HirId id)
     541              : {
     542      1244884 :   auto it = locations.find (id);
     543      1244884 :   if (it == locations.end ())
     544              :     return UNDEF_LOCATION;
     545              : 
     546      1121262 :   return it->second;
     547              : }
     548              : 
     549              : tl::optional<HIR::Stmt *>
     550            0 : Mappings::resolve_nodeid_to_stmt (NodeId id)
     551              : {
     552            0 :   auto it = nodeIdToHirMappings.find (id);
     553            0 :   if (it == nodeIdToHirMappings.end ())
     554            0 :     return tl::nullopt;
     555              : 
     556            0 :   HirId resolved = it->second;
     557            0 :   return hir.stmts.lookup (resolved);
     558              : }
     559              : 
     560              : void
     561         5874 : Mappings::iterate_impl_items (
     562              :   std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
     563              : {
     564        88118 :   for (auto it = hirImplItemMappings.begin (); it != hirImplItemMappings.end ();
     565        82244 :        it++)
     566              :     {
     567        82244 :       auto id = it->first;
     568        82244 :       auto impl_item = it->second.second;
     569        82244 :       auto impl
     570        82244 :         = lookup_associated_impl (impl_item->get_impl_mappings ().get_hirid ());
     571        82244 :       if (!cb (id, impl_item, impl))
     572         5874 :         return;
     573              :     }
     574              : }
     575              : 
     576              : void
     577         6087 : Mappings::insert_adt_impl_mapping (DefId adt_id, HIR::ImplBlock *impl)
     578              : {
     579         6087 :   hirAdtImplMappings[adt_id].push_back (impl);
     580         6087 :   hirIndexedAdtImpls.insert (impl);
     581         6087 : }
     582              : 
     583              : void
     584         4782 : Mappings::build_impl_indexes ()
     585              : {
     586         4782 :   gcc_checking_assert (!hirImplIndexesBuilt);
     587         4782 :   if (hirImplIndexesBuilt)
     588              :     return;
     589         4782 :   hirImplIndexesBuilt = true;
     590              : 
     591         4782 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     592        32487 :   auto resolve_item = [&] (const HIR::Type &type) -> HIR::Item * {
     593        27705 :     auto node_id = nr_ctx.lookup (type.get_mappings ().get_nodeid (),
     594              :                                   Resolver2_0::Namespace::Types);
     595        27705 :     if (!node_id.has_value ())
     596              :       return nullptr;
     597              : 
     598        25190 :     auto hir_id = lookup_node_to_hir (node_id.value ());
     599        25190 :     gcc_checking_assert (hir_id.has_value ());
     600        25190 :     if (!hir_id.has_value ())
     601              :       return nullptr;
     602              : 
     603        25190 :     auto item = hir.items.lookup (hir_id.value ());
     604        25190 :     return item.has_value () ? item.value () : nullptr;
     605         4782 :   };
     606              : 
     607         4782 :   iterate_impl_blocks ([&] (HirId, HIR::ImplBlock *impl) -> bool {
     608        14609 :     HIR::Item *self_item = resolve_item (impl->get_type ());
     609        14609 :     if (self_item != nullptr)
     610              :       {
     611         6088 :         auto kind = self_item->get_item_kind ();
     612         6088 :         if (kind == HIR::Item::ItemKind::Struct
     613         6088 :             || kind == HIR::Item::ItemKind::Enum
     614            9 :             || kind == HIR::Item::ItemKind::Union)
     615         6087 :           insert_adt_impl_mapping (self_item->get_mappings ().get_defid (),
     616              :                                    impl);
     617              :       }
     618              : 
     619        14609 :     if (impl->has_trait_ref ())
     620              :       {
     621        13096 :         HIR::Item *trait_item = resolve_item (impl->get_trait_ref ());
     622        13096 :         if (trait_item != nullptr
     623        13096 :             && trait_item->get_item_kind () == HIR::Item::ItemKind::Trait)
     624        13028 :           insert_trait_impl_mapping (trait_item->get_mappings ().get_defid (),
     625              :                                      impl);
     626              :       }
     627        14609 :     return true;
     628              :   });
     629              : }
     630              : 
     631              : void
     632          770 : Mappings::iterate_adt_impl_items (
     633              :   DefId adt_id,
     634              :   std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
     635              : {
     636         3341 :   auto iterate_impl = [&] (HIR::ImplBlock *impl) {
     637         6074 :     for (auto &item : impl->get_impl_items ())
     638              :       {
     639         3503 :         HIR::ImplItem *impl_item = item.get ();
     640         3503 :         HirId id = impl_item->get_impl_mappings ().get_hirid ();
     641         3503 :         if (!cb (id, impl_item, impl))
     642         2571 :           return false;
     643              :       }
     644              :     return true;
     645          770 :   };
     646              : 
     647          770 :   auto adt_impls = hirAdtImplMappings.find (adt_id);
     648          770 :   if (adt_impls != hirAdtImplMappings.end ())
     649         1706 :     for (auto *impl : adt_impls->second)
     650          939 :       if (!iterate_impl (impl))
     651            0 :         return;
     652              : 
     653              :   // Impl self types which cannot be classified as a concrete ADT include
     654              :   // blanket implementations such as `impl<T> Trait for T`.  They must remain
     655              :   // candidates for every ADT receiver.
     656         3866 :   for (auto &mapping : hirImplBlockMappings)
     657              :     {
     658         3096 :       HIR::ImplBlock *impl = mapping.second;
     659         3096 :       if (hirIndexedAdtImpls.find (impl) == hirIndexedAdtImpls.end ())
     660         1632 :         if (!iterate_impl (impl))
     661            0 :           return;
     662              :     }
     663              : }
     664              : 
     665              : void
     666        13028 : Mappings::insert_trait_impl_mapping (DefId trait_id, HIR::ImplBlock *impl)
     667              : {
     668        13028 :   hirTraitImplMappings[trait_id].push_back (impl);
     669        13028 : }
     670              : 
     671              : void
     672         1571 : Mappings::iterate_trait_impl_blocks_for_item (
     673              :   const std::string &name, std::function<bool (HirId, HIR::ImplBlock *)> cb)
     674              : {
     675         1571 :   auto traits = hirTraitItemNameMappings.find (name);
     676         1571 :   if (traits == hirTraitItemNameMappings.end ())
     677         1571 :     return;
     678              : 
     679         2186 :   for (auto trait_id : traits->second)
     680              :     {
     681         1094 :       auto impls = hirTraitImplMappings.find (trait_id);
     682         1094 :       if (impls == hirTraitImplMappings.end ())
     683            3 :         continue;
     684              : 
     685         3574 :       for (auto *impl : impls->second)
     686         2483 :         if (!cb (impl->get_mappings ().get_hirid (), impl))
     687            0 :           return;
     688              :     }
     689              : }
     690              : 
     691              : void
     692         4211 : Mappings::insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait)
     693              : {
     694         4211 :   rust_assert (hirTraitItemsToTraitMappings.find (trait_item_id)
     695              :                == hirTraitItemsToTraitMappings.end ());
     696         4211 :   hirTraitItemsToTraitMappings[trait_item_id] = trait;
     697              : 
     698         4211 :   auto item = hir.trait_items.lookup (trait_item_id);
     699         4211 :   rust_assert (item.has_value ());
     700         4211 :   if (item.value ()->get_item_kind () != HIR::TraitItem::TraitItemKind::FUNC)
     701         1356 :     return;
     702              : 
     703         3251 :   auto *function = static_cast<HIR::TraitItemFunc *> (item.value ());
     704         3251 :   if (!function->get_decl ().is_method ())
     705              :     return;
     706              : 
     707         5710 :   auto name = function->get_decl ().get_function_name ().as_string ();
     708         2855 :   hirTraitItemNameMappings[name].push_back (
     709         2855 :     trait->get_mappings ().get_defid ());
     710         2855 : }
     711              : 
     712              : void
     713         1280 : Mappings::iterate_trait_impl_items (
     714              :   DefId trait_id,
     715              :   std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
     716              : {
     717         1280 :   auto trait_impls = hirTraitImplMappings.find (trait_id);
     718         1280 :   if (trait_impls == hirTraitImplMappings.end ())
     719              :     return;
     720              : 
     721         6261 :   for (auto *impl : trait_impls->second)
     722        14862 :     for (auto &item : impl->get_impl_items ())
     723              :       {
     724         9881 :         HIR::ImplItem *impl_item = item.get ();
     725         9881 :         HirId id = impl_item->get_impl_mappings ().get_hirid ();
     726         9881 :         if (!cb (id, impl_item, impl))
     727         1280 :           return;
     728              :       }
     729              : }
     730              : 
     731              : void
     732        71146 : Mappings::iterate_trait_impl_blocks (
     733              :   DefId trait_id, std::function<bool (HirId, HIR::ImplBlock *)> cb)
     734              : {
     735        71146 :   auto trait_impls = hirTraitImplMappings.find (trait_id);
     736        71146 :   if (trait_impls == hirTraitImplMappings.end ())
     737              :     return;
     738              : 
     739       322743 :   for (auto *impl : trait_impls->second)
     740       290628 :     if (!cb (impl->get_mappings ().get_hirid (), impl))
     741        71146 :       return;
     742              : }
     743              : 
     744              : void
     745         4782 : Mappings::iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb)
     746              : {
     747        19391 :   for (auto it = hirImplBlockMappings.begin ();
     748        19391 :        it != hirImplBlockMappings.end (); it++)
     749              :     {
     750        14609 :       HirId id = it->first;
     751        14609 :       HIR::ImplBlock *impl_block = it->second;
     752        14609 :       if (!cb (id, impl_block))
     753         4782 :         return;
     754              :     }
     755              : }
     756              : 
     757              : void
     758            0 : Mappings::iterate_trait_items (
     759              :   std::function<bool (HIR::TraitItem *, HIR::Trait *)> cb)
     760              : {
     761            0 :   for (auto it = hirTraitItemMappings.begin ();
     762            0 :        it != hirTraitItemMappings.end (); it++)
     763              :     {
     764            0 :       HirId trait_item_id = it->first;
     765            0 :       HIR::TraitItem *trait_item = it->second;
     766            0 :       HIR::Trait *trait = lookup_trait_item_mapping (trait_item_id);
     767              : 
     768            0 :       if (!cb (trait_item, trait))
     769            0 :         return;
     770              :     }
     771              : }
     772              : 
     773              : void
     774         1816 : Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
     775              : {
     776         1816 :   auto outer_attrs = macro->get_outer_attrs ();
     777         1816 :   bool should_be_builtin
     778         1816 :     = std::any_of (outer_attrs.begin (), outer_attrs.end (),
     779         1462 :                    [] (AST::Attribute attr) {
     780         1462 :                      return attr.get_path ()
     781         1462 :                             == Values::Attributes::RUSTC_BUILTIN_MACRO;
     782              :                    });
     783         1816 :   if (should_be_builtin)
     784              :     {
     785          198 :       auto builtin
     786          198 :         = MacroBuiltin::builtins.lookup (macro->get_rule_name ().as_string ());
     787          198 :       if (!builtin.has_value ())
     788              :         {
     789            2 :           rust_error_at (macro->get_locus (),
     790              :                          "cannot find a built-in macro with name %qs",
     791            2 :                          macro->get_rule_name ().as_string ().c_str ());
     792            2 :           return;
     793              :         }
     794              : 
     795          196 :       auto transcriber = MacroBuiltin::builtin_transcribers.find (
     796          196 :         macro->get_rule_name ().as_string ());
     797          196 :       macro->set_builtin_transcriber (transcriber->second);
     798              :     }
     799              : 
     800         1814 :   auto it = macroMappings.find (macro->get_node_id ());
     801         1814 :   rust_assert (it == macroMappings.end ());
     802              : 
     803         1814 :   macroMappings[macro->get_node_id ()] = {macro, crate.get_current_crate ()};
     804         1816 : }
     805              : 
     806              : tl::optional<AST::MacroRulesDefinition *>
     807       122141 : Mappings::lookup_macro_def (NodeId id)
     808              : {
     809       122141 :   auto it = macroMappings.find (id);
     810       122141 :   if (it == macroMappings.end ())
     811         1816 :     return tl::nullopt;
     812              : 
     813       120325 :   return it->second.first;
     814              : }
     815              : 
     816              : tl::optional<CrateNum>
     817          527 : Mappings::lookup_macro_def_crate (NodeId id)
     818              : {
     819          527 :   auto it = macroMappings.find (id);
     820          527 :   if (it == macroMappings.end ())
     821            0 :     return tl::nullopt;
     822              : 
     823          527 :   return it->second.second;
     824              : }
     825              : 
     826              : void
     827        61687 : Mappings::insert_macro_invocation (AST::MacroInvocation &invoc,
     828              :                                    AST::MacroRulesDefinition *def)
     829              : {
     830        61687 :   auto it = macroInvocations.find (invoc.get_node_id ());
     831        61687 :   rust_assert (it == macroInvocations.end ());
     832              : 
     833        61687 :   macroInvocations[invoc.get_node_id ()] = def;
     834        61687 : }
     835              : 
     836              : tl::optional<AST::MacroRulesDefinition *>
     837       123683 : Mappings::lookup_macro_invocation (AST::MacroInvocation &invoc)
     838              : {
     839       123683 :   auto it = macroInvocations.find (invoc.get_node_id ());
     840       123683 :   if (it == macroInvocations.end ())
     841        61999 :     return tl::nullopt;
     842              : 
     843        61684 :   return it->second;
     844              : }
     845              : 
     846              : void
     847           50 : Mappings::insert_exported_macro (AST::MacroRulesDefinition &def)
     848              : {
     849           50 :   exportedMacros.emplace_back (def);
     850           50 : }
     851              : 
     852              : std::vector<AST::MacroRulesDefinition>
     853         4446 : Mappings::get_exported_macros ()
     854              : {
     855         4446 :   return exportedMacros;
     856              : }
     857              : 
     858              : void
     859            0 : Mappings::insert_module_child (NodeId module, NodeId child)
     860              : {
     861            0 :   auto it = module_child_map.find (module);
     862            0 :   if (it == module_child_map.end ())
     863            0 :     module_child_map.insert ({module, {child}});
     864              :   else
     865            0 :     it->second.emplace_back (child);
     866            0 : }
     867              : 
     868              : tl::optional<std::vector<NodeId> &>
     869            0 : Mappings::lookup_module_children (NodeId module)
     870              : {
     871            0 :   auto it = module_child_map.find (module);
     872            0 :   if (it == module_child_map.end ())
     873            0 :     return tl::nullopt;
     874              : 
     875            0 :   return it->second;
     876              : }
     877              : 
     878              : void
     879         8208 : Mappings::insert_glob_container (NodeId id, AST::GlobContainer *container)
     880              : {
     881         8208 :   rust_assert (glob_containers.find (id) == glob_containers.end ());
     882              : 
     883              :   // Crates have different memory managements that regular items
     884         8208 :   if (container->get_glob_container_kind () == AST::GlobContainer::Kind::Crate)
     885         5098 :     glob_containers[id] = crate.get_ast_crate_by_node_id_raw (id);
     886              :   else
     887         3110 :     glob_containers[id] = container;
     888         8208 : }
     889              : 
     890              : void
     891        13844 : Mappings::insert_module_id (NodeId id)
     892              : {
     893        13844 :   module_ids.insert (id);
     894        13844 : }
     895              : 
     896              : bool
     897       175140 : Mappings::is_module (NodeId id)
     898              : {
     899       175140 :   return module_ids.find (id) != module_ids.end ();
     900              : }
     901              : 
     902              : void
     903          174 : Mappings::insert_extern_crate_id (NodeId id)
     904              : {
     905          174 :   extern_crate_ids.insert (id);
     906          174 : }
     907              : 
     908              : bool
     909           88 : Mappings::is_extern_crate (NodeId id)
     910              : {
     911           88 :   return extern_crate_ids.find (id) != extern_crate_ids.end ();
     912              : }
     913              : 
     914              : tl::optional<AST::GlobContainer *>
     915        77485 : Mappings::lookup_glob_container (NodeId id)
     916              : {
     917        77485 :   auto it = glob_containers.find (id);
     918        77485 :   if (it == glob_containers.end ())
     919        25310 :     return tl::nullopt;
     920              : 
     921        52175 :   return {it->second};
     922              : }
     923              : 
     924              : void
     925            0 : Mappings::insert_module_child_item (NodeId module,
     926              :                                     Resolver::CanonicalPath child)
     927              : {
     928            0 :   rust_assert (!child.is_empty ());
     929            0 :   rust_assert (child.get_node_id () != UNKNOWN_NODEID);
     930              : 
     931            0 :   auto it = module_child_items.find (module);
     932            0 :   if (it == module_child_items.end ())
     933            0 :     module_child_items.insert ({module, {child}});
     934              :   else
     935            0 :     it->second.emplace_back (child);
     936            0 : }
     937              : 
     938              : tl::optional<std::vector<Resolver::CanonicalPath> &>
     939            0 : Mappings::lookup_module_chidren_items (NodeId module)
     940              : {
     941            0 :   auto it = module_child_items.find (module);
     942            0 :   if (it == module_child_items.end ())
     943            0 :     return tl::nullopt;
     944              : 
     945            0 :   return it->second;
     946              : }
     947              : 
     948              : tl::optional<Resolver::CanonicalPath &>
     949            0 : Mappings::lookup_module_child (NodeId module, const std::string &item_name)
     950              : {
     951            0 :   tl::optional<std::vector<Resolver::CanonicalPath> &> children
     952            0 :     = lookup_module_chidren_items (module);
     953            0 :   if (!children.has_value ())
     954            0 :     return tl::nullopt;
     955              : 
     956              :   // lookup the children to match the name if we can
     957            0 :   for (auto &child : children.value ())
     958              :     {
     959            0 :       const std::string &raw_identifier = child.get ();
     960            0 :       bool found = raw_identifier.compare (item_name) == 0;
     961            0 :       if (found)
     962            0 :         return child;
     963            0 :     }
     964              : 
     965            0 :   return tl::nullopt;
     966              : }
     967              : 
     968              : void
     969            0 : Mappings::insert_child_item_to_parent_module_mapping (NodeId child_item,
     970              :                                                       NodeId parent_module)
     971              : {
     972            0 :   child_to_parent_module_map.insert ({child_item, parent_module});
     973            0 : }
     974              : 
     975              : tl::optional<NodeId>
     976            0 : Mappings::lookup_parent_module (NodeId child_item)
     977              : {
     978            0 :   auto it = child_to_parent_module_map.find (child_item);
     979            0 :   if (it == child_to_parent_module_map.end ())
     980            0 :     return tl::nullopt;
     981              : 
     982            0 :   return it->second;
     983              : }
     984              : 
     985              : bool
     986            0 : Mappings::node_is_module (NodeId query)
     987              : {
     988            0 :   return module_child_items.find (query) != module_child_items.end ();
     989              : }
     990              : 
     991              : void
     992        37479 : Mappings::insert_ast_item (AST::Item *item)
     993              : {
     994        37479 :   auto it = ast_item_mappings.find (item->get_node_id ());
     995        37479 :   rust_assert (it == ast_item_mappings.end ());
     996              : 
     997        37479 :   ast_item_mappings[item->get_node_id ()] = item;
     998        37479 : }
     999              : 
    1000              : tl::optional<AST::Item *>
    1001            0 : Mappings::lookup_ast_item (NodeId id)
    1002              : {
    1003            0 :   auto it = ast_item_mappings.find (id);
    1004            0 :   if (it == ast_item_mappings.end ())
    1005            0 :     return tl::nullopt;
    1006              : 
    1007            0 :   return it->second;
    1008              : }
    1009              : 
    1010              : HIR::ImplBlock *
    1011        67924 : Mappings::lookup_builtin_marker ()
    1012              : {
    1013        67924 :   return builtinMarker;
    1014              : }
    1015              : 
    1016              : // FIXME: Before merging: Should we remove the `locus` parameter here? since
    1017              : // lang items are looked up mostly for code generation, it doesn't make sense to
    1018              : // error out on the locus of the node trying to access an inexistant lang item
    1019              : DefId
    1020         8894 : Mappings::get_lang_item (LangItem::Kind item_type, location_t locus)
    1021              : {
    1022         8894 :   if (auto item = lookup_lang_item (item_type))
    1023         8893 :     return *item;
    1024              : 
    1025            2 :   rust_fatal_error (locus, "failed to find lang item %s",
    1026            1 :                     LangItem::ToString (item_type).c_str ());
    1027              : }
    1028              : 
    1029              : tl::optional<HIR::TraitItem *>
    1030           43 : Mappings::lookup_trait_item_lang_item (LangItem::Kind item, location_t locus)
    1031              : {
    1032           43 :   DefId trait_item_id = get_lang_item (item, locus);
    1033           43 :   return lookup_trait_item_defid (trait_item_id);
    1034              : }
    1035              : 
    1036              : void
    1037         3893 : Mappings::insert_lang_item (LangItem::Kind item_type, DefId id)
    1038              : {
    1039         3893 :   auto it = lang_item_mappings.find (item_type);
    1040         3893 :   rust_assert (it == lang_item_mappings.end ());
    1041              : 
    1042         3893 :   lang_item_mappings[item_type] = id;
    1043         3893 : }
    1044              : 
    1045              : tl::optional<DefId &>
    1046       230586 : Mappings::lookup_lang_item (LangItem::Kind item_type)
    1047              : {
    1048       230586 :   auto it = lang_item_mappings.find (item_type);
    1049       230586 :   if (it == lang_item_mappings.end ())
    1050       148854 :     return tl::nullopt;
    1051              : 
    1052        81732 :   return it->second;
    1053              : }
    1054              : 
    1055              : void
    1056         3928 : Mappings::insert_lang_item_node (LangItem::Kind item_type, NodeId node_id)
    1057              : {
    1058         3928 :   auto it = lang_item_nodes.find (item_type);
    1059         3928 :   rust_assert (it == lang_item_nodes.end ());
    1060              : 
    1061         3928 :   lang_item_nodes.insert ({item_type, node_id});
    1062         3928 : }
    1063              : 
    1064              : tl::optional<NodeId &>
    1065         4089 : Mappings::lookup_lang_item_node (LangItem::Kind item_type)
    1066              : {
    1067         4089 :   auto it = lang_item_nodes.find (item_type);
    1068         4089 :   if (it == lang_item_nodes.end ())
    1069            1 :     return tl::nullopt;
    1070              : 
    1071         4088 :   return it->second;
    1072              : }
    1073              : 
    1074              : NodeId
    1075         4089 : Mappings::get_lang_item_node (LangItem::Kind item_type)
    1076              : {
    1077         4089 :   if (auto lookup = lookup_lang_item_node (item_type))
    1078         4088 :     return *lookup;
    1079              : 
    1080            2 :   rust_fatal_error (UNKNOWN_LOCATION, "undeclared lang item: %qs",
    1081            1 :                     LangItem::PrettyString (item_type).c_str ());
    1082              : }
    1083              : 
    1084              : std::string &
    1085         1525 : Mappings::get_lang_item_identifier (LangItem::Kind item_type)
    1086              : {
    1087              :   // Lang item names are hardcoded because they're only required for metadata
    1088              :   // dump which will get removed at some point
    1089         1525 :   static std::unordered_map<LangItem::Kind, std::string> identifiers
    1090          101 :     = {{LangItem::Kind::COPY, "Copy"},
    1091          101 :        {LangItem::Kind::CLONE, "Clone"},
    1092          101 :        {LangItem::Kind::STRUCTURAL_PEQ, "StructuralPartialEq"},
    1093          101 :        {LangItem::Kind::STRUCTURAL_TEQ, "StructuralEq"},
    1094          101 :        {LangItem::Kind::SIZED, "Sized"},
    1095          101 :        {LangItem::Kind::EQ, "PartialEq"},
    1096         2333 :        {LangItem::Kind::PHANTOM_DATA, "PhantomData"}};
    1097         1525 :   auto result = identifiers.find (item_type);
    1098         1525 :   if (result != identifiers.cend ())
    1099         1525 :     return result->second;
    1100            0 :   rust_unreachable ();
    1101              : }
    1102              : 
    1103              : void
    1104           22 : Mappings::insert_auto_trait (HIR::Trait *trait)
    1105              : {
    1106           22 :   auto_traits.emplace_back (trait);
    1107           22 : }
    1108              : 
    1109              : std::vector<HIR::Trait *> &
    1110        68102 : Mappings::get_auto_traits ()
    1111              : {
    1112        68102 :   return auto_traits;
    1113              : }
    1114              : 
    1115              : void
    1116          117 : Mappings::add_capture (NodeId closure, NodeId definition)
    1117              : {
    1118          117 :   auto cap = captures.find (closure);
    1119          117 :   if (cap == captures.end ())
    1120           76 :     captures[closure] = {definition};
    1121              :   else
    1122           41 :     cap->second.push_back (definition);
    1123          117 : }
    1124              : 
    1125              : tl::optional<std::vector<NodeId>>
    1126           66 : Mappings::lookup_captures (NodeId closure)
    1127              : {
    1128           66 :   auto cap = captures.find (closure);
    1129           66 :   if (cap == captures.end ())
    1130           45 :     return tl::nullopt;
    1131              :   else
    1132           21 :     return cap->second;
    1133              : }
    1134              : 
    1135              : void
    1136         1681 : Mappings::add_derived_node (NodeId node_id)
    1137              : {
    1138         1681 :   derived_nodes.insert (node_id);
    1139         1681 : }
    1140              : 
    1141              : bool
    1142            0 : Mappings::is_derived_node (NodeId node_id)
    1143              : {
    1144            0 :   return derived_nodes.find (node_id) != derived_nodes.end ();
    1145              : }
    1146              : 
    1147              : void
    1148       505760 : Mappings::add_function_node (NodeId node_id)
    1149              : {
    1150       505760 :   function_nodes.insert (node_id);
    1151       505760 : }
    1152              : 
    1153              : bool
    1154         1021 : Mappings::is_function_node (NodeId node_id)
    1155              : {
    1156         1021 :   return function_nodes.find (node_id) != function_nodes.end ();
    1157              : }
    1158              : 
    1159              : } // namespace Analysis
    1160              : } // namespace Rust
        

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