1 // Copyright (C) 2020-2023 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_AST_RESOLVE_IMPLITEM_H
20 #define RUST_AST_RESOLVE_IMPLITEM_H
21
22 #include "rust-ast-resolve-base.h"
23 #include "rust-ast-resolve-type.h"
24 #include "rust-ast-full.h"
25
26 namespace Rust {
27 namespace Resolver {
28
29 class ResolveToplevelImplItem : public ResolverBase
30 {
31 using Rust::Resolver::ResolverBase::visit;
32
33 public:
34 static void go (AST::InherentImplItem *item, const CanonicalPath &prefix)
35 {
36 if (item->is_marked_for_strip ())
37 return;
38
39 ResolveToplevelImplItem resolver (prefix);
40 item->accept_vis (resolver);
41 }
42
43 static void go (AST::TraitImplItem *item, const CanonicalPath &prefix)
44 {
45 if (item->is_marked_for_strip ())
46 return;
47
48 ResolveToplevelImplItem resolver (prefix);
49 item->accept_vis (resolver);
50 }
51
52 void visit (AST::TypeAlias &type) override
53 {
54 auto decl
55 = CanonicalPath::new_seg (type.get_node_id (), type.get_new_type_name ());
56 auto path = prefix.append (decl);
57
58 resolver->get_type_scope ().insert (
59 path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
60 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
61 RichLocation r (type.get_locus ());
62 r.add_range (locus);
63 rust_error_at (r, "redefined multiple times");
64 });
65 }
66
67 void visit (AST::ConstantItem &constant) override
68 {
69 auto decl = CanonicalPath::new_seg (constant.get_node_id (),
70 constant.get_identifier ());
71 auto path = prefix.append (decl);
72
73 resolver->get_name_scope ().insert (
74 path, constant.get_node_id (), constant.get_locus (), false,
75 Rib::ItemType::Const,
76 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
77 RichLocation r (constant.get_locus ());
78 r.add_range (locus);
79 rust_error_at (r, "redefined multiple times");
80 });
81 }
82
83 void visit (AST::Function &function) override
84 {
85 auto decl = CanonicalPath::new_seg (function.get_node_id (),
86 function.get_function_name ());
87 auto path = prefix.append (decl);
88
89 resolver->get_name_scope ().insert (
90 path, function.get_node_id (), function.get_locus (), false,
91 Rib::ItemType::Function,
92 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
93 RichLocation r (function.get_locus ());
94 r.add_range (locus);
95 rust_error_at (r, "redefined multiple times");
96 });
97 }
98
99 void visit (AST::Method &method) override
100 {
101 auto decl = CanonicalPath::new_seg (method.get_node_id (),
102 method.get_method_name ());
103 auto path = prefix.append (decl);
104
105 resolver->get_name_scope ().insert (
106 path, method.get_node_id (), method.get_locus (), false,
107 Rib::ItemType::Function,
108 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
109 RichLocation r (method.get_locus ());
110 r.add_range (locus);
111 rust_error_at (r, "redefined multiple times");
112 });
113 }
114
115 private:
116 ResolveToplevelImplItem (const CanonicalPath &prefix)
117 : ResolverBase (), prefix (prefix)
118 {
119 rust_assert (!prefix.is_empty ());
120 }
121
122 const CanonicalPath &prefix;
123 };
124
125 class ResolveTopLevelTraitItems : public ResolverBase
126 {
127 using Rust::Resolver::ResolverBase::visit;
128
129 public:
130 static void go (AST::TraitItem *item, const CanonicalPath &prefix,
131 const CanonicalPath &canonical_prefix)
132 {
133 ResolveTopLevelTraitItems resolver (prefix, canonical_prefix);
134 item->accept_vis (resolver);
135 };
136
137 void visit (AST::TraitItemFunc &function) override
138 {
139 auto decl = CanonicalPath::new_seg (
140 function.get_node_id (),
141 function.get_trait_function_decl ().get_identifier ());
142 auto path = prefix.append (decl);
143 auto cpath = canonical_prefix.append (decl);
144
145 resolver->get_name_scope ().insert (
146 path, function.get_node_id (), function.get_locus (), false,
147 Rib::ItemType::Function,
148 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
149 RichLocation r (function.get_locus ());
150 r.add_range (locus);
151 rust_error_at (r, "redefined multiple times");
152 });
153
154 mappings->insert_canonical_path (function.get_node_id (), cpath);
155 }
156
157 void visit (AST::TraitItemMethod &method) override
158 {
159 auto decl = CanonicalPath::new_seg (
160 method.get_node_id (), method.get_trait_method_decl ().get_identifier ());
161 auto path = prefix.append (decl);
162 auto cpath = canonical_prefix.append (decl);
163
164 resolver->get_name_scope ().insert (
165 path, method.get_node_id (), method.get_locus (), false,
166 Rib::ItemType::Function,
167 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
168 RichLocation r (method.get_locus ());
169 r.add_range (locus);
170 rust_error_at (r, "redefined multiple times");
171 });
172
173 mappings->insert_canonical_path (method.get_node_id (), cpath);
174 }
175
176 void visit (AST::TraitItemConst &constant) override
177 {
178 auto decl = CanonicalPath::new_seg (constant.get_node_id (),
179 constant.get_identifier ());
180 auto path = prefix.append (decl);
181 auto cpath = canonical_prefix.append (decl);
182
183 resolver->get_name_scope ().insert (
184 path, constant.get_node_id (), constant.get_locus (), false,
185 Rib::ItemType::Const,
186 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
187 RichLocation r (constant.get_locus ());
188 r.add_range (locus);
189 rust_error_at (r, "redefined multiple times");
190 });
191
192 mappings->insert_canonical_path (constant.get_node_id (), cpath);
193 }
194
195 void visit (AST::TraitItemType &type) override
196 {
197 auto decl
198 = CanonicalPath::new_seg (type.get_node_id (), type.get_identifier ());
199 auto path = prefix.append (decl);
200 auto cpath = canonical_prefix.append (decl);
201
202 resolver->get_type_scope ().insert (
203 path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
204 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
205 RichLocation r (type.get_locus ());
206 r.add_range (locus);
207 rust_error_at (r, "redefined multiple times");
208 });
209
210 mappings->insert_canonical_path (type.get_node_id (), cpath);
211 }
212
213 private:
214 ResolveTopLevelTraitItems (const CanonicalPath &prefix,
215 const CanonicalPath &canonical_prefix)
216 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
217 {}
218
219 const CanonicalPath &prefix;
220 const CanonicalPath &canonical_prefix;
221 };
222
223 class ResolveToplevelExternItem : public ResolverBase
224 {
225 using Rust::Resolver::ResolverBase::visit;
226
227 public:
228 static void go (AST::ExternalItem *item, const CanonicalPath &prefix)
229 {
230 ResolveToplevelExternItem resolver (prefix);
231 item->accept_vis (resolver);
232 };
233
234 void visit (AST::ExternalFunctionItem &function) override
235 {
236 auto decl = CanonicalPath::new_seg (function.get_node_id (),
237 function.get_identifier ());
238 auto path = prefix.append (decl);
239
240 resolver->get_name_scope ().insert (
241 path, function.get_node_id (), function.get_locus (), false,
242 Rib::ItemType::Function,
243 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
244 RichLocation r (function.get_locus ());
245 r.add_range (locus);
246 rust_error_at (r, "redefined multiple times");
247 });
248
249 NodeId current_module = resolver->peek_current_module_scope ();
250 mappings->insert_module_child_item (current_module, decl);
251 }
252
253 void visit (AST::ExternalStaticItem &item) override
254 {
255 auto decl
256 = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
257 auto path = prefix.append (decl);
258
259 resolver->get_name_scope ().insert (
260 path, item.get_node_id (), item.get_locus (), false,
261 Rib::ItemType::Static,
262 [&] (const CanonicalPath &, NodeId, Location locus) -> void {
263 RichLocation r (item.get_locus ());
264 r.add_range (locus);
265 rust_error_at (r, "redefined multiple times");
266 });
267
268 NodeId current_module = resolver->peek_current_module_scope ();
269 mappings->insert_module_child_item (current_module, decl);
270 }
271
272 private:
273 ResolveToplevelExternItem (const CanonicalPath &prefix)
274 : ResolverBase (), prefix (prefix)
275 {}
276
277 const CanonicalPath &prefix;
278 };
279
280 } // namespace Resolver
281 } // namespace Rust
282
283 #endif // RUST_AST_RESOLVE_IMPLITEM_H