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-rib.h"
20 : : #include "rust-name-resolution-context.h"
21 : :
22 : : namespace Rust {
23 : : namespace Resolver2_0 {
24 : :
25 : 37300 : Rib::Definition::Definition (NodeId id, Mode mode, bool enum_variant)
26 : 37300 : : enum_variant (enum_variant)
27 : : {
28 : 37300 : switch (mode)
29 : : {
30 : 2583 : case Mode::SHADOWABLE:
31 : 2583 : ids_shadowable.push_back (id);
32 : 2583 : return;
33 : 34705 : case Mode::NON_SHADOWABLE:
34 : 34705 : ids_non_shadowable.push_back (id);
35 : 34705 : return;
36 : 12 : case Mode::GLOBBED:
37 : 12 : ids_globbed.push_back (id);
38 : 12 : return;
39 : 0 : default:
40 : 0 : gcc_unreachable ();
41 : : }
42 : : }
43 : :
44 : : bool
45 : 38026 : Rib::Definition::is_ambiguous () const
46 : : {
47 : 38026 : if (!ids_shadowable.empty ())
48 : : return false;
49 : 35888 : else if (!ids_non_shadowable.empty ())
50 : 35878 : return ids_non_shadowable.size () > 1;
51 : : else
52 : 10 : return ids_globbed.size () > 1;
53 : : }
54 : :
55 : : bool
56 : 6628 : Rib::Definition::is_variant () const
57 : : {
58 : 6628 : return enum_variant;
59 : : }
60 : :
61 : : std::string
62 : 188195 : Rib::Definition::to_string () const
63 : : {
64 : 188195 : std::stringstream out;
65 : 188195 : const char *headers[3] = {"(S)[", "] (NS)[", "] (G)["};
66 : 188195 : const std::vector<NodeId> *id_lists[3]
67 : 188195 : = {&ids_shadowable, &ids_non_shadowable, &ids_globbed};
68 : 752780 : for (int i = 0; i < 3; i++)
69 : : {
70 : 564585 : out << headers[i];
71 : 564585 : std::string sep;
72 : 752930 : for (auto id : *id_lists[i])
73 : : {
74 : 188345 : out << sep << id;
75 : 188345 : sep = ",";
76 : : }
77 : 564585 : }
78 : 188195 : out << "]";
79 : 188195 : if (enum_variant)
80 : 1012 : out << "(enum variant)";
81 : 188195 : return out.str ();
82 : 188195 : }
83 : :
84 : : Rib::Definition
85 : 2583 : Rib::Definition::Shadowable (NodeId id)
86 : : {
87 : 2583 : return Definition (id, Mode::SHADOWABLE, false);
88 : : }
89 : :
90 : : Rib::Definition
91 : 34705 : Rib::Definition::NonShadowable (NodeId id, bool enum_variant)
92 : : {
93 : 34705 : return Definition (id, Mode::NON_SHADOWABLE, enum_variant);
94 : : }
95 : :
96 : : Rib::Definition
97 : 12 : Rib::Definition::Globbed (NodeId id)
98 : : {
99 : 12 : return Definition (id, Mode::GLOBBED, false);
100 : : }
101 : :
102 : 9557 : DuplicateNameError::DuplicateNameError (std::string name, NodeId existing)
103 : 9557 : : name (name), existing (existing)
104 : 9557 : {}
105 : :
106 : 204111 : Rib::Rib (Kind kind) : kind (kind) {}
107 : :
108 : 0 : Rib::Rib (Kind kind, std::string identifier, NodeId id)
109 : 0 : : Rib (kind, {{identifier, id}})
110 : 0 : {}
111 : :
112 : 0 : Rib::Rib (Kind kind, std::unordered_map<std::string, NodeId> to_insert)
113 : 0 : : kind (kind)
114 : : {
115 : 0 : for (auto &value : to_insert)
116 : 0 : values.insert ({value.first, Definition::NonShadowable (value.second)});
117 : 0 : }
118 : :
119 : : tl::expected<NodeId, DuplicateNameError>
120 : 35859 : Rib::insert (std::string name, Definition def)
121 : : {
122 : 35859 : auto it = values.find (name);
123 : 35859 : if (it == values.end ())
124 : : {
125 : : /* No old value */
126 : 26213 : values[name] = def;
127 : : }
128 : 9646 : else if (it->second.ids_non_shadowable.empty ()
129 : 9646 : || def.ids_non_shadowable.empty ())
130 : : { /* No non-shadowable conflict */
131 : 125 : auto ¤t = values[name];
132 : 126 : for (auto id : def.ids_non_shadowable)
133 : : {
134 : 1 : if (std::find (current.ids_non_shadowable.cbegin (),
135 : : current.ids_non_shadowable.cend (), id)
136 : 1 : == current.ids_non_shadowable.cend ())
137 : 1 : current.ids_non_shadowable.push_back (id);
138 : : else
139 : : // TODO: should this produce an error?
140 : 0 : return tl::make_unexpected (DuplicateNameError (name, id));
141 : : }
142 : 212 : for (auto id : def.ids_shadowable)
143 : : {
144 : 117 : if (std::find (current.ids_shadowable.cbegin (),
145 : : current.ids_shadowable.cend (), id)
146 : 117 : == current.ids_shadowable.cend ())
147 : 87 : current.ids_shadowable.push_back (id);
148 : : else
149 : : // TODO: should this produce an error?
150 : 30 : return tl::make_unexpected (DuplicateNameError (name, id));
151 : : }
152 : 96 : for (auto id : def.ids_globbed)
153 : : {
154 : 7 : if (std::find (current.ids_globbed.cbegin (),
155 : : current.ids_globbed.cend (), id)
156 : 7 : == current.ids_globbed.cend ())
157 : 1 : current.ids_globbed.push_back (id);
158 : : else
159 : : // TODO: should this produce an error?
160 : 6 : return tl::make_unexpected (DuplicateNameError (name, id));
161 : : }
162 : : }
163 : : else /* Multiple non-shadowable */
164 : : {
165 : 28563 : return tl::make_unexpected (
166 : 28563 : DuplicateNameError (name, it->second.ids_non_shadowable.back ()));
167 : : }
168 : :
169 : 26302 : if (!def.ids_shadowable.empty ())
170 : 2553 : return def.ids_shadowable.back ();
171 : 23749 : else if (!def.ids_non_shadowable.empty ())
172 : 23743 : return def.ids_non_shadowable.back ();
173 : 6 : rust_assert (!def.ids_globbed.empty ());
174 : 6 : return def.ids_globbed.back ();
175 : : }
176 : :
177 : : tl::optional<Rib::Definition>
178 : 31103 : Rib::get (const std::string &name)
179 : : {
180 : 31103 : auto it = values.find (name);
181 : :
182 : 31103 : if (it == values.end ())
183 : 20371 : return tl::nullopt;
184 : :
185 : 10732 : return it->second;
186 : : }
187 : :
188 : : const std::unordered_map<std::string, Rib::Definition> &
189 : 478882 : Rib::get_values () const
190 : : {
191 : 478882 : return values;
192 : : }
193 : :
194 : : } // namespace Resolver2_0
195 : : } // namespace Rust
|