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 #include "rust-system.h"
20 #include "rust-operators.h"
21
22 namespace Rust {
23 namespace Analysis {
24
25 // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
26 class RustLangItem
27 {
28 public:
29 enum ItemType
30 {
31 ADD,
32 SUBTRACT,
33 MULTIPLY,
34 DIVIDE,
35 REMAINDER,
36 BITAND,
37 BITOR,
38 BITXOR,
39 SHL,
40 SHR,
41
42 NEGATION,
43 NOT,
44
45 ADD_ASSIGN,
46 SUB_ASSIGN,
47 MUL_ASSIGN,
48 DIV_ASSIGN,
49 REM_ASSIGN,
50 BITAND_ASSIGN,
51 BITOR_ASSIGN,
52 BITXOR_ASSIGN,
53 SHL_ASSIGN,
54 SHR_ASSIGN,
55
56 DEREF,
57 DEREF_MUT,
58
59 // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/index.rs
60 INDEX,
61 INDEX_MUT,
62
63 // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/range.rs
64 RANGE_FULL,
65 RANGE,
66 RANGE_FROM,
67 RANGE_TO,
68 RANGE_INCLUSIVE,
69 RANGE_TO_INCLUSIVE,
70
71 // https://github.com/rust-lang/rust/blob/master/library/core/src/ptr/const_ptr.rs
72 CONST_PTR,
73 MUT_PTR,
74 CONST_SLICE_PTR,
75
76 // https://github.com/rust-lang/rust/blob/master/library/core/src/marker.rs
77 PHANTOM_DATA,
78
79 // functions
80 FN_ONCE,
81 FN_ONCE_OUTPUT,
82
83 // markers
84 COPY,
85 CLONE,
86 SIZED,
87
88 // delimiter
89 UNKNOWN,
90 };
91
92 static ItemType Parse (const std::string &item)
93 {
94 if (item.compare ("add") == 0)
95 {
96 return ItemType::ADD;
97 }
98 else if (item.compare ("sub") == 0)
99 {
100 return ItemType::SUBTRACT;
101 }
102 else if (item.compare ("mul") == 0)
103 {
104 return ItemType::MULTIPLY;
105 }
106 else if (item.compare ("div") == 0)
107 {
108 return ItemType::DIVIDE;
109 }
110 else if (item.compare ("rem") == 0)
111 {
112 return ItemType::REMAINDER;
113 }
114 else if (item.compare ("bitand") == 0)
115 {
116 return ItemType::BITAND;
117 }
118 else if (item.compare ("bitor") == 0)
119 {
120 return ItemType::BITOR;
121 }
122 else if (item.compare ("bitxor") == 0)
123 {
124 return ItemType::BITXOR;
125 }
126 else if (item.compare ("shl") == 0)
127 {
128 return ItemType::SHL;
129 }
130 else if (item.compare ("shr") == 0)
131 {
132 return ItemType::SHR;
133 }
134 else if (item.compare ("neg") == 0)
135 {
136 return ItemType::NEGATION;
137 }
138 else if (item.compare ("not") == 0)
139 {
140 return ItemType::NOT;
141 }
142 else if (item.compare ("add_assign") == 0)
143 {
144 return ItemType::ADD_ASSIGN;
145 }
146 else if (item.compare ("sub_assign") == 0)
147 {
148 return ItemType::SUB_ASSIGN;
149 }
150 else if (item.compare ("mul_assign") == 0)
151 {
152 return ItemType::MUL_ASSIGN;
153 }
154 else if (item.compare ("div_assign") == 0)
155 {
156 return ItemType::DIV_ASSIGN;
157 }
158 else if (item.compare ("rem_assign") == 0)
159 {
160 return ItemType::REM_ASSIGN;
161 }
162 else if (item.compare ("bitand_assign") == 0)
163 {
164 return ItemType::BITAND_ASSIGN;
165 }
166 else if (item.compare ("bitor_assign") == 0)
167 {
168 return ItemType::BITOR_ASSIGN;
169 }
170 else if (item.compare ("bitxor_assign") == 0)
171 {
172 return ItemType::BITXOR_ASSIGN;
173 }
174 else if (item.compare ("shl_assign") == 0)
175 {
176 return ItemType::SHL_ASSIGN;
177 }
178 else if (item.compare ("shr_assign") == 0)
179 {
180 return ItemType::SHR_ASSIGN;
181 }
182 else if (item.compare ("deref") == 0)
183 {
184 return ItemType::DEREF;
185 }
186 else if (item.compare ("deref_mut") == 0)
187 {
188 return ItemType::DEREF_MUT;
189 }
190 else if (item.compare ("index") == 0)
191 {
192 return ItemType::INDEX;
193 }
194 else if (item.compare ("index_mut") == 0)
195 {
196 return ItemType::INDEX_MUT;
197 }
198 else if (item.compare ("RangeFull") == 0)
199 {
200 return ItemType::RANGE_FULL;
201 }
202 else if (item.compare ("Range") == 0)
203 {
204 return ItemType::RANGE;
205 }
206 else if (item.compare ("RangeFrom") == 0)
207 {
208 return ItemType::RANGE_FROM;
209 }
210 else if (item.compare ("RangeTo") == 0)
211 {
212 return ItemType::RANGE_TO;
213 }
214 else if (item.compare ("RangeInclusive") == 0)
215 {
216 return ItemType::RANGE_INCLUSIVE;
217 }
218 else if (item.compare ("RangeToInclusive") == 0)
219 {
220 return ItemType::RANGE_TO_INCLUSIVE;
221 }
222 else if (item.compare ("const_ptr") == 0)
223 {
224 return ItemType::CONST_PTR;
225 }
226 else if (item.compare ("mut_ptr") == 0)
227 {
228 return ItemType::MUT_PTR;
229 }
230 else if (item.compare ("const_slice_ptr") == 0)
231 {
232 return ItemType::CONST_SLICE_PTR;
233 }
234 else if (item.compare ("phantom_data") == 0)
235 {
236 return ItemType::PHANTOM_DATA;
237 }
238 else if (item.compare ("fn_once") == 0)
239 {
240 return ItemType::FN_ONCE;
241 }
242 else if (item.compare ("fn_once_output") == 0)
243 {
244 return ItemType::FN_ONCE_OUTPUT;
245 }
246 else if (item.compare ("copy") == 0)
247 {
248 return ItemType::COPY;
249 }
250 else if (item.compare ("clone") == 0)
251 {
252 return ItemType::CLONE;
253 }
254 else if (item.compare ("sized") == 0)
255 {
256 return ItemType::SIZED;
257 }
258
259 return ItemType::UNKNOWN;
260 }
261
262 static std::string ToString (ItemType type)
263 {
264 switch (type)
265 {
266 case ADD:
267 return "add";
268 case SUBTRACT:
269 return "sub";
270 case MULTIPLY:
271 return "mul";
272 case DIVIDE:
273 return "div";
274 case REMAINDER:
275 return "rem";
276 case BITAND:
277 return "bitand";
278 case BITOR:
279 return "bitor";
280 case BITXOR:
281 return "bitxor";
282 case SHL:
283 return "shl";
284 case SHR:
285 return "shr";
286 case NEGATION:
287 return "neg";
288 case NOT:
289 return "not";
290 case ADD_ASSIGN:
291 return "add_assign";
292 case SUB_ASSIGN:
293 return "sub_assign";
294 case MUL_ASSIGN:
295 return "mul_assign";
296 case DIV_ASSIGN:
297 return "div_assign";
298 case REM_ASSIGN:
299 return "rem_assign";
300 case BITAND_ASSIGN:
301 return "bitand_assign";
302 case BITOR_ASSIGN:
303 return "bitor_assign";
304 case BITXOR_ASSIGN:
305 return "bitxor_assign";
306 case SHL_ASSIGN:
307 return "shl_assign";
308 case SHR_ASSIGN:
309 return "shr_assign";
310 case DEREF:
311 return "deref";
312 case DEREF_MUT:
313 return "deref_mut";
314 case INDEX:
315 return "index";
316 case INDEX_MUT:
317 return "index_mut";
318 case RANGE_FULL:
319 return "RangeFull";
320 case RANGE:
321 return "Range";
322 case RANGE_FROM:
323 return "RangeFrom";
324 case RANGE_TO:
325 return "RangeTo";
326 case RANGE_INCLUSIVE:
327 return "RangeInclusive";
328 case RANGE_TO_INCLUSIVE:
329 return "RangeToInclusive";
330 case CONST_PTR:
331 return "const_ptr";
332 case MUT_PTR:
333 return "mut_ptr";
334 case CONST_SLICE_PTR:
335 return "const_slice_ptr";
336 case PHANTOM_DATA:
337 return "phantom_data";
338 case FN_ONCE:
339 return "fn_once";
340 case FN_ONCE_OUTPUT:
341 return "fn_once_output";
342 case COPY:
343 return "copy";
344 case CLONE:
345 return "clone";
346 case SIZED:
347 return "sized";
348
349 case UNKNOWN:
350 return "<UNKNOWN>";
351 }
352 return "<UNKNOWN>";
353 }
354
355 static ItemType OperatorToLangItem (ArithmeticOrLogicalOperator op)
356 {
357 switch (op)
358 {
359 case ArithmeticOrLogicalOperator::ADD:
360 return ItemType::ADD;
361 case ArithmeticOrLogicalOperator::SUBTRACT:
362 return ItemType::SUBTRACT;
363 case ArithmeticOrLogicalOperator::MULTIPLY:
364 return ItemType::MULTIPLY;
365 case ArithmeticOrLogicalOperator::DIVIDE:
366 return ItemType::DIVIDE;
367 case ArithmeticOrLogicalOperator::MODULUS:
368 return ItemType::REMAINDER;
369 case ArithmeticOrLogicalOperator::BITWISE_AND:
370 return ItemType::BITAND;
371 case ArithmeticOrLogicalOperator::BITWISE_OR:
372 return ItemType::BITOR;
373 case ArithmeticOrLogicalOperator::BITWISE_XOR:
374 return ItemType::BITXOR;
375 case ArithmeticOrLogicalOperator::LEFT_SHIFT:
376 return ItemType::SHL;
377 case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
378 return ItemType::SHR;
379 }
380 return ItemType::UNKNOWN;
381 }
382
383 static ItemType
384 CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op)
385 {
386 switch (op)
387 {
388 case ArithmeticOrLogicalOperator::ADD:
389 return ItemType::ADD_ASSIGN;
390 case ArithmeticOrLogicalOperator::SUBTRACT:
391 return ItemType::SUB_ASSIGN;
392 case ArithmeticOrLogicalOperator::MULTIPLY:
393 return ItemType::MUL_ASSIGN;
394 case ArithmeticOrLogicalOperator::DIVIDE:
395 return ItemType::DIV_ASSIGN;
396 case ArithmeticOrLogicalOperator::MODULUS:
397 return ItemType::REM_ASSIGN;
398 case ArithmeticOrLogicalOperator::BITWISE_AND:
399 return ItemType::BITAND_ASSIGN;
400 case ArithmeticOrLogicalOperator::BITWISE_OR:
401 return ItemType::BITOR_ASSIGN;
402 case ArithmeticOrLogicalOperator::BITWISE_XOR:
403 return ItemType::BITXOR_ASSIGN;
404 case ArithmeticOrLogicalOperator::LEFT_SHIFT:
405 return ItemType::SHL_ASSIGN;
406 case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
407 return ItemType::SHR_ASSIGN;
408 }
409 return ItemType::UNKNOWN;
410 }
411
412 static ItemType NegationOperatorToLangItem (NegationOperator op)
413 {
414 switch (op)
415 {
416 case NegationOperator::NEGATE:
417 return ItemType::NEGATION;
418 case NegationOperator::NOT:
419 return ItemType::NOT;
420 }
421 return ItemType::UNKNOWN;
422 }
423 };
424
425 } // namespace Analysis
426 } // namespace Rust