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 ¶m : 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 |