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 : #ifndef RUST_NAME_RESOLVER_H
20 : #define RUST_NAME_RESOLVER_H
21 :
22 : #include "rust-system.h"
23 : #include "rust-canonical-path.h"
24 : #include "rust-hir-map.h"
25 : #include "rust-hir-type-check.h"
26 :
27 : namespace Rust {
28 : namespace Resolver {
29 :
30 : class Rib
31 : {
32 : public:
33 : enum ItemType
34 : {
35 : Var,
36 : Param,
37 : Function,
38 : Type,
39 : Module,
40 : Static,
41 : Const,
42 : Trait,
43 : Impl,
44 : TraitImpl,
45 : ExternCrate,
46 : MacroDecl,
47 : Label,
48 : Unknown
49 : };
50 :
51 : // FIXME
52 : // Rust uses local_def_ids assigned by def_collector on the AST. Consider
53 : // moving to a local-def-id
54 : Rib (CrateNum crateNum, NodeId node_id);
55 :
56 : // this takes the relative paths of items within a compilation unit for lookup
57 : void insert_name (
58 : const CanonicalPath &path, NodeId id, location_t locus, bool shadow,
59 : ItemType type,
60 : std::function<void (const CanonicalPath &, NodeId, location_t)> dup_cb);
61 :
62 : bool lookup_canonical_path (const NodeId &id, CanonicalPath *ident);
63 : bool lookup_name (const CanonicalPath &ident, NodeId *id);
64 : void clear_name (const CanonicalPath &ident, NodeId id);
65 : void append_reference_for_def (NodeId def, NodeId ref);
66 : bool have_references_for_node (NodeId def) const;
67 : bool decl_was_declared_here (NodeId def) const;
68 : bool lookup_decl_type (NodeId def, ItemType *type) const;
69 : void debug () const;
70 : std::string debug_str () const;
71 :
72 : CrateNum get_crate_num () const { return crate_num; }
73 0 : NodeId get_node_id () const { return node_id; }
74 : std::map<NodeId, location_t> &get_declarations () { return decls_within_rib; }
75 :
76 : private:
77 : CrateNum crate_num;
78 : NodeId node_id;
79 : std::map<CanonicalPath, NodeId> path_mappings;
80 : std::map<NodeId, CanonicalPath> reverse_path_mappings;
81 : std::map<NodeId, location_t> decls_within_rib;
82 : std::map<NodeId, std::set<NodeId>> references;
83 : std::map<NodeId, ItemType> decl_type_mappings;
84 : };
85 :
86 : class Scope
87 : {
88 : public:
89 : Scope (CrateNum crate_num);
90 :
91 : void insert (
92 : const CanonicalPath &ident, NodeId id, location_t locus, bool shadow,
93 : Rib::ItemType type,
94 : std::function<void (const CanonicalPath &, NodeId, location_t)> dup_cb);
95 :
96 : void insert (const CanonicalPath &ident, NodeId id, location_t locus,
97 : Rib::ItemType type = Rib::ItemType::Unknown);
98 : bool lookup (const CanonicalPath &ident, NodeId *id);
99 : bool lookup_decl_type (NodeId id, Rib::ItemType *type);
100 : bool lookup_rib_for_decl (NodeId id, const Rib **rib);
101 :
102 : void iterate (std::function<bool (Rib *)> cb);
103 : void iterate (std::function<bool (const Rib *)> cb) const;
104 :
105 : Rib *peek ();
106 : void push (NodeId id);
107 : Rib *pop ();
108 :
109 : bool decl_was_declared_here (NodeId def) const;
110 : void append_reference_for_def (NodeId refId, NodeId defId);
111 :
112 0 : CrateNum get_crate_num () const { return crate_num; }
113 :
114 0 : const std::vector<Rib *> &get_context () const { return stack; };
115 :
116 : private:
117 : CrateNum crate_num;
118 : std::vector<Rib *> stack;
119 : };
120 :
121 : class Resolver
122 : {
123 : public:
124 : static Resolver *get ();
125 : ~Resolver () {}
126 :
127 : // these builtin types
128 : void insert_builtin_types (Rib *r);
129 :
130 : // these will be required for type resolution passes to
131 : // map back to tyty nodes
132 : std::vector<AST::Type *> &get_builtin_types ();
133 :
134 : void push_new_name_rib (Rib *r);
135 : void push_new_type_rib (Rib *r);
136 : void push_new_label_rib (Rib *r);
137 : void push_new_macro_rib (Rib *r);
138 :
139 : bool find_name_rib (NodeId id, Rib **rib);
140 : bool find_type_rib (NodeId id, Rib **rib);
141 : bool find_label_rib (NodeId id, Rib **rib);
142 : bool find_macro_rib (NodeId id, Rib **rib);
143 :
144 : void insert_resolved_name (NodeId refId, NodeId defId);
145 : bool lookup_resolved_name (NodeId refId, NodeId *defId);
146 :
147 : void insert_resolved_type (NodeId refId, NodeId defId);
148 : bool lookup_resolved_type (NodeId refId, NodeId *defId);
149 :
150 : void insert_resolved_label (NodeId refId, NodeId defId);
151 : bool lookup_resolved_label (NodeId refId, NodeId *defId);
152 :
153 : void insert_resolved_macro (NodeId refId, NodeId defId);
154 : bool lookup_resolved_macro (NodeId refId, NodeId *defId);
155 :
156 : void insert_resolved_misc (NodeId refId, NodeId defId);
157 : bool lookup_resolved_misc (NodeId refId, NodeId *defId);
158 :
159 : // proxy for scoping
160 0 : Scope &get_name_scope () { return name_scope; }
161 0 : Scope &get_type_scope () { return type_scope; }
162 0 : Scope &get_label_scope () { return label_scope; }
163 0 : Scope &get_macro_scope () { return macro_scope; }
164 :
165 : NodeId get_global_type_node_id () { return global_type_node_id; }
166 :
167 0 : void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; }
168 : NodeId get_unit_type_node_id () { return unit_ty_node_id; }
169 :
170 0 : void set_never_type_node_id (NodeId id) { never_ty_node_id = id; }
171 : NodeId get_never_type_node_id () { return never_ty_node_id; }
172 :
173 : void push_new_module_scope (NodeId module_id)
174 : {
175 : current_module_stack.push_back (module_id);
176 : }
177 :
178 : void pop_module_scope ()
179 : {
180 : rust_assert (!current_module_stack.empty ());
181 : current_module_stack.pop_back ();
182 : }
183 :
184 : NodeId peek_current_module_scope () const
185 : {
186 : rust_assert (!current_module_stack.empty ());
187 : return current_module_stack.back ();
188 : }
189 :
190 : NodeId peek_crate_module_scope () const
191 : {
192 : rust_assert (!current_module_stack.empty ());
193 : return current_module_stack.front ();
194 : }
195 :
196 : NodeId peek_parent_module_scope () const
197 : {
198 : rust_assert (current_module_stack.size () > 1);
199 : return current_module_stack.at (current_module_stack.size () - 2);
200 : }
201 :
202 : void push_closure_context (NodeId closure_expr_id);
203 : void pop_closure_context ();
204 : void insert_captured_item (NodeId id);
205 : const std::set<NodeId> &get_captures (NodeId id) const;
206 :
207 : std::string as_debug_string () const
208 : {
209 : std::stringstream ss;
210 :
211 : ss << "Names:\n";
212 : for (auto &n : name_ribs)
213 : {
214 : ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
215 : << "\n";
216 : }
217 : ss << "Types:\n";
218 : for (auto &n : type_ribs)
219 : {
220 : ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
221 : << "\n";
222 : }
223 : ss << "Macros:\n";
224 :
225 : for (auto &n : macro_ribs)
226 : {
227 : ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
228 : << "\n";
229 : }
230 :
231 : ss << "Labels:\n";
232 :
233 : for (auto &n : label_ribs)
234 : {
235 : ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
236 : << "\n";
237 : }
238 :
239 : return ss.str ();
240 : }
241 :
242 : protected:
243 : bool decl_needs_capture (NodeId decl_rib_node_id, NodeId closure_rib_node_id,
244 : const Scope &scope);
245 :
246 : private:
247 : Resolver ();
248 :
249 : void generate_builtins ();
250 : NodeId setup_builtin (const std::string &name, TyTy::BaseType *tyty);
251 :
252 : Analysis::Mappings &mappings;
253 : TypeCheckContext *tyctx;
254 :
255 : std::vector<AST::Type *> builtins;
256 :
257 : Scope name_scope;
258 : Scope type_scope;
259 : Scope label_scope;
260 : Scope macro_scope;
261 :
262 : NodeId global_type_node_id;
263 : NodeId unit_ty_node_id;
264 : NodeId never_ty_node_id;
265 :
266 : // map a AST Node to a Rib
267 : std::map<NodeId, Rib *> name_ribs;
268 : std::map<NodeId, Rib *> type_ribs;
269 : std::map<NodeId, Rib *> label_ribs;
270 : std::map<NodeId, Rib *> macro_ribs;
271 :
272 : // Rust uses DefIds to namespace these under a crate_num
273 : // but then it uses the def_collector to assign local_defids
274 : // to each ast node as well. not sure if this is going to fit
275 : // with gcc very well to compile a full crate in one go but we will
276 : // see.
277 :
278 : // these are of the form ref->Def-NodeId
279 : // we need two namespaces one for names and ones for types
280 : std::map<NodeId, NodeId> resolved_names;
281 : std::map<NodeId, NodeId> resolved_types;
282 : std::map<NodeId, NodeId> resolved_labels;
283 : std::map<NodeId, NodeId> resolved_macros;
284 :
285 : // misc
286 : std::map<NodeId, NodeId> misc_resolved_items;
287 :
288 : // keep track of the current module scope ids
289 : std::vector<NodeId> current_module_stack;
290 :
291 : // captured variables mappings
292 : std::vector<NodeId> closure_context;
293 : std::map<NodeId, std::set<NodeId>> closures_capture_mappings;
294 : };
295 :
296 : } // namespace Resolver
297 : } // namespace Rust
298 :
299 : #endif // RUST_NAME_RESOLVER_H
|