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