GCC Code Coverage Report


Directory: ../
File: src/typechecker/TypeChecker.cpp
Date: 2025-02-05 01:09:36
Exec Total Coverage
Lines: 1557 1631 95.5%
Functions: 82 83 98.8%
Branches: 2516 4585 54.9%

Line Branch Exec Source
1 // Copyright (c) 2021-2025 ChilliBits. All rights reserved.
2
3 #include "TypeChecker.h"
4
5 #include <SourceFile.h>
6 #include <ast/ASTBuilder.h>
7 #include <ast/Attributes.h>
8 #include <global/GlobalResourceManager.h>
9 #include <symboltablebuilder/ScopeHandle.h>
10 #include <symboltablebuilder/SymbolTableBuilder.h>
11 #include <typechecker/MacroDefs.h>
12 #include <typechecker/TypeMatcher.h>
13
14 namespace spice::compiler {
15
16 2799 TypeChecker::TypeChecker(GlobalResourceManager &resourceManager, SourceFile *sourceFile, TypeCheckerMode typeCheckerMode)
17
1/2
✓ Branch 0 (4→5) taken 2799 times.
✗ Branch 1 (4→7) not taken.
2799 : CompilerPass(resourceManager, sourceFile), typeCheckerMode(typeCheckerMode), warnings(sourceFile->compilerOutput.warnings) {
18 2799 }
19
20 2300 std::any TypeChecker::visitEntry(EntryNode *node) {
21 // Initialize
22 2300 currentScope = rootScope;
23
24 // Initialize AST nodes with size of 1
25 2300 const bool isPrepare = typeCheckerMode == TC_MODE_PRE;
26
2/2
✓ Branch 0 (2→3) taken 988 times.
✓ Branch 1 (2→4) taken 1312 times.
2300 if (isPrepare)
27 988 node->resizeToNumberOfManifestations(1);
28
29 // Visit children
30
2/2
✓ Branch 0 (4→5) taken 2256 times.
✓ Branch 1 (4→22) taken 44 times.
2300 visitChildren(node);
31
32 // Check which implicit structures we need for each struct, defined in this source file
33
2/2
✓ Branch 0 (6→7) taken 974 times.
✓ Branch 1 (6→19) taken 1282 times.
2256 if (isPrepare) {
34
1/2
✓ Branch 0 (7→8) taken 974 times.
✗ Branch 1 (7→26) not taken.
974 const std::vector<const Struct *> manifestations = rootScope->getAllStructManifestationsInDeclarationOrder();
35
2/2
✓ Branch 0 (16→10) taken 580 times.
✓ Branch 1 (16→17) taken 974 times.
1554 for (const Struct *manifestation : manifestations) {
36 // Check if we need to create a default ctor, copy ctor or dtor
37
1/2
✓ Branch 0 (11→12) taken 580 times.
✗ Branch 1 (11→23) not taken.
580 createDefaultCtorIfRequired(*manifestation, manifestation->scope);
38
1/2
✓ Branch 0 (12→13) taken 580 times.
✗ Branch 1 (12→23) not taken.
580 createDefaultCopyCtorIfRequired(*manifestation, manifestation->scope);
39
1/2
✓ Branch 0 (13→14) taken 580 times.
✗ Branch 1 (13→23) not taken.
580 createDefaultDtorIfRequired(*manifestation, manifestation->scope);
40 }
41 974 }
42
43
1/2
✓ Branch 0 (19→20) taken 2256 times.
✗ Branch 1 (19→27) not taken.
2256 return nullptr;
44 }
45
46 746 std::any TypeChecker::visitMainFctDef(MainFctDefNode *node) {
47
2/2
✓ Branch 0 (2→3) taken 354 times.
✓ Branch 1 (2→4) taken 392 times.
746 if (typeCheckerMode == TC_MODE_PRE)
48 354 return visitMainFctDefPrepare(node);
49 else
50 392 return visitMainFctDefCheck(node);
51 }
52
53 18593 std::any TypeChecker::visitFctDef(FctDefNode *node) {
54
2/2
✓ Branch 0 (2→3) taken 6005 times.
✓ Branch 1 (2→4) taken 12588 times.
18593 if (typeCheckerMode == TC_MODE_PRE)
55 6005 return visitFctDefPrepare(node);
56 else
57 12588 return visitFctDefCheck(node);
58 }
59
60 8961 std::any TypeChecker::visitProcDef(ProcDefNode *node) {
61
2/2
✓ Branch 0 (2→3) taken 2950 times.
✓ Branch 1 (2→4) taken 6011 times.
8961 if (typeCheckerMode == TC_MODE_PRE)
62 2950 return visitProcDefPrepare(node);
63 else
64 6011 return visitProcDefCheck(node);
65 }
66
67 1526 std::any TypeChecker::visitStructDef(StructDefNode *node) {
68
2/2
✓ Branch 0 (2→3) taken 585 times.
✓ Branch 1 (2→4) taken 941 times.
1526 if (typeCheckerMode == TC_MODE_PRE)
69 585 return visitStructDefPrepare(node);
70 else
71 941 return visitStructDefCheck(node);
72 }
73
74 161 std::any TypeChecker::visitInterfaceDef(InterfaceDefNode *node) {
75
2/2
✓ Branch 0 (2→3) taken 80 times.
✓ Branch 1 (2→4) taken 81 times.
161 if (typeCheckerMode == TC_MODE_PRE)
76 80 return visitInterfaceDefPrepare(node);
77
1/2
✓ Branch 0 (4→5) taken 81 times.
✗ Branch 1 (4→7) not taken.
81 return nullptr;
78 }
79
80 184 std::any TypeChecker::visitEnumDef(EnumDefNode *node) {
81
2/2
✓ Branch 0 (2→3) taken 63 times.
✓ Branch 1 (2→4) taken 121 times.
184 if (typeCheckerMode == TC_MODE_PRE)
82 63 return visitEnumDefPrepare(node);
83
1/2
✓ Branch 0 (4→5) taken 121 times.
✗ Branch 1 (4→7) not taken.
121 return nullptr;
84 }
85
86 2361 std::any TypeChecker::visitGenericTypeDef(GenericTypeDefNode *node) {
87
2/2
✓ Branch 0 (2→3) taken 759 times.
✓ Branch 1 (2→4) taken 1602 times.
2361 if (typeCheckerMode == TC_MODE_PRE)
88 759 return visitGenericTypeDefPrepare(node);
89
1/2
✓ Branch 0 (4→5) taken 1602 times.
✗ Branch 1 (4→7) not taken.
1602 return nullptr;
90 }
91
92 121 std::any TypeChecker::visitAliasDef(AliasDefNode *node) {
93
2/2
✓ Branch 0 (2→3) taken 45 times.
✓ Branch 1 (2→4) taken 76 times.
121 if (typeCheckerMode == TC_MODE_PRE)
94 45 return visitAliasDefPrepare(node);
95
1/2
✓ Branch 0 (4→5) taken 76 times.
✗ Branch 1 (4→7) not taken.
76 return nullptr;
96 }
97
98 1864 std::any TypeChecker::visitGlobalVarDef(GlobalVarDefNode *node) {
99
2/2
✓ Branch 0 (2→3) taken 760 times.
✓ Branch 1 (2→4) taken 1104 times.
1864 if (typeCheckerMode == TC_MODE_PRE)
100 760 return visitGlobalVarDefPrepare(node);
101
1/2
✓ Branch 0 (4→5) taken 1104 times.
✗ Branch 1 (4→7) not taken.
1104 return nullptr;
102 }
103
104 2498 std::any TypeChecker::visitExtDecl(ExtDeclNode *node) {
105
2/2
✓ Branch 0 (2→3) taken 851 times.
✓ Branch 1 (2→4) taken 1647 times.
2498 if (typeCheckerMode == TC_MODE_PRE)
106 851 return visitExtDeclPrepare(node);
107
1/2
✓ Branch 0 (4→5) taken 1647 times.
✗ Branch 1 (4→7) not taken.
1647 return nullptr;
108 }
109
110 1294 std::any TypeChecker::visitImportDef(ImportDefNode *node) {
111
2/2
✓ Branch 0 (2→3) taken 466 times.
✓ Branch 1 (2→4) taken 828 times.
1294 if (typeCheckerMode == TC_MODE_PRE)
112 466 return visitImportDefPrepare(node);
113
1/2
✓ Branch 0 (4→5) taken 828 times.
✗ Branch 1 (4→7) not taken.
828 return nullptr;
114 }
115
116 2061 std::any TypeChecker::visitUnsafeBlock(UnsafeBlockNode *node) {
117 // Change to unsafe block body scope
118
2/4
✓ Branch 0 (2→3) taken 2061 times.
✗ Branch 1 (2→13) not taken.
✓ Branch 2 (3→4) taken 2061 times.
✗ Branch 3 (3→11) not taken.
2061 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::UNSAFE_BODY);
119
120 // Visit body
121
1/2
✓ Branch 0 (5→6) taken 2061 times.
✗ Branch 1 (5→15) not taken.
2061 visit(node->body);
122
123
1/2
✓ Branch 0 (7→8) taken 2061 times.
✗ Branch 1 (7→16) not taken.
4122 return nullptr;
124 2061 }
125
126 1168 std::any TypeChecker::visitForLoop(ForLoopNode *node) {
127 // Change to for body scope
128
2/4
✓ Branch 0 (2→3) taken 1168 times.
✗ Branch 1 (2→37) not taken.
✓ Branch 2 (3→4) taken 1168 times.
✗ Branch 3 (3→35) not taken.
1168 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::FOR_BODY);
129
130 // Visit loop variable declaration
131
1/2
✓ Branch 0 (5→6) taken 1168 times.
✗ Branch 1 (5→39) not taken.
1168 visit(node->initDecl);
132
133 // Visit condition
134
2/4
✓ Branch 0 (7→8) taken 1168 times.
✗ Branch 1 (7→42) not taken.
✓ Branch 2 (8→9) taken 1168 times.
✗ Branch 3 (8→40) not taken.
1168 const QualType conditionType = std::any_cast<ExprResult>(visit(node->condAssign)).type;
135
2/6
✓ Branch 0 (10→11) taken 1168 times.
✗ Branch 1 (10→55) not taken.
✗ Branch 2 (11→12) not taken.
✓ Branch 3 (11→14) taken 1168 times.
✗ Branch 4 (12→13) not taken.
✗ Branch 5 (12→44) not taken.
1168 HANDLE_UNRESOLVED_TYPE_PTR(conditionType)
136 // Check if condition evaluates to bool
137
3/4
✓ Branch 0 (14→15) taken 1168 times.
✗ Branch 1 (14→55) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→26) taken 1167 times.
1168 if (!conditionType.is(TY_BOOL))
138
4/8
✓ Branch 0 (18→19) taken 1 times.
✗ Branch 1 (18→47) not taken.
✓ Branch 2 (19→20) taken 1 times.
✗ Branch 3 (19→45) not taken.
✓ Branch 4 (22→23) taken 1 times.
✗ Branch 5 (22→51) not taken.
✓ Branch 6 (23→24) taken 1 times.
✗ Branch 7 (23→51) not taken.
3 SOFT_ERROR_ER(node->condAssign, CONDITION_MUST_BE_BOOL, "For loop condition must be of type bool")
139
140 // Visit incrementer
141
1/2
✓ Branch 0 (26→27) taken 1167 times.
✗ Branch 1 (26→52) not taken.
1167 visit(node->incAssign);
142
143 // Visit body
144
1/2
✓ Branch 0 (28→29) taken 1167 times.
✗ Branch 1 (28→53) not taken.
1167 visit(node->body);
145
146
1/2
✓ Branch 0 (30→31) taken 1167 times.
✗ Branch 1 (30→54) not taken.
1167 return nullptr;
147 1168 }
148
149 92 std::any TypeChecker::visitForeachLoop(ForeachLoopNode *node) {
150 // Visit iterator assignment
151 92 AssignExprNode *iteratorNode = node->iteratorAssign;
152
2/4
✓ Branch 0 (2→3) taken 92 times.
✗ Branch 1 (2→200) not taken.
✓ Branch 2 (3→4) taken 92 times.
✗ Branch 3 (3→198) not taken.
92 QualType iteratorOrIterableType = std::any_cast<ExprResult>(visit(iteratorNode)).type;
153
2/6
✓ Branch 0 (5→6) taken 92 times.
✗ Branch 1 (5→344) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→9) taken 92 times.
✗ Branch 4 (7→8) not taken.
✗ Branch 5 (7→202) not taken.
92 HANDLE_UNRESOLVED_TYPE_PTR(iteratorOrIterableType)
154
1/2
✓ Branch 0 (9→10) taken 92 times.
✗ Branch 1 (9→203) not taken.
92 iteratorOrIterableType = iteratorOrIterableType.removeReferenceWrapper();
155
156 // Retrieve iterator type
157 92 QualType iteratorType = iteratorOrIterableType;
158
159
3/4
✓ Branch 0 (10→11) taken 92 times.
✗ Branch 1 (10→344) not taken.
✓ Branch 2 (11→12) taken 73 times.
✓ Branch 3 (11→72) taken 19 times.
92 if (iteratorOrIterableType.isIterable(node)) {
160 73 const QualType &iterableType = iteratorOrIterableType;
161
3/4
✓ Branch 0 (12→13) taken 73 times.
✗ Branch 1 (12→344) not taken.
✓ Branch 2 (13→14) taken 8 times.
✓ Branch 3 (13→50) taken 65 times.
73 if (iteratorOrIterableType.isArray()) { // Array
162
2/4
✓ Branch 0 (16→17) taken 8 times.
✗ Branch 1 (16→206) not taken.
✓ Branch 2 (17→18) taken 8 times.
✗ Branch 3 (17→204) not taken.
16 const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(ARRAY_ITERATOR_NAME);
163
2/2
✓ Branch 0 (20→21) taken 1 times.
✓ Branch 1 (20→29) taken 7 times.
8 if (!nameRegistryEntry) {
164
2/4
✓ Branch 0 (23→24) taken 1 times.
✗ Branch 1 (23→212) not taken.
✓ Branch 2 (24→25) taken 1 times.
✗ Branch 3 (24→210) not taken.
1 softError(node, UNKNOWN_DATATYPE, "Forgot to import \"std/iterator/array-iterator\"?");
165
1/2
✓ Branch 0 (27→28) taken 1 times.
✗ Branch 1 (27→216) not taken.
1 return nullptr;
166 }
167 7 nameRegistryEntry->targetEntry->used = nameRegistryEntry->importEntry->used = true;
168 7 Scope *matchScope = nameRegistryEntry->targetScope->parent;
169
1/2
✗ Branch 0 (29→30) not taken.
✓ Branch 1 (29→31) taken 7 times.
7 assert(matchScope->type == ScopeType::GLOBAL);
170
1/2
✓ Branch 0 (31→32) taken 7 times.
✗ Branch 1 (31→234) not taken.
7 QualType unsignedLongType(TY_LONG);
171
1/2
✓ Branch 0 (32→33) taken 7 times.
✗ Branch 1 (32→234) not taken.
7 unsignedLongType.makeUnsigned(true);
172
1/2
✓ Branch 0 (37→38) taken 7 times.
✗ Branch 1 (37→217) not taken.
14 const ArgList argTypes = {Arg(iterableType, false), Arg(unsignedLongType, false)};
173
1/2
✓ Branch 0 (39→40) taken 7 times.
✗ Branch 1 (39→232) not taken.
7 const QualType thisType(TY_DYN);
174
2/4
✓ Branch 0 (43→44) taken 7 times.
✗ Branch 1 (43→225) not taken.
✓ Branch 2 (44→45) taken 7 times.
✗ Branch 3 (44→223) not taken.
21 node->getIteratorFct = FunctionManager::match(this, matchScope, "iterate", thisType, argTypes, {}, true, iteratorNode);
175 7 } else { // Struct, implementing Iterator interface
176
1/2
✓ Branch 0 (50→51) taken 65 times.
✗ Branch 1 (50→344) not taken.
65 Scope *matchScope = iterableType.getBodyScope();
177
2/4
✓ Branch 0 (55→56) taken 65 times.
✗ Branch 1 (55→237) not taken.
✓ Branch 2 (56→57) taken 65 times.
✗ Branch 3 (56→235) not taken.
195 node->getIteratorFct = FunctionManager::match(this, matchScope, "getIterator", iterableType, {}, {}, true, iteratorNode);
178 }
179
2/2
✓ Branch 0 (62→63) taken 1 times.
✓ Branch 1 (62→71) taken 71 times.
72 if (node->getIteratorFct == nullptr)
180
2/4
✓ Branch 0 (66→67) taken 1 times.
✗ Branch 1 (66→250) not taken.
✓ Branch 2 (67→68) taken 1 times.
✗ Branch 3 (67→247) not taken.
3 throw SemanticError(iteratorNode, INVALID_ITERATOR, "No getIterator() function found for the given iterable type");
181
182 71 iteratorType = QualType(node->getIteratorFct->returnType);
183 // Create anonymous entry for the iterator
184
1/2
✓ Branch 0 (71→72) taken 71 times.
✗ Branch 1 (71→344) not taken.
71 currentScope->symbolTable.insertAnonymous(iteratorType, iteratorNode);
185 }
186
187 // Change to foreach body scope
188
2/4
✓ Branch 0 (72→73) taken 90 times.
✗ Branch 1 (72→258) not taken.
✓ Branch 2 (73→74) taken 90 times.
✗ Branch 3 (73→256) not taken.
90 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::FOREACH_BODY);
189
190 // Check iterator type
191
3/4
✓ Branch 0 (75→76) taken 90 times.
✗ Branch 1 (75→342) not taken.
✓ Branch 2 (76→77) taken 1 times.
✓ Branch 3 (76→84) taken 89 times.
90 if (!iteratorType.isIterator(node)) {
192 const std::string errMsg =
193 "Can only iterate over arrays or data structures, inheriting from IIterator or IIterable. You provided " +
194
2/4
✓ Branch 0 (77→78) taken 1 times.
✗ Branch 1 (77→262) not taken.
✓ Branch 2 (78→79) taken 1 times.
✗ Branch 3 (78→260) not taken.
1 iteratorType.getName(false);
195
1/2
✓ Branch 0 (80→81) taken 1 times.
✗ Branch 1 (80→264) not taken.
1 softError(node->iteratorAssign, OPERATOR_WRONG_DATA_TYPE, errMsg);
196
1/2
✓ Branch 0 (81→82) taken 1 times.
✗ Branch 1 (81→263) not taken.
1 return nullptr;
197 1 }
198
1/2
✓ Branch 0 (84→85) taken 89 times.
✗ Branch 1 (84→342) not taken.
89 const QualTypeList &iteratorTemplateTypes = iteratorType.getTemplateTypes();
199
2/2
✓ Branch 0 (86→87) taken 1 times.
✓ Branch 1 (86→97) taken 88 times.
89 if (iteratorTemplateTypes.empty())
200
4/8
✓ Branch 0 (89→90) taken 1 times.
✗ Branch 1 (89→269) not taken.
✓ Branch 2 (90→91) taken 1 times.
✗ Branch 3 (90→267) not taken.
✓ Branch 4 (93→94) taken 1 times.
✗ Branch 5 (93→273) not taken.
✓ Branch 6 (94→95) taken 1 times.
✗ Branch 7 (94→273) not taken.
3 SOFT_ERROR_ER(node->iteratorAssign, INVALID_ITERATOR,
201 "Iterator has no generic arguments so that the item type could not be inferred")
202
203 88 const bool hasIdx = node->idxVarDecl;
204
2/2
✓ Branch 0 (97→98) taken 6 times.
✓ Branch 1 (97→118) taken 82 times.
88 if (hasIdx) {
205 // Visit index declaration or assignment
206
2/4
✓ Branch 0 (98→99) taken 6 times.
✗ Branch 1 (98→276) not taken.
✓ Branch 2 (99→100) taken 6 times.
✗ Branch 3 (99→274) not taken.
6 auto indexType = std::any_cast<QualType>(visit(node->idxVarDecl));
207
2/6
✓ Branch 0 (101→102) taken 6 times.
✗ Branch 1 (101→285) not taken.
✗ Branch 2 (102→103) not taken.
✓ Branch 3 (102→105) taken 6 times.
✗ Branch 4 (103→104) not taken.
✗ Branch 5 (103→277) not taken.
6 HANDLE_UNRESOLVED_TYPE_PTR(indexType)
208 // Check if index type is int
209
3/4
✓ Branch 0 (105→106) taken 6 times.
✗ Branch 1 (105→285) not taken.
✓ Branch 2 (106→107) taken 1 times.
✓ Branch 3 (106→116) taken 5 times.
6 if (!indexType.is(TY_LONG))
210
5/10
✓ Branch 0 (107→108) taken 1 times.
✗ Branch 1 (107→282) not taken.
✓ Branch 2 (108→109) taken 1 times.
✗ Branch 3 (108→280) not taken.
✓ Branch 4 (109→110) taken 1 times.
✗ Branch 5 (109→278) not taken.
✓ Branch 6 (112→113) taken 1 times.
✗ Branch 7 (112→284) not taken.
✓ Branch 8 (113→114) taken 1 times.
✗ Branch 9 (113→284) not taken.
1 SOFT_ERROR_ER(node->idxVarDecl, FOREACH_IDX_NOT_LONG,
211 "Index in foreach loop must be of type long. You provided " + indexType.getName(false))
212 }
213
214 // Retrieve .get(), .getIdx(), .isValid() and .next() functions
215
1/2
✓ Branch 0 (118→119) taken 87 times.
✗ Branch 1 (118→342) not taken.
87 Scope *matchScope = iteratorType.getBodyScope();
216 87 QualType iteratorItemType;
217
2/2
✓ Branch 0 (119→120) taken 5 times.
✓ Branch 1 (119→135) taken 82 times.
87 if (hasIdx) {
218
2/4
✓ Branch 0 (124→125) taken 5 times.
✗ Branch 1 (124→288) not taken.
✓ Branch 2 (125→126) taken 5 times.
✗ Branch 3 (125→286) not taken.
15 node->getIdxFct = FunctionManager::match(this, matchScope, "getIdx", iteratorType, {}, {}, false, node);
219
1/2
✗ Branch 0 (130→131) not taken.
✓ Branch 1 (130→132) taken 5 times.
5 assert(node->getIdxFct != nullptr);
220
1/2
✓ Branch 0 (132→133) taken 5 times.
✗ Branch 1 (132→342) not taken.
5 iteratorItemType = node->getIdxFct->returnType.getTemplateTypes().back();
221 } else {
222
2/4
✓ Branch 0 (139→140) taken 82 times.
✗ Branch 1 (139→300) not taken.
✓ Branch 2 (140→141) taken 82 times.
✗ Branch 3 (140→298) not taken.
246 node->getFct = FunctionManager::match(this, matchScope, "get", iteratorType, {}, {}, false, node);
223
1/2
✗ Branch 0 (145→146) not taken.
✓ Branch 1 (145→147) taken 82 times.
82 assert(node->getFct != nullptr);
224 82 iteratorItemType = node->getFct->returnType;
225 }
226
2/4
✓ Branch 0 (152→153) taken 87 times.
✗ Branch 1 (152→312) not taken.
✓ Branch 2 (153→154) taken 87 times.
✗ Branch 3 (153→310) not taken.
261 node->isValidFct = FunctionManager::match(this, matchScope, "isValid", iteratorType, {}, {}, false, node);
227
1/2
✗ Branch 0 (158→159) not taken.
✓ Branch 1 (158→160) taken 87 times.
87 assert(node->isValidFct != nullptr);
228
2/4
✓ Branch 0 (164→165) taken 87 times.
✗ Branch 1 (164→324) not taken.
✓ Branch 2 (165→166) taken 87 times.
✗ Branch 3 (165→322) not taken.
261 node->nextFct = FunctionManager::match(this, matchScope, "next", iteratorType, {}, {}, false, node);
229
1/2
✗ Branch 0 (170→171) not taken.
✓ Branch 1 (170→172) taken 87 times.
87 assert(node->nextFct != nullptr);
230
231 // Retrieve item variable entry
232
1/2
✓ Branch 0 (172→173) taken 87 times.
✗ Branch 1 (172→342) not taken.
87 SymbolTableEntry *itemVarSymbol = currentScope->lookupStrict(node->itemVarDecl->varName);
233
1/2
✗ Branch 0 (175→176) not taken.
✓ Branch 1 (175→177) taken 87 times.
87 assert(itemVarSymbol != nullptr);
234
235 // Check type of the item
236
2/4
✓ Branch 0 (177→178) taken 87 times.
✗ Branch 1 (177→336) not taken.
✓ Branch 2 (178→179) taken 87 times.
✗ Branch 3 (178→334) not taken.
87 auto itemType = std::any_cast<QualType>(visit(node->itemVarDecl));
237
2/6
✓ Branch 0 (180→181) taken 87 times.
✗ Branch 1 (180→342) not taken.
✗ Branch 2 (181→182) not taken.
✓ Branch 3 (181→184) taken 87 times.
✗ Branch 4 (182→183) not taken.
✗ Branch 5 (182→337) not taken.
87 HANDLE_UNRESOLVED_TYPE_PTR(itemType)
238
3/4
✓ Branch 0 (184→185) taken 87 times.
✗ Branch 1 (184→342) not taken.
✓ Branch 2 (185→186) taken 4 times.
✓ Branch 3 (185→188) taken 83 times.
87 if (itemType.is(TY_DYN)) { // Perform type inference
239 // Update evaluated symbol type of the declaration data type
240
1/2
✓ Branch 0 (186→187) taken 4 times.
✗ Branch 1 (186→342) not taken.
4 node->itemVarDecl->dataType->setEvaluatedSymbolType(iteratorItemType, manIdx);
241 // Update item type
242 4 itemType = iteratorItemType;
243 } else {
244 // Check item type
245 83 const ExprResult itemResult = {itemType, itemVarSymbol};
246 83 const ExprResult iteratorItemResult = {iteratorItemType, nullptr /* always a temporary */};
247
2/2
✓ Branch 0 (188→189) taken 82 times.
✓ Branch 1 (188→338) taken 1 times.
83 (void)opRuleManager.getAssignResultType(node->itemVarDecl, itemResult, iteratorItemResult, true, false, ERROR_FOREACH_ITEM);
248 }
249
250 // Update type of item
251
1/2
✓ Branch 0 (190→191) taken 86 times.
✗ Branch 1 (190→342) not taken.
86 itemVarSymbol->updateType(itemType, true);
252
253 // Visit body
254
1/2
✓ Branch 0 (191→192) taken 86 times.
✗ Branch 1 (191→340) not taken.
86 visit(node->body);
255
256
1/2
✓ Branch 0 (193→194) taken 86 times.
✗ Branch 1 (193→341) not taken.
86 return nullptr;
257 90 }
258
259 650 std::any TypeChecker::visitWhileLoop(WhileLoopNode *node) {
260 // Change to while body scope
261
2/4
✓ Branch 0 (2→3) taken 650 times.
✗ Branch 1 (2→33) not taken.
✓ Branch 2 (3→4) taken 650 times.
✗ Branch 3 (3→31) not taken.
650 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::WHILE_BODY);
262
263 // Visit condition
264
3/4
✓ Branch 0 (5→6) taken 649 times.
✓ Branch 1 (5→37) taken 1 times.
✓ Branch 2 (6→7) taken 649 times.
✗ Branch 3 (6→35) not taken.
650 const QualType conditionType = std::any_cast<ExprResult>(visit(node->condition)).type;
265
2/6
✓ Branch 0 (8→9) taken 649 times.
✗ Branch 1 (8→49) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→12) taken 649 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→39) not taken.
649 HANDLE_UNRESOLVED_TYPE_PTR(conditionType)
266 // Check if condition evaluates to bool
267
3/4
✓ Branch 0 (12→13) taken 649 times.
✗ Branch 1 (12→49) not taken.
✓ Branch 2 (13→14) taken 1 times.
✓ Branch 3 (13→24) taken 648 times.
649 if (!conditionType.is(TY_BOOL))
268
4/8
✓ Branch 0 (16→17) taken 1 times.
✗ Branch 1 (16→42) not taken.
✓ Branch 2 (17→18) taken 1 times.
✗ Branch 3 (17→40) not taken.
✓ Branch 4 (20→21) taken 1 times.
✗ Branch 5 (20→46) not taken.
✓ Branch 6 (21→22) taken 1 times.
✗ Branch 7 (21→46) not taken.
3 SOFT_ERROR_ER(node->condition, CONDITION_MUST_BE_BOOL, "While loop condition must be of type bool")
269
270 // Visit body
271
1/2
✓ Branch 0 (24→25) taken 648 times.
✗ Branch 1 (24→47) not taken.
648 visit(node->body);
272
273
1/2
✓ Branch 0 (26→27) taken 648 times.
✗ Branch 1 (26→48) not taken.
648 return nullptr;
274 650 }
275
276 9 std::any TypeChecker::visitDoWhileLoop(DoWhileLoopNode *node) {
277 // Change to while body scope
278
2/4
✓ Branch 0 (2→3) taken 9 times.
✗ Branch 1 (2→33) not taken.
✓ Branch 2 (3→4) taken 9 times.
✗ Branch 3 (3→31) not taken.
9 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::WHILE_BODY);
279
280 // Visit body
281
1/2
✓ Branch 0 (5→6) taken 9 times.
✗ Branch 1 (5→35) not taken.
9 visit(node->body);
282
283 // Visit condition
284
2/4
✓ Branch 0 (7→8) taken 9 times.
✗ Branch 1 (7→38) not taken.
✓ Branch 2 (8→9) taken 9 times.
✗ Branch 3 (8→36) not taken.
9 const QualType conditionType = std::any_cast<ExprResult>(visit(node->condition)).type;
285
2/6
✓ Branch 0 (10→11) taken 9 times.
✗ Branch 1 (10→49) not taken.
✗ Branch 2 (11→12) not taken.
✓ Branch 3 (11→14) taken 9 times.
✗ Branch 4 (12→13) not taken.
✗ Branch 5 (12→40) not taken.
9 HANDLE_UNRESOLVED_TYPE_PTR(conditionType)
286 // Check if condition evaluates to bool
287
3/4
✓ Branch 0 (14→15) taken 9 times.
✗ Branch 1 (14→49) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→26) taken 8 times.
9 if (!conditionType.is(TY_BOOL))
288
4/8
✓ Branch 0 (18→19) taken 1 times.
✗ Branch 1 (18→43) not taken.
✓ Branch 2 (19→20) taken 1 times.
✗ Branch 3 (19→41) not taken.
✓ Branch 4 (22→23) taken 1 times.
✗ Branch 5 (22→47) not taken.
✓ Branch 6 (23→24) taken 1 times.
✗ Branch 7 (23→47) not taken.
3 SOFT_ERROR_ER(node->condition, CONDITION_MUST_BE_BOOL, "Do-While loop condition must be of type bool")
289
290
1/2
✓ Branch 0 (26→27) taken 8 times.
✗ Branch 1 (26→48) not taken.
8 return nullptr;
291 9 }
292
293 3785 std::any TypeChecker::visitIfStmt(IfStmtNode *node) {
294 // Change to then body scope
295
2/4
✓ Branch 0 (2→3) taken 3785 times.
✗ Branch 1 (2→41) not taken.
✓ Branch 2 (3→4) taken 3785 times.
✗ Branch 3 (3→39) not taken.
3785 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::IF_ELSE_BODY);
296
297 // Visit condition
298
3/4
✓ Branch 0 (5→6) taken 3783 times.
✓ Branch 1 (5→45) taken 2 times.
✓ Branch 2 (6→7) taken 3783 times.
✗ Branch 3 (6→43) not taken.
3785 const QualType conditionType = std::any_cast<ExprResult>(visit(node->condition)).type;
299
4/6
✓ Branch 0 (8→9) taken 3783 times.
✗ Branch 1 (8→59) not taken.
✓ Branch 2 (9→10) taken 1 times.
✓ Branch 3 (9→12) taken 3782 times.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→47) not taken.
3783 HANDLE_UNRESOLVED_TYPE_PTR(conditionType)
300 // Check if condition evaluates to bool
301
3/4
✓ Branch 0 (12→13) taken 3782 times.
✗ Branch 1 (12→59) not taken.
✓ Branch 2 (13→14) taken 2 times.
✓ Branch 3 (13→24) taken 3780 times.
3782 if (!conditionType.is(TY_BOOL))
302
4/8
✓ Branch 0 (16→17) taken 2 times.
✗ Branch 1 (16→50) not taken.
✓ Branch 2 (17→18) taken 2 times.
✗ Branch 3 (17→48) not taken.
✓ Branch 4 (20→21) taken 2 times.
✗ Branch 5 (20→54) not taken.
✓ Branch 6 (21→22) taken 2 times.
✗ Branch 7 (21→54) not taken.
6 SOFT_ERROR_ER(node->condition, CONDITION_MUST_BE_BOOL, "If condition must be of type bool")
303
304 // Warning for bool assignment
305
2/2
✓ Branch 0 (24→25) taken 1 times.
✓ Branch 1 (24→27) taken 3779 times.
3780 if (node->condition->op == AssignExprNode::AssignOp::OP_ASSIGN)
306
1/2
✓ Branch 0 (25→26) taken 1 times.
✗ Branch 1 (25→55) not taken.
1 sourceFile->compilerOutput.warnings.emplace_back(node->condition->codeLoc, BOOL_ASSIGN_AS_CONDITION,
307 "If you want to compare the values, use '=='");
308
309 // Visit body
310
1/2
✓ Branch 0 (27→28) taken 3780 times.
✗ Branch 1 (27→56) not taken.
3780 visit(node->thenBody);
311
312 // Leave then body scope
313
1/2
✓ Branch 0 (29→30) taken 3780 times.
✗ Branch 1 (29→59) not taken.
3780 scopeHandle.leaveScopeEarly();
314
315 // Visit else statement if existing
316
2/2
✓ Branch 0 (30→31) taken 146 times.
✓ Branch 1 (30→34) taken 3634 times.
3780 if (node->elseStmt)
317
1/2
✓ Branch 0 (31→32) taken 146 times.
✗ Branch 1 (31→57) not taken.
146 visit(node->elseStmt);
318
319
1/2
✓ Branch 0 (34→35) taken 3780 times.
✗ Branch 1 (34→58) not taken.
3780 return nullptr;
320 3785 }
321
322 146 std::any TypeChecker::visitElseStmt(ElseStmtNode *node) {
323 // Visit if statement in the case of an else if branch
324
2/2
✓ Branch 0 (2→3) taken 43 times.
✓ Branch 1 (2→7) taken 103 times.
146 if (node->isElseIf) {
325
1/2
✓ Branch 0 (3→4) taken 43 times.
✗ Branch 1 (3→16) not taken.
43 visit(node->ifStmt);
326
1/2
✓ Branch 0 (5→6) taken 43 times.
✗ Branch 1 (5→17) not taken.
43 return nullptr;
327 }
328
329 // Change to else body scope
330
2/4
✓ Branch 0 (7→8) taken 103 times.
✗ Branch 1 (7→20) not taken.
✓ Branch 2 (8→9) taken 103 times.
✗ Branch 3 (8→18) not taken.
103 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::IF_ELSE_BODY);
331
332 // Visit body
333
1/2
✓ Branch 0 (10→11) taken 103 times.
✗ Branch 1 (10→22) not taken.
103 visit(node->body);
334
335
1/2
✓ Branch 0 (12→13) taken 103 times.
✗ Branch 1 (12→23) not taken.
103 return nullptr;
336 103 }
337
338 12 std::any TypeChecker::visitSwitchStmt(SwitchStmtNode *node) {
339 // Check expression type
340
2/4
✓ Branch 0 (2→3) taken 12 times.
✗ Branch 1 (2→56) not taken.
✓ Branch 2 (3→4) taken 12 times.
✗ Branch 3 (3→54) not taken.
12 const QualType exprType = std::any_cast<ExprResult>(visit(node->assignExpr)).type;
341
2/6
✓ Branch 0 (5→6) taken 12 times.
✗ Branch 1 (5→83) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→9) taken 12 times.
✗ Branch 4 (7→8) not taken.
✗ Branch 5 (7→58) not taken.
12 HANDLE_UNRESOLVED_TYPE_PTR(exprType)
342
3/4
✓ Branch 0 (9→10) taken 12 times.
✗ Branch 1 (9→59) not taken.
✓ Branch 2 (10→11) taken 1 times.
✓ Branch 3 (10→21) taken 11 times.
12 if (!exprType.isOneOf({TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_CHAR, TY_BOOL}))
343
4/8
✓ Branch 0 (13→14) taken 1 times.
✗ Branch 1 (13→62) not taken.
✓ Branch 2 (14→15) taken 1 times.
✗ Branch 3 (14→60) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→66) not taken.
✓ Branch 6 (18→19) taken 1 times.
✗ Branch 7 (18→66) not taken.
3 SOFT_ERROR_ER(node->assignExpr, SWITCH_EXPR_MUST_BE_PRIMITIVE,
344 "Switch expression must be of int, short, long, byte, char or bool type")
345
346 // Visit children
347
1/2
✓ Branch 0 (21→22) taken 11 times.
✗ Branch 1 (21→67) not taken.
11 visitChildren(node);
348
349 // Check if case constant types match switch expression type
350
2/2
✓ Branch 0 (49→25) taken 53 times.
✓ Branch 1 (49→50) taken 9 times.
62 for (const CaseBranchNode *caseBranchNode : node->caseBranches)
351
2/2
✓ Branch 0 (46→28) taken 70 times.
✓ Branch 1 (46→47) taken 51 times.
121 for (CaseConstantNode *constantNode : caseBranchNode->caseConstants) {
352
2/4
✓ Branch 0 (29→30) taken 70 times.
✗ Branch 1 (29→70) not taken.
✓ Branch 2 (30→31) taken 70 times.
✗ Branch 3 (30→68) not taken.
70 const QualType constantType = std::any_cast<ExprResult>(visit(constantNode)).type;
353
3/4
✓ Branch 0 (32→33) taken 70 times.
✗ Branch 1 (32→79) not taken.
✓ Branch 2 (33→34) taken 2 times.
✓ Branch 3 (33→44) taken 68 times.
70 if (!constantType.matches(exprType, false, true, true))
354
4/8
✓ Branch 0 (36→37) taken 2 times.
✗ Branch 1 (36→74) not taken.
✓ Branch 2 (37→38) taken 2 times.
✗ Branch 3 (37→72) not taken.
✓ Branch 4 (40→41) taken 2 times.
✗ Branch 5 (40→78) not taken.
✓ Branch 6 (41→42) taken 2 times.
✗ Branch 7 (41→78) not taken.
6 SOFT_ERROR_ER(constantNode, SWITCH_CASE_TYPE_MISMATCH, "Case value type does not match the switch expression type")
355 }
356
357
1/2
✓ Branch 0 (50→51) taken 9 times.
✗ Branch 1 (50→82) not taken.
9 return nullptr;
358 }
359
360 53 std::any TypeChecker::visitCaseBranch(CaseBranchNode *node) {
361 // Change to case body scope
362
2/4
✓ Branch 0 (2→3) taken 53 times.
✗ Branch 1 (2→21) not taken.
✓ Branch 2 (3→4) taken 53 times.
✗ Branch 3 (3→19) not taken.
53 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::CASE_BODY);
363
364 // Visit constant list
365
2/2
✓ Branch 0 (12→7) taken 70 times.
✓ Branch 1 (12→13) taken 53 times.
123 for (CaseConstantNode *constant : node->caseConstants)
366
1/2
✓ Branch 0 (8→9) taken 70 times.
✗ Branch 1 (8→23) not taken.
70 visit(constant);
367
368 // Visit body
369
1/2
✓ Branch 0 (13→14) taken 53 times.
✗ Branch 1 (13→25) not taken.
53 visit(node->body);
370
371
1/2
✓ Branch 0 (15→16) taken 53 times.
✗ Branch 1 (15→26) not taken.
106 return nullptr;
372 53 }
373
374 6 std::any TypeChecker::visitDefaultBranch(DefaultBranchNode *node) {
375 // Change to default body scope
376
2/4
✓ Branch 0 (2→3) taken 6 times.
✗ Branch 1 (2→13) not taken.
✓ Branch 2 (3→4) taken 6 times.
✗ Branch 3 (3→11) not taken.
6 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::DEFAULT_BODY);
377
378 // Visit body
379
1/2
✓ Branch 0 (5→6) taken 6 times.
✗ Branch 1 (5→15) not taken.
6 visit(node->body);
380
381
1/2
✓ Branch 0 (7→8) taken 6 times.
✗ Branch 1 (7→16) not taken.
12 return nullptr;
382 6 }
383
384 27 std::any TypeChecker::visitAnonymousBlockStmt(AnonymousBlockStmtNode *node) {
385 // Change to anonymous scope body scope
386
2/4
✓ Branch 0 (2→3) taken 27 times.
✗ Branch 1 (2→13) not taken.
✓ Branch 2 (3→4) taken 27 times.
✗ Branch 3 (3→11) not taken.
27 ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::ANONYMOUS_BLOCK_BODY);
387
388 // Visit body
389
1/2
✓ Branch 0 (5→6) taken 27 times.
✗ Branch 1 (5→15) not taken.
27 visit(node->body);
390
391
1/2
✓ Branch 0 (7→8) taken 27 times.
✗ Branch 1 (7→16) not taken.
54 return nullptr;
392 27 }
393
394 16737 std::any TypeChecker::visitStmtLst(StmtLstNode *node) {
395 // Visit nodes in this scope
396
2/2
✓ Branch 0 (15→4) taken 32169 times.
✓ Branch 1 (15→16) taken 16706 times.
48875 for (StmtNode *stmt : node->statements) {
397
1/2
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 32169 times.
32169 if (!stmt)
398 continue;
399 // Print warning if statement is unreachable
400
2/2
✓ Branch 0 (7→8) taken 7 times.
✓ Branch 1 (7→10) taken 32162 times.
32169 if (stmt->unreachable) {
401
1/2
✓ Branch 0 (8→9) taken 7 times.
✗ Branch 1 (8→20) not taken.
7 warnings.emplace_back(stmt->codeLoc, UNREACHABLE_CODE, "This statement is unreachable");
402 7 continue;
403 }
404 // Visit the statement
405
2/2
✓ Branch 0 (10→11) taken 32131 times.
✓ Branch 1 (10→21) taken 31 times.
32162 visit(stmt);
406 }
407
408 // Do cleanup of this scope, e.g. dtor calls for struct instances
409 16706 doScopeCleanup(node);
410
411
1/2
✓ Branch 0 (17→18) taken 16706 times.
✗ Branch 1 (17→23) not taken.
16706 return nullptr;
412 }
413
414 12982 std::any TypeChecker::visitParamLst(ParamLstNode *node) {
415 12982 NamedParamList namedParams;
416 12982 bool metOptional = false;
417
418
2/2
✓ Branch 0 (35→4) taken 20276 times.
✓ Branch 1 (35→36) taken 12982 times.
33258 for (DeclStmtNode *param : node->params) {
419 // Visit param
420
2/4
✓ Branch 0 (5→6) taken 20276 times.
✗ Branch 1 (5→43) not taken.
✓ Branch 2 (6→7) taken 20276 times.
✗ Branch 3 (6→41) not taken.
20276 const auto paramType = std::any_cast<QualType>(visit(param));
421
3/4
✓ Branch 0 (8→9) taken 20276 times.
✗ Branch 1 (8→57) not taken.
✓ Branch 2 (9→10) taken 2 times.
✓ Branch 3 (9→11) taken 20274 times.
20276 if (paramType.is(TY_UNRESOLVED))
422 11 continue;
423
424 // Check if the type could be inferred. Dyn without a default value is forbidden
425
3/4
✓ Branch 0 (11→12) taken 20274 times.
✗ Branch 1 (11→57) not taken.
✓ Branch 2 (12→13) taken 3 times.
✓ Branch 3 (12→19) taken 20271 times.
20274 if (paramType.is(TY_DYN)) {
426
3/6
✓ Branch 0 (13→14) taken 3 times.
✗ Branch 1 (13→48) not taken.
✓ Branch 2 (14→15) taken 3 times.
✗ Branch 3 (14→46) not taken.
✓ Branch 4 (15→16) taken 3 times.
✗ Branch 5 (15→44) not taken.
3 softError(node, FCT_PARAM_IS_TYPE_DYN, "Type of parameter '" + param->varName + "' is invalid");
427 3 continue;
428 }
429
430 // Ensure that no optional param comes after a mandatory param
431
2/2
✓ Branch 0 (19→20) taken 2158 times.
✓ Branch 1 (19→21) taken 18113 times.
20271 if (param->hasAssignment) {
432 2158 metOptional = true;
433
2/2
✓ Branch 0 (21→22) taken 6 times.
✓ Branch 1 (21→29) taken 18107 times.
18113 } else if (metOptional) {
434
2/4
✓ Branch 0 (24→25) taken 6 times.
✗ Branch 1 (24→52) not taken.
✓ Branch 2 (25→26) taken 6 times.
✗ Branch 3 (25→50) not taken.
6 softError(param, INVALID_PARAM_ORDER, "Mandatory parameters must go before any optional parameters");
435 6 continue;
436 }
437
438 // Add parameter to named param list
439
1/2
✓ Branch 0 (30→31) taken 20265 times.
✗ Branch 1 (30→56) not taken.
20265 namedParams.push_back({param->varName.c_str(), paramType, metOptional});
440 }
441
442
1/2
✓ Branch 0 (36→37) taken 12982 times.
✗ Branch 1 (36→59) not taken.
25964 return namedParams;
443 12982 }
444
445 1260 std::any TypeChecker::visitField(FieldNode *node) {
446
2/4
✓ Branch 0 (2→3) taken 1260 times.
✗ Branch 1 (2→37) not taken.
✓ Branch 2 (3→4) taken 1260 times.
✗ Branch 3 (3→35) not taken.
1260 auto fieldType = std::any_cast<QualType>(visit(node->dataType));
447
4/6
✓ Branch 0 (5→6) taken 1260 times.
✗ Branch 1 (5→50) not taken.
✓ Branch 2 (6→7) taken 1 times.
✓ Branch 3 (6→9) taken 1259 times.
✓ Branch 4 (7→8) taken 1 times.
✗ Branch 5 (7→50) not taken.
1260 HANDLE_UNRESOLVED_TYPE_QT(fieldType)
448
449
2/2
✓ Branch 0 (9→10) taken 165 times.
✓ Branch 1 (9→31) taken 1094 times.
1259 if (TernaryExprNode *defaultValueNode = node->defaultValue) {
450
2/4
✓ Branch 0 (10→11) taken 165 times.
✗ Branch 1 (10→40) not taken.
✓ Branch 2 (11→12) taken 165 times.
✗ Branch 3 (11→38) not taken.
165 const QualType defaultValueType = std::any_cast<ExprResult>(visit(defaultValueNode)).type;
451
2/6
✓ Branch 0 (13→14) taken 165 times.
✗ Branch 1 (13→49) not taken.
✗ Branch 2 (14→15) not taken.
✓ Branch 3 (14→17) taken 165 times.
✗ Branch 4 (15→16) not taken.
✗ Branch 5 (15→49) not taken.
166 HANDLE_UNRESOLVED_TYPE_QT(defaultValueType)
452
3/4
✓ Branch 0 (17→18) taken 165 times.
✗ Branch 1 (17→49) not taken.
✓ Branch 2 (18→19) taken 1 times.
✓ Branch 3 (18→29) taken 164 times.
165 if (!fieldType.matches(defaultValueType, false, true, true))
453
4/8
✓ Branch 0 (21→22) taken 1 times.
✗ Branch 1 (21→44) not taken.
✓ Branch 2 (22→23) taken 1 times.
✗ Branch 3 (22→42) not taken.
✓ Branch 4 (25→26) taken 1 times.
✗ Branch 5 (25→48) not taken.
✓ Branch 6 (26→27) taken 1 times.
✗ Branch 7 (26→48) not taken.
3 SOFT_ERROR_QT(node, FIELD_TYPE_NOT_MATCHING, "Type of the default values does not match the field type")
454 }
455
456
1/2
✓ Branch 0 (31→32) taken 1258 times.
✗ Branch 1 (31→50) not taken.
1258 return fieldType;
457 }
458
459 186 std::any TypeChecker::visitSignature(SignatureNode *node) {
460 186 const bool isFunction = node->signatureType == SignatureNode::SignatureType::TYPE_FUNCTION;
461
462 // Retrieve function template types
463 186 std::vector<GenericType> usedGenericTypes;
464
2/2
✓ Branch 0 (2→3) taken 97 times.
✓ Branch 1 (2→33) taken 89 times.
186 if (node->hasTemplateTypes) {
465
2/2
✓ Branch 0 (31→5) taken 97 times.
✓ Branch 1 (31→32) taken 96 times.
193 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
466 // Visit template type
467
2/4
✓ Branch 0 (6→7) taken 97 times.
✗ Branch 1 (6→108) not taken.
✓ Branch 2 (7→8) taken 97 times.
✗ Branch 3 (7→106) not taken.
97 auto templateType = std::any_cast<QualType>(visit(dataType));
468
2/4
✓ Branch 0 (9→10) taken 97 times.
✗ Branch 1 (9→117) not taken.
✗ Branch 2 (10→11) not taken.
✓ Branch 3 (10→13) taken 97 times.
97 if (templateType.is(TY_UNRESOLVED))
469 return static_cast<std::vector<Function *> *>(nullptr);
470 // Check if it is a generic type
471
3/4
✓ Branch 0 (13→14) taken 97 times.
✗ Branch 1 (13→117) not taken.
✓ Branch 2 (14→15) taken 1 times.
✓ Branch 3 (14→23) taken 96 times.
97 if (!templateType.is(TY_GENERIC)) {
472
2/4
✓ Branch 0 (17→18) taken 1 times.
✗ Branch 1 (17→112) not taken.
✓ Branch 2 (18→19) taken 1 times.
✗ Branch 3 (18→110) not taken.
1 softError(dataType, EXPECTED_GENERIC_TYPE, "A template list can only contain generic types");
473
1/2
✓ Branch 0 (21→22) taken 1 times.
✗ Branch 1 (21→116) not taken.
1 return static_cast<std::vector<Function *> *>(nullptr);
474 }
475 // Convert generic symbol type to generic type
476
2/4
✓ Branch 0 (23→24) taken 96 times.
✗ Branch 1 (23→117) not taken.
✓ Branch 2 (24→25) taken 96 times.
✗ Branch 3 (24→117) not taken.
96 const GenericType *genericType = rootScope->lookupGenericType(templateType.getSubType());
477
1/2
✗ Branch 0 (25→26) not taken.
✓ Branch 1 (25→27) taken 96 times.
96 assert(genericType != nullptr);
478
1/2
✓ Branch 0 (27→28) taken 96 times.
✗ Branch 1 (27→117) not taken.
96 usedGenericTypes.push_back(*genericType);
479 }
480 }
481
482 // Visit return type
483
1/2
✓ Branch 0 (33→34) taken 185 times.
✗ Branch 1 (33→159) not taken.
185 QualType returnType(TY_DYN);
484
2/2
✓ Branch 0 (34→35) taken 144 times.
✓ Branch 1 (34→51) taken 41 times.
185 if (isFunction) {
485
2/4
✓ Branch 0 (35→36) taken 144 times.
✗ Branch 1 (35→121) not taken.
✓ Branch 2 (36→37) taken 144 times.
✗ Branch 3 (36→119) not taken.
144 returnType = std::any_cast<QualType>(visit(node->returnType));
486
2/4
✓ Branch 0 (38→39) taken 144 times.
✗ Branch 1 (38→159) not taken.
✗ Branch 2 (39→40) not taken.
✓ Branch 3 (39→42) taken 144 times.
144 if (returnType.is(TY_UNRESOLVED))
487 return static_cast<std::vector<Function *> *>(nullptr);
488
489
3/4
✓ Branch 0 (42→43) taken 144 times.
✗ Branch 1 (42→159) not taken.
✓ Branch 2 (43→44) taken 1 times.
✓ Branch 3 (43→51) taken 143 times.
144 if (!returnType.isCoveredByGenericTypeList(usedGenericTypes))
490
2/4
✓ Branch 0 (46→47) taken 1 times.
✗ Branch 1 (46→126) not taken.
✓ Branch 2 (47→48) taken 1 times.
✗ Branch 3 (47→124) not taken.
2 softError(node->returnType, GENERIC_TYPE_NOT_IN_TEMPLATE,
491 "Generic return type not included in the template type list of the function");
492 }
493
494 // Visit params
495 185 QualTypeList paramTypes;
496 185 ParamList paramList;
497
2/2
✓ Branch 0 (51→52) taken 12 times.
✓ Branch 1 (51→80) taken 173 times.
185 if (node->hasParams) {
498
1/2
✓ Branch 0 (53→54) taken 12 times.
✗ Branch 1 (53→155) not taken.
12 paramList.reserve(node->paramTypeLst->dataTypes.size());
499
2/2
✓ Branch 0 (78→56) taken 14 times.
✓ Branch 1 (78→79) taken 12 times.
26 for (DataTypeNode *param : node->paramTypeLst->dataTypes) {
500
2/4
✓ Branch 0 (57→58) taken 14 times.
✗ Branch 1 (57→132) not taken.
✓ Branch 2 (58→59) taken 14 times.
✗ Branch 3 (58→130) not taken.
14 auto paramType = std::any_cast<QualType>(visit(param));
501
2/4
✓ Branch 0 (60→61) taken 14 times.
✗ Branch 1 (60→141) not taken.
✗ Branch 2 (61→62) not taken.
✓ Branch 3 (61→64) taken 14 times.
14 if (paramType.is(TY_UNRESOLVED))
502 return static_cast<std::vector<Function *> *>(nullptr);
503
504 // Check if the type is present in the template for generic types
505
3/4
✓ Branch 0 (64→65) taken 14 times.
✗ Branch 1 (64→141) not taken.
✓ Branch 2 (65→66) taken 2 times.
✓ Branch 3 (65→73) taken 12 times.
14 if (!paramType.isCoveredByGenericTypeList(usedGenericTypes)) {
506
2/4
✓ Branch 0 (68→69) taken 2 times.
✗ Branch 1 (68→136) not taken.
✓ Branch 2 (69→70) taken 2 times.
✗ Branch 3 (69→134) not taken.
2 softError(node->paramTypeLst, GENERIC_TYPE_NOT_IN_TEMPLATE,
507 "Generic param type not included in the template type list of the function");
508 2 continue;
509 }
510
511
1/2
✓ Branch 0 (73→74) taken 12 times.
✗ Branch 1 (73→141) not taken.
12 paramTypes.push_back(paramType);
512
1/2
✓ Branch 0 (74→75) taken 12 times.
✗ Branch 1 (74→140) not taken.
12 paramList.push_back({paramType, false});
513 }
514 }
515
516 // Build signature object
517
4/8
✓ Branch 0 (80→81) taken 185 times.
✗ Branch 1 (80→150) not taken.
✓ Branch 2 (81→82) taken 185 times.
✗ Branch 3 (81→147) not taken.
✓ Branch 4 (82→83) taken 185 times.
✗ Branch 5 (82→144) not taken.
✓ Branch 6 (83→84) taken 185 times.
✗ Branch 7 (83→143) not taken.
185 const Function signature(node->methodName, nullptr, QualType(TY_DYN), returnType, paramList, usedGenericTypes, node);
518
519 // Add signature to current scope
520
1/2
✓ Branch 0 (88→89) taken 185 times.
✗ Branch 1 (88→153) not taken.
185 Function *manifestation = FunctionManager::insert(currentScope, signature, &node->signatureManifestations);
521 185 manifestation->entry = node->entry;
522 185 manifestation->used = true;
523
524 // Prepare signature type
525
2/2
✓ Branch 0 (89→90) taken 144 times.
✓ Branch 1 (89→91) taken 41 times.
185 const SuperType superType = isFunction ? TY_FUNCTION : TY_PROCEDURE;
526
2/4
✓ Branch 0 (92→93) taken 185 times.
✗ Branch 1 (92→151) not taken.
✓ Branch 2 (93→94) taken 185 times.
✗ Branch 3 (93→151) not taken.
185 QualType signatureType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
527 185 signatureType.setQualifiers(node->signatureQualifiers);
528
529 // Set entry to signature type
530
1/2
✗ Branch 0 (95→96) not taken.
✓ Branch 1 (95→97) taken 185 times.
185 assert(node->entry != nullptr);
531
1/2
✓ Branch 0 (97→98) taken 185 times.
✗ Branch 1 (97→153) not taken.
185 node->entry->updateType(signatureType, false);
532 185 node->entry->used = true;
533
534
1/2
✓ Branch 0 (98→99) taken 185 times.
✗ Branch 1 (98→152) not taken.
185 return &node->signatureManifestations;
535 186 }
536
537 26864 std::any TypeChecker::visitDeclStmt(DeclStmtNode *node) {
538 // Retrieve entry of the lhs variable
539
1/2
✓ Branch 0 (2→3) taken 26864 times.
✗ Branch 1 (2→180) not taken.
26864 SymbolTableEntry *localVarEntry = currentScope->lookupStrict(node->varName);
540
1/2
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 26864 times.
26864 assert(localVarEntry != nullptr);
541
542 26864 QualType localVarType;
543
2/2
✓ Branch 0 (7→8) taken 8442 times.
✓ Branch 1 (7→57) taken 18422 times.
26864 if (node->hasAssignment) {
544 // Visit the right side
545
3/4
✓ Branch 0 (8→9) taken 8437 times.
✓ Branch 1 (8→130) taken 5 times.
✓ Branch 2 (9→10) taken 8437 times.
✗ Branch 3 (9→128) not taken.
8442 auto rhs = std::any_cast<ExprResult>(visit(node->assignExpr));
546 8437 auto [rhsTy, rhsEntry] = rhs;
547
548 // Visit data type
549
3/4
✓ Branch 0 (11→12) taken 8434 times.
✓ Branch 1 (11→133) taken 3 times.
✓ Branch 2 (12→13) taken 8434 times.
✗ Branch 3 (12→131) not taken.
8437 localVarType = std::any_cast<QualType>(visit(node->dataType));
550
551 // Check if type has to be inferred or both types are fixed
552
8/10
✓ Branch 0 (14→15) taken 8434 times.
✗ Branch 1 (14→149) not taken.
✓ Branch 2 (15→16) taken 8430 times.
✓ Branch 3 (15→19) taken 4 times.
✓ Branch 4 (16→17) taken 8430 times.
✗ Branch 5 (16→149) not taken.
✓ Branch 6 (17→18) taken 8410 times.
✓ Branch 7 (17→19) taken 20 times.
✓ Branch 8 (20→21) taken 8410 times.
✓ Branch 9 (20→45) taken 24 times.
8434 if (!localVarType.is(TY_UNRESOLVED) && !rhsTy.is(TY_UNRESOLVED)) {
553 8410 const ExprResult lhsResult = {localVarType, localVarEntry};
554
2/2
✓ Branch 0 (21→22) taken 8400 times.
✓ Branch 1 (21→147) taken 10 times.
8410 const auto [type, copyCtor] = opRuleManager.getAssignResultType(node, lhsResult, rhs, true);
555 8400 localVarType = type;
556 8400 node->calledCopyCtor = copyCtor;
557
558 // If this is a struct type, check if the type is known. If not, error out
559
8/14
✓ Branch 0 (24→25) taken 8400 times.
✗ Branch 1 (24→135) not taken.
✓ Branch 2 (25→26) taken 1062 times.
✓ Branch 3 (25→31) taken 7338 times.
✓ Branch 4 (26→27) taken 1062 times.
✗ Branch 5 (26→135) not taken.
✓ Branch 6 (27→28) taken 1062 times.
✗ Branch 7 (27→135) not taken.
✓ Branch 8 (28→29) taken 1062 times.
✗ Branch 9 (28→135) not taken.
✗ Branch 10 (29→30) not taken.
✓ Branch 11 (29→31) taken 1062 times.
✗ Branch 12 (32→33) not taken.
✓ Branch 13 (32→44) taken 8400 times.
8400 if (localVarType.isBase(TY_STRUCT) && !sourceFile->getNameRegistryEntry(localVarType.getBase().getSubType())) {
560 const std::string structName = localVarType.getBase().getSubType();
561 softError(node->dataType, UNKNOWN_DATATYPE, "Unknown struct type '" + structName + "'. Forgot to import?");
562 localVarType = QualType(TY_UNRESOLVED);
563 }
564 } else {
565
1/2
✓ Branch 0 (45→46) taken 24 times.
✗ Branch 1 (45→148) not taken.
24 localVarType = QualType(TY_UNRESOLVED);
566 }
567
568 // If there is an anonymous entry attached (e.g. for struct instantiation) and we take over ownership, delete it
569
9/10
✓ Branch 0 (47→48) taken 8424 times.
✗ Branch 1 (47→149) not taken.
✓ Branch 2 (48→49) taken 8275 times.
✓ Branch 3 (48→52) taken 149 times.
✓ Branch 4 (49→50) taken 1713 times.
✓ Branch 5 (49→52) taken 6562 times.
✓ Branch 6 (50→51) taken 840 times.
✓ Branch 7 (50→52) taken 873 times.
✓ Branch 8 (53→54) taken 840 times.
✓ Branch 9 (53→56) taken 7584 times.
8424 if (!localVarType.isRef() && rhsEntry != nullptr && rhsEntry->anonymous) {
570
1/2
✓ Branch 0 (54→55) taken 840 times.
✗ Branch 1 (54→149) not taken.
840 currentScope->symbolTable.deleteAnonymous(rhsEntry->name);
571 840 rhs.entry = rhsEntry = nullptr;
572 }
573 } else {
574 // Visit data type
575
2/4
✓ Branch 0 (57→58) taken 18422 times.
✗ Branch 1 (57→152) not taken.
✓ Branch 2 (58→59) taken 18422 times.
✗ Branch 3 (58→150) not taken.
18422 localVarType = std::any_cast<QualType>(visit(node->dataType));
576
577 // References with no initialization are illegal
578
9/10
✓ Branch 0 (60→61) taken 18422 times.
✗ Branch 1 (60→180) not taken.
✓ Branch 2 (61→62) taken 5604 times.
✓ Branch 3 (61→65) taken 12818 times.
✓ Branch 4 (62→63) taken 56 times.
✓ Branch 5 (62→65) taken 5548 times.
✓ Branch 6 (63→64) taken 1 times.
✓ Branch 7 (63→65) taken 55 times.
✓ Branch 8 (66→67) taken 1 times.
✓ Branch 9 (66→74) taken 18421 times.
18422 if (localVarType.isRef() && !node->isFctParam && !node->isForEachItem)
579
2/4
✓ Branch 0 (69→70) taken 1 times.
✗ Branch 1 (69→156) not taken.
✓ Branch 2 (70→71) taken 1 times.
✗ Branch 3 (70→154) not taken.
2 softError(node, REFERENCE_WITHOUT_INITIALIZER, "References must always be initialized directly");
580
581 // If this is a struct, check for the default ctor
582
9/10
✓ Branch 0 (74→75) taken 18422 times.
✗ Branch 1 (74→180) not taken.
✓ Branch 2 (75→76) taken 650 times.
✓ Branch 3 (75→79) taken 17772 times.
✓ Branch 4 (76→77) taken 152 times.
✓ Branch 5 (76→79) taken 498 times.
✓ Branch 6 (77→78) taken 143 times.
✓ Branch 7 (77→79) taken 9 times.
✓ Branch 8 (80→81) taken 143 times.
✓ Branch 9 (80→121) taken 18279 times.
18422 if (localVarType.is(TY_STRUCT) && !node->isFctParam && !node->isForEachItem) {
583
1/2
✓ Branch 0 (81→82) taken 143 times.
✗ Branch 1 (81→180) not taken.
143 Scope *matchScope = localVarType.getBodyScope();
584
1/2
✗ Branch 0 (82→83) not taken.
✓ Branch 1 (82→84) taken 143 times.
143 assert(matchScope != nullptr);
585 // Check if we are required to call a ctor
586
1/2
✓ Branch 0 (84→85) taken 143 times.
✗ Branch 1 (84→180) not taken.
143 const Struct *spiceStruct = localVarType.getStruct(node);
587
1/2
✗ Branch 0 (85→86) not taken.
✓ Branch 1 (85→87) taken 143 times.
143 assert(spiceStruct != nullptr);
588
1/2
✓ Branch 0 (87→88) taken 143 times.
✗ Branch 1 (87→89) not taken.
143 auto structDeclNode = spice_pointer_cast<StructDefNode *>(spiceStruct->declNode);
589
5/6
✓ Branch 0 (94→95) taken 143 times.
✗ Branch 1 (94→180) not taken.
✓ Branch 2 (95→96) taken 142 times.
✓ Branch 3 (95→97) taken 1 times.
✓ Branch 4 (96→97) taken 19 times.
✓ Branch 5 (96→98) taken 123 times.
143 node->isCtorCallRequired = matchScope->hasRefFields() || structDeclNode->emitVTable;
590 // Check if we have a no-args ctor to call
591
1/2
✓ Branch 0 (99→100) taken 143 times.
✗ Branch 1 (99→180) not taken.
143 const std::string &structName = localVarType.getSubType();
592 143 const QualType &thisType = localVarType;
593
2/4
✓ Branch 0 (104→105) taken 143 times.
✗ Branch 1 (104→162) not taken.
✓ Branch 2 (105→106) taken 143 times.
✗ Branch 3 (105→160) not taken.
429 node->calledInitCtor = FunctionManager::match(this, matchScope, CTOR_FUNCTION_NAME, thisType, {}, {}, false, node);
594
4/4
✓ Branch 0 (110→111) taken 15 times.
✓ Branch 1 (110→121) taken 128 times.
✓ Branch 2 (111→112) taken 2 times.
✓ Branch 3 (111→121) taken 13 times.
143 if (!node->calledInitCtor && node->isCtorCallRequired)
595
5/10
✓ Branch 0 (112→113) taken 2 times.
✗ Branch 1 (112→176) not taken.
✓ Branch 2 (113→114) taken 2 times.
✗ Branch 3 (113→174) not taken.
✓ Branch 4 (114→115) taken 2 times.
✗ Branch 5 (114→172) not taken.
✓ Branch 6 (117→118) taken 2 times.
✗ Branch 7 (117→178) not taken.
✓ Branch 8 (118→119) taken 2 times.
✗ Branch 9 (118→178) not taken.
2 SOFT_ERROR_QT(node, MISSING_NO_ARGS_CTOR, "Struct '" + structName + "' misses a no-args constructor")
596 }
597 }
598
599 // Update the type of the variable
600
1/2
✓ Branch 0 (121→122) taken 26844 times.
✗ Branch 1 (121→180) not taken.
26844 localVarEntry->updateType(localVarType, true);
601
1/2
✓ Branch 0 (122→123) taken 26844 times.
✗ Branch 1 (122→180) not taken.
26844 node->entries.at(manIdx) = localVarEntry;
602
603 // Update the state of the variable
604
1/2
✓ Branch 0 (123→124) taken 26844 times.
✗ Branch 1 (123→179) not taken.
26844 localVarEntry->updateState(INITIALIZED, node);
605
606
1/2
✓ Branch 0 (124→125) taken 26844 times.
✗ Branch 1 (124→180) not taken.
26844 return localVarType;
607 }
608
609 140 std::any TypeChecker::visitCaseConstant(CaseConstantNode *node) {
610 // If we have a normal constant, we can take the symbol type from there
611
2/2
✓ Branch 0 (2→3) taken 36 times.
✓ Branch 1 (2→4) taken 104 times.
140 if (node->constant)
612 36 return visit(node->constant);
613
614 // Check if a local or global variable can be found by searching for the name
615
2/2
✓ Branch 0 (5→6) taken 30 times.
✓ Branch 1 (5→11) taken 74 times.
104 if (node->identifierFragments.size() == 1)
616 60 node->entry = currentScope->lookup(node->identifierFragments.back());
617
618 // If no local or global was found, search in the name registry
619
2/2
✓ Branch 0 (11→12) taken 37 times.
✓ Branch 1 (11→24) taken 67 times.
104 if (!node->entry) {
620 37 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier);
621
1/2
✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→23) taken 37 times.
37 if (!registryEntry)
622 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found")
623 37 node->entry = registryEntry->targetEntry;
624 }
625
1/2
✗ Branch 0 (24→25) not taken.
✓ Branch 1 (24→26) taken 104 times.
104 assert(node->entry != nullptr);
626
627 // Check for the correct type
628 104 const QualType &qualType = node->entry->getQualType();
629
3/4
✓ Branch 0 (27→28) taken 104 times.
✗ Branch 1 (27→51) not taken.
✓ Branch 2 (28→29) taken 2 times.
✓ Branch 3 (28→39) taken 102 times.
104 if (!qualType.isOneOf({TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_CHAR, TY_BOOL}))
630
4/8
✓ Branch 0 (31→32) taken 2 times.
✗ Branch 1 (31→54) not taken.
✓ Branch 2 (32→33) taken 2 times.
✗ Branch 3 (32→52) not taken.
✓ Branch 4 (35→36) taken 2 times.
✗ Branch 5 (35→58) not taken.
✓ Branch 6 (36→37) taken 2 times.
✗ Branch 7 (36→58) not taken.
6 SOFT_ERROR_ER(node, CASE_CONSTANT_INVALID_TYPE, "Case constants must be of type int, short, long, byte, char, bool or enum")
631
632
2/4
✓ Branch 0 (39→40) taken 102 times.
✗ Branch 1 (39→59) not taken.
✓ Branch 2 (40→41) taken 102 times.
✗ Branch 3 (40→59) not taken.
102 return ExprResult{node->setEvaluatedSymbolType(qualType, manIdx)};
633 }
634
635 7862 std::any TypeChecker::visitReturnStmt(ReturnStmtNode *node) {
636 // Retrieve return variable entry
637
1/2
✓ Branch 0 (4→5) taken 7862 times.
✗ Branch 1 (4→68) not taken.
23586 SymbolTableEntry *returnVar = currentScope->lookup(RETURN_VARIABLE_NAME);
638 7862 const bool isFunction = returnVar != nullptr;
639
4/6
✓ Branch 0 (10→11) taken 7816 times.
✓ Branch 1 (10→13) taken 46 times.
✓ Branch 2 (11→12) taken 7816 times.
✗ Branch 3 (11→91) not taken.
✓ Branch 4 (13→14) taken 46 times.
✗ Branch 5 (13→91) not taken.
7862 const QualType returnType = isFunction ? returnVar->getQualType() : QualType(TY_DYN);
640
641 // Check if procedure with return value
642
2/2
✓ Branch 0 (14→15) taken 46 times.
✓ Branch 1 (14→28) taken 7816 times.
7862 if (!isFunction) {
643
2/2
✓ Branch 0 (15→16) taken 2 times.
✓ Branch 1 (15→26) taken 44 times.
46 if (node->hasReturnValue)
644
4/8
✓ Branch 0 (18→19) taken 2 times.
✗ Branch 1 (18→74) not taken.
✓ Branch 2 (19→20) taken 2 times.
✗ Branch 3 (19→72) not taken.
✓ Branch 4 (22→23) taken 2 times.
✗ Branch 5 (22→78) not taken.
✓ Branch 6 (23→24) taken 2 times.
✗ Branch 7 (23→78) not taken.
6 SOFT_ERROR_ER(node->assignExpr, RETURN_WITH_VALUE_IN_PROCEDURE, "Return with value in procedure is not allowed")
645
1/2
✓ Branch 0 (26→27) taken 44 times.
✗ Branch 1 (26→79) not taken.
44 return nullptr;
646 }
647
648
7/8
✓ Branch 0 (28→29) taken 6 times.
✓ Branch 1 (28→33) taken 7810 times.
✓ Branch 2 (30→31) taken 6 times.
✗ Branch 3 (30→91) not taken.
✓ Branch 4 (31→32) taken 2 times.
✓ Branch 5 (31→33) taken 4 times.
✓ Branch 6 (34→35) taken 2 times.
✓ Branch 7 (34→45) taken 7814 times.
7816 if (!node->hasReturnValue && !returnVar->getLifecycle().isInitialized())
649
4/8
✓ Branch 0 (37→38) taken 2 times.
✗ Branch 1 (37→82) not taken.
✓ Branch 2 (38→39) taken 2 times.
✗ Branch 3 (38→80) not taken.
✓ Branch 4 (41→42) taken 2 times.
✗ Branch 5 (41→86) not taken.
✓ Branch 6 (42→43) taken 2 times.
✗ Branch 7 (42→86) not taken.
6 SOFT_ERROR_QT(node, RETURN_WITHOUT_VALUE_RESULT, "Return without value, but result variable is not initialized yet")
650
651
2/2
✓ Branch 0 (45→46) taken 4 times.
✓ Branch 1 (45→48) taken 7810 times.
7814 if (!node->hasReturnValue)
652
1/2
✓ Branch 0 (46→47) taken 4 times.
✗ Branch 1 (46→87) not taken.
4 return nullptr;
653
654 // Visit right side
655
2/4
✓ Branch 0 (48→49) taken 7810 times.
✗ Branch 1 (48→90) not taken.
✓ Branch 2 (49→50) taken 7810 times.
✗ Branch 3 (49→88) not taken.
7810 const auto rhs = std::any_cast<ExprResult>(visit(node->assignExpr));
656
2/6
✓ Branch 0 (51→52) taken 7810 times.
✗ Branch 1 (51→91) not taken.
✗ Branch 2 (52→53) not taken.
✓ Branch 3 (52→55) taken 7810 times.
✗ Branch 4 (53→54) not taken.
✗ Branch 5 (53→91) not taken.
7810 HANDLE_UNRESOLVED_TYPE_QT(rhs.type)
657
658 // Check if types match
659 7810 const ExprResult returnResult = {returnType, returnVar};
660
2/2
✓ Branch 0 (55→56) taken 7807 times.
✓ Branch 1 (55→91) taken 3 times.
7810 auto [_, copyCtor] = opRuleManager.getAssignResultType(node->assignExpr, returnResult, rhs, false, true, ERROR_MSG_RETURN);
661 7807 node->calledCopyCtor = copyCtor;
662
663 // Check if the dtor call on the return value can be skipped
664
2/2
✓ Branch 0 (58→59) taken 2417 times.
✓ Branch 1 (58→62) taken 5390 times.
7807 if (rhs.entry != nullptr) {
665
2/2
✓ Branch 0 (59→60) taken 1107 times.
✓ Branch 1 (59→61) taken 1310 times.
2417 if (rhs.entry->anonymous) {
666 // If there is an anonymous entry attached (e.g. for struct instantiation), delete it
667
1/2
✓ Branch 0 (60→62) taken 1107 times.
✗ Branch 1 (60→91) not taken.
1107 currentScope->symbolTable.deleteAnonymous(rhs.entry->name);
668 } else {
669 // Otherwise omit the destructor call, because the caller destructs the value
670 1310 rhs.entry->omitDtorCall = true;
671 }
672 }
673
674
1/2
✓ Branch 0 (62→63) taken 7807 times.
✗ Branch 1 (62→91) not taken.
7807 return node->returnType = returnType;
675 }
676
677 105 std::any TypeChecker::visitBreakStmt(BreakStmtNode *node) {
678 // Check if the stated number is valid
679
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→12) taken 104 times.
105 if (node->breakTimes < 1)
680
4/8
✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→30) not taken.
✓ Branch 2 (5→6) taken 1 times.
✗ Branch 3 (5→28) not taken.
✓ Branch 4 (8→9) taken 1 times.
✗ Branch 5 (8→34) not taken.
✓ Branch 6 (9→10) taken 1 times.
✗ Branch 7 (9→34) not taken.
1 SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "Break count must be >= 1, you provided " + std::to_string(node->breakTimes))
681
682 // Check if we can break this often
683 104 const unsigned int maxBreaks = currentScope->getLoopNestingDepth();
684
2/2
✓ Branch 0 (13→14) taken 1 times.
✓ Branch 1 (13→25) taken 103 times.
104 if (static_cast<unsigned int>(node->breakTimes) > maxBreaks)
685
5/10
✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→39) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→37) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→35) not taken.
✓ Branch 6 (21→22) taken 1 times.
✗ Branch 7 (21→44) not taken.
✓ Branch 8 (22→23) taken 1 times.
✗ Branch 9 (22→44) not taken.
1 SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "We can only break " + std::to_string(maxBreaks) + " time(s) here")
686
687
1/2
✓ Branch 0 (25→26) taken 103 times.
✗ Branch 1 (25→45) not taken.
103 return nullptr;
688 }
689
690 351 std::any TypeChecker::visitContinueStmt(ContinueStmtNode *node) {
691 // Check if the stated number is valid
692
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→12) taken 350 times.
351 if (node->continueTimes < 1)
693
4/8
✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→30) not taken.
✓ Branch 2 (5→6) taken 1 times.
✗ Branch 3 (5→28) not taken.
✓ Branch 4 (8→9) taken 1 times.
✗ Branch 5 (8→34) not taken.
✓ Branch 6 (9→10) taken 1 times.
✗ Branch 7 (9→34) not taken.
1 SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER,
694 "Continue count must be >= 1, you provided " + std::to_string(node->continueTimes))
695
696 // Check if we can continue this often
697 350 const unsigned int maxContinues = currentScope->getLoopNestingDepth();
698
2/2
✓ Branch 0 (13→14) taken 1 times.
✓ Branch 1 (13→25) taken 349 times.
350 if (static_cast<unsigned int>(node->continueTimes) > maxContinues)
699
5/10
✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→39) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→37) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→35) not taken.
✓ Branch 6 (21→22) taken 1 times.
✗ Branch 7 (21→44) not taken.
✓ Branch 8 (22→23) taken 1 times.
✗ Branch 9 (22→44) not taken.
1 SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER, "We can only continue " + std::to_string(maxContinues) + " time(s) here")
700
701
1/2
✓ Branch 0 (25→26) taken 349 times.
✗ Branch 1 (25→45) not taken.
349 return nullptr;
702 }
703
704 6 std::any TypeChecker::visitFallthroughStmt(FallthroughStmtNode *node) {
705 // Check if we can do a fallthrough here
706
2/2
✓ Branch 0 (3→4) taken 2 times.
✓ Branch 1 (3→14) taken 4 times.
6 if (!currentScope->isInCaseBranch())
707
4/8
✓ Branch 0 (6→7) taken 2 times.
✗ Branch 1 (6→19) not taken.
✓ Branch 2 (7→8) taken 2 times.
✗ Branch 3 (7→17) not taken.
✓ Branch 4 (10→11) taken 2 times.
✗ Branch 5 (10→23) not taken.
✓ Branch 6 (11→12) taken 2 times.
✗ Branch 7 (11→23) not taken.
6 SOFT_ERROR_ER(node, FALLTHROUGH_NOT_ALLOWED, "Fallthrough is only allowed in case branches")
708
709
1/2
✓ Branch 0 (14→15) taken 4 times.
✗ Branch 1 (14→24) not taken.
4 return nullptr;
710 }
711
712 686 std::any TypeChecker::visitAssertStmt(AssertStmtNode *node) {
713 // Visit condition
714
2/4
✓ Branch 0 (2→3) taken 686 times.
✗ Branch 1 (2→29) not taken.
✓ Branch 2 (3→4) taken 686 times.
✗ Branch 3 (3→27) not taken.
686 const QualType conditionType = std::any_cast<ExprResult>(visit(node->assignExpr)).type;
715
2/8
✓ Branch 0 (5→6) taken 686 times.
✗ Branch 1 (5→40) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→11) taken 686 times.
✗ Branch 4 (7→8) not taken.
✗ Branch 5 (7→31) not taken.
✗ Branch 6 (8→9) not taken.
✗ Branch 7 (8→31) not taken.
686 HANDLE_UNRESOLVED_TYPE_ER(conditionType)
716
717 // Check if condition evaluates to bool
718
3/4
✓ Branch 0 (11→12) taken 686 times.
✗ Branch 1 (11→40) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→23) taken 685 times.
686 if (!conditionType.is(TY_BOOL))
719
4/8
✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→34) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→32) not taken.
✓ Branch 4 (19→20) taken 1 times.
✗ Branch 5 (19→38) not taken.
✓ Branch 6 (20→21) taken 1 times.
✗ Branch 7 (20→38) not taken.
3 SOFT_ERROR_ER(node->assignExpr, ASSERTION_CONDITION_BOOL, "The asserted condition must be of type bool")
720
721
1/2
✓ Branch 0 (23→24) taken 685 times.
✗ Branch 1 (23→39) not taken.
685 return nullptr;
722 }
723
724 1454 std::any TypeChecker::visitBuiltinCall(BuiltinCallNode *node) {
725
2/2
✓ Branch 0 (2→3) taken 691 times.
✓ Branch 1 (2→4) taken 763 times.
1454 if (node->printfCall)
726 691 return visitPrintfCall(node->printfCall);
727
2/2
✓ Branch 0 (4→5) taken 126 times.
✓ Branch 1 (4→6) taken 637 times.
763 if (node->sizeofCall)
728 126 return visitSizeofCall(node->sizeofCall);
729
2/2
✓ Branch 0 (6→7) taken 11 times.
✓ Branch 1 (6→8) taken 626 times.
637 if (node->alignofCall)
730 11 return visitAlignofCall(node->alignofCall);
731
2/2
✓ Branch 0 (8→9) taken 36 times.
✓ Branch 1 (8→10) taken 590 times.
626 if (node->lenCall)
732 36 return visitLenCall(node->lenCall);
733
2/2
✓ Branch 0 (10→11) taken 589 times.
✓ Branch 1 (10→12) taken 1 times.
590 if (node->panicCall)
734 589 return visitPanicCall(node->panicCall);
735
1/2
✓ Branch 0 (12→13) taken 1 times.
✗ Branch 1 (12→14) not taken.
1 if (node->sysCall)
736 1 return visitSysCall(node->sysCall);
737 assert_fail("Unknown builtin call");
738 return nullptr;
739 }
740
741 691 std::any TypeChecker::visitPrintfCall(PrintfCallNode *node) {
742 // Check if assignment types match placeholder types
743 691 size_t placeholderCount = 0;
744 691 size_t index = node->templatedString.find_first_of('%');
745
5/6
✓ Branch 0 (118→119) taken 574 times.
✓ Branch 1 (118→122) taken 669 times.
✓ Branch 2 (120→121) taken 574 times.
✗ Branch 3 (120→122) not taken.
✓ Branch 4 (123→3) taken 574 times.
✓ Branch 5 (123→124) taken 669 times.
1243 while (index != std::string::npos && index != node->templatedString.size() - 1) {
746 // Check if there is another assignExpr
747
2/2
✓ Branch 0 (4→5) taken 1 times.
✓ Branch 1 (4→15) taken 573 times.
574 if (node->args.size() <= placeholderCount)
748
4/8
✓ Branch 0 (7→8) taken 1 times.
✗ Branch 1 (7→144) not taken.
✓ Branch 2 (8→9) taken 1 times.
✗ Branch 3 (8→142) not taken.
✓ Branch 4 (11→12) taken 1 times.
✗ Branch 5 (11→148) not taken.
✓ Branch 6 (12→13) taken 1 times.
✗ Branch 7 (12→148) not taken.
3 SOFT_ERROR_ER(node, PRINTF_ARG_COUNT_ERROR, "The placeholder string contains more placeholders than arguments")
749
750 // Get next assignment
751
1/2
✓ Branch 0 (15→16) taken 573 times.
✗ Branch 1 (15→198) not taken.
573 AssignExprNode *assignment = node->args.at(placeholderCount);
752 // Visit assignment
753
2/4
✓ Branch 0 (16→17) taken 573 times.
✗ Branch 1 (16→151) not taken.
✓ Branch 2 (17→18) taken 573 times.
✗ Branch 3 (17→149) not taken.
573 QualType argType = std::any_cast<ExprResult>(visit(assignment)).type;
754
5/8
✓ Branch 0 (19→20) taken 573 times.
✗ Branch 1 (19→198) not taken.
✓ Branch 2 (20→21) taken 15 times.
✓ Branch 3 (20→25) taken 558 times.
✓ Branch 4 (21→22) taken 15 times.
✗ Branch 5 (21→153) not taken.
✓ Branch 6 (22→23) taken 15 times.
✗ Branch 7 (22→153) not taken.
573 HANDLE_UNRESOLVED_TYPE_ER(argType)
755
1/2
✓ Branch 0 (25→26) taken 558 times.
✗ Branch 1 (25→154) not taken.
558 argType = argType.removeReferenceWrapper();
756
757
6/8
✓ Branch 0 (26→27) taken 558 times.
✗ Branch 1 (26→198) not taken.
✓ Branch 2 (27→28) taken 15 times.
✓ Branch 3 (27→40) taken 304 times.
✓ Branch 4 (27→52) taken 34 times.
✓ Branch 5 (27→64) taken 200 times.
✓ Branch 6 (27→85) taken 5 times.
✗ Branch 7 (27→104) not taken.
558 switch (node->templatedString.at(index + 1)) {
758 15 case 'c': {
759
3/4
✓ Branch 0 (28→29) taken 15 times.
✗ Branch 1 (28→198) not taken.
✓ Branch 2 (29→30) taken 1 times.
✓ Branch 3 (29→39) taken 14 times.
15 if (!argType.is(TY_CHAR))
760
5/10
✓ Branch 0 (30→31) taken 1 times.
✗ Branch 1 (30→159) not taken.
✓ Branch 2 (31→32) taken 1 times.
✗ Branch 3 (31→157) not taken.
✓ Branch 4 (32→33) taken 1 times.
✗ Branch 5 (32→155) not taken.
✓ Branch 6 (35→36) taken 1 times.
✗ Branch 7 (35→161) not taken.
✓ Branch 8 (36→37) taken 1 times.
✗ Branch 9 (36→161) not taken.
1 SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, "The placeholder string expects char, but got " + argType.getName(false))
761 14 placeholderCount++;
762 14 break;
763 }
764 304 case 'd':
765 case 'i':
766 case 'l':
767 case 'o':
768 case 'u':
769 case 'x':
770 case 'X': {
771
3/4
✓ Branch 0 (40→41) taken 304 times.
✗ Branch 1 (40→162) not taken.
✓ Branch 2 (41→42) taken 2 times.
✓ Branch 3 (41→51) taken 302 times.
304 if (!argType.isOneOf({TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_BOOL}))
772
5/10
✓ Branch 0 (42→43) taken 2 times.
✗ Branch 1 (42→167) not taken.
✓ Branch 2 (43→44) taken 2 times.
✗ Branch 3 (43→165) not taken.
✓ Branch 4 (44→45) taken 2 times.
✗ Branch 5 (44→163) not taken.
✓ Branch 6 (47→48) taken 2 times.
✗ Branch 7 (47→169) not taken.
✓ Branch 8 (48→49) taken 2 times.
✗ Branch 9 (48→169) not taken.
2 SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR,
773 "The placeholder string expects int, short, long, byte or bool, but got " + argType.getName(false))
774 302 placeholderCount++;
775 302 break;
776 }
777 34 case 'a':
778 case 'A':
779 case 'f':
780 case 'F':
781 case 'e':
782 case 'E':
783 case 'g':
784 case 'G': {
785
3/4
✓ Branch 0 (52→53) taken 34 times.
✗ Branch 1 (52→198) not taken.
✓ Branch 2 (53→54) taken 1 times.
✓ Branch 3 (53→63) taken 33 times.
34 if (!argType.is(TY_DOUBLE))
786
5/10
✓ Branch 0 (54→55) taken 1 times.
✗ Branch 1 (54→174) not taken.
✓ Branch 2 (55→56) taken 1 times.
✗ Branch 3 (55→172) not taken.
✓ Branch 4 (56→57) taken 1 times.
✗ Branch 5 (56→170) not taken.
✓ Branch 6 (59→60) taken 1 times.
✗ Branch 7 (59→176) not taken.
✓ Branch 8 (60→61) taken 1 times.
✗ Branch 9 (60→176) not taken.
1 SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, "The placeholder string expects double, but got " + argType.getName(false))
787 33 placeholderCount++;
788 33 break;
789 }
790 200 case 's': {
791
13/18
✓ Branch 0 (64→65) taken 200 times.
✗ Branch 1 (64→198) not taken.
✓ Branch 2 (65→66) taken 43 times.
✓ Branch 3 (65→73) taken 157 times.
✓ Branch 4 (66→67) taken 43 times.
✗ Branch 5 (66→198) not taken.
✓ Branch 6 (67→68) taken 2 times.
✓ Branch 7 (67→73) taken 41 times.
✓ Branch 8 (68→69) taken 2 times.
✗ Branch 9 (68→198) not taken.
✓ Branch 10 (69→70) taken 1 times.
✓ Branch 11 (69→73) taken 1 times.
✓ Branch 12 (70→71) taken 1 times.
✗ Branch 13 (70→198) not taken.
✓ Branch 14 (71→72) taken 1 times.
✗ Branch 15 (71→73) not taken.
✓ Branch 16 (74→75) taken 1 times.
✓ Branch 17 (74→84) taken 199 times.
200 if (!argType.is(TY_STRING) && !argType.isStringObj() && !argType.isPtrTo(TY_CHAR) && !argType.isArrayOf(TY_CHAR))
792
5/10
✓ Branch 0 (75→76) taken 1 times.
✗ Branch 1 (75→181) not taken.
✓ Branch 2 (76→77) taken 1 times.
✗ Branch 3 (76→179) not taken.
✓ Branch 4 (77→78) taken 1 times.
✗ Branch 5 (77→177) not taken.
✓ Branch 6 (80→81) taken 1 times.
✗ Branch 7 (80→183) not taken.
✓ Branch 8 (81→82) taken 1 times.
✗ Branch 9 (81→183) not taken.
1 SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR,
793 "The placeholder string expects string, String, char* or char[], but got " + argType.getName(false))
794 199 placeholderCount++;
795 199 break;
796 }
797 5 case 'p': {
798
9/14
✓ Branch 0 (85→86) taken 5 times.
✗ Branch 1 (85→198) not taken.
✓ Branch 2 (86→87) taken 1 times.
✓ Branch 3 (86→92) taken 4 times.
✓ Branch 4 (87→88) taken 1 times.
✗ Branch 5 (87→198) not taken.
✓ Branch 6 (88→89) taken 1 times.
✗ Branch 7 (88→92) not taken.
✓ Branch 8 (89→90) taken 1 times.
✗ Branch 9 (89→198) not taken.
✓ Branch 10 (90→91) taken 1 times.
✗ Branch 11 (90→92) not taken.
✓ Branch 12 (93→94) taken 1 times.
✓ Branch 13 (93→103) taken 4 times.
5 if (!argType.isPtr() && !argType.isArray() && !argType.is(TY_STRING))
799
5/10
✓ Branch 0 (94→95) taken 1 times.
✗ Branch 1 (94→188) not taken.
✓ Branch 2 (95→96) taken 1 times.
✗ Branch 3 (95→186) not taken.
✓ Branch 4 (96→97) taken 1 times.
✗ Branch 5 (96→184) not taken.
✓ Branch 6 (99→100) taken 1 times.
✗ Branch 7 (99→190) not taken.
✓ Branch 8 (100→101) taken 1 times.
✗ Branch 9 (100→190) not taken.
1 SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR,
800 "The placeholder string expects pointer, array or string, but got " + argType.getName(false))
801 4 placeholderCount++;
802 4 break;
803 }
804 default:
805 SOFT_ERROR_ER(node, PRINTF_TYPE_ERROR, "The placeholder string contains an invalid placeholder")
806 }
807 552 index = node->templatedString.find_first_of('%', index + 2); // We can also skip the following char
808 }
809
810 // Check if the number of placeholders matches the number of args
811
2/2
✓ Branch 0 (125→126) taken 1 times.
✓ Branch 1 (125→136) taken 668 times.
669 if (placeholderCount < node->args.size())
812
4/8
✓ Branch 0 (128→129) taken 1 times.
✗ Branch 1 (128→201) not taken.
✓ Branch 2 (129→130) taken 1 times.
✗ Branch 3 (129→199) not taken.
✓ Branch 4 (132→133) taken 1 times.
✗ Branch 5 (132→205) not taken.
✓ Branch 6 (133→134) taken 1 times.
✗ Branch 7 (133→205) not taken.
3 SOFT_ERROR_ER(node, PRINTF_ARG_COUNT_ERROR, "The placeholder string contains less placeholders than arguments")
813
814
3/6
✓ Branch 0 (136→137) taken 668 times.
✗ Branch 1 (136→206) not taken.
✓ Branch 2 (137→138) taken 668 times.
✗ Branch 3 (137→206) not taken.
✓ Branch 4 (138→139) taken 668 times.
✗ Branch 5 (138→206) not taken.
668 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_INT), manIdx)};
815 }
816
817 126 std::any TypeChecker::visitSizeofCall(SizeofCallNode *node) {
818
2/2
✓ Branch 0 (2→3) taken 109 times.
✓ Branch 1 (2→6) taken 17 times.
126 if (node->isType) { // Size of type
819
1/2
✓ Branch 0 (3→4) taken 109 times.
✗ Branch 1 (3→15) not taken.
109 visit(node->dataType);
820 } else { // Size of value
821
1/2
✓ Branch 0 (6→7) taken 17 times.
✗ Branch 1 (6→16) not taken.
17 visit(node->assignExpr);
822 }
823
824
3/6
✓ Branch 0 (9→10) taken 126 times.
✗ Branch 1 (9→17) not taken.
✓ Branch 2 (10→11) taken 126 times.
✗ Branch 3 (10→17) not taken.
✓ Branch 4 (11→12) taken 126 times.
✗ Branch 5 (11→17) not taken.
126 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)};
825 }
826
827 11 std::any TypeChecker::visitAlignofCall(AlignofCallNode *node) {
828
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→6) taken 10 times.
11 if (node->isType) { // Align of type
829
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→15) not taken.
1 visit(node->dataType);
830 } else { // Align of value
831
1/2
✓ Branch 0 (6→7) taken 10 times.
✗ Branch 1 (6→16) not taken.
10 visit(node->assignExpr);
832 }
833
834
3/6
✓ Branch 0 (9→10) taken 11 times.
✗ Branch 1 (9→17) not taken.
✓ Branch 2 (10→11) taken 11 times.
✗ Branch 3 (10→17) not taken.
✓ Branch 4 (11→12) taken 11 times.
✗ Branch 5 (11→17) not taken.
11 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)};
835 }
836
837 36 std::any TypeChecker::visitLenCall(LenCallNode *node) {
838
2/4
✓ Branch 0 (2→3) taken 36 times.
✗ Branch 1 (2→48) not taken.
✓ Branch 2 (3→4) taken 36 times.
✗ Branch 3 (3→46) not taken.
36 QualType argType = std::any_cast<ExprResult>(visit(node->assignExpr)).type;
839
2/8
✓ Branch 0 (5→6) taken 36 times.
✗ Branch 1 (5→61) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→11) taken 36 times.
✗ Branch 4 (7→8) not taken.
✗ Branch 5 (7→50) not taken.
✗ Branch 6 (8→9) not taken.
✗ Branch 7 (8→50) not taken.
36 HANDLE_UNRESOLVED_TYPE_ER(argType)
840
1/2
✓ Branch 0 (11→12) taken 36 times.
✗ Branch 1 (11→51) not taken.
36 argType = argType.removeReferenceWrapper();
841
842 // Check if arg is of type array
843
8/10
✓ Branch 0 (12→13) taken 36 times.
✗ Branch 1 (12→61) not taken.
✓ Branch 2 (13→14) taken 24 times.
✓ Branch 3 (13→17) taken 12 times.
✓ Branch 4 (14→15) taken 24 times.
✗ Branch 5 (14→61) not taken.
✓ Branch 6 (15→16) taken 1 times.
✓ Branch 7 (15→17) taken 23 times.
✓ Branch 8 (18→19) taken 1 times.
✓ Branch 9 (18→29) taken 35 times.
36 if (!argType.isArray() && !argType.is(TY_STRING))
844
4/8
✓ Branch 0 (21→22) taken 1 times.
✗ Branch 1 (21→54) not taken.
✓ Branch 2 (22→23) taken 1 times.
✗ Branch 3 (22→52) not taken.
✓ Branch 4 (25→26) taken 1 times.
✗ Branch 5 (25→58) not taken.
✓ Branch 6 (26→27) taken 1 times.
✗ Branch 7 (26→58) not taken.
3 SOFT_ERROR_ER(node->assignExpr, EXPECTED_ARRAY_TYPE, "The len builtin can only work on arrays or strings")
845
846 // If we want to use the len builtin on a string, we need to import the string runtime module
847
7/10
✓ Branch 0 (29→30) taken 35 times.
✗ Branch 1 (29→61) not taken.
✓ Branch 2 (30→31) taken 23 times.
✓ Branch 3 (30→36) taken 12 times.
✓ Branch 4 (31→32) taken 23 times.
✗ Branch 5 (31→61) not taken.
✓ Branch 6 (34→35) taken 23 times.
✗ Branch 7 (34→36) not taken.
✓ Branch 8 (37→38) taken 23 times.
✓ Branch 9 (37→39) taken 12 times.
58 if (argType.is(TY_STRING) && !sourceFile->isStringRT())
848
1/2
✓ Branch 0 (38→39) taken 23 times.
✗ Branch 1 (38→61) not taken.
23 sourceFile->requestRuntimeModule(STRING_RT);
849
850
3/6
✓ Branch 0 (39→40) taken 35 times.
✗ Branch 1 (39→59) not taken.
✓ Branch 2 (40→41) taken 35 times.
✗ Branch 3 (40→59) not taken.
✓ Branch 4 (41→42) taken 35 times.
✗ Branch 5 (41→59) not taken.
35 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)};
851 }
852
853 589 std::any TypeChecker::visitPanicCall(PanicCallNode *node) {
854
2/4
✓ Branch 0 (2→3) taken 589 times.
✗ Branch 1 (2→33) not taken.
✓ Branch 2 (3→4) taken 589 times.
✗ Branch 3 (3→31) not taken.
589 QualType argType = std::any_cast<ExprResult>(visit(node->assignExpr)).type;
855
2/8
✓ Branch 0 (5→6) taken 589 times.
✗ Branch 1 (5→46) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→11) taken 589 times.
✗ Branch 4 (7→8) not taken.
✗ Branch 5 (7→35) not taken.
✗ Branch 6 (8→9) not taken.
✗ Branch 7 (8→35) not taken.
589 HANDLE_UNRESOLVED_TYPE_ER(argType)
856
1/2
✓ Branch 0 (11→12) taken 589 times.
✗ Branch 1 (11→36) not taken.
589 argType = argType.removeReferenceWrapper();
857
858 // Check if arg is of type array
859
2/4
✓ Branch 0 (12→13) taken 589 times.
✗ Branch 1 (12→46) not taken.
✗ Branch 2 (13→14) not taken.
✓ Branch 3 (13→24) taken 589 times.
589 if (!argType.isErrorObj())
860 SOFT_ERROR_ER(node->assignExpr, EXPECTED_ERROR_TYPE, "The panic builtin can only work with errors")
861
862
3/6
✓ Branch 0 (24→25) taken 589 times.
✗ Branch 1 (24→44) not taken.
✓ Branch 2 (25→26) taken 589 times.
✗ Branch 3 (25→44) not taken.
✓ Branch 4 (26→27) taken 589 times.
✗ Branch 5 (26→44) not taken.
589 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx)};
863 }
864
865 1 std::any TypeChecker::visitSysCall(SysCallNode *node) {
866 // Check if the syscall number if of type short
867
2/4
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→62) not taken.
✓ Branch 2 (4→5) taken 1 times.
✗ Branch 3 (4→60) not taken.
1 const QualType sysCallNumberType = std::any_cast<ExprResult>(visit(node->args.front())).type;
868
2/4
✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→89) not taken.
✗ Branch 2 (7→8) not taken.
✓ Branch 3 (7→19) taken 1 times.
1 if (!sysCallNumberType.is(TY_SHORT))
869 SOFT_ERROR_ER(node->args.front(), INVALID_SYSCALL_NUMBER_TYPE, "Syscall number must be of type short")
870
871 // Check if the syscall number is out of range
872 // According to https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/
873
2/4
✓ Branch 0 (19→20) taken 1 times.
✗ Branch 1 (19→89) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→33) taken 1 times.
1 if (node->hasCompileTimeValue()) {
874 const unsigned short sysCallNumber = node->getCompileTimeValue().shortValue;
875 if (sysCallNumber < 0 || sysCallNumber > 439)
876 SOFT_ERROR_ER(node, SYSCALL_NUMBER_OUT_OF_RANGE, "Only syscall numbers between 0 and 439 are supported")
877 }
878
879 // Check if too many syscall args are given
880 // According to https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/
881
1/2
✗ Branch 0 (34→35) not taken.
✓ Branch 1 (34→46) taken 1 times.
1 if (node->args.size() > 6)
882 SOFT_ERROR_ER(node->args.front(), TOO_MANY_SYSCALL_ARGS, "There are no syscalls that support more than 6 arguments")
883
884 // Visit children
885
2/2
✓ Branch 0 (52→47) taken 3 times.
✓ Branch 1 (52→53) taken 1 times.
4 for (size_t i = 1; i < node->args.size(); i++)
886
2/4
✓ Branch 0 (47→48) taken 3 times.
✗ Branch 1 (47→86) not taken.
✓ Branch 2 (48→49) taken 3 times.
✗ Branch 3 (48→86) not taken.
3 visit(node->args.at(i));
887
888
3/6
✓ Branch 0 (53→54) taken 1 times.
✗ Branch 1 (53→87) not taken.
✓ Branch 2 (54→55) taken 1 times.
✗ Branch 3 (54→87) not taken.
✓ Branch 4 (55→56) taken 1 times.
✗ Branch 5 (55→87) not taken.
1 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)};
889 }
890
891 60556 std::any TypeChecker::visitAssignExpr(AssignExprNode *node) {
892 // Check if ternary
893
2/2
✓ Branch 0 (2→3) taken 55130 times.
✓ Branch 1 (2→10) taken 5426 times.
60556 if (node->ternaryExpr) {
894
3/4
✓ Branch 0 (3→4) taken 55115 times.
✓ Branch 1 (3→98) taken 15 times.
✓ Branch 2 (4→5) taken 55115 times.
✗ Branch 3 (4→96) not taken.
55130 auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr));
895
1/2
✓ Branch 0 (6→7) taken 55115 times.
✗ Branch 1 (6→99) not taken.
55115 node->setEvaluatedSymbolType(result.type, manIdx);
896
1/2
✓ Branch 0 (7→8) taken 55115 times.
✗ Branch 1 (7→99) not taken.
55115 return result;
897 }
898
899 // Check if assignment
900
1/2
✓ Branch 0 (10→11) taken 5426 times.
✗ Branch 1 (10→87) not taken.
5426 if (node->op != AssignExprNode::AssignOp::OP_NONE) {
901 // Visit the right side first
902
2/4
✓ Branch 0 (11→12) taken 5426 times.
✗ Branch 1 (11→102) not taken.
✓ Branch 2 (12→13) taken 5426 times.
✗ Branch 3 (12→100) not taken.
5426 auto rhs = std::any_cast<ExprResult>(visit(node->rhs));
903 5426 auto [rhsType, rhsEntry] = rhs;
904
5/8
✓ Branch 0 (14→15) taken 5426 times.
✗ Branch 1 (14→121) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→20) taken 5425 times.
✓ Branch 4 (16→17) taken 1 times.
✗ Branch 5 (16→103) not taken.
✓ Branch 6 (17→18) taken 1 times.
✗ Branch 7 (17→103) not taken.
5426 HANDLE_UNRESOLVED_TYPE_ER(rhsType)
905 // Then visit the left side
906
2/4
✓ Branch 0 (20→21) taken 5425 times.
✗ Branch 1 (20→106) not taken.
✓ Branch 2 (21→22) taken 5425 times.
✗ Branch 3 (21→104) not taken.
5425 auto lhs = std::any_cast<ExprResult>(visit(node->lhs));
907 5425 auto [lhsType, lhsVar] = lhs;
908
5/8
✓ Branch 0 (23→24) taken 5425 times.
✗ Branch 1 (23→121) not taken.
✓ Branch 2 (24→25) taken 1 times.
✓ Branch 3 (24→29) taken 5424 times.
✓ Branch 4 (25→26) taken 1 times.
✗ Branch 5 (25→107) not taken.
✓ Branch 6 (26→27) taken 1 times.
✗ Branch 7 (26→107) not taken.
5425 HANDLE_UNRESOLVED_TYPE_ER(lhsType)
909
910 // Take a look at the operator
911
2/2
✓ Branch 0 (29→30) taken 4860 times.
✓ Branch 1 (29→43) taken 564 times.
5424 if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) {
912
8/10
✓ Branch 0 (30→31) taken 4859 times.
✓ Branch 1 (30→37) taken 1 times.
✓ Branch 2 (31→32) taken 4859 times.
✗ Branch 3 (31→121) not taken.
✓ Branch 4 (32→33) taken 3921 times.
✓ Branch 5 (32→37) taken 938 times.
✓ Branch 6 (34→35) taken 3921 times.
✗ Branch 7 (34→121) not taken.
✓ Branch 8 (35→36) taken 1262 times.
✓ Branch 9 (35→37) taken 2659 times.
4860 const bool isDecl = lhs.entry != nullptr && lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized();
913
2/2
✓ Branch 0 (38→39) taken 4859 times.
✓ Branch 1 (38→108) taken 1 times.
4860 rhsType = opRuleManager.getAssignResultType(node, lhs, rhs, isDecl).first;
914
915 // If there is an anonymous entry attached (e.g. for struct instantiation), delete it
916
4/4
✓ Branch 0 (39→40) taken 2318 times.
✓ Branch 1 (39→73) taken 2541 times.
✓ Branch 2 (40→41) taken 136 times.
✓ Branch 3 (40→73) taken 2182 times.
4859 if (rhsEntry != nullptr && rhsEntry->anonymous) {
917
1/2
✓ Branch 0 (41→42) taken 136 times.
✗ Branch 1 (41→121) not taken.
136 currentScope->symbolTable.deleteAnonymous(rhsEntry->name);
918 136 rhsEntry = nullptr;
919 }
920
2/2
✓ Branch 0 (43→44) taken 227 times.
✓ Branch 1 (43→46) taken 337 times.
564 } else if (node->op == AssignExprNode::AssignOp::OP_PLUS_EQUAL) {
921
1/2
✓ Branch 0 (44→45) taken 227 times.
✗ Branch 1 (44→109) not taken.
227 rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type;
922
2/2
✓ Branch 0 (46→47) taken 28 times.
✓ Branch 1 (46→49) taken 309 times.
337 } else if (node->op == AssignExprNode::AssignOp::OP_MINUS_EQUAL) {
923
1/2
✓ Branch 0 (47→48) taken 28 times.
✗ Branch 1 (47→110) not taken.
28 rhsType = opRuleManager.getMinusEqualResultType(node, lhs, rhs, 0).type;
924
2/2
✓ Branch 0 (49→50) taken 16 times.
✓ Branch 1 (49→52) taken 293 times.
309 } else if (node->op == AssignExprNode::AssignOp::OP_MUL_EQUAL) {
925
1/2
✓ Branch 0 (50→51) taken 16 times.
✗ Branch 1 (50→111) not taken.
16 rhsType = opRuleManager.getMulEqualResultType(node, lhs, rhs, 0).type;
926
2/2
✓ Branch 0 (52→53) taken 36 times.
✓ Branch 1 (52→55) taken 257 times.
293 } else if (node->op == AssignExprNode::AssignOp::OP_DIV_EQUAL) {
927
1/2
✓ Branch 0 (53→54) taken 36 times.
✗ Branch 1 (53→112) not taken.
36 rhsType = opRuleManager.getDivEqualResultType(node, lhs, rhs, 0).type;
928
2/2
✓ Branch 0 (55→56) taken 6 times.
✓ Branch 1 (55→58) taken 251 times.
257 } else if (node->op == AssignExprNode::AssignOp::OP_REM_EQUAL) {
929
1/2
✓ Branch 0 (56→57) taken 6 times.
✗ Branch 1 (56→113) not taken.
6 rhsType = opRuleManager.getRemEqualResultType(node, lhs, rhs);
930
2/2
✓ Branch 0 (58→59) taken 2 times.
✓ Branch 1 (58→61) taken 249 times.
251 } else if (node->op == AssignExprNode::AssignOp::OP_SHL_EQUAL) {
931
1/2
✓ Branch 0 (59→60) taken 2 times.
✗ Branch 1 (59→114) not taken.
2 rhsType = opRuleManager.getSHLEqualResultType(node, lhs, rhs);
932
2/2
✓ Branch 0 (61→62) taken 3 times.
✓ Branch 1 (61→64) taken 246 times.
249 } else if (node->op == AssignExprNode::AssignOp::OP_SHR_EQUAL) {
933
1/2
✓ Branch 0 (62→63) taken 3 times.
✗ Branch 1 (62→115) not taken.
3 rhsType = opRuleManager.getSHREqualResultType(node, lhs, rhs);
934
2/2
✓ Branch 0 (64→65) taken 1 times.
✓ Branch 1 (64→67) taken 245 times.
246 } else if (node->op == AssignExprNode::AssignOp::OP_AND_EQUAL) {
935
1/2
✓ Branch 0 (65→66) taken 1 times.
✗ Branch 1 (65→116) not taken.
1 rhsType = opRuleManager.getAndEqualResultType(node, lhs, rhs);
936
2/2
✓ Branch 0 (67→68) taken 1 times.
✓ Branch 1 (67→70) taken 244 times.
245 } else if (node->op == AssignExprNode::AssignOp::OP_OR_EQUAL) {
937
1/2
✓ Branch 0 (68→69) taken 1 times.
✗ Branch 1 (68→117) not taken.
1 rhsType = opRuleManager.getOrEqualResultType(node, lhs, rhs);
938
1/2
✓ Branch 0 (70→71) taken 244 times.
✗ Branch 1 (70→73) not taken.
244 } else if (node->op == AssignExprNode::AssignOp::OP_XOR_EQUAL) {
939
1/2
✓ Branch 0 (71→72) taken 244 times.
✗ Branch 1 (71→118) not taken.
244 rhsType = opRuleManager.getXorEqualResultType(node, lhs, rhs);
940 }
941
942
1/2
✓ Branch 0 (73→74) taken 5423 times.
✗ Branch 1 (73→82) not taken.
5423 if (lhsVar) { // Variable is involved on the left side
943 // Perform type inference
944
3/4
✓ Branch 0 (74→75) taken 5423 times.
✗ Branch 1 (74→121) not taken.
✓ Branch 2 (75→76) taken 1 times.
✓ Branch 3 (75→77) taken 5422 times.
5423 if (lhsType.is(TY_DYN))
945
1/2
✓ Branch 0 (76→77) taken 1 times.
✗ Branch 1 (76→121) not taken.
1 lhsVar->updateType(rhsType, false);
946
947 // In case the lhs variable is captured, notify the capture about the write access
948
3/4
✓ Branch 0 (77→78) taken 5423 times.
✗ Branch 1 (77→121) not taken.
✓ Branch 2 (78→79) taken 3 times.
✓ Branch 3 (78→80) taken 5420 times.
5423 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsVar->name); lhsCapture)
949
1/2
✓ Branch 0 (79→80) taken 3 times.
✗ Branch 1 (79→121) not taken.
3 lhsCapture->setAccessType(READ_WRITE);
950
951 // Update the state of the variable
952
1/2
✓ Branch 0 (80→81) taken 5423 times.
✗ Branch 1 (80→119) not taken.
5423 lhsVar->updateState(INITIALIZED, node);
953 }
954
955
2/4
✓ Branch 0 (82→83) taken 5423 times.
✗ Branch 1 (82→120) not taken.
✓ Branch 2 (83→84) taken 5423 times.
✗ Branch 3 (83→120) not taken.
5423 return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)};
956 }
957
958 throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE
959 }
960
961 55718 std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) {
962 // Check if there is a ternary operator applied
963
2/2
✓ Branch 0 (2→3) taken 55391 times.
✓ Branch 1 (2→5) taken 327 times.
55718 if (!node->falseExpr)
964
2/2
✓ Branch 0 (3→4) taken 55376 times.
✓ Branch 1 (3→162) taken 15 times.
55391 return visit(node->condition);
965
966 // Visit condition
967
2/4
✓ Branch 0 (5→6) taken 327 times.
✗ Branch 1 (5→127) not taken.
✓ Branch 2 (6→7) taken 327 times.
✗ Branch 3 (6→125) not taken.
327 const auto condition = std::any_cast<ExprResult>(visit(node->condition));
968
2/8
✓ Branch 0 (8→9) taken 327 times.
✗ Branch 1 (8→162) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 327 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→128) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→128) not taken.
327 HANDLE_UNRESOLVED_TYPE_ER(condition.type)
969
6/10
✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→16) taken 326 times.
✓ Branch 2 (16→17) taken 326 times.
✗ Branch 3 (16→129) not taken.
✓ Branch 4 (17→18) taken 326 times.
✗ Branch 5 (17→129) not taken.
✓ Branch 6 (18→19) taken 326 times.
✓ Branch 7 (18→20) taken 1 times.
✗ Branch 8 (129→130) not taken.
✗ Branch 9 (129→131) not taken.
327 const auto trueExpr = node->isShortened ? condition : std::any_cast<ExprResult>(visit(node->trueExpr));
970 327 const auto [trueType, trueEntry] = trueExpr;
971
2/8
✓ Branch 0 (20→21) taken 327 times.
✗ Branch 1 (20→162) not taken.
✗ Branch 2 (21→22) not taken.
✓ Branch 3 (21→26) taken 327 times.
✗ Branch 4 (22→23) not taken.
✗ Branch 5 (22→133) not taken.
✗ Branch 6 (23→24) not taken.
✗ Branch 7 (23→133) not taken.
327 HANDLE_UNRESOLVED_TYPE_ER(trueType)
972
2/4
✓ Branch 0 (26→27) taken 327 times.
✗ Branch 1 (26→136) not taken.
✓ Branch 2 (27→28) taken 327 times.
✗ Branch 3 (27→134) not taken.
327 const auto falseExpr = std::any_cast<ExprResult>(visit(node->falseExpr));
973 327 const auto [falseType, falseEntry] = falseExpr;
974
2/8
✓ Branch 0 (29→30) taken 327 times.
✗ Branch 1 (29→162) not taken.
✗ Branch 2 (30→31) not taken.
✓ Branch 3 (30→35) taken 327 times.
✗ Branch 4 (31→32) not taken.
✗ Branch 5 (31→137) not taken.
✗ Branch 6 (32→33) not taken.
✗ Branch 7 (32→137) not taken.
327 HANDLE_UNRESOLVED_TYPE_ER(falseType)
975
976 // Check if the condition evaluates to bool
977
3/4
✓ Branch 0 (35→36) taken 327 times.
✗ Branch 1 (35→162) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→47) taken 326 times.
327 if (!condition.type.is(TY_BOOL))
978
4/8
✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→140) not taken.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→138) not taken.
✓ Branch 4 (43→44) taken 1 times.
✗ Branch 5 (43→144) not taken.
✓ Branch 6 (44→45) taken 1 times.
✗ Branch 7 (44→144) not taken.
3 SOFT_ERROR_ER(node->condition, OPERATOR_WRONG_DATA_TYPE, "Condition operand in ternary must be a bool")
979
980 // Check if trueType and falseType are matching
981
1/2
✓ Branch 0 (47→48) taken 326 times.
✗ Branch 1 (47→162) not taken.
326 const QualType trueTypeModified = trueType.removeReferenceWrapper();
982
1/2
✓ Branch 0 (48→49) taken 326 times.
✗ Branch 1 (48→162) not taken.
326 const QualType falseTypeModified = falseType.removeReferenceWrapper();
983
3/4
✓ Branch 0 (49→50) taken 326 times.
✗ Branch 1 (49→162) not taken.
✓ Branch 2 (50→51) taken 1 times.
✓ Branch 3 (50→66) taken 325 times.
326 if (!trueTypeModified.matches(falseTypeModified, false, true, false))
984
8/16
✓ Branch 0 (51→52) taken 1 times.
✗ Branch 1 (51→158) not taken.
✓ Branch 2 (52→53) taken 1 times.
✗ Branch 3 (52→153) not taken.
✓ Branch 4 (53→54) taken 1 times.
✗ Branch 5 (53→151) not taken.
✓ Branch 6 (54→55) taken 1 times.
✗ Branch 7 (54→149) not taken.
✓ Branch 8 (55→56) taken 1 times.
✗ Branch 9 (55→147) not taken.
✓ Branch 10 (56→57) taken 1 times.
✗ Branch 11 (56→145) not taken.
✓ Branch 12 (62→63) taken 1 times.
✗ Branch 13 (62→160) not taken.
✓ Branch 14 (63→64) taken 1 times.
✗ Branch 15 (63→160) not taken.
1 SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE,
985 "True and false operands in ternary must be of same data type. Got " + trueType.getName(true) + " and " +
986 falseType.getName(true))
987
988 // If there is an anonymous symbol attached to left or right, remove it,
989 // since the result takes over the ownership of any destructible object.
990
4/4
✓ Branch 0 (66→67) taken 111 times.
✓ Branch 1 (66→69) taken 214 times.
✓ Branch 2 (67→68) taken 82 times.
✓ Branch 3 (67→69) taken 29 times.
325 const bool removeAnonymousSymbolTrueSide = trueEntry && trueEntry->anonymous;
991
2/2
✓ Branch 0 (70→71) taken 82 times.
✓ Branch 1 (70→72) taken 243 times.
325 if (removeAnonymousSymbolTrueSide) {
992
1/2
✓ Branch 0 (71→82) taken 82 times.
✗ Branch 1 (71→162) not taken.
82 currentScope->symbolTable.deleteAnonymous(trueEntry->name);
993
11/14
✓ Branch 0 (72→73) taken 29 times.
✓ Branch 1 (72→79) taken 214 times.
✓ Branch 2 (73→74) taken 29 times.
✗ Branch 3 (73→79) not taken.
✓ Branch 4 (74→75) taken 29 times.
✗ Branch 5 (74→162) not taken.
✓ Branch 6 (75→76) taken 21 times.
✓ Branch 7 (75→79) taken 8 times.
✓ Branch 8 (76→77) taken 21 times.
✗ Branch 9 (76→162) not taken.
✓ Branch 10 (77→78) taken 8 times.
✓ Branch 11 (77→79) taken 13 times.
✓ Branch 12 (80→81) taken 8 times.
✓ Branch 13 (80→82) taken 235 times.
243 } else if (trueEntry && !trueEntry->anonymous && !trueType.isRef() && !trueType.isTriviallyCopyable(node)) {
994 8 node->trueSideCallsCopyCtor = true;
995 }
996
4/4
✓ Branch 0 (82→83) taken 288 times.
✓ Branch 1 (82→85) taken 37 times.
✓ Branch 2 (83→84) taken 81 times.
✓ Branch 3 (83→85) taken 207 times.
325 const bool removeAnonymousSymbolFalseSide = falseEntry && falseEntry->anonymous;
997
2/2
✓ Branch 0 (86→87) taken 81 times.
✓ Branch 1 (86→88) taken 244 times.
325 if (removeAnonymousSymbolFalseSide) {
998
1/2
✓ Branch 0 (87→98) taken 81 times.
✗ Branch 1 (87→162) not taken.
81 currentScope->symbolTable.deleteAnonymous(falseEntry->name);
999
11/14
✓ Branch 0 (88→89) taken 207 times.
✓ Branch 1 (88→95) taken 37 times.
✓ Branch 2 (89→90) taken 207 times.
✗ Branch 3 (89→95) not taken.
✓ Branch 4 (90→91) taken 207 times.
✗ Branch 5 (90→162) not taken.
✓ Branch 6 (91→92) taken 198 times.
✓ Branch 7 (91→95) taken 9 times.
✓ Branch 8 (92→93) taken 198 times.
✗ Branch 9 (92→162) not taken.
✓ Branch 10 (93→94) taken 8 times.
✓ Branch 11 (93→95) taken 190 times.
✓ Branch 12 (96→97) taken 8 times.
✓ Branch 13 (96→98) taken 236 times.
244 } else if (falseEntry && !falseEntry->anonymous && !falseType.isRef() && !falseType.isTriviallyCopyable(node)) {
1000 8 node->falseSideCallsCopyCtor = true;
1001 }
1002
1003 // Create a new anonymous symbol for the result if required
1004 325 const QualType &resultType = trueType;
1005 325 SymbolTableEntry *anonymousSymbol = nullptr;
1006
4/4
✓ Branch 0 (98→99) taken 243 times.
✓ Branch 1 (98→100) taken 82 times.
✓ Branch 2 (99→100) taken 2 times.
✓ Branch 3 (99→101) taken 241 times.
325 const bool removedAnonymousSymbols = removeAnonymousSymbolTrueSide || removeAnonymousSymbolFalseSide;
1007
4/4
✓ Branch 0 (102→103) taken 317 times.
✓ Branch 1 (102→104) taken 8 times.
✓ Branch 2 (103→104) taken 2 times.
✓ Branch 3 (103→105) taken 315 times.
325 const bool calledCopyCtor = node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor;
1008
9/10
✓ Branch 0 (106→107) taken 241 times.
✓ Branch 1 (106→110) taken 84 times.
✓ Branch 2 (107→108) taken 235 times.
✓ Branch 3 (107→110) taken 6 times.
✓ Branch 4 (108→109) taken 235 times.
✗ Branch 5 (108→162) not taken.
✓ Branch 6 (109→110) taken 8 times.
✓ Branch 7 (109→111) taken 227 times.
✓ Branch 8 (112→113) taken 98 times.
✓ Branch 9 (112→115) taken 227 times.
325 if (removedAnonymousSymbols || calledCopyCtor || resultType.isRef())
1009
1/2
✓ Branch 0 (113→114) taken 98 times.
✗ Branch 1 (113→162) not taken.
98 anonymousSymbol = currentScope->symbolTable.insertAnonymous(resultType, node);
1010
1011 // Lookup copy ctor, if at least one side needs it
1012
4/4
✓ Branch 0 (115→116) taken 317 times.
✓ Branch 1 (115→117) taken 8 times.
✓ Branch 2 (116→117) taken 2 times.
✓ Branch 3 (116→119) taken 315 times.
325 if (node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor)
1013
1/2
✓ Branch 0 (117→118) taken 10 times.
✗ Branch 1 (117→162) not taken.
10 node->calledCopyCtor = matchCopyCtor(trueTypeModified, node);
1014
1015
2/4
✓ Branch 0 (119→120) taken 325 times.
✗ Branch 1 (119→161) not taken.
✓ Branch 2 (120→121) taken 325 times.
✗ Branch 3 (120→161) not taken.
325 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), anonymousSymbol};
1016 }
1017
1018 56371 std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) {
1019 // Check if a logical or operator is applied
1020
2/2
✓ Branch 0 (3→4) taken 55551 times.
✓ Branch 1 (3→7) taken 820 times.
56371 if (node->operands.size() == 1)
1021
2/2
✓ Branch 0 (5→6) taken 55537 times.
✓ Branch 1 (5→46) taken 14 times.
55551 return visit(node->operands.front());
1022
1023 // Visit leftmost operand
1024
2/4
✓ Branch 0 (8→9) taken 820 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 820 times.
✗ Branch 3 (9→37) not taken.
820 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
1025
2/8
✓ Branch 0 (11→12) taken 820 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 820 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
820 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
1026
1027 // Loop through all remaining operands
1028
2/2
✓ Branch 0 (31→18) taken 1054 times.
✓ Branch 1 (31→32) taken 819 times.
1873 for (size_t i = 1; i < node->operands.size(); i++) {
1029
2/4
✓ Branch 0 (19→20) taken 1054 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 1054 times.
✗ Branch 3 (20→41) not taken.
1054 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
1030
2/8
✓ Branch 0 (22→23) taken 1054 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 1054 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
1054 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
1031
2/2
✓ Branch 0 (28→29) taken 1053 times.
✓ Branch 1 (28→45) taken 1 times.
1054 currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)};
1032 }
1033
1034
1/2
✓ Branch 0 (32→33) taken 819 times.
✗ Branch 1 (32→46) not taken.
819 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
1035
1/2
✓ Branch 0 (33→34) taken 819 times.
✗ Branch 1 (33→46) not taken.
819 return currentOperand;
1036 }
1037
1038 57425 std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) {
1039 // Check if a logical and operator is applied
1040
2/2
✓ Branch 0 (3→4) taken 57290 times.
✓ Branch 1 (3→7) taken 135 times.
57425 if (node->operands.size() == 1)
1041
2/2
✓ Branch 0 (5→6) taken 57276 times.
✓ Branch 1 (5→46) taken 14 times.
57290 return visit(node->operands.front());
1042
1043 // Visit leftmost operand
1044
2/4
✓ Branch 0 (8→9) taken 135 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 135 times.
✗ Branch 3 (9→37) not taken.
135 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
1045
2/8
✓ Branch 0 (11→12) taken 135 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 135 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
135 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
1046
1047 // Loop through all remaining operands
1048
2/2
✓ Branch 0 (31→18) taken 170 times.
✓ Branch 1 (31→32) taken 135 times.
305 for (size_t i = 1; i < node->operands.size(); i++) {
1049
2/4
✓ Branch 0 (19→20) taken 170 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 170 times.
✗ Branch 3 (20→41) not taken.
170 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
1050
2/8
✓ Branch 0 (22→23) taken 170 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 170 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
170 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
1051
1/2
✓ Branch 0 (28→29) taken 170 times.
✗ Branch 1 (28→45) not taken.
170 currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)};
1052 }
1053
1054
1/2
✓ Branch 0 (32→33) taken 135 times.
✗ Branch 1 (32→46) not taken.
135 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
1055
1/2
✓ Branch 0 (33→34) taken 135 times.
✗ Branch 1 (33→46) not taken.
135 return currentOperand;
1056 }
1057
1058 57595 std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) {
1059 // Check if a bitwise or operator is applied
1060
2/2
✓ Branch 0 (3→4) taken 57530 times.
✓ Branch 1 (3→7) taken 65 times.
57595 if (node->operands.size() == 1)
1061
2/2
✓ Branch 0 (5→6) taken 57517 times.
✓ Branch 1 (5→46) taken 13 times.
57530 return visit(node->operands.front());
1062
1063 // Visit leftmost operand
1064
2/4
✓ Branch 0 (8→9) taken 65 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 65 times.
✗ Branch 3 (9→37) not taken.
65 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
1065
2/8
✓ Branch 0 (11→12) taken 65 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 65 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
65 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
1066
1067 // Loop through all remaining operands
1068
2/2
✓ Branch 0 (31→18) taken 68 times.
✓ Branch 1 (31→32) taken 64 times.
132 for (size_t i = 1; i < node->operands.size(); i++) {
1069
2/4
✓ Branch 0 (19→20) taken 68 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 68 times.
✗ Branch 3 (20→41) not taken.
68 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
1070
2/8
✓ Branch 0 (22→23) taken 68 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 68 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
68 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
1071
2/2
✓ Branch 0 (28→29) taken 67 times.
✓ Branch 1 (28→45) taken 1 times.
68 currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)};
1072 }
1073
1074
1/2
✓ Branch 0 (32→33) taken 64 times.
✗ Branch 1 (32→46) not taken.
64 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
1075
1/2
✓ Branch 0 (33→34) taken 64 times.
✗ Branch 1 (33→46) not taken.
64 return currentOperand;
1076 }
1077
1078 57663 std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) {
1079 // Check if a bitwise xor operator is applied
1080
2/2
✓ Branch 0 (3→4) taken 57659 times.
✓ Branch 1 (3→7) taken 4 times.
57663 if (node->operands.size() == 1)
1081
2/2
✓ Branch 0 (5→6) taken 57646 times.
✓ Branch 1 (5→46) taken 13 times.
57659 return visit(node->operands.front());
1082
1083 // Visit leftmost operand
1084
2/4
✓ Branch 0 (8→9) taken 4 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 4 times.
✗ Branch 3 (9→37) not taken.
4 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
1085
2/8
✓ Branch 0 (11→12) taken 4 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
4 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
1086
1087 // Loop through all remaining operands
1088
2/2
✓ Branch 0 (31→18) taken 7 times.
✓ Branch 1 (31→32) taken 4 times.
11 for (size_t i = 1; i < node->operands.size(); i++) {
1089
2/4
✓ Branch 0 (19→20) taken 7 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 7 times.
✗ Branch 3 (20→41) not taken.
7 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
1090
2/8
✓ Branch 0 (22→23) taken 7 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 7 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
7 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
1091
1/2
✓ Branch 0 (28→29) taken 7 times.
✗ Branch 1 (28→45) not taken.
7 currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)};
1092 }
1093
1094
1/2
✓ Branch 0 (32→33) taken 4 times.
✗ Branch 1 (32→46) not taken.
4 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
1095
1/2
✓ Branch 0 (33→34) taken 4 times.
✗ Branch 1 (33→46) not taken.
4 return currentOperand;
1096 }
1097
1098 57670 std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) {
1099 // Check if a bitwise and operator is applied
1100
2/2
✓ Branch 0 (3→4) taken 57640 times.
✓ Branch 1 (3→7) taken 30 times.
57670 if (node->operands.size() == 1)
1101
2/2
✓ Branch 0 (5→6) taken 57627 times.
✓ Branch 1 (5→46) taken 13 times.
57640 return visit(node->operands.front());
1102
1103 // Visit leftmost operand
1104
2/4
✓ Branch 0 (8→9) taken 30 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 30 times.
✗ Branch 3 (9→37) not taken.
30 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
1105
2/8
✓ Branch 0 (11→12) taken 30 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 30 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
30 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
1106
1107 // Loop through all remaining operands
1108
2/2
✓ Branch 0 (31→18) taken 33 times.
✓ Branch 1 (31→32) taken 30 times.
63 for (size_t i = 1; i < node->operands.size(); i++) {
1109
2/4
✓ Branch 0 (19→20) taken 33 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 33 times.
✗ Branch 3 (20→41) not taken.
33 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
1110
2/8
✓ Branch 0 (22→23) taken 33 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 33 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
33 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
1111
1/2
✓ Branch 0 (28→29) taken 33 times.
✗ Branch 1 (28→45) not taken.
33 currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)};
1112 }
1113
1114
1/2
✓ Branch 0 (32→33) taken 30 times.
✗ Branch 1 (32→46) not taken.
30 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
1115
1/2
✓ Branch 0 (33→34) taken 30 times.
✗ Branch 1 (33→46) not taken.
30 return currentOperand;
1116 }
1117
1118 57703 std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) {
1119 // Check if at least one equality operator is applied
1120
2/2
✓ Branch 0 (3→4) taken 53076 times.
✓ Branch 1 (3→7) taken 4627 times.
57703 if (node->operands.size() == 1)
1121
2/2
✓ Branch 0 (5→6) taken 53064 times.
✓ Branch 1 (5→73) taken 12 times.
53076 return visit(node->operands.front());
1122
1123 // Visit right side first, then left side
1124
2/4
✓ Branch 0 (8→9) taken 4627 times.
✗ Branch 1 (8→58) not taken.
✓ Branch 2 (9→10) taken 4627 times.
✗ Branch 3 (9→56) not taken.
4627 const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1]));
1125
2/8
✓ Branch 0 (11→12) taken 4627 times.
✗ Branch 1 (11→73) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4627 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→59) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→59) not taken.
4627 HANDLE_UNRESOLVED_TYPE_ER(rhs.type)
1126
2/4
✓ Branch 0 (18→19) taken 4627 times.
✗ Branch 1 (18→62) not taken.
✓ Branch 2 (19→20) taken 4627 times.
✗ Branch 3 (19→60) not taken.
4627 const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0]));
1127
2/8
✓ Branch 0 (21→22) taken 4627 times.
✗ Branch 1 (21→73) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 4627 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→63) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→63) not taken.
4627 HANDLE_UNRESOLVED_TYPE_ER(lhs.type)
1128
1129 // Check if we need the string runtime to perform a string comparison
1130
10/14
✓ Branch 0 (27→28) taken 4627 times.
✗ Branch 1 (27→73) not taken.
✓ Branch 2 (28→29) taken 113 times.
✓ Branch 3 (28→36) taken 4514 times.
✓ Branch 4 (29→30) taken 113 times.
✗ Branch 5 (29→73) not taken.
✓ Branch 6 (30→31) taken 112 times.
✓ Branch 7 (30→36) taken 1 times.
✓ Branch 8 (31→32) taken 112 times.
✗ Branch 9 (31→73) not taken.
✓ Branch 10 (34→35) taken 112 times.
✗ Branch 11 (34→36) not taken.
✓ Branch 12 (37→38) taken 112 times.
✓ Branch 13 (37→39) taken 4515 times.
4739 if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT())
1131
1/2
✓ Branch 0 (38→39) taken 112 times.
✗ Branch 1 (38→73) not taken.
112 sourceFile->requestRuntimeModule(STRING_RT);
1132
1133 // Check operator
1134 4627 ExprResult result;
1135
2/2
✓ Branch 0 (39→40) taken 3249 times.
✓ Branch 1 (39→41) taken 1378 times.
4627 if (node->op == EqualityExprNode::EqualityOp::OP_EQUAL) // Operator was equal
1136
2/2
✓ Branch 0 (40→51) taken 3248 times.
✓ Branch 1 (40→73) taken 1 times.
3249 result = opRuleManager.getEqualResultType(node, lhs, rhs, 0);
1137
1/2
✓ Branch 0 (41→42) taken 1378 times.
✗ Branch 1 (41→43) not taken.
1378 else if (node->op == EqualityExprNode::EqualityOp::OP_NOT_EQUAL) // Operator was not equal
1138
1/2
✓ Branch 0 (42→51) taken 1378 times.
✗ Branch 1 (42→73) not taken.
1378 result = opRuleManager.getNotEqualResultType(node, lhs, rhs, 0);
1139 else
1140 throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE
1141
1142
1/2
✓ Branch 0 (51→52) taken 4626 times.
✗ Branch 1 (51→73) not taken.
4626 node->setEvaluatedSymbolType(result.type, manIdx);
1143
1/2
✓ Branch 0 (52→53) taken 4626 times.
✗ Branch 1 (52→73) not taken.
4626 return result;
1144 }
1145
1146 62330 std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) {
1147 // Check if a relational operator is applied
1148
2/2
✓ Branch 0 (3→4) taken 59171 times.
✓ Branch 1 (3→7) taken 3159 times.
62330 if (node->operands.size() == 1)
1149
2/2
✓ Branch 0 (5→6) taken 59160 times.
✓ Branch 1 (5→75) taken 11 times.
59171 return visit(node->operands.front());
1150
1151 // Visit right side first, then left side
1152
2/4
✓ Branch 0 (8→9) taken 3159 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 3159 times.
✗ Branch 3 (9→53) not taken.
3159 const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1]));
1153
5/8
✓ Branch 0 (11→12) taken 3159 times.
✗ Branch 1 (11→75) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→17) taken 3158 times.
✓ Branch 4 (13→14) taken 1 times.
✗ Branch 5 (13→56) not taken.
✓ Branch 6 (14→15) taken 1 times.
✗ Branch 7 (14→56) not taken.
3159 HANDLE_UNRESOLVED_TYPE_ER(rhs.type)
1154
2/4
✓ Branch 0 (18→19) taken 3158 times.
✗ Branch 1 (18→59) not taken.
✓ Branch 2 (19→20) taken 3158 times.
✗ Branch 3 (19→57) not taken.
3158 const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0]));
1155
2/8
✓ Branch 0 (21→22) taken 3158 times.
✗ Branch 1 (21→75) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 3158 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→60) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→60) not taken.
3158 HANDLE_UNRESOLVED_TYPE_ER(lhs.type)
1156
1157 // Check operator
1158 3158 QualType resultType;
1159
2/2
✓ Branch 0 (27→28) taken 1616 times.
✓ Branch 1 (27→30) taken 1542 times.
3158 if (node->op == RelationalExprNode::RelationalOp::OP_LESS) // Operator was less
1160
1/2
✓ Branch 0 (28→29) taken 1616 times.
✗ Branch 1 (28→61) not taken.
1616 resultType = OpRuleManager::getLessResultType(node, lhs, rhs);
1161
2/2
✓ Branch 0 (30→31) taken 388 times.
✓ Branch 1 (30→33) taken 1154 times.
1542 else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER) // Operator was greater
1162
2/2
✓ Branch 0 (31→32) taken 387 times.
✓ Branch 1 (31→62) taken 1 times.
388 resultType = OpRuleManager::getGreaterResultType(node, lhs, rhs);
1163
2/2
✓ Branch 0 (33→34) taken 344 times.
✓ Branch 1 (33→36) taken 810 times.
1154 else if (node->op == RelationalExprNode::RelationalOp::OP_LESS_EQUAL) // Operator was less equal
1164
1/2
✓ Branch 0 (34→35) taken 344 times.
✗ Branch 1 (34→63) not taken.
344 resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs);
1165
1/2
✓ Branch 0 (36→37) taken 810 times.
✗ Branch 1 (36→39) not taken.
810 else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER_EQUAL) // Operator was greater equal
1166
1/2
✓ Branch 0 (37→38) taken 810 times.
✗ Branch 1 (37→64) not taken.
810 resultType = OpRuleManager::getGreaterEqualResultType(node, lhs, rhs);
1167 else
1168 throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE
1169
1170
2/4
✓ Branch 0 (47→48) taken 3157 times.
✗ Branch 1 (47→74) not taken.
✓ Branch 2 (48→49) taken 3157 times.
✗ Branch 3 (48→74) not taken.
3157 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)};
1171 }
1172
1173 65488 std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) {
1174 // Check if at least one shift operator is applied
1175
2/2
✓ Branch 0 (3→4) taken 65449 times.
✓ Branch 1 (3→7) taken 39 times.
65488 if (node->operands.size() == 1)
1176
2/2
✓ Branch 0 (5→6) taken 65438 times.
✓ Branch 1 (5→69) taken 11 times.
65449 return visit(node->operands.front());
1177
1178 // Visit leftmost operand
1179
2/4
✓ Branch 0 (8→9) taken 39 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 39 times.
✗ Branch 3 (9→51) not taken.
39 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
1180
2/8
✓ Branch 0 (11→12) taken 39 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 39 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→54) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→54) not taken.
39 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
1181
1182 // Loop through remaining operands
1183
2/2
✓ Branch 0 (45→18) taken 63 times.
✓ Branch 1 (45→46) taken 39 times.
102 for (size_t i = 0; i < node->opQueue.size(); i++) {
1184
2/4
✓ Branch 0 (19→20) taken 63 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 63 times.
✗ Branch 3 (20→55) not taken.
63 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
1185
2/8
✓ Branch 0 (22→23) taken 63 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 63 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→58) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→58) not taken.
63 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
1186
1187 // Check operator
1188 63 const ShiftExprNode::ShiftOp &op = node->opQueue.front().first;
1189
2/2
✓ Branch 0 (29→30) taken 56 times.
✓ Branch 1 (29→31) taken 7 times.
63 if (op == ShiftExprNode::ShiftOp::OP_SHIFT_LEFT)
1190
1/2
✓ Branch 0 (30→41) taken 56 times.
✗ Branch 1 (30→68) not taken.
56 currentResult = opRuleManager.getShiftLeftResultType(node, currentResult, operandResult, i);
1191
1/2
✓ Branch 0 (31→32) taken 7 times.
✗ Branch 1 (31→33) not taken.
7 else if (op == ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT)
1192
1/2
✓ Branch 0 (32→41) taken 7 times.
✗ Branch 1 (32→68) not taken.
7 currentResult = opRuleManager.getShiftRightResultType(node, currentResult, operandResult, i);
1193 else
1194 throw CompilerError(UNHANDLED_BRANCH, "ShiftExpr fall-through"); // GCOV_EXCL_LINE
1195
1196 // Push the new item and pop the old one on the other side of the queue
1197
1/2
✓ Branch 0 (41→42) taken 63 times.
✗ Branch 1 (41→68) not taken.
63 node->opQueue.emplace(op, currentResult.type);
1198 63 node->opQueue.pop();
1199 }
1200
1201
1/2
✓ Branch 0 (46→47) taken 39 times.
✗ Branch 1 (46→69) not taken.
39 node->setEvaluatedSymbolType(currentResult.type, manIdx);
1202
1/2
✓ Branch 0 (47→48) taken 39 times.
✗ Branch 1 (47→69) not taken.
39 return currentResult;
1203 }
1204
1205 65551 std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) {
1206 // Check if at least one additive operator is applied
1207
2/2
✓ Branch 0 (3→4) taken 61890 times.
✓ Branch 1 (3→7) taken 3661 times.
65551 if (node->operands.size() == 1)
1208
2/2
✓ Branch 0 (5→6) taken 61880 times.
✓ Branch 1 (5→69) taken 10 times.
61890 return visit(node->operands.front());
1209
1210 // Visit leftmost operand
1211
2/4
✓ Branch 0 (8→9) taken 3661 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 3661 times.
✗ Branch 3 (9→51) not taken.
3661 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
1212
2/8
✓ Branch 0 (11→12) taken 3661 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 3661 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→54) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→54) not taken.
3661 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
1213
1214 // Loop through remaining operands
1215
2/2
✓ Branch 0 (45→18) taken 4178 times.
✓ Branch 1 (45→46) taken 3660 times.
7838 for (size_t i = 0; i < node->opQueue.size(); i++) {
1216
2/4
✓ Branch 0 (19→20) taken 4178 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 4178 times.
✗ Branch 3 (20→55) not taken.
4178 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
1217
2/8
✓ Branch 0 (22→23) taken 4178 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 4178 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→58) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→58) not taken.
4178 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
1218
1219 // Check operator
1220 4178 const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first;
1221
2/2
✓ Branch 0 (29→30) taken 2500 times.
✓ Branch 1 (29→31) taken 1678 times.
4178 if (op == AdditiveExprNode::AdditiveOp::OP_PLUS)
1222
2/2
✓ Branch 0 (30→41) taken 2499 times.
✓ Branch 1 (30→68) taken 1 times.
2500 currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i);
1223
1/2
✓ Branch 0 (31→32) taken 1678 times.
✗ Branch 1 (31→33) not taken.
1678 else if (op == AdditiveExprNode::AdditiveOp::OP_MINUS)
1224
1/2
✓ Branch 0 (32→41) taken 1678 times.
✗ Branch 1 (32→68) not taken.
1678 currentResult = opRuleManager.getMinusResultType(node, currentResult, operandResult, i);
1225 else
1226 throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE
1227
1228 // Push the new item and pop the old one on the other side of the queue
1229
1/2
✓ Branch 0 (41→42) taken 4177 times.
✗ Branch 1 (41→68) not taken.
4177 node->opQueue.emplace(op, currentResult.type);
1230 4177 node->opQueue.pop();
1231 }
1232
1233
1/2
✓ Branch 0 (46→47) taken 3660 times.
✗ Branch 1 (46→69) not taken.
3660 node->setEvaluatedSymbolType(currentResult.type, manIdx);
1234
1/2
✓ Branch 0 (47→48) taken 3660 times.
✗ Branch 1 (47→69) not taken.
3660 return currentResult;
1235 }
1236
1237 69729 std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) {
1238 // Check if at least one multiplicative operator is applied
1239
2/2
✓ Branch 0 (3→4) taken 68836 times.
✓ Branch 1 (3→7) taken 893 times.
69729 if (node->operands.size() == 1)
1240
2/2
✓ Branch 0 (5→6) taken 68827 times.
✓ Branch 1 (5→71) taken 9 times.
68836 return visit(node->operands.front());
1241
1242 // Visit leftmost operand
1243
2/4
✓ Branch 0 (8→9) taken 893 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 893 times.
✗ Branch 3 (9→53) not taken.
893 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
1244
2/8
✓ Branch 0 (11→12) taken 893 times.
✗ Branch 1 (11→71) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 893 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→56) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→56) not taken.
893 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
1245 // Loop through remaining operands
1246
2/2
✓ Branch 0 (47→18) taken 917 times.
✓ Branch 1 (47→48) taken 892 times.
1809 for (size_t i = 0; i < node->opQueue.size(); i++) {
1247
2/4
✓ Branch 0 (19→20) taken 917 times.
✗ Branch 1 (19→59) not taken.
✓ Branch 2 (20→21) taken 917 times.
✗ Branch 3 (20→57) not taken.
917 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
1248
2/8
✓ Branch 0 (22→23) taken 917 times.
✗ Branch 1 (22→70) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 917 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→60) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→60) not taken.
917 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
1249
1250 // Check operator
1251 917 const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first;
1252
2/2
✓ Branch 0 (29→30) taken 691 times.
✓ Branch 1 (29→31) taken 226 times.
917 if (op == MultiplicativeExprNode::MultiplicativeOp::OP_MUL)
1253
2/2
✓ Branch 0 (30→43) taken 690 times.
✓ Branch 1 (30→70) taken 1 times.
691 currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i);
1254
2/2
✓ Branch 0 (31→32) taken 217 times.
✓ Branch 1 (31→33) taken 9 times.
226 else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_DIV)
1255
1/2
✓ Branch 0 (32→43) taken 217 times.
✗ Branch 1 (32→70) not taken.
217 currentResult = opRuleManager.getDivResultType(node, currentResult, operandResult, i);
1256
1/2
✓ Branch 0 (33→34) taken 9 times.
✗ Branch 1 (33→35) not taken.
9 else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_REM)
1257
1/2
✓ Branch 0 (34→43) taken 9 times.
✗ Branch 1 (34→70) not taken.
9 currentResult = OpRuleManager::getRemResultType(node, currentResult, operandResult);
1258 else
1259 throw CompilerError(UNHANDLED_BRANCH, "Multiplicative fall-through"); // GCOV_EXCL_LINE
1260
1261 // Push the new item and pop the old one on the other side of the queue
1262
1/2
✓ Branch 0 (43→44) taken 916 times.
✗ Branch 1 (43→70) not taken.
916 node->opQueue.emplace(op, currentResult.type);
1263 916 node->opQueue.pop();
1264 }
1265
1266
1/2
✓ Branch 0 (48→49) taken 892 times.
✗ Branch 1 (48→71) not taken.
892 node->setEvaluatedSymbolType(currentResult.type, manIdx);
1267
1/2
✓ Branch 0 (49→50) taken 892 times.
✗ Branch 1 (49→71) not taken.
892 return currentResult;
1268 }
1269
1270 70646 std::any TypeChecker::visitCastExpr(CastExprNode *node) {
1271 // Check if cast is applied
1272
2/2
✓ Branch 0 (2→3) taken 67925 times.
✓ Branch 1 (2→5) taken 2721 times.
70646 if (!node->isCast)
1273
2/2
✓ Branch 0 (3→4) taken 67916 times.
✓ Branch 1 (3→65) taken 9 times.
67925 return visit(node->prefixUnaryExpr);
1274
1275 // Visit source type
1276
2/4
✓ Branch 0 (5→6) taken 2721 times.
✗ Branch 1 (5→49) not taken.
✓ Branch 2 (6→7) taken 2721 times.
✗ Branch 3 (6→47) not taken.
2721 const auto src = std::any_cast<ExprResult>(visit(node->prefixUnaryExpr));
1277
2/8
✓ Branch 0 (8→9) taken 2721 times.
✗ Branch 1 (8→65) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 2721 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→50) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→50) not taken.
2721 HANDLE_UNRESOLVED_TYPE_ER(src.type)
1278 // Visit destination type
1279
2/4
✓ Branch 0 (14→15) taken 2721 times.
✗ Branch 1 (14→53) not taken.
✓ Branch 2 (15→16) taken 2721 times.
✗ Branch 3 (15→51) not taken.
2721 const auto dstType = std::any_cast<QualType>(visit(node->dataType));
1280
2/8
✓ Branch 0 (17→18) taken 2721 times.
✗ Branch 1 (17→65) not taken.
✗ Branch 2 (18→19) not taken.
✓ Branch 3 (18→23) taken 2721 times.
✗ Branch 4 (19→20) not taken.
✗ Branch 5 (19→54) not taken.
✗ Branch 6 (20→21) not taken.
✗ Branch 7 (20→54) not taken.
2721 HANDLE_UNRESOLVED_TYPE_ER(dstType)
1281
1282 // Check for identity cast
1283
3/4
✓ Branch 0 (23→24) taken 2721 times.
✗ Branch 1 (23→65) not taken.
✓ Branch 2 (24→25) taken 1190 times.
✓ Branch 3 (24→34) taken 1531 times.
2721 if (src.type == dstType) {
1284
2/4
✓ Branch 0 (27→28) taken 1190 times.
✗ Branch 1 (27→57) not taken.
✓ Branch 2 (28→29) taken 1190 times.
✗ Branch 3 (28→55) not taken.
1190 const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified.");
1285
1/2
✓ Branch 0 (31→32) taken 1190 times.
✗ Branch 1 (31→61) not taken.
1190 sourceFile->compilerOutput.warnings.push_back(warning);
1286 1190 }
1287
1288 // Get result type
1289
1/2
✓ Branch 0 (34→35) taken 2721 times.
✗ Branch 1 (34→65) not taken.
2721 const QualType resultType = opRuleManager.getCastResultType(node, dstType, src);
1290
1291
1/2
✓ Branch 0 (35→36) taken 2721 times.
✗ Branch 1 (35→65) not taken.
2721 const bool typesMatch = dstType.matches(src.type, false, true, true);
1292
1/2
✓ Branch 0 (36→37) taken 2721 times.
✗ Branch 1 (36→65) not taken.
2721 const bool sameContainerType = src.type.isSameContainerTypeAs(dstType);
1293
4/4
✓ Branch 0 (37→38) taken 1531 times.
✓ Branch 1 (37→39) taken 1190 times.
✓ Branch 2 (38→39) taken 121 times.
✓ Branch 3 (38→40) taken 1410 times.
2721 SymbolTableEntry *entry = typesMatch || sameContainerType ? src.entry : nullptr;
1294
2/4
✓ Branch 0 (41→42) taken 2721 times.
✗ Branch 1 (41→64) not taken.
✓ Branch 2 (42→43) taken 2721 times.
✗ Branch 3 (42→64) not taken.
2721 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry};
1295 }
1296
1297 77012 std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) {
1298 // Reset access scope
1299 77012 accessScope = nullptr;
1300
1301 // If no operator is applied, simply visit the postfix unary expression
1302
2/2
✓ Branch 0 (2→3) taken 76071 times.
✓ Branch 1 (2→5) taken 941 times.
77012 if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE)
1303
2/2
✓ Branch 0 (3→4) taken 76063 times.
✓ Branch 1 (3→78) taken 8 times.
76071 return visit(node->postfixUnaryExpr);
1304
1305 // Visit the right side
1306 941 PrefixUnaryExprNode *rhsNode = node->prefixUnaryExpr;
1307
2/4
✓ Branch 0 (5→6) taken 941 times.
✗ Branch 1 (5→57) not taken.
✓ Branch 2 (6→7) taken 941 times.
✗ Branch 3 (6→55) not taken.
941 auto operand = std::any_cast<ExprResult>(visit(rhsNode));
1308 941 auto [operandType, operandEntry] = operand;
1309
5/8
✓ Branch 0 (8→9) taken 941 times.
✗ Branch 1 (8→78) not taken.
✓ Branch 2 (9→10) taken 1 times.
✓ Branch 3 (9→14) taken 940 times.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→58) not taken.
✓ Branch 6 (11→12) taken 1 times.
✗ Branch 7 (11→58) not taken.
941 HANDLE_UNRESOLVED_TYPE_ER(operandType)
1310 // Determine action, based on the given operator
1311
7/8
✓ Branch 0 (14→15) taken 16 times.
✓ Branch 1 (14→17) taken 33 times.
✓ Branch 2 (14→25) taken 8 times.
✓ Branch 3 (14→33) taken 630 times.
✓ Branch 4 (14→35) taken 1 times.
✓ Branch 5 (14→37) taken 173 times.
✓ Branch 6 (14→39) taken 79 times.
✗ Branch 7 (14→41) not taken.
940 switch (node->op) {
1312 16 case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS:
1313
1/2
✓ Branch 0 (15→16) taken 16 times.
✗ Branch 1 (15→59) not taken.
16 operandType = OpRuleManager::getPrefixMinusResultType(node, operand);
1314 16 break;
1315 33 case PrefixUnaryExprNode::PrefixUnaryOp::OP_PLUS_PLUS:
1316
1/2
✓ Branch 0 (17→18) taken 33 times.
✗ Branch 1 (17→60) not taken.
33 operandType = opRuleManager.getPrefixPlusPlusResultType(node, operand);
1317
1318
2/2
✓ Branch 0 (18→19) taken 30 times.
✓ Branch 1 (18→24) taken 3 times.
33 if (operandEntry) {
1319 // In case the lhs is captured, notify the capture about the write access
1320
2/4
✓ Branch 0 (19→20) taken 30 times.
✗ Branch 1 (19→78) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→22) taken 30 times.
30 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
1321 lhsCapture->setAccessType(READ_WRITE);
1322
1323 // Update the state of the variable
1324
1/2
✓ Branch 0 (22→23) taken 30 times.
✗ Branch 1 (22→61) not taken.
30 operandEntry->updateState(INITIALIZED, node);
1325 }
1326
1327 33 break;
1328 8 case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS_MINUS:
1329
2/2
✓ Branch 0 (25→26) taken 7 times.
✓ Branch 1 (25→62) taken 1 times.
8 operandType = opRuleManager.getPrefixMinusMinusResultType(node, operand);
1330
1331
2/2
✓ Branch 0 (26→27) taken 4 times.
✓ Branch 1 (26→32) taken 3 times.
7 if (operandEntry) {
1332 // In case the lhs is captured, notify the capture about the write access
1333
2/4
✓ Branch 0 (27→28) taken 4 times.
✗ Branch 1 (27→78) not taken.
✗ Branch 2 (28→29) not taken.
✓ Branch 3 (28→30) taken 4 times.
4 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
1334 lhsCapture->setAccessType(READ_WRITE);
1335
1336 // Update the state of the variable
1337
1/2
✓ Branch 0 (30→31) taken 4 times.
✗ Branch 1 (30→63) not taken.
4 operandEntry->updateState(INITIALIZED, node);
1338 }
1339
1340 7 break;
1341 630 case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT:
1342
1/2
✓ Branch 0 (33→34) taken 630 times.
✗ Branch 1 (33→64) not taken.
630 operandType = OpRuleManager::getPrefixNotResultType(node, operand);
1343 630 break;
1344 1 case PrefixUnaryExprNode::PrefixUnaryOp::OP_BITWISE_NOT:
1345
1/2
✓ Branch 0 (35→36) taken 1 times.
✗ Branch 1 (35→65) not taken.
1 operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operand);
1346 1 break;
1347 173 case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE:
1348
1/2
✓ Branch 0 (37→38) taken 173 times.
✗ Branch 1 (37→66) not taken.
173 operandType = OpRuleManager::getPrefixMulResultType(node, operand);
1349 173 break;
1350 79 case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF:
1351
1/2
✓ Branch 0 (39→40) taken 79 times.
✗ Branch 1 (39→67) not taken.
79 operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand);
1352 79 break;
1353 default:
1354 throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE
1355 }
1356
1357
2/4
✓ Branch 0 (49→50) taken 939 times.
✗ Branch 1 (49→77) not taken.
✓ Branch 2 (50→51) taken 939 times.
✗ Branch 3 (50→77) not taken.
939 return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry};
1358 }
1359
1360 95194 std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) {
1361 // If no operator is applied, simply visit the atomic expression
1362
2/2
✓ Branch 0 (2→3) taken 76071 times.
✓ Branch 1 (2→5) taken 19123 times.
95194 if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE)
1363
2/2
✓ Branch 0 (3→4) taken 76064 times.
✓ Branch 1 (3→318) taken 7 times.
76071 return visit(node->atomicExpr);
1364
1365 // Visit left side
1366 19123 PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr;
1367
2/4
✓ Branch 0 (5→6) taken 19123 times.
✗ Branch 1 (5→212) not taken.
✓ Branch 2 (6→7) taken 19123 times.
✗ Branch 3 (6→210) not taken.
19123 auto operand = std::any_cast<ExprResult>(visit(lhsNode));
1368 19123 auto [operandType, operandEntry] = operand;
1369
5/8
✓ Branch 0 (8→9) taken 19123 times.
✗ Branch 1 (8→318) not taken.
✓ Branch 2 (9→10) taken 6 times.
✓ Branch 3 (9→14) taken 19117 times.
✓ Branch 4 (10→11) taken 6 times.
✗ Branch 5 (10→213) not taken.
✓ Branch 6 (11→12) taken 6 times.
✗ Branch 7 (11→213) not taken.
19123 HANDLE_UNRESOLVED_TYPE_ER(operandType)
1370
1371
4/5
✓ Branch 0 (14→15) taken 2980 times.
✓ Branch 1 (14→101) taken 14200 times.
✓ Branch 2 (14→160) taken 1570 times.
✓ Branch 3 (14→168) taken 367 times.
✗ Branch 4 (14→176) not taken.
19117 switch (node->op) {
1372 2980 case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: {
1373 // Visit index assignment
1374 2980 AssignExprNode *indexAssignExpr = node->subscriptIndexExpr;
1375
2/4
✓ Branch 0 (15→16) taken 2980 times.
✗ Branch 1 (15→216) not taken.
✓ Branch 2 (16→17) taken 2980 times.
✗ Branch 3 (16→214) not taken.
2980 const auto index = std::any_cast<ExprResult>(visit(indexAssignExpr));
1376
2/8
✓ Branch 0 (18→19) taken 2980 times.
✗ Branch 1 (18→260) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 2980 times.
✗ Branch 4 (20→21) not taken.
✗ Branch 5 (20→217) not taken.
✗ Branch 6 (21→22) not taken.
✗ Branch 7 (21→217) not taken.
2980 HANDLE_UNRESOLVED_TYPE_ER(index.type)
1377 // Check if the index is of the right type
1378
3/4
✓ Branch 0 (24→25) taken 2980 times.
✗ Branch 1 (24→218) not taken.
✓ Branch 2 (25→26) taken 1 times.
✓ Branch 3 (25→36) taken 2979 times.
2980 if (!index.type.isOneOf({TY_INT, TY_LONG}))
1379
4/8
✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→221) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→219) not taken.
✓ Branch 4 (32→33) taken 1 times.
✗ Branch 5 (32→225) not taken.
✓ Branch 6 (33→34) taken 1 times.
✗ Branch 7 (33→225) not taken.
3 SOFT_ERROR_ER(node, ARRAY_INDEX_NOT_INT_OR_LONG, "Array index must be of type int or long")
1380
1381 // Check is there is an overloaded operator function available, if yes accept it
1382
1/2
✓ Branch 0 (36→37) taken 2979 times.
✗ Branch 1 (36→226) not taken.
2979 const auto [type, _] = opRuleManager.isOperatorOverloadingFctAvailable<2>(node, OP_FCT_SUBSCRIPT, {operand, index}, 0);
1383
3/4
✓ Branch 0 (37→38) taken 2979 times.
✗ Branch 1 (37→260) not taken.
✓ Branch 2 (38→39) taken 94 times.
✓ Branch 3 (38→40) taken 2885 times.
2979 if (!type.is(TY_INVALID)) {
1384 94 operandType = type;
1385 2978 break;
1386 }
1387
1388
1/2
✓ Branch 0 (40→41) taken 2885 times.
✗ Branch 1 (40→227) not taken.
2885 operandType = operandType.removeReferenceWrapper();
1389
1390 // Check if we can apply the subscript operator on the lhs type
1391
2/4
✓ Branch 0 (41→42) taken 2885 times.
✗ Branch 1 (41→228) not taken.
✗ Branch 2 (42→43) not taken.
✓ Branch 3 (42→52) taken 2885 times.
2885 if (!operandType.isOneOf({TY_ARRAY, TY_PTR, TY_STRING}))
1392 SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE,
1393 "Can only apply subscript operator on array type, got " + operandType.getName(true))
1394
1395 // Check if we have an unsafe operation
1396
6/10
✓ Branch 0 (52→53) taken 2885 times.
✗ Branch 1 (52→260) not taken.
✓ Branch 2 (53→54) taken 2072 times.
✓ Branch 3 (53→57) taken 813 times.
✓ Branch 4 (54→55) taken 2072 times.
✗ Branch 5 (54→260) not taken.
✗ Branch 6 (55→56) not taken.
✓ Branch 7 (55→57) taken 2072 times.
✗ Branch 8 (58→59) not taken.
✓ Branch 9 (58→69) taken 2885 times.
2885 if (operandType.isPtr() && !currentScope->doesAllowUnsafeOperations())
1397 SOFT_ERROR_ER(
1398 node, UNSAFE_OPERATION_IN_SAFE_CONTEXT,
1399 "The subscript operator on pointers is an unsafe operation. Use unsafe blocks if you know what you are doing.")
1400
1401 // In case of compile time index value and known array size, perform a compile time out-of-bounds check
1402
11/14
✓ Branch 0 (69→70) taken 2885 times.
✗ Branch 1 (69→260) not taken.
✓ Branch 2 (70→71) taken 136 times.
✓ Branch 3 (70→76) taken 2749 times.
✓ Branch 4 (71→72) taken 136 times.
✗ Branch 5 (71→260) not taken.
✓ Branch 6 (72→73) taken 96 times.
✓ Branch 7 (72→76) taken 40 times.
✓ Branch 8 (73→74) taken 96 times.
✗ Branch 9 (73→260) not taken.
✓ Branch 10 (74→75) taken 34 times.
✓ Branch 11 (74→76) taken 62 times.
✓ Branch 12 (77→78) taken 34 times.
✓ Branch 13 (77→96) taken 2851 times.
2885 if (operandType.isArray() && operandType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) {
1403
1/2
✓ Branch 0 (78→79) taken 34 times.
✗ Branch 1 (78→243) not taken.
34 const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue;
1404
1/2
✓ Branch 0 (79→80) taken 34 times.
✗ Branch 1 (79→260) not taken.
34 const unsigned int constSize = operandType.getArraySize();
1405 // Check if we are accessing out-of-bounds memory
1406
2/2
✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→96) taken 33 times.
34 if (constIndex >= static_cast<int32_t>(constSize)) {
1407 1 const std::string idxStr = std::to_string(constIndex);
1408 1 const std::string sizeStr = std::to_string(constSize);
1409
6/12
✓ Branch 0 (83→84) taken 1 times.
✗ Branch 1 (83→250) not taken.
✓ Branch 2 (84→85) taken 1 times.
✗ Branch 3 (84→248) not taken.
✓ Branch 4 (85→86) taken 1 times.
✗ Branch 5 (85→246) not taken.
✓ Branch 6 (86→87) taken 1 times.
✗ Branch 7 (86→244) not taken.
✓ Branch 8 (90→91) taken 1 times.
✗ Branch 9 (90→253) not taken.
✓ Branch 10 (91→92) taken 1 times.
✗ Branch 11 (91→253) not taken.
1 SOFT_ERROR_ER(node, ARRAY_INDEX_OUT_OF_BOUNDS,
1410 "You are trying to access element with index " + idxStr + " of an array with size " + sizeStr)
1411 1 }
1412 }
1413
1414 // Get item type
1415
1/2
✓ Branch 0 (96→97) taken 2884 times.
✗ Branch 1 (96→259) not taken.
2884 operandType = operandType.getContained();
1416
1417 // Remove heap qualifier
1418 2884 operandType.getQualifiers().isHeap = false;
1419
1420 2884 break;
1421 }
1422 14200 case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: {
1423 14200 const std::string &fieldName = node->identifier;
1424
1425 // Check if lhs is enum or strobj
1426 14200 QualType lhsBaseTy = operandType;
1427
1/2
✓ Branch 0 (101→102) taken 14200 times.
✗ Branch 1 (101→288) not taken.
14200 autoDeReference(lhsBaseTy);
1428
3/4
✓ Branch 0 (102→103) taken 14200 times.
✗ Branch 1 (102→288) not taken.
✓ Branch 2 (103→104) taken 1 times.
✓ Branch 3 (103→113) taken 14199 times.
14200 if (!lhsBaseTy.is(TY_STRUCT))
1429
5/10
✓ Branch 0 (104→105) taken 1 times.
✗ Branch 1 (104→265) not taken.
✓ Branch 2 (105→106) taken 1 times.
✗ Branch 3 (105→263) not taken.
✓ Branch 4 (106→107) taken 1 times.
✗ Branch 5 (106→261) not taken.
✓ Branch 6 (109→110) taken 1 times.
✗ Branch 7 (109→267) not taken.
✓ Branch 8 (110→111) taken 1 times.
✗ Branch 9 (110→267) not taken.
1 SOFT_ERROR_ER(node, INVALID_MEMBER_ACCESS, "Cannot apply member access operator on " + operandType.getName(false))
1430
1431 // Retrieve registry entry
1432
1/2
✓ Branch 0 (113→114) taken 14199 times.
✗ Branch 1 (113→288) not taken.
14199 const std::string &structName = lhsBaseTy.getSubType();
1433
1/2
✓ Branch 0 (114→115) taken 14199 times.
✗ Branch 1 (114→288) not taken.
14199 Scope *structScope = lhsBaseTy.getBodyScope();
1434
1435 // If we only have the generic struct scope, lookup the concrete manifestation scope
1436
2/2
✓ Branch 0 (115→116) taken 75 times.
✓ Branch 1 (115→121) taken 14124 times.
14199 if (structScope->isGenericScope) {
1437 75 Scope *matchScope = structScope->parent;
1438
2/4
✓ Branch 0 (116→117) taken 75 times.
✗ Branch 1 (116→288) not taken.
✓ Branch 2 (117→118) taken 75 times.
✗ Branch 3 (117→288) not taken.
75 Struct *spiceStruct = StructManager::match(matchScope, structName, lhsBaseTy.getTemplateTypes(), node);
1439
1/2
✗ Branch 0 (118→119) not taken.
✓ Branch 1 (118→120) taken 75 times.
75 assert(spiceStruct != nullptr);
1440 75 structScope = spiceStruct->scope;
1441 }
1442
1/2
✗ Branch 0 (121→122) not taken.
✓ Branch 1 (121→123) taken 14199 times.
14199 assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope
1443
1444 // Get accessed field
1445 14199 std::vector<size_t> indexPath;
1446
1/2
✓ Branch 0 (123→124) taken 14199 times.
✗ Branch 1 (123→286) not taken.
14199 SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath);
1447
2/2
✓ Branch 0 (124→125) taken 2 times.
✓ Branch 1 (124→136) taken 14197 times.
14199 if (!memberEntry)
1448
6/12
✓ Branch 0 (125→126) taken 2 times.
✗ Branch 1 (125→274) not taken.
✓ Branch 2 (126→127) taken 2 times.
✗ Branch 3 (126→272) not taken.
✓ Branch 4 (127→128) taken 2 times.
✗ Branch 5 (127→270) not taken.
✓ Branch 6 (128→129) taken 2 times.
✗ Branch 7 (128→268) not taken.
✓ Branch 8 (132→133) taken 2 times.
✗ Branch 9 (132→277) not taken.
✓ Branch 10 (133→134) taken 2 times.
✗ Branch 11 (133→277) not taken.
2 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Field '" + node->identifier + "' not found in struct " + structName)
1449
1/2
✓ Branch 0 (136→137) taken 14197 times.
✗ Branch 1 (136→286) not taken.
14197 const QualType memberType = memberEntry->getQualType();
1450
1451 // Check for insufficient visibility
1452
8/14
✓ Branch 0 (137→138) taken 14197 times.
✗ Branch 1 (137→278) not taken.
✓ Branch 2 (138→139) taken 69 times.
✓ Branch 3 (138→144) taken 14128 times.
✓ Branch 4 (139→140) taken 69 times.
✗ Branch 5 (139→278) not taken.
✓ Branch 6 (140→141) taken 69 times.
✗ Branch 7 (140→278) not taken.
✓ Branch 8 (141→142) taken 69 times.
✗ Branch 9 (141→278) not taken.
✗ Branch 10 (142→143) not taken.
✓ Branch 11 (142→144) taken 69 times.
✗ Branch 12 (145→146) not taken.
✓ Branch 13 (145→155) taken 14197 times.
14197 if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().getBase().isPublic())
1453 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access field '" + fieldName + "' due to its private visibility")
1454
1455 // Set field to used
1456 14197 memberEntry->used = true;
1457
1458 // Overwrite type and entry of left side with member type and entry
1459 14197 operandType = memberType;
1460 14197 operandEntry = memberEntry;
1461 14197 break;
1462
2/2
✓ Branch 0 (157→158) taken 2 times.
✓ Branch 1 (157→159) taken 14197 times.
14199 }
1463 1570 case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: {
1464
2/2
✓ Branch 0 (160→161) taken 1569 times.
✓ Branch 1 (160→289) taken 1 times.
1570 operandType = opRuleManager.getPostfixPlusPlusResultType(node, operand, 0).type;
1465
1466
2/2
✓ Branch 0 (161→162) taken 1565 times.
✓ Branch 1 (161→167) taken 4 times.
1569 if (operandEntry) {
1467 // In case the lhs is captured, notify the capture about the write access
1468
3/4
✓ Branch 0 (162→163) taken 1565 times.
✗ Branch 1 (162→318) not taken.
✓ Branch 2 (163→164) taken 4 times.
✓ Branch 3 (163→165) taken 1561 times.
1565 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
1469
1/2
✓ Branch 0 (164→165) taken 4 times.
✗ Branch 1 (164→318) not taken.
4 lhsCapture->setAccessType(READ_WRITE);
1470
1471 // Update the state of the variable
1472
1/2
✓ Branch 0 (165→166) taken 1565 times.
✗ Branch 1 (165→290) not taken.
1565 operandEntry->updateState(INITIALIZED, node);
1473 }
1474
1475 1569 break;
1476 }
1477 367 case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: {
1478
1/2
✓ Branch 0 (168→169) taken 367 times.
✗ Branch 1 (168→291) not taken.
367 operandType = opRuleManager.getPostfixMinusMinusResultType(node, operand, 0).type;
1479
1480
2/2
✓ Branch 0 (169→170) taken 363 times.
✓ Branch 1 (169→175) taken 4 times.
367 if (operandEntry) {
1481 // In case the lhs is captured, notify the capture about the write access
1482
2/4
✓ Branch 0 (170→171) taken 363 times.
✗ Branch 1 (170→318) not taken.
✗ Branch 2 (171→172) not taken.
✓ Branch 3 (171→173) taken 363 times.
363 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
1483 lhsCapture->setAccessType(READ_WRITE);
1484
1485 // Update the state of the variable
1486
1/2
✓ Branch 0 (173→174) taken 363 times.
✗ Branch 1 (173→292) not taken.
363 operandEntry->updateState(INITIALIZED, node);
1487 }
1488
1489 367 break;
1490 }
1491 default:
1492 throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE
1493 }
1494
1495
2/4
✓ Branch 0 (184→185) taken 19111 times.
✗ Branch 1 (184→318) not taken.
✗ Branch 2 (185→186) not taken.
✓ Branch 3 (185→204) taken 19111 times.
19111 if (operandType.is(TY_INVALID)) {
1496 const std::string varName = operandEntry ? operandEntry->name : "";
1497 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Variable '" + varName + "' was referenced before declared")
1498 }
1499
1500
2/4
✓ Branch 0 (204→205) taken 19111 times.
✗ Branch 1 (204→317) not taken.
✓ Branch 2 (205→206) taken 19111 times.
✗ Branch 3 (205→317) not taken.
19111 return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry};
1501 }
1502
1503 76071 std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) {
1504 // Check if constant
1505
2/2
✓ Branch 0 (2→3) taken 14752 times.
✓ Branch 1 (2→5) taken 61319 times.
76071 if (node->constant)
1506
1/2
✓ Branch 0 (3→4) taken 14752 times.
✗ Branch 1 (3→243) not taken.
14752 return visit(node->constant);
1507
1508 // Check if value
1509
2/2
✓ Branch 0 (5→6) taken 14672 times.
✓ Branch 1 (5→8) taken 46647 times.
61319 if (node->value)
1510
2/2
✓ Branch 0 (6→7) taken 14668 times.
✓ Branch 1 (6→243) taken 4 times.
14672 return visit(node->value);
1511
1512 // Check for builtin calls
1513
2/2
✓ Branch 0 (8→9) taken 1454 times.
✓ Branch 1 (8→11) taken 45193 times.
46647 if (node->builtinCall)
1514
1/2
✓ Branch 0 (9→10) taken 1454 times.
✗ Branch 1 (9→243) not taken.
1454 return visit(node->builtinCall);
1515
1516 // Check for assign expression within parentheses
1517
2/2
✓ Branch 0 (11→12) taken 546 times.
✓ Branch 1 (11→14) taken 44647 times.
45193 if (node->assignExpr)
1518
2/2
✓ Branch 0 (12→13) taken 543 times.
✓ Branch 1 (12→243) taken 3 times.
546 return visit(node->assignExpr);
1519
1520 // Identifier (local or global variable access)
1521
1/2
✗ Branch 0 (15→16) not taken.
✓ Branch 1 (15→17) taken 44647 times.
44647 assert(!node->fqIdentifier.empty());
1522
1/2
✓ Branch 0 (17→18) taken 44647 times.
✗ Branch 1 (17→19) not taken.
44647 if (!accessScope)
1523 44647 accessScope = currentScope;
1524
1525 // Check if a local or global variable can be found by searching for the name
1526 44647 SymbolTableEntry *varEntry = nullptr;
1527
2/2
✓ Branch 0 (20→21) taken 44389 times.
✓ Branch 1 (20→26) taken 258 times.
44647 if (node->identifierFragments.size() == 1)
1528 88778 varEntry = accessScope->lookup(node->identifierFragments.back());
1529
1530 // If no local or global was found, search in the name registry
1531
2/2
✓ Branch 0 (26→27) taken 317 times.
✓ Branch 1 (26→39) taken 44330 times.
44647 if (!varEntry) {
1532
1/2
✓ Branch 0 (27→28) taken 317 times.
✗ Branch 1 (27→243) not taken.
317 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier);
1533
2/2
✓ Branch 0 (28→29) taken 1 times.
✓ Branch 1 (28→38) taken 316 times.
317 if (!registryEntry)
1534
5/10
✓ Branch 0 (29→30) taken 1 times.
✗ Branch 1 (29→185) not taken.
✓ Branch 2 (30→31) taken 1 times.
✗ Branch 3 (30→183) not taken.
✓ Branch 4 (31→32) taken 1 times.
✗ Branch 5 (31→181) not taken.
✓ Branch 6 (34→35) taken 1 times.
✗ Branch 7 (34→187) not taken.
✓ Branch 8 (35→36) taken 1 times.
✗ Branch 9 (35→187) not taken.
1 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found")
1535 316 varEntry = registryEntry->targetEntry;
1536 316 accessScope = registryEntry->targetScope;
1537 }
1538
1/2
✗ Branch 0 (39→40) not taken.
✓ Branch 1 (39→41) taken 44646 times.
44646 assert(varEntry != nullptr);
1539
1/2
✗ Branch 0 (41→42) not taken.
✓ Branch 1 (41→43) taken 44646 times.
44646 assert(accessScope != nullptr);
1540
1/2
✓ Branch 0 (43→44) taken 44646 times.
✗ Branch 1 (43→243) not taken.
44646 AtomicExprNode::VarAccessData &data = node->data.at(manIdx);
1541
1/2
✓ Branch 0 (44→45) taken 44646 times.
✗ Branch 1 (44→243) not taken.
44646 data = {varEntry, accessScope, accessScope->symbolTable.lookupCapture(varEntry->name)};
1542
1/2
✓ Branch 0 (45→46) taken 44646 times.
✗ Branch 1 (45→243) not taken.
44646 const QualType varType = varEntry->getQualType();
1543
5/8
✓ Branch 0 (46→47) taken 44646 times.
✗ Branch 1 (46→243) not taken.
✓ Branch 2 (47→48) taken 8 times.
✓ Branch 3 (47→52) taken 44638 times.
✓ Branch 4 (48→49) taken 8 times.
✗ Branch 5 (48→188) not taken.
✓ Branch 6 (49→50) taken 8 times.
✗ Branch 7 (49→188) not taken.
44646 HANDLE_UNRESOLVED_TYPE_ER(varType)
1544
1545
7/8
✓ Branch 0 (52→53) taken 44638 times.
✗ Branch 1 (52→189) not taken.
✓ Branch 2 (53→54) taken 56 times.
✓ Branch 3 (53→56) taken 44582 times.
✓ Branch 4 (54→55) taken 9 times.
✓ Branch 5 (54→56) taken 47 times.
✓ Branch 6 (57→58) taken 9 times.
✓ Branch 7 (57→86) taken 44629 times.
44638 if (varType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && varEntry->global) {
1546 // Check if overloaded function was referenced
1547
1/2
✓ Branch 0 (58→59) taken 9 times.
✗ Branch 1 (58→243) not taken.
9 const std::vector<Function *> *manifestations = varEntry->declNode->getFctManifestations(varEntry->name);
1548
2/2
✓ Branch 0 (60→61) taken 1 times.
✓ Branch 1 (60→71) taken 8 times.
9 if (manifestations->size() > 1)
1549
4/8
✓ Branch 0 (63→64) taken 1 times.
✗ Branch 1 (63→192) not taken.
✓ Branch 2 (64→65) taken 1 times.
✗ Branch 3 (64→190) not taken.
✓ Branch 4 (67→68) taken 1 times.
✗ Branch 5 (67→196) not taken.
✓ Branch 6 (68→69) taken 1 times.
✗ Branch 7 (68→196) not taken.
3 SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Overloaded functions / functions with optional params cannot be referenced")
1550
2/2
✓ Branch 0 (73→74) taken 1 times.
✓ Branch 1 (73→84) taken 7 times.
8 if (!manifestations->front()->templateTypes.empty())
1551
4/8
✓ Branch 0 (76→77) taken 1 times.
✗ Branch 1 (76→199) not taken.
✓ Branch 2 (77→78) taken 1 times.
✗ Branch 3 (77→197) not taken.
✓ Branch 4 (80→81) taken 1 times.
✗ Branch 5 (80→203) not taken.
✓ Branch 6 (81→82) taken 1 times.
✗ Branch 7 (81→203) not taken.
3 SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Generic functions cannot be referenced")
1552 // Set referenced function to used
1553 7 Function *referencedFunction = manifestations->front();
1554 7 referencedFunction->used = true;
1555 7 referencedFunction->entry->used = true;
1556 }
1557
1558
3/4
✓ Branch 0 (86→87) taken 44636 times.
✗ Branch 1 (86→243) not taken.
✓ Branch 2 (87→88) taken 2 times.
✓ Branch 3 (87→97) taken 44634 times.
44636 if (varType.is(TY_INVALID))
1559
5/10
✓ Branch 0 (88→89) taken 2 times.
✗ Branch 1 (88→208) not taken.
✓ Branch 2 (89→90) taken 2 times.
✗ Branch 3 (89→206) not taken.
✓ Branch 4 (90→91) taken 2 times.
✗ Branch 5 (90→204) not taken.
✓ Branch 6 (93→94) taken 2 times.
✗ Branch 7 (93→210) not taken.
✓ Branch 8 (94→95) taken 2 times.
✗ Branch 9 (94→210) not taken.
2 SOFT_ERROR_ER(node, USED_BEFORE_DECLARED, "Symbol '" + varEntry->name + "' was used before declared.")
1560
1561 // The base type should be an extended primitive
1562
1/2
✓ Branch 0 (97→98) taken 44634 times.
✗ Branch 1 (97→243) not taken.
44634 const QualType baseType = varType.getBase();
1563
6/10
✓ Branch 0 (98→99) taken 44634 times.
✗ Branch 1 (98→243) not taken.
✓ Branch 2 (99→100) taken 2 times.
✓ Branch 3 (99→103) taken 44632 times.
✓ Branch 4 (100→101) taken 2 times.
✗ Branch 5 (100→243) not taken.
✗ Branch 6 (101→102) not taken.
✓ Branch 7 (101→103) taken 2 times.
✗ Branch 8 (104→105) not taken.
✓ Branch 9 (104→116) taken 44634 times.
44634 if (!baseType.isExtendedPrimitive() && !baseType.is(TY_DYN))
1564 SOFT_ERROR_ER(node, INVALID_SYMBOL_ACCESS, "A symbol of type " + varType.getName(false) + " cannot be accessed here")
1565
1566 // Check if is an imported variable
1567
3/4
✓ Branch 0 (116→117) taken 44634 times.
✗ Branch 1 (116→243) not taken.
✓ Branch 2 (117→118) taken 174 times.
✓ Branch 3 (117→134) taken 44460 times.
44634 if (accessScope->isImportedBy(rootScope)) {
1568 // Check if the entry is public
1569
8/10
✓ Branch 0 (118→119) taken 54 times.
✓ Branch 1 (118→123) taken 120 times.
✓ Branch 2 (119→120) taken 54 times.
✗ Branch 3 (119→243) not taken.
✓ Branch 4 (120→121) taken 54 times.
✗ Branch 5 (120→243) not taken.
✓ Branch 6 (121→122) taken 1 times.
✓ Branch 7 (121→123) taken 53 times.
✓ Branch 8 (124→125) taken 1 times.
✓ Branch 9 (124→134) taken 173 times.
174 if (varEntry->scope->type != ScopeType::ENUM && !varEntry->getQualType().isPublic())
1570
5/10
✓ Branch 0 (125→126) taken 1 times.
✗ Branch 1 (125→225) not taken.
✓ Branch 2 (126→127) taken 1 times.
✗ Branch 3 (126→223) not taken.
✓ Branch 4 (127→128) taken 1 times.
✗ Branch 5 (127→221) not taken.
✓ Branch 6 (130→131) taken 1 times.
✗ Branch 7 (130→227) not taken.
✓ Branch 8 (131→132) taken 1 times.
✗ Branch 9 (131→227) not taken.
1 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access '" + varEntry->name + "' due to its private visibility")
1571 }
1572
1573 // Check if we have seen a 'this.' prefix, because the generator needs that
1574
6/8
✓ Branch 0 (134→135) taken 1 times.
✓ Branch 1 (134→139) taken 44632 times.
✓ Branch 2 (136→137) taken 1 times.
✗ Branch 3 (136→243) not taken.
✓ Branch 4 (137→138) taken 1 times.
✗ Branch 5 (137→139) not taken.
✓ Branch 6 (140→141) taken 1 times.
✓ Branch 7 (140→150) taken 44632 times.
44633 if (varEntry->scope->type == ScopeType::STRUCT && node->identifierFragments.front() != THIS_VARIABLE_NAME)
1575
5/10
✓ Branch 0 (141→142) taken 1 times.
✗ Branch 1 (141→232) not taken.
✓ Branch 2 (142→143) taken 1 times.
✗ Branch 3 (142→230) not taken.
✓ Branch 4 (143→144) taken 1 times.
✗ Branch 5 (143→228) not taken.
✓ Branch 6 (146→147) taken 1 times.
✗ Branch 7 (146→234) not taken.
✓ Branch 8 (147→148) taken 1 times.
✗ Branch 9 (147→234) not taken.
1 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE,
1576 "The symbol '" + node->fqIdentifier + "' could not be found. Missing 'this.' prefix?")
1577
1578 // Set symbol table entry to used
1579 44632 varEntry->used = true;
1580
1581 // Retrieve scope for the new scope path fragment
1582
3/4
✓ Branch 0 (150→151) taken 44632 times.
✗ Branch 1 (150→243) not taken.
✓ Branch 2 (151→152) taken 16065 times.
✓ Branch 3 (151→175) taken 28567 times.
44632 if (baseType.is(TY_STRUCT)) {
1583 // Set access scope to struct scope
1584
1/2
✓ Branch 0 (152→153) taken 16065 times.
✗ Branch 1 (152→243) not taken.
16065 const std::string &structName = baseType.getSubType();
1585
1/2
✓ Branch 0 (153→154) taken 16065 times.
✗ Branch 1 (153→243) not taken.
16065 const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(structName);
1586
1/2
✗ Branch 0 (154→155) not taken.
✓ Branch 1 (154→156) taken 16065 times.
16065 assert(nameRegistryEntry != nullptr);
1587
1588 // Change the access scope to the struct scope
1589 16065 data.accessScope = accessScope = nameRegistryEntry->targetScope;
1590
1591 // Check if the entry is public if it is imported
1592
1/2
✗ Branch 0 (156→157) not taken.
✓ Branch 1 (156→158) taken 16065 times.
16065 assert(nameRegistryEntry->targetEntry != nullptr);
1593
9/12
✓ Branch 0 (158→159) taken 16065 times.
✗ Branch 1 (158→243) not taken.
✓ Branch 2 (159→160) taken 16065 times.
✗ Branch 3 (159→243) not taken.
✓ Branch 4 (160→161) taken 821 times.
✓ Branch 5 (160→164) taken 15244 times.
✓ Branch 6 (161→162) taken 821 times.
✗ Branch 7 (161→243) not taken.
✓ Branch 8 (162→163) taken 1 times.
✓ Branch 9 (162→164) taken 820 times.
✓ Branch 10 (165→166) taken 1 times.
✓ Branch 11 (165→175) taken 16064 times.
16065 if (!nameRegistryEntry->targetEntry->getQualType().isPublic() && accessScope->parent->isImportedBy(rootScope))
1594
5/10
✓ Branch 0 (166→167) taken 1 times.
✗ Branch 1 (166→239) not taken.
✓ Branch 2 (167→168) taken 1 times.
✗ Branch 3 (167→237) not taken.
✓ Branch 4 (168→169) taken 1 times.
✗ Branch 5 (168→235) not taken.
✓ Branch 6 (171→172) taken 1 times.
✗ Branch 7 (171→241) not taken.
✓ Branch 8 (172→173) taken 1 times.
✗ Branch 9 (172→241) not taken.
1 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access struct '" + structName + "' due to its private visibility")
1595 }
1596
1597
2/4
✓ Branch 0 (175→176) taken 44631 times.
✗ Branch 1 (175→242) not taken.
✓ Branch 2 (176→177) taken 44631 times.
✗ Branch 3 (176→242) not taken.
44631 return ExprResult{node->setEvaluatedSymbolType(varType, manIdx), varEntry};
1598 }
1599
1600 14672 std::any TypeChecker::visitValue(ValueNode *node) {
1601 // Function call
1602
2/2
✓ Branch 0 (2→3) taken 13136 times.
✓ Branch 1 (2→4) taken 1536 times.
14672 if (node->fctCall)
1603 13136 return visit(node->fctCall);
1604
1605 // Array initialization
1606
2/2
✓ Branch 0 (4→5) taken 66 times.
✓ Branch 1 (4→6) taken 1470 times.
1536 if (node->arrayInitialization)
1607 66 return visit(node->arrayInitialization);
1608
1609 // Struct instantiation
1610
2/2
✓ Branch 0 (6→7) taken 283 times.
✓ Branch 1 (6→8) taken 1187 times.
1470 if (node->structInstantiation)
1611 283 return visit(node->structInstantiation);
1612
1613 // Lambda function
1614
2/2
✓ Branch 0 (8→9) taken 12 times.
✓ Branch 1 (8→10) taken 1175 times.
1187 if (node->lambdaFunc)
1615 12 return visit(node->lambdaFunc);
1616
1617 // Lambda procedure
1618
2/2
✓ Branch 0 (10→11) taken 28 times.
✓ Branch 1 (10→12) taken 1147 times.
1175 if (node->lambdaProc)
1619 28 return visit(node->lambdaProc);
1620
1621 // Lambda expression
1622
2/2
✓ Branch 0 (12→13) taken 1 times.
✓ Branch 1 (12→14) taken 1146 times.
1147 if (node->lambdaExpr)
1623 1 return visit(node->lambdaExpr);
1624
1625 // Typed nil
1626
1/2
✓ Branch 0 (14→15) taken 1146 times.
✗ Branch 1 (14→41) not taken.
1146 if (node->isNil) {
1627
2/4
✓ Branch 0 (15→16) taken 1146 times.
✗ Branch 1 (15→52) not taken.
✓ Branch 2 (16→17) taken 1146 times.
✗ Branch 3 (16→50) not taken.
1146 const auto nilType = std::any_cast<QualType>(visit(node->nilType));
1628
2/8
✓ Branch 0 (18→19) taken 1146 times.
✗ Branch 1 (18→62) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 1146 times.
✗ Branch 4 (20→21) not taken.
✗ Branch 5 (20→53) not taken.
✗ Branch 6 (21→22) not taken.
✗ Branch 7 (21→53) not taken.
1146 HANDLE_UNRESOLVED_TYPE_ER(nilType)
1629
2/4
✓ Branch 0 (24→25) taken 1146 times.
✗ Branch 1 (24→62) not taken.
✗ Branch 2 (25→26) not taken.
✓ Branch 3 (25→36) taken 1146 times.
1146 if (nilType.is(TY_DYN))
1630 SOFT_ERROR_ER(node->nilType, UNEXPECTED_DYN_TYPE, "Nil must have an explicit type")
1631
2/4
✓ Branch 0 (36→37) taken 1146 times.
✗ Branch 1 (36→61) not taken.
✓ Branch 2 (37→38) taken 1146 times.
✗ Branch 3 (37→61) not taken.
1146 return ExprResult{node->setEvaluatedSymbolType(nilType, manIdx)};
1632 }
1633
1634 throw CompilerError(UNHANDLED_BRANCH, "Value fall-through"); // GCOV_EXCL_LINE
1635 }
1636
1637 17163 std::any TypeChecker::visitConstant(ConstantNode *node) {
1638 SuperType superType;
1639
7/9
✓ Branch 0 (2→3) taken 204 times.
✓ Branch 1 (2→4) taken 3006 times.
✓ Branch 2 (2→5) taken 200 times.
✓ Branch 3 (2→6) taken 6558 times.
✗ Branch 4 (2→7) not taken.
✓ Branch 5 (2→8) taken 2085 times.
✓ Branch 6 (2→9) taken 2954 times.
✓ Branch 7 (2→10) taken 2156 times.
✗ Branch 8 (2→11) not taken.
17163 switch (node->type) {
1640 204 case ConstantNode::PrimitiveValueType::TYPE_DOUBLE:
1641 204 superType = TY_DOUBLE;
1642 204 break;
1643 3006 case ConstantNode::PrimitiveValueType::TYPE_INT:
1644 3006 superType = TY_INT;
1645 3006 break;
1646 200 case ConstantNode::PrimitiveValueType::TYPE_SHORT:
1647 200 superType = TY_SHORT;
1648 200 break;
1649 6558 case ConstantNode::PrimitiveValueType::TYPE_LONG:
1650 6558 superType = TY_LONG;
1651 6558 break;
1652 case ConstantNode::PrimitiveValueType::TYPE_BYTE:
1653 superType = TY_BYTE;
1654 break;
1655 2085 case ConstantNode::PrimitiveValueType::TYPE_CHAR:
1656 2085 superType = TY_CHAR;
1657 2085 break;
1658 2954 case ConstantNode::PrimitiveValueType::TYPE_STRING:
1659 2954 superType = TY_STRING;
1660 2954 break;
1661 2156 case ConstantNode::PrimitiveValueType::TYPE_BOOL:
1662 2156 superType = TY_BOOL;
1663 2156 break;
1664 default: // GCOV_EXCL_LINE
1665 throw CompilerError(UNHANDLED_BRANCH, "Constant fall-through"); // GCOV_EXCL_LINE
1666 }
1667
1668 // Create symbol type
1669
1/2
✓ Branch 0 (19→20) taken 17163 times.
✗ Branch 1 (19→37) not taken.
17163 QualType symbolType(superType);
1670
1/2
✓ Branch 0 (20→21) taken 17163 times.
✗ Branch 1 (20→37) not taken.
17163 symbolType.setQualifiers(TypeQualifiers::of(superType));
1671
1672
2/4
✓ Branch 0 (22→23) taken 17163 times.
✗ Branch 1 (22→36) not taken.
✓ Branch 2 (23→24) taken 17163 times.
✗ Branch 3 (23→36) not taken.
17163 return ExprResult{node->setEvaluatedSymbolType(symbolType, manIdx)};
1673 }
1674
1675 13136 std::any TypeChecker::visitFctCall(FctCallNode *node) {
1676
1/2
✓ Branch 0 (2→3) taken 13136 times.
✗ Branch 1 (2→547) not taken.
13136 FctCallNode::FctCallData &data = node->data.at(manIdx);
1677
1678 // Retrieve arg types
1679 13136 data.argResults.clear();
1680
2/2
✓ Branch 0 (4→5) taken 10180 times.
✓ Branch 1 (4→27) taken 2956 times.
13136 if (node->hasArgs) {
1681
1/2
✓ Branch 0 (6→7) taken 10180 times.
✗ Branch 1 (6→547) not taken.
10180 data.argResults.reserve(node->argLst->args.size());
1682
2/2
✓ Branch 0 (25→9) taken 15657 times.
✓ Branch 1 (25→26) taken 10180 times.
25837 for (AssignExprNode *arg : node->argLst->args) {
1683 // Visit argument
1684
2/4
✓ Branch 0 (10→11) taken 15657 times.
✗ Branch 1 (10→412) not taken.
✓ Branch 2 (11→12) taken 15657 times.
✗ Branch 3 (11→410) not taken.
15657 const auto argResult = std::any_cast<ExprResult>(visit(arg));
1685
2/8
✓ Branch 0 (13→14) taken 15657 times.
✗ Branch 1 (13→414) not taken.
✗ Branch 2 (14→15) not taken.
✓ Branch 3 (14→19) taken 15657 times.
✗ Branch 4 (15→16) not taken.
✗ Branch 5 (15→413) not taken.
✗ Branch 6 (16→17) not taken.
✗ Branch 7 (16→413) not taken.
15657 HANDLE_UNRESOLVED_TYPE_ER(argResult.type)
1686
2/4
✓ Branch 0 (19→20) taken 15657 times.
✗ Branch 1 (19→414) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→22) taken 15657 times.
15657 assert(!argResult.type.hasAnyGenericParts());
1687 // Save arg type to arg types list
1688
1/2
✓ Branch 0 (22→23) taken 15657 times.
✗ Branch 1 (22→414) not taken.
15657 data.argResults.push_back(argResult);
1689 }
1690 }
1691
1692 // Retrieve entry of the first fragment
1693 13136 const std::string &firstFrag = node->functionNameFragments.front();
1694
1/2
✓ Branch 0 (28→29) taken 13136 times.
✗ Branch 1 (28→547) not taken.
13136 SymbolTableEntry *firstFragEntry = currentScope->lookup(firstFrag);
1695
2/2
✓ Branch 0 (31→32) taken 8193 times.
✓ Branch 1 (31→69) taken 4943 times.
13136 if (firstFragEntry) {
1696 // Check if we have seen a 'this.' prefix, because the generator needs that
1697
6/8
✓ Branch 0 (32→33) taken 1 times.
✓ Branch 1 (32→36) taken 8192 times.
✓ Branch 2 (33→34) taken 1 times.
✗ Branch 3 (33→426) not taken.
✓ Branch 4 (34→35) taken 1 times.
✗ Branch 5 (34→36) not taken.
✓ Branch 6 (37→38) taken 1 times.
✓ Branch 7 (37→47) taken 8192 times.
8193 if (firstFragEntry->scope->type == ScopeType::STRUCT && firstFrag != THIS_VARIABLE_NAME)
1698
5/10
✓ Branch 0 (38→39) taken 1 times.
✗ Branch 1 (38→420) not taken.
✓ Branch 2 (39→40) taken 1 times.
✗ Branch 3 (39→418) not taken.
✓ Branch 4 (40→41) taken 1 times.
✗ Branch 5 (40→416) not taken.
✓ Branch 6 (43→44) taken 1 times.
✗ Branch 7 (43→422) not taken.
✓ Branch 8 (44→45) taken 1 times.
✗ Branch 9 (44→422) not taken.
1 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE,
1699 "The symbol '" + firstFrag + "' could not be found. Missing 'this.' prefix?")
1700
1701 8192 firstFragEntry->used = true;
1702 // Decide of which type the function call is
1703
2/4
✓ Branch 0 (47→48) taken 8192 times.
✗ Branch 1 (47→426) not taken.
✓ Branch 2 (48→49) taken 8192 times.
✗ Branch 3 (48→426) not taken.
8192 const QualType &baseType = firstFragEntry->getQualType().getBase();
1704
5/8
✓ Branch 0 (49→50) taken 8192 times.
✗ Branch 1 (49→426) not taken.
✓ Branch 2 (50→51) taken 4 times.
✓ Branch 3 (50→55) taken 8188 times.
✓ Branch 4 (51→52) taken 4 times.
✗ Branch 5 (51→423) not taken.
✓ Branch 6 (52→53) taken 4 times.
✗ Branch 7 (52→423) not taken.
8192 HANDLE_UNRESOLVED_TYPE_ER(baseType)
1705
3/4
✓ Branch 0 (55→56) taken 8188 times.
✗ Branch 1 (55→424) not taken.
✓ Branch 2 (56→57) taken 6217 times.
✓ Branch 3 (56→60) taken 1971 times.
8188 if (baseType.isOneOf({TY_STRUCT, TY_INTERFACE})) {
1706
2/2
✓ Branch 0 (57→58) taken 926 times.
✓ Branch 1 (57→59) taken 5291 times.
6217 if (firstFragEntry->scope->type == ScopeType::GLOBAL)
1707 926 data.callType = FctCallNode::FctCallType::TYPE_CTOR;
1708 else
1709 5291 data.callType = FctCallNode::FctCallType::TYPE_METHOD;
1710
7/8
✓ Branch 0 (60→61) taken 1971 times.
✗ Branch 1 (60→425) not taken.
✓ Branch 2 (61→62) taken 1903 times.
✓ Branch 3 (61→64) taken 68 times.
✓ Branch 4 (62→63) taken 48 times.
✓ Branch 5 (62→64) taken 1855 times.
✓ Branch 6 (65→66) taken 48 times.
✓ Branch 7 (65→67) taken 1923 times.
1971 } else if (baseType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && firstFragEntry->scope->type != ScopeType::GLOBAL) {
1711 48 data.callType = FctCallNode::FctCallType::TYPE_FCT_PTR;
1712 }
1713 }
1714
1715 // Get struct name. Retrieve it from alias if required
1716
1/2
✓ Branch 0 (69→70) taken 13131 times.
✗ Branch 1 (69→547) not taken.
13131 std::string fqFunctionName = node->fqFunctionName;
1717
1/2
✓ Branch 0 (70→71) taken 13131 times.
✗ Branch 1 (70→545) not taken.
13131 SymbolTableEntry *aliasEntry = rootScope->lookupStrict(fqFunctionName);
1718 13131 SymbolTableEntry *aliasedTypeContainerEntry = nullptr;
1719
6/8
✓ Branch 0 (73→74) taken 2783 times.
✓ Branch 1 (73→78) taken 10348 times.
✓ Branch 2 (74→75) taken 2783 times.
✗ Branch 3 (74→545) not taken.
✓ Branch 4 (75→76) taken 2783 times.
✗ Branch 5 (75→545) not taken.
✓ Branch 6 (76→77) taken 1 times.
✓ Branch 7 (76→78) taken 2782 times.
13131 const bool isAliasType = aliasEntry && aliasEntry->getQualType().is(TY_ALIAS);
1720
2/2
✓ Branch 0 (79→80) taken 1 times.
✓ Branch 1 (79→90) taken 13130 times.
13131 if (isAliasType) {
1721
1/2
✓ Branch 0 (80→81) taken 1 times.
✗ Branch 1 (80→429) not taken.
2 aliasedTypeContainerEntry = rootScope->lookupStrict(aliasEntry->name + ALIAS_CONTAINER_SUFFIX);
1722
1/2
✗ Branch 0 (85→86) not taken.
✓ Branch 1 (85→87) taken 1 times.
1 assert(aliasedTypeContainerEntry != nullptr);
1723 // Set alias entry used
1724 1 aliasEntry->used = true;
1725
3/6
✓ Branch 0 (87→88) taken 1 times.
✗ Branch 1 (87→545) not taken.
✓ Branch 2 (88→89) taken 1 times.
✗ Branch 3 (88→545) not taken.
✓ Branch 4 (89→90) taken 1 times.
✗ Branch 5 (89→545) not taken.
1 fqFunctionName = aliasedTypeContainerEntry->getQualType().getSubType();
1726 }
1727
1728 // Get the concrete template types
1729 13131 QualTypeList concreteTemplateTypes;
1730
2/2
✓ Branch 0 (90→91) taken 1 times.
✓ Branch 1 (90→110) taken 13130 times.
13131 if (isAliasType) {
1731 // Retrieve concrete template types from type alias
1732
3/6
✓ Branch 0 (91→92) taken 1 times.
✗ Branch 1 (91→543) not taken.
✓ Branch 2 (92→93) taken 1 times.
✗ Branch 3 (92→543) not taken.
✓ Branch 4 (93→94) taken 1 times.
✗ Branch 5 (93→543) not taken.
1 concreteTemplateTypes = aliasedTypeContainerEntry->getQualType().getTemplateTypes();
1733 // Check if the aliased type specified template types and the struct instantiation does
1734
3/6
✓ Branch 0 (95→96) taken 1 times.
✗ Branch 1 (95→98) not taken.
✗ Branch 2 (96→97) not taken.
✓ Branch 3 (96→98) taken 1 times.
✗ Branch 4 (99→100) not taken.
✓ Branch 5 (99→110) taken 1 times.
1 if (!concreteTemplateTypes.empty() && node->hasTemplateTypes)
1735 SOFT_ERROR_ER(node->templateTypeLst, ALIAS_WITH_TEMPLATE_LIST, "The aliased type already has a template list")
1736 }
1737
1738 // Get concrete template types
1739
2/2
✓ Branch 0 (110→111) taken 517 times.
✓ Branch 1 (110→146) taken 12614 times.
13131 if (node->hasTemplateTypes) {
1740
2/2
✓ Branch 0 (144→113) taken 601 times.
✓ Branch 1 (144→145) taken 517 times.
1118 for (DataTypeNode *templateTypeNode : node->templateTypeLst->dataTypes) {
1741
2/4
✓ Branch 0 (114→115) taken 601 times.
✗ Branch 1 (114→439) not taken.
✓ Branch 2 (115→116) taken 601 times.
✗ Branch 3 (115→437) not taken.
601 auto templateType = std::any_cast<QualType>(visit(templateTypeNode));
1742
2/4
✓ Branch 0 (117→118) taken 601 times.
✗ Branch 1 (117→440) not taken.
✗ Branch 2 (118→119) not taken.
✓ Branch 3 (118→120) taken 601 times.
601 assert(!templateType.isOneOf({TY_DYN, TY_INVALID}));
1743
1744 // Abort if the type is unresolved
1745
2/4
✓ Branch 0 (120→121) taken 601 times.
✗ Branch 1 (120→450) not taken.
✗ Branch 2 (121→122) not taken.
✓ Branch 3 (121→128) taken 601 times.
601 if (templateType.is(TY_UNRESOLVED))
1746 HANDLE_UNRESOLVED_TYPE_ER(templateType)
1747
1748 // Check if the given type is generic
1749
2/4
✓ Branch 0 (128→129) taken 601 times.
✗ Branch 1 (128→450) not taken.
✗ Branch 2 (129→130) not taken.
✓ Branch 3 (129→140) taken 601 times.
601 if (templateType.is(TY_GENERIC))
1750 SOFT_ERROR_ER(templateTypeNode, EXPECTED_NON_GENERIC_TYPE, "You must specify a concrete type here")
1751
1752
1/2
✓ Branch 0 (140→141) taken 601 times.
✗ Branch 1 (140→450) not taken.
601 concreteTemplateTypes.push_back(templateType);
1753 }
1754 }
1755
1756 // Check if this is a method call or a normal function call
1757
2/2
✓ Branch 0 (147→148) taken 5291 times.
✓ Branch 1 (147→162) taken 7840 times.
13131 if (data.isMethodCall()) {
1758 // This is a method call
1759
1/2
✓ Branch 0 (148→149) taken 5291 times.
✗ Branch 1 (148→543) not taken.
5291 data.thisType = firstFragEntry->getQualType();
1760
2/4
✓ Branch 0 (149→150) taken 5291 times.
✗ Branch 1 (149→452) not taken.
✓ Branch 2 (150→151) taken 5291 times.
✗ Branch 3 (150→452) not taken.
5291 Scope *structBodyScope = data.thisType.getBase().getBodyScope();
1761
1/2
✗ Branch 0 (151→152) not taken.
✓ Branch 1 (151→153) taken 5291 times.
5291 assert(structBodyScope != nullptr);
1762
3/4
✓ Branch 0 (153→154) taken 5291 times.
✗ Branch 1 (153→543) not taken.
✓ Branch 2 (154→155) taken 2 times.
✓ Branch 3 (154→160) taken 5289 times.
5291 if (bool success = visitMethodCall(node, structBodyScope, concreteTemplateTypes); !success) // Check if soft errors occurred
1763
3/6
✓ Branch 0 (155→156) taken 2 times.
✗ Branch 1 (155→453) not taken.
✓ Branch 2 (156→157) taken 2 times.
✗ Branch 3 (156→453) not taken.
✓ Branch 4 (157→158) taken 2 times.
✗ Branch 5 (157→453) not taken.
2 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)};
1764
1/2
✗ Branch 0 (160→161) not taken.
✓ Branch 1 (160→198) taken 5289 times.
5289 assert(data.calleeParentScope != nullptr);
1765
2/2
✓ Branch 0 (163→164) taken 48 times.
✓ Branch 1 (163→177) taken 7792 times.
7840 } else if (data.isFctPtrCall()) {
1766 // This is a function pointer call
1767
2/4
✓ Branch 0 (164→165) taken 48 times.
✗ Branch 1 (164→458) not taken.
✓ Branch 2 (165→166) taken 48 times.
✗ Branch 3 (165→458) not taken.
48 const QualType &functionType = firstFragEntry->getQualType().getBase();
1768
2/4
✓ Branch 0 (166→167) taken 48 times.
✗ Branch 1 (166→455) not taken.
✗ Branch 2 (167→168) not taken.
✓ Branch 3 (167→169) taken 48 times.
48 assert(functionType.isOneOf({TY_FUNCTION, TY_PROCEDURE}));
1769
1/2
✓ Branch 0 (169→170) taken 48 times.
✗ Branch 1 (169→458) not taken.
48 bool success = visitFctPtrCall(node, functionType);
1770
1/2
✗ Branch 0 (170→171) not taken.
✓ Branch 1 (170→176) taken 48 times.
48 if (!success) // Check if soft errors occurred
1771 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)};
1772 } else {
1773 // This is an ordinary function call
1774
3/4
✓ Branch 0 (178→179) taken 931 times.
✓ Branch 1 (178→182) taken 6861 times.
✗ Branch 2 (180→181) not taken.
✓ Branch 3 (180→182) taken 931 times.
7792 assert(data.isOrdinaryCall() || data.isCtorCall());
1775
3/4
✓ Branch 0 (182→183) taken 7792 times.
✗ Branch 1 (182→461) not taken.
✓ Branch 2 (183→184) taken 7790 times.
✓ Branch 3 (183→459) taken 2 times.
7794 bool success = visitOrdinaryFctCall(node, concreteTemplateTypes, fqFunctionName);
1776
2/2
✓ Branch 0 (185→186) taken 4 times.
✓ Branch 1 (185→191) taken 7786 times.
7790 if (!success) // Check if soft errors occurred
1777
3/6
✓ Branch 0 (186→187) taken 4 times.
✗ Branch 1 (186→462) not taken.
✓ Branch 2 (187→188) taken 4 times.
✗ Branch 3 (187→462) not taken.
✓ Branch 4 (188→189) taken 4 times.
✗ Branch 5 (188→462) not taken.
4 return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)};
1778
1/2
✗ Branch 0 (191→192) not taken.
✓ Branch 1 (191→193) taken 7786 times.
7786 assert(data.calleeParentScope != nullptr);
1779
1780 // If the call is no ordinary call, it must be a constructor, which takes a struct as this type.
1781
4/6
✓ Branch 0 (194→195) taken 2011 times.
✓ Branch 1 (194→198) taken 5775 times.
✓ Branch 2 (195→196) taken 2011 times.
✗ Branch 3 (195→543) not taken.
✗ Branch 4 (196→197) not taken.
✓ Branch 5 (196→198) taken 2011 times.
7786 assert(data.isOrdinaryCall() || data.thisType.is(TY_STRUCT));
1782 }
1783
1784
2/2
✓ Branch 0 (199→200) taken 13075 times.
✓ Branch 1 (199→269) taken 48 times.
13123 if (!data.isFctPtrCall()) {
1785 // Check if we were able to find a function
1786
2/2
✓ Branch 0 (200→201) taken 12 times.
✓ Branch 1 (200→236) taken 13063 times.
13075 if (!data.callee) {
1787 // Build error message
1788
6/10
✓ Branch 0 (202→203) taken 2 times.
✓ Branch 1 (202→206) taken 10 times.
✓ Branch 2 (205→208) taken 2 times.
✗ Branch 3 (205→464) not taken.
✓ Branch 4 (207→208) taken 10 times.
✗ Branch 5 (207→464) not taken.
✓ Branch 6 (208→209) taken 2 times.
✓ Branch 7 (208→211) taken 10 times.
✗ Branch 8 (464→465) not taken.
✗ Branch 9 (464→467) not taken.
14 const std::string functionName = data.isCtorCall() ? CTOR_FUNCTION_NAME : node->functionNameFragments.back();
1789 12 ParamList errArgTypes;
1790
1/2
✓ Branch 0 (212→213) taken 12 times.
✗ Branch 1 (212→484) not taken.
12 errArgTypes.reserve(data.argResults.size());
1791
2/2
✓ Branch 0 (219→215) taken 7 times.
✓ Branch 1 (219→220) taken 12 times.
19 for (const auto &[type, _] : data.argResults)
1792
1/2
✓ Branch 0 (216→217) taken 7 times.
✗ Branch 1 (216→469) not taken.
7 errArgTypes.push_back({type, false});
1793
2/4
✓ Branch 0 (221→222) taken 12 times.
✗ Branch 1 (221→471) not taken.
✓ Branch 2 (222→223) taken 12 times.
✗ Branch 3 (222→471) not taken.
12 const std::string signature = Function::getSignature(functionName, data.thisType, QualType(TY_DYN), errArgTypes, {}, false);
1794 // Throw error
1795
5/10
✓ Branch 0 (224→225) taken 12 times.
✗ Branch 1 (224→479) not taken.
✓ Branch 2 (225→226) taken 12 times.
✗ Branch 3 (225→477) not taken.
✓ Branch 4 (226→227) taken 12 times.
✗ Branch 5 (226→475) not taken.
✓ Branch 6 (229→230) taken 12 times.
✗ Branch 7 (229→481) not taken.
✓ Branch 8 (230→231) taken 12 times.
✗ Branch 9 (230→481) not taken.
12 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_FUNCTION, "Function/procedure '" + signature + "' could not be found")
1796 12 }
1797
1798 // Check if we need to request a re-visit, because the function body was not type-checked yet
1799 13063 requestRevisitIfRequired(data.callee);
1800
1801 // Get function entry from function object
1802 13063 SymbolTableEntry *functionEntry = data.callee->entry;
1803
1804 // Check if the called function has sufficient visibility
1805
1/2
✓ Branch 0 (237→238) taken 13063 times.
✗ Branch 1 (237→543) not taken.
13063 data.isImported = data.calleeParentScope->isImportedBy(rootScope);
1806
8/10
✓ Branch 0 (238→239) taken 3667 times.
✓ Branch 1 (238→243) taken 9396 times.
✓ Branch 2 (239→240) taken 3667 times.
✗ Branch 3 (239→543) not taken.
✓ Branch 4 (240→241) taken 3667 times.
✗ Branch 5 (240→543) not taken.
✓ Branch 6 (241→242) taken 1 times.
✓ Branch 7 (241→243) taken 3666 times.
✓ Branch 8 (244→245) taken 1 times.
✓ Branch 9 (244→269) taken 13062 times.
13063 if (data.isImported && !functionEntry->getQualType().isPublic()) {
1807
1/2
✓ Branch 0 (245→246) taken 1 times.
✗ Branch 1 (245→505) not taken.
1 const QualType functionEntryType = functionEntry->getQualType();
1808
1/2
✓ Branch 0 (246→247) taken 1 times.
✗ Branch 1 (246→505) not taken.
1 const std::string signature = data.callee->getSignature();
1809
2/4
✓ Branch 0 (247→248) taken 1 times.
✗ Branch 1 (247→503) not taken.
✓ Branch 2 (248→249) taken 1 times.
✗ Branch 3 (248→258) not taken.
1 if (functionEntryType.is(TY_FUNCTION))
1810
5/10
✓ Branch 0 (249→250) taken 1 times.
✗ Branch 1 (249→493) not taken.
✓ Branch 2 (250→251) taken 1 times.
✗ Branch 3 (250→491) not taken.
✓ Branch 4 (251→252) taken 1 times.
✗ Branch 5 (251→489) not taken.
✓ Branch 6 (254→255) taken 1 times.
✗ Branch 7 (254→495) not taken.
✓ Branch 8 (255→256) taken 1 times.
✗ Branch 9 (255→495) not taken.
1 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Function '" + signature + "' has insufficient visibility")
1811 else
1812 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Procedure '" + signature + "' has insufficient visibility")
1813 1 }
1814 }
1815
1816 // Generate arg infos
1817
2/2
✓ Branch 0 (269→270) taken 10168 times.
✓ Branch 1 (269→309) taken 2942 times.
13110 if (node->hasArgs) {
1818 10168 QualTypeList paramTypes;
1819
2/2
✓ Branch 0 (271→272) taken 25 times.
✓ Branch 1 (271→278) taken 10143 times.
10168 if (data.isFctPtrCall()) {
1820
2/4
✓ Branch 0 (272→273) taken 25 times.
✗ Branch 1 (272→507) not taken.
✓ Branch 2 (273→274) taken 25 times.
✗ Branch 3 (273→507) not taken.
25 const QualType &functionType = firstFragEntry->getQualType().getBase();
1821
1/2
✓ Branch 0 (274→275) taken 25 times.
✗ Branch 1 (274→506) not taken.
25 paramTypes = functionType.getFunctionParamTypes();
1822 } else {
1823
1/2
✗ Branch 0 (278→279) not taken.
✓ Branch 1 (278→280) taken 10143 times.
10143 assert(data.callee != nullptr);
1824
1/2
✓ Branch 0 (280→281) taken 10143 times.
✗ Branch 1 (280→508) not taken.
10143 paramTypes = data.callee->getParamTypes();
1825 }
1826
1827 10168 node->argLst->argInfos.clear();
1828
2/2
✓ Branch 0 (302→286) taken 15642 times.
✓ Branch 1 (302→303) taken 10168 times.
25810 for (size_t argIdx = 0; argIdx < data.argResults.size(); argIdx++) {
1829
1/2
✓ Branch 0 (286→287) taken 15642 times.
✗ Branch 1 (286→510) not taken.
15642 const QualType &expectedType = paramTypes.at(argIdx);
1830
1/2
✓ Branch 0 (287→288) taken 15642 times.
✗ Branch 1 (287→510) not taken.
15642 const auto &[actualType, entry] = data.argResults.at(argIdx);
1831
1832 15642 Function *copyCtor = nullptr;
1833
10/14
✓ Branch 0 (288→289) taken 15642 times.
✗ Branch 1 (288→510) not taken.
✓ Branch 2 (289→290) taken 40 times.
✓ Branch 3 (289→295) taken 15602 times.
✓ Branch 4 (290→291) taken 40 times.
✗ Branch 5 (290→510) not taken.
✓ Branch 6 (291→292) taken 40 times.
✗ Branch 7 (291→295) not taken.
✓ Branch 8 (292→293) taken 40 times.
✗ Branch 9 (292→510) not taken.
✓ Branch 10 (293→294) taken 22 times.
✓ Branch 11 (293→295) taken 18 times.
✓ Branch 12 (296→297) taken 22 times.
✓ Branch 13 (296→299) taken 15620 times.
15642 if (expectedType.is(TY_STRUCT) && actualType.is(TY_STRUCT) && !actualType.isTriviallyCopyable(node)) {
1834
1/2
✓ Branch 0 (297→298) taken 22 times.
✗ Branch 1 (297→510) not taken.
22 copyCtor = matchCopyCtor(actualType, node);
1835
1/2
✓ Branch 0 (298→299) taken 22 times.
✗ Branch 1 (298→510) not taken.
22 currentScope->symbolTable.insertAnonymous(actualType, node, argIdx + 1); // +1 because 0 is reserved for return value
1836 }
1837
1838
1/2
✓ Branch 0 (299→300) taken 15642 times.
✗ Branch 1 (299→509) not taken.
15642 node->argLst->argInfos.push_back(ArgLstNode::ArgInfo{copyCtor});
1839 }
1840
1/2
✗ Branch 0 (305→306) not taken.
✓ Branch 1 (305→307) taken 10168 times.
10168 assert(node->argLst->argInfos.size() == node->argLst->args.size());
1841 10168 }
1842
1843 // Retrieve return type
1844
6/10
✓ Branch 0 (310→311) taken 48 times.
✓ Branch 1 (310→315) taken 13062 times.
✓ Branch 2 (311→312) taken 48 times.
✗ Branch 3 (311→513) not taken.
✓ Branch 4 (312→313) taken 48 times.
✗ Branch 5 (312→513) not taken.
✓ Branch 6 (313→314) taken 48 times.
✗ Branch 7 (313→513) not taken.
✓ Branch 8 (315→316) taken 13062 times.
✗ Branch 9 (315→513) not taken.
26172 const bool isFct = data.isFctPtrCall() ? firstFragEntry->getQualType().getBase().is(TY_FUNCTION) : data.callee->isFunction();
1845 13110 QualType returnType;
1846
2/2
✓ Branch 0 (320→321) taken 48 times.
✓ Branch 1 (320→328) taken 13062 times.
13110 if (data.isFctPtrCall()) {
1847
6/10
✓ Branch 0 (321→322) taken 20 times.
✓ Branch 1 (321→326) taken 28 times.
✓ Branch 2 (322→323) taken 20 times.
✗ Branch 3 (322→514) not taken.
✓ Branch 4 (323→324) taken 20 times.
✗ Branch 5 (323→514) not taken.
✓ Branch 6 (324→325) taken 20 times.
✗ Branch 7 (324→514) not taken.
✓ Branch 8 (326→327) taken 28 times.
✗ Branch 9 (326→514) not taken.
48 returnType = isFct ? firstFragEntry->getQualType().getBase().getFunctionReturnType() : QualType(TY_BOOL);
1848
2/2
✓ Branch 0 (329→330) taken 2009 times.
✓ Branch 1 (329→331) taken 11053 times.
13062 } else if (data.isCtorCall()) {
1849 // Set return type to 'this' type
1850 2009 returnType = data.thisType;
1851
3/4
✓ Branch 0 (331→332) taken 11053 times.
✗ Branch 1 (331→543) not taken.
✓ Branch 2 (334→335) taken 2592 times.
✓ Branch 3 (334→337) taken 8461 times.
22106 } else if (data.callee->isProcedure()) {
1852 // Procedures always have the return type 'dyn'
1853
1/2
✓ Branch 0 (335→336) taken 2592 times.
✗ Branch 1 (335→516) not taken.
2592 returnType = QualType(TY_DYN);
1854 } else {
1855 8461 returnType = data.callee->returnType;
1856 }
1857
1858 // Initialize return type if required
1859 13110 SymbolTableEntry *anonymousSymbol = nullptr;
1860
3/4
✓ Branch 0 (338→339) taken 13110 times.
✗ Branch 1 (338→543) not taken.
✓ Branch 2 (339→340) taken 3143 times.
✓ Branch 3 (339→370) taken 9967 times.
13110 if (returnType.isBase(TY_STRUCT)) {
1861
1/2
✓ Branch 0 (340→341) taken 3143 times.
✗ Branch 1 (340→531) not taken.
3143 QualType returnBaseType = returnType.getBase();
1862
1/2
✓ Branch 0 (341→342) taken 3143 times.
✗ Branch 1 (341→531) not taken.
3143 const std::string &structName = returnBaseType.getSubType();
1863
1/2
✓ Branch 0 (342→343) taken 3143 times.
✗ Branch 1 (342→531) not taken.
3143 Scope *matchScope = returnBaseType.getBodyScope()->parent;
1864
1/2
✗ Branch 0 (343→344) not taken.
✓ Branch 1 (343→345) taken 3143 times.
3143 assert(matchScope != nullptr);
1865
2/4
✓ Branch 0 (345→346) taken 3143 times.
✗ Branch 1 (345→531) not taken.
✓ Branch 2 (346→347) taken 3143 times.
✗ Branch 3 (346→531) not taken.
3143 Struct *spiceStruct = StructManager::match(matchScope, structName, returnBaseType.getTemplateTypes(), node);
1866
1/2
✗ Branch 0 (347→348) not taken.
✓ Branch 1 (347→360) taken 3143 times.
3143 if (!spiceStruct) {
1867 const std::string signature = Struct::getSignature(structName, returnBaseType.getTemplateTypes());
1868 SOFT_ERROR_ER(node, UNKNOWN_DATATYPE,
1869 "Could not find struct candidate for struct '" + signature + "'. Do the template types match?")
1870 }
1871
2/4
✓ Branch 0 (360→361) taken 3143 times.
✗ Branch 1 (360→527) not taken.
✓ Branch 2 (361→362) taken 3143 times.
✗ Branch 3 (361→527) not taken.
3143 returnType = returnType.getWithBodyScope(spiceStruct->scope).replaceBaseType(returnBaseType);
1872
3/6
✓ Branch 0 (362→363) taken 3143 times.
✗ Branch 1 (362→529) not taken.
✓ Branch 2 (363→364) taken 3143 times.
✗ Branch 3 (363→529) not taken.
✓ Branch 4 (364→365) taken 3143 times.
✗ Branch 5 (364→529) not taken.
3143 returnType = mapImportedScopeTypeToLocalType(returnType.getBase().getBodyScope(), returnType);
1873
1874 // Add anonymous symbol to keep track of de-allocation
1875
3/4
✓ Branch 0 (365→366) taken 3143 times.
✗ Branch 1 (365→531) not taken.
✓ Branch 2 (366→367) taken 2730 times.
✓ Branch 3 (366→369) taken 413 times.
3143 if (returnType.is(TY_STRUCT))
1876
1/2
✓ Branch 0 (367→368) taken 2730 times.
✗ Branch 1 (367→531) not taken.
2730 anonymousSymbol = currentScope->symbolTable.insertAnonymous(returnType, node);
1877 }
1878
1879 // Remove public qualifier to not have public local variables
1880 13110 returnType.getQualifiers().isPublic = false;
1881
1882 // Check if the return value gets discarded
1883
7/8
✓ Branch 0 (371→372) taken 8481 times.
✓ Branch 1 (371→375) taken 4629 times.
✓ Branch 2 (372→373) taken 8481 times.
✗ Branch 3 (372→543) not taken.
✓ Branch 4 (373→374) taken 141 times.
✓ Branch 5 (373→375) taken 8340 times.
✓ Branch 6 (376→377) taken 141 times.
✓ Branch 7 (376→402) taken 12969 times.
13110 if (isFct && !node->hasReturnValueReceiver()) {
1884 // Check if we want to ignore the discarded return value
1885 141 bool ignoreUnusedReturnValue = false;
1886
2/2
✓ Branch 0 (378→379) taken 138 times.
✓ Branch 1 (378→399) taken 3 times.
141 if (!data.isFctPtrCall()) {
1887
1/2
✗ Branch 0 (379→380) not taken.
✓ Branch 1 (379→381) taken 138 times.
138 assert(data.callee != nullptr);
1888
1/2
✓ Branch 0 (381→382) taken 138 times.
✗ Branch 1 (381→383) not taken.
138 auto fctDef = dynamic_cast<const FctDefNode *>(data.callee->declNode);
1889
12/18
✓ Branch 0 (384→385) taken 92 times.
✓ Branch 1 (384→392) taken 46 times.
✓ Branch 2 (385→386) taken 24 times.
✓ Branch 3 (385→392) taken 68 times.
✓ Branch 4 (388→389) taken 24 times.
✗ Branch 5 (388→532) not taken.
✓ Branch 6 (389→390) taken 24 times.
✗ Branch 7 (389→532) not taken.
✓ Branch 8 (390→391) taken 23 times.
✓ Branch 9 (390→392) taken 1 times.
✓ Branch 10 (393→394) taken 24 times.
✓ Branch 11 (393→395) taken 114 times.
✓ Branch 12 (395→396) taken 24 times.
✓ Branch 13 (395→398) taken 114 times.
✗ Branch 14 (532→533) not taken.
✗ Branch 15 (532→534) not taken.
✗ Branch 16 (536→537) not taken.
✗ Branch 17 (536→539) not taken.
186 ignoreUnusedReturnValue = fctDef && fctDef->attrs && fctDef->attrs->attrLst->hasAttr(ATTR_IGNORE_UNUSED_RETURN_VALUE);
1890 }
1891
1892
2/2
✓ Branch 0 (399→400) taken 118 times.
✓ Branch 1 (399→402) taken 23 times.
141 if (!ignoreUnusedReturnValue)
1893
1/2
✓ Branch 0 (400→401) taken 118 times.
✗ Branch 1 (400→541) not taken.
118 warnings.emplace_back(node->codeLoc, UNUSED_RETURN_VALUE, "The return value of the function call is unused");
1894 }
1895
1896
2/4
✓ Branch 0 (402→403) taken 13110 times.
✗ Branch 1 (402→542) not taken.
✓ Branch 2 (403→404) taken 13110 times.
✗ Branch 3 (403→542) not taken.
13110 return ExprResult{node->setEvaluatedSymbolType(returnType, manIdx), anonymousSymbol};
1897 13133 }
1898
1899 7792 bool TypeChecker::visitOrdinaryFctCall(FctCallNode *node, QualTypeList &templateTypes, std::string fqFunctionName) {
1900
1/2
✓ Branch 0 (2→3) taken 7792 times.
✗ Branch 1 (2→156) not taken.
7792 FctCallNode::FctCallData &data = node->data.at(manIdx);
1901
1902 // Check if this is a ctor call to the String type
1903
2/2
✓ Branch 0 (4→5) taken 7730 times.
✓ Branch 1 (4→38) taken 62 times.
7792 if (node->functionNameFragments.size() == 1) {
1904
2/2
✓ Branch 0 (20→7) taken 23190 times.
✓ Branch 1 (20→21) taken 7730 times.
30920 for (const auto &[typeName, runtimeModule] : TYPE_NAME_TO_RT_MODULE_MAPPING)
1905
8/10
✓ Branch 0 (10→11) taken 23190 times.
✗ Branch 1 (10→125) not taken.
✓ Branch 2 (11→12) taken 1576 times.
✓ Branch 3 (11→15) taken 21614 times.
✓ Branch 4 (12→13) taken 1576 times.
✗ Branch 5 (12→125) not taken.
✓ Branch 6 (13→14) taken 771 times.
✓ Branch 7 (13→15) taken 805 times.
✓ Branch 8 (16→17) taken 771 times.
✓ Branch 9 (16→18) taken 22419 times.
23190 if (fqFunctionName == typeName && !sourceFile->isRT(runtimeModule))
1906
1/2
✓ Branch 0 (17→18) taken 771 times.
✗ Branch 1 (17→125) not taken.
771 sourceFile->requestRuntimeModule(runtimeModule);
1907
2/2
✓ Branch 0 (36→23) taken 108220 times.
✓ Branch 1 (36→37) taken 7730 times.
115950 for (const auto &[fctName, runtimeModule] : FCT_NAME_TO_RT_MODULE_MAPPING)
1908
8/10
✓ Branch 0 (26→27) taken 108220 times.
✗ Branch 1 (26→126) not taken.
✓ Branch 2 (27→28) taken 455 times.
✓ Branch 3 (27→31) taken 107765 times.
✓ Branch 4 (28→29) taken 455 times.
✗ Branch 5 (28→126) not taken.
✓ Branch 6 (29→30) taken 447 times.
✓ Branch 7 (29→31) taken 8 times.
✓ Branch 8 (32→33) taken 447 times.
✓ Branch 9 (32→34) taken 107773 times.
108220 if (fqFunctionName == fctName && !sourceFile->isRT(runtimeModule))
1909
1/2
✓ Branch 0 (33→34) taken 447 times.
✗ Branch 1 (33→126) not taken.
447 sourceFile->requestRuntimeModule(runtimeModule);
1910 }
1911
1912 // Check if the type is generic (possible in case of ctor call)
1913
1/2
✓ Branch 0 (38→39) taken 7792 times.
✗ Branch 1 (38→156) not taken.
7792 const QualType *genericType = rootScope->lookupGenericType(fqFunctionName);
1914
6/8
✓ Branch 0 (39→40) taken 1 times.
✓ Branch 1 (39→43) taken 7791 times.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→156) not taken.
✓ Branch 4 (41→42) taken 1 times.
✗ Branch 5 (41→43) not taken.
✓ Branch 6 (44→45) taken 1 times.
✓ Branch 7 (44→50) taken 7791 times.
7792 if (genericType && typeMapping.contains(fqFunctionName)) {
1915
1/2
✓ Branch 0 (45→46) taken 1 times.
✗ Branch 1 (45→156) not taken.
1 const QualType &replacementType = typeMapping.at(fqFunctionName);
1916
2/4
✓ Branch 0 (46→47) taken 1 times.
✗ Branch 1 (46→156) not taken.
✓ Branch 2 (47→48) taken 1 times.
✗ Branch 3 (47→50) not taken.
1 if (replacementType.is(TY_STRUCT))
1917
2/4
✓ Branch 0 (48→49) taken 1 times.
✗ Branch 1 (48→156) not taken.
✓ Branch 2 (49→50) taken 1 times.
✗ Branch 3 (49→156) not taken.
1 fqFunctionName = replacementType.getSubType();
1918 }
1919
1920 // Check if the exported name registry contains that function name
1921
1/2
✓ Branch 0 (50→51) taken 7792 times.
✗ Branch 1 (50→156) not taken.
7792 const NameRegistryEntry *functionRegistryEntry = sourceFile->getNameRegistryEntry(fqFunctionName);
1922
2/2
✓ Branch 0 (51→52) taken 3 times.
✓ Branch 1 (51→60) taken 7789 times.
7792 if (!functionRegistryEntry) {
1923
2/4
✓ Branch 0 (53→54) taken 3 times.
✗ Branch 1 (53→129) not taken.
✓ Branch 2 (54→55) taken 3 times.
✗ Branch 3 (54→127) not taken.
3 const std::string msg = "Function/procedure/struct '" + node->functionNameFragments.back() + "' could not be found";
1924
1/2
✓ Branch 0 (56→57) taken 3 times.
✗ Branch 1 (56→130) not taken.
3 SOFT_ERROR_BOOL(node, REFERENCED_UNDEFINED_FUNCTION, msg)
1925 3 }
1926 7789 const SymbolTableEntry *functionEntry = functionRegistryEntry->targetEntry;
1927 7789 data.calleeParentScope = functionRegistryEntry->targetScope;
1928
1929 // Check if the target symbol is a struct -> this must be a constructor call
1930
7/10
✓ Branch 0 (60→61) taken 7789 times.
✗ Branch 1 (60→65) not taken.
✓ Branch 2 (61→62) taken 7789 times.
✗ Branch 3 (61→156) not taken.
✓ Branch 4 (62→63) taken 7789 times.
✗ Branch 5 (62→156) not taken.
✓ Branch 6 (63→64) taken 2012 times.
✓ Branch 7 (63→65) taken 5777 times.
✓ Branch 8 (66→67) taken 2012 times.
✓ Branch 9 (66→68) taken 5777 times.
7789 if (functionEntry != nullptr && functionEntry->getQualType().is(TY_STRUCT))
1931 2012 data.callType = FctCallNode::FctCallType::TYPE_CTOR;
1932
1933 // For constructor calls, do some preparation
1934
1/2
✓ Branch 0 (69→70) taken 7789 times.
✗ Branch 1 (69→156) not taken.
7789 std::string functionName = node->functionNameFragments.back();
1935
2/2
✓ Branch 0 (71→72) taken 2012 times.
✓ Branch 1 (71→93) taken 5777 times.
7789 if (data.isCtorCall()) {
1936 2012 const NameRegistryEntry *structRegistryEntry = functionRegistryEntry;
1937 2012 const SymbolTableEntry *structEntry = functionEntry;
1938
1/2
✓ Branch 0 (72→73) taken 2012 times.
✗ Branch 1 (72→145) not taken.
2012 const std::string structName = structRegistryEntry->targetEntry->name;
1939
1940 // Substantiate potentially generic this struct
1941
1/2
✓ Branch 0 (73→74) taken 2012 times.
✗ Branch 1 (73→143) not taken.
2012 const Struct *thisStruct = StructManager::match(structEntry->scope, structName, templateTypes, node);
1942
2/2
✓ Branch 0 (74→75) taken 1 times.
✓ Branch 1 (74→84) taken 2011 times.
2012 if (!thisStruct) {
1943
1/2
✓ Branch 0 (75→76) taken 1 times.
✗ Branch 1 (75→141) not taken.
1 const std::string signature = Struct::getSignature(structName, templateTypes);
1944
3/6
✓ Branch 0 (76→77) taken 1 times.
✗ Branch 1 (76→137) not taken.
✓ Branch 2 (77→78) taken 1 times.
✗ Branch 3 (77→135) not taken.
✓ Branch 4 (78→79) taken 1 times.
✗ Branch 5 (78→133) not taken.
1 SOFT_ERROR_BOOL(node, UNKNOWN_DATATYPE,
1945 "Could not find struct candidate for struct '" + signature + "'. Do the template types match?")
1946 1 }
1947
1948 // Override function name
1949
1/2
✓ Branch 0 (84→85) taken 2011 times.
✗ Branch 1 (84→143) not taken.
2011 functionName = CTOR_FUNCTION_NAME;
1950
1951 // Set the 'this' type of the function to the struct type
1952
2/4
✓ Branch 0 (85→86) taken 2011 times.
✗ Branch 1 (85→142) not taken.
✓ Branch 2 (86→87) taken 2011 times.
✗ Branch 3 (86→142) not taken.
2011 data.thisType = structEntry->getQualType().getWithBodyScope(thisStruct->scope);
1953 2011 data.calleeParentScope = thisStruct->scope;
1954
2/2
✓ Branch 0 (89→90) taken 2011 times.
✓ Branch 1 (89→92) taken 1 times.
2012 }
1955
1956 // Attach the concrete template types to the 'this' type
1957
7/8
✓ Branch 0 (93→94) taken 7788 times.
✗ Branch 1 (93→154) not taken.
✓ Branch 2 (94→95) taken 2011 times.
✓ Branch 3 (94→98) taken 5777 times.
✓ Branch 4 (96→97) taken 329 times.
✓ Branch 5 (96→98) taken 1682 times.
✓ Branch 6 (99→100) taken 329 times.
✓ Branch 7 (99→102) taken 7459 times.
7788 if (!data.thisType.is(TY_DYN) && !templateTypes.empty())
1958
1/2
✓ Branch 0 (100→101) taken 329 times.
✗ Branch 1 (100→146) not taken.
329 data.thisType = data.thisType.getWithTemplateTypes(templateTypes);
1959
1960 // Map local arg types to imported types
1961 7788 ArgList localArgs;
1962
1/2
✓ Branch 0 (103→104) taken 7788 times.
✗ Branch 1 (103→152) not taken.
7788 localArgs.reserve(data.argResults.size());
1963
2/2
✓ Branch 0 (112→106) taken 11741 times.
✓ Branch 1 (112→113) taken 7788 times.
19529 for (const ExprResult &argResult : data.argResults)
1964
2/4
✓ Branch 0 (108→109) taken 11741 times.
✗ Branch 1 (108→147) not taken.
✓ Branch 2 (109→110) taken 11741 times.
✗ Branch 3 (109→147) not taken.
11741 localArgs.emplace_back(mapLocalTypeToImportedScopeType(data.calleeParentScope, argResult.type), argResult.isTemporary());
1965
1966 // Map local template types to imported types
1967
2/2
✓ Branch 0 (119→115) taken 602 times.
✓ Branch 1 (119→120) taken 7788 times.
8390 for (QualType &templateType : templateTypes)
1968
1/2
✓ Branch 0 (116→117) taken 602 times.
✗ Branch 1 (116→150) not taken.
602 templateType = mapLocalTypeToImportedScopeType(data.calleeParentScope, templateType);
1969
1970 // Retrieve function object
1971 7788 Scope *matchScope = data.calleeParentScope;
1972
2/2
✓ Branch 0 (120→121) taken 7786 times.
✓ Branch 1 (120→152) taken 2 times.
7788 data.callee = FunctionManager::match(this, matchScope, functionName, data.thisType, localArgs, templateTypes, false, node);
1973
1974 7786 return true;
1975 7791 }
1976
1977 48 bool TypeChecker::visitFctPtrCall(const FctCallNode *node, const QualType &functionType) const {
1978
1/2
✓ Branch 0 (2→3) taken 48 times.
✗ Branch 1 (2→75) not taken.
48 const auto &[callType, isImported, thisType, argResults, callee, calleeParentScope] = node->data.at(manIdx);
1979
1980 // Check if the given argument types match the type
1981
1/2
✓ Branch 0 (3→4) taken 48 times.
✗ Branch 1 (3→75) not taken.
48 const QualTypeList expectedArgTypes = functionType.getFunctionParamTypes();
1982
1/2
✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→14) taken 48 times.
48 if (argResults.size() != expectedArgTypes.size())
1983 SOFT_ERROR_BOOL(node, REFERENCED_UNDEFINED_FUNCTION, "Expected and actual number of arguments do not match")
1984
1985 // Create resolver function, that always returns a nullptr
1986 48 TypeMatcher::ResolverFct resolverFct = [](const std::string &) { return nullptr; };
1987
1988
2/2
✓ Branch 0 (41→16) taken 31 times.
✓ Branch 1 (41→42) taken 48 times.
79 for (size_t i = 0; i < argResults.size(); i++) {
1989
1/2
✓ Branch 0 (16→17) taken 31 times.
✗ Branch 1 (16→71) not taken.
31 const QualType &actualType = argResults.at(i).type;
1990
1/2
✓ Branch 0 (17→18) taken 31 times.
✗ Branch 1 (17→71) not taken.
31 const QualType &expectedType = expectedArgTypes.at(i);
1991
2/4
✓ Branch 0 (19→20) taken 31 times.
✗ Branch 1 (19→68) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→34) taken 31 times.
31 if (TypeMapping tm; !TypeMatcher::matchRequestedToCandidateType(expectedType, actualType, tm, resolverFct, false))
1992
1/16
✗ Branch 0 (21→22) not taken.
✗ Branch 1 (21→66) not taken.
✗ Branch 2 (22→23) not taken.
✗ Branch 3 (22→61) not taken.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→59) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→57) not taken.
✗ Branch 8 (25→26) not taken.
✗ Branch 9 (25→55) not taken.
✗ Branch 10 (26→27) not taken.
✗ Branch 11 (26→53) not taken.
✗ Branch 12 (27→28) not taken.
✗ Branch 13 (27→53) not taken.
✓ Branch 14 (36→37) taken 31 times.
✗ Branch 15 (36→39) not taken.
31 SOFT_ERROR_BOOL(node->argLst->args.at(i), REFERENCED_UNDEFINED_FUNCTION,
1993 "Expected " + expectedType.getName(false) + " but got " + actualType.getName(false))
1994 }
1995 48 return true;
1996 48 }
1997
1998 5291 bool TypeChecker::visitMethodCall(FctCallNode *node, Scope *structScope, QualTypeList &templateTypes) {
1999
1/2
✓ Branch 0 (2→3) taken 5291 times.
✗ Branch 1 (2→107) not taken.
5291 auto &[callType, isImported, thisType, argResults, callee, calleeParentScope] = node->data.at(manIdx);
2000
2001 // Traverse through structs - the first fragment is already looked up and the last one is the method name
2002
2/2
✓ Branch 0 (41→4) taken 713 times.
✓ Branch 1 (41→42) taken 5289 times.
6002 for (size_t i = 1; i < node->functionNameFragments.size() - 1; i++) {
2003
2/4
✓ Branch 0 (4→5) taken 713 times.
✗ Branch 1 (4→107) not taken.
✓ Branch 2 (5→6) taken 713 times.
✗ Branch 3 (5→107) not taken.
713 const std::string &identifier = node->functionNameFragments.at(i);
2004
2005 // Retrieve field entry
2006 713 SymbolTableEntry *fieldEntry = structScope->lookupStrict(identifier);
2007
2/2
✓ Branch 0 (8→9) taken 1 times.
✓ Branch 1 (8→24) taken 712 times.
713 if (!fieldEntry) {
2008
1/2
✓ Branch 0 (9→10) taken 1 times.
✗ Branch 1 (9→83) not taken.
1 std::stringstream errorMsg;
2009
1/2
✓ Branch 0 (10→11) taken 1 times.
✗ Branch 1 (10→81) not taken.
1 errorMsg << "The type '";
2010
3/6
✓ Branch 0 (11→12) taken 1 times.
✗ Branch 1 (11→76) not taken.
✓ Branch 2 (12→13) taken 1 times.
✗ Branch 3 (12→76) not taken.
✓ Branch 4 (13→14) taken 1 times.
✗ Branch 5 (13→74) not taken.
1 errorMsg << thisType.getBase().getName(false, true);
2011
3/6
✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→81) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→81) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→81) not taken.
1 errorMsg << "' does not have a member with the name '" << identifier << "'";
2012
2/4
✓ Branch 0 (18→19) taken 1 times.
✗ Branch 1 (18→80) not taken.
✓ Branch 2 (19→20) taken 1 times.
✗ Branch 3 (19→78) not taken.
1 SOFT_ERROR_BOOL(node, ACCESS_TO_NON_EXISTING_MEMBER, errorMsg.str())
2013 1 }
2014
5/8
✓ Branch 0 (24→25) taken 712 times.
✗ Branch 1 (24→85) not taken.
✓ Branch 2 (25→26) taken 712 times.
✗ Branch 3 (25→85) not taken.
✓ Branch 4 (26→27) taken 712 times.
✗ Branch 5 (26→84) not taken.
✓ Branch 6 (27→28) taken 1 times.
✓ Branch 7 (27→34) taken 711 times.
712 if (!fieldEntry->getQualType().getBase().isOneOf({TY_STRUCT, TY_INTERFACE}))
2015
3/6
✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→90) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→88) not taken.
✓ Branch 4 (30→31) taken 1 times.
✗ Branch 5 (30→86) not taken.
1 SOFT_ERROR_BOOL(node, INVALID_MEMBER_ACCESS,
2016 "Cannot call a method on '" + identifier + "', since it is no struct or interface")
2017 711 fieldEntry->used = true;
2018
2019 // Get struct type and scope
2020
1/2
✓ Branch 0 (34→35) taken 711 times.
✗ Branch 1 (34→107) not taken.
711 thisType = fieldEntry->getQualType();
2021
2/4
✓ Branch 0 (35→36) taken 711 times.
✗ Branch 1 (35→92) not taken.
✓ Branch 2 (36→37) taken 711 times.
✗ Branch 3 (36→92) not taken.
711 structScope = thisType.getBase().getBodyScope();
2022
1/2
✗ Branch 0 (37→38) not taken.
✓ Branch 1 (37→39) taken 711 times.
711 assert(structScope != nullptr);
2023 }
2024
2025
2/4
✓ Branch 0 (42→43) taken 5289 times.
✗ Branch 1 (42→107) not taken.
✗ Branch 2 (43→44) not taken.
✓ Branch 3 (43→51) taken 5289 times.
5289 if (thisType.is(TY_INTERFACE))
2026 SOFT_ERROR_BOOL(node, INVALID_MEMBER_ACCESS, "Cannot call a method on an interface")
2027
2028 // Map local arg types to imported types
2029 5289 Scope *matchScope = calleeParentScope = structScope;
2030 5289 ArgList localArgs;
2031
2/2
✓ Branch 0 (59→53) taken 3879 times.
✓ Branch 1 (59→60) taken 5289 times.
9168 for (const ExprResult &argResult : argResults)
2032
2/4
✓ Branch 0 (55→56) taken 3879 times.
✗ Branch 1 (55→99) not taken.
✓ Branch 2 (56→57) taken 3879 times.
✗ Branch 3 (56→99) not taken.
3879 localArgs.emplace_back(mapLocalTypeToImportedScopeType(calleeParentScope, argResult.type), argResult.isTemporary());
2033
2034 // Map local template types to imported types
2035
1/2
✗ Branch 0 (66→62) not taken.
✓ Branch 1 (66→67) taken 5289 times.
5289 for (QualType &templateType : templateTypes)
2036 templateType = mapLocalTypeToImportedScopeType(calleeParentScope, templateType);
2037
2038 // 'this' type
2039 5289 QualType localThisType = thisType;
2040
1/2
✓ Branch 0 (67→68) taken 5289 times.
✗ Branch 1 (67→105) not taken.
5289 autoDeReference(localThisType);
2041
1/2
✓ Branch 0 (68→69) taken 5289 times.
✗ Branch 1 (68→104) not taken.
5289 localThisType = mapLocalTypeToImportedScopeType(calleeParentScope, localThisType);
2042
2043 // Retrieve function object
2044 5289 const std::string &functionName = node->functionNameFragments.back();
2045
1/2
✓ Branch 0 (70→71) taken 5289 times.
✗ Branch 1 (70→105) not taken.
5289 callee = FunctionManager::match(this, matchScope, functionName, localThisType, localArgs, templateTypes, false, node);
2046
2047 5289 return true;
2048 5289 }
2049
2050 66 std::any TypeChecker::visitArrayInitialization(ArrayInitializationNode *node) {
2051
5/6
✓ Branch 0 (2→3) taken 65 times.
✓ Branch 1 (2→5) taken 1 times.
✗ Branch 2 (4→5) not taken.
✓ Branch 3 (4→6) taken 65 times.
✓ Branch 4 (7→8) taken 1 times.
✓ Branch 5 (7→18) taken 65 times.
66 if (!node->itemLst || node->itemLst->args.empty())
2052
4/8
✓ Branch 0 (10→11) taken 1 times.
✗ Branch 1 (10→68) not taken.
✓ Branch 2 (11→12) taken 1 times.
✗ Branch 3 (11→66) not taken.
✓ Branch 4 (14→15) taken 1 times.
✗ Branch 5 (14→72) not taken.
✓ Branch 6 (15→16) taken 1 times.
✗ Branch 7 (15→72) not taken.
3 SOFT_ERROR_ER(node, ARRAY_SIZE_INVALID, "Array initializers must at least contain one value");
2053 65 node->actualSize = node->itemLst->args.size();
2054
2055
1/2
✓ Branch 0 (19→20) taken 65 times.
✗ Branch 1 (19→97) not taken.
65 QualType actualItemType(TY_DYN);
2056 // Check if all values have the same type
2057
2/2
✓ Branch 0 (55→22) taken 435 times.
✓ Branch 1 (55→56) taken 64 times.
499 for (AssignExprNode *arg : node->itemLst->args) {
2058
2/4
✓ Branch 0 (23→24) taken 435 times.
✗ Branch 1 (23→75) not taken.
✓ Branch 2 (24→25) taken 435 times.
✗ Branch 3 (24→73) not taken.
435 const QualType itemType = std::any_cast<ExprResult>(visit(arg)).type;
2059
2/8
✓ Branch 0 (26→27) taken 435 times.
✗ Branch 1 (26→94) not taken.
✗ Branch 2 (27→28) not taken.
✓ Branch 3 (27→32) taken 435 times.
✗ Branch 4 (28→29) not taken.
✗ Branch 5 (28→77) not taken.
✗ Branch 6 (29→30) not taken.
✗ Branch 7 (29→77) not taken.
435 HANDLE_UNRESOLVED_TYPE_ER(itemType)
2060
3/4
✓ Branch 0 (32→33) taken 435 times.
✗ Branch 1 (32→94) not taken.
✓ Branch 2 (33→34) taken 65 times.
✓ Branch 3 (33→35) taken 370 times.
435 if (actualItemType.is(TY_DYN)) // Perform type inference
2061 65 actualItemType = itemType;
2062
3/4
✓ Branch 0 (35→36) taken 370 times.
✗ Branch 1 (35→94) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→52) taken 369 times.
370 else if (itemType != actualItemType) // Check if types are matching
2063
8/16
✓ Branch 0 (37→38) taken 1 times.
✗ Branch 1 (37→91) not taken.
✓ Branch 2 (38→39) taken 1 times.
✗ Branch 3 (38→86) not taken.
✓ Branch 4 (39→40) taken 1 times.
✗ Branch 5 (39→84) not taken.
✓ Branch 6 (40→41) taken 1 times.
✗ Branch 7 (40→82) not taken.
✓ Branch 8 (41→42) taken 1 times.
✗ Branch 9 (41→80) not taken.
✓ Branch 10 (42→43) taken 1 times.
✗ Branch 11 (42→78) not taken.
✓ Branch 12 (48→49) taken 1 times.
✗ Branch 13 (48→93) not taken.
✓ Branch 14 (49→50) taken 1 times.
✗ Branch 15 (49→93) not taken.
1 SOFT_ERROR_ER(arg, ARRAY_ITEM_TYPE_NOT_MATCHING,
2064 "All provided values have to be of the same data type. You provided " + actualItemType.getName(false) +
2065 " and " + itemType.getName(false))
2066 }
2067
2/4
✓ Branch 0 (56→57) taken 64 times.
✗ Branch 1 (56→97) not taken.
✗ Branch 2 (57→58) not taken.
✓ Branch 3 (57→59) taken 64 times.
64 assert(!actualItemType.is(TY_DYN));
2068
2069
1/2
✓ Branch 0 (59→60) taken 64 times.
✗ Branch 1 (59→97) not taken.
64 const QualType arrayType = actualItemType.toArr(node, node->actualSize, true);
2070
2/4
✓ Branch 0 (60→61) taken 64 times.
✗ Branch 1 (60→96) not taken.
✓ Branch 2 (61→62) taken 64 times.
✗ Branch 3 (61→96) not taken.
64 return ExprResult{node->setEvaluatedSymbolType(arrayType, manIdx)};
2071 }
2072
2073 283 std::any TypeChecker::visitStructInstantiation(StructInstantiationNode *node) {
2074 // Get struct name. Retrieve it from alias if required
2075
1/2
✓ Branch 0 (2→3) taken 283 times.
✗ Branch 1 (2→302) not taken.
283 std::string structName = node->fqStructName;
2076
1/2
✓ Branch 0 (3→4) taken 283 times.
✗ Branch 1 (3→300) not taken.
283 SymbolTableEntry *aliasEntry = rootScope->lookupStrict(structName);
2077 283 SymbolTableEntry *aliasedTypeContainerEntry = nullptr;
2078
6/8
✓ Branch 0 (6→7) taken 277 times.
✓ Branch 1 (6→11) taken 6 times.
✓ Branch 2 (7→8) taken 277 times.
✗ Branch 3 (7→300) not taken.
✓ Branch 4 (8→9) taken 277 times.
✗ Branch 5 (8→300) not taken.
✓ Branch 6 (9→10) taken 1 times.
✓ Branch 7 (9→11) taken 276 times.
283 const bool isAliasType = aliasEntry && aliasEntry->getQualType().is(TY_ALIAS);
2079
2/2
✓ Branch 0 (12→13) taken 1 times.
✓ Branch 1 (12→23) taken 282 times.
283 if (isAliasType) {
2080
1/2
✓ Branch 0 (13→14) taken 1 times.
✗ Branch 1 (13→220) not taken.
2 aliasedTypeContainerEntry = rootScope->lookupStrict(aliasEntry->name + ALIAS_CONTAINER_SUFFIX);
2081
1/2
✗ Branch 0 (18→19) not taken.
✓ Branch 1 (18→20) taken 1 times.
1 assert(aliasedTypeContainerEntry != nullptr);
2082 // Set alias entry used
2083 1 aliasEntry->used = true;
2084
3/6
✓ Branch 0 (20→21) taken 1 times.
✗ Branch 1 (20→300) not taken.
✓ Branch 2 (21→22) taken 1 times.
✗ Branch 3 (21→300) not taken.
✓ Branch 4 (22→23) taken 1 times.
✗ Branch 5 (22→300) not taken.
1 structName = aliasedTypeContainerEntry->getQualType().getSubType();
2085 }
2086
2087 // Check if access scope was altered
2088
1/4
✗ Branch 0 (23→24) not taken.
✓ Branch 1 (23→34) taken 283 times.
✗ Branch 2 (24→25) not taken.
✗ Branch 3 (24→34) not taken.
283 if (accessScope != nullptr && accessScope != currentScope)
2089 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, "Cannot find struct '" + structName + "'")
2090
2091 // Retrieve struct
2092
1/2
✓ Branch 0 (34→35) taken 283 times.
✗ Branch 1 (34→300) not taken.
283 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(structName);
2093
2/2
✓ Branch 0 (35→36) taken 1 times.
✓ Branch 1 (35→45) taken 282 times.
283 if (!registryEntry)
2094
5/10
✓ Branch 0 (36→37) taken 1 times.
✗ Branch 1 (36→232) not taken.
✓ Branch 2 (37→38) taken 1 times.
✗ Branch 3 (37→230) not taken.
✓ Branch 4 (38→39) taken 1 times.
✗ Branch 5 (38→228) not taken.
✓ Branch 6 (41→42) taken 1 times.
✗ Branch 7 (41→234) not taken.
✓ Branch 8 (42→43) taken 1 times.
✗ Branch 9 (42→234) not taken.
1 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, "Cannot find struct '" + structName + "'")
2095
2/4
✓ Branch 0 (45→46) taken 282 times.
✗ Branch 1 (45→48) not taken.
✓ Branch 2 (46→47) taken 282 times.
✗ Branch 3 (46→48) not taken.
282 assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr);
2096 282 SymbolTableEntry *structEntry = registryEntry->targetEntry;
2097 282 Scope *structScope = accessScope = registryEntry->targetScope;
2098
2099 // Get struct type
2100
1/2
✓ Branch 0 (49→50) taken 282 times.
✗ Branch 1 (49→300) not taken.
282 QualType structType = structEntry->getQualType();
2101
2102 // Get the concrete template types
2103 282 QualTypeList concreteTemplateTypes;
2104
2/2
✓ Branch 0 (50→51) taken 1 times.
✓ Branch 1 (50→70) taken 281 times.
282 if (isAliasType) {
2105 // Retrieve concrete template types from type alias
2106
3/6
✓ Branch 0 (51→52) taken 1 times.
✗ Branch 1 (51→298) not taken.
✓ Branch 2 (52→53) taken 1 times.
✗ Branch 3 (52→298) not taken.
✓ Branch 4 (53→54) taken 1 times.
✗ Branch 5 (53→298) not taken.
1 concreteTemplateTypes = aliasedTypeContainerEntry->getQualType().getTemplateTypes();
2107 // Check if the aliased type specified template types and the struct instantiation does
2108
3/6
✓ Branch 0 (55→56) taken 1 times.
✗ Branch 1 (55→58) not taken.
✗ Branch 2 (56→57) not taken.
✓ Branch 3 (56→58) taken 1 times.
✗ Branch 4 (59→60) not taken.
✓ Branch 5 (59→70) taken 1 times.
1 if (!concreteTemplateTypes.empty() && node->templateTypeLst)
2109 SOFT_ERROR_ER(node->templateTypeLst, ALIAS_WITH_TEMPLATE_LIST, "The aliased type already has a template list")
2110 }
2111
2112
2/2
✓ Branch 0 (70→71) taken 14 times.
✓ Branch 1 (70→103) taken 268 times.
282 if (node->templateTypeLst) {
2113
1/2
✓ Branch 0 (72→73) taken 14 times.
✗ Branch 1 (72→298) not taken.
14 concreteTemplateTypes.reserve(node->templateTypeLst->dataTypes.size());
2114
2/2
✓ Branch 0 (101→75) taken 21 times.
✓ Branch 1 (101→102) taken 14 times.
35 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
2115
2/4
✓ Branch 0 (76→77) taken 21 times.
✗ Branch 1 (76→244) not taken.
✓ Branch 2 (77→78) taken 21 times.
✗ Branch 3 (77→242) not taken.
21 auto concreteType = std::any_cast<QualType>(visit(dataType));
2116
2/8
✓ Branch 0 (79→80) taken 21 times.
✗ Branch 1 (79→253) not taken.
✗ Branch 2 (80→81) not taken.
✓ Branch 3 (80→85) taken 21 times.
✗ Branch 4 (81→82) not taken.
✗ Branch 5 (81→245) not taken.
✗ Branch 6 (82→83) not taken.
✗ Branch 7 (82→245) not taken.
21 HANDLE_UNRESOLVED_TYPE_ER(concreteType)
2117 // Check if generic type
2118
2/4
✓ Branch 0 (85→86) taken 21 times.
✗ Branch 1 (85→253) not taken.
✗ Branch 2 (86→87) not taken.
✓ Branch 3 (86→97) taken 21 times.
21 if (concreteType.is(TY_GENERIC))
2119 SOFT_ERROR_ER(dataType, EXPECTED_NON_GENERIC_TYPE, "Struct instantiations may only take concrete template types")
2120
1/2
✓ Branch 0 (97→98) taken 21 times.
✗ Branch 1 (97→253) not taken.
21 concreteTemplateTypes.push_back(concreteType);
2121 }
2122 }
2123
2124 // Get the struct instance
2125
1/2
✓ Branch 0 (103→104) taken 282 times.
✗ Branch 1 (103→298) not taken.
282 structName = structEntry->name;
2126
1/2
✓ Branch 0 (104→105) taken 282 times.
✗ Branch 1 (104→298) not taken.
282 Struct *spiceStruct = StructManager::match(structScope->parent, structName, concreteTemplateTypes, node);
2127
1/2
✗ Branch 0 (105→106) not taken.
✓ Branch 1 (105→117) taken 282 times.
282 if (!spiceStruct) {
2128 const std::string structSignature = Struct::getSignature(structName, concreteTemplateTypes);
2129 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, "Struct '" + structSignature + "' could not be found")
2130 }
2131
1/2
✓ Branch 0 (117→118) taken 282 times.
✗ Branch 1 (117→298) not taken.
282 node->instantiatedStructs.at(manIdx) = spiceStruct;
2132
2133 // Struct instantiation for an inheriting struct is forbidden, because the vtable needs to be initialized and this is done in
2134 // the ctor of the struct, which is never called in case of struct instantiation
2135
2/2
✓ Branch 0 (119→120) taken 1 times.
✓ Branch 1 (119→130) taken 281 times.
282 if (!spiceStruct->interfaceTypes.empty())
2136
4/8
✓ Branch 0 (122→123) taken 1 times.
✗ Branch 1 (122→267) not taken.
✓ Branch 2 (123→124) taken 1 times.
✗ Branch 3 (123→265) not taken.
✓ Branch 4 (126→127) taken 1 times.
✗ Branch 5 (126→271) not taken.
✓ Branch 6 (127→128) taken 1 times.
✗ Branch 7 (127→271) not taken.
3 SOFT_ERROR_ER(node, INVALID_STRUCT_INSTANTIATION, "Struct instantiations for inheriting structs are forbidden")
2137
2138 // Use scope of concrete substantiation and not the scope of the generic type
2139 281 structScope = spiceStruct->scope;
2140
1/2
✓ Branch 0 (130→131) taken 281 times.
✗ Branch 1 (130→272) not taken.
281 structType = structType.getWithBodyScope(structScope);
2141
2142 // Set template types to the struct
2143 281 QualTypeList templateTypes;
2144
2/2
✓ Branch 0 (137→133) taken 22 times.
✓ Branch 1 (137→138) taken 281 times.
303 for (const GenericType &genericType : spiceStruct->templateTypes)
2145
1/2
✓ Branch 0 (134→135) taken 22 times.
✗ Branch 1 (134→273) not taken.
22 templateTypes.emplace_back(genericType);
2146
1/2
✓ Branch 0 (138→139) taken 281 times.
✗ Branch 1 (138→274) not taken.
281 structType = structType.getWithTemplateTypes(templateTypes);
2147
2148 // Check if the number of fields matches
2149
2/2
✓ Branch 0 (139→140) taken 267 times.
✓ Branch 1 (139→183) taken 14 times.
281 if (node->fieldLst) { // Check if any fields are passed. Empty braces are also allowed
2150
2/2
✓ Branch 0 (142→143) taken 1 times.
✓ Branch 1 (142→153) taken 266 times.
267 if (spiceStruct->fieldTypes.size() != node->fieldLst->args.size())
2151
4/8
✓ Branch 0 (145→146) taken 1 times.
✗ Branch 1 (145→277) not taken.
✓ Branch 2 (146→147) taken 1 times.
✗ Branch 3 (146→275) not taken.
✓ Branch 4 (149→150) taken 1 times.
✗ Branch 5 (149→281) not taken.
✓ Branch 6 (150→151) taken 1 times.
✗ Branch 7 (150→281) not taken.
3 SOFT_ERROR_ER(node->fieldLst, NUMBER_OF_FIELDS_NOT_MATCHING,
2152 "You've passed too less/many field values. Pass either none or all of them")
2153
2154 // Check if the field types are matching
2155 266 const size_t fieldCount = spiceStruct->fieldTypes.size();
2156
1/2
✓ Branch 0 (154→155) taken 266 times.
✗ Branch 1 (154→296) not taken.
266 const size_t explicitFieldsStartIdx = structScope->getFieldCount() - fieldCount;
2157
2/2
✓ Branch 0 (182→156) taken 386 times.
✓ Branch 1 (182→202) taken 265 times.
651 for (size_t i = 0; i < node->fieldLst->args.size(); i++) {
2158 // Get actual type
2159
1/2
✓ Branch 0 (156→157) taken 386 times.
✗ Branch 1 (156→286) not taken.
386 AssignExprNode *assignExpr = node->fieldLst->args.at(i);
2160
2/4
✓ Branch 0 (157→158) taken 386 times.
✗ Branch 1 (157→284) not taken.
✓ Branch 2 (158→159) taken 386 times.
✗ Branch 3 (158→282) not taken.
386 auto fieldResult = std::any_cast<ExprResult>(visit(assignExpr));
2161
2/8
✓ Branch 0 (160→161) taken 386 times.
✗ Branch 1 (160→286) not taken.
✗ Branch 2 (161→162) not taken.
✓ Branch 3 (161→166) taken 386 times.
✗ Branch 4 (162→163) not taken.
✗ Branch 5 (162→285) not taken.
✗ Branch 6 (163→164) not taken.
✗ Branch 7 (163→285) not taken.
386 HANDLE_UNRESOLVED_TYPE_ER(fieldResult.type)
2162 // Get expected type
2163
1/2
✗ Branch 0 (166→167) not taken.
✓ Branch 1 (166→168) taken 386 times.
386 SymbolTableEntry *expectedField = structScope->lookupField(explicitFieldsStartIdx + i);
2164
1/2
✗ Branch 0 (171→172) not taken.
✓ Branch 1 (171→173) taken 386 times.
386 assert(expectedField != nullptr);
2165
1/2
✓ Branch 0 (173→174) taken 386 times.
✗ Branch 1 (173→286) not taken.
386 const ExprResult expected = {expectedField->getQualType(), expectedField};
2166
1/2
✓ Branch 0 (174→175) taken 386 times.
✗ Branch 1 (174→286) not taken.
386 const bool rhsIsImmediate = assignExpr->hasCompileTimeValue();
2167
2168 // Check if actual type matches expected type
2169
2/2
✓ Branch 0 (175→176) taken 385 times.
✓ Branch 1 (175→286) taken 1 times.
386 (void)opRuleManager.getFieldAssignResultType(assignExpr, expected, fieldResult, rhsIsImmediate, true);
2170
2171 // If there is an anonymous entry attached (e.g. for struct instantiation), delete it
2172
4/4
✓ Branch 0 (176→177) taken 97 times.
✓ Branch 1 (176→180) taken 288 times.
✓ Branch 2 (177→178) taken 3 times.
✓ Branch 3 (177→180) taken 94 times.
385 if (fieldResult.entry != nullptr && fieldResult.entry->anonymous) {
2173
1/2
✓ Branch 0 (178→179) taken 3 times.
✗ Branch 1 (178→286) not taken.
3 currentScope->symbolTable.deleteAnonymous(fieldResult.entry->name);
2174 3 fieldResult.entry = nullptr;
2175 }
2176 }
2177 } else {
2178
2/2
✓ Branch 0 (200→185) taken 43 times.
✓ Branch 1 (200→201) taken 14 times.
57 for (QualType &fieldType : spiceStruct->fieldTypes) {
2179
2/4
✓ Branch 0 (186→187) taken 43 times.
✗ Branch 1 (186→294) not taken.
✗ Branch 2 (187→188) not taken.
✓ Branch 3 (187→198) taken 43 times.
43 if (fieldType.isRef())
2180 SOFT_ERROR_ER(node, REFERENCE_WITHOUT_INITIALIZER,
2181 "The struct takes at least one reference field. You need to instantiate it with all fields.")
2182 }
2183 }
2184
2185 // Update type of struct entry
2186
1/2
✓ Branch 0 (202→203) taken 279 times.
✗ Branch 1 (202→296) not taken.
279 structEntry->updateType(structType, true);
2187
2188 // If not all values are constant, insert anonymous symbol to keep track of dtor calls for de-allocation
2189 279 SymbolTableEntry *anonymousEntry = nullptr;
2190
2/2
✓ Branch 0 (203→204) taken 265 times.
✓ Branch 1 (203→208) taken 14 times.
279 if (node->fieldLst != nullptr)
2191
3/4
✓ Branch 0 (204→205) taken 265 times.
✗ Branch 1 (204→296) not taken.
✓ Branch 2 (205→206) taken 234 times.
✓ Branch 3 (205→208) taken 31 times.
599 if (std::ranges::any_of(node->fieldLst->args, [](const AssignExprNode *field) { return !field->hasCompileTimeValue(); }))
2192
1/2
✓ Branch 0 (206→207) taken 234 times.
✗ Branch 1 (206→296) not taken.
234 anonymousEntry = currentScope->symbolTable.insertAnonymous(structType, node);
2193
2194 // Remove public qualifier to not have public local variables
2195 279 structType.getQualifiers().isPublic = false;
2196
2197
2/4
✓ Branch 0 (209→210) taken 279 times.
✗ Branch 1 (209→295) not taken.
✓ Branch 2 (210→211) taken 279 times.
✗ Branch 3 (210→295) not taken.
279 return ExprResult{node->setEvaluatedSymbolType(structType, manIdx), anonymousEntry};
2198 285 }
2199
2200 12 std::any TypeChecker::visitLambdaFunc(LambdaFuncNode *node) {
2201 // Check if all control paths in the lambda body return
2202 12 bool returnsOnAllControlPaths = true;
2203
3/4
✓ Branch 0 (2→3) taken 12 times.
✗ Branch 1 (2→186) not taken.
✓ Branch 2 (3→4) taken 1 times.
✓ Branch 3 (3→14) taken 11 times.
12 if (!node->returnsOnAllControlPaths(&returnsOnAllControlPaths))
2204
4/8
✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→112) not taken.
✓ Branch 2 (7→8) taken 1 times.
✗ Branch 3 (7→110) not taken.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→116) not taken.
✓ Branch 6 (11→12) taken 1 times.
✗ Branch 7 (11→116) not taken.
3 SOFT_ERROR_ER(node, MISSING_RETURN_STMT, "Not all control paths of this lambda function have a return statement")
2205
2206 // Change to function scope
2207
2/4
✓ Branch 0 (14→15) taken 11 times.
✗ Branch 1 (14→119) not taken.
✓ Branch 2 (15→16) taken 11 times.
✗ Branch 3 (15→117) not taken.
11 Scope *bodyScope = currentScope->getChildScope(node->getScopeId());
2208
1/2
✓ Branch 0 (17→18) taken 11 times.
✗ Branch 1 (17→120) not taken.
11 ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY);
2209
2210 // Visit return type
2211
2/4
✓ Branch 0 (18→19) taken 11 times.
✗ Branch 1 (18→123) not taken.
✓ Branch 2 (19→20) taken 11 times.
✗ Branch 3 (19→121) not taken.
11 const auto returnType = std::any_cast<QualType>(visit(node->returnType));
2212
2/8
✓ Branch 0 (21→22) taken 11 times.
✗ Branch 1 (21→184) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 11 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→124) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→124) not taken.
11 HANDLE_UNRESOLVED_TYPE_ER(returnType)
2213
3/4
✓ Branch 0 (27→28) taken 11 times.
✗ Branch 1 (27→184) not taken.
✓ Branch 2 (28→29) taken 1 times.
✓ Branch 3 (28→39) taken 10 times.
11 if (returnType.is(TY_DYN))
2214
4/8
✓ Branch 0 (31→32) taken 1 times.
✗ Branch 1 (31→127) not taken.
✓ Branch 2 (32→33) taken 1 times.
✗ Branch 3 (32→125) not taken.
✓ Branch 4 (35→36) taken 1 times.
✗ Branch 5 (35→131) not taken.
✓ Branch 6 (36→37) taken 1 times.
✗ Branch 7 (36→131) not taken.
3 SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Dyn return types are not allowed")
2215
2216 // Set the type of the result variable
2217
1/2
✓ Branch 0 (41→42) taken 10 times.
✗ Branch 1 (41→134) not taken.
30 SymbolTableEntry *resultVarEntry = currentScope->lookupStrict(RETURN_VARIABLE_NAME);
2218
1/2
✗ Branch 0 (47→48) not taken.
✓ Branch 1 (47→49) taken 10 times.
10 assert(resultVarEntry != nullptr);
2219
1/2
✓ Branch 0 (49→50) taken 10 times.
✗ Branch 1 (49→184) not taken.
10 resultVarEntry->updateType(returnType, true);
2220 10 resultVarEntry->used = true;
2221
2222 // Visit parameters
2223 10 QualTypeList paramTypes;
2224 10 ParamList paramList;
2225
2/2
✓ Branch 0 (50→51) taken 6 times.
✓ Branch 1 (50→72) taken 4 times.
10 if (node->hasParams) {
2226 // Visit param list to retrieve the param names
2227
2/4
✓ Branch 0 (51→52) taken 6 times.
✗ Branch 1 (51→140) not taken.
✓ Branch 2 (52→53) taken 6 times.
✗ Branch 3 (52→138) not taken.
6 auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst));
2228
2/2
✓ Branch 0 (69→56) taken 10 times.
✓ Branch 1 (69→70) taken 6 times.
16 for (const auto &[name, qualType, isOptional] : namedParamList) {
2229
1/2
✗ Branch 0 (57→58) not taken.
✓ Branch 1 (57→65) taken 10 times.
10 if (isOptional)
2230 softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters");
2231
2232
1/2
✓ Branch 0 (65→66) taken 10 times.
✗ Branch 1 (65→148) not taken.
10 paramTypes.push_back(qualType);
2233
1/2
✓ Branch 0 (66→67) taken 10 times.
✗ Branch 1 (66→147) not taken.
10 paramList.push_back({qualType, isOptional});
2234 }
2235 6 }
2236
2237 // Visit lambda body
2238
2/2
✓ Branch 0 (72→73) taken 9 times.
✓ Branch 1 (72→152) taken 1 times.
10 visit(node->body);
2239
2240 // Leave function body scope
2241
1/2
✓ Branch 0 (74→75) taken 9 times.
✗ Branch 1 (74→180) not taken.
9 scopeHandle.leaveScopeEarly();
2242
2243 // Prepare type of function
2244
1/2
✓ Branch 0 (75→76) taken 9 times.
✗ Branch 1 (75→153) not taken.
9 const QualType functionType = QualType(TY_FUNCTION)
2245
1/2
✓ Branch 0 (76→77) taken 9 times.
✗ Branch 1 (76→153) not taken.
9 .getWithFunctionParamAndReturnTypes(returnType, paramTypes)
2246
1/2
✓ Branch 0 (78→79) taken 9 times.
✗ Branch 1 (78→153) not taken.
9 .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty());
2247
2248 // Create function object
2249
2/4
✓ Branch 0 (79→80) taken 9 times.
✗ Branch 1 (79→157) not taken.
✓ Branch 2 (80→81) taken 9 times.
✗ Branch 3 (80→155) not taken.
9 const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn();
2250
4/8
✓ Branch 0 (83→84) taken 9 times.
✗ Branch 1 (83→166) not taken.
✓ Branch 2 (84→85) taken 9 times.
✗ Branch 3 (84→163) not taken.
✓ Branch 4 (85→86) taken 9 times.
✗ Branch 5 (85→162) not taken.
✓ Branch 6 (87→88) taken 9 times.
✗ Branch 7 (87→158) not taken.
9 node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), returnType, paramList, {}, node);
2251
1/2
✓ Branch 0 (93→94) taken 9 times.
✗ Branch 1 (93→178) not taken.
9 node->manifestations.at(manIdx).bodyScope = bodyScope;
2252
3/6
✓ Branch 0 (94→95) taken 9 times.
✗ Branch 1 (94→175) not taken.
✓ Branch 2 (95→96) taken 9 times.
✗ Branch 3 (95→173) not taken.
✓ Branch 4 (96→97) taken 9 times.
✗ Branch 5 (96→171) not taken.
9 node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx);
2253
2254 // Check special requirements if this is an async lambda
2255
1/2
✓ Branch 0 (100→101) taken 9 times.
✗ Branch 1 (100→178) not taken.
9 (void)checkAsyncLambdaCaptureRules(node, node->lambdaAttr);
2256
2257
2/4
✓ Branch 0 (101→102) taken 9 times.
✗ Branch 1 (101→177) not taken.
✓ Branch 2 (102→103) taken 9 times.
✗ Branch 3 (102→177) not taken.
9 return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)};
2258 13 }
2259
2260 28 std::any TypeChecker::visitLambdaProc(LambdaProcNode *node) {
2261 // Mark unreachable statements
2262 28 bool doSetPredecessorsUnreachable = true;
2263
1/2
✓ Branch 0 (2→3) taken 28 times.
✗ Branch 1 (2→123) not taken.
28 node->returnsOnAllControlPaths(&doSetPredecessorsUnreachable);
2264
2265 // Change to function scope
2266
2/4
✓ Branch 0 (3→4) taken 28 times.
✗ Branch 1 (3→71) not taken.
✓ Branch 2 (4→5) taken 28 times.
✗ Branch 3 (4→69) not taken.
28 Scope *bodyScope = currentScope->getChildScope(node->getScopeId());
2267
1/2
✓ Branch 0 (6→7) taken 28 times.
✗ Branch 1 (6→72) not taken.
28 ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY);
2268
2269 // Visit parameters
2270 28 QualTypeList paramTypes;
2271 28 ParamList paramList;
2272
2/2
✓ Branch 0 (7→8) taken 7 times.
✓ Branch 1 (7→29) taken 21 times.
28 if (node->hasParams) {
2273 // Visit param list to retrieve the param names
2274
2/4
✓ Branch 0 (8→9) taken 7 times.
✗ Branch 1 (8→75) not taken.
✓ Branch 2 (9→10) taken 7 times.
✗ Branch 3 (9→73) not taken.
7 auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst));
2275
2/2
✓ Branch 0 (26→13) taken 11 times.
✓ Branch 1 (26→27) taken 7 times.
18 for (const auto &[_, qualType, isOptional] : namedParamList) {
2276
2/2
✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→22) taken 10 times.
11 if (isOptional)
2277
2/4
✓ Branch 0 (17→18) taken 1 times.
✗ Branch 1 (17→78) not taken.
✓ Branch 2 (18→19) taken 1 times.
✗ Branch 3 (18→76) not taken.
2 softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters");
2278
2279
1/2
✓ Branch 0 (22→23) taken 11 times.
✗ Branch 1 (22→83) not taken.
11 paramTypes.push_back(qualType);
2280
1/2
✓ Branch 0 (23→24) taken 11 times.
✗ Branch 1 (23→82) not taken.
11 paramList.push_back({qualType, isOptional});
2281 }
2282 7 }
2283
2284 // Visit lambda body
2285
1/2
✓ Branch 0 (29→30) taken 28 times.
✗ Branch 1 (29→87) not taken.
28 visit(node->body);
2286
2287 // Leave function body scope
2288
1/2
✓ Branch 0 (31→32) taken 28 times.
✗ Branch 1 (31→117) not taken.
28 scopeHandle.leaveScopeEarly();
2289
2290 // Prepare type of function
2291
1/2
✓ Branch 0 (32→33) taken 28 times.
✗ Branch 1 (32→89) not taken.
28 const QualType functionType = QualType(TY_PROCEDURE)
2292
2/4
✓ Branch 0 (33→34) taken 28 times.
✗ Branch 1 (33→88) not taken.
✓ Branch 2 (34→35) taken 28 times.
✗ Branch 3 (34→88) not taken.
28 .getWithFunctionParamAndReturnTypes(QualType(TY_DYN), paramTypes)
2293
1/2
✓ Branch 0 (36→37) taken 28 times.
✗ Branch 1 (36→88) not taken.
28 .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty());
2294
2295 // Create function object
2296
2/4
✓ Branch 0 (37→38) taken 28 times.
✗ Branch 1 (37→93) not taken.
✓ Branch 2 (38→39) taken 28 times.
✗ Branch 3 (38→91) not taken.
28 const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn();
2297
5/10
✓ Branch 0 (41→42) taken 28 times.
✗ Branch 1 (41→103) not taken.
✓ Branch 2 (42→43) taken 28 times.
✗ Branch 3 (42→100) not taken.
✓ Branch 4 (43→44) taken 28 times.
✗ Branch 5 (43→99) not taken.
✓ Branch 6 (44→45) taken 28 times.
✗ Branch 7 (44→98) not taken.
✓ Branch 8 (46→47) taken 28 times.
✗ Branch 9 (46→94) not taken.
28 node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), QualType(TY_DYN), paramList, {}, node);
2298
1/2
✓ Branch 0 (52→53) taken 28 times.
✗ Branch 1 (52→115) not taken.
28 node->manifestations.at(manIdx).bodyScope = bodyScope;
2299
3/6
✓ Branch 0 (53→54) taken 28 times.
✗ Branch 1 (53→112) not taken.
✓ Branch 2 (54→55) taken 28 times.
✗ Branch 3 (54→110) not taken.
✓ Branch 4 (55→56) taken 28 times.
✗ Branch 5 (55→108) not taken.
28 node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx);
2300
2301 // Check special requirements if this is an async lambda
2302
1/2
✓ Branch 0 (59→60) taken 28 times.
✗ Branch 1 (59→115) not taken.
28 (void)checkAsyncLambdaCaptureRules(node, node->lambdaAttr);
2303
2304
2/4
✓ Branch 0 (60→61) taken 28 times.
✗ Branch 1 (60→114) not taken.
✓ Branch 2 (61→62) taken 28 times.
✗ Branch 3 (61→114) not taken.
56 return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)};
2305 28 }
2306
2307 1 std::any TypeChecker::visitLambdaExpr(LambdaExprNode *node) {
2308 // Change to function scope
2309
2/4
✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→90) not taken.
✓ Branch 2 (3→4) taken 1 times.
✗ Branch 3 (3→88) not taken.
1 Scope *bodyScope = currentScope->getChildScope(node->getScopeId());
2310
1/2
✓ Branch 0 (5→6) taken 1 times.
✗ Branch 1 (5→91) not taken.
1 ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY);
2311
2312 // Visit parameters
2313 1 QualTypeList paramTypes;
2314 1 ParamList paramList;
2315
1/2
✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→28) not taken.
1 if (node->hasParams) {
2316 // Visit param list to retrieve the param names
2317
2/4
✓ Branch 0 (7→8) taken 1 times.
✗ Branch 1 (7→94) not taken.
✓ Branch 2 (8→9) taken 1 times.
✗ Branch 3 (8→92) not taken.
1 auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst));
2318
2/2
✓ Branch 0 (25→12) taken 2 times.
✓ Branch 1 (25→26) taken 1 times.
3 for (const NamedParam &param : namedParamList) {
2319
1/2
✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→21) taken 2 times.
2 if (param.isOptional)
2320 softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters");
2321
2322
1/2
✓ Branch 0 (21→22) taken 2 times.
✗ Branch 1 (21→102) not taken.
2 paramTypes.push_back(param.qualType);
2323
1/2
✓ Branch 0 (22→23) taken 2 times.
✗ Branch 1 (22→101) not taken.
2 paramList.push_back({param.qualType, param.isOptional});
2324 }
2325 1 }
2326
2327 // Visit lambda expression
2328
2/4
✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→108) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→106) not taken.
1 const QualType returnType = std::any_cast<ExprResult>(visit(node->lambdaExpr)).type;
2329
2/8
✓ Branch 0 (31→32) taken 1 times.
✗ Branch 1 (31→145) not taken.
✗ Branch 2 (32→33) not taken.
✓ Branch 3 (32→37) taken 1 times.
✗ Branch 4 (33→34) not taken.
✗ Branch 5 (33→110) not taken.
✗ Branch 6 (34→35) not taken.
✗ Branch 7 (34→110) not taken.
1 HANDLE_UNRESOLVED_TYPE_ER(returnType)
2330
2/4
✓ Branch 0 (37→38) taken 1 times.
✗ Branch 1 (37→145) not taken.
✗ Branch 2 (38→39) not taken.
✓ Branch 3 (38→49) taken 1 times.
1 if (returnType.is(TY_DYN))
2331 SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Dyn return types are not allowed")
2332
2333 // Leave function body scope
2334
1/2
✓ Branch 0 (49→50) taken 1 times.
✗ Branch 1 (49→145) not taken.
1 scopeHandle.leaveScopeEarly();
2335
2336 // Prepare type of function
2337
2/4
✓ Branch 0 (50→51) taken 1 times.
✗ Branch 1 (50→145) not taken.
✗ Branch 2 (51→52) not taken.
✓ Branch 3 (51→53) taken 1 times.
1 const SuperType superType = returnType.is(TY_DYN) ? TY_PROCEDURE : TY_FUNCTION;
2338
1/2
✓ Branch 0 (54→55) taken 1 times.
✗ Branch 1 (54→118) not taken.
1 const QualType functionType = QualType(superType)
2339
1/2
✓ Branch 0 (55→56) taken 1 times.
✗ Branch 1 (55→118) not taken.
1 .getWithFunctionParamAndReturnTypes(returnType, paramTypes)
2340
1/2
✓ Branch 0 (57→58) taken 1 times.
✗ Branch 1 (57→118) not taken.
1 .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty());
2341
2342 // Create function object
2343
2/4
✓ Branch 0 (58→59) taken 1 times.
✗ Branch 1 (58→122) not taken.
✓ Branch 2 (59→60) taken 1 times.
✗ Branch 3 (59→120) not taken.
1 const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn();
2344
4/8
✓ Branch 0 (62→63) taken 1 times.
✗ Branch 1 (62→131) not taken.
✓ Branch 2 (63→64) taken 1 times.
✗ Branch 3 (63→128) not taken.
✓ Branch 4 (64→65) taken 1 times.
✗ Branch 5 (64→127) not taken.
✓ Branch 6 (66→67) taken 1 times.
✗ Branch 7 (66→123) not taken.
1 node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), returnType, paramList, {}, node);
2345
1/2
✓ Branch 0 (72→73) taken 1 times.
✗ Branch 1 (72→143) not taken.
1 node->manifestations.at(manIdx).bodyScope = bodyScope;
2346
3/6
✓ Branch 0 (73→74) taken 1 times.
✗ Branch 1 (73→140) not taken.
✓ Branch 2 (74→75) taken 1 times.
✗ Branch 3 (74→138) not taken.
✓ Branch 4 (75→76) taken 1 times.
✗ Branch 5 (75→136) not taken.
1 node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx);
2347
2348
2/4
✓ Branch 0 (79→80) taken 1 times.
✗ Branch 1 (79→142) not taken.
✓ Branch 2 (80→81) taken 1 times.
✗ Branch 3 (80→142) not taken.
1 return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)};
2349 1 }
2350
2351 48109 std::any TypeChecker::visitDataType(DataTypeNode *node) {
2352 // Visit base data type
2353
2/4
✓ Branch 0 (2→3) taken 48109 times.
✗ Branch 1 (2→219) not taken.
✓ Branch 2 (3→4) taken 48109 times.
✗ Branch 3 (3→217) not taken.
48109 auto type = std::any_cast<QualType>(visit(node->baseDataType));
2354
4/6
✓ Branch 0 (5→6) taken 48109 times.
✗ Branch 1 (5→321) not taken.
✓ Branch 2 (6→7) taken 3 times.
✓ Branch 3 (6→9) taken 48106 times.
✓ Branch 4 (7→8) taken 3 times.
✗ Branch 5 (7→321) not taken.
48109 HANDLE_UNRESOLVED_TYPE_QT(type)
2355
2356
1/2
✓ Branch 0 (9→10) taken 48106 times.
✗ Branch 1 (9→321) not taken.
48106 std::queue<DataTypeNode::TypeModifier> tmQueue = node->tmQueue;
2357
2/2
✓ Branch 0 (108→11) taken 12082 times.
✓ Branch 1 (108→109) taken 48098 times.
60180 while (!tmQueue.empty()) {
2358
1/2
✓ Branch 0 (12→13) taken 12082 times.
✗ Branch 1 (12→270) not taken.
12082 auto [modifierType, hasSize, hardcodedSize, sizeVarName] = tmQueue.front();
2359
2360 // Only the outermost array can have an unknown size
2361
8/10
✓ Branch 0 (13→14) taken 12082 times.
✗ Branch 1 (13→268) not taken.
✓ Branch 2 (14→15) taken 38 times.
✓ Branch 3 (14→18) taken 12044 times.
✓ Branch 4 (15→16) taken 38 times.
✗ Branch 5 (15→268) not taken.
✓ Branch 6 (16→17) taken 2 times.
✓ Branch 7 (16→18) taken 36 times.
✓ Branch 8 (19→20) taken 2 times.
✓ Branch 9 (19→30) taken 12080 times.
12082 if (type.isArray() && type.getArraySize() == ARRAY_SIZE_UNKNOWN)
2362
4/8
✓ Branch 0 (22→23) taken 2 times.
✗ Branch 1 (22→222) not taken.
✓ Branch 2 (23→24) taken 2 times.
✗ Branch 3 (23→220) not taken.
✓ Branch 4 (26→27) taken 2 times.
✗ Branch 5 (26→226) not taken.
✓ Branch 6 (27→28) taken 2 times.
✗ Branch 7 (27→226) not taken.
6 SOFT_ERROR_QT(node, ARRAY_SIZE_INVALID,
2363 "Usage of incomplete array type. Only the outermost array type may have unknown size")
2364
2365
3/4
✓ Branch 0 (30→31) taken 5239 times.
✓ Branch 1 (30→33) taken 6703 times.
✓ Branch 2 (30→35) taken 138 times.
✗ Branch 3 (30→92) not taken.
12080 switch (modifierType) {
2366 5239 case DataTypeNode::TypeModifierType::TYPE_PTR: {
2367
2/2
✓ Branch 0 (31→32) taken 5237 times.
✓ Branch 1 (31→227) taken 2 times.
5239 type = type.toPtr(node);
2368 5237 break;
2369 }
2370 6703 case DataTypeNode::TypeModifierType::TYPE_REF: {
2371
1/2
✓ Branch 0 (33→34) taken 6703 times.
✗ Branch 1 (33→228) not taken.
6703 type = type.toRef(node);
2372 6703 break;
2373 }
2374 138 case DataTypeNode::TypeModifierType::TYPE_ARRAY: {
2375 138 const std::string &varName = sizeVarName;
2376
2/2
✓ Branch 0 (36→37) taken 35 times.
✓ Branch 1 (36→78) taken 103 times.
138 if (!varName.empty()) {
2377
1/2
✓ Branch 0 (37→38) taken 35 times.
✗ Branch 1 (37→268) not taken.
35 const SymbolTableEntry *globalVar = rootScope->lookupStrict(varName);
2378
2/2
✓ Branch 0 (40→41) taken 1 times.
✓ Branch 1 (40→50) taken 34 times.
35 if (!globalVar)
2379
5/10
✓ Branch 0 (41→42) taken 1 times.
✗ Branch 1 (41→233) not taken.
✓ Branch 2 (42→43) taken 1 times.
✗ Branch 3 (42→231) not taken.
✓ Branch 4 (43→44) taken 1 times.
✗ Branch 5 (43→229) not taken.
✓ Branch 6 (46→47) taken 1 times.
✗ Branch 7 (46→235) not taken.
✓ Branch 8 (47→48) taken 1 times.
✗ Branch 9 (47→235) not taken.
1 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_VARIABLE, "Could not find global variable '" + varName + "' ")
2380
4/6
✓ Branch 0 (50→51) taken 34 times.
✗ Branch 1 (50→268) not taken.
✓ Branch 2 (51→52) taken 34 times.
✗ Branch 3 (51→268) not taken.
✓ Branch 4 (52→53) taken 1 times.
✓ Branch 5 (52→63) taken 33 times.
34 if (!globalVar->getQualType().isConst())
2381
4/8
✓ Branch 0 (55→56) taken 1 times.
✗ Branch 1 (55→238) not taken.
✓ Branch 2 (56→57) taken 1 times.
✗ Branch 3 (56→236) not taken.
✓ Branch 4 (59→60) taken 1 times.
✗ Branch 5 (59→242) not taken.
✓ Branch 6 (60→61) taken 1 times.
✗ Branch 7 (60→242) not taken.
3 SOFT_ERROR_QT(node, EXPECTED_CONST_VARIABLE, "The size of the array must be known at compile time")
2382
4/6
✓ Branch 0 (63→64) taken 33 times.
✗ Branch 1 (63→268) not taken.
✓ Branch 2 (64→65) taken 33 times.
✗ Branch 3 (64→268) not taken.
✓ Branch 4 (65→66) taken 1 times.
✓ Branch 5 (65→76) taken 32 times.
33 if (!globalVar->getQualType().is(TY_INT))
2383
4/8
✓ Branch 0 (68→69) taken 1 times.
✗ Branch 1 (68→245) not taken.
✓ Branch 2 (69→70) taken 1 times.
✗ Branch 3 (69→243) not taken.
✓ Branch 4 (72→73) taken 1 times.
✗ Branch 5 (72→249) not taken.
✓ Branch 6 (73→74) taken 1 times.
✗ Branch 7 (73→249) not taken.
3 SOFT_ERROR_QT(node, OPERATOR_WRONG_DATA_TYPE, "Expected variable of type int")
2384
1/2
✓ Branch 0 (76→77) taken 32 times.
✗ Branch 1 (76→250) not taken.
32 hardcodedSize = globalVar->declNode->getCompileTimeValue().intValue;
2385 }
2386
2387
3/4
✓ Branch 0 (78→79) taken 79 times.
✓ Branch 1 (78→90) taken 56 times.
✗ Branch 2 (79→80) not taken.
✓ Branch 3 (79→90) taken 79 times.
135 if (hasSize && hardcodedSize <= 1)
2388 SOFT_ERROR_QT(node, ARRAY_SIZE_INVALID, "The size of an array must be > 1 and explicitly stated")
2389
2/2
✓ Branch 0 (90→91) taken 134 times.
✓ Branch 1 (90→258) taken 1 times.
135 type = type.toArr(node, hardcodedSize);
2390 134 break;
2391 }
2392 default: // GCOV_EXCL_LINE
2393 throw CompilerError(UNHANDLED_BRANCH, "Modifier type fall-through"); // GCOV_EXCL_LINE
2394 }
2395 12074 tmQueue.pop();
2396
2/2
✓ Branch 0 (103→104) taken 12074 times.
✓ Branch 1 (103→106) taken 5 times.
12082 }
2397
2398 // Attach the qualifiers to the type
2399
2/2
✓ Branch 0 (109→110) taken 19600 times.
✓ Branch 1 (109→210) taken 28498 times.
48098 if (node->qualifierLst) {
2400
1/2
✓ Branch 0 (110→111) taken 19600 times.
✗ Branch 1 (110→317) not taken.
19600 const QualType baseType = type.getBase();
2401
2/2
✓ Branch 0 (207→113) taken 22376 times.
✓ Branch 1 (207→208) taken 19598 times.
41974 for (const QualifierNode *qualifier : node->qualifierLst->qualifiers) {
2402
2/2
✓ Branch 0 (114→115) taken 9247 times.
✓ Branch 1 (114→117) taken 13129 times.
22376 if (qualifier->type == QualifierNode::QualifierType::TY_CONST) {
2403 9247 type.getQualifiers().isConst = true;
2404
2/2
✓ Branch 0 (117→118) taken 2 times.
✓ Branch 1 (117→132) taken 13127 times.
13129 } else if (qualifier->type == QualifierNode::QualifierType::TY_SIGNED) {
2405
2/4
✓ Branch 0 (118→119) taken 2 times.
✗ Branch 1 (118→271) not taken.
✗ Branch 2 (119→120) not taken.
✓ Branch 3 (119→129) taken 2 times.
2 if (!baseType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BYTE, TY_CHAR, TY_GENERIC}))
2406 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "Cannot use this qualifier on type " + baseType.getName(false))
2407 2 type.getQualifiers().isSigned = true;
2408 2 type.getQualifiers().isUnsigned = false;
2409
2/2
✓ Branch 0 (132→133) taken 9127 times.
✓ Branch 1 (132→147) taken 4000 times.
13127 } else if (qualifier->type == QualifierNode::QualifierType::TY_UNSIGNED) {
2410
2/4
✓ Branch 0 (133→134) taken 9127 times.
✗ Branch 1 (133→279) not taken.
✗ Branch 2 (134→135) not taken.
✓ Branch 3 (134→144) taken 9127 times.
9127 if (!baseType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BYTE, TY_CHAR, TY_GENERIC}))
2411 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "Cannot use this qualifier on type " + baseType.getName(false))
2412 9127 type.getQualifiers().isSigned = false;
2413 9127 type.getQualifiers().isUnsigned = true;
2414
2/2
✓ Branch 0 (147→148) taken 3531 times.
✓ Branch 1 (147→162) taken 469 times.
4000 } else if (qualifier->type == QualifierNode::QualifierType::TY_HEAP) {
2415 // Heap variables can only be pointers
2416
4/6
✓ Branch 0 (148→149) taken 3531 times.
✗ Branch 1 (148→288) not taken.
✓ Branch 2 (149→150) taken 3531 times.
✗ Branch 3 (149→287) not taken.
✓ Branch 4 (150→151) taken 1 times.
✓ Branch 5 (150→160) taken 3530 times.
3531 if (!type.removeReferenceWrapper().isOneOf({TY_PTR, TY_ARRAY, TY_STRING}))
2417
5/10
✓ Branch 0 (151→152) taken 1 times.
✗ Branch 1 (151→293) not taken.
✓ Branch 2 (152→153) taken 1 times.
✗ Branch 3 (152→291) not taken.
✓ Branch 4 (153→154) taken 1 times.
✗ Branch 5 (153→289) not taken.
✓ Branch 6 (156→157) taken 1 times.
✗ Branch 7 (156→295) not taken.
✓ Branch 8 (157→158) taken 1 times.
✗ Branch 9 (157→295) not taken.
1 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT,
2418 "The heap qualifier can only be applied to symbols of pointer type, you provided " +
2419 baseType.getName(false))
2420
2421 3530 type.getQualifiers().isHeap = true;
2422
3/4
✓ Branch 0 (162→163) taken 7 times.
✓ Branch 1 (162→178) taken 462 times.
✓ Branch 2 (163→164) taken 7 times.
✗ Branch 3 (163→178) not taken.
469 } else if (qualifier->type == QualifierNode::QualifierType::TY_COMPOSITION && node->isFieldType) {
2423
3/4
✓ Branch 0 (164→165) taken 7 times.
✗ Branch 1 (164→316) not taken.
✓ Branch 2 (165→166) taken 1 times.
✓ Branch 3 (165→176) taken 6 times.
7 if (!type.is(TY_STRUCT))
2424
4/8
✓ Branch 0 (168→169) taken 1 times.
✗ Branch 1 (168→298) not taken.
✓ Branch 2 (169→170) taken 1 times.
✗ Branch 3 (169→296) not taken.
✓ Branch 4 (172→173) taken 1 times.
✗ Branch 5 (172→302) not taken.
✓ Branch 6 (173→174) taken 1 times.
✗ Branch 7 (173→302) not taken.
3 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "The compose qualifier can only be used on plain struct fields")
2425 6 type.getQualifiers().isComposition = true;
2426
4/6
✓ Branch 0 (178→179) taken 462 times.
✗ Branch 1 (178→183) not taken.
✓ Branch 2 (179→180) taken 258 times.
✓ Branch 3 (179→181) taken 204 times.
✓ Branch 4 (180→181) taken 258 times.
✗ Branch 5 (180→183) not taken.
462 } else if (qualifier->type == QualifierNode::QualifierType::TY_PUBLIC && (node->isFieldType || node->isGlobalType)) {
2427 462 type.getQualifiers().isPublic = true;
2428 } else {
2429 auto entryName = "local variable";
2430 if (node->isGlobalType)
2431 entryName = "global variable";
2432 else if (node->isFieldType)
2433 entryName = "field";
2434 else if (node->isParamType)
2435 entryName = "param";
2436 else if (node->isReturnType)
2437 entryName = "return variable";
2438 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT,
2439 "Cannot use this qualifier on a " + std::string(entryName) + " definition")
2440 }
2441 }
2442 }
2443
2444
2/4
✓ Branch 0 (210→211) taken 48096 times.
✗ Branch 1 (210→318) not taken.
✓ Branch 2 (211→212) taken 48096 times.
✗ Branch 3 (211→318) not taken.
48096 return node->setEvaluatedSymbolType(type, manIdx);
2445 48106 }
2446
2447 48109 std::any TypeChecker::visitBaseDataType(BaseDataTypeNode *node) {
2448
11/11
✓ Branch 0 (2→3) taken 206 times.
✓ Branch 1 (2→8) taken 2712 times.
✓ Branch 2 (2→13) taken 360 times.
✓ Branch 3 (2→18) taken 9995 times.
✓ Branch 4 (2→23) taken 1875 times.
✓ Branch 5 (2→28) taken 6776 times.
✓ Branch 6 (2→33) taken 6236 times.
✓ Branch 7 (2→38) taken 3271 times.
✓ Branch 8 (2→43) taken 16159 times.
✓ Branch 9 (2→55) taken 156 times.
✓ Branch 10 (2→67) taken 363 times.
48109 switch (node->type) {
2449 206 case BaseDataTypeNode::Type::TYPE_DOUBLE:
2450
3/6
✓ Branch 0 (3→4) taken 206 times.
✗ Branch 1 (3→73) not taken.
✓ Branch 2 (4→5) taken 206 times.
✗ Branch 3 (4→73) not taken.
✓ Branch 4 (5→6) taken 206 times.
✗ Branch 5 (5→73) not taken.
206 return node->setEvaluatedSymbolType(QualType(TY_DOUBLE), manIdx);
2451 2712 case BaseDataTypeNode::Type::TYPE_INT:
2452
3/6
✓ Branch 0 (8→9) taken 2712 times.
✗ Branch 1 (8→75) not taken.
✓ Branch 2 (9→10) taken 2712 times.
✗ Branch 3 (9→75) not taken.
✓ Branch 4 (10→11) taken 2712 times.
✗ Branch 5 (10→75) not taken.
2712 return node->setEvaluatedSymbolType(QualType(TY_INT), manIdx);
2453 360 case BaseDataTypeNode::Type::TYPE_SHORT:
2454
3/6
✓ Branch 0 (13→14) taken 360 times.
✗ Branch 1 (13→77) not taken.
✓ Branch 2 (14→15) taken 360 times.
✗ Branch 3 (14→77) not taken.
✓ Branch 4 (15→16) taken 360 times.
✗ Branch 5 (15→77) not taken.
360 return node->setEvaluatedSymbolType(QualType(TY_SHORT), manIdx);
2455 9995 case BaseDataTypeNode::Type::TYPE_LONG:
2456
3/6
✓ Branch 0 (18→19) taken 9995 times.
✗ Branch 1 (18→79) not taken.
✓ Branch 2 (19→20) taken 9995 times.
✗ Branch 3 (19→79) not taken.
✓ Branch 4 (20→21) taken 9995 times.
✗ Branch 5 (20→79) not taken.
9995 return node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx);
2457 1875 case BaseDataTypeNode::Type::TYPE_BYTE:
2458
3/6
✓ Branch 0 (23→24) taken 1875 times.
✗ Branch 1 (23→81) not taken.
✓ Branch 2 (24→25) taken 1875 times.
✗ Branch 3 (24→81) not taken.
✓ Branch 4 (25→26) taken 1875 times.
✗ Branch 5 (25→81) not taken.
1875 return node->setEvaluatedSymbolType(QualType(TY_BYTE), manIdx);
2459 6776 case BaseDataTypeNode::Type::TYPE_CHAR:
2460
3/6
✓ Branch 0 (28→29) taken 6776 times.
✗ Branch 1 (28→83) not taken.
✓ Branch 2 (29→30) taken 6776 times.
✗ Branch 3 (29→83) not taken.
✓ Branch 4 (30→31) taken 6776 times.
✗ Branch 5 (30→83) not taken.
6776 return node->setEvaluatedSymbolType(QualType(TY_CHAR), manIdx);
2461 6236 case BaseDataTypeNode::Type::TYPE_STRING:
2462
3/6
✓ Branch 0 (33→34) taken 6236 times.
✗ Branch 1 (33→85) not taken.
✓ Branch 2 (34→35) taken 6236 times.
✗ Branch 3 (34→85) not taken.
✓ Branch 4 (35→36) taken 6236 times.
✗ Branch 5 (35→85) not taken.
6236 return node->setEvaluatedSymbolType(QualType(TY_STRING), manIdx);
2463 3271 case BaseDataTypeNode::Type::TYPE_BOOL:
2464
3/6
✓ Branch 0 (38→39) taken 3271 times.
✗ Branch 1 (38→87) not taken.
✓ Branch 2 (39→40) taken 3271 times.
✗ Branch 3 (39→87) not taken.
✓ Branch 4 (40→41) taken 3271 times.
✗ Branch 5 (40→87) not taken.
3271 return node->setEvaluatedSymbolType(QualType(TY_BOOL), manIdx);
2465 16159 case BaseDataTypeNode::Type::TYPE_CUSTOM: {
2466
2/4
✓ Branch 0 (43→44) taken 16159 times.
✗ Branch 1 (43→91) not taken.
✓ Branch 2 (44→45) taken 16159 times.
✗ Branch 3 (44→89) not taken.
16159 const auto customType = std::any_cast<QualType>(visit(node->customDataType));
2467
4/6
✓ Branch 0 (46→47) taken 16159 times.
✗ Branch 1 (46→93) not taken.
✓ Branch 2 (47→48) taken 3 times.
✓ Branch 3 (47→50) taken 16156 times.
✓ Branch 4 (48→49) taken 3 times.
✗ Branch 5 (48→93) not taken.
16159 HANDLE_UNRESOLVED_TYPE_QT(customType)
2468
2/4
✓ Branch 0 (50→51) taken 16156 times.
✗ Branch 1 (50→92) not taken.
✓ Branch 2 (51→52) taken 16156 times.
✗ Branch 3 (51→92) not taken.
16156 return node->setEvaluatedSymbolType(customType, manIdx);
2469 }
2470 156 case BaseDataTypeNode::Type::TYPE_FUNCTION: {
2471
2/4
✓ Branch 0 (55→56) taken 156 times.
✗ Branch 1 (55→96) not taken.
✓ Branch 2 (56→57) taken 156 times.
✗ Branch 3 (56→94) not taken.
156 const auto functionType = std::any_cast<QualType>(visit(node->functionDataType));
2472
2/6
✓ Branch 0 (58→59) taken 156 times.
✗ Branch 1 (58→98) not taken.
✗ Branch 2 (59→60) not taken.
✓ Branch 3 (59→62) taken 156 times.
✗ Branch 4 (60→61) not taken.
✗ Branch 5 (60→98) not taken.
156 HANDLE_UNRESOLVED_TYPE_QT(functionType)
2473
2/4
✓ Branch 0 (62→63) taken 156 times.
✗ Branch 1 (62→97) not taken.
✓ Branch 2 (63→64) taken 156 times.
✗ Branch 3 (63→97) not taken.
156 return node->setEvaluatedSymbolType(functionType, manIdx);
2474 }
2475 363 default:
2476
3/6
✓ Branch 0 (67→68) taken 363 times.
✗ Branch 1 (67→99) not taken.
✓ Branch 2 (68→69) taken 363 times.
✗ Branch 3 (68→99) not taken.
✓ Branch 4 (69→70) taken 363 times.
✗ Branch 5 (69→99) not taken.
363 return node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx);
2477 }
2478 }
2479
2480 16159 std::any TypeChecker::visitCustomDataType(CustomDataTypeNode *node) {
2481 // It is a struct type -> get the access scope
2482
2/2
✓ Branch 0 (2→3) taken 4575 times.
✓ Branch 1 (2→4) taken 11584 times.
16159 Scope *localAccessScope = accessScope ? accessScope : currentScope;
2483
2484
1/2
✓ Branch 0 (6→7) taken 16159 times.
✗ Branch 1 (6→276) not taken.
16159 const std::string firstFragment = node->typeNameFragments.front();
2485
2486 // Check this type requires a runtime module
2487
2/2
✓ Branch 0 (8→9) taken 16133 times.
✓ Branch 1 (8→26) taken 26 times.
16159 if (node->typeNameFragments.size() == 1)
2488
2/2
✓ Branch 0 (24→11) taken 48399 times.
✓ Branch 1 (24→25) taken 16133 times.
64532 for (const auto &[typeName, runtimeModule] : TYPE_NAME_TO_RT_MODULE_MAPPING)
2489
8/10
✓ Branch 0 (14→15) taken 48399 times.
✗ Branch 1 (14→212) not taken.
✓ Branch 2 (15→16) taken 4634 times.
✓ Branch 3 (15→19) taken 43765 times.
✓ Branch 4 (16→17) taken 4634 times.
✗ Branch 5 (16→212) not taken.
✓ Branch 6 (17→18) taken 1055 times.
✓ Branch 7 (17→19) taken 3579 times.
✓ Branch 8 (20→21) taken 1055 times.
✓ Branch 9 (20→22) taken 47344 times.
48399 if (firstFragment == typeName && !sourceFile->isRT(runtimeModule))
2490
1/2
✓ Branch 0 (21→22) taken 1055 times.
✗ Branch 1 (21→212) not taken.
1055 sourceFile->requestRuntimeModule(runtimeModule);
2491
2492 // Check if it is a generic type
2493 16159 bool isImported = node->typeNameFragments.size() > 1;
2494
1/2
✓ Branch 0 (27→28) taken 16159 times.
✗ Branch 1 (27→274) not taken.
16159 const QualType *genericType = rootScope->lookupGenericType(firstFragment);
2495
4/4
✓ Branch 0 (28→29) taken 16133 times.
✓ Branch 1 (28→49) taken 26 times.
✓ Branch 2 (29→30) taken 7203 times.
✓ Branch 3 (29→49) taken 8930 times.
16159 if (!isImported && genericType) {
2496 // Take the concrete replacement type for the name of this generic type if available
2497 7203 QualType symbolType = *genericType;
2498
3/4
✓ Branch 0 (30→31) taken 7203 times.
✗ Branch 1 (30→214) not taken.
✓ Branch 2 (31→32) taken 1777 times.
✓ Branch 3 (31→34) taken 5426 times.
7203 if (typeMapping.contains(firstFragment))
2499
1/2
✓ Branch 0 (32→33) taken 1777 times.
✗ Branch 1 (32→214) not taken.
1777 symbolType = typeMapping.at(firstFragment);
2500
2501 // Check if the replacement is a String type
2502
9/12
✓ Branch 0 (34→35) taken 7203 times.
✗ Branch 1 (34→42) not taken.
✓ Branch 2 (35→36) taken 7203 times.
✗ Branch 3 (35→214) not taken.
✓ Branch 4 (36→37) taken 187 times.
✓ Branch 5 (36→42) taken 7016 times.
✓ Branch 6 (37→38) taken 187 times.
✗ Branch 7 (37→214) not taken.
✓ Branch 8 (40→41) taken 166 times.
✓ Branch 9 (40→42) taken 21 times.
✓ Branch 10 (43→44) taken 166 times.
✓ Branch 11 (43→45) taken 7037 times.
7390 if (!isImported && symbolType.isStringObj() && !sourceFile->isStringRT())
2503
1/2
✓ Branch 0 (44→45) taken 166 times.
✗ Branch 1 (44→214) not taken.
166 sourceFile->requestRuntimeModule(STRING_RT);
2504
2505
2/4
✓ Branch 0 (45→46) taken 7203 times.
✗ Branch 1 (45→213) not taken.
✓ Branch 2 (46→47) taken 7203 times.
✗ Branch 3 (46→213) not taken.
7203 return node->setEvaluatedSymbolType(symbolType, manIdx);
2506 }
2507
2508 // Check if the type exists in the exported names registry
2509
1/2
✓ Branch 0 (49→50) taken 8956 times.
✗ Branch 1 (49→274) not taken.
8956 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqTypeName);
2510
2/2
✓ Branch 0 (50→51) taken 2 times.
✓ Branch 1 (50→60) taken 8954 times.
8956 if (!registryEntry)
2511
5/10
✓ Branch 0 (51→52) taken 2 times.
✗ Branch 1 (51→219) not taken.
✓ Branch 2 (52→53) taken 2 times.
✗ Branch 3 (52→217) not taken.
✓ Branch 4 (53→54) taken 2 times.
✗ Branch 5 (53→215) not taken.
✓ Branch 6 (56→57) taken 2 times.
✗ Branch 7 (56→221) not taken.
✓ Branch 8 (57→58) taken 2 times.
✗ Branch 9 (57→221) not taken.
2 SOFT_ERROR_QT(node, UNKNOWN_DATATYPE, "Unknown datatype '" + node->fqTypeName + "'")
2512
2/4
✓ Branch 0 (60→61) taken 8954 times.
✗ Branch 1 (60→63) not taken.
✓ Branch 2 (61→62) taken 8954 times.
✗ Branch 3 (61→63) not taken.
8954 assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr);
2513 8954 SymbolTableEntry *entry = registryEntry->targetEntry;
2514
1/2
✗ Branch 0 (64→65) not taken.
✓ Branch 1 (64→66) taken 8954 times.
8954 assert(entry != nullptr);
2515 8954 entry->used = true;
2516 8954 localAccessScope = registryEntry->targetScope->parent;
2517
2518 // Get struct type
2519
1/2
✓ Branch 0 (66→67) taken 8954 times.
✗ Branch 1 (66→274) not taken.
8954 QualType entryType = entry->getQualType();
2520
2521 // Enums can early-return
2522
3/4
✓ Branch 0 (67→68) taken 8954 times.
✗ Branch 1 (67→274) not taken.
✓ Branch 2 (68→69) taken 112 times.
✓ Branch 3 (68→73) taken 8842 times.
8954 if (entryType.is(TY_ENUM))
2523
2/4
✓ Branch 0 (69→70) taken 112 times.
✗ Branch 1 (69→222) not taken.
✓ Branch 2 (70→71) taken 112 times.
✗ Branch 3 (70→222) not taken.
224 return QualType(TY_INT);
2524
2525
3/4
✓ Branch 0 (73→74) taken 8842 times.
✗ Branch 1 (73→223) not taken.
✓ Branch 2 (74→75) taken 7992 times.
✓ Branch 3 (74→177) taken 850 times.
8842 if (entryType.isOneOf({TY_STRUCT, TY_INTERFACE})) {
2526
2/4
✓ Branch 0 (75→76) taken 7992 times.
✗ Branch 1 (75→77) not taken.
✗ Branch 2 (78→79) not taken.
✓ Branch 3 (78→80) taken 7992 times.
7992 assert(dynamic_cast<DataTypeNode *>(node->parent->parent) != nullptr);
2527
2528 // Collect the concrete template types
2529 7992 bool allTemplateTypesConcrete = true;
2530 7992 QualTypeList templateTypes;
2531
2/2
✓ Branch 0 (80→81) taken 1919 times.
✓ Branch 1 (80→113) taken 6073 times.
7992 if (node->templateTypeLst) {
2532
1/2
✗ Branch 0 (81→82) not taken.
✓ Branch 1 (81→83) taken 1919 times.
1919 assert(localAccessScope != nullptr);
2533
1/2
✓ Branch 0 (83→84) taken 1919 times.
✗ Branch 1 (83→254) not taken.
1919 isImported = localAccessScope->isImportedBy(rootScope);
2534
2535
1/2
✓ Branch 0 (85→86) taken 1919 times.
✗ Branch 1 (85→254) not taken.
1919 templateTypes.reserve(node->templateTypeLst->dataTypes.size());
2536
2/2
✓ Branch 0 (110→88) taken 2502 times.
✓ Branch 1 (110→111) taken 1919 times.
4421 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
2537
2/4
✓ Branch 0 (89→90) taken 2502 times.
✗ Branch 1 (89→226) not taken.
✓ Branch 2 (90→91) taken 2502 times.
✗ Branch 3 (90→224) not taken.
2502 auto templateType = std::any_cast<QualType>(visit(dataType));
2538
2/6
✓ Branch 0 (92→93) taken 2502 times.
✗ Branch 1 (92→228) not taken.
✗ Branch 2 (93→94) not taken.
✓ Branch 3 (93→96) taken 2502 times.
✗ Branch 4 (94→95) not taken.
✗ Branch 5 (94→228) not taken.
2502 HANDLE_UNRESOLVED_TYPE_QT(templateType)
2539
2/4
✓ Branch 0 (96→97) taken 2502 times.
✗ Branch 1 (96→228) not taken.
✗ Branch 2 (97→98) not taken.
✓ Branch 3 (97→99) taken 2502 times.
2502 if (entryType.is(TY_GENERIC)) {
2540 allTemplateTypesConcrete = false;
2541
2/2
✓ Branch 0 (99→100) taken 908 times.
✓ Branch 1 (99→106) taken 1594 times.
2502 } else if (isImported) {
2542 // Introduce the local type to the imported source file
2543
1/2
✓ Branch 0 (100→101) taken 908 times.
✗ Branch 1 (100→227) not taken.
908 [[maybe_unused]] QualType importedType = mapLocalTypeToImportedScopeType(localAccessScope, templateType);
2544
3/6
✓ Branch 0 (101→102) taken 908 times.
✗ Branch 1 (101→227) not taken.
✓ Branch 2 (102→103) taken 908 times.
✗ Branch 3 (102→227) not taken.
✗ Branch 4 (103→104) not taken.
✓ Branch 5 (103→105) taken 908 times.
908 assert(importedType.is(templateType.getSuperType()));
2545 }
2546
1/2
✓ Branch 0 (106→107) taken 2502 times.
✗ Branch 1 (106→228) not taken.
2502 templateTypes.push_back(templateType);
2547 }
2548
1/2
✓ Branch 0 (111→112) taken 1919 times.
✗ Branch 1 (111→230) not taken.
1919 entryType = entryType.getWithTemplateTypes(templateTypes);
2549 }
2550
2551 // Check if struct is defined before the current code location, if defined in the same source file
2552 7992 const CodeLoc &declCodeLoc = entry->declNode->codeLoc;
2553 7992 const CodeLoc &codeLoc = node->codeLoc;
2554
6/6
✓ Branch 0 (114→115) taken 6209 times.
✓ Branch 1 (114→122) taken 1783 times.
✓ Branch 2 (120→121) taken 1 times.
✓ Branch 3 (120→122) taken 6208 times.
✓ Branch 4 (123→124) taken 1 times.
✓ Branch 5 (123→149) taken 7991 times.
14201 if (declCodeLoc.sourceFile->filePath == codeLoc.sourceFile->filePath && declCodeLoc > codeLoc) {
2555
2/4
✓ Branch 0 (124→125) taken 1 times.
✗ Branch 1 (124→254) not taken.
✓ Branch 2 (125→126) taken 1 times.
✗ Branch 3 (125→136) not taken.
1 if (entryType.is(TY_STRUCT)) {
2556
4/8
✓ Branch 0 (128→129) taken 1 times.
✗ Branch 1 (128→233) not taken.
✓ Branch 2 (129→130) taken 1 times.
✗ Branch 3 (129→231) not taken.
✓ Branch 4 (132→133) taken 1 times.
✗ Branch 5 (132→237) not taken.
✓ Branch 6 (133→134) taken 1 times.
✗ Branch 7 (133→237) not taken.
3 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_STRUCT, "Structs must be defined before usage")
2557 } else {
2558 assert(entryType.is(TY_INTERFACE));
2559 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_INTERFACE, "Interfaces must be defined before usage")
2560 }
2561 }
2562
2563
1/2
✓ Branch 0 (149→150) taken 7991 times.
✗ Branch 1 (149→171) not taken.
7991 if (allTemplateTypesConcrete) { // Only do the next step, if we have concrete template types
2564 // Set the struct/interface instance to used, if found
2565 // Here, it is allowed to accept, that the struct/interface cannot be found, because there are self-referencing ones
2566
3/4
✓ Branch 0 (150→151) taken 7991 times.
✗ Branch 1 (150→254) not taken.
✓ Branch 2 (151→152) taken 7853 times.
✓ Branch 3 (151→160) taken 138 times.
7991 if (entryType.is(TY_STRUCT)) {
2567
1/2
✓ Branch 0 (153→154) taken 7853 times.
✗ Branch 1 (153→248) not taken.
7853 const std::string structName = node->typeNameFragments.back();
2568
3/4
✓ Branch 0 (154→155) taken 7853 times.
✗ Branch 1 (154→246) not taken.
✓ Branch 2 (155→156) taken 7819 times.
✓ Branch 3 (155→158) taken 34 times.
7853 if (Struct *spiceStruct = StructManager::match(localAccessScope, structName, templateTypes, node))
2569
1/2
✓ Branch 0 (156→157) taken 7819 times.
✗ Branch 1 (156→245) not taken.
7819 entryType = entryType.getWithBodyScope(spiceStruct->scope);
2570 7853 } else {
2571
2/4
✓ Branch 0 (160→161) taken 138 times.
✗ Branch 1 (160→252) not taken.
✗ Branch 2 (161→162) not taken.
✓ Branch 3 (161→163) taken 138 times.
138 assert(entryType.is(TY_INTERFACE));
2572
1/2
✓ Branch 0 (164→165) taken 138 times.
✗ Branch 1 (164→252) not taken.
138 const std::string interfaceName = node->typeNameFragments.back();
2573
2/4
✓ Branch 0 (165→166) taken 138 times.
✗ Branch 1 (165→250) not taken.
✓ Branch 2 (166→167) taken 138 times.
✗ Branch 3 (166→169) not taken.
138 if (const Interface *spiceInterface = InterfaceManager::match(localAccessScope, interfaceName, templateTypes, node))
2574
1/2
✓ Branch 0 (167→168) taken 138 times.
✗ Branch 1 (167→249) not taken.
138 entryType = entryType.getWithBodyScope(spiceInterface->scope);
2575 138 }
2576 }
2577
2578
2/4
✓ Branch 0 (171→172) taken 7991 times.
✗ Branch 1 (171→253) not taken.
✓ Branch 2 (172→173) taken 7991 times.
✗ Branch 3 (172→253) not taken.
7991 return node->setEvaluatedSymbolType(entryType, manIdx);
2579 7992 }
2580
2581
2/4
✓ Branch 0 (177→178) taken 850 times.
✗ Branch 1 (177→274) not taken.
✓ Branch 2 (178→179) taken 850 times.
✗ Branch 3 (178→191) not taken.
850 if (entryType.is(TY_ALIAS)) {
2582 // Get type of aliased type container entry
2583
1/2
✓ Branch 0 (179→180) taken 850 times.
✗ Branch 1 (179→260) not taken.
850 const std::string aliasedContainerEntryName = entry->name + ALIAS_CONTAINER_SUFFIX;
2584
1/2
✓ Branch 0 (180→181) taken 850 times.
✗ Branch 1 (180→258) not taken.
850 SymbolTableEntry *aliasedTypeContainerEntry = entry->scope->lookupStrict(aliasedContainerEntryName);
2585
1/2
✗ Branch 0 (183→184) not taken.
✓ Branch 1 (183→185) taken 850 times.
850 assert(aliasedTypeContainerEntry != nullptr);
2586
3/6
✓ Branch 0 (185→186) taken 850 times.
✗ Branch 1 (185→257) not taken.
✓ Branch 2 (186→187) taken 850 times.
✗ Branch 3 (186→257) not taken.
✓ Branch 4 (187→188) taken 850 times.
✗ Branch 5 (187→257) not taken.
850 return node->setEvaluatedSymbolType(aliasedTypeContainerEntry->getQualType(), manIdx);
2587 850 }
2588
2589 const bool isInvalid = entryType.is(TY_INVALID);
2590 SOFT_ERROR_QT(node, EXPECTED_TYPE, isInvalid ? "Used type before declared" : "Expected type, but got " + entryType.getName())
2591 16159 }
2592
2593 156 std::any TypeChecker::visitFunctionDataType(FunctionDataTypeNode *node) {
2594 // Visit return type
2595
1/2
✓ Branch 0 (2→3) taken 156 times.
✗ Branch 1 (2→72) not taken.
156 QualType returnType(TY_DYN);
2596
2/2
✓ Branch 0 (3→4) taken 29 times.
✓ Branch 1 (3→23) taken 127 times.
156 if (node->isFunction) {
2597
2/4
✓ Branch 0 (4→5) taken 29 times.
✗ Branch 1 (4→54) not taken.
✓ Branch 2 (5→6) taken 29 times.
✗ Branch 3 (5→52) not taken.
29 returnType = std::any_cast<QualType>(visit(node->returnType));
2598
2/6
✓ Branch 0 (7→8) taken 29 times.
✗ Branch 1 (7→72) not taken.
✗ Branch 2 (8→9) not taken.
✓ Branch 3 (8→11) taken 29 times.
✗ Branch 4 (9→10) not taken.
✗ Branch 5 (9→72) not taken.
29 HANDLE_UNRESOLVED_TYPE_QT(returnType)
2599
2/4
✓ Branch 0 (11→12) taken 29 times.
✗ Branch 1 (11→72) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→23) taken 29 times.
29 if (returnType.is(TY_DYN))
2600 SOFT_ERROR_ER(node->returnType, UNEXPECTED_DYN_TYPE, "Function types cannot have return type dyn")
2601 }
2602
2603 // Visit param types
2604 156 QualTypeList paramTypes;
2605
2/2
✓ Branch 0 (23→24) taken 111 times.
✓ Branch 1 (23→40) taken 45 times.
156 if (const TypeLstNode *paramTypeListNode = node->paramTypeLst; paramTypeListNode != nullptr) {
2606
2/2
✓ Branch 0 (38→26) taken 124 times.
✓ Branch 1 (38→39) taken 111 times.
235 for (DataTypeNode *paramTypeNode : paramTypeListNode->dataTypes) {
2607
2/4
✓ Branch 0 (27→28) taken 124 times.
✗ Branch 1 (27→65) not taken.
✓ Branch 2 (28→29) taken 124 times.
✗ Branch 3 (28→63) not taken.
124 auto paramType = std::any_cast<QualType>(visit(paramTypeNode));
2608
2/6
✓ Branch 0 (30→31) taken 124 times.
✗ Branch 1 (30→66) not taken.
✗ Branch 2 (31→32) not taken.
✓ Branch 3 (31→34) taken 124 times.
✗ Branch 4 (32→33) not taken.
✗ Branch 5 (32→66) not taken.
124 HANDLE_UNRESOLVED_TYPE_QT(returnType)
2609
1/2
✓ Branch 0 (34→35) taken 124 times.
✗ Branch 1 (34→66) not taken.
124 paramTypes.push_back(paramType);
2610 }
2611 }
2612
2613 // Build function type
2614
2/2
✓ Branch 0 (40→41) taken 29 times.
✓ Branch 1 (40→42) taken 127 times.
156 const SuperType superType = node->isFunction ? TY_FUNCTION : TY_PROCEDURE;
2615
2/4
✓ Branch 0 (43→44) taken 156 times.
✗ Branch 1 (43→68) not taken.
✓ Branch 2 (44→45) taken 156 times.
✗ Branch 3 (44→68) not taken.
156 const QualType functionType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
2616
2617
2/4
✓ Branch 0 (45→46) taken 156 times.
✗ Branch 1 (45→69) not taken.
✓ Branch 2 (46→47) taken 156 times.
✗ Branch 3 (46→69) not taken.
156 return node->setEvaluatedSymbolType(functionType, manIdx);
2618 156 }
2619
2620 /**
2621 * Check if the capture rules for async lambdas are enforced if the async attribute is set
2622 *
2623 * Only one capture with pointer type, pass-by-val is allowed, since only then we can store it in the second field of the
2624 * fat pointer and can ensure, that no stack variable is referenced inside the lambda.
2625 *
2626 * @param node Lambda base node
2627 * @param attrs Lambda attributes
2628 * @return False if the rules are violated, true otherwise
2629 */
2630 37 bool TypeChecker::checkAsyncLambdaCaptureRules(const LambdaBaseNode *node, const LambdaAttrNode *attrs) const {
2631 // If the async attribute is not set, we can return early
2632
18/32
✓ Branch 0 (2→3) taken 16 times.
✓ Branch 1 (2→13) taken 21 times.
✓ Branch 2 (5→6) taken 16 times.
✗ Branch 3 (5→53) not taken.
✓ Branch 4 (6→7) taken 16 times.
✗ Branch 5 (6→53) not taken.
✓ Branch 6 (7→8) taken 16 times.
✗ Branch 7 (7→13) not taken.
✓ Branch 8 (10→11) taken 16 times.
✗ Branch 9 (10→53) not taken.
✓ Branch 10 (11→12) taken 16 times.
✗ Branch 11 (11→53) not taken.
✗ Branch 12 (12→13) not taken.
✓ Branch 13 (12→14) taken 16 times.
✓ Branch 14 (15→16) taken 16 times.
✓ Branch 15 (15→17) taken 21 times.
✓ Branch 16 (17→18) taken 16 times.
✓ Branch 17 (17→20) taken 21 times.
✓ Branch 18 (20→21) taken 16 times.
✓ Branch 19 (20→22) taken 21 times.
✓ Branch 20 (22→23) taken 16 times.
✓ Branch 21 (22→25) taken 21 times.
✓ Branch 22 (25→26) taken 21 times.
✓ Branch 23 (25→27) taken 16 times.
✗ Branch 24 (53→54) not taken.
✗ Branch 25 (53→55) not taken.
✗ Branch 26 (57→58) not taken.
✗ Branch 27 (57→60) not taken.
✗ Branch 28 (62→63) not taken.
✗ Branch 29 (62→64) not taken.
✗ Branch 30 (66→67) not taken.
✗ Branch 31 (66→69) not taken.
101 if (!attrs || !attrs->attrLst->hasAttr(ATTR_ASYNC) || !attrs->attrLst->getAttrValueByName(ATTR_ASYNC)->boolValue)
2633 21 return true; // Not violated
2634
2635 // If we don't have any captures, we can return early
2636 16 const CaptureMap &captures = node->bodyScope->symbolTable.captures;
2637
2/2
✓ Branch 0 (28→29) taken 10 times.
✓ Branch 1 (28→30) taken 6 times.
16 if (captures.empty())
2638 10 return true; // Not violated
2639
2640 // Check for the capture rules
2641 6 if (const Capture &capture = captures.begin()->second;
2642
8/8
✓ Branch 0 (33→34) taken 4 times.
✓ Branch 1 (33→39) taken 2 times.
✓ Branch 2 (36→37) taken 2 times.
✓ Branch 3 (36→39) taken 2 times.
✓ Branch 4 (38→39) taken 1 times.
✓ Branch 5 (38→40) taken 1 times.
✓ Branch 6 (41→42) taken 5 times.
✓ Branch 7 (41→51) taken 1 times.
6 captures.size() > 1 || !capture.capturedSymbol->getQualType().isPtr() || capture.getMode() != BY_VALUE) {
2643 5 const auto warningMessage =
2644 "Async lambdas can only capture one pointer by value without storing captures in the caller stack frame, which can lead "
2645 "to bugs due to references, outliving the validity scope of the referenced variable.";
2646
2/4
✓ Branch 0 (44→45) taken 5 times.
✗ Branch 1 (44→73) not taken.
✓ Branch 2 (45→46) taken 5 times.
✗ Branch 3 (45→71) not taken.
5 const CompilerWarning warning(node->codeLoc, ASYNC_LAMBDA_CAPTURE_RULE_VIOLATION, warningMessage);
2647
1/2
✓ Branch 0 (48→49) taken 5 times.
✗ Branch 1 (48→77) not taken.
5 currentScope->sourceFile->compilerOutput.warnings.push_back(warning);
2648 5 }
2649
2650 6 return false; // Violated
2651 }
2652
2653 32 Function *TypeChecker::matchCopyCtor(const QualType &thisType, const ASTNode *node) {
2654
1/2
✓ Branch 0 (2→3) taken 32 times.
✗ Branch 1 (2→40) not taken.
32 Scope *matchScope = thisType.getBodyScope();
2655
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 32 times.
32 assert(matchScope != nullptr);
2656
2/4
✓ Branch 0 (5→6) taken 32 times.
✗ Branch 1 (5→27) not taken.
✓ Branch 2 (9→10) taken 32 times.
✗ Branch 3 (9→23) not taken.
64 const ArgList args = {{thisType.toConstRef(node), false}};
2657
2/4
✓ Branch 0 (14→15) taken 32 times.
✗ Branch 1 (14→31) not taken.
✓ Branch 2 (15→16) taken 32 times.
✗ Branch 3 (15→29) not taken.
128 return FunctionManager::match(this, matchScope, CTOR_FUNCTION_NAME, thisType, args, {}, true, node);
2658 32 }
2659
2660 109632 QualType TypeChecker::mapLocalTypeToImportedScopeType(const Scope *targetScope, const QualType &symbolType) const {
2661 // Skip all types, except structs
2662
3/4
✓ Branch 0 (2→3) taken 109632 times.
✗ Branch 1 (2→50) not taken.
✓ Branch 2 (3→4) taken 98798 times.
✓ Branch 3 (3→5) taken 10834 times.
109632 if (!symbolType.isBase(TY_STRUCT))
2663 98798 return symbolType;
2664
2665 // If the target scope is in the current source file, we can return the symbol type as is
2666 10834 SourceFile *targetSourceFile = targetScope->sourceFile;
2667
2/2
✓ Branch 0 (5→6) taken 4820 times.
✓ Branch 1 (5→7) taken 6014 times.
10834 if (targetSourceFile == sourceFile)
2668 4820 return symbolType;
2669
2670 // Match the scope of the symbol type against all scopes in the name registry of the target source file
2671
5/8
✓ Branch 0 (7→8) taken 6014 times.
✗ Branch 1 (7→46) not taken.
✓ Branch 2 (8→9) taken 6014 times.
✗ Branch 3 (8→46) not taken.
✓ Branch 4 (9→10) taken 6014 times.
✗ Branch 5 (9→46) not taken.
✓ Branch 6 (33→11) taken 264936 times.
✓ Branch 7 (33→34) taken 213 times.
265149 for (const auto &entry : targetSourceFile->exportedNameRegistry | std::views::values)
2672
7/10
✓ Branch 0 (12→13) taken 264936 times.
✗ Branch 1 (12→17) not taken.
✓ Branch 2 (13→14) taken 264936 times.
✗ Branch 3 (13→46) not taken.
✓ Branch 4 (14→15) taken 264936 times.
✗ Branch 5 (14→46) not taken.
✓ Branch 6 (15→16) taken 18229 times.
✓ Branch 7 (15→17) taken 246707 times.
✓ Branch 8 (18→19) taken 18229 times.
✓ Branch 9 (18→31) taken 246707 times.
264936 if (entry.targetEntry != nullptr && entry.targetEntry->getQualType().isBase(TY_STRUCT))
2673
3/4
✓ Branch 0 (19→20) taken 18229 times.
✗ Branch 1 (19→45) not taken.
✓ Branch 2 (29→22) taken 38236 times.
✓ Branch 3 (29→30) taken 12428 times.
50664 for (const Struct *manifestation : *entry.targetEntry->declNode->getStructManifestations())
2674
4/6
✓ Branch 0 (23→24) taken 38236 times.
✗ Branch 1 (23→44) not taken.
✓ Branch 2 (24→25) taken 38236 times.
✗ Branch 3 (24→44) not taken.
✓ Branch 4 (25→26) taken 5801 times.
✓ Branch 5 (25→27) taken 32435 times.
38236 if (manifestation->scope == symbolType.getBase().getBodyScope())
2675 5801 return symbolType;
2676
2677 // The target source file does not know about the struct at all
2678 // -> show it how to find the struct
2679
3/6
✓ Branch 0 (34→35) taken 213 times.
✗ Branch 1 (34→47) not taken.
✓ Branch 2 (35→36) taken 213 times.
✗ Branch 3 (35→47) not taken.
✓ Branch 4 (36→37) taken 213 times.
✗ Branch 5 (36→47) not taken.
213 const std::string structName = symbolType.getBase().getSubType();
2680
1/2
✓ Branch 0 (37→38) taken 213 times.
✗ Branch 1 (37→48) not taken.
213 const NameRegistryEntry *origRegistryEntry = sourceFile->getNameRegistryEntry(structName);
2681
1/2
✗ Branch 0 (38→39) not taken.
✓ Branch 1 (38→40) taken 213 times.
213 assert(origRegistryEntry != nullptr);
2682 213 const uint64_t targetTypeId = origRegistryEntry->typeId;
2683 213 SymbolTableEntry *targetEntry = origRegistryEntry->targetEntry;
2684
1/2
✓ Branch 0 (40→41) taken 213 times.
✗ Branch 1 (40→48) not taken.
213 targetSourceFile->addNameRegistryEntry(structName, targetTypeId, targetEntry, origRegistryEntry->targetScope, false);
2685
2686 213 return symbolType;
2687 213 }
2688
2689 3744 QualType TypeChecker::mapImportedScopeTypeToLocalType(const Scope *sourceScope, const QualType &symbolType) const {
2690 // Skip all types, except structs
2691
3/4
✓ Branch 0 (2→3) taken 3744 times.
✗ Branch 1 (2→45) not taken.
✓ Branch 2 (3→4) taken 488 times.
✓ Branch 3 (3→5) taken 3256 times.
3744 if (!symbolType.isBase(TY_STRUCT))
2692 488 return symbolType;
2693
2694 // If the source scope is in the current source file, we can return the symbol type as is
2695 3256 const SourceFile *sourceSourceFile = sourceScope->sourceFile;
2696
2/2
✓ Branch 0 (5→6) taken 1114 times.
✓ Branch 1 (5→7) taken 2142 times.
3256 if (sourceSourceFile == sourceFile)
2697 1114 return symbolType;
2698
2699 // Match the scope of the symbol type against all scopes in the name registry of this source file
2700
1/2
✓ Branch 0 (7→8) taken 2142 times.
✗ Branch 1 (7→45) not taken.
2142 const QualType baseType = symbolType.getBase();
2701
5/8
✓ Branch 0 (8→9) taken 2142 times.
✗ Branch 1 (8→44) not taken.
✓ Branch 2 (9→10) taken 2142 times.
✗ Branch 3 (9→44) not taken.
✓ Branch 4 (10→11) taken 2142 times.
✗ Branch 5 (10→44) not taken.
✓ Branch 6 (33→12) taken 116323 times.
✓ Branch 7 (33→34) taken 44 times.
116367 for (const auto &entry : sourceFile->exportedNameRegistry | std::views::values)
2702
7/10
✓ Branch 0 (13→14) taken 116323 times.
✗ Branch 1 (13→18) not taken.
✓ Branch 2 (14→15) taken 116323 times.
✗ Branch 3 (14→44) not taken.
✓ Branch 4 (15→16) taken 116323 times.
✗ Branch 5 (15→44) not taken.
✓ Branch 6 (16→17) taken 6964 times.
✓ Branch 7 (16→18) taken 109359 times.
✓ Branch 8 (19→20) taken 6964 times.
✓ Branch 9 (19→31) taken 109359 times.
116323 if (entry.targetEntry != nullptr && entry.targetEntry->getQualType().isBase(TY_STRUCT))
2703
3/4
✓ Branch 0 (20→21) taken 6964 times.
✗ Branch 1 (20→43) not taken.
✓ Branch 2 (29→23) taken 15656 times.
✓ Branch 3 (29→30) taken 4866 times.
20522 for (const Struct *manifestation : *entry.targetEntry->declNode->getStructManifestations())
2704
3/4
✓ Branch 0 (24→25) taken 15656 times.
✗ Branch 1 (24→43) not taken.
✓ Branch 2 (25→26) taken 2098 times.
✓ Branch 3 (25→27) taken 13558 times.
15656 if (manifestation->scope == baseType.getBodyScope())
2705 2098 return symbolType;
2706
2707 // This source file does not know about the struct at all
2708 // -> show it how to find the struct
2709
2/4
✓ Branch 0 (34→35) taken 44 times.
✗ Branch 1 (34→45) not taken.
✓ Branch 2 (35→36) taken 44 times.
✗ Branch 3 (35→45) not taken.
44 const NameRegistryEntry *origRegistryEntry = sourceSourceFile->getNameRegistryEntry(baseType.getSubType());
2710
1/2
✗ Branch 0 (36→37) not taken.
✓ Branch 1 (36→38) taken 44 times.
44 assert(origRegistryEntry != nullptr);
2711 44 const uint64_t typeId = origRegistryEntry->typeId;
2712 44 SymbolTableEntry *targetEntry = origRegistryEntry->targetEntry;
2713
2/4
✓ Branch 0 (38→39) taken 44 times.
✗ Branch 1 (38→45) not taken.
✓ Branch 2 (39→40) taken 44 times.
✗ Branch 3 (39→45) not taken.
44 sourceFile->addNameRegistryEntry(baseType.getSubType(), typeId, targetEntry, origRegistryEntry->targetScope, false);
2714
2715 44 return symbolType;
2716 }
2717
2718 /**
2719 * Auto-dereference the given symbol type.
2720 * This process is NOT equivalent with getBase() because getBase() also removes e.g. array wrappers
2721 *
2722 * @param symbolType Input symbol type
2723 */
2724 19489 void TypeChecker::autoDeReference(QualType &symbolType) {
2725
6/6
✓ Branch 0 (6→7) taken 21438 times.
✓ Branch 1 (6→9) taken 14597 times.
✓ Branch 2 (8→9) taken 1949 times.
✓ Branch 3 (8→10) taken 19489 times.
✓ Branch 4 (11→3) taken 16546 times.
✓ Branch 5 (11→12) taken 19489 times.
36035 while (symbolType.isPtr() || symbolType.isRef())
2726
1/2
✓ Branch 0 (3→4) taken 16546 times.
✗ Branch 1 (3→13) not taken.
16546 symbolType = symbolType.getContained();
2727 19489 }
2728
2729 /**
2730 * Returns the operator function list for the current manifestation and the given node
2731 *
2732 * @param node Node to retrieve the op fct pointer list from
2733 * @return Op fct pointer list
2734 */
2735 743 std::vector<const Function *> &TypeChecker::getOpFctPointers(ASTNode *node) const {
2736
1/2
✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 743 times.
743 assert(node->getOpFctPointers()->size() > manIdx);
2737 743 return node->getOpFctPointers()->at(manIdx);
2738 }
2739
2740 /**
2741 * Check if a function has been type-checked already. If not, request a revisit
2742 *
2743 * @param fct Function to check
2744 */
2745 20675 void TypeChecker::requestRevisitIfRequired(const Function *fct) {
2746
4/4
✓ Branch 0 (2→3) taken 20605 times.
✓ Branch 1 (2→5) taken 70 times.
✓ Branch 2 (3→4) taken 11320 times.
✓ Branch 3 (3→5) taken 9285 times.
20675 if (fct && !fct->alreadyTypeChecked)
2747 11320 fct->entry->scope->sourceFile->reVisitRequested = true;
2748 20675 }
2749
2750 /**
2751 * Add a soft error to the error list
2752 */
2753 25 void TypeChecker::softError(const ASTNode *node, const SemanticErrorType errorType, const std::string &message) const {
2754 25 resourceManager.errorManager.addSoftError(node, errorType, message);
2755 25 }
2756
2757 } // namespace spice::compiler
2758