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_HIR_MAP_H
20 : #define RUST_HIR_MAP_H
21 :
22 : #include "optional.h"
23 : #include "rust-system.h"
24 : #include "rust-location.h"
25 : #include "rust-mapping-common.h"
26 : #include "rust-canonical-path.h"
27 : #include "rust-ast-full-decls.h"
28 : #include "rust-hir-full-decls.h"
29 : #include "rust-lang-item.h"
30 : #include "rust-privacy-common.h"
31 : #include "libproc_macro_internal/proc_macro.h"
32 : #include "rust-proc-macro.h"
33 : #include "optional.h"
34 :
35 : namespace Rust {
36 : namespace Analysis {
37 :
38 : class NodeMapping
39 : {
40 : public:
41 605157 : NodeMapping (CrateNum crateNum, NodeId nodeId, HirId hirId,
42 : LocalDefId localDefId)
43 559229 : : crateNum (crateNum), nodeId (nodeId), hirId (hirId),
44 559229 : localDefId (localDefId)
45 : {}
46 :
47 : static NodeMapping get_error ();
48 :
49 : CrateNum get_crate_num () const;
50 : NodeId get_nodeid () const;
51 : HirId get_hirid () const;
52 : LocalDefId get_local_defid () const;
53 : DefId get_defid () const;
54 :
55 : static DefId get_defid (CrateNum crate_num, LocalDefId local_defid);
56 :
57 : std::string as_string () const;
58 :
59 : bool is_equal (const NodeMapping &other) const
60 : {
61 : return get_crate_num () == other.get_crate_num ()
62 : && get_nodeid () == other.get_nodeid ()
63 : && get_hirid () == other.get_hirid ()
64 : && get_local_defid () == other.get_local_defid ();
65 : }
66 :
67 : private:
68 : CrateNum crateNum;
69 : NodeId nodeId;
70 : HirId hirId;
71 : LocalDefId localDefId;
72 : };
73 :
74 : class Mappings
75 : {
76 : public:
77 : static Mappings &get ();
78 : ~Mappings ();
79 :
80 : CrateNum get_next_crate_num (const std::string &name);
81 : void set_current_crate (CrateNum crateNum);
82 : CrateNum get_current_crate () const;
83 : tl::optional<const std::string &> get_crate_name (CrateNum crate_num) const;
84 :
85 : tl::optional<CrateNum> lookup_crate_num (NodeId node_id) const;
86 : void set_crate_name (CrateNum crate_num, const std::string &name);
87 : const std::string &get_current_crate_name () const;
88 : tl::optional<CrateNum>
89 : lookup_crate_name (const std::string &crate_name) const;
90 : tl::optional<NodeId> crate_num_to_nodeid (const CrateNum &crate_num) const;
91 : bool node_is_crate (NodeId node_id) const;
92 :
93 : NodeId get_next_node_id ();
94 273780 : HirId get_next_hir_id () { return get_next_hir_id (get_current_crate ()); }
95 : HirId get_next_hir_id (CrateNum crateNum);
96 : LocalDefId get_next_localdef_id ()
97 : {
98 : return get_next_localdef_id (get_current_crate ());
99 : }
100 : LocalDefId get_next_localdef_id (CrateNum crateNum);
101 :
102 : AST::Crate &get_ast_crate (CrateNum crateNum);
103 : AST::Crate &get_ast_crate_by_node_id (NodeId id);
104 : AST::Crate &insert_ast_crate (std::unique_ptr<AST::Crate> &&crate,
105 : CrateNum crate_num);
106 : HIR::Crate &insert_hir_crate (std::unique_ptr<HIR::Crate> &&crate);
107 : HIR::Crate &get_hir_crate (CrateNum crateNum);
108 : bool is_local_hirid_crate (HirId crateNum);
109 :
110 : void insert_defid_mapping (DefId id, HIR::Item *item);
111 : tl::optional<HIR::Item *> lookup_defid (DefId id);
112 : void insert_defid_mapping (DefId id, HIR::TraitItem *item);
113 : tl::optional<HIR::TraitItem *> lookup_trait_item_defid (DefId id);
114 :
115 : void insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
116 : HIR::Item *item);
117 : tl::optional<HIR::Item *> lookup_local_defid (CrateNum crateNum,
118 : LocalDefId id);
119 :
120 : void insert_hir_item (HIR::Item *item);
121 : tl::optional<HIR::Item *> lookup_hir_item (HirId id);
122 :
123 : void insert_hir_enumitem (HIR::Enum *parent, HIR::EnumItem *item);
124 : std::pair<HIR::Enum *, HIR::EnumItem *> lookup_hir_enumitem (HirId id);
125 :
126 : void insert_hir_trait_item (HIR::TraitItem *item);
127 : tl::optional<HIR::TraitItem *> lookup_hir_trait_item (HirId id);
128 :
129 : void insert_hir_extern_block (HIR::ExternBlock *block);
130 : tl::optional<HIR::ExternBlock *> lookup_hir_extern_block (HirId id);
131 :
132 : void insert_hir_extern_item (HIR::ExternalItem *item, HirId parent_block);
133 :
134 : // std::pair<hir_extern_item, parent hirid>
135 : tl::optional<std::pair<HIR::ExternalItem *, HirId>>
136 : lookup_hir_extern_item (HirId id);
137 :
138 : void insert_hir_impl_block (HIR::ImplBlock *item);
139 : tl::optional<HIR::ImplBlock *> lookup_hir_impl_block (HirId id);
140 : tl::optional<HIR::ImplBlock *> lookup_impl_block_type (HirId id);
141 :
142 : void insert_module (HIR::Module *module);
143 : tl::optional<HIR::Module *> lookup_module (HirId id);
144 :
145 : void insert_hir_implitem (HirId parent_impl_id, HIR::ImplItem *item);
146 : // Optional<ImpItem, ParentImpl Hir id>
147 : tl::optional<std::pair<HIR::ImplItem *, HirId>>
148 : lookup_hir_implitem (HirId id);
149 :
150 : void insert_hir_expr (HIR::Expr *expr);
151 : tl::optional<HIR::Expr *> lookup_hir_expr (HirId id);
152 :
153 : void insert_hir_path_expr_seg (HIR::PathExprSegment *expr);
154 : tl::optional<HIR::PathExprSegment *> lookup_hir_path_expr_seg (HirId id);
155 :
156 : void insert_hir_generic_param (HIR::GenericParam *expr);
157 : tl::optional<HIR::GenericParam *> lookup_hir_generic_param (HirId id);
158 :
159 : void insert_hir_type (HIR::Type *type);
160 : tl::optional<HIR::Type *> lookup_hir_type (HirId id);
161 :
162 : void insert_hir_stmt (HIR::Stmt *stmt);
163 : tl::optional<HIR::Stmt *> lookup_hir_stmt (HirId id);
164 :
165 : void insert_hir_param (HIR::FunctionParam *type);
166 : tl::optional<HIR::FunctionParam *> lookup_hir_param (HirId id);
167 :
168 : void insert_hir_self_param (HIR::SelfParam *type);
169 : tl::optional<HIR::SelfParam *> lookup_hir_self_param (HirId id);
170 :
171 : void insert_hir_struct_field (HIR::StructExprField *type);
172 : tl::optional<HIR::StructExprField *> lookup_hir_struct_field (HirId id);
173 :
174 : void insert_hir_pattern (HIR::Pattern *pattern);
175 : tl::optional<HIR::Pattern *> lookup_hir_pattern (HirId id);
176 :
177 : void walk_local_defids_for_crate (CrateNum crateNum,
178 : std::function<bool (HIR::Item *)> cb);
179 :
180 : void insert_node_to_hir (NodeId id, HirId ref);
181 : tl::optional<HirId> lookup_node_to_hir (NodeId id);
182 : tl::optional<NodeId> lookup_hir_to_node (HirId id);
183 :
184 : void insert_location (HirId id, location_t locus);
185 : location_t lookup_location (HirId id);
186 :
187 : tl::optional<HIR::Stmt *> resolve_nodeid_to_stmt (NodeId id);
188 :
189 : std::set<HirId> &get_hirids_within_crate (CrateNum crate)
190 : {
191 : return hirNodesWithinCrate[crate];
192 : }
193 :
194 8086 : void insert_impl_item_mapping (HirId impl_item_id, HIR::ImplBlock *impl)
195 : {
196 8086 : rust_assert (hirImplItemsToImplMappings.find (impl_item_id)
197 : == hirImplItemsToImplMappings.end ());
198 8086 : hirImplItemsToImplMappings[impl_item_id] = impl;
199 8086 : }
200 :
201 326651 : HIR::ImplBlock *lookup_associated_impl (HirId impl_item_id)
202 : {
203 326651 : auto lookup = hirImplItemsToImplMappings.find (impl_item_id);
204 326651 : rust_assert (lookup != hirImplItemsToImplMappings.end ());
205 326651 : return lookup->second;
206 : }
207 :
208 : void iterate_impl_items (
209 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
210 :
211 : void iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb);
212 :
213 : void iterate_trait_items (
214 : std::function<bool (HIR::TraitItem *item, HIR::Trait *)> cb);
215 :
216 3959 : bool is_impl_item (HirId id) { return lookup_hir_implitem (id).has_value (); }
217 :
218 3321 : void insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait)
219 : {
220 3321 : rust_assert (hirTraitItemsToTraitMappings.find (trait_item_id)
221 : == hirTraitItemsToTraitMappings.end ());
222 3321 : hirTraitItemsToTraitMappings[trait_item_id] = trait;
223 3321 : }
224 :
225 1157 : HIR::Trait *lookup_trait_item_mapping (HirId trait_item_id)
226 : {
227 1157 : auto lookup = hirTraitItemsToTraitMappings.find (trait_item_id);
228 1157 : rust_assert (lookup != hirTraitItemsToTraitMappings.end ());
229 1157 : return lookup->second;
230 : }
231 :
232 0 : void insert_canonical_path (NodeId id, const Resolver::CanonicalPath path)
233 : {
234 0 : if (auto p = lookup_canonical_path (id))
235 : {
236 : // if we have already stored a canonical path this is ok so long as
237 : // this new path is equal or is smaller that the existing one but in
238 : // that case we ignore it.
239 0 : if (p->is_equal (path))
240 0 : return;
241 : else
242 : {
243 0 : rust_assert (p->size () >= path.size ());
244 : return;
245 : }
246 : }
247 :
248 0 : paths.emplace (id, std::move (path));
249 : }
250 :
251 : tl::optional<const Resolver::CanonicalPath &>
252 0 : lookup_canonical_path (NodeId id)
253 : {
254 0 : auto it = paths.find (id);
255 0 : if (it == paths.end ())
256 0 : return tl::nullopt;
257 :
258 0 : return it->second;
259 : }
260 :
261 : void insert_lang_item (LangItem::Kind item_type, DefId id);
262 : tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type);
263 :
264 : void insert_lang_item_node (LangItem::Kind item_type, NodeId node_id);
265 : tl::optional<NodeId &> lookup_lang_item_node (LangItem::Kind item_type);
266 : NodeId get_lang_item_node (LangItem::Kind item_type);
267 :
268 : // This will fatal_error when this lang item does not exist
269 : DefId get_lang_item (LangItem::Kind item_type, location_t locus);
270 :
271 : void insert_macro_def (AST::MacroRulesDefinition *macro);
272 :
273 : tl::optional<AST::MacroRulesDefinition *> lookup_macro_def (NodeId id);
274 : tl::optional<CrateNum> lookup_macro_def_crate (NodeId id);
275 :
276 : void insert_macro_invocation (AST::MacroInvocation &invoc,
277 : AST::MacroRulesDefinition *def);
278 : tl::optional<AST::MacroRulesDefinition *>
279 : lookup_macro_invocation (AST::MacroInvocation &invoc);
280 :
281 : void insert_exported_macro (AST::MacroRulesDefinition &def);
282 : std::vector<AST::MacroRulesDefinition> get_exported_macros ();
283 :
284 : void insert_derive_proc_macros (CrateNum num,
285 : std::vector<CustomDeriveProcMacro> macros);
286 : void insert_bang_proc_macros (CrateNum num,
287 : std::vector<BangProcMacro> macros);
288 : void insert_attribute_proc_macros (CrateNum num,
289 : std::vector<AttributeProcMacro> macros);
290 :
291 : tl::optional<std::vector<CustomDeriveProcMacro> &>
292 : lookup_derive_proc_macros (CrateNum num);
293 : tl::optional<std::vector<BangProcMacro> &>
294 : lookup_bang_proc_macros (CrateNum num);
295 : tl::optional<std::vector<AttributeProcMacro> &>
296 : lookup_attribute_proc_macros (CrateNum num);
297 :
298 : void insert_derive_proc_macro_def (CustomDeriveProcMacro macro);
299 : void insert_bang_proc_macro_def (BangProcMacro macro);
300 : void insert_attribute_proc_macro_def (AttributeProcMacro macro);
301 :
302 : tl::optional<CustomDeriveProcMacro &>
303 : lookup_derive_proc_macro_def (NodeId id);
304 : tl::optional<BangProcMacro &> lookup_bang_proc_macro_def (NodeId id);
305 : tl::optional<AttributeProcMacro &>
306 : lookup_attribute_proc_macro_def (NodeId id);
307 :
308 : tl::optional<CustomDeriveProcMacro &>
309 : lookup_derive_proc_macro_invocation (AST::SimplePath &invoc);
310 : tl::optional<BangProcMacro &>
311 : lookup_bang_proc_macro_invocation (AST::MacroInvocation &invoc_id);
312 : tl::optional<AttributeProcMacro &>
313 : lookup_attribute_proc_macro_invocation (AST::SimplePath &invoc);
314 : void insert_derive_proc_macro_invocation (AST::SimplePath &invoc,
315 : CustomDeriveProcMacro def);
316 : void insert_bang_proc_macro_invocation (AST::MacroInvocation &invoc,
317 : BangProcMacro def);
318 : void insert_attribute_proc_macro_invocation (AST::SimplePath &invoc,
319 : AttributeProcMacro def);
320 :
321 : void insert_visibility (NodeId id, Privacy::ModuleVisibility visibility);
322 : tl::optional<Privacy::ModuleVisibility &> lookup_visibility (NodeId id);
323 :
324 : void insert_glob_container (NodeId, AST::GlobContainer *);
325 : tl::optional<AST::GlobContainer *> lookup_glob_container (NodeId id);
326 : void insert_module_child (NodeId module, NodeId child);
327 : tl::optional<std::vector<NodeId> &> lookup_module_children (NodeId module);
328 :
329 : void insert_module_child_item (NodeId module, Resolver::CanonicalPath item);
330 : tl::optional<std::vector<Resolver::CanonicalPath> &>
331 : lookup_module_chidren_items (NodeId module);
332 : tl::optional<Resolver::CanonicalPath &>
333 : lookup_module_child (NodeId module, const std::string &item_name);
334 :
335 : void insert_child_item_to_parent_module_mapping (NodeId child_item,
336 : NodeId parent_module);
337 : tl::optional<NodeId> lookup_parent_module (NodeId child_item);
338 : bool node_is_module (NodeId query);
339 :
340 : void insert_ast_item (AST::Item *item);
341 : tl::optional<AST::Item *> lookup_ast_item (NodeId id);
342 :
343 : HIR::ImplBlock *lookup_builtin_marker ();
344 :
345 : tl::optional<HIR::TraitItem *>
346 : lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);
347 :
348 : void insert_auto_trait (HIR::Trait *trait);
349 : std::vector<HIR::Trait *> &get_auto_traits ();
350 : void add_capture (NodeId closure, NodeId definition);
351 : tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure);
352 :
353 : void add_derived_node (NodeId node_id);
354 : bool is_derived_node (NodeId node_id);
355 :
356 : private:
357 : Mappings ();
358 :
359 : CrateNum crateNumItr;
360 : CrateNum currentCrateNum;
361 : HirId hirIdIter;
362 : NodeId nodeIdIter;
363 : std::map<CrateNum, LocalDefId> localIdIter;
364 : HIR::ImplBlock *builtinMarker;
365 :
366 : AST::Crate *get_ast_crate_by_node_id_raw (NodeId id);
367 :
368 : std::map<NodeId, CrateNum> crate_node_to_crate_num;
369 : std::map<CrateNum, AST::Crate *> ast_crate_mappings;
370 : std::map<CrateNum, HIR::Crate *> hir_crate_mappings;
371 : std::map<DefId, HIR::Item *> defIdMappings;
372 : std::map<DefId, HIR::TraitItem *> defIdTraitItemMappings;
373 : std::map<CrateNum, std::map<LocalDefId, HIR::Item *>> localDefIdMappings;
374 :
375 : std::map<HirId, HIR::Module *> hirModuleMappings;
376 : std::map<HirId, HIR::Item *> hirItemMappings;
377 : std::map<HirId, std::pair<HIR::Enum *, HIR::EnumItem *>> hirEnumItemMappings;
378 : std::map<HirId, HIR::Type *> hirTypeMappings;
379 : std::map<HirId, HIR::Expr *> hirExprMappings;
380 : std::map<HirId, HIR::Stmt *> hirStmtMappings;
381 : std::map<HirId, HIR::FunctionParam *> hirParamMappings;
382 : std::map<HirId, HIR::StructExprField *> hirStructFieldMappings;
383 : std::map<HirId, std::pair<HirId, HIR::ImplItem *>> hirImplItemMappings;
384 : std::map<HirId, HIR::SelfParam *> hirSelfParamMappings;
385 : std::map<HirId, HIR::ImplBlock *> hirImplItemsToImplMappings;
386 : std::map<HirId, HIR::ImplBlock *> hirImplBlockMappings;
387 : std::map<HirId, HIR::ImplBlock *> hirImplBlockTypeMappings;
388 : std::map<HirId, HIR::TraitItem *> hirTraitItemMappings;
389 : std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings;
390 : std::map<HirId, std::pair<HIR::ExternalItem *, HirId>> hirExternItemMappings;
391 : std::map<HirId, HIR::PathExprSegment *> hirPathSegMappings;
392 : std::map<HirId, HIR::GenericParam *> hirGenericParamMappings;
393 : std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings;
394 : std::map<HirId, HIR::Pattern *> hirPatternMappings;
395 :
396 : // FIXME: Add documentation
397 : std::vector<HIR::Trait *> auto_traits;
398 :
399 : // We need to have two maps here, as lang-items need to be used for both AST
400 : // passes and HIR passes. Thus those two maps are created at different times.
401 : std::map<LangItem::Kind, DefId> lang_item_mappings;
402 : std::map<LangItem::Kind, NodeId> lang_item_nodes;
403 :
404 : std::map<NodeId, Resolver::CanonicalPath> paths;
405 : std::map<NodeId, location_t> locations;
406 : std::map<NodeId, HirId> nodeIdToHirMappings;
407 : std::map<HirId, NodeId> hirIdToNodeMappings;
408 :
409 : // all hirid nodes
410 : std::map<CrateNum, std::set<HirId>> hirNodesWithinCrate;
411 :
412 : // MBE macros
413 : std::map<NodeId, std::pair<AST::MacroRulesDefinition *, CrateNum>>
414 : macroMappings;
415 : std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations;
416 : std::vector<AST::MacroRulesDefinition> exportedMacros;
417 :
418 : // Procedural macros
419 : std::map<CrateNum, std::vector<CustomDeriveProcMacro>>
420 : procmacrosDeriveMappings;
421 : std::map<CrateNum, std::vector<BangProcMacro>> procmacrosBangMappings;
422 : std::map<CrateNum, std::vector<AttributeProcMacro>>
423 : procmacrosAttributeMappings;
424 :
425 : std::map<NodeId, CustomDeriveProcMacro> procmacroDeriveMappings;
426 : std::map<NodeId, BangProcMacro> procmacroBangMappings;
427 : std::map<NodeId, AttributeProcMacro> procmacroAttributeMappings;
428 : std::map<NodeId, CustomDeriveProcMacro> procmacroDeriveInvocations;
429 : std::map<NodeId, BangProcMacro> procmacroBangInvocations;
430 : std::map<NodeId, AttributeProcMacro> procmacroAttributeInvocations;
431 :
432 : // crate names
433 : std::map<CrateNum, std::string> crate_names;
434 :
435 : // Low level visibility map for each DefId
436 : std::map<NodeId, Privacy::ModuleVisibility> visibility_map;
437 :
438 : // Module tree maps
439 :
440 : // Maps each module's node id to a list of its children
441 : std::map<NodeId, std::vector<NodeId>> module_child_map;
442 : std::map<NodeId, std::vector<Resolver::CanonicalPath>> module_child_items;
443 : std::map<NodeId, NodeId> child_to_parent_module_map;
444 : std::map<NodeId, AST::GlobContainer *> glob_containers;
445 :
446 : // AST mappings
447 : std::map<NodeId, AST::Item *> ast_item_mappings;
448 :
449 : // Closure AST NodeId -> vector of Definition node ids
450 : std::unordered_map<NodeId, std::vector<NodeId>> captures;
451 :
452 : std::set<NodeId> derived_nodes;
453 : };
454 :
455 : } // namespace Analysis
456 : } // namespace Rust
457 :
458 : #endif // RUST_HIR_MAP_H
|