LCOV - code coverage report
Current view: top level - gcc/rust/resolve - rust-forever-stack.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 0.0 % 129 0
Test Date: 2026-02-28 14:20:25 Functions: 0.0 % 26 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2024-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 "expected.h"
      20              : #include "rust-ast.h"
      21              : #include "rust-diagnostics.h"
      22              : #include "rust-forever-stack.h"
      23              : #include "rust-rib.h"
      24              : #include "optional.h"
      25              : 
      26              : namespace Rust {
      27              : namespace Resolver2_0 {
      28              : 
      29              : bool
      30            0 : ForeverStackStore::Node::is_root () const
      31              : {
      32            0 :   return !parent.has_value ();
      33              : }
      34              : 
      35              : bool
      36            0 : ForeverStackStore::Node::is_leaf () const
      37              : {
      38            0 :   return children.empty ();
      39              : }
      40              : 
      41              : NodeId
      42            0 : ForeverStackStore::Node::get_id () const
      43              : {
      44            0 :   return id;
      45              : }
      46              : 
      47              : ForeverStackStore::Node &
      48            0 : ForeverStackStore::Node::insert_child (NodeId id, tl::optional<Identifier> path,
      49              :                                        Rib::Kind kind)
      50              : {
      51            0 :   auto res = children.insert ({Link (id, path), Node (kind, id, *this)});
      52              : 
      53            0 :   rust_debug ("inserting link: Link(%d [%s]): existed? %s", id,
      54              :               path.has_value () ? path.value ().as_string ().c_str ()
      55              :                                 : "<anon>",
      56              :               !res.second ? "yes" : "no");
      57              : 
      58              :   // sanity check on rib kind
      59              :   // pick the value rib, since all ribs should have the same kind anyways
      60            0 :   rust_assert (res.second || res.first->second.value_rib.kind == kind);
      61              : 
      62              :   // verify, if we're using an existing node, our paths don't contradict
      63            0 :   if (!res.second && path.has_value ())
      64              :     {
      65            0 :       auto other_path = res.first->first.path;
      66            0 :       rust_assert (!other_path.has_value ()
      67              :                    || other_path.value ().as_string ()
      68              :                         == path.value ().as_string ());
      69            0 :     }
      70              : 
      71            0 :   return res.first->second;
      72              : }
      73              : 
      74              : tl::optional<ForeverStackStore::Node &>
      75            0 : ForeverStackStore::Node::get_child (const Identifier &path)
      76              : {
      77            0 :   for (auto &ent : children)
      78              :     {
      79            0 :       if (ent.first.path.has_value ()
      80            0 :           && ent.first.path->as_string () == path.as_string ())
      81            0 :         return ent.second;
      82              :     }
      83            0 :   return tl::nullopt;
      84              : }
      85              : 
      86              : tl::optional<const ForeverStackStore::Node &>
      87            0 : ForeverStackStore::Node::get_child (const Identifier &path) const
      88              : {
      89            0 :   for (auto &ent : children)
      90              :     {
      91            0 :       if (ent.first.path.has_value ()
      92            0 :           && ent.first.path->as_string () == path.as_string ())
      93            0 :         return ent.second;
      94              :     }
      95            0 :   return tl::nullopt;
      96              : }
      97              : 
      98              : tl::optional<ForeverStackStore::Node &>
      99            0 : ForeverStackStore::Node::get_parent ()
     100              : {
     101            0 :   return parent;
     102              : }
     103              : 
     104              : tl::optional<const ForeverStackStore::Node &>
     105            0 : ForeverStackStore::Node::get_parent () const
     106              : {
     107            0 :   if (parent)
     108            0 :     return *parent;
     109            0 :   return tl::nullopt;
     110              : }
     111              : 
     112              : tl::optional<const Identifier &>
     113            0 : ForeverStackStore::Node::get_parent_path () const
     114              : {
     115            0 :   if (parent.has_value ())
     116            0 :     for (auto &ent : parent->children)
     117            0 :       if (ent.first.id == id && ent.first.path.has_value ())
     118            0 :         return ent.first.path.value ();
     119            0 :   return tl::nullopt;
     120              : }
     121              : 
     122              : Rib &
     123            0 : ForeverStackStore::Node::get_rib (Namespace ns)
     124              : {
     125            0 :   switch (ns)
     126              :     {
     127            0 :     case Namespace::Values:
     128            0 :       return value_rib;
     129            0 :     case Namespace::Types:
     130            0 :       return type_rib;
     131            0 :     case Namespace::Labels:
     132            0 :       return label_rib;
     133            0 :     case Namespace::Macros:
     134            0 :       return macro_rib;
     135            0 :     default:
     136            0 :       rust_unreachable ();
     137              :     }
     138              : }
     139              : 
     140              : const Rib &
     141            0 : ForeverStackStore::Node::get_rib (Namespace ns) const
     142              : {
     143            0 :   switch (ns)
     144              :     {
     145            0 :     case Namespace::Values:
     146            0 :       return value_rib;
     147            0 :     case Namespace::Types:
     148            0 :       return type_rib;
     149            0 :     case Namespace::Labels:
     150            0 :       return label_rib;
     151            0 :     case Namespace::Macros:
     152            0 :       return macro_rib;
     153            0 :     default:
     154            0 :       rust_unreachable ();
     155              :     }
     156              : }
     157              : 
     158              : tl::expected<NodeId, DuplicateNameError>
     159            0 : ForeverStackStore::Node::insert (const Identifier &name, NodeId node,
     160              :                                  Namespace ns)
     161              : {
     162              :   // So what do we do here - if the Rib has already been pushed in an earlier
     163              :   // pass, we might end up in a situation where it is okay to re-add new names.
     164              :   // Do we just ignore that here? Do we keep track of if the Rib is new or not?
     165              :   // should our cursor have info on the current node like "is it newly pushed"?
     166            0 :   return get_rib (ns).insert (name.as_string (),
     167            0 :                               Rib::Definition::NonShadowable (node));
     168              : }
     169              : 
     170              : tl::expected<NodeId, DuplicateNameError>
     171            0 : ForeverStackStore::Node::insert_shadowable (const Identifier &name, NodeId node,
     172              :                                             Namespace ns)
     173              : {
     174            0 :   return get_rib (ns).insert (name.as_string (),
     175            0 :                               Rib::Definition::Shadowable (node));
     176              : }
     177              : 
     178              : tl::expected<NodeId, DuplicateNameError>
     179            0 : ForeverStackStore::Node::insert_globbed (const Identifier &name, NodeId node,
     180              :                                          Namespace ns)
     181              : {
     182            0 :   return get_rib (ns).insert (name.as_string (),
     183            0 :                               Rib::Definition::Globbed (node));
     184              : }
     185              : 
     186              : void
     187            0 : ForeverStackStore::Node::reverse_iter (std::function<KeepGoing (Node &)> lambda)
     188              : {
     189            0 :   for (Node *tmp = this; lambda (*tmp) == KeepGoing::Yes && !tmp->is_root ();
     190            0 :        tmp = &tmp->parent.value ())
     191              :     ;
     192            0 : }
     193              : 
     194              : void
     195            0 : ForeverStackStore::Node::reverse_iter (
     196              :   std::function<KeepGoing (const Node &)> lambda) const
     197              : {
     198            0 :   for (const Node *tmp = this;
     199            0 :        lambda (*tmp) == KeepGoing::Yes && !tmp->is_root ();
     200            0 :        tmp = &tmp->parent.value ())
     201              :     ;
     202            0 : }
     203              : 
     204              : void
     205            0 : ForeverStackStore::Node::child_iter (
     206              :   std::function<KeepGoing (NodeId, tl::optional<const Identifier &>, Node &)>
     207              :     lambda)
     208              : {
     209            0 :   for (auto &ent : children)
     210              :     {
     211            0 :       tl::optional<const Identifier &> path;
     212            0 :       if (ent.first.path.has_value ())
     213            0 :         path = ent.first.path.value ();
     214            0 :       auto keep_going = lambda (ent.first.id, path, ent.second);
     215            0 :       if (keep_going == KeepGoing::No)
     216            0 :         return;
     217              :     }
     218              : }
     219              : 
     220              : void
     221            0 : ForeverStackStore::Node::child_iter (
     222              :   std::function<KeepGoing (NodeId, tl::optional<const Identifier &>,
     223              :                            const Node &)>
     224              :     lambda) const
     225              : {
     226            0 :   for (auto &ent : children)
     227              :     {
     228            0 :       tl::optional<const Identifier &> path;
     229            0 :       if (ent.first.path.has_value ())
     230            0 :         path = ent.first.path.value ();
     231            0 :       auto keep_going = lambda (ent.first.id, path, ent.second);
     232            0 :       if (keep_going == KeepGoing::No)
     233            0 :         return;
     234              :     }
     235              : }
     236              : 
     237              : ForeverStackStore::Node &
     238            0 : ForeverStackStore::Node::find_closest_module ()
     239              : {
     240              :   // get kind of value_rib
     241              :   // but all ribs should share the same kind anyways
     242            0 :   if (value_rib.kind == Rib::Kind::Module || !parent.has_value ())
     243            0 :     return *this;
     244              :   else
     245            0 :     return parent->find_closest_module ();
     246              : }
     247              : 
     248              : const ForeverStackStore::Node &
     249            0 : ForeverStackStore::Node::find_closest_module () const
     250              : {
     251              :   // get kind of value_rib
     252              :   // but all ribs should share the same kind anyways
     253            0 :   if (value_rib.kind != Rib::Kind::Module || !parent.has_value ())
     254            0 :     return *this;
     255              :   else
     256            0 :     return parent->find_closest_module ();
     257              : }
     258              : 
     259              : tl::optional<ForeverStackStore::Node &>
     260            0 : ForeverStackStore::Node::dfs_node (NodeId to_find)
     261              : {
     262            0 :   if (id == to_find)
     263            0 :     return *this;
     264              : 
     265            0 :   for (auto &child : children)
     266              :     {
     267            0 :       auto candidate = child.second.dfs_node (to_find);
     268              : 
     269            0 :       if (candidate.has_value ())
     270            0 :         return candidate;
     271              :     }
     272              : 
     273            0 :   return tl::nullopt;
     274              : }
     275              : 
     276              : tl::optional<const ForeverStackStore::Node &>
     277            0 : ForeverStackStore::Node::dfs_node (NodeId to_find) const
     278              : {
     279            0 :   if (id == to_find)
     280            0 :     return *this;
     281              : 
     282            0 :   for (auto &child : children)
     283              :     {
     284            0 :       auto candidate = child.second.dfs_node (to_find);
     285              : 
     286            0 :       if (candidate.has_value ())
     287            0 :         return candidate;
     288              :     }
     289              : 
     290            0 :   return tl::nullopt;
     291              : }
     292              : 
     293              : ForeverStackStore::Node &
     294            0 : ForeverStackStore::get_root ()
     295              : {
     296            0 :   return root;
     297              : }
     298              : 
     299              : const ForeverStackStore::Node &
     300            0 : ForeverStackStore::get_root () const
     301              : {
     302            0 :   return root;
     303              : }
     304              : 
     305              : tl::optional<ForeverStackStore::Node &>
     306            0 : ForeverStackStore::get_node (NodeId node_id)
     307              : {
     308            0 :   return root.dfs_node (node_id);
     309              : }
     310              : 
     311              : tl::optional<const ForeverStackStore::Node &>
     312            0 : ForeverStackStore::get_node (NodeId node_id) const
     313              : {
     314            0 :   return root.dfs_node (node_id);
     315              : }
     316              : 
     317              : } // namespace Resolver2_0
     318              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.