GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 98.1% 254 / 1 / 260
Functions: 97.8% 45 / 0 / 46
Branches: 59.2% 297 / 6 / 508

src/symboltablebuilder/Type.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "Type.h"
4
5 #include <utility>
6
7 #include <SourceFile.h>
8 #include <ast/Attributes.h>
9 #include <driver/Driver.h>
10 #include <exception/CompilerError.h>
11 #include <exception/SemanticError.h>
12 #include <global/GlobalResourceManager.h>
13 #include <global/TypeRegistry.h>
14 #include <irgenerator/NameMangling.h>
15 #include <model/Struct.h>
16 #include <model/Union.h>
17 #include <symboltablebuilder/Scope.h>
18 #include <symboltablebuilder/SymbolTableEntry.h>
19
20 #include <llvm/IR/Module.h>
21 #include <llvm/IR/Type.h>
22
23 namespace spice::compiler {
24
25
3/10
✓ Branch 5 → 6 taken 10087506 times.
✗ Branch 5 → 11 not taken.
✓ Branch 7 → 8 taken 10087506 times.
✓ Branch 7 → 9 taken 10087506 times.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 14 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 19 not taken.
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
30262518 Type::Type(SuperType superType) : typeChain({TypeChainElement{superType}}) {}
26
27
4/12
✓ Branch 4 → 5 taken 12457 times.
✗ Branch 4 → 19 not taken.
✓ Branch 6 → 7 taken 12457 times.
✗ Branch 6 → 13 not taken.
✓ Branch 8 → 9 taken 12457 times.
✓ Branch 8 → 10 taken 12457 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
37371 Type::Type(SuperType superType, const std::string &subType) : typeChain({TypeChainElement{superType, subType}}) {}
28
29 14309 Type::Type(SuperType superType, const std::string &subType, uint64_t typeId, const TypeChainElementData &data,
30 const QualTypeList &templateTypes)
31
5/14
✓ Branch 4 → 5 taken 14309 times.
✗ Branch 4 → 24 not taken.
✓ Branch 5 → 6 taken 14309 times.
✗ Branch 5 → 21 not taken.
✓ Branch 7 → 8 taken 14309 times.
✗ Branch 7 → 15 not taken.
✓ Branch 9 → 10 taken 14309 times.
✓ Branch 9 → 11 taken 14309 times.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 29 not taken.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
42927 : typeChain({TypeChainElement(superType, subType, typeId, data, templateTypes)}) {}
32
33 42241116 Type::Type(TypeChain typeChain) : typeChain(std::move(typeChain)) {}
34
35 /**
36 * Get the super type of the current type
37 *
38 * @return Super type
39 */
40 105934167 SuperType Type::getSuperType() const {
41
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 105934167 times.
105934167 assert(!typeChain.empty());
42 105934167 return typeChain.back().superType;
43 }
44
45 /**
46 * Get the sub type of the current type
47 *
48 * @return Sub type
49 */
50 2377177 const std::string &Type::getSubType() const {
51
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2377177 times.
2377177 assert(!typeChain.empty());
52
2/4
✓ Branch 5 → 6 taken 2377177 times.
✗ Branch 5 → 11 not taken.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 2377177 times.
2377177 assert(isOneOf({TY_STRUCT, TY_INTERFACE, TY_UNION, TY_ENUM, TY_GENERIC}));
53 2377177 return typeChain.back().subType;
54 }
55
56 /**
57 * Get the array size of the current type
58 *
59 * @return Array size
60 */
61 12220 unsigned int Type::getArraySize() const {
62
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 12220 times.
12220 assert(isArray());
63 12220 return typeChain.back().data.arraySize;
64 }
65
66 /**
67 * Get the body scope of the current type
68 *
69 * @return Body scope
70 */
71 8740470 Scope *Type::getBodyScope() const {
72
2/4
✓ Branch 2 → 3 taken 8740470 times.
✗ Branch 2 → 8 not taken.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 8740470 times.
8740470 assert(isOneOf({TY_STRUCT, TY_INTERFACE, TY_UNION}));
73 8740470 return typeChain.back().data.bodyScope;
74 }
75
76 /**
77 * Get the return type of function type
78 *
79 * @return Function return type
80 */
81 156 const QualType &Type::getFunctionReturnType() const {
82
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 156 times.
156 assert(is(TY_FUNCTION));
83
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 156 times.
156 assert(!typeChain.front().paramTypes.empty());
84 156 return typeChain.front().paramTypes.front();
85 }
86
87 /**
88 * Get the param types of a function or procedure type
89 *
90 * @return Function param types
91 */
92 824 QualTypeList Type::getFunctionParamTypes() const {
93
2/4
✓ Branch 2 → 3 taken 824 times.
✗ Branch 2 → 23 not taken.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 824 times.
824 assert(isOneOf({TY_FUNCTION, TY_PROCEDURE}));
94
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 824 times.
824 if (typeChain.front().paramTypes.empty())
95 return {};
96
1/2
✓ Branch 18 → 19 taken 824 times.
✗ Branch 18 → 24 not taken.
3296 return {typeChain.front().paramTypes.begin() + 1, typeChain.front().paramTypes.end()};
97 }
98
99 /**
100 * Get the param and return types of a function or procedure base type
101 *
102 * @return Function param and return types (first is return type, rest are param types)
103 */
104 11094 const QualTypeList &Type::getFunctionParamAndReturnTypes() const {
105
2/4
✓ Branch 3 → 4 taken 11094 times.
✗ Branch 3 → 9 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 11094 times.
11094 assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE}));
106 11094 return typeChain.front().paramTypes;
107 }
108
109 /**
110 * Check if a function or procedure type has captures
111 *
112 * @return Has captures
113 */
114 730 bool Type::hasLambdaCaptures() const {
115
2/4
✓ Branch 3 → 4 taken 730 times.
✗ Branch 3 → 9 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 730 times.
730 assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE}));
116 730 return typeChain.front().data.hasCaptures;
117 }
118
119 /**
120 * Retrieve template types of the current type
121 *
122 * @return Vector of template types
123 */
124 4126847 const QualTypeList &Type::getTemplateTypes() const { return typeChain.back().templateTypes; }
125
126 /**
127 * Get the type chain depth of the current type
128 *
129 * @return Type chain depth
130 */
131 size_t Type::getTypeChainDepth() const { return typeChain.size(); }
132
133 /**
134 * Check if the current type is of a certain super type
135 *
136 * @return Applicable or not
137 */
138 81470359 bool Type::is(SuperType superType) const { return getSuperType() == superType; }
139
140 /**
141 * Check if the current type is one of a list of super types
142 *
143 * @return Applicable or not
144 */
145 22165352 bool Type::isOneOf(const std::initializer_list<SuperType> &superTypes) const {
146 63734253 return std::ranges::any_of(superTypes, [this](SuperType superType) { return is(superType); });
147 }
148
149 /**
150 * Check if the base type of the current type chain is of a certain super type
151 *
152 * @param superType Super type to check for
153 * @return Applicable or not
154 */
155 41469105 bool Type::isBase(SuperType superType) const {
156
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 41469105 times.
41469105 assert(!typeChain.empty());
157 41469105 return typeChain.front().superType == superType;
158 }
159
160 /**
161 * Check if the current type is a primitive type
162 *
163 * @return Primitive type or not
164 */
165
1/2
✓ Branch 2 → 3 taken 1129782 times.
✗ Branch 2 → 6 not taken.
1129782 bool Type::isPrimitive() const { return isOneOf({TY_DOUBLE, TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_CHAR, TY_STRING, TY_BOOL}); }
166
167 /**
168 * Check if the type is an extended primitive type
169 * The definition of extended primitive types contains all primitive types plus the following:
170 * - structs
171 * - interfaces
172 * - functions/procedures
173 *
174 * @return Extended primitive or not
175 */
176 863405 bool Type::isExtendedPrimitive() const {
177
6/8
✓ Branch 2 → 3 taken 863405 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 321634 times.
✓ Branch 3 → 6 taken 541771 times.
✓ Branch 4 → 5 taken 321634 times.
✗ Branch 4 → 10 not taken.
✓ Branch 5 → 6 taken 243673 times.
✓ Branch 5 → 7 taken 77961 times.
863405 return isPrimitive() || isOneOf({TY_STRUCT, TY_INTERFACE, TY_UNION, TY_FUNCTION, TY_PROCEDURE});
178 }
179
180 /**
181 * Check if the current type is a pointer type
182 *
183 * @return Pointer type or not
184 */
185 4082767 bool Type::isPtr() const { return getSuperType() == TY_PTR; }
186
187 /**
188 * Check if the current type is a reference type
189 *
190 * @return Reference type or not
191 */
192 8795544 bool Type::isRef() const { return getSuperType() == TY_REF; }
193
194 /**
195 * Check if the current type is an array type
196 *
197 * @return Array type or not
198 */
199 2356325 bool Type::isArray() const { return getSuperType() == TY_ARRAY; }
200
201 /**
202 * Checks if the base type is generic itself or has generic parts in its template types
203 *
204 * @return Contains generic parts or not
205 */
206 3397367 bool Type::hasAnyGenericParts() const { // NOLINT(misc-no-recursion)
207
1/2
✓ Branch 2 → 3 taken 3397367 times.
✗ Branch 2 → 34 not taken.
3397367 const Type *baseType = getBase();
208
209 // Check if the type itself is generic
210
2/2
✓ Branch 4 → 5 taken 549569 times.
✓ Branch 4 → 6 taken 2847798 times.
3397367 if (baseType->is(TY_GENERIC))
211 549569 return true;
212
213 // Check if the type has generic template types
214
1/2
✓ Branch 7 → 8 taken 2847798 times.
✗ Branch 7 → 34 not taken.
2847798 const auto templateTypes = baseType->getTemplateTypes();
215
3/4
✓ Branch 8 → 9 taken 2847798 times.
✗ Branch 8 → 32 not taken.
✓ Branch 9 → 10 taken 234881 times.
✓ Branch 9 → 11 taken 2612917 times.
3488344 if (std::ranges::any_of(templateTypes, [](const QualType &t) { return t.hasAnyGenericParts(); }))
216 234881 return true;
217
218 // Check param and return types or functions/procedures
219
3/4
✓ Branch 11 → 12 taken 2612917 times.
✗ Branch 11 → 28 not taken.
✓ Branch 12 → 13 taken 10265 times.
✓ Branch 12 → 24 taken 2602652 times.
2612917 if (baseType->isOneOf({TY_FUNCTION, TY_PROCEDURE})) {
220
2/4
✓ Branch 13 → 14 taken 10265 times.
✗ Branch 13 → 31 not taken.
✓ Branch 14 → 15 taken 10265 times.
✗ Branch 14 → 31 not taken.
10265 const auto paramTypes = baseType->getFunctionParamAndReturnTypes();
221
3/4
✓ Branch 15 → 16 taken 10265 times.
✗ Branch 15 → 29 not taken.
✓ Branch 16 → 17 taken 446 times.
✓ Branch 16 → 18 taken 9819 times.
28475 if (std::ranges::any_of(paramTypes, [](const QualType &t) { return t.hasAnyGenericParts(); }))
222 446 return true;
223
2/2
✓ Branch 20 → 21 taken 9819 times.
✓ Branch 20 → 23 taken 446 times.
10265 }
224
225 2612471 return false; // Does not have generic parts
226 2847798 }
227
228 /**
229 * Check if the current type is of the same container type like the other type.
230 * Only TY_PTR, TY_REF and TY_ARRAY are considered as container types.
231 *
232 * @param other Other symbol type
233 * @return Same container type or not
234 */
235 891429 bool Type::isSameContainerTypeAs(const Type *other) const {
236
4/4
✓ Branch 3 → 4 taken 31372 times.
✓ Branch 3 → 7 taken 860057 times.
✓ Branch 5 → 6 taken 28861 times.
✓ Branch 5 → 7 taken 2511 times.
891429 const bool bothPtr = isPtr() && other->isPtr();
237
4/4
✓ Branch 9 → 10 taken 56415 times.
✓ Branch 9 → 13 taken 835014 times.
✓ Branch 11 → 12 taken 42081 times.
✓ Branch 11 → 13 taken 14334 times.
891429 const bool bothRef = isRef() && other->isRef();
238
3/4
✓ Branch 15 → 16 taken 856 times.
✓ Branch 15 → 19 taken 890573 times.
✓ Branch 17 → 18 taken 856 times.
✗ Branch 17 → 19 not taken.
891429 const bool bothArray = isArray() && other->isArray();
239
6/6
✓ Branch 20 → 21 taken 862568 times.
✓ Branch 20 → 23 taken 28861 times.
✓ Branch 21 → 22 taken 820487 times.
✓ Branch 21 → 23 taken 42081 times.
✓ Branch 22 → 23 taken 856 times.
✓ Branch 22 → 24 taken 819631 times.
891429 return bothPtr || bothRef || bothArray;
240 }
241
242 /**
243 * Check for the matching compatibility of two types.
244 * Useful for struct and function matching as well as assignment type validation and function arg matching.
245 *
246 * @param otherType Type to compare against
247 * @param ignoreArraySize Ignore array sizes
248 * @return Matching or not
249 */
250 1028944 bool Type::matches(const Type *otherType, bool ignoreArraySize) const {
251 // If the size does not match, it is not equal
252
2/2
✓ Branch 4 → 5 taken 121338 times.
✓ Branch 4 → 6 taken 907606 times.
1028944 if (typeChain.size() != otherType->typeChain.size())
253 121338 return false;
254
255 // Compare the elements
256
2/2
✓ Branch 18 → 7 taken 1009736 times.
✓ Branch 18 → 19 taken 609912 times.
1619648 for (size_t i = 0; i < typeChain.size(); i++) {
257 1009736 const TypeChainElement &lhsElement = typeChain.at(i);
258 1009736 const TypeChainElement &rhsElement = otherType->typeChain.at(i);
259
260 // Ignore differences in array size
261
5/6
✓ Branch 9 → 10 taken 612501 times.
✓ Branch 9 → 13 taken 397235 times.
✓ Branch 10 → 11 taken 10 times.
✓ Branch 10 → 13 taken 612491 times.
✓ Branch 11 → 12 taken 10 times.
✗ Branch 11 → 13 not taken.
1009736 if (ignoreArraySize && lhsElement.superType == TY_ARRAY && rhsElement.superType == TY_ARRAY)
262 10 continue;
263
264 // Not both types are arrays -> compare them as usual
265
2/2
✓ Branch 14 → 15 taken 297694 times.
✓ Branch 14 → 16 taken 712032 times.
1009726 if (lhsElement != rhsElement)
266 297694 return false;
267 }
268
269 609912 return true;
270 }
271
272 /**
273 * Get the name of the symbol type as a string
274 *
275 * @param name Get name of type
276 * @param withSize Include the array size for sized types
277 * @param ignorePublic Ignore any potential public qualifier
278 * @param withAliases Print aliases as is and not decompose them
279 * @return Symbol type name
280 */
281 5494972 void Type::getName(std::stringstream &name, bool withSize, bool ignorePublic, bool withAliases) const {
282 // Loop through all chain elements
283
2/2
✓ Branch 18 → 4 taken 7208570 times.
✓ Branch 18 → 19 taken 5494972 times.
18198514 for (const TypeChainElement &chainElement : typeChain)
284
2/4
✓ Branch 6 → 7 taken 7208570 times.
✗ Branch 6 → 22 not taken.
✓ Branch 7 → 8 taken 7208570 times.
✗ Branch 7 → 20 not taken.
7208570 name << chainElement.getName(withSize, ignorePublic, withAliases);
285 5494972 }
286
287 /**
288 * Get the name of the symbol type as a string
289 *
290 * @param withSize Include the array size for sized types
291 * @param ignorePublic Ignore any potential public qualifier
292 * @param withAliases Print aliases as is and not decompose them
293 * @return Symbol type name
294 */
295 119301 std::string Type::getName(bool withSize, bool ignorePublic, bool withAliases) const {
296
1/2
✓ Branch 2 → 3 taken 119301 times.
✗ Branch 2 → 11 not taken.
119301 std::stringstream name;
297
1/2
✓ Branch 3 → 4 taken 119301 times.
✗ Branch 3 → 9 not taken.
119301 getName(name, withSize, ignorePublic, withAliases);
298
1/2
✓ Branch 4 → 5 taken 119301 times.
✗ Branch 4 → 9 not taken.
238602 return name.str();
299 119301 }
300
301 /**
302 * Get the pointer type of the current type as a new type
303 *
304 * @param node AST node for error messages
305 * @return Pointer type of the current type
306 */
307 247475 const Type *Type::toPtr(const ASTNode *node) const {
308
2/2
✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 12 taken 247471 times.
247475 if (is(TY_DYN))
309
2/4
✓ Branch 7 → 8 taken 4 times.
✗ Branch 7 → 32 not taken.
✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 29 not taken.
12 throw SemanticError(node, DYN_POINTERS_NOT_ALLOWED, "Just use the dyn type without '*' instead");
310
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 22 taken 247471 times.
247471 if (isRef())
311 throw SemanticError(node, REF_POINTERS_ARE_NOT_ALLOWED, "Pointers to references are not allowed. Use pointer instead");
312
313 // Create new type chain
314
1/2
✓ Branch 22 → 23 taken 247471 times.
✗ Branch 22 → 50 not taken.
247471 TypeChain newTypeChain = typeChain;
315
1/2
✓ Branch 23 → 24 taken 247471 times.
✗ Branch 23 → 47 not taken.
247471 newTypeChain.emplace_back(TY_PTR);
316
317 // Register new type or return if already registered
318
1/2
✓ Branch 24 → 25 taken 247471 times.
✗ Branch 24 → 48 not taken.
494942 return TypeRegistry::getOrInsert(newTypeChain);
319 247471 }
320
321 /**
322 * Get the reference type of the current type as a new type
323 *
324 * @param node AST node for error messages
325 * @return Reference type of the current type
326 */
327 115401 const Type *Type::toRef(const ASTNode *node) const {
328
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 12 taken 115401 times.
115401 if (is(TY_DYN))
329 throw SemanticError(node, DYN_REFERENCES_NOT_ALLOWED, "Just use the dyn type without '&' instead");
330
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 22 taken 115401 times.
115401 if (isRef())
331 throw SemanticError(node, MULTI_REF_NOT_ALLOWED, "References to references are not allowed");
332
333 // Create new type chain
334
1/2
✓ Branch 22 → 23 taken 115401 times.
✗ Branch 22 → 50 not taken.
115401 TypeChain newTypeChain = typeChain;
335
1/2
✓ Branch 23 → 24 taken 115401 times.
✗ Branch 23 → 47 not taken.
115401 newTypeChain.emplace_back(TY_REF);
336
337 // Register new type or return if already registered
338
1/2
✓ Branch 24 → 25 taken 115401 times.
✗ Branch 24 → 48 not taken.
230802 return TypeRegistry::getOrInsert(newTypeChain);
339 115401 }
340
341 /**
342 * Get the array type of the current type as a new type
343 *
344 * @param node AST node for error messages
345 * @param size Size of the array
346 * @param skipDynCheck Skip check if array base type is dyn
347 * @return Array type of the current type
348 */
349 1889 const Type *Type::toArr(const ASTNode *node, unsigned int size, bool skipDynCheck) const {
350
6/6
✓ Branch 2 → 3 taken 1221 times.
✓ Branch 2 → 6 taken 668 times.
✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 6 taken 1219 times.
✓ Branch 7 → 8 taken 2 times.
✓ Branch 7 → 16 taken 1887 times.
1889 if (!skipDynCheck && typeChain.back().superType == TY_DYN)
351
2/4
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 26 not taken.
✓ Branch 12 → 13 taken 2 times.
✗ Branch 12 → 23 not taken.
6 throw SemanticError(node, DYN_ARRAYS_NOT_ALLOWED, "Just use the dyn type without '[]' instead");
352
353 // Create new type chain
354
1/2
✓ Branch 16 → 17 taken 1887 times.
✗ Branch 16 → 36 not taken.
1887 TypeChain newTypeChain = typeChain;
355
1/2
✓ Branch 17 → 18 taken 1887 times.
✗ Branch 17 → 32 not taken.
1887 newTypeChain.emplace_back(TY_ARRAY, TypeChainElementData{.arraySize = size});
356
357 // Register new type or return if already registered
358
1/2
✓ Branch 18 → 19 taken 1887 times.
✗ Branch 18 → 34 not taken.
3774 return TypeRegistry::getOrInsert(newTypeChain);
359 1887 }
360
361 /**
362 * Retrieve the base type of an array or a pointer
363 *
364 * @return Base type
365 */
366 1442256 const Type *Type::getContained() const {
367
2/2
✓ Branch 3 → 4 taken 3456 times.
✓ Branch 3 → 6 taken 1438800 times.
1442256 if (is(TY_STRING))
368
1/2
✓ Branch 4 → 5 taken 3456 times.
✗ Branch 4 → 18 not taken.
3456 return TypeRegistry::getOrInsert(TY_CHAR);
369
370 // Create new type chain
371
1/2
✓ Branch 6 → 7 taken 1438800 times.
✗ Branch 6 → 18 not taken.
1438800 TypeChain newTypeChain = typeChain;
372
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 1438800 times.
1438800 assert(newTypeChain.size() > 1);
373 1438800 newTypeChain.pop_back();
374
375 // Register new type or return if already registered
376
1/2
✓ Branch 11 → 12 taken 1438800 times.
✗ Branch 11 → 16 not taken.
1438800 return TypeRegistry::getOrInsert(newTypeChain);
377 1438800 }
378
379 /**
380 * Replace the base type with another one
381 *
382 * @param newBaseType New base type
383 * @return The new type
384 */
385 156928 const Type *Type::replaceBase(const Type *newBaseType) const {
386
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 156928 times.
156928 assert(!typeChain.empty());
387
388 // Create new type
389
1/2
✓ Branch 5 → 6 taken 156928 times.
✗ Branch 5 → 27 not taken.
156928 TypeChain newTypeChain = newBaseType->typeChain;
390
4/4
✓ Branch 7 → 8 taken 7336 times.
✓ Branch 7 → 11 taken 149592 times.
✓ Branch 9 → 10 taken 144 times.
✓ Branch 9 → 11 taken 7192 times.
156928 const bool doubleRef = newTypeChain.back().superType == TY_REF && typeChain.back().superType == TY_REF;
391
2/2
✓ Branch 19 → 13 taken 19929 times.
✓ Branch 19 → 20 taken 156928 times.
176857 for (size_t i = 1; i < typeChain.size(); i++)
392
3/4
✓ Branch 13 → 14 taken 144 times.
✓ Branch 13 → 15 taken 19785 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 144 times.
19929 if (!doubleRef || i > 1)
393
2/4
✓ Branch 15 → 16 taken 19785 times.
✗ Branch 15 → 25 not taken.
✓ Branch 16 → 17 taken 19785 times.
✗ Branch 16 → 25 not taken.
19785 newTypeChain.push_back(typeChain.at(i));
394
395 // Register new type or return if already registered
396
1/2
✓ Branch 20 → 21 taken 156928 times.
✗ Branch 20 → 25 not taken.
313856 return TypeRegistry::getOrInsert(newTypeChain);
397 156928 }
398
399 /**
400 * Remove reference wrapper from the current type
401 *
402 * @return Type without reference wrapper
403 */
404
1/2
✓ Branch 3 → 4 taken 341560 times.
✗ Branch 3 → 6 not taken.
341560 const Type *Type::removeReferenceWrapper() const { return isRef() ? getContained() : this; }
405
406 /**
407 * Retrieve the base type of the current type
408 *
409 * @return Base type
410 */
411 18721837 const Type *Type::getBase() const {
412
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 18721837 times.
18721837 assert(!typeChain.empty());
413
414 // Create new type chain
415
3/6
✓ Branch 9 → 10 taken 18721837 times.
✗ Branch 9 → 19 not taken.
✓ Branch 12 → 13 taken 18721837 times.
✓ Branch 12 → 14 taken 18721837 times.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 25 not taken.
56165511 const TypeChain newTypeChain = {typeChain.front()};
416
417 // Register new type or return if already registered
418
1/2
✓ Branch 14 → 15 taken 18721837 times.
✗ Branch 14 → 32 not taken.
37443674 return TypeRegistry::getOrInsert(newTypeChain);
419
1/6
✓ Branch 6 → 7 taken 18721837 times.
✗ Branch 6 → 26 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 30 not taken.
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
37443674 }
420
421 /**
422 * Retrieve the same type, but with lambda captures
423 *
424 * @return Type with lambda captures
425 */
426 279 const Type *Type::getWithLambdaCaptures(bool enabled) const {
427
3/6
✓ Branch 2 → 3 taken 279 times.
✗ Branch 2 → 16 not taken.
✓ Branch 3 → 4 taken 279 times.
✗ Branch 3 → 13 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 279 times.
279 assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE}));
428
429 // Create new type chain
430
1/2
✓ Branch 6 → 7 taken 279 times.
✗ Branch 6 → 16 not taken.
279 TypeChain newTypeChain = typeChain;
431 279 newTypeChain.front().data.hasCaptures = enabled;
432
433 // Register new type or return if already registered
434
1/2
✓ Branch 8 → 9 taken 279 times.
✗ Branch 8 → 14 not taken.
558 return TypeRegistry::getOrInsert(newTypeChain);
435 279 }
436
437 /**
438 * Retrieve the same type, but with the body scope removed
439 *
440 * @return Type with body scope removed
441 */
442 257474 const Type *Type::getWithBodyScope(Scope *bodyScope) const {
443
3/6
✓ Branch 2 → 3 taken 257474 times.
✗ Branch 2 → 16 not taken.
✓ Branch 3 → 4 taken 257474 times.
✗ Branch 3 → 13 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 257474 times.
257474 assert(getBase()->isOneOf({TY_STRUCT, TY_INTERFACE, TY_UNION}));
444
445 // Create new type chain
446
1/2
✓ Branch 6 → 7 taken 257474 times.
✗ Branch 6 → 16 not taken.
257474 TypeChain newTypeChain = typeChain;
447 257474 newTypeChain.front().data.bodyScope = bodyScope;
448
449 // Register new type or return if already registered
450
1/2
✓ Branch 8 → 9 taken 257474 times.
✗ Branch 8 → 14 not taken.
514948 return TypeRegistry::getOrInsert(newTypeChain);
451 257474 }
452
453 /**
454 * Retrieve the same type, but with the given template types
455 *
456 * @return Type with new template types
457 */
458 36739 const Type *Type::getWithTemplateTypes(const QualTypeList &templateTypes) const {
459
2/4
✓ Branch 2 → 3 taken 36739 times.
✗ Branch 2 → 8 not taken.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 36739 times.
36739 assert(isOneOf({TY_STRUCT, TY_INTERFACE, TY_UNION}));
460 36739 return getWithBaseTemplateTypes(templateTypes);
461 }
462
463 /**
464 * Retrieve the same type, but with the given base template types
465 *
466 * @return Type with new base template types
467 */
468 84716 const Type *Type::getWithBaseTemplateTypes(const QualTypeList &templateTypes) const {
469
3/6
✓ Branch 2 → 3 taken 84716 times.
✗ Branch 2 → 17 not taken.
✓ Branch 3 → 4 taken 84716 times.
✗ Branch 3 → 14 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 84716 times.
84716 assert(getBase()->isOneOf({TY_STRUCT, TY_INTERFACE, TY_UNION}));
470
471 // Create new type chain
472
1/2
✓ Branch 6 → 7 taken 84716 times.
✗ Branch 6 → 17 not taken.
84716 TypeChain newTypeChain = typeChain;
473
1/2
✓ Branch 8 → 9 taken 84716 times.
✗ Branch 8 → 15 not taken.
84716 newTypeChain.front().templateTypes = templateTypes;
474
475 // Register new type or return if already registered
476
1/2
✓ Branch 9 → 10 taken 84716 times.
✗ Branch 9 → 15 not taken.
169432 return TypeRegistry::getOrInsert(newTypeChain);
477 84716 }
478
479 /**
480 * Retrieve the same type, but with the param and return types removed
481 *
482 * @return Type with param and return types removed
483 */
484 95765 const Type *Type::getWithFunctionParamAndReturnTypes(const QualTypeList &paramAndReturnTypes) const {
485
3/6
✓ Branch 2 → 3 taken 95765 times.
✗ Branch 2 → 17 not taken.
✓ Branch 3 → 4 taken 95765 times.
✗ Branch 3 → 14 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 95765 times.
95765 assert(getBase()->isOneOf({TY_FUNCTION, TY_PROCEDURE}));
486
487 // Create new type chain
488
1/2
✓ Branch 6 → 7 taken 95765 times.
✗ Branch 6 → 17 not taken.
95765 TypeChain newTypeChain = typeChain;
489
1/2
✓ Branch 8 → 9 taken 95765 times.
✗ Branch 8 → 15 not taken.
95765 newTypeChain.front().paramTypes = paramAndReturnTypes;
490
491 // Register new type or return if already registered
492
1/2
✓ Branch 9 → 10 taken 95765 times.
✗ Branch 9 → 15 not taken.
191530 return TypeRegistry::getOrInsert(newTypeChain);
493 95765 }
494
495 /**
496 * Return the LLVM type for this symbol type
497 *
498 * @param sourceFile Referenced source file
499 * @return Corresponding LLVM type
500 */
501 82721 llvm::Type *Type::toLLVMType(SourceFile *sourceFile) const { // NOLINT(misc-no-recursion)
502
2/4
✓ Branch 3 → 4 taken 82721 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 82721 times.
✗ Branch 5 → 7 not taken.
82721 assert(!typeChain.empty() && !is(TY_INVALID));
503
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 10 taken 82719 times.
82721 llvm::LLVMContext &context = sourceFile->cliOptions.useLTO ? sourceFile->resourceManager.ltoContext : sourceFile->context;
504
505
10/12
✓ Branch 11 → 12 taken 82721 times.
✗ Branch 11 → 222 not taken.
✓ Branch 12 → 13 taken 41596 times.
✓ Branch 12 → 17 taken 41125 times.
✓ Branch 14 → 15 taken 1029 times.
✓ Branch 14 → 18 taken 40567 times.
✓ Branch 15 → 16 taken 1029 times.
✗ Branch 15 → 222 not taken.
✓ Branch 16 → 17 taken 142 times.
✓ Branch 16 → 18 taken 887 times.
✓ Branch 19 → 20 taken 41267 times.
✓ Branch 19 → 22 taken 41454 times.
82721 if (isOneOf({TY_PTR, TY_REF, TY_STRING}) || (isArray() && getArraySize() == 0))
506 41267 return llvm::PointerType::get(context, 0);
507
508
2/2
✓ Branch 23 → 24 taken 887 times.
✓ Branch 23 → 32 taken 40567 times.
41454 if (isArray()) {
509
1/2
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 887 times.
887 assert(getArraySize() > 0);
510 887 llvm::Type *containedType = sourceFile->getLLVMType(getContained());
511 887 return llvm::ArrayType::get(containedType, getArraySize());
512 }
513
514
1/2
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 40567 times.
40567 assert(!hasAnyGenericParts());
515
516
2/2
✓ Branch 36 → 37 taken 469 times.
✓ Branch 36 → 39 taken 40098 times.
40567 if (is(TY_DOUBLE))
517 469 return llvm::Type::getDoubleTy(context);
518
519
3/4
✓ Branch 39 → 40 taken 40098 times.
✗ Branch 39 → 223 not taken.
✓ Branch 40 → 41 taken 3815 times.
✓ Branch 40 → 43 taken 36283 times.
40098 if (isOneOf({TY_INT, TY_ENUM}))
520 3815 return llvm::Type::getInt32Ty(context);
521
522
2/2
✓ Branch 44 → 45 taken 296 times.
✓ Branch 44 → 47 taken 35987 times.
36283 if (is(TY_SHORT))
523 296 return llvm::Type::getInt16Ty(context);
524
525
2/2
✓ Branch 48 → 49 taken 2540 times.
✓ Branch 48 → 51 taken 33447 times.
35987 if (is(TY_LONG))
526 2540 return llvm::Type::getInt64Ty(context);
527
528
3/4
✓ Branch 51 → 52 taken 33447 times.
✗ Branch 51 → 224 not taken.
✓ Branch 52 → 53 taken 3094 times.
✓ Branch 52 → 55 taken 30353 times.
33447 if (isOneOf({TY_CHAR, TY_BYTE}))
529 3094 return llvm::Type::getInt8Ty(context);
530
531
2/2
✓ Branch 56 → 57 taken 3427 times.
✓ Branch 56 → 59 taken 26926 times.
30353 if (is(TY_BOOL))
532 3427 return llvm::Type::getInt1Ty(context);
533
534
3/4
✓ Branch 59 → 60 taken 26926 times.
✗ Branch 59 → 225 not taken.
✓ Branch 60 → 61 taken 26202 times.
✓ Branch 60 → 153 taken 724 times.
26926 if (isOneOf({TY_STRUCT, TY_INTERFACE})) {
535
1/2
✓ Branch 61 → 62 taken 26202 times.
✗ Branch 61 → 254 not taken.
26202 const Scope *structBodyScope = getBodyScope();
536
2/4
✓ Branch 63 → 64 taken 26202 times.
✗ Branch 63 → 254 not taken.
✓ Branch 64 → 65 taken 26202 times.
✗ Branch 64 → 254 not taken.
26202 const std::string structSignature = Struct::getSignature(getSubType(), getTemplateTypes());
537
1/2
✓ Branch 65 → 66 taken 26202 times.
✗ Branch 65 → 252 not taken.
26202 const SymbolTableEntry *structSymbol = structBodyScope->parent->lookupStrict(structSignature);
538
1/2
✗ Branch 68 → 69 not taken.
✓ Branch 68 → 70 taken 26202 times.
26202 assert(structSymbol != nullptr);
539
540 // Collect concrete field types
541 26202 std::string mangledName;
542 26202 std::vector<llvm::Type *> fieldTypes;
543 26202 bool isPacked = false;
544
2/2
✓ Branch 72 → 73 taken 23446 times.
✓ Branch 72 → 135 taken 2756 times.
26202 if (is(TY_STRUCT)) { // Struct
545
2/4
✓ Branch 73 → 74 taken 23446 times.
✗ Branch 73 → 248 not taken.
✓ Branch 74 → 75 taken 23446 times.
✗ Branch 74 → 248 not taken.
23446 const Struct *spiceStruct = structSymbol->getQualType().getStruct(structSymbol->declNode);
546
1/2
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 77 taken 23446 times.
23446 assert(spiceStruct != nullptr);
547
1/2
✓ Branch 77 → 78 taken 23446 times.
✗ Branch 77 → 226 not taken.
23446 mangledName = NameMangling::mangleStruct(*spiceStruct);
548
549
1/2
✓ Branch 80 → 81 taken 23446 times.
✗ Branch 80 → 248 not taken.
23446 const size_t totalFieldCount = spiceStruct->scope->getFieldCount();
550
1/2
✓ Branch 81 → 82 taken 23446 times.
✗ Branch 81 → 248 not taken.
23446 fieldTypes.reserve(totalFieldCount);
551
552 // If the struct implements interfaces, the first implicit field (added below via lookupField) is an interface
553 // type, which already lowers to a { ptr } struct carrying the vtable pointer. Only add an explicit ptr field
554 // here for structs without interfaces that still need a vtable (e.g. RTTI root types), to avoid duplicating it.
555
2/4
✓ Branch 82 → 83 taken 23446 times.
✗ Branch 82 → 248 not taken.
✗ Branch 83 → 84 not taken.
✓ Branch 83 → 85 taken 23446 times.
23446 assert(structSymbol->declNode->isStructDef());
556
1/2
✓ Branch 85 → 86 taken 23446 times.
✗ Branch 85 → 87 not taken.
23446 const auto structDeclNode = spice_pointer_cast<StructDefNode *>(structSymbol->declNode);
557
3/4
✓ Branch 94 → 95 taken 23446 times.
✗ Branch 94 → 248 not taken.
✓ Branch 95 → 96 taken 222 times.
✓ Branch 95 → 99 taken 23224 times.
23446 if (spiceStruct->hasSynthesizedVTablePtr())
558
2/4
✓ Branch 96 → 97 taken 222 times.
✗ Branch 96 → 227 not taken.
✓ Branch 97 → 98 taken 222 times.
✗ Branch 97 → 227 not taken.
222 fieldTypes.push_back(llvm::PointerType::get(context, 0));
559
560 // Collect all field types
561
2/2
✓ Branch 113 → 100 taken 62564 times.
✓ Branch 113 → 114 taken 23446 times.
86010 for (size_t i = 0; i < totalFieldCount; i++) {
562
1/2
✗ Branch 100 → 101 not taken.
✓ Branch 100 → 103 taken 62564 times.
62564 const SymbolTableEntry *fieldSymbol = spiceStruct->scope->lookupField(i);
563
1/2
✗ Branch 106 → 107 not taken.
✓ Branch 106 → 108 taken 62564 times.
62564 assert(fieldSymbol != nullptr);
564
3/6
✓ Branch 108 → 109 taken 62564 times.
✗ Branch 108 → 228 not taken.
✓ Branch 110 → 111 taken 62564 times.
✗ Branch 110 → 228 not taken.
✓ Branch 111 → 112 taken 62564 times.
✗ Branch 111 → 228 not taken.
62564 fieldTypes.push_back(sourceFile->getLLVMType(fieldSymbol->getQualType().getType()));
565 }
566
567 // Check if the struct is declared as packed
568
12/18
✓ Branch 114 → 115 taken 224 times.
✓ Branch 114 → 121 taken 23222 times.
✓ Branch 117 → 118 taken 224 times.
✗ Branch 117 → 229 not taken.
✓ Branch 118 → 119 taken 224 times.
✗ Branch 118 → 229 not taken.
✓ Branch 119 → 120 taken 2 times.
✓ Branch 119 → 121 taken 222 times.
✓ Branch 122 → 123 taken 224 times.
✓ Branch 122 → 124 taken 23222 times.
✓ Branch 124 → 125 taken 224 times.
✓ Branch 124 → 127 taken 23222 times.
✓ Branch 127 → 128 taken 2 times.
✓ Branch 127 → 145 taken 23444 times.
✗ Branch 229 → 230 not taken.
✗ Branch 229 → 231 not taken.
✗ Branch 233 → 234 not taken.
✗ Branch 233 → 236 not taken.
23894 if (structDeclNode->attrs && structDeclNode->attrs->attrLst->hasAttr(ATTR_CORE_COMPILER_PACKED))
569
2/4
✓ Branch 130 → 131 taken 2 times.
✗ Branch 130 → 240 not taken.
✓ Branch 131 → 132 taken 2 times.
✗ Branch 131 → 238 not taken.
6 isPacked = structDeclNode->attrs->attrLst->getAttrValueByName(ATTR_CORE_COMPILER_PACKED)->boolValue;
570 } else { // Interface
571
2/4
✓ Branch 135 → 136 taken 2756 times.
✗ Branch 135 → 248 not taken.
✓ Branch 136 → 137 taken 2756 times.
✗ Branch 136 → 248 not taken.
2756 const Interface *spiceInterface = structSymbol->getQualType().getInterface(structSymbol->declNode);
572
1/2
✗ Branch 137 → 138 not taken.
✓ Branch 137 → 139 taken 2756 times.
2756 assert(spiceInterface != nullptr);
573
1/2
✓ Branch 139 → 140 taken 2756 times.
✗ Branch 139 → 244 not taken.
2756 mangledName = NameMangling::mangleInterface(*spiceInterface);
574
575 // vtable pointer
576
2/4
✓ Branch 142 → 143 taken 2756 times.
✗ Branch 142 → 245 not taken.
✓ Branch 143 → 144 taken 2756 times.
✗ Branch 143 → 245 not taken.
2756 fieldTypes.push_back(llvm::PointerType::get(context, 0));
577 }
578
579
1/2
✓ Branch 147 → 148 taken 26202 times.
✗ Branch 147 → 246 not taken.
26202 return llvm::StructType::create(context, fieldTypes, mangledName, isPacked);
580 26202 }
581
582
2/2
✓ Branch 154 → 155 taken 64 times.
✓ Branch 154 → 206 taken 660 times.
724 if (is(TY_UNION)) {
583 // A union is lowered to { i32 tag, [0 x MaxAlignTy] alignPad, [maxSize x i8] payload }. The tag tracks which field
584 // is currently active. The zero-length array contributes no bytes but forces the whole struct's (and therefore the
585 // payload's) ABI alignment to be at least as strict as the most-aligned field, so that every field can be safely
586 // loaded/stored at the payload's address regardless of its own alignment requirement. The payload itself is always
587 // a raw byte buffer (not a typed array), so that any field's value can be stored/loaded there directly, and any
588 // compile-time constant for it can be built uniformly as packed raw bytes, without needing a legal LLVM constant
589 // conversion between the payload's declared element type and a field's unrelated type.
590
1/2
✓ Branch 155 → 156 taken 64 times.
✗ Branch 155 → 267 not taken.
64 const Scope *unionBodyScope = getBodyScope();
591
2/4
✓ Branch 157 → 158 taken 64 times.
✗ Branch 157 → 267 not taken.
✓ Branch 158 → 159 taken 64 times.
✗ Branch 158 → 267 not taken.
64 const std::string unionSignature = Union::getSignature(getSubType(), getTemplateTypes());
592
1/2
✓ Branch 159 → 160 taken 64 times.
✗ Branch 159 → 265 not taken.
64 const SymbolTableEntry *unionSymbol = unionBodyScope->parent->lookupStrict(unionSignature);
593
1/2
✗ Branch 162 → 163 not taken.
✓ Branch 162 → 164 taken 64 times.
64 assert(unionSymbol != nullptr);
594
595
2/4
✓ Branch 164 → 165 taken 64 times.
✗ Branch 164 → 265 not taken.
✓ Branch 165 → 166 taken 64 times.
✗ Branch 165 → 265 not taken.
64 const Union *spiceUnion = unionSymbol->getQualType().getUnion(unionSymbol->declNode);
596
1/2
✗ Branch 166 → 167 not taken.
✓ Branch 166 → 168 taken 64 times.
64 assert(spiceUnion != nullptr);
597
1/2
✓ Branch 168 → 169 taken 64 times.
✗ Branch 168 → 265 not taken.
64 const std::string mangledName = NameMangling::mangleUnion(*spiceUnion);
598
599
1/2
✓ Branch 170 → 171 taken 64 times.
✗ Branch 170 → 263 not taken.
64 const llvm::DataLayout &dataLayout = sourceFile->targetMachine->createDataLayout();
600
1/2
✓ Branch 171 → 172 taken 64 times.
✗ Branch 171 → 261 not taken.
64 const size_t totalFieldCount = spiceUnion->scope->getFieldCount();
601
602 64 uint64_t maxSize = 0;
603 64 uint64_t maxAlign = 1;
604
1/2
✓ Branch 172 → 173 taken 64 times.
✗ Branch 172 → 261 not taken.
64 llvm::Type *maxAlignFieldType = llvm::Type::getInt8Ty(context);
605
2/2
✓ Branch 193 → 174 taken 380 times.
✓ Branch 193 → 194 taken 64 times.
444 for (size_t i = 0; i < totalFieldCount; i++) {
606
1/2
✓ Branch 174 → 175 taken 380 times.
✗ Branch 174 → 177 not taken.
380 const SymbolTableEntry *fieldSymbol = spiceUnion->scope->lookupField(i);
607
1/2
✗ Branch 180 → 181 not taken.
✓ Branch 180 → 182 taken 380 times.
380 assert(fieldSymbol != nullptr);
608
2/4
✓ Branch 182 → 183 taken 380 times.
✗ Branch 182 → 257 not taken.
✓ Branch 184 → 185 taken 380 times.
✗ Branch 184 → 257 not taken.
380 llvm::Type *fieldType = sourceFile->getLLVMType(fieldSymbol->getQualType().getType());
609
2/4
✓ Branch 185 → 186 taken 380 times.
✗ Branch 185 → 255 not taken.
✓ Branch 186 → 187 taken 380 times.
✗ Branch 186 → 255 not taken.
380 const uint64_t fieldSize = dataLayout.getTypeAllocSize(fieldType);
610
1/2
✓ Branch 187 → 188 taken 380 times.
✗ Branch 187 → 256 not taken.
380 const uint64_t fieldAlign = dataLayout.getABITypeAlign(fieldType).value();
611 380 maxSize = std::max(maxSize, fieldSize);
612
2/2
✓ Branch 190 → 191 taken 78 times.
✓ Branch 190 → 192 taken 302 times.
380 if (fieldAlign > maxAlign) {
613 78 maxAlign = fieldAlign;
614 78 maxAlignFieldType = fieldType;
615 }
616 }
617
618
1/2
✓ Branch 194 → 195 taken 64 times.
✗ Branch 194 → 261 not taken.
64 llvm::Type *tagType = llvm::Type::getInt32Ty(context);
619
1/2
✓ Branch 195 → 196 taken 64 times.
✗ Branch 195 → 261 not taken.
64 llvm::Type *alignPadType = llvm::ArrayType::get(maxAlignFieldType, 0);
620
2/4
✓ Branch 196 → 197 taken 64 times.
✗ Branch 196 → 261 not taken.
✓ Branch 197 → 198 taken 64 times.
✗ Branch 197 → 261 not taken.
64 llvm::Type *payloadType = llvm::ArrayType::get(llvm::Type::getInt8Ty(context), maxSize);
621
1/2
✓ Branch 200 → 201 taken 64 times.
✗ Branch 200 → 258 not taken.
64 return llvm::StructType::create(context, {tagType, alignPadType, payloadType}, mangledName);
622 64 }
623
624
2/4
✓ Branch 206 → 207 taken 660 times.
✗ Branch 206 → 268 not taken.
✓ Branch 207 → 208 taken 660 times.
✗ Branch 207 → 214 not taken.
660 if (isOneOf({TY_FUNCTION, TY_PROCEDURE})) {
625 // Lambda/function values are represented as a fat pointer with three slots:
626 // { fctPtr, capturePtr, captureSize }. The capture size (in bytes) travels with
627 // the value so that the std Lambda type can take ownership of the captures on the
628 // heap regardless of where the lambda came from. It is 0 if there is no owned
629 // capture struct (no captures, or a single capture stored inline in capturePtr).
630 660 llvm::PointerType *ptrTy = llvm::PointerType::get(context, 0);
631 660 llvm::IntegerType *int64Ty = llvm::Type::getInt64Ty(context);
632
1/2
✓ Branch 211 → 212 taken 660 times.
✗ Branch 211 → 269 not taken.
660 return llvm::StructType::get(context, {ptrTy, ptrTy, int64Ty});
633 }
634
635 throw CompilerError(UNHANDLED_BRANCH, "Cannot determine LLVM type of " + getName(true, true, true)); // GCOVR_EXCL_LINE
636 }
637
638 /**
639 * Remove pointers / arrays / references if both types have them as far as possible.
640 *
641 * @param typeA Candidate type
642 * @param typeB Requested type
643 */
644 803779 void Type::unwrapBoth(const Type *&typeA, const Type *&typeB) {
645 // Unwrap both types as far as possible
646
2/2
✓ Branch 7 → 3 taken 65779 times.
✓ Branch 7 → 8 taken 803779 times.
869558 while (typeA->isSameContainerTypeAs(typeB)) {
647 65779 typeB = typeB->getContained();
648 65779 typeA = typeA->getContained();
649 }
650 803779 }
651
652 /**
653 * Remove pointers / arrays / references if both types have them as far as possible.
654 * Furthermore, remove reference wrappers if possible.
655 *
656 * @param typeA Candidate type
657 * @param typeB Requested type
658 */
659 787609 void Type::unwrapBothWithRefWrappers(const Type *&typeA, const Type *&typeB) {
660 // Remove reference wrapper of front type if required
661
6/6
✓ Branch 3 → 4 taken 361882 times.
✓ Branch 3 → 7 taken 425727 times.
✓ Branch 5 → 6 taken 319883 times.
✓ Branch 5 → 7 taken 41999 times.
✓ Branch 8 → 9 taken 319883 times.
✓ Branch 8 → 11 taken 467726 times.
787609 if (typeA->isRef() && !typeB->isRef())
662 319883 typeA = typeA->removeReferenceWrapper();
663
664 // Remove reference wrapper of requested type if required
665
8/8
✓ Branch 12 → 13 taken 745610 times.
✓ Branch 12 → 18 taken 41999 times.
✓ Branch 14 → 15 taken 26198 times.
✓ Branch 14 → 18 taken 719412 times.
✓ Branch 16 → 17 taken 21677 times.
✓ Branch 16 → 18 taken 4521 times.
✓ Branch 19 → 20 taken 21677 times.
✓ Branch 19 → 22 taken 765932 times.
787609 if (!typeA->isRef() && typeB->isRef() && !typeA->isBase(TY_GENERIC))
666 21677 typeB = typeB->removeReferenceWrapper();
667
668 // Unwrap both types as far as possible
669 787609 unwrapBoth(typeA, typeB);
670 787609 }
671
672 /**
673 * Check if two types have the same type chain depth
674 *
675 * @param typeA First type
676 * @param typeB Second type
677 * @return Same depth or not
678 */
679 129095 bool Type::hasSameTypeChainDepth(const Type *typeA, const Type *typeB) {
680 129095 return typeA->typeChain.size() == typeB->typeChain.size();
681 }
682
683 } // namespace spice::compiler
684