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-name-resolution-context.h"
20 : : #include "optional.h"
21 : : #include "rust-mapping-common.h"
22 : :
23 : : namespace Rust {
24 : : namespace Resolver2_0 {
25 : :
26 : 4105 : BindingLayer::BindingLayer (BindingSource source) : source (source)
27 : : {
28 : 4105 : push (Binding::Kind::Product);
29 : 4105 : }
30 : :
31 : : bool
32 : 5158 : BindingLayer::bind_test (Identifier ident, Binding::Kind kind)
33 : : {
34 : 10370 : for (auto &bind : bindings)
35 : : {
36 : 5229 : if (bind.set.find (ident) != bind.set.cend () && bind.kind == kind)
37 : : {
38 : 5158 : return true;
39 : : }
40 : : }
41 : : return false;
42 : : }
43 : :
44 : : void
45 : 4141 : BindingLayer::push (Binding::Kind kind)
46 : : {
47 : 4141 : bindings.push_back (Binding (kind));
48 : 4141 : }
49 : :
50 : : bool
51 : 2583 : BindingLayer::is_and_bound (Identifier ident)
52 : : {
53 : 2583 : return bind_test (ident, Binding::Kind::Product);
54 : : }
55 : :
56 : : bool
57 : 2575 : BindingLayer::is_or_bound (Identifier ident)
58 : : {
59 : 2575 : return bind_test (ident, Binding::Kind::Or);
60 : : }
61 : :
62 : : void
63 : 2575 : BindingLayer::insert_ident (Identifier ident)
64 : : {
65 : 2575 : bindings.back ().set.insert (ident);
66 : 2575 : }
67 : :
68 : : void
69 : 36 : BindingLayer::merge ()
70 : : {
71 : 36 : auto last_binding = bindings.back ();
72 : 36 : bindings.pop_back ();
73 : 67 : for (auto &value : last_binding.set)
74 : : {
75 : 31 : bindings.back ().set.insert (value);
76 : : }
77 : 36 : }
78 : :
79 : : BindingSource
80 : 8 : BindingLayer::get_source () const
81 : : {
82 : 8 : return source;
83 : : }
84 : :
85 : 4939 : NameResolutionContext::NameResolutionContext ()
86 : 4939 : : mappings (Analysis::Mappings::get ())
87 : 4939 : {}
88 : :
89 : : tl::expected<NodeId, DuplicateNameError>
90 : 16964 : NameResolutionContext::insert (Identifier name, NodeId id, Namespace ns)
91 : : {
92 : 16964 : switch (ns)
93 : : {
94 : 7888 : case Namespace::Values:
95 : 7888 : return values.insert (name, id);
96 : 9013 : case Namespace::Types:
97 : 9013 : return types.insert (name, id);
98 : 63 : case Namespace::Macros:
99 : 63 : return macros.insert (name, id);
100 : 0 : case Namespace::Labels:
101 : 0 : default:
102 : : // return labels.insert (name, id);
103 : 0 : rust_unreachable ();
104 : : }
105 : : }
106 : :
107 : : tl::expected<NodeId, DuplicateNameError>
108 : 435 : NameResolutionContext::insert_variant (Identifier name, NodeId id)
109 : : {
110 : 435 : return types.insert_variant (name, id);
111 : : }
112 : :
113 : : tl::expected<NodeId, DuplicateNameError>
114 : 0 : NameResolutionContext::insert_shadowable (Identifier name, NodeId id,
115 : : Namespace ns)
116 : : {
117 : 0 : switch (ns)
118 : : {
119 : 0 : case Namespace::Values:
120 : 0 : return values.insert_shadowable (name, id);
121 : 0 : case Namespace::Types:
122 : 0 : return types.insert_shadowable (name, id);
123 : 0 : case Namespace::Macros:
124 : 0 : return macros.insert_shadowable (name, id);
125 : 0 : case Namespace::Labels:
126 : 0 : default:
127 : : // return labels.insert (name, id);
128 : 0 : rust_unreachable ();
129 : : }
130 : : }
131 : :
132 : : tl::expected<NodeId, DuplicateNameError>
133 : 24 : NameResolutionContext::insert_globbed (Identifier name, NodeId id, Namespace ns)
134 : : {
135 : 24 : switch (ns)
136 : : {
137 : 20 : case Namespace::Values:
138 : 20 : return values.insert_globbed (name, id);
139 : 4 : case Namespace::Types:
140 : 4 : return types.insert_globbed (name, id);
141 : 0 : case Namespace::Macros:
142 : 0 : return macros.insert_globbed (name, id);
143 : 0 : case Namespace::Labels:
144 : 0 : default:
145 : : // return labels.insert (name, id);
146 : 0 : rust_unreachable ();
147 : : }
148 : : }
149 : :
150 : : void
151 : 21641 : NameResolutionContext::map_usage (Usage usage, Definition definition)
152 : : {
153 : 21641 : auto inserted = resolved_nodes.emplace (usage, definition).second;
154 : :
155 : : // is that valid?
156 : 21641 : rust_assert (inserted);
157 : 21639 : }
158 : :
159 : : tl::optional<NodeId>
160 : 131332 : NameResolutionContext::lookup (NodeId usage) const
161 : : {
162 : 131332 : auto it = resolved_nodes.find (Usage (usage));
163 : :
164 : 131332 : if (it == resolved_nodes.end ())
165 : 633 : return tl::nullopt;
166 : :
167 : 130699 : return it->second.id;
168 : : }
169 : :
170 : : void
171 : 56194 : NameResolutionContext::scoped (Rib::Kind rib_kind, NodeId id,
172 : : std::function<void (void)> lambda,
173 : : tl::optional<Identifier> path)
174 : : {
175 : : // NOTE: You must be at the root node when pushing the prelude rib.
176 : 56194 : values.push (rib_kind, id, path);
177 : 56194 : types.push (rib_kind, id, path);
178 : 56194 : macros.push (rib_kind, id, path);
179 : : // labels.push (rib, id);
180 : :
181 : 56194 : lambda ();
182 : :
183 : 56190 : values.pop ();
184 : 56190 : types.pop ();
185 : 56190 : macros.pop ();
186 : : // labels.pop (rib);
187 : 56190 : }
188 : :
189 : : void
190 : 0 : NameResolutionContext::scoped (Rib::Kind rib_kind, Namespace ns,
191 : : NodeId scope_id,
192 : : std::function<void (void)> lambda,
193 : : tl::optional<Identifier> path)
194 : : {
195 : : // This could work... I'm not sure why you would want to do this though.
196 : 0 : rust_assert (rib_kind != Rib::Kind::Prelude);
197 : :
198 : 0 : switch (ns)
199 : : {
200 : 0 : case Namespace::Values:
201 : 0 : values.push (rib_kind, scope_id, path);
202 : 0 : break;
203 : 0 : case Namespace::Types:
204 : 0 : types.push (rib_kind, scope_id, path);
205 : 0 : break;
206 : 0 : case Namespace::Labels:
207 : 0 : case Namespace::Macros:
208 : 0 : gcc_unreachable ();
209 : : }
210 : :
211 : 0 : lambda ();
212 : :
213 : 0 : switch (ns)
214 : : {
215 : 0 : case Namespace::Values:
216 : 0 : values.pop ();
217 : 0 : break;
218 : 0 : case Namespace::Types:
219 : 0 : types.pop ();
220 : 0 : break;
221 : : case Namespace::Labels:
222 : : case Namespace::Macros:
223 : : gcc_unreachable ();
224 : : }
225 : 0 : }
226 : :
227 : : } // namespace Resolver2_0
228 : : } // namespace Rust
|