Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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-rib.h"
20 : : #include "rust-name-resolution-context.h"
21 : :
22 : : namespace Rust {
23 : : namespace Resolver2_0 {
24 : :
25 : 704 : Rib::Definition::Definition (NodeId id, bool shadowable)
26 : 704 : : ids ({id}), shadowable (shadowable)
27 : 704 : {}
28 : :
29 : : bool
30 : 226 : Rib::Definition::is_ambiguous () const
31 : : {
32 : 226 : return shadowable && ids.size () > 1;
33 : : }
34 : :
35 : : std::string
36 : 2146 : Rib::Definition::to_string () const
37 : : {
38 : 2146 : std::stringstream out;
39 : 4189 : out << (shadowable ? "(S)" : "(NS)") << "[";
40 : 2146 : std::string sep;
41 : 4297 : for (auto id : ids)
42 : : {
43 : 2151 : out << sep << id;
44 : 2151 : sep = ",";
45 : : }
46 : 2146 : out << "]";
47 : 2146 : return out.str ();
48 : 2146 : }
49 : :
50 : : Rib::Definition
51 : 28 : Rib::Definition::Shadowable (NodeId id)
52 : : {
53 : 28 : return Definition (id, true);
54 : : }
55 : :
56 : : Rib::Definition
57 : 676 : Rib::Definition::NonShadowable (NodeId id)
58 : : {
59 : 676 : return Definition (id, false);
60 : : }
61 : :
62 : 38 : DuplicateNameError::DuplicateNameError (std::string name, NodeId existing)
63 : 38 : : name (name), existing (existing)
64 : 38 : {}
65 : :
66 : 15019 : Rib::Rib (Kind kind) : kind (kind) {}
67 : :
68 : 0 : Rib::Rib (Kind kind, std::string identifier, NodeId id)
69 : 0 : : Rib (kind, {{identifier, id}})
70 : 0 : {}
71 : :
72 : 0 : Rib::Rib (Kind kind, std::unordered_map<std::string, NodeId> to_insert)
73 : 0 : : kind (kind)
74 : : {
75 : 0 : for (auto &value : to_insert)
76 : 0 : values.insert ({value.first, Definition::NonShadowable (value.second)});
77 : 0 : }
78 : :
79 : : tl::expected<NodeId, DuplicateNameError>
80 : 701 : Rib::insert (std::string name, Definition def)
81 : : {
82 : 701 : auto it = values.find (name);
83 : 701 : if (it == values.end ())
84 : : {
85 : : /* No old value */
86 : 652 : values[name] = def;
87 : : }
88 : 49 : else if (it->second.shadowable && def.shadowable)
89 : : { /* Both shadowable */
90 : 10 : auto ¤t = values[name];
91 : 20 : for (auto id : def.ids)
92 : : {
93 : 10 : if (std::find (current.ids.cbegin (), current.ids.cend (), id)
94 : 10 : == current.ids.cend ())
95 : : {
96 : 1 : current.ids.push_back (id);
97 : : }
98 : : }
99 : : }
100 : 39 : else if (it->second.shadowable)
101 : : { /* Only old shadowable : replace value */
102 : 1 : values[name] = def;
103 : : }
104 : : else /* Neither are shadowable */
105 : : {
106 : 114 : return tl::make_unexpected (
107 : 114 : DuplicateNameError (name, it->second.ids.back ()));
108 : : }
109 : :
110 : 663 : return def.ids.back ();
111 : : }
112 : :
113 : : tl::optional<Rib::Definition>
114 : 441 : Rib::get (const std::string &name)
115 : : {
116 : 441 : auto it = values.find (name);
117 : :
118 : 441 : if (it == values.end ())
119 : 297 : return tl::nullopt;
120 : :
121 : 144 : return it->second;
122 : : }
123 : :
124 : : const std::unordered_map<std::string, Rib::Definition> &
125 : 3397 : Rib::get_values () const
126 : : {
127 : 3397 : return values;
128 : : }
129 : :
130 : : } // namespace Resolver2_0
131 : : } // namespace Rust
|