GCC Code Coverage Report


Directory: src/
File: src/mir/type.cpp
Date: 2025-10-15 09:43:47
Exec Total Coverage
Lines: 201 212 94.8%
Functions: 38 40 95.0%
Branches: 110 115 95.7%

Line Branch Exec Source
1 #include <gyoji-mir/types.hpp>
2 #include <variant>
3 #include <stdio.h>
4 #include <gyoji-misc/jstring.hpp>
5
6 using namespace Gyoji::context;
7 using namespace Gyoji::mir;
8
9 ////////////////////////////////////////
10 // Type
11 ////////////////////////////////////////
12 598 Type::Type(
13 std::string _name,
14 TypeType _type,
15 bool _complete,
16 const SourceReference & _source_ref
17 598 )
18 598 : name(_name)
19 598 , type(_type)
20 598 , complete(_complete)
21 598 , declared_source_ref(&_source_ref)
22 598 , defined_source_ref(&_source_ref)
23 598 , pointer_or_ref(nullptr)
24 598 , array_length(1)
25 598 , return_type(nullptr)
26 598 , argument_types()
27 598 , members()
28 598 {}
29 6 Type::Type(std::string _name, const SourceReference & _source_ref, const Type & _other)
30 6 : name(_name)
31 6 , type(_other.type)
32 6 , complete(_other.complete)
33 6 , declared_source_ref(&_source_ref)
34 6 , defined_source_ref(&_source_ref)
35 6 , pointer_or_ref(_other.pointer_or_ref)
36 6 , array_length(_other.array_length)
37 6 , return_type(_other.return_type)
38 6 , argument_types(_other.argument_types)
39 6 , members(_other.members)
40 {
41 6 }
42
43 604 Type::~Type()
44 604 {}
45
46 bool
47 1488 Type::is_complete() const
48 1488 { return complete; }
49
50 bool
51 1150 Type::is_primitive() const
52 {
53 return
54 2238 (type == TYPE_PRIMITIVE_u8) ||
55
2/2
✓ Branch 0 taken 1026 times.
✓ Branch 1 taken 62 times.
1088 (type == TYPE_PRIMITIVE_u16) ||
56
2/2
✓ Branch 0 taken 964 times.
✓ Branch 1 taken 62 times.
1026 (type == TYPE_PRIMITIVE_u32) ||
57
2/2
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 62 times.
964 (type == TYPE_PRIMITIVE_u64) ||
58
59
2/2
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 62 times.
902 (type == TYPE_PRIMITIVE_i8) ||
60
2/2
✓ Branch 0 taken 778 times.
✓ Branch 1 taken 62 times.
840 (type == TYPE_PRIMITIVE_i16) ||
61
2/2
✓ Branch 0 taken 716 times.
✓ Branch 1 taken 62 times.
778 (type == TYPE_PRIMITIVE_i32) ||
62
2/2
✓ Branch 0 taken 654 times.
✓ Branch 1 taken 62 times.
716 (type == TYPE_PRIMITIVE_i64) ||
63
64
2/2
✓ Branch 0 taken 592 times.
✓ Branch 1 taken 62 times.
654 (type == TYPE_PRIMITIVE_f32) ||
65
2/2
✓ Branch 0 taken 530 times.
✓ Branch 1 taken 62 times.
592 (type == TYPE_PRIMITIVE_f64) ||
66
67
4/4
✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 468 times.
✓ Branch 3 taken 62 times.
2706 (type == TYPE_PRIMITIVE_bool) ||
68
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 406 times.
1618 (type == TYPE_PRIMITIVE_void)
69 ;
70 }
71
72 bool
73 474 Type::is_pointer() const
74 474 { return (type == TYPE_POINTER); }
75
76 bool
77 322 Type::is_reference() const
78 322 { return (type == TYPE_REFERENCE); }
79
80 bool
81 1032 Type::is_numeric() const
82 {
83 return
84 1988 (type == TYPE_PRIMITIVE_u8) ||
85
2/2
✓ Branch 0 taken 828 times.
✓ Branch 1 taken 128 times.
956 (type == TYPE_PRIMITIVE_u16) ||
86
2/2
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 176 times.
828 (type == TYPE_PRIMITIVE_u32) ||
87
2/2
✓ Branch 0 taken 564 times.
✓ Branch 1 taken 88 times.
652 (type == TYPE_PRIMITIVE_u64) ||
88
89
2/2
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 76 times.
564 (type == TYPE_PRIMITIVE_i8) ||
90
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 128 times.
488 (type == TYPE_PRIMITIVE_i16) ||
91
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 128 times.
360 (type == TYPE_PRIMITIVE_i32) ||
92
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 88 times.
232 (type == TYPE_PRIMITIVE_i64) ||
93
94
4/4
✓ Branch 0 taken 956 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 64 times.
2068 (type == TYPE_PRIMITIVE_f32) ||
95
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
1112 (type == TYPE_PRIMITIVE_f64);
96 }
97
98 bool
99 1508 Type::is_integer() const
100 {
101 return
102 2916 (type == TYPE_PRIMITIVE_u8) ||
103
2/2
✓ Branch 0 taken 1198 times.
✓ Branch 1 taken 210 times.
1408 (type == TYPE_PRIMITIVE_u16) ||
104
2/2
✓ Branch 0 taken 924 times.
✓ Branch 1 taken 274 times.
1198 (type == TYPE_PRIMITIVE_u32) ||
105
2/2
✓ Branch 0 taken 764 times.
✓ Branch 1 taken 160 times.
924 (type == TYPE_PRIMITIVE_u64) ||
106
107
2/2
✓ Branch 0 taken 664 times.
✓ Branch 1 taken 100 times.
764 (type == TYPE_PRIMITIVE_i8) ||
108
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 190 times.
664 (type == TYPE_PRIMITIVE_i16) ||
109
4/4
✓ Branch 0 taken 1408 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 284 times.
✓ Branch 3 taken 190 times.
3200 (type == TYPE_PRIMITIVE_i32) ||
110
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 144 times.
1792 (type == TYPE_PRIMITIVE_i64);
111 }
112
113 bool
114 680 Type::is_signed() const
115 {
116 return
117 1292 (type == TYPE_PRIMITIVE_i8) ||
118
2/2
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 124 times.
612 (type == TYPE_PRIMITIVE_i16) ||
119
4/4
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 364 times.
✓ Branch 3 taken 124 times.
1656 (type == TYPE_PRIMITIVE_i32) ||
120
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 280 times.
1044 (type == TYPE_PRIMITIVE_i64);
121 }
122
123 bool
124 380 Type::is_unsigned() const
125 {
126 return
127 712 (type == TYPE_PRIMITIVE_u8) ||
128
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 104 times.
332 (type == TYPE_PRIMITIVE_u16) ||
129
4/4
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 132 times.
808 (type == TYPE_PRIMITIVE_u32) ||
130
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 12 times.
476 (type == TYPE_PRIMITIVE_u64);
131 }
132
133 bool
134 258 Type::is_float() const
135 {
136 return
137
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 46 times.
470 (type == TYPE_PRIMITIVE_f32) ||
138
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 122 times.
470 (type == TYPE_PRIMITIVE_f64);
139 }
140
141 bool
142 38 Type::is_bool() const
143 {
144 return
145 38 (type == TYPE_PRIMITIVE_bool);
146 }
147
148 bool
149 460 Type::is_void() const
150 {
151 return
152 460 (type == TYPE_PRIMITIVE_void);
153 }
154 bool
155 308 Type::is_enum() const
156 308 { return (type == TYPE_ENUM); }
157
158 bool
159 1252 Type::is_composite() const
160 1252 { return (type == TYPE_COMPOSITE); }
161
162 bool
163 240 Type::is_function_pointer() const
164 240 { return (type == TYPE_FUNCTION_POINTER); }
165
166 bool
167 14 Type::is_array() const
168 14 { return (type == TYPE_ARRAY); }
169
170 size_t
171 840 Type::get_primitive_size() const
172 {
173
4/5
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 200 times.
✓ Branch 2 taken 304 times.
✓ Branch 3 taken 196 times.
✗ Branch 4 not taken.
840 switch (type) {
174 140 case TYPE_PRIMITIVE_u8:
175 case TYPE_PRIMITIVE_i8:
176 140 return 1;
177 200 case TYPE_PRIMITIVE_u16:
178 case TYPE_PRIMITIVE_i16:
179 200 return 2;
180 304 case TYPE_PRIMITIVE_u32:
181 case TYPE_PRIMITIVE_i32:
182 case TYPE_PRIMITIVE_f32:
183 304 return 4;
184 196 case TYPE_PRIMITIVE_u64:
185 case TYPE_PRIMITIVE_i64:
186 case TYPE_PRIMITIVE_f64:
187 196 return 8;
188 default:
189 fprintf(stderr, "Compiler Bug! This function should only be called for integer and floating-point types\n");
190 exit(1);
191 }
192 return 0;
193
194 }
195
196
197 Type::TypeType
198 1972 Type::get_type() const
199 1972 { return type; }
200 const std::string &
201 13806 Type::get_name() const
202 13806 { return name; }
203
204 const std::vector<TypeMember> &
205 8 Type::get_members() const
206 8 { return members; }
207
208 const std::map<std::string, TypeMethod> &
209 4 Type::get_methods() const
210 4 { return methods; }
211
212 const TypeMember *
213 24 Type::member_get(const std::string & member_name) const
214 {
215 24 const auto it = members_by_name.find(member_name);
216
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
24 if (it == members_by_name.end()) {
217 return nullptr;
218 }
219 24 return it->second;
220 }
221
222 const Type *
223 110 Type::get_pointer_target() const
224 110 { return pointer_or_ref; }
225
226 size_t
227 2 Type::get_array_length() const
228 2 { return array_length; }
229
230 const Type*
231 184 Type::get_return_type() const
232 184 { return return_type; }
233
234 const std::vector<Argument> &
235 382 Type::get_argument_types() const
236 {
237 382 return argument_types;
238 }
239
240
241 void
242 76 Type::complete_pointer_definition(const Type *_type, const SourceReference & _source_ref)
243 {
244 76 complete = true;
245 76 pointer_or_ref = _type;
246 76 defined_source_ref = &_source_ref;
247 76 }
248
249 void
250 2 Type::complete_array_definition(const Type *_type, size_t _array_length, const Gyoji::context::SourceReference & _source_ref)
251 {
252 2 complete = true;
253 2 pointer_or_ref = _type;
254 2 array_length = _array_length;
255 2 defined_source_ref = &_source_ref;
256 2 }
257
258 void
259 16 Type::complete_composite_definition(
260 std::vector<TypeMember> _members,
261 std::map<std::string, TypeMethod> _methods,
262 const SourceReference & _source_ref)
263 {
264 16 complete = true;
265 16 members = _members;
266 16 methods = _methods;
267
2/2
✓ Branch 4 taken 42 times.
✓ Branch 5 taken 16 times.
58 for (const TypeMember & member : members) {
268 42 members_by_name.insert(std::pair(member.get_name(), &member));
269 }
270 16 defined_source_ref = &_source_ref;
271 16 }
272
273 void
274 118 Type::complete_function_pointer_definition(
275 const Type *_return_type,
276 const std::vector<Argument> & _argument_types,
277 const Gyoji::context::SourceReference & _source_ref
278 )
279 {
280 118 complete = true;
281 118 return_type = _return_type;
282 118 argument_types = _argument_types;
283 118 defined_source_ref = &_source_ref;
284 118 }
285
286 const SourceReference &
287 Type::get_declared_source_ref() const
288 { return *declared_source_ref; }
289
290 const SourceReference &
291 2 Type::get_defined_source_ref() const
292 2 { return *defined_source_ref; }
293
294 void
295 604 Type::dump(FILE *out) const
296 {
297 604 std::string type_desc("unknown");
298
299
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 602 times.
604 if (!is_complete()) {
300 4 type_desc = std::string("class (forward declaration)");
301 }
302
2/2
✓ Branch 1 taken 384 times.
✓ Branch 2 taken 218 times.
602 else if (is_primitive()) {
303 768 type_desc = std::string("primitive");
304 }
305
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 202 times.
218 else if (type == TYPE_COMPOSITE) {
306 32 type_desc = std::string("class");
307 }
308
2/2
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 126 times.
202 else if (is_pointer()) {
309 76 type_desc = std::string("pointer");
310 228 type_desc += std::string(" to ") + pointer_or_ref->get_name();
311 }
312
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 120 times.
126 else if (is_reference()) {
313 6 type_desc = std::string("reference");
314 18 type_desc += std::string(" to ") + pointer_or_ref->get_name();
315 }
316
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
120 else if (is_enum()) {
317 type_desc = std::string("enum");
318 }
319
2/2
✓ Branch 1 taken 118 times.
✓ Branch 2 taken 2 times.
120 else if (is_function_pointer()) {
320 118 std::string desc;
321 118 desc = desc + return_type->get_name();
322 118 std::vector<std::string> arglist;
323
2/2
✓ Branch 5 taken 190 times.
✓ Branch 6 taken 118 times.
308 for (const Argument & arg : argument_types) {
324 190 arglist.push_back(arg.get_type()->get_name());
325 }
326 236 desc = desc + std::string("(*)");
327 708 desc = desc + std::string("(") + Gyoji::misc::join(arglist, ",") + std::string(")");
328 118 type_desc = std::string("function-pointer ") + desc;
329 118 }
330
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 else if (is_array()) {
331 4 type_desc = std::string("array ");
332 8 type_desc += pointer_or_ref->get_name() + std::string("[") + std::to_string(array_length) + std::string("]");
333 }
334 else {
335 fprintf(stderr, "Compiler Bug! Unknown type of type when dumping types.\n");
336 exit(1);
337 }
338
339
340
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 586 times.
604 if (is_composite()) {
341 18 fprintf(out, " %s : %s {\n", name.c_str(), type_desc.c_str());
342
2/2
✓ Branch 5 taken 42 times.
✓ Branch 6 taken 18 times.
60 for (const auto & m : members) {
343 42 fprintf(out, " %s : %s\n", m.get_name().c_str(), m.get_type()->get_name().c_str());
344 }
345
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 18 times.
20 for (const auto & m : methods) {
346 2 fprintf(out, " %s : %s\n", m.first.c_str(), m.second.get_class_type()->get_name().c_str());
347 2 fprintf(out, " ret %s\n", m.second.get_return_type()->get_name().c_str());
348
2/2
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 2 times.
6 for (const auto & arg : m.second.get_arguments()) {
349 4 fprintf(out, " arg %s\n", arg.get_type()->get_name().c_str());
350 }
351 }
352 18 fprintf(out, " }\n");
353 }
354 else {
355 586 fprintf(out, " %s : %s\n", name.c_str(), type_desc.c_str());
356 }
357 604 }
358
359
360 /////////////////////////
361 // Argument
362 /////////////////////////
363 562 Argument::Argument(
364 const Type *_argument_type,
365 const Gyoji::context::SourceReference & _source_ref
366 562 )
367 562 : argument_type(_argument_type)
368 562 , source_ref(&_source_ref)
369 562 {}
370 1042 Argument::Argument(const Argument & _other)
371 1042 : argument_type(_other.argument_type)
372 1042 , source_ref(_other.source_ref)
373 1042 {}
374 1604 Argument::~Argument()
375 1604 {}
376 const Type*
377 904 Argument::get_type() const
378 904 { return argument_type; }
379
380 const Gyoji::context::SourceReference &
381 Argument::get_source_ref() const
382 { return *source_ref; }
383
384