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-name-resolver.h"
20 : #include "rust-ast-full.h"
21 :
22 : // for flag_name_resolution_2_0
23 : #include "options.h"
24 :
25 : namespace Rust {
26 : namespace Resolver {
27 :
28 0 : Rib::Rib (CrateNum crateNum, NodeId node_id)
29 0 : : crate_num (crateNum), node_id (node_id)
30 0 : {}
31 :
32 : void
33 0 : Rib::insert_name (
34 : const CanonicalPath &path, NodeId id, location_t locus, bool shadow,
35 : ItemType type,
36 : std::function<void (const CanonicalPath &, NodeId, location_t)> dup_cb)
37 : {
38 0 : auto it = path_mappings.find (path);
39 0 : bool path_already_exists = it != path_mappings.end ();
40 0 : if (path_already_exists && !shadow)
41 : {
42 0 : const auto &decl = decls_within_rib.find (it->second);
43 0 : if (decl != decls_within_rib.end ())
44 0 : dup_cb (path, it->second, decl->second);
45 : else
46 0 : dup_cb (path, it->second, locus);
47 :
48 0 : return;
49 : }
50 :
51 0 : path_mappings[path] = id;
52 0 : reverse_path_mappings.insert ({id, path});
53 0 : decls_within_rib.insert ({id, locus});
54 0 : references[id] = {};
55 0 : decl_type_mappings.insert ({id, type});
56 : }
57 :
58 : bool
59 0 : Rib::lookup_name (const CanonicalPath &ident, NodeId *id)
60 : {
61 0 : auto it = path_mappings.find (ident);
62 0 : if (it == path_mappings.end ())
63 : return false;
64 :
65 0 : *id = it->second;
66 0 : return true;
67 : }
68 :
69 : void
70 0 : Rib::clear_name (const CanonicalPath &ident, NodeId id)
71 : {
72 0 : auto ii = path_mappings.find (ident);
73 0 : if (ii != path_mappings.end ())
74 0 : path_mappings.erase (ii);
75 :
76 0 : auto ij = reverse_path_mappings.find (id);
77 0 : if (ij != reverse_path_mappings.end ())
78 0 : reverse_path_mappings.erase (ij);
79 :
80 0 : auto ik = decls_within_rib.find (id);
81 0 : if (ik != decls_within_rib.end ())
82 0 : decls_within_rib.erase (ik);
83 0 : }
84 :
85 : void
86 0 : Rib::append_reference_for_def (NodeId def, NodeId ref)
87 : {
88 0 : references[def].insert (ref);
89 0 : }
90 :
91 : bool
92 0 : Rib::have_references_for_node (NodeId def) const
93 : {
94 0 : auto it = references.find (def);
95 0 : if (it == references.end ())
96 : return false;
97 :
98 0 : return !it->second.empty ();
99 : }
100 :
101 : bool
102 0 : Rib::decl_was_declared_here (NodeId def) const
103 : {
104 0 : for (auto &it : decls_within_rib)
105 : {
106 0 : if (it.first == def)
107 0 : return true;
108 : }
109 : return false;
110 : }
111 :
112 : bool
113 0 : Rib::lookup_decl_type (NodeId def, ItemType *type) const
114 : {
115 0 : auto it = decl_type_mappings.find (def);
116 0 : if (it == decl_type_mappings.end ())
117 : return false;
118 :
119 0 : *type = it->second;
120 0 : return true;
121 : }
122 :
123 : void
124 0 : Rib::debug () const
125 : {
126 0 : fprintf (stderr, "%s\n", debug_str ().c_str ());
127 0 : }
128 :
129 : std::string
130 0 : Rib::debug_str () const
131 : {
132 0 : std::string buffer;
133 0 : for (const auto &it : path_mappings)
134 : {
135 0 : buffer += it.first.get () + "=" + std::to_string (it.second);
136 0 : buffer += ",";
137 : }
138 0 : return "{" + buffer + "}";
139 0 : }
140 :
141 0 : Scope::Scope (CrateNum crate_num) : crate_num (crate_num) {}
142 :
143 : void
144 0 : Scope::insert (
145 : const CanonicalPath &ident, NodeId id, location_t locus, bool shadow,
146 : Rib::ItemType type,
147 : std::function<void (const CanonicalPath &, NodeId, location_t)> dup_cb)
148 : {
149 0 : peek ()->insert_name (ident, id, locus, shadow, type, dup_cb);
150 0 : }
151 :
152 : void
153 0 : Scope::insert (const CanonicalPath &ident, NodeId id, location_t locus,
154 : Rib::ItemType type)
155 : {
156 0 : peek ()->insert_name (ident, id, locus, true, type,
157 0 : [] (const CanonicalPath &, NodeId, location_t) -> void {
158 : });
159 0 : }
160 :
161 : bool
162 0 : Scope::lookup (const CanonicalPath &ident, NodeId *id)
163 : {
164 0 : NodeId lookup = UNKNOWN_NODEID;
165 0 : iterate ([&] (Rib *r) mutable -> bool {
166 0 : if (r->lookup_name (ident, &lookup))
167 0 : return false;
168 : return true;
169 : });
170 :
171 0 : *id = lookup;
172 0 : return lookup != UNKNOWN_NODEID;
173 : }
174 :
175 : bool
176 0 : Scope::lookup_decl_type (NodeId id, Rib::ItemType *type)
177 : {
178 0 : bool found = false;
179 0 : iterate ([&] (const Rib *r) -> bool {
180 0 : if (r->decl_was_declared_here (id))
181 : {
182 0 : bool ok = r->lookup_decl_type (id, type);
183 0 : rust_assert (ok);
184 0 : found = true;
185 0 : return false;
186 : }
187 : return true;
188 : });
189 0 : return found;
190 : }
191 :
192 : bool
193 0 : Scope::lookup_rib_for_decl (NodeId id, const Rib **rib)
194 : {
195 0 : bool found = false;
196 0 : iterate ([&] (const Rib *r) -> bool {
197 0 : if (r->decl_was_declared_here (id))
198 : {
199 0 : *rib = r;
200 0 : found = true;
201 0 : return false;
202 : }
203 : return true;
204 : });
205 0 : return found;
206 : }
207 :
208 : void
209 0 : Scope::iterate (std::function<bool (Rib *)> cb)
210 : {
211 0 : for (auto it = stack.rbegin (); it != stack.rend (); ++it)
212 : {
213 0 : if (!cb (*it))
214 0 : return;
215 : }
216 : }
217 :
218 : void
219 0 : Scope::iterate (std::function<bool (const Rib *)> cb) const
220 : {
221 0 : for (auto it = stack.rbegin (); it != stack.rend (); ++it)
222 : {
223 0 : if (!cb (*it))
224 0 : return;
225 : }
226 : }
227 :
228 : Rib *
229 0 : Scope::peek ()
230 : {
231 0 : return stack.back ();
232 : }
233 :
234 : void
235 0 : Scope::push (NodeId id)
236 : {
237 0 : stack.push_back (new Rib (get_crate_num (), id));
238 0 : }
239 :
240 : Rib *
241 0 : Scope::pop ()
242 : {
243 0 : Rib *r = peek ();
244 0 : stack.pop_back ();
245 0 : return r;
246 : }
247 :
248 : void
249 0 : Scope::append_reference_for_def (NodeId refId, NodeId defId)
250 : {
251 0 : bool ok = false;
252 0 : iterate ([&] (Rib *r) mutable -> bool {
253 0 : if (r->decl_was_declared_here (defId))
254 : {
255 0 : ok = true;
256 0 : r->append_reference_for_def (defId, refId);
257 : }
258 0 : return true;
259 : });
260 0 : rust_assert (ok);
261 0 : }
262 :
263 : bool
264 0 : Scope::decl_was_declared_here (NodeId def) const
265 : {
266 0 : bool found = false;
267 0 : iterate ([&] (const Rib *r) -> bool {
268 0 : if (r->decl_was_declared_here (def))
269 : {
270 0 : found = true;
271 0 : return false;
272 : }
273 : return true;
274 : });
275 0 : return found;
276 : }
277 :
278 4684 : Resolver::Resolver () {}
279 :
280 : Resolver *
281 13052 : Resolver::get ()
282 : {
283 13052 : static Resolver *instance;
284 13052 : if (instance == nullptr)
285 4684 : instance = new Resolver ();
286 :
287 13052 : return instance;
288 : }
289 :
290 : void
291 0 : Resolver::insert_resolved_name (NodeId refId, NodeId defId)
292 : {
293 0 : rust_unreachable ();
294 : }
295 :
296 : bool
297 0 : Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
298 : {
299 0 : rust_unreachable ();
300 : }
301 :
302 : void
303 0 : Resolver::insert_resolved_type (NodeId refId, NodeId defId)
304 : {
305 0 : rust_unreachable ();
306 : }
307 :
308 : bool
309 0 : Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
310 : {
311 0 : rust_unreachable ();
312 : }
313 :
314 : void
315 0 : Resolver::insert_resolved_misc (NodeId refId, NodeId defId)
316 : {
317 0 : rust_unreachable ();
318 : }
319 :
320 : bool
321 0 : Resolver::lookup_resolved_misc (NodeId refId, NodeId *defId)
322 : {
323 0 : rust_unreachable ();
324 : }
325 :
326 : } // namespace Resolver
327 : } // namespace Rust
|