GCC Code Coverage Report


Directory: src/
File: src/mir/operation.cpp
Date: 2025-10-24 11:14:59
Exec Total Coverage
Lines: 562 611 92.0%
Functions: 103 114 90.4%
Branches: 34 42 81.0%

Line Branch Exec Source
1 /* Copyright 2025 Jonathan S. Arney
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * https://github.com/jarney/gyoji/blob/master/LICENSE
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <gyoji-mir/operations.hpp>
16 #include <gyoji-misc/jstring.hpp>
17
18 using namespace Gyoji::mir;
19
20 namespace Gyoji::mir {
21 static std::map<Operation::OperationType, std::string> op_type_names;
22 }
23
24 30 void Gyoji::mir::operation_static_init()
25 {
26 // This doesn't really belong here, but I don't have a
27 // better place to globally initialize static data.
28
29
30 // Functions and global symbols
31 30 op_type_names.insert(std::pair(Operation::OP_FUNCTION_CALL, "function-call"));
32 30 op_type_names.insert(std::pair(Operation::OP_DESTRUCTOR, "destructor"));
33 30 op_type_names.insert(std::pair(Operation::OP_SYMBOL, "symbol"));
34
35 // Cast operations.
36 30 op_type_names.insert(std::pair(Operation::OP_WIDEN_SIGNED, "widen-signed"));
37 30 op_type_names.insert(std::pair(Operation::OP_WIDEN_UNSIGNED, "widen-unsigned"));
38 30 op_type_names.insert(std::pair(Operation::OP_WIDEN_FLOAT, "widen-float"));
39
40 // Indirect access
41 30 op_type_names.insert(std::pair(Operation::OP_ARRAY_INDEX, "array-index"));
42 30 op_type_names.insert(std::pair(Operation::OP_DOT, "dot"));
43
44 // Variable access
45
46 30 op_type_names.insert(std::pair(Operation::OP_LOCAL_DECLARE, "declare"));
47 30 op_type_names.insert(std::pair(Operation::OP_LOCAL_UNDECLARE, "undeclare"));
48 30 op_type_names.insert(std::pair(Operation::OP_LOCAL_VARIABLE, "load"));
49
50 // Literals
51 30 op_type_names.insert(std::pair(Operation::OP_LITERAL_CHAR, "literal-char"));
52 30 op_type_names.insert(std::pair(Operation::OP_LITERAL_STRING, "literal-string"));
53 30 op_type_names.insert(std::pair(Operation::OP_LITERAL_INT, "literal-int"));
54 30 op_type_names.insert(std::pair(Operation::OP_LITERAL_FLOAT, "literal-float"));
55 30 op_type_names.insert(std::pair(Operation::OP_LITERAL_BOOL, "literal-bool"));
56 30 op_type_names.insert(std::pair(Operation::OP_LITERAL_NULL, "literal-null"));
57 30 op_type_names.insert(std::pair(Operation::OP_ANONYMOUS_STRUCTURE, "anonymous-structure"));
58
59 // Unary operations
60 30 op_type_names.insert(std::pair(Operation::OP_ADDRESSOF, "addressof"));
61 30 op_type_names.insert(std::pair(Operation::OP_DEREFERENCE, "dereference"));
62 30 op_type_names.insert(std::pair(Operation::OP_NEGATE, "negate"));
63 30 op_type_names.insert(std::pair(Operation::OP_BITWISE_NOT, "bitwise-not"));
64 30 op_type_names.insert(std::pair(Operation::OP_LOGICAL_NOT, "logical-not"));
65 30 op_type_names.insert(std::pair(Operation::OP_SIZEOF_TYPE, "sizeof"));
66
67 // Binary operations: arithmetic
68 30 op_type_names.insert(std::pair(Operation::OP_ADD, "add"));
69 30 op_type_names.insert(std::pair(Operation::OP_SUBTRACT, "subtract"));
70 30 op_type_names.insert(std::pair(Operation::OP_MULTIPLY, "multiply"));
71 30 op_type_names.insert(std::pair(Operation::OP_DIVIDE, "divide"));
72 30 op_type_names.insert(std::pair(Operation::OP_MODULO, "modulo"));
73
74 // Binary operations: logical
75 30 op_type_names.insert(std::pair(Operation::OP_LOGICAL_AND, "logical-and"));
76 30 op_type_names.insert(std::pair(Operation::OP_LOGICAL_OR, "logical-or"));
77
78 // Binary operations: bitwise
79 30 op_type_names.insert(std::pair(Operation::OP_BITWISE_AND, "bitwise-and"));
80 30 op_type_names.insert(std::pair(Operation::OP_BITWISE_OR, "bitwise-or"));
81 30 op_type_names.insert(std::pair(Operation::OP_BITWISE_XOR, "bitwise-xor"));
82 30 op_type_names.insert(std::pair(Operation::OP_SHIFT_LEFT, "bitwise-shift-left"));
83 30 op_type_names.insert(std::pair(Operation::OP_SHIFT_RIGHT, "bitwise-shift-right"));
84
85 // Binary operations: comparisons
86 30 op_type_names.insert(std::pair(Operation::OP_COMPARE_LESS, "compare-less"));
87 30 op_type_names.insert(std::pair(Operation::OP_COMPARE_GREATER, "compare-greater"));
88 30 op_type_names.insert(std::pair(Operation::OP_COMPARE_LESS_EQUAL, "compare-less-equal"));
89 30 op_type_names.insert(std::pair(Operation::OP_COMPARE_GREATER_EQUAL, "compare-greater-equal"));
90 30 op_type_names.insert(std::pair(Operation::OP_COMPARE_NOT_EQUAL, "compare-not-equal"));
91 30 op_type_names.insert(std::pair(Operation::OP_COMPARE_EQUAL, "compare-equal"));
92
93 // Binary operations: assignment
94 30 op_type_names.insert(std::pair(Operation::OP_ASSIGN, "store"));
95
96 // Branch and flow control
97 30 op_type_names.insert(std::pair(Operation::OP_JUMP_CONDITIONAL, "jump-conditional"));
98 30 op_type_names.insert(std::pair(Operation::OP_JUMP, "jump"));
99 30 op_type_names.insert(std::pair(Operation::OP_RETURN, "return"));
100 30 op_type_names.insert(std::pair(Operation::OP_RETURN_VOID, "return-void"));
101 30 }
102
103 3140 Operation::Operation(
104 OperationType _type,
105 const Gyoji::context::SourceReference & _src_ref,
106 size_t _result
107 3140 )
108 3140 : type(_type)
109 3140 , src_ref(_src_ref)
110 3140 , result(_result)
111 3140 {}
112 588 Operation::Operation(
113 OperationType _type,
114 const Gyoji::context::SourceReference & _src_ref,
115 size_t _result,
116 size_t _operand
117 588 )
118 588 : type(_type)
119 588 , src_ref(_src_ref)
120 588 , result(_result)
121 {
122 588 add_operand(_operand);
123 588 }
124 672 Operation::Operation(
125 OperationType _type,
126 const Gyoji::context::SourceReference & _src_ref,
127 size_t _result,
128 size_t _operand_a,
129 size_t _operand_b
130 672 )
131 672 : type(_type)
132 672 , src_ref(_src_ref)
133 672 , result(_result)
134 {
135 672 add_operand(_operand_a);
136 672 add_operand(_operand_b);
137 672 }
138 Operation::Operation(
139 OperationType _type,
140 const Gyoji::context::SourceReference & _src_ref,
141 size_t _result,
142 size_t _operand_a,
143 size_t _operand_b,
144 size_t _operand_c
145 )
146 : type(_type)
147 , src_ref(_src_ref)
148 , result(_result)
149 {
150 add_operand(_operand_a);
151 add_operand(_operand_b);
152 add_operand(_operand_c);
153 }
154 8800 Operation::~Operation()
155 8800 {}
156
157 void
158 2032 Operation::add_operand(size_t operand)
159 {
160 2032 operands.push_back(operand);
161 2032 }
162
163 std::string
164 800 Operation::get_description() const
165 {
166 800 const auto & it = op_type_names.find(type);
167 800 const std::string & op_name = it->second;
168
169 4000 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
170
2/2
✓ Branch 4 taken 1562 times.
✓ Branch 5 taken 800 times.
2362 for (const auto & operand : operands) {
171 4686 desc = desc + std::string(" _") + std::to_string(operand);
172 }
173 800 desc = desc + std::string(" )");
174
175 800 return desc;
176 }
177 bool
178 13400 Operation::is_terminating() const
179 {
180 // Identify any instructions that
181 // would terminate a basic block.
182 26686 return (type == OP_JUMP) ||
183
2/2
✓ Branch 0 taken 13166 times.
✓ Branch 1 taken 120 times.
13286 (type == OP_JUMP_CONDITIONAL) ||
184
4/4
✓ Branch 0 taken 13286 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 12308 times.
✓ Branch 3 taken 858 times.
38994 (type == OP_RETURN) ||
185
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 12292 times.
25708 (type == OP_RETURN_VOID);
186 }
187
188 std::vector<size_t>
189 360 Operation::get_connections() const
190 {
191 360 std::vector<size_t> connections;
192
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 324 times.
360 if (type == OP_JUMP) {
193 // A bit embarrased we have to cast here, but I don't want
194 // to rework this right now.
195 36 OperationJump *jumpop = (OperationJump*)this;
196 36 connections.push_back(jumpop->get_jump_block());
197 }
198
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 284 times.
324 else if (type == OP_JUMP_CONDITIONAL) {
199 // A bit embarrased we have to cast here, but I don't want
200 // to rework this right now.
201 40 OperationJumpConditional *ifop = (OperationJumpConditional*)this;
202 40 connections.push_back(ifop->get_if_block());
203 40 connections.push_back(ifop->get_else_block());
204 }
205 360 return connections;
206 }
207
208 Operation::OperationType
209 25716 Operation::get_type() const
210 25716 { return type; }
211
212 const std::vector<size_t> &
213 5250 Operation::get_operands() const
214 5250 { return operands; }
215
216 size_t
217 9676 Operation::get_result() const
218 9676 { return result; }
219
220 const Gyoji::context::SourceReference &
221 Operation::get_source_ref() const
222 { return src_ref; }
223
224 void
225 4378 Operation::dump(FILE *out, size_t operation_index) const
226 {
227 // fprintf(out, " %ld : %s\n", operation_index, get_description().c_str());
228 4378 fprintf(out, " %s\n", get_description().c_str());
229 4378 }
230
231
232 //////////////////////////////////////////////
233 // OperationUnary
234 //////////////////////////////////////////////
235 170 OperationUnary::OperationUnary(
236 OperationType _type,
237 const Gyoji::context::SourceReference & _src_ref,
238 size_t _result,
239 size_t _operand
240 170 )
241 170 : Operation(_type, _src_ref, _result, _operand)
242 170 {}
243 400 OperationUnary::~OperationUnary()
244 400 {}
245 size_t
246 170 OperationUnary::get_a() const
247 170 { return operands.at(0); }
248 //////////////////////////////////////////////
249 // OperationCast
250 //////////////////////////////////////////////
251 136 OperationCast::OperationCast(
252 OperationType _type,
253 const Gyoji::context::SourceReference & _src_ref,
254 size_t _result,
255 size_t _operand,
256 const Type *_cast_type
257 136 )
258 : OperationUnary(_type, _src_ref, _result, _operand)
259 136 , cast_type(_cast_type)
260 136 {}
261 544 OperationCast::~OperationCast()
262 544 {}
263
264 const Type*
265 136 OperationCast::get_cast_type() const
266 136 { return cast_type; }
267
268 std::string
269 136 OperationCast::get_description() const
270 {
271 136 const auto & it = op_type_names.find(type);
272 136 const std::string & op_name = it->second;
273
274 680 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
275 408 desc = desc + std::string(" _") + std::to_string(operands.at(0));
276 408 desc = desc + std::string(" ") + cast_type->get_name();
277 136 desc = desc + std::string(" )");
278 136 return desc;
279 }
280
281 //////////////////////////////////////////////
282 // OperationBinary
283 //////////////////////////////////////////////
284
285 672 OperationBinary::OperationBinary(
286 OperationType _type,
287 const Gyoji::context::SourceReference & _src_ref,
288 size_t _result,
289 size_t _operand_a,
290 size_t _operand_b
291 672 )
292 672 : Operation(_type, _src_ref, _result, _operand_a, _operand_b)
293 672 {}
294 2688 OperationBinary::~OperationBinary()
295 2688 {}
296 size_t
297 1064 OperationBinary::get_a() const
298 1064 { return operands.at(0); }
299
300 size_t
301 1442 OperationBinary::get_b() const
302 1442 { return operands.at(1); }
303
304
305 //////////////////////////////////////////////
306 // OperationFunctionCall
307 //////////////////////////////////////////////
308 90 OperationFunctionCall::OperationFunctionCall(
309 Operation::OperationType _type,
310 const Gyoji::context::SourceReference & _src_ref,
311 size_t _result,
312 size_t _callee_tmpvar,
313 std::vector<size_t> _arg_args
314 90 )
315 90 : Operation(_type, _src_ref, _result, _callee_tmpvar)
316 {
317
2/2
✓ Branch 5 taken 98 times.
✓ Branch 6 taken 90 times.
188 for (const auto & av : _arg_args) {
318 98 add_operand(av);
319 }
320 90 }
321
322 360 OperationFunctionCall::~OperationFunctionCall()
323 360 {}
324
325 //////////////////////////////////////////////
326 // OperationSymbol
327 //////////////////////////////////////////////
328 90 OperationSymbol::OperationSymbol(
329 const Gyoji::context::SourceReference & _src_ref,
330 size_t _result,
331 std::vector<size_t> _partial_operands,
332 std::string _symbol_name
333 90 )
334 : Operation(OP_SYMBOL, _src_ref, _result)
335 90 , symbol_name(_symbol_name)
336 {
337
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 90 times.
92 for (size_t partial_operand : _partial_operands) {
338 2 add_operand(partial_operand);
339 }
340 90 }
341
342 360 OperationSymbol::~OperationSymbol()
343 360 {}
344
345 const std::string &
346 90 OperationSymbol::get_symbol_name() const
347 90 { return symbol_name; }
348
349 std::string
350 90 OperationSymbol::get_description() const
351 {
352 90 const auto & it = op_type_names.find(type);
353 90 const std::string & op_name = it->second;
354
355 90 std::string partials = "";
356
2/2
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 90 times.
92 for (const size_t & op : operands) {
357 6 partials = partials + std::string(" _") + std::to_string(op);
358 }
359
360 450 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
361 270 desc = desc + std::string(" ") + symbol_name;
362 180 desc = desc + std::string(" ") + partials;
363 90 desc = desc + std::string(" )");
364 90 return desc;
365 90 }
366
367 //////////////////////////////////////////////
368 // OperationArrayIndex
369 //////////////////////////////////////////////
370 OperationArrayIndex::OperationArrayIndex(
371 const Gyoji::context::SourceReference & _src_ref,
372 size_t _result,
373 size_t _array_tmpvar,
374 size_t _index_tmpvar
375 )
376 : OperationBinary(OP_ARRAY_INDEX, _src_ref, _result, _array_tmpvar, _index_tmpvar)
377 {}
378 OperationArrayIndex::~OperationArrayIndex()
379 {}
380
381 //////////////////////////////////////////////
382 // OperationDot
383 //////////////////////////////////////////////
384 4 OperationDot::OperationDot(
385 const Gyoji::context::SourceReference & _src_ref,
386 size_t _result,
387 size_t _operand,
388 std::string _member_name
389 4 )
390 : OperationUnary(OP_DOT, _src_ref, _result, _operand)
391 4 , member_name(_member_name)
392 4 {}
393
394 16 OperationDot::~OperationDot()
395 16 {}
396
397 const std::string &
398 4 OperationDot::get_member_name() const
399 4 { return member_name; }
400
401 std::string
402 4 OperationDot::get_description() const
403 {
404 4 const auto & it = op_type_names.find(type);
405 4 const std::string & op_name = it->second;
406
407 20 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
408 12 desc = desc + std::string(" _") + std::to_string(operands.at(0));
409 12 desc = desc + std::string(" ") + member_name;
410 4 desc = desc + std::string(" )");
411 4 return desc;
412 }
413
414 //////////////////////////////////////////////
415 // OperationLocalVariable
416 //////////////////////////////////////////////
417 1492 OperationLocalVariable::OperationLocalVariable(
418 const Gyoji::context::SourceReference & _src_ref,
419 size_t _result,
420 std::string _symbol_name,
421 const Type * _var_type
422 1492 )
423 : Operation(OP_LOCAL_VARIABLE, _src_ref, _result)
424 1492 , symbol_name(_symbol_name)
425 1492 , var_type(_var_type)
426 1492 {}
427 5968 OperationLocalVariable::~OperationLocalVariable()
428 5968 {}
429
430 const std::string &
431 2984 OperationLocalVariable::get_symbol_name() const
432 2984 { return symbol_name; }
433
434 const Type *
435 1492 OperationLocalVariable::get_var_type() const
436 1492 { return var_type; }
437
438 std::string
439 1492 OperationLocalVariable::get_description() const
440 {
441 1492 const auto & it = op_type_names.find(type);
442 1492 const std::string & op_name = it->second;
443
444 7460 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
445 2984 desc = desc + std::string(" ") + symbol_name;
446 4476 desc = desc + std::string(" ") + var_type->get_name();
447 1492 desc = desc + std::string(" )");
448 1492 return desc;
449 }
450
451 //////////////////////////////////////////////
452 // OperationLiteralChar
453 //////////////////////////////////////////////
454 8 OperationLiteralChar::OperationLiteralChar(
455 const Gyoji::context::SourceReference & _src_ref,
456 size_t _result,
457 char _literal_char
458 8 )
459 : Operation(OP_LITERAL_CHAR, _src_ref, _result)
460 8 , literal_char(_literal_char)
461 8 {}
462 32 OperationLiteralChar::~OperationLiteralChar()
463 32 {}
464
465 char
466 8 OperationLiteralChar::get_literal_char() const
467 8 { return literal_char; }
468
469 std::string
470 8 OperationLiteralChar::get_description() const
471 {
472 8 const auto & it = op_type_names.find(type);
473 8 const std::string & op_name = it->second;
474 8 std::string char_unescaped;
475 8 char_unescaped.push_back(literal_char);
476 8 std::string char_escaped;
477 8 Gyoji::misc::string_c_escape(char_escaped, char_unescaped, true);
478
479 40 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
480 24 desc = desc + std::string(" ") + literal_char;
481 8 desc = desc + std::string(" )");
482 8 return desc;
483 8 }
484
485 //////////////////////////////////////////////
486 // OperationLiteralString
487 //////////////////////////////////////////////
488 12 OperationLiteralString::OperationLiteralString(
489 const Gyoji::context::SourceReference & _src_ref,
490 size_t _result,
491 std::string _literal_string
492 12 )
493 : Operation(OP_LITERAL_STRING, _src_ref, _result)
494 12 , literal_string(_literal_string)
495 12 {}
496 48 OperationLiteralString::~OperationLiteralString()
497 48 {}
498
499 const std::string &
500 12 OperationLiteralString::get_literal_string() const
501 12 { return literal_string; }
502
503 std::string
504 12 OperationLiteralString::get_description() const
505 {
506 12 const auto & it = op_type_names.find(type);
507 12 const std::string & op_name = it->second;
508
509 12 std::string literal_escaped;
510 12 Gyoji::misc::string_c_escape(literal_escaped, literal_string, false);
511
512 72 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
513 24 desc = desc + std::string(" \"") + literal_escaped;
514 12 desc = desc + std::string(" \")");
515 12 return desc;
516 12 }
517
518 //////////////////////////////////////////////
519 // OperationLiteralInt
520 //////////////////////////////////////////////
521 12 OperationLiteralInt::OperationLiteralInt(
522 const Gyoji::context::SourceReference & _src_ref,
523 size_t _result,
524 Type::TypeType _literal_type,
525 unsigned char _literal_u8
526 12 )
527 : Operation(OP_LITERAL_INT, _src_ref, _result)
528 12 , literal_type(_literal_type)
529 12 , literal_u8(_literal_u8)
530 12 , literal_u16(0)
531 12 , literal_u32(0)
532 12 , literal_u64(0L)
533 12 , literal_i8(0)
534 12 , literal_i16(0)
535 12 , literal_i32(0)
536 12 , literal_i64(0)
537 12 {}
538 26 OperationLiteralInt::OperationLiteralInt(
539 const Gyoji::context::SourceReference & _src_ref,
540 size_t _result,
541 Type::TypeType _literal_type,
542 unsigned short _literal_u16
543 26 )
544 : Operation(OP_LITERAL_INT, _src_ref, _result)
545 26 , literal_type(_literal_type)
546 26 , literal_u8(0)
547 26 , literal_u16(_literal_u16)
548 26 , literal_u32(0)
549 26 , literal_u64(0L)
550 26 , literal_i8(0)
551 26 , literal_i16(0)
552 26 , literal_i32(0)
553 26 , literal_i64(0)
554 26 {}
555 166 OperationLiteralInt::OperationLiteralInt(
556 const Gyoji::context::SourceReference & _src_ref,
557 size_t _result,
558 Type::TypeType _literal_type,
559 unsigned int _literal_u32
560 166 )
561 : Operation(OP_LITERAL_INT, _src_ref, _result)
562 166 , literal_type(_literal_type)
563 166 , literal_u8(0)
564 166 , literal_u16(0)
565 166 , literal_u32(_literal_u32)
566 166 , literal_u64(0L)
567 166 , literal_i8(0)
568 166 , literal_i16(0)
569 166 , literal_i32(0)
570 166 , literal_i64(0)
571 166 {}
572 18 OperationLiteralInt::OperationLiteralInt(
573 const Gyoji::context::SourceReference & _src_ref,
574 size_t _result,
575 Type::TypeType _literal_type,
576 unsigned long _literal_u64
577 18 )
578 : Operation(OP_LITERAL_INT, _src_ref, _result)
579 18 , literal_type(_literal_type)
580 18 , literal_u8(0)
581 18 , literal_u16(0)
582 18 , literal_u32(0)
583 18 , literal_u64(_literal_u64)
584 18 , literal_i8(0)
585 18 , literal_i16(0)
586 18 , literal_i32(0)
587 18 , literal_i64(0)
588 18 {}
589 /////
590 10 OperationLiteralInt::OperationLiteralInt(
591 const Gyoji::context::SourceReference & _src_ref,
592 size_t _result,
593 Type::TypeType _literal_type,
594 char _literal_i8
595 10 )
596 : Operation(OP_LITERAL_INT, _src_ref, _result)
597 10 , literal_type(_literal_type)
598 10 , literal_u8(0)
599 10 , literal_u16(0)
600 10 , literal_u32(0)
601 10 , literal_u64(0L)
602 10 , literal_i8(_literal_i8)
603 10 , literal_i16(0)
604 10 , literal_i32(0)
605 10 , literal_i64(0)
606 10 {}
607 16 OperationLiteralInt::OperationLiteralInt(
608 const Gyoji::context::SourceReference & _src_ref,
609 size_t _result,
610 Type::TypeType _literal_type,
611 short _literal_i16
612 16 )
613 : Operation(OP_LITERAL_INT, _src_ref, _result)
614 16 , literal_type(_literal_type)
615 16 , literal_u8(0)
616 16 , literal_u16(0)
617 16 , literal_u32(0)
618 16 , literal_u64(0L)
619 16 , literal_i8(0)
620 16 , literal_i16(_literal_i16)
621 16 , literal_i32(0)
622 16 , literal_i64(0)
623 16 {}
624 8 OperationLiteralInt::OperationLiteralInt(
625 const Gyoji::context::SourceReference & _src_ref,
626 size_t _result,
627 Type::TypeType _literal_type,
628 int _literal_i32
629 8 )
630 : Operation(OP_LITERAL_INT, _src_ref, _result)
631 8 , literal_type(_literal_type)
632 8 , literal_u8(0)
633 8 , literal_u16(0)
634 8 , literal_u32(0)
635 8 , literal_u64(0L)
636 8 , literal_i8(0)
637 8 , literal_i16(0)
638 8 , literal_i32(_literal_i32)
639 8 , literal_i64(0)
640 8 {}
641 10 OperationLiteralInt::OperationLiteralInt(
642 const Gyoji::context::SourceReference & _src_ref,
643 size_t _result,
644 Type::TypeType _literal_type,
645 long _literal_i64
646 10 )
647 : Operation(OP_LITERAL_INT, _src_ref, _result)
648 10 , literal_type(_literal_type)
649 10 , literal_u8(0)
650 10 , literal_u16(0)
651 10 , literal_u32(0)
652 10 , literal_u64(0)
653 10 , literal_i8(0)
654 10 , literal_i16(0)
655 10 , literal_i32(0)
656 10 , literal_i64(_literal_i64)
657 10 {}
658
659 1064 OperationLiteralInt::~OperationLiteralInt()
660 1064 {}
661
662 Type::TypeType
663 244 OperationLiteralInt::get_literal_type() const
664 244 { return literal_type; }
665 unsigned char
666 12 OperationLiteralInt::get_literal_u8() const
667 12 { return literal_u8; }
668 unsigned short
669 14 OperationLiteralInt::get_literal_u16() const
670 14 { return literal_u16; }
671 unsigned int
672 166 OperationLiteralInt::get_literal_u32() const
673 166 { return literal_u32; }
674 unsigned long
675 18 OperationLiteralInt::get_literal_u64() const
676 18 { return literal_u64; }
677 char
678 10 OperationLiteralInt::get_literal_i8() const
679 10 { return literal_i8; }
680 short
681 6 OperationLiteralInt::get_literal_i16() const
682 6 { return literal_i16; }
683 int
684 8 OperationLiteralInt::get_literal_i32() const
685 8 { return literal_i32; }
686 long
687 10 OperationLiteralInt::get_literal_i64() const
688 10 { return literal_i64; }
689
690 std::string
691 244 OperationLiteralInt::get_description() const
692 {
693 244 const auto & it = op_type_names.find(type);
694 244 const std::string & op_name = it->second;
695
696 244 std::string literalstr;
697 244 std::string literaltype;
698
699
8/9
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 166 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
244 switch (literal_type) {
700 12 case Type::TYPE_PRIMITIVE_u8:
701 12 literalstr = std::to_string(literal_u8);
702 12 literaltype = "u8";
703 12 break;
704 14 case Type::TYPE_PRIMITIVE_u16:
705 14 literalstr = std::to_string(literal_u16);
706 14 literaltype = "u16";
707 14 break;
708 166 case Type::TYPE_PRIMITIVE_u32:
709 166 literalstr = std::to_string(literal_u32);
710 166 literaltype = "u32";
711 166 break;
712 18 case Type::TYPE_PRIMITIVE_u64:
713 18 literalstr = std::to_string(literal_u64);
714 18 literaltype = "u64";
715 18 break;
716 10 case Type::TYPE_PRIMITIVE_i8:
717 10 literalstr = std::to_string(literal_i8);
718 10 literaltype = "i8";
719 10 break;
720 6 case Type::TYPE_PRIMITIVE_i16:
721 6 literalstr = std::to_string(literal_i16);
722 6 literaltype = "i16";
723 6 break;
724 8 case Type::TYPE_PRIMITIVE_i32:
725 8 literalstr = std::to_string(literal_i32);
726 8 literaltype = "i32";
727 8 break;
728 10 case Type::TYPE_PRIMITIVE_i64:
729 10 literalstr = std::to_string(literal_i64);
730 10 literaltype = "i64";
731 10 break;
732 default:
733 literalstr = "Error: Unsupported literal int type";
734 break;
735 }
736 1464 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
737 488 desc = desc + std::string(" ") + literalstr + literaltype;
738 244 desc = desc + std::string(" )");
739 244 return desc;
740 244 }
741
742 //////////////////////////////////////////////
743 // OperationLiteralFloat
744 //////////////////////////////////////////////
745
746 2 OperationLiteralFloat::OperationLiteralFloat(
747 const Gyoji::context::SourceReference & _src_ref,
748 size_t _result,
749 float _literal_float
750 2 )
751 : Operation(OP_LITERAL_FLOAT, _src_ref, _result)
752 2 , literal_type(Type::TYPE_PRIMITIVE_f32)
753 2 , literal_float_f32(_literal_float)
754 2 , literal_float_f64(0.0)
755 2 {}
756 4 OperationLiteralFloat::OperationLiteralFloat(
757 const Gyoji::context::SourceReference & _src_ref,
758 size_t _result,
759 double _literal_float
760 4 )
761 : Operation(OP_LITERAL_FLOAT, _src_ref, _result)
762 4 , literal_type(Type::TYPE_PRIMITIVE_f64)
763 4 , literal_float_f32(0.0)
764 4 , literal_float_f64(_literal_float)
765 4 {}
766 24 OperationLiteralFloat::~OperationLiteralFloat()
767 24 {}
768
769 float
770 2 OperationLiteralFloat::get_literal_float() const
771 2 { return literal_float_f32; }
772
773 double
774 4 OperationLiteralFloat::get_literal_double() const
775 4 { return literal_float_f64; }
776
777 Type::TypeType
778 6 OperationLiteralFloat::get_literal_type() const
779 6 { return literal_type; }
780 std::string
781 6 OperationLiteralFloat::get_description() const
782 {
783 6 const auto & it = op_type_names.find(type);
784 6 const std::string & op_name = it->second;
785
786 6 std::string literal_float;
787
2/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
6 switch (literal_type) {
788 2 case Type::TYPE_PRIMITIVE_f32:
789 2 literal_float = std::to_string(literal_float_f32) + std::string(" f32");
790 2 break;
791 4 case Type::TYPE_PRIMITIVE_f64:
792 4 literal_float = std::to_string(literal_float_f64) + std::string(" f64");
793 4 break;
794 default:
795 fprintf(stderr, "Compiler Bug! Unknown literal float type\n");
796 exit(1);
797 }
798
799 36 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
800 12 desc = desc + std::string(" ") + literal_float;
801 6 desc = desc + std::string(" )");
802 6 return desc;
803 6 }
804
805 //////////////////////////////////////////////
806 // OperationLiteralBool
807 //////////////////////////////////////////////
808 OperationLiteralBool::OperationLiteralBool(
809 const Gyoji::context::SourceReference & _src_ref,
810 size_t _result,
811 bool _literal_bool
812 )
813 : Operation(OP_LITERAL_BOOL, _src_ref, _result)
814 , literal_bool(_literal_bool)
815 {}
816 OperationLiteralBool::~OperationLiteralBool()
817 {}
818 bool
819 OperationLiteralBool::get_literal_bool() const
820 { return literal_bool; }
821 std::string
822 OperationLiteralBool::get_description() const
823 {
824 const auto & it = op_type_names.find(type);
825 const std::string & op_name = it->second;
826 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (");
827 desc = desc + std::string(" ") + (literal_bool ? std::string("true") : std::string("false"));
828 desc = desc + std::string(" )");
829 return desc;
830 }
831 //////////////////////////////////////////////
832 // OperationLiteralNull
833 //////////////////////////////////////////////
834 OperationLiteralNull::OperationLiteralNull(
835 const Gyoji::context::SourceReference & _src_ref,
836 size_t _result
837 )
838 : Operation(OP_LITERAL_NULL, _src_ref, _result)
839 {}
840 OperationLiteralNull::~OperationLiteralNull()
841 {}
842 std::string
843 OperationLiteralNull::get_description() const
844 {
845 const auto & it = op_type_names.find(type);
846 const std::string & op_name = it->second;
847 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" ( )");
848 return desc;
849 }
850 //////////////////////////////////////////////
851 // OperationAnonymousStructure
852 //////////////////////////////////////////////
853
854 6 OperationAnonymousStructure::OperationAnonymousStructure(
855 const Gyoji::context::SourceReference & _src_ref,
856 size_t _result,
857 std::vector<std::pair<std::string, size_t>> _fields
858 6 )
859 6 : Operation(OP_ANONYMOUS_STRUCTURE, _src_ref, _result)
860 {
861 6 fprintf(stderr, "Constructing anonymous structure of length %ld\n", _fields.size());
862
2/2
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 6 times.
16 for (const auto & p : _fields) {
863 10 fields.insert(p);
864 10 operands.push_back(p.second);
865 }
866 6 }
867 24 OperationAnonymousStructure::~OperationAnonymousStructure()
868 24 {}
869
870 const std::map<std::string, size_t> &
871 6 OperationAnonymousStructure::get_fields() const
872 6 { return fields; }
873
874 std::string
875 6 OperationAnonymousStructure::get_description() const
876 {
877 6 std::vector<std::string> field_desc;
878
879
2/2
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 6 times.
16 for (const auto & p : fields) {
880 10 size_t tmpvar = p.second;
881 10 std::string name = p.first;
882 30 field_desc.push_back(std::string(name) + std::string(": _") + std::to_string(tmpvar));
883 10 }
884 6 std::string fdesc = Gyoji::misc::join(field_desc, ", ");
885
886 6 const auto & it = op_type_names.find(type);
887 6 const std::string & op_name = it->second;
888 42 std::string desc = std::string("_") + std::to_string(result) + std::string(" = ") + op_name + std::string(" (") + fdesc + std::string(" )");
889 6 return desc;
890 6 }
891
892 //////////////////////////////////////////////
893 // OperationJumpConditional
894 //////////////////////////////////////////////
895 40 OperationJumpConditional::OperationJumpConditional(
896 const Gyoji::context::SourceReference & _src_ref,
897 size_t _operand,
898 size_t _if_block,
899 size_t _else_block
900 40 )
901 : Operation(OP_JUMP_CONDITIONAL, _src_ref, 0, _operand)
902 40 , if_block(_if_block)
903 40 , else_block(_else_block)
904 {
905 40 }
906
907 160 OperationJumpConditional::~OperationJumpConditional()
908 160 {}
909
910 std::string
911 40 OperationJumpConditional::get_description() const
912 {
913 40 const auto & it = op_type_names.find(type);
914 40 const std::string & op_name = it->second;
915
916 40 std::string desc = op_name + std::string(" (");
917 120 desc = desc + std::string(" _") + std::to_string(operands.at(0));
918 120 desc = desc + std::string(" BB") + std::to_string(get_if_block());
919 120 desc = desc + std::string(" BB") + std::to_string(get_else_block());
920 40 desc = desc + std::string(" )");
921 40 return desc;
922 }
923 size_t
924 120 OperationJumpConditional::get_if_block() const
925 120 { return if_block; }
926 size_t
927 120 OperationJumpConditional::get_else_block() const
928 120 { return else_block; }
929
930 //////////////////////////////////////////////
931 // OperationJump
932 //////////////////////////////////////////////
933 36 OperationJump::OperationJump(
934 const Gyoji::context::SourceReference & _src_ref,
935 size_t _block
936 36 )
937 : Operation(OP_JUMP, _src_ref, 0)
938 36 , jump_block(_block)
939 36 {}
940 144 OperationJump::~OperationJump()
941 144 {}
942
943 std::string
944 36 OperationJump::get_description() const
945 {
946 36 const auto & it = op_type_names.find(type);
947 36 const std::string & op_name = it->second;
948
949 36 std::string desc = op_name + std::string(" (");
950 108 desc = desc + std::string(" BB") + std::to_string(get_jump_block());
951 36 desc = desc + std::string(" )");
952 36 return desc;
953 }
954 size_t
955 108 OperationJump::get_jump_block() const
956 108 { return jump_block; }
957
958 //////////////////////////////////////////////
959 // OperationReturn
960 //////////////////////////////////////////////
961 280 OperationReturn::OperationReturn(
962 const Gyoji::context::SourceReference & _src_ref,
963 size_t _operand
964 280 )
965 280 : Operation(OP_RETURN, _src_ref, 0, _operand)
966 280 {}
967 1120 OperationReturn::~OperationReturn()
968 1120 {}
969
970 std::string
971 280 OperationReturn::get_description() const
972 {
973 280 const auto & it = op_type_names.find(type);
974 280 const std::string & op_name = it->second;
975
976 280 std::string desc = op_name + std::string(" (");
977 840 desc = desc + std::string(" _") + std::to_string(operands.at(0));
978 280 desc = desc + std::string(" )");
979 280 return desc;
980 }
981
982 //////////////////////////////////////////////
983 // OperationReturnVoid
984 //////////////////////////////////////////////
985 8 OperationReturnVoid::OperationReturnVoid(
986 const Gyoji::context::SourceReference & _src_ref
987 8 )
988 8 : Operation(OP_RETURN_VOID, _src_ref, 0, 0)
989 8 {}
990 32 OperationReturnVoid::~OperationReturnVoid()
991 32 {}
992
993 std::string
994 8 OperationReturnVoid::get_description() const
995 {
996 8 const auto & it = op_type_names.find(type);
997 8 const std::string & op_name = it->second;
998 8 return op_name;
999 }
1000
1001 //////////////////////////////////////////////
1002 // OperationLocalDeclare
1003 //////////////////////////////////////////////
1004 312 OperationLocalDeclare::OperationLocalDeclare(
1005 const Gyoji::context::SourceReference & _src_ref,
1006 std::string _variable,
1007 const Type *_variable_type
1008 312 )
1009 : Operation(OP_LOCAL_DECLARE, _src_ref, 0)
1010 312 , variable(_variable)
1011 312 , variable_type(_variable_type)
1012 312 {}
1013 1248 OperationLocalDeclare::~OperationLocalDeclare()
1014 1248 {}
1015 const std::string &
1016 624 OperationLocalDeclare::get_variable() const
1017 624 { return variable; }
1018 const Type*
1019 312 OperationLocalDeclare::get_variable_type() const
1020 312 { return variable_type; }
1021
1022 std::string
1023 312 OperationLocalDeclare::get_description() const
1024 {
1025 312 const auto & it = op_type_names.find(type);
1026 312 const std::string & op_name = it->second;
1027
1028 312 std::string desc = op_name + std::string(" (");
1029 624 desc = desc + std::string(" ") + variable;
1030 936 desc = desc + std::string(" ") + variable_type->get_name();
1031 312 desc = desc + std::string(" )");
1032 312 return desc;
1033 }
1034 //////////////////////////////////////////////
1035 // OperationLocalUndeclare
1036 //////////////////////////////////////////////
1037 904 OperationLocalUndeclare::OperationLocalUndeclare(
1038 const Gyoji::context::SourceReference & _src_ref,
1039 std::string _variable
1040 904 )
1041 : Operation(OP_LOCAL_UNDECLARE, _src_ref, 0)
1042 904 , variable(_variable)
1043 904 {}
1044
1045 3616 OperationLocalUndeclare::~OperationLocalUndeclare()
1046 3616 {}
1047
1048 std::string
1049 904 OperationLocalUndeclare::get_description() const
1050 {
1051 904 const auto & it = op_type_names.find(type);
1052 904 const std::string & op_name = it->second;
1053
1054 904 std::string desc = op_name + std::string(" (");
1055 2712 desc = desc + std::string(" ") + variable;
1056 904 desc = desc + std::string(" )");
1057 904 return desc;
1058 }
1059 //////////////////////////////////////////////
1060 // OperationSizeofType
1061 //////////////////////////////////////////////
1062 8 OperationSizeofType::OperationSizeofType(
1063 const Gyoji::context::SourceReference & _src_ref,
1064 size_t _result,
1065 const Type *_type
1066 8 )
1067 : Operation(OP_SIZEOF_TYPE, _src_ref, _result)
1068 8 , type(_type)
1069 8 {}
1070 32 OperationSizeofType::~OperationSizeofType()
1071 32 {}
1072
1073 const Type *
1074 8 OperationSizeofType::get_type() const
1075 8 { return type; }
1076
1077