Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2024 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 | 4327 | TypeChecker::TypeChecker(GlobalResourceManager &resourceManager, SourceFile *sourceFile, TypeCheckerMode typeCheckerMode) | |
17 |
1/2✓ Branch 3 taken 4327 times.
✗ Branch 4 not taken.
|
4327 | : CompilerPass(resourceManager, sourceFile), typeCheckerMode(typeCheckerMode), warnings(sourceFile->compilerOutput.warnings) { |
18 | 4327 | } | |
19 | |||
20 | 4536 | std::any TypeChecker::visitEntry(EntryNode *node) { | |
21 | // Initialize | ||
22 | 4536 | currentScope = rootScope; | |
23 | |||
24 | // Initialize AST nodes with size of 1 | ||
25 | 4536 | const bool isPrepare = typeCheckerMode == TC_MODE_PRE; | |
26 |
2/2✓ Branch 0 taken 868 times.
✓ Branch 1 taken 3668 times.
|
4536 | if (isPrepare) |
27 | 868 | node->resizeToNumberOfManifestations(1); | |
28 | |||
29 | // Visit children | ||
30 |
2/2✓ Branch 1 taken 4492 times.
✓ Branch 2 taken 44 times.
|
4536 | visitChildren(node); |
31 | |||
32 | // Check which implicit structures we need for each struct, defined in this source file | ||
33 |
2/2✓ Branch 0 taken 854 times.
✓ Branch 1 taken 3638 times.
|
4492 | if (isPrepare) { |
34 |
1/2✓ Branch 1 taken 854 times.
✗ Branch 2 not taken.
|
854 | const std::vector<const Struct *> manifestations = rootScope->getAllStructManifestationsInDeclarationOrder(); |
35 |
2/2✓ Branch 5 taken 539 times.
✓ Branch 6 taken 854 times.
|
1393 | for (const Struct *manifestation : manifestations) { |
36 | // Check if we need to create a default ctor, copy ctor or dtor | ||
37 |
1/2✓ Branch 1 taken 539 times.
✗ Branch 2 not taken.
|
539 | createDefaultCtorIfRequired(*manifestation, manifestation->scope); |
38 |
1/2✓ Branch 1 taken 539 times.
✗ Branch 2 not taken.
|
539 | createDefaultCopyCtorIfRequired(*manifestation, manifestation->scope); |
39 |
1/2✓ Branch 1 taken 539 times.
✗ Branch 2 not taken.
|
539 | createDefaultDtorIfRequired(*manifestation, manifestation->scope); |
40 | } | ||
41 | 854 | } | |
42 | |||
43 |
1/2✓ Branch 1 taken 4492 times.
✗ Branch 2 not taken.
|
4492 | return nullptr; |
44 | } | ||
45 | |||
46 | 723 | std::any TypeChecker::visitMainFctDef(MainFctDefNode *node) { | |
47 |
2/2✓ Branch 0 taken 343 times.
✓ Branch 1 taken 380 times.
|
723 | if (typeCheckerMode == TC_MODE_PRE) |
48 | 343 | return visitMainFctDefPrepare(node); | |
49 | else | ||
50 | 380 | return visitMainFctDefCheck(node); | |
51 | } | ||
52 | |||
53 | 31717 | std::any TypeChecker::visitFctDef(FctDefNode *node) { | |
54 |
2/2✓ Branch 0 taken 4247 times.
✓ Branch 1 taken 27470 times.
|
31717 | if (typeCheckerMode == TC_MODE_PRE) |
55 | 4247 | return visitFctDefPrepare(node); | |
56 | else | ||
57 | 27470 | return visitFctDefCheck(node); | |
58 | } | ||
59 | |||
60 | 21261 | std::any TypeChecker::visitProcDef(ProcDefNode *node) { | |
61 |
2/2✓ Branch 0 taken 2701 times.
✓ Branch 1 taken 18560 times.
|
21261 | if (typeCheckerMode == TC_MODE_PRE) |
62 | 2701 | return visitProcDefPrepare(node); | |
63 | else | ||
64 | 18560 | return visitProcDefCheck(node); | |
65 | } | ||
66 | |||
67 | 3583 | std::any TypeChecker::visitStructDef(StructDefNode *node) { | |
68 |
2/2✓ Branch 0 taken 544 times.
✓ Branch 1 taken 3039 times.
|
3583 | if (typeCheckerMode == TC_MODE_PRE) |
69 | 544 | return visitStructDefPrepare(node); | |
70 | else | ||
71 | 3039 | return visitStructDefCheck(node); | |
72 | } | ||
73 | |||
74 | 416 | std::any TypeChecker::visitInterfaceDef(InterfaceDefNode *node) { | |
75 |
2/2✓ Branch 0 taken 74 times.
✓ Branch 1 taken 342 times.
|
416 | if (typeCheckerMode == TC_MODE_PRE) |
76 | 74 | return visitInterfaceDefPrepare(node); | |
77 |
1/2✓ Branch 1 taken 342 times.
✗ Branch 2 not taken.
|
342 | return nullptr; |
78 | } | ||
79 | |||
80 | 121 | std::any TypeChecker::visitEnumDef(EnumDefNode *node) { | |
81 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 83 times.
|
121 | if (typeCheckerMode == TC_MODE_PRE) |
82 | 38 | return visitEnumDefPrepare(node); | |
83 |
1/2✓ Branch 1 taken 83 times.
✗ Branch 2 not taken.
|
83 | return nullptr; |
84 | } | ||
85 | |||
86 | 5544 | std::any TypeChecker::visitGenericTypeDef(GenericTypeDefNode *node) { | |
87 |
2/2✓ Branch 0 taken 722 times.
✓ Branch 1 taken 4822 times.
|
5544 | if (typeCheckerMode == TC_MODE_PRE) |
88 | 722 | return visitGenericTypeDefPrepare(node); | |
89 |
1/2✓ Branch 1 taken 4822 times.
✗ Branch 2 not taken.
|
4822 | return nullptr; |
90 | } | ||
91 | |||
92 | 112 | std::any TypeChecker::visitAliasDef(AliasDefNode *node) { | |
93 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 82 times.
|
112 | if (typeCheckerMode == TC_MODE_PRE) |
94 | 30 | return visitAliasDefPrepare(node); | |
95 |
1/2✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
|
82 | return nullptr; |
96 | } | ||
97 | |||
98 | 4635 | std::any TypeChecker::visitGlobalVarDef(GlobalVarDefNode *node) { | |
99 |
2/2✓ Branch 0 taken 734 times.
✓ Branch 1 taken 3901 times.
|
4635 | if (typeCheckerMode == TC_MODE_PRE) |
100 | 734 | return visitGlobalVarDefPrepare(node); | |
101 |
1/2✓ Branch 1 taken 3901 times.
✗ Branch 2 not taken.
|
3901 | return nullptr; |
102 | } | ||
103 | |||
104 | 4461 | std::any TypeChecker::visitExtDecl(ExtDeclNode *node) { | |
105 |
2/2✓ Branch 0 taken 701 times.
✓ Branch 1 taken 3760 times.
|
4461 | if (typeCheckerMode == TC_MODE_PRE) |
106 | 701 | return visitExtDeclPrepare(node); | |
107 |
1/2✓ Branch 1 taken 3760 times.
✗ Branch 2 not taken.
|
3760 | return nullptr; |
108 | } | ||
109 | |||
110 | 1419 | std::any TypeChecker::visitImportDef(ImportDefNode *node) { | |
111 |
2/2✓ Branch 0 taken 361 times.
✓ Branch 1 taken 1058 times.
|
1419 | if (typeCheckerMode == TC_MODE_PRE) |
112 | 361 | return visitImportDefPrepare(node); | |
113 |
1/2✓ Branch 1 taken 1058 times.
✗ Branch 2 not taken.
|
1058 | return nullptr; |
114 | } | ||
115 | |||
116 | 1661 | std::any TypeChecker::visitUnsafeBlock(UnsafeBlockNode *node) { | |
117 | // Change to unsafe block body scope | ||
118 |
2/4✓ Branch 1 taken 1661 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1661 times.
✗ Branch 5 not taken.
|
1661 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::UNSAFE_BODY); |
119 | |||
120 | // Visit body | ||
121 |
2/4✓ Branch 1 taken 1661 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1661 times.
✗ Branch 5 not taken.
|
1661 | visit(node->body()); |
122 | |||
123 |
1/2✓ Branch 1 taken 1661 times.
✗ Branch 2 not taken.
|
3322 | return nullptr; |
124 | 1661 | } | |
125 | |||
126 | 1049 | std::any TypeChecker::visitForLoop(ForLoopNode *node) { | |
127 | // Change to for body scope | ||
128 |
2/4✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 5 not taken.
|
1049 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::FOR_BODY); |
129 | |||
130 | // Visit loop variable declaration | ||
131 |
2/4✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 5 not taken.
|
1049 | visit(node->initDecl()); |
132 | |||
133 | // Visit condition | ||
134 |
3/6✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1049 times.
✗ Branch 8 not taken.
|
1049 | const QualType conditionType = std::any_cast<ExprResult>(visit(node->condAssign())).type; |
135 |
2/6✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1049 | HANDLE_UNRESOLVED_TYPE_PTR(conditionType) |
136 | // Check if condition evaluates to bool | ||
137 |
3/4✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1048 times.
|
1049 | if (!conditionType.is(TY_BOOL)) |
138 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 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 |
2/4✓ Branch 1 taken 1048 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1048 times.
✗ Branch 5 not taken.
|
1048 | visit(node->incAssign()); |
142 | |||
143 | // Visit body | ||
144 |
2/4✓ Branch 1 taken 1048 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1048 times.
✗ Branch 5 not taken.
|
1048 | visit(node->body()); |
145 | |||
146 |
1/2✓ Branch 1 taken 1048 times.
✗ Branch 2 not taken.
|
1048 | return nullptr; |
147 | 1049 | } | |
148 | |||
149 | 91 | std::any TypeChecker::visitForeachLoop(ForeachLoopNode *node) { | |
150 | // Visit iterator assignment | ||
151 |
1/2✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
|
91 | AssignExprNode *iteratorNode = node->iteratorAssign(); |
152 |
2/4✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 91 times.
✗ Branch 5 not taken.
|
91 | QualType iteratorOrIterableType = std::any_cast<ExprResult>(visit(iteratorNode)).type; |
153 |
2/6✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
91 | HANDLE_UNRESOLVED_TYPE_PTR(iteratorOrIterableType) |
154 |
1/2✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
|
91 | iteratorOrIterableType = iteratorOrIterableType.removeReferenceWrapper(); |
155 | |||
156 | // Retrieve iterator type | ||
157 | 91 | QualType iteratorType = iteratorOrIterableType; | |
158 | |||
159 |
3/4✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 19 times.
|
91 | if (iteratorOrIterableType.isIterable(node)) { |
160 | 72 | const QualType &iterableType = iteratorOrIterableType; | |
161 |
3/4✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 64 times.
|
72 | if (iteratorOrIterableType.isArray()) { // Array |
162 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
16 | const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(ARRAY_ITERATOR_NAME); |
163 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
|
8 | if (!nameRegistryEntry) { |
164 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | softError(node, UNKNOWN_DATATYPE, "Forgot to import \"std/iterator/array-iterator\"?"); |
165 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 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 not taken.
✓ Branch 1 taken 7 times.
|
7 | assert(matchScope->type == ScopeType::GLOBAL); |
170 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | QualType unsignedLongType(TY_LONG); |
171 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | unsignedLongType.makeUnsigned(true); |
172 |
1/2✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
|
14 | const ArgList argTypes = {Arg(iterableType, false), Arg(unsignedLongType, false)}; |
173 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | const QualType thisType(TY_DYN); |
174 |
2/4✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 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 1 taken 64 times.
✗ Branch 2 not taken.
|
64 | Scope *matchScope = iterableType.getBodyScope(); |
177 |
2/4✓ Branch 3 taken 64 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 64 times.
✗ Branch 7 not taken.
|
192 | node->getIteratorFct = FunctionManager::match(this, matchScope, "getIterator", iterableType, {}, {}, true, iteratorNode); |
178 | } | ||
179 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 70 times.
|
71 | if (node->getIteratorFct == nullptr) |
180 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
3 | throw SemanticError(iteratorNode, INVALID_ITERATOR, "No getIterator() function found for the given iterable type"); |
181 | |||
182 | 70 | iteratorType = QualType(node->getIteratorFct->returnType); | |
183 | // Create anonymous entry for the iterator | ||
184 |
1/2✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
|
70 | currentScope->symbolTable.insertAnonymous(iteratorType, iteratorNode); |
185 | } | ||
186 | |||
187 | // Change to foreach body scope | ||
188 |
2/4✓ Branch 1 taken 89 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 89 times.
✗ Branch 5 not taken.
|
89 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::FOREACH_BODY); |
189 | |||
190 | // Check iterator type | ||
191 |
3/4✓ Branch 1 taken 89 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 88 times.
|
89 | 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 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | iteratorType.getName(false); |
195 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | softError(node->iteratorAssign(), OPERATOR_WRONG_DATA_TYPE, errMsg); |
196 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | return nullptr; |
197 | 1 | } | |
198 |
1/2✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
|
88 | const QualTypeList &iteratorTemplateTypes = iteratorType.getTemplateTypes(); |
199 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 87 times.
|
88 | if (iteratorTemplateTypes.empty()) |
200 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 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 |
1/2✓ Branch 1 taken 87 times.
✗ Branch 2 not taken.
|
87 | const bool hasIdx = node->idxVarDecl(); |
204 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 81 times.
|
87 | if (hasIdx) { |
205 | // Visit index declaration or assignment | ||
206 |
3/6✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
6 | auto indexType = std::any_cast<QualType>(visit(node->idxVarDecl())); |
207 |
2/6✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
6 | HANDLE_UNRESOLVED_TYPE_PTR(indexType) |
208 | // Check if index type is int | ||
209 |
3/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
|
6 | if (!indexType.is(TY_LONG)) |
210 |
8/16✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 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 1 taken 86 times.
✗ Branch 2 not taken.
|
86 | Scope *matchScope = iteratorType.getBodyScope(); |
216 | 86 | QualType iteratorItemType; | |
217 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 81 times.
|
86 | if (hasIdx) { |
218 |
2/4✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
|
15 | node->getIdxFct = FunctionManager::match(this, matchScope, "getIdx", iteratorType, {}, {}, false, node); |
219 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | assert(node->getIdxFct != nullptr); |
220 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | iteratorItemType = node->getIdxFct->returnType.getTemplateTypes().back(); |
221 | } else { | ||
222 |
2/4✓ Branch 3 taken 81 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 81 times.
✗ Branch 7 not taken.
|
243 | node->getFct = FunctionManager::match(this, matchScope, "get", iteratorType, {}, {}, false, node); |
223 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
|
81 | assert(node->getFct != nullptr); |
224 | 81 | iteratorItemType = node->getFct->returnType; | |
225 | } | ||
226 |
2/4✓ Branch 3 taken 86 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 86 times.
✗ Branch 7 not taken.
|
258 | node->isValidFct = FunctionManager::match(this, matchScope, "isValid", iteratorType, {}, {}, false, node); |
227 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
|
86 | assert(node->isValidFct != nullptr); |
228 |
2/4✓ Branch 3 taken 86 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 86 times.
✗ Branch 7 not taken.
|
258 | node->nextFct = FunctionManager::match(this, matchScope, "next", iteratorType, {}, {}, false, node); |
229 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
|
86 | assert(node->nextFct != nullptr); |
230 | |||
231 | // Retrieve item variable entry | ||
232 |
2/4✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 86 times.
✗ Branch 5 not taken.
|
86 | SymbolTableEntry *itemVarSymbol = currentScope->lookupStrict(node->itemVarDecl()->varName); |
233 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
|
86 | assert(itemVarSymbol != nullptr); |
234 | |||
235 | // Check type of the item | ||
236 |
3/6✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 86 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 86 times.
✗ Branch 8 not taken.
|
86 | auto itemType = std::any_cast<QualType>(visit(node->itemVarDecl())); |
237 |
2/6✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 86 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
86 | HANDLE_UNRESOLVED_TYPE_PTR(itemType) |
238 |
3/4✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 82 times.
|
86 | if (itemType.is(TY_DYN)) { // Perform type inference |
239 | // Update evaluated symbol type of the declaration data type | ||
240 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | node->itemVarDecl()->dataType()->setEvaluatedSymbolType(iteratorItemType, manIdx); |
241 | // Update item type | ||
242 | 4 | itemType = iteratorItemType; | |
243 | } else { | ||
244 | // Check item type | ||
245 | 82 | const ExprResult itemResult = {itemType, itemVarSymbol}; | |
246 | 82 | const ExprResult iteratorItemResult = {iteratorItemType, nullptr /* always a temporary */}; | |
247 |
3/4✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 81 times.
✓ Branch 5 taken 1 times.
|
82 | (void)opRuleManager.getAssignResultType(node->itemVarDecl(), itemResult, iteratorItemResult, true, false, ERROR_FOREACH_ITEM); |
248 | } | ||
249 | |||
250 | // Update type of item | ||
251 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | itemVarSymbol->updateType(itemType, true); |
252 | |||
253 | // Visit body | ||
254 |
2/4✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 85 times.
✗ Branch 5 not taken.
|
85 | visit(node->body()); |
255 | |||
256 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | return nullptr; |
257 | 89 | } | |
258 | |||
259 | 468 | std::any TypeChecker::visitWhileLoop(WhileLoopNode *node) { | |
260 | // Change to while body scope | ||
261 |
2/4✓ Branch 1 taken 468 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 468 times.
✗ Branch 5 not taken.
|
468 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::WHILE_BODY); |
262 | |||
263 | // Visit condition | ||
264 |
4/6✓ Branch 1 taken 468 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 467 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 467 times.
✗ Branch 8 not taken.
|
468 | const QualType conditionType = std::any_cast<ExprResult>(visit(node->condition())).type; |
265 |
2/6✓ Branch 1 taken 467 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 467 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
467 | HANDLE_UNRESOLVED_TYPE_PTR(conditionType) |
266 | // Check if condition evaluates to bool | ||
267 |
3/4✓ Branch 1 taken 467 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 466 times.
|
467 | if (!conditionType.is(TY_BOOL)) |
268 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 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 |
2/4✓ Branch 1 taken 466 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 466 times.
✗ Branch 5 not taken.
|
466 | visit(node->body()); |
272 | |||
273 |
1/2✓ Branch 1 taken 466 times.
✗ Branch 2 not taken.
|
466 | return nullptr; |
274 | 468 | } | |
275 | |||
276 | 9 | std::any TypeChecker::visitDoWhileLoop(DoWhileLoopNode *node) { | |
277 | // Change to while body scope | ||
278 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::WHILE_BODY); |
279 | |||
280 | // Visit body | ||
281 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | visit(node->body()); |
282 | |||
283 | // Visit condition | ||
284 |
3/6✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
|
9 | const QualType conditionType = std::any_cast<ExprResult>(visit(node->condition())).type; |
285 |
2/6✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
9 | HANDLE_UNRESOLVED_TYPE_PTR(conditionType) |
286 | // Check if condition evaluates to bool | ||
287 |
3/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 8 times.
|
9 | if (!conditionType.is(TY_BOOL)) |
288 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 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 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | return nullptr; |
291 | 9 | } | |
292 | |||
293 | 3030 | std::any TypeChecker::visitIfStmt(IfStmtNode *node) { | |
294 | // Change to then body scope | ||
295 |
2/4✓ Branch 1 taken 3030 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3030 times.
✗ Branch 5 not taken.
|
3030 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::IF_ELSE_BODY); |
296 | |||
297 | // Visit condition | ||
298 |
1/2✓ Branch 1 taken 3030 times.
✗ Branch 2 not taken.
|
3030 | AssignExprNode *condition = node->condition(); |
299 |
3/4✓ Branch 1 taken 3028 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 3028 times.
✗ Branch 5 not taken.
|
3030 | const QualType conditionType = std::any_cast<ExprResult>(visit(condition)).type; |
300 |
4/6✓ Branch 1 taken 3028 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3027 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
3028 | HANDLE_UNRESOLVED_TYPE_PTR(conditionType) |
301 | // Check if condition evaluates to bool | ||
302 |
3/4✓ Branch 1 taken 3027 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 3025 times.
|
3027 | if (!conditionType.is(TY_BOOL)) |
303 |
7/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
|
6 | SOFT_ERROR_ER(node->condition(), CONDITION_MUST_BE_BOOL, "If condition must be of type bool") |
304 | |||
305 | // Warning for bool assignment | ||
306 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3024 times.
|
3025 | if (condition->op == AssignExprNode::OP_ASSIGN) |
307 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | sourceFile->compilerOutput.warnings.emplace_back(condition->codeLoc, BOOL_ASSIGN_AS_CONDITION, |
308 | "If you want to compare the values, use '=='"); | ||
309 | |||
310 | // Visit body | ||
311 |
2/4✓ Branch 1 taken 3025 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3025 times.
✗ Branch 5 not taken.
|
3025 | visit(node->thenBody()); |
312 | |||
313 | // Leave then body scope | ||
314 |
1/2✓ Branch 1 taken 3025 times.
✗ Branch 2 not taken.
|
3025 | scopeHandle.leaveScopeEarly(); |
315 | |||
316 | // Visit else statement if existing | ||
317 |
3/4✓ Branch 1 taken 3025 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 141 times.
✓ Branch 4 taken 2884 times.
|
3025 | if (node->elseStmt()) |
318 |
2/4✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
|
141 | visit(node->elseStmt()); |
319 | |||
320 |
1/2✓ Branch 1 taken 3025 times.
✗ Branch 2 not taken.
|
3025 | return nullptr; |
321 | 3030 | } | |
322 | |||
323 | 141 | std::any TypeChecker::visitElseStmt(ElseStmtNode *node) { | |
324 | // Visit if statement in the case of an else if branch | ||
325 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 99 times.
|
141 | if (node->isElseIf) { |
326 |
2/4✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
|
42 | visit(node->ifStmt()); |
327 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | return nullptr; |
328 | } | ||
329 | |||
330 | // Change to else body scope | ||
331 |
2/4✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 99 times.
✗ Branch 5 not taken.
|
99 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::IF_ELSE_BODY); |
332 | |||
333 | // Visit body | ||
334 |
2/4✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 99 times.
✗ Branch 5 not taken.
|
99 | visit(node->body()); |
335 | |||
336 |
1/2✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
|
99 | return nullptr; |
337 | 99 | } | |
338 | |||
339 | 8 | std::any TypeChecker::visitSwitchStmt(SwitchStmtNode *node) { | |
340 | // Check expression type | ||
341 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | AssignExprNode *expr = node->assignExpr(); |
342 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | const QualType exprType = std::any_cast<ExprResult>(visit(expr)).type; |
343 |
2/6✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
8 | HANDLE_UNRESOLVED_TYPE_PTR(exprType) |
344 |
3/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 7 times.
|
8 | if (!exprType.isOneOf({TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_CHAR, TY_BOOL})) |
345 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
|
3 | SOFT_ERROR_ER(node->assignExpr(), SWITCH_EXPR_MUST_BE_PRIMITIVE, |
346 | "Switch expression must be of int, short, long, byte, char or bool type") | ||
347 | |||
348 | // Visit children | ||
349 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | visitChildren(node); |
350 | |||
351 | // Check if case constant types match switch expression type | ||
352 |
3/4✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 28 times.
✓ Branch 9 taken 5 times.
|
33 | for (const CaseBranchNode *caseBranchNode : node->caseBranches()) |
353 |
3/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 28 times.
✓ Branch 9 taken 26 times.
|
54 | for (CaseConstantNode *constantNode : caseBranchNode->caseConstants()) { |
354 |
2/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | const QualType constantType = std::any_cast<ExprResult>(visit(constantNode)).type; |
355 |
3/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 26 times.
|
28 | if (!constantType.matches(exprType, false, true, true)) |
356 |
5/10✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
|
6 | SOFT_ERROR_ER(constantNode, SWITCH_CASE_TYPE_MISMATCH, "Case value type does not match the switch expression type") |
357 |
4/4✓ Branch 1 taken 26 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 2 times.
|
35 | } |
358 | |||
359 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | return nullptr; |
360 | } | ||
361 | |||
362 | 28 | std::any TypeChecker::visitCaseBranch(CaseBranchNode *node) { | |
363 | // Change to case body scope | ||
364 |
2/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::CASE_BODY); |
365 | |||
366 | // Visit constant list | ||
367 |
3/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 28 times.
|
56 | for (CaseConstantNode *constant : node->caseConstants()) |
368 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
56 | visit(constant); |
369 | |||
370 | // Visit body | ||
371 |
2/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | visit(node->body()); |
372 | |||
373 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
56 | return nullptr; |
374 | 28 | } | |
375 | |||
376 | 3 | std::any TypeChecker::visitDefaultBranch(DefaultBranchNode *node) { | |
377 | // Change to default body scope | ||
378 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::DEFAULT_BODY); |
379 | |||
380 | // Visit body | ||
381 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | visit(node->body()); |
382 | |||
383 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
6 | return nullptr; |
384 | 3 | } | |
385 | |||
386 | 13 | std::any TypeChecker::visitAnonymousBlockStmt(AnonymousBlockStmtNode *node) { | |
387 | // Change to anonymous scope body scope | ||
388 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
13 | ScopeHandle scopeHandle(this, node->getScopeId(), ScopeType::ANONYMOUS_BLOCK_BODY); |
389 | |||
390 | // Visit body | ||
391 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
13 | visit(node->body()); |
392 | |||
393 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | return nullptr; |
394 | 13 | } | |
395 | |||
396 | 13253 | std::any TypeChecker::visitStmtLst(StmtLstNode *node) { | |
397 | // Visit nodes in this scope | ||
398 |
2/2✓ Branch 5 taken 26430 times.
✓ Branch 6 taken 13222 times.
|
39652 | for (ASTNode *stmt : node->children) { |
399 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 26430 times.
|
26430 | if (!stmt) |
400 | ✗ | continue; | |
401 | // Print warning if statement is unreachable | ||
402 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 26425 times.
|
26430 | if (stmt->unreachable) { |
403 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | warnings.emplace_back(stmt->codeLoc, UNREACHABLE_CODE, "This statement is unreachable"); |
404 | 5 | continue; | |
405 | } | ||
406 | // Visit the statement | ||
407 |
2/2✓ Branch 1 taken 26394 times.
✓ Branch 2 taken 31 times.
|
26425 | visit(stmt); |
408 | } | ||
409 | |||
410 | // Do cleanup of this scope, e.g. dtor calls for struct instances | ||
411 | 13222 | doScopeCleanup(node); | |
412 | |||
413 |
1/2✓ Branch 1 taken 13222 times.
✗ Branch 2 not taken.
|
13222 | return nullptr; |
414 | } | ||
415 | |||
416 | 9504 | std::any TypeChecker::visitParamLst(ParamLstNode *node) { | |
417 | 9504 | NamedParamList namedParams; | |
418 | 9504 | bool metOptional = false; | |
419 | |||
420 |
3/4✓ Branch 1 taken 9504 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 15064 times.
✓ Branch 9 taken 9504 times.
|
24568 | for (DeclStmtNode *param : node->params()) { |
421 | // Visit param | ||
422 |
2/4✓ Branch 1 taken 15064 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15064 times.
✗ Branch 5 not taken.
|
15064 | const auto paramType = std::any_cast<QualType>(visit(param)); |
423 |
3/4✓ Branch 1 taken 15064 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 15062 times.
|
15064 | if (paramType.is(TY_UNRESOLVED)) |
424 | 11 | continue; | |
425 | |||
426 | // Check if the type could be inferred. Dyn without a default value is forbidden | ||
427 |
3/4✓ Branch 1 taken 15062 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 15059 times.
|
15062 | if (paramType.is(TY_DYN)) { |
428 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
|
3 | softError(node, FCT_PARAM_IS_TYPE_DYN, "Type of parameter '" + param->varName + "' is invalid"); |
429 | 3 | continue; | |
430 | } | ||
431 | |||
432 | // Ensure that no optional param comes after a mandatory param | ||
433 |
2/2✓ Branch 0 taken 1859 times.
✓ Branch 1 taken 13200 times.
|
15059 | if (param->hasAssignment) { |
434 | 1859 | metOptional = true; | |
435 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13194 times.
|
13200 | } else if (metOptional) { |
436 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
6 | softError(param, INVALID_PARAM_ORDER, "Mandatory parameters must go before any optional parameters"); |
437 | 6 | continue; | |
438 | } | ||
439 | |||
440 | // Add parameter to named param list | ||
441 |
1/2✓ Branch 2 taken 15053 times.
✗ Branch 3 not taken.
|
15053 | namedParams.push_back({param->varName.c_str(), paramType, metOptional}); |
442 | 9504 | } | |
443 | |||
444 |
1/2✓ Branch 1 taken 9504 times.
✗ Branch 2 not taken.
|
19008 | return namedParams; |
445 | 9504 | } | |
446 | |||
447 | 1182 | std::any TypeChecker::visitField(FieldNode *node) { | |
448 |
3/6✓ Branch 1 taken 1182 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1182 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1182 times.
✗ Branch 8 not taken.
|
1182 | auto fieldType = std::any_cast<QualType>(visit(node->dataType())); |
449 |
5/8✓ Branch 1 taken 1182 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1181 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1182 | HANDLE_UNRESOLVED_TYPE_QT(fieldType) |
450 | |||
451 |
3/4✓ Branch 1 taken 1181 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 151 times.
✓ Branch 4 taken 1030 times.
|
1181 | if (TernaryExprNode *defaultValueNode = node->defaultValue()) { |
452 |
2/4✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 151 times.
✗ Branch 5 not taken.
|
151 | const QualType defaultValueType = std::any_cast<ExprResult>(visit(defaultValueNode)).type; |
453 |
2/8✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 151 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
151 | HANDLE_UNRESOLVED_TYPE_QT(defaultValueType) |
454 |
3/4✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 150 times.
|
151 | if (!fieldType.matches(defaultValueType, false, true, true)) |
455 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
|
3 | SOFT_ERROR_QT(node, FIELD_TYPE_NOT_MATCHING, "Type of the default values does not match the field type") |
456 | } | ||
457 | |||
458 |
1/2✓ Branch 1 taken 1180 times.
✗ Branch 2 not taken.
|
1180 | return fieldType; |
459 | } | ||
460 | |||
461 | 172 | std::any TypeChecker::visitSignature(SignatureNode *node) { | |
462 | 172 | const bool isFunction = node->signatureType == SignatureNode::TYPE_FUNCTION; | |
463 | |||
464 | // Retrieve function template types | ||
465 | 172 | std::vector<GenericType> usedGenericTypes; | |
466 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 81 times.
|
172 | if (node->hasTemplateTypes) { |
467 |
4/6✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 91 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 91 times.
✓ Branch 12 taken 90 times.
|
181 | for (DataTypeNode *dataType : node->templateTypeLst()->dataTypes()) { |
468 | // Visit template type | ||
469 |
2/4✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 91 times.
✗ Branch 5 not taken.
|
91 | auto templateType = std::any_cast<QualType>(visit(dataType)); |
470 |
2/4✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
|
91 | if (templateType.is(TY_UNRESOLVED)) |
471 | ✗ | return static_cast<std::vector<Function *> *>(nullptr); | |
472 | // Check if it is a generic type | ||
473 |
3/4✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 90 times.
|
91 | if (!templateType.is(TY_GENERIC)) { |
474 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | softError(dataType, EXPECTED_GENERIC_TYPE, "A template list can only contain generic types"); |
475 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | return static_cast<std::vector<Function *> *>(nullptr); |
476 | } | ||
477 | // Convert generic symbol type to generic type | ||
478 |
2/4✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 90 times.
✗ Branch 5 not taken.
|
90 | const GenericType *genericType = rootScope->lookupGenericType(templateType.getSubType()); |
479 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
|
90 | assert(genericType != nullptr); |
480 |
1/2✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
|
90 | usedGenericTypes.push_back(*genericType); |
481 |
2/2✓ Branch 1 taken 90 times.
✓ Branch 2 taken 1 times.
|
91 | } |
482 | } | ||
483 | |||
484 | // Visit return type | ||
485 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | QualType returnType(TY_DYN); |
486 |
2/2✓ Branch 0 taken 132 times.
✓ Branch 1 taken 39 times.
|
171 | if (isFunction) { |
487 |
3/6✓ Branch 1 taken 132 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 132 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 132 times.
✗ Branch 8 not taken.
|
132 | returnType = std::any_cast<QualType>(visit(node->returnType())); |
488 |
2/4✓ Branch 1 taken 132 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 132 times.
|
132 | if (returnType.is(TY_UNRESOLVED)) |
489 | ✗ | return static_cast<std::vector<Function *> *>(nullptr); | |
490 | |||
491 |
3/4✓ Branch 1 taken 132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 131 times.
|
132 | if (!returnType.isCoveredByGenericTypeList(usedGenericTypes)) |
492 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
2 | softError(node->returnType(), GENERIC_TYPE_NOT_IN_TEMPLATE, |
493 | "Generic return type not included in the template type list of the function"); | ||
494 | } | ||
495 | |||
496 | // Visit params | ||
497 | 171 | QualTypeList paramTypes; | |
498 | 171 | ParamList paramList; | |
499 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 159 times.
|
171 | if (node->hasParams) { |
500 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
|
12 | paramList.reserve(node->paramTypeLst()->dataTypes().size()); |
501 |
4/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 14 times.
✓ Branch 12 taken 12 times.
|
26 | for (DataTypeNode *param : node->paramTypeLst()->dataTypes()) { |
502 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
14 | auto paramType = std::any_cast<QualType>(visit(param)); |
503 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
|
14 | if (paramType.is(TY_UNRESOLVED)) |
504 | ✗ | return static_cast<std::vector<Function *> *>(nullptr); | |
505 | |||
506 | // Check if the type is present in the template for generic types | ||
507 |
3/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 12 times.
|
14 | if (!paramType.isCoveredByGenericTypeList(usedGenericTypes)) { |
508 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
|
2 | softError(node->paramTypeLst(), GENERIC_TYPE_NOT_IN_TEMPLATE, |
509 | "Generic param type not included in the template type list of the function"); | ||
510 | 2 | continue; | |
511 | } | ||
512 | |||
513 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | paramTypes.push_back(paramType); |
514 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | paramList.push_back({paramType, false}); |
515 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | } |
516 | } | ||
517 | |||
518 | // Build signature object | ||
519 |
4/8✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 171 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 171 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 171 times.
✗ Branch 11 not taken.
|
171 | const Function signature(node->methodName, nullptr, QualType(TY_DYN), returnType, paramList, usedGenericTypes, node); |
520 | |||
521 | // Add signature to current scope | ||
522 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | Function *manifestation = FunctionManager::insert(currentScope, signature, &node->signatureManifestations); |
523 | 171 | manifestation->entry = node->entry; | |
524 | 171 | manifestation->used = true; | |
525 | |||
526 | // Prepare signature type | ||
527 |
2/2✓ Branch 0 taken 132 times.
✓ Branch 1 taken 39 times.
|
171 | const SuperType superType = isFunction ? TY_FUNCTION : TY_PROCEDURE; |
528 |
2/4✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 171 times.
✗ Branch 5 not taken.
|
171 | QualType signatureType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes); |
529 | 171 | signatureType.setSpecifiers(node->signatureSpecifiers); | |
530 | |||
531 | // Set entry to signature type | ||
532 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 171 times.
|
171 | assert(node->entry != nullptr); |
533 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | node->entry->updateType(signatureType, false); |
534 | 171 | node->entry->used = true; | |
535 | |||
536 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | return &node->signatureManifestations; |
537 | 172 | } | |
538 | |||
539 | 20795 | std::any TypeChecker::visitDeclStmt(DeclStmtNode *node) { | |
540 | // Retrieve entry of the lhs variable | ||
541 |
1/2✓ Branch 1 taken 20795 times.
✗ Branch 2 not taken.
|
20795 | SymbolTableEntry *localVarEntry = currentScope->lookupStrict(node->varName); |
542 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20795 times.
|
20795 | assert(localVarEntry != nullptr); |
543 | |||
544 | 20795 | QualType localVarType; | |
545 |
2/2✓ Branch 0 taken 7384 times.
✓ Branch 1 taken 13411 times.
|
20795 | if (node->hasAssignment) { |
546 | // Visit the right side | ||
547 |
4/6✓ Branch 1 taken 7384 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7379 times.
✓ Branch 5 taken 5 times.
✓ Branch 7 taken 7379 times.
✗ Branch 8 not taken.
|
7384 | auto rhs = std::any_cast<ExprResult>(visit(node->assignExpr())); |
548 | 7379 | auto [rhsTy, rhsEntry] = rhs; | |
549 | |||
550 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
551 |
4/4✓ Branch 0 taken 1617 times.
✓ Branch 1 taken 5762 times.
✓ Branch 2 taken 803 times.
✓ Branch 3 taken 814 times.
|
7379 | if (rhsEntry != nullptr && rhsEntry->anonymous) { |
552 |
1/2✓ Branch 1 taken 803 times.
✗ Branch 2 not taken.
|
803 | currentScope->symbolTable.deleteAnonymous(rhsEntry->name); |
553 | 803 | rhs.entry = rhsEntry = nullptr; | |
554 | } | ||
555 | |||
556 | // Visit data type | ||
557 |
4/6✓ Branch 1 taken 7379 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7376 times.
✓ Branch 5 taken 3 times.
✓ Branch 7 taken 7376 times.
✗ Branch 8 not taken.
|
7379 | localVarType = std::any_cast<QualType>(visit(node->dataType())); |
558 | |||
559 | // Infer the type left to right if the right side is an empty array initialization | ||
560 |
3/4✓ Branch 1 taken 7376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 7374 times.
|
7376 | if (rhsTy.isArrayOf(TY_DYN)) |
561 | 2 | rhsTy = QualType(localVarType); | |
562 | |||
563 | // Check if type has to be inferred or both types are fixed | ||
564 |
8/10✓ Branch 1 taken 7376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7372 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 7372 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7353 times.
✓ Branch 9 taken 19 times.
✓ Branch 10 taken 7353 times.
✓ Branch 11 taken 23 times.
|
7376 | if (!localVarType.is(TY_UNRESOLVED) && !rhsTy.is(TY_UNRESOLVED)) { |
565 | 7353 | const ExprResult lhsResult = {localVarType, localVarEntry}; | |
566 |
2/2✓ Branch 1 taken 7343 times.
✓ Branch 2 taken 10 times.
|
7353 | localVarType = opRuleManager.getAssignResultType(node, lhsResult, rhs, true); |
567 | |||
568 | // Call copy ctor if required | ||
569 |
9/10✓ Branch 1 taken 7343 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 836 times.
✓ Branch 4 taken 6507 times.
✓ Branch 5 taken 832 times.
✓ Branch 6 taken 4 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 829 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 7340 times.
|
7343 | if (localVarType.is(TY_STRUCT) && !node->isParam && !rhs.isTemporary()) { |
570 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | Scope *matchScope = localVarType.getBodyScope(); |
571 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(matchScope != nullptr); |
572 | // Check if we have a no-args ctor to call | ||
573 | 3 | const QualType &thisType = localVarType; | |
574 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
6 | const ArgList args = {{thisType.toConstRef(node), false}}; |
575 |
2/4✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
9 | node->calledCopyCtor = FunctionManager::match(this, matchScope, CTOR_FUNCTION_NAME, thisType, args, {}, true, node); |
576 | 3 | } | |
577 | |||
578 | // If this is a struct type, check if the type is known. If not, error out | ||
579 |
8/14✓ Branch 1 taken 7343 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 968 times.
✓ Branch 4 taken 6375 times.
✓ Branch 6 taken 968 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 968 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 968 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 968 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 7343 times.
|
7343 | if (localVarType.isBase(TY_STRUCT) && !sourceFile->getNameRegistryEntry(localVarType.getBase().getSubType())) { |
580 | ✗ | const std::string structName = localVarType.getBase().getSubType(); | |
581 | ✗ | softError(node->dataType(), UNKNOWN_DATATYPE, "Unknown struct type '" + structName + "'. Forgot to import?"); | |
582 | ✗ | localVarType = QualType(TY_UNRESOLVED); | |
583 | ✗ | } | |
584 | } else { | ||
585 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | localVarType = QualType(TY_UNRESOLVED); |
586 | } | ||
587 | } else { | ||
588 | // Visit data type | ||
589 |
3/6✓ Branch 1 taken 13411 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13411 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13411 times.
✗ Branch 8 not taken.
|
13411 | localVarType = std::any_cast<QualType>(visit(node->dataType())); |
590 | |||
591 | // References with no initialization are illegal | ||
592 |
9/10✓ Branch 1 taken 13411 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4644 times.
✓ Branch 4 taken 8767 times.
✓ Branch 5 taken 54 times.
✓ Branch 6 taken 4590 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 53 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 13410 times.
|
13411 | if (localVarType.isRef() && !node->isParam && !node->isForEachItem) |
593 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | softError(node, REFERENCE_WITHOUT_INITIALIZER, "References must always be initialized directly"); |
594 | |||
595 | // If this is a struct, check for the default ctor | ||
596 |
9/10✓ Branch 1 taken 13411 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 332 times.
✓ Branch 4 taken 13079 times.
✓ Branch 5 taken 57 times.
✓ Branch 6 taken 275 times.
✓ Branch 7 taken 49 times.
✓ Branch 8 taken 8 times.
✓ Branch 9 taken 49 times.
✓ Branch 10 taken 13362 times.
|
13411 | if (localVarType.is(TY_STRUCT) && !node->isParam && !node->isForEachItem) { |
597 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | Scope *matchScope = localVarType.getBodyScope(); |
598 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
|
49 | assert(matchScope != nullptr); |
599 | // Check if we are required to call a ctor | ||
600 |
2/4✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
|
49 | auto structDeclNode = spice_pointer_cast<StructDefNode *>(localVarType.getStruct(node)->declNode); |
601 |
5/6✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 17 times.
✓ Branch 6 taken 31 times.
|
49 | node->isCtorCallRequired = matchScope->hasRefFields() || structDeclNode->emitVTable; |
602 | // Check if we have a no-args ctor to call | ||
603 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | const std::string &structName = localVarType.getSubType(); |
604 | 49 | const QualType &thisType = localVarType; | |
605 |
2/4✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
|
147 | node->calledInitCtor = FunctionManager::match(this, matchScope, CTOR_FUNCTION_NAME, thisType, {}, {}, false, node); |
606 |
4/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 12 times.
|
49 | if (!node->calledInitCtor && node->isCtorCallRequired) |
607 |
5/10✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
|
2 | SOFT_ERROR_QT(node, MISSING_NO_ARGS_CTOR, "Struct '" + structName + "' misses a no-args constructor") |
608 | } | ||
609 | } | ||
610 | |||
611 | // Update the type of the variable | ||
612 |
1/2✓ Branch 1 taken 20775 times.
✗ Branch 2 not taken.
|
20775 | localVarEntry->updateType(localVarType, true); |
613 |
1/2✓ Branch 1 taken 20775 times.
✗ Branch 2 not taken.
|
20775 | node->entries.at(manIdx) = localVarEntry; |
614 | |||
615 | // Update the state of the variable | ||
616 |
1/2✓ Branch 1 taken 20775 times.
✗ Branch 2 not taken.
|
20775 | localVarEntry->updateState(INITIALIZED, node, true); |
617 | |||
618 |
2/4✓ Branch 1 taken 20775 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20775 times.
✗ Branch 5 not taken.
|
20775 | return node->setEvaluatedSymbolType(localVarType, manIdx); |
619 | } | ||
620 | |||
621 | 56 | std::any TypeChecker::visitCaseConstant(CaseConstantNode *node) { | |
622 | // If we have a normal constant, we can take the symbol type from there | ||
623 |
3/4✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 20 times.
|
56 | if (node->constant()) |
624 |
2/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
|
36 | return visit(node->constant()); |
625 | |||
626 | // Check if a local or global variable can be found by searching for the name | ||
627 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
|
20 | if (node->identifierFragments.size() == 1) |
628 | 4 | node->enumItemEntry = currentScope->lookup(node->identifierFragments.back()); | |
629 | |||
630 | // If no local or global was found, search in the name registry | ||
631 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 11 times.
|
20 | if (!node->enumItemEntry) { |
632 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier); |
633 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (!registryEntry) |
634 | ✗ | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found") | |
635 | 9 | node->enumItemEntry = registryEntry->targetEntry; | |
636 | } | ||
637 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | assert(node->enumItemEntry != nullptr); |
638 | |||
639 | // Check for the correct type | ||
640 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
|
20 | if (node->enumItemEntry->scope->type != ScopeType::ENUM) |
641 |
5/10✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
|
6 | SOFT_ERROR_ER(node, CASE_CONSTANT_NOT_ENUM, "Case constants must be of type enum") |
642 | |||
643 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | const QualType varType = node->enumItemEntry->getQualType(); |
644 |
2/4✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
|
18 | assert(varType.is(TY_INT)); |
645 |
2/4✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
|
18 | return ExprResult{node->setEvaluatedSymbolType(varType, manIdx)}; |
646 | } | ||
647 | |||
648 | 5860 | std::any TypeChecker::visitReturnStmt(ReturnStmtNode *node) { | |
649 | // Retrieve return variable entry | ||
650 |
1/2✓ Branch 1 taken 5860 times.
✗ Branch 2 not taken.
|
17580 | SymbolTableEntry *returnVar = currentScope->lookup(RETURN_VARIABLE_NAME); |
651 | 5860 | const bool isFunction = returnVar != nullptr; | |
652 |
4/6✓ Branch 0 taken 5816 times.
✓ Branch 1 taken 44 times.
✓ Branch 3 taken 5816 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 44 times.
✗ Branch 7 not taken.
|
5860 | const QualType returnType = isFunction ? returnVar->getQualType() : QualType(TY_DYN); |
653 | |||
654 | // Check if procedure with return value | ||
655 |
2/2✓ Branch 0 taken 44 times.
✓ Branch 1 taken 5816 times.
|
5860 | if (!isFunction) { |
656 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 42 times.
|
44 | if (node->hasReturnValue) |
657 |
7/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
|
6 | SOFT_ERROR_ER(node->assignExpr(), RETURN_WITH_VALUE_IN_PROCEDURE, "Return with value in procedure is not allowed") |
658 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | return nullptr; |
659 | } | ||
660 | |||
661 |
7/8✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5810 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 5814 times.
|
5816 | if (!node->hasReturnValue && !returnVar->getLifecycle().isInitialized()) |
662 |
4/8✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
|
6 | SOFT_ERROR_QT(node, RETURN_WITHOUT_VALUE_RESULT, "Return without value, but result variable is not initialized yet") |
663 | |||
664 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5810 times.
|
5814 | if (!node->hasReturnValue) |
665 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | return nullptr; |
666 | |||
667 | // Visit right side | ||
668 |
3/6✓ Branch 1 taken 5810 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5810 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5810 times.
✗ Branch 8 not taken.
|
5810 | auto rhs = std::any_cast<ExprResult>(visit(node->assignExpr())); |
669 |
2/8✓ Branch 1 taken 5810 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5810 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
5810 | HANDLE_UNRESOLVED_TYPE_QT(rhs.type) |
670 | |||
671 | // Check if types match | ||
672 | 5810 | const ExprResult returnResult = {returnType, returnVar}; | |
673 |
3/4✓ Branch 1 taken 5810 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5808 times.
✓ Branch 5 taken 2 times.
|
5810 | (void)opRuleManager.getAssignResultType(node->assignExpr(), returnResult, rhs, false, true, ERROR_MSG_RETURN); |
674 | |||
675 | // Manage dtor call | ||
676 |
2/2✓ Branch 0 taken 1575 times.
✓ Branch 1 taken 4233 times.
|
5808 | if (rhs.entry != nullptr) { |
677 |
2/2✓ Branch 0 taken 622 times.
✓ Branch 1 taken 953 times.
|
1575 | if (rhs.entry->anonymous) { |
678 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
679 |
1/2✓ Branch 1 taken 622 times.
✗ Branch 2 not taken.
|
622 | currentScope->symbolTable.deleteAnonymous(rhs.entry->name); |
680 | 622 | rhs.entry = nullptr; | |
681 | } else { | ||
682 | // Otherwise omit the destructor call, because the caller destructs the value | ||
683 | 953 | rhs.entry->omitDtorCall = true; | |
684 | } | ||
685 | } | ||
686 | |||
687 |
2/4✓ Branch 1 taken 5808 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5808 times.
✗ Branch 5 not taken.
|
5808 | return node->setEvaluatedSymbolType(returnType, manIdx); |
688 | } | ||
689 | |||
690 | 101 | std::any TypeChecker::visitBreakStmt(BreakStmtNode *node) { | |
691 | // Check if the stated number is valid | ||
692 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 100 times.
|
101 | if (node->breakTimes < 1) |
693 |
5/10✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "Break count must be >= 1, you provided " + std::to_string(node->breakTimes)) |
694 | |||
695 | // Check if we can break this often | ||
696 | 100 | const unsigned int maxBreaks = currentScope->getLoopNestingDepth(); | |
697 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 99 times.
|
100 | if (static_cast<unsigned int>(node->breakTimes) > maxBreaks) |
698 |
6/12✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "We can only break " + std::to_string(maxBreaks) + " time(s) here") |
699 | |||
700 |
1/2✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
|
99 | return nullptr; |
701 | } | ||
702 | |||
703 | 335 | std::any TypeChecker::visitContinueStmt(ContinueStmtNode *node) { | |
704 | // Check if the stated number is valid | ||
705 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 334 times.
|
335 | if (node->continueTimes < 1) |
706 |
5/10✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER, |
707 | "Continue count must be >= 1, you provided " + std::to_string(node->continueTimes)) | ||
708 | |||
709 | // Check if we can continue this often | ||
710 | 334 | const unsigned int maxContinues = currentScope->getLoopNestingDepth(); | |
711 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 333 times.
|
334 | if (static_cast<unsigned int>(node->continueTimes) > maxContinues) |
712 |
6/12✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER, "We can only continue " + std::to_string(maxContinues) + " time(s) here") |
713 | |||
714 |
1/2✓ Branch 1 taken 333 times.
✗ Branch 2 not taken.
|
333 | return nullptr; |
715 | } | ||
716 | |||
717 | 6 | std::any TypeChecker::visitFallthroughStmt(FallthroughStmtNode *node) { | |
718 | // Check if we can do a fallthrough here | ||
719 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
|
6 | if (!currentScope->isInCaseBranch()) |
720 |
5/10✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
|
6 | SOFT_ERROR_ER(node, FALLTHROUGH_NOT_ALLOWED, "Fallthrough is only allowed in case branches") |
721 | |||
722 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | return nullptr; |
723 | } | ||
724 | |||
725 | 657 | std::any TypeChecker::visitAssertStmt(AssertStmtNode *node) { | |
726 | // Visit condition | ||
727 |
3/6✓ Branch 1 taken 657 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 657 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 657 times.
✗ Branch 8 not taken.
|
657 | const QualType conditionType = std::any_cast<ExprResult>(visit(node->assignExpr())).type; |
728 |
2/10✓ Branch 1 taken 657 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 657 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
657 | HANDLE_UNRESOLVED_TYPE_ER(conditionType) |
729 | |||
730 | // Check if condition evaluates to bool | ||
731 |
3/4✓ Branch 1 taken 657 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 656 times.
|
657 | if (!conditionType.is(TY_BOOL)) |
732 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
|
3 | SOFT_ERROR_ER(node->assignExpr(), ASSERTION_CONDITION_BOOL, "The asserted condition must be of type bool") |
733 | |||
734 |
1/2✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
|
656 | return nullptr; |
735 | } | ||
736 | |||
737 | 651 | std::any TypeChecker::visitPrintfCall(PrintfCallNode *node) { | |
738 | // Check if assignment types match placeholder types | ||
739 | 651 | size_t placeholderCount = 0; | |
740 | 651 | size_t index = node->templatedString.find_first_of('%'); | |
741 |
5/6✓ Branch 0 taken 550 times.
✓ Branch 1 taken 629 times.
✓ Branch 3 taken 550 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 550 times.
✓ Branch 6 taken 629 times.
|
1179 | while (index != std::string::npos && index != node->templatedString.size() - 1) { |
742 | // Check if there is another assignExpr | ||
743 |
3/4✓ Branch 1 taken 550 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 549 times.
|
550 | if (node->args().size() <= placeholderCount) |
744 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
3 | SOFT_ERROR_ER(node, PRINTF_ARG_COUNT_ERROR, "The placeholder string contains more placeholders than arguments") |
745 | |||
746 | // Get next assignment | ||
747 |
2/4✓ Branch 1 taken 549 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 549 times.
✗ Branch 5 not taken.
|
549 | AssignExprNode *assignment = node->args().at(placeholderCount); |
748 | // Visit assignment | ||
749 |
2/4✓ Branch 1 taken 549 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 549 times.
✗ Branch 5 not taken.
|
549 | QualType argType = std::any_cast<ExprResult>(visit(assignment)).type; |
750 |
6/10✓ Branch 1 taken 549 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 534 times.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 15 times.
✗ Branch 13 not taken.
|
549 | HANDLE_UNRESOLVED_TYPE_ER(argType) |
751 |
1/2✓ Branch 1 taken 534 times.
✗ Branch 2 not taken.
|
534 | argType = argType.removeReferenceWrapper(); |
752 | |||
753 |
6/8✓ Branch 1 taken 534 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 292 times.
✓ Branch 5 taken 34 times.
✓ Branch 6 taken 188 times.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
|
534 | switch (node->templatedString.at(index + 1)) { |
754 | 15 | case 'c': { | |
755 |
3/4✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 14 times.
|
15 | if (!argType.is(TY_CHAR)) |
756 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, "The placeholder string expects char, but got " + argType.getName(false)) |
757 | 14 | placeholderCount++; | |
758 | 14 | break; | |
759 | } | ||
760 | 292 | case 'd': | |
761 | case 'i': | ||
762 | case 'l': | ||
763 | case 'o': | ||
764 | case 'u': | ||
765 | case 'x': | ||
766 | case 'X': { | ||
767 |
3/4✓ Branch 1 taken 292 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 290 times.
|
292 | if (!argType.isOneOf({TY_INT, TY_SHORT, TY_LONG, TY_BYTE, TY_BOOL})) |
768 |
6/12✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
|
2 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, |
769 | "The placeholder string expects int, short, long, byte or bool, but got " + argType.getName(false)) | ||
770 | 290 | placeholderCount++; | |
771 | 290 | break; | |
772 | } | ||
773 | 34 | case 'a': | |
774 | case 'A': | ||
775 | case 'f': | ||
776 | case 'F': | ||
777 | case 'e': | ||
778 | case 'E': | ||
779 | case 'g': | ||
780 | case 'G': { | ||
781 |
3/4✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 33 times.
|
34 | if (!argType.is(TY_DOUBLE)) |
782 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, "The placeholder string expects double, but got " + argType.getName(false)) |
783 | 33 | placeholderCount++; | |
784 | 33 | break; | |
785 | } | ||
786 | 188 | case 's': { | |
787 |
13/18✓ Branch 1 taken 188 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 159 times.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 27 times.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 187 times.
|
188 | if (!argType.is(TY_STRING) && !argType.isStringObj() && !argType.isPtrTo(TY_CHAR) && !argType.isArrayOf(TY_CHAR)) |
788 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, |
789 | "The placeholder string expects string, String, char* or char[], but got " + argType.getName(false)) | ||
790 | 187 | placeholderCount++; | |
791 | 187 | break; | |
792 | } | ||
793 | 5 | case 'p': { | |
794 |
9/14✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 4 times.
|
5 | if (!argType.isPtr() && !argType.isArray() && !argType.is(TY_STRING)) |
795 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(assignment, PRINTF_TYPE_ERROR, |
796 | "The placeholder string expects pointer, array or string, but got " + argType.getName(false)) | ||
797 | 4 | placeholderCount++; | |
798 | 4 | break; | |
799 | } | ||
800 | ✗ | default: | |
801 | ✗ | SOFT_ERROR_ER(node, PRINTF_TYPE_ERROR, "The placeholder string contains an invalid placeholder") | |
802 | } | ||
803 | 528 | index = node->templatedString.find_first_of('%', index + 2); // We can also skip the following char | |
804 | } | ||
805 | |||
806 | // Check if the number of placeholders matches the number of args | ||
807 |
3/4✓ Branch 1 taken 629 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 628 times.
|
629 | if (placeholderCount < node->args().size()) |
808 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
3 | SOFT_ERROR_ER(node, PRINTF_ARG_COUNT_ERROR, "The placeholder string contains less placeholders than arguments") |
809 | |||
810 |
3/6✓ Branch 1 taken 628 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 628 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 628 times.
✗ Branch 8 not taken.
|
628 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_INT), manIdx)}; |
811 | } | ||
812 | |||
813 | 119 | std::any TypeChecker::visitSizeofCall(SizeofCallNode *node) { | |
814 |
2/2✓ Branch 0 taken 102 times.
✓ Branch 1 taken 17 times.
|
119 | if (node->isType) { // Size of type |
815 |
2/4✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 102 times.
✗ Branch 5 not taken.
|
102 | visit(node->dataType()); |
816 | } else { // Size of value | ||
817 |
2/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
|
17 | visit(node->assignExpr()); |
818 | } | ||
819 | |||
820 |
3/6✓ Branch 1 taken 119 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 119 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 119 times.
✗ Branch 8 not taken.
|
119 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
821 | } | ||
822 | |||
823 | 11 | std::any TypeChecker::visitAlignofCall(AlignofCallNode *node) { | |
824 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
|
11 | if (node->isType) { // Align of type |
825 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | visit(node->dataType()); |
826 | } else { // Align of value | ||
827 |
2/4✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
|
10 | visit(node->assignExpr()); |
828 | } | ||
829 | |||
830 |
3/6✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
|
11 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
831 | } | ||
832 | |||
833 | 36 | std::any TypeChecker::visitLenCall(LenCallNode *node) { | |
834 |
3/6✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 36 times.
✗ Branch 8 not taken.
|
36 | QualType argType = std::any_cast<ExprResult>(visit(node->assignExpr())).type; |
835 |
2/10✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
36 | HANDLE_UNRESOLVED_TYPE_ER(argType) |
836 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | argType = argType.removeReferenceWrapper(); |
837 | |||
838 | // Check if arg is of type array | ||
839 |
8/10✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 12 times.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 23 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 35 times.
|
36 | if (!argType.isArray() && !argType.is(TY_STRING)) |
840 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
|
3 | SOFT_ERROR_ER(node->assignExpr(), EXPECTED_ARRAY_TYPE, "The len builtin can only work on arrays or strings") |
841 | |||
842 | // If we want to use the len builtin on a string, we need to import the string runtime module | ||
843 |
7/10✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 12 times.
✓ Branch 6 taken 23 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 23 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 23 times.
✓ Branch 11 taken 12 times.
|
58 | if (argType.is(TY_STRING) && !sourceFile->isStringRT()) |
844 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | sourceFile->requestRuntimeModule(STRING_RT); |
845 | |||
846 |
3/6✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 35 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 35 times.
✗ Branch 8 not taken.
|
35 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
847 | } | ||
848 | |||
849 | 366 | std::any TypeChecker::visitPanicCall(PanicCallNode *node) { | |
850 |
3/6✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 366 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 366 times.
✗ Branch 8 not taken.
|
366 | QualType argType = std::any_cast<ExprResult>(visit(node->assignExpr())).type; |
851 |
2/10✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 366 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
366 | HANDLE_UNRESOLVED_TYPE_ER(argType) |
852 |
1/2✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
|
366 | argType = argType.removeReferenceWrapper(); |
853 | |||
854 | // Check if arg is of type array | ||
855 |
2/4✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 366 times.
|
366 | if (!argType.isErrorObj()) |
856 | ✗ | SOFT_ERROR_ER(node->assignExpr(), EXPECTED_ERROR_TYPE, "The panic builtin can only work with errors") | |
857 | |||
858 |
3/6✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 366 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 366 times.
✗ Branch 8 not taken.
|
366 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx)}; |
859 | } | ||
860 | |||
861 | 1 | std::any TypeChecker::visitSysCall(SysCallNode *node) { | |
862 | // Check if the syscall number if of type short | ||
863 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | const std::vector<AssignExprNode *> assignExprs = node->assignExprs(); |
864 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | const QualType sysCallNumberType = std::any_cast<ExprResult>(visit(assignExprs.front())).type; |
865 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | if (!sysCallNumberType.is(TY_SHORT)) |
866 | ✗ | SOFT_ERROR_ER(assignExprs.front(), INVALID_SYSCALL_NUMBER_TYPE, "Syscall number must be of type short") | |
867 | |||
868 | // Check if the syscall number is out of range | ||
869 | // According to https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/ | ||
870 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | if (node->hasCompileTimeValue()) { |
871 | ✗ | const unsigned short sysCallNumber = node->getCompileTimeValue().shortValue; | |
872 | ✗ | if (sysCallNumber < 0 || sysCallNumber > 439) | |
873 | ✗ | SOFT_ERROR_ER(node, SYSCALL_NUMBER_OUT_OF_RANGE, "Only syscall numbers between 0 and 439 are supported") | |
874 | } | ||
875 | |||
876 | // Check if too many syscall args are given | ||
877 | // According to https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/ | ||
878 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
|
1 | if (node->assignExprs().size() > 6) |
879 | ✗ | SOFT_ERROR_ER(node->assignExprs().front(), TOO_MANY_SYSCALL_ARGS, "There are no syscalls that support more than 6 arguments") | |
880 | |||
881 | // Visit children | ||
882 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
4 | for (size_t i = 1; i < assignExprs.size(); i++) |
883 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | visit(assignExprs.at(i)); |
884 | |||
885 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
1 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx)}; |
886 | 1 | } | |
887 | |||
888 | 48605 | std::any TypeChecker::visitAssignExpr(AssignExprNode *node) { | |
889 | // Check if ternary | ||
890 |
2/2✓ Branch 1 taken 43821 times.
✓ Branch 2 taken 4784 times.
|
48605 | if (node->ternaryExpr()) { |
891 |
4/6✓ Branch 1 taken 43821 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43806 times.
✓ Branch 5 taken 15 times.
✓ Branch 7 taken 43806 times.
✗ Branch 8 not taken.
|
43821 | auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr())); |
892 |
1/2✓ Branch 1 taken 43806 times.
✗ Branch 2 not taken.
|
43806 | node->setEvaluatedSymbolType(result.type, manIdx); |
893 |
1/2✓ Branch 1 taken 43806 times.
✗ Branch 2 not taken.
|
43806 | return result; |
894 | } | ||
895 | |||
896 | // Check if assignment | ||
897 |
1/2✓ Branch 0 taken 4784 times.
✗ Branch 1 not taken.
|
4784 | if (node->op != AssignExprNode::OP_NONE) { |
898 | // Visit the right side first | ||
899 |
3/6✓ Branch 1 taken 4784 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4784 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4784 times.
✗ Branch 8 not taken.
|
4784 | auto rhs = std::any_cast<ExprResult>(visit(node->rhs())); |
900 | 4784 | auto [rhsType, rhsEntry] = rhs; | |
901 |
6/10✓ Branch 1 taken 4784 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4783 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
|
4784 | HANDLE_UNRESOLVED_TYPE_ER(rhsType) |
902 | // Then visit the left side | ||
903 |
3/6✓ Branch 1 taken 4783 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4783 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4783 times.
✗ Branch 8 not taken.
|
4783 | auto lhs = std::any_cast<ExprResult>(visit(node->lhs())); |
904 | 4783 | auto [lhsType, lhsVar] = lhs; | |
905 |
6/10✓ Branch 1 taken 4783 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4782 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
|
4783 | HANDLE_UNRESOLVED_TYPE_ER(lhsType) |
906 | |||
907 | // Take a look at the operator | ||
908 |
2/2✓ Branch 0 taken 4251 times.
✓ Branch 1 taken 531 times.
|
4782 | if (node->op == AssignExprNode::OP_ASSIGN) { |
909 |
6/8✓ Branch 1 taken 4251 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3481 times.
✓ Branch 4 taken 770 times.
✓ Branch 7 taken 3481 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1179 times.
✓ Branch 10 taken 2302 times.
|
4251 | const bool isDecl = lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized(); |
910 |
2/2✓ Branch 1 taken 4249 times.
✓ Branch 2 taken 2 times.
|
4251 | rhsType = opRuleManager.getAssignResultType(node, lhs, rhs, isDecl); |
911 | |||
912 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
913 |
4/4✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 2201 times.
✓ Branch 2 taken 125 times.
✓ Branch 3 taken 1923 times.
|
4249 | if (rhsEntry != nullptr && rhsEntry->anonymous) { |
914 |
1/2✓ Branch 1 taken 125 times.
✗ Branch 2 not taken.
|
125 | currentScope->symbolTable.deleteAnonymous(rhsEntry->name); |
915 | 125 | rhsEntry = nullptr; | |
916 | } | ||
917 |
2/2✓ Branch 0 taken 213 times.
✓ Branch 1 taken 318 times.
|
531 | } else if (node->op == AssignExprNode::OP_PLUS_EQUAL) { |
918 |
1/2✓ Branch 1 taken 213 times.
✗ Branch 2 not taken.
|
213 | rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type; |
919 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 291 times.
|
318 | } else if (node->op == AssignExprNode::OP_MINUS_EQUAL) { |
920 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | rhsType = opRuleManager.getMinusEqualResultType(node, lhs, rhs, 0).type; |
921 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 276 times.
|
291 | } else if (node->op == AssignExprNode::OP_MUL_EQUAL) { |
922 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | rhsType = opRuleManager.getMulEqualResultType(node, lhs, rhs, 0).type; |
923 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 241 times.
|
276 | } else if (node->op == AssignExprNode::OP_DIV_EQUAL) { |
924 |
1/2✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
|
35 | rhsType = opRuleManager.getDivEqualResultType(node, lhs, rhs, 0).type; |
925 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 236 times.
|
241 | } else if (node->op == AssignExprNode::OP_REM_EQUAL) { |
926 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | rhsType = OpRuleManager::getRemEqualResultType(node, lhs, rhs); |
927 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 235 times.
|
236 | } else if (node->op == AssignExprNode::OP_SHL_EQUAL) { |
928 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | rhsType = OpRuleManager::getSHLEqualResultType(node, lhs, rhs); |
929 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 233 times.
|
235 | } else if (node->op == AssignExprNode::OP_SHR_EQUAL) { |
930 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | rhsType = OpRuleManager::getSHREqualResultType(node, lhs, rhs); |
931 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 232 times.
|
233 | } else if (node->op == AssignExprNode::OP_AND_EQUAL) { |
932 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | rhsType = OpRuleManager::getAndEqualResultType(node, lhs, rhs); |
933 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 231 times.
|
232 | } else if (node->op == AssignExprNode::OP_OR_EQUAL) { |
934 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | rhsType = OpRuleManager::getOrEqualResultType(node, lhs, rhs); |
935 |
1/2✓ Branch 0 taken 231 times.
✗ Branch 1 not taken.
|
231 | } else if (node->op == AssignExprNode::OP_XOR_EQUAL) { |
936 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
231 | rhsType = OpRuleManager::getXorEqualResultType(node, lhs, rhs); |
937 | } | ||
938 | |||
939 |
1/2✓ Branch 0 taken 4780 times.
✗ Branch 1 not taken.
|
4780 | if (lhsVar) { // Variable is involved on the left side |
940 | // Perform type inference | ||
941 |
3/4✓ Branch 1 taken 4780 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4779 times.
|
4780 | if (lhsType.is(TY_DYN)) |
942 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | lhsVar->updateType(rhsType, false); |
943 | |||
944 | // In case the lhs variable is captured, notify the capture about the write access | ||
945 |
3/4✓ Branch 1 taken 4780 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4777 times.
|
4780 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsVar->name); lhsCapture) |
946 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | lhsCapture->setAccessType(READ_WRITE); |
947 | |||
948 | // Update the state of the variable | ||
949 |
1/2✓ Branch 1 taken 4780 times.
✗ Branch 2 not taken.
|
4780 | lhsVar->updateState(INITIALIZED, node, false); |
950 | } | ||
951 | |||
952 |
2/4✓ Branch 1 taken 4780 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4780 times.
✗ Branch 5 not taken.
|
4780 | return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)}; |
953 | } | ||
954 | |||
955 | − | throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE | |
956 | } | ||
957 | |||
958 | 44653 | std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) { | |
959 | // Check if there is a ternary operator applied | ||
960 |
2/2✓ Branch 1 taken 44370 times.
✓ Branch 2 taken 283 times.
|
44653 | if (node->children.size() == 1) |
961 |
3/4✓ Branch 1 taken 44370 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 44355 times.
✓ Branch 6 taken 15 times.
|
88740 | return visit(node->operands().front()); |
962 | |||
963 | // Visit condition | ||
964 |
1/2✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
|
283 | LogicalOrExprNode *condition = node->operands()[0]; |
965 |
2/4✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 283 times.
✗ Branch 5 not taken.
|
283 | const QualType conditionType = std::any_cast<ExprResult>(visit(condition)).type; |
966 |
2/10✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 283 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
283 | HANDLE_UNRESOLVED_TYPE_ER(conditionType) |
967 | |||
968 | 283 | QualType trueType; | |
969 | 283 | QualType falseType; | |
970 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 282 times.
|
283 | if (node->isShortened) { |
971 | 1 | trueType = conditionType; | |
972 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
1 | falseType = std::any_cast<ExprResult>(visit(node->operands()[1])).type; |
973 | } else { | ||
974 |
3/6✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 282 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 282 times.
✗ Branch 9 not taken.
|
282 | trueType = std::any_cast<ExprResult>(visit(node->operands()[1])).type; |
975 |
2/10✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 282 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
282 | HANDLE_UNRESOLVED_TYPE_ER(trueType) |
976 |
3/6✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 282 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 282 times.
✗ Branch 9 not taken.
|
282 | falseType = std::any_cast<ExprResult>(visit(node->operands()[2])).type; |
977 | } | ||
978 |
2/10✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 283 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
283 | HANDLE_UNRESOLVED_TYPE_ER(falseType) |
979 | |||
980 | // Check if the condition evaluates to bool | ||
981 |
3/4✓ Branch 1 taken 283 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 282 times.
|
283 | if (!conditionType.is(TY_BOOL)) |
982 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
3 | SOFT_ERROR_ER(condition, OPERATOR_WRONG_DATA_TYPE, "Condition operand in ternary must be a bool") |
983 | |||
984 | // Check if trueType and falseType are matching | ||
985 |
1/2✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
|
282 | const QualType trueTypeModified = trueType.removeReferenceWrapper(); |
986 |
1/2✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
|
282 | const QualType falseTypeModified = falseType.removeReferenceWrapper(); |
987 |
3/4✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 281 times.
|
282 | if (!trueTypeModified.matches(falseTypeModified, false, true, false)) |
988 |
9/18✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
|
1 | SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE, |
989 | "True and false operands in ternary must be of same data type. Got " + trueType.getName(true) + " and " + | ||
990 | falseType.getName(true)) | ||
991 | |||
992 |
2/4✓ Branch 1 taken 281 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 281 times.
✗ Branch 5 not taken.
|
281 | return ExprResult{node->setEvaluatedSymbolType(trueType, manIdx)}; |
993 | } | ||
994 | |||
995 | 45218 | std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) { | |
996 | // Check if a logical or operator is applied | ||
997 |
2/2✓ Branch 1 taken 44957 times.
✓ Branch 2 taken 261 times.
|
45218 | if (node->children.size() == 1) |
998 |
3/4✓ Branch 1 taken 44957 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 44943 times.
✓ Branch 6 taken 14 times.
|
89914 | return visit(node->operands().front()); |
999 | |||
1000 | // Visit leftmost operand | ||
1001 |
3/6✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 261 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 261 times.
✗ Branch 9 not taken.
|
261 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1002 |
2/10✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 261 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
261 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
1003 | // Loop through all remaining operands | ||
1004 |
3/4✓ Branch 1 taken 548 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 288 times.
✓ Branch 6 taken 260 times.
|
548 | for (size_t i = 1; i < node->operands().size(); i++) { |
1005 |
3/6✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 288 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 288 times.
✗ Branch 9 not taken.
|
288 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands()[i])); |
1006 |
2/10✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 288 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
288 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
1007 |
2/2✓ Branch 1 taken 287 times.
✓ Branch 2 taken 1 times.
|
288 | currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)}; |
1008 | } | ||
1009 | |||
1010 |
1/2✓ Branch 1 taken 260 times.
✗ Branch 2 not taken.
|
260 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
1011 |
1/2✓ Branch 1 taken 260 times.
✗ Branch 2 not taken.
|
260 | return currentOperand; |
1012 | } | ||
1013 | |||
1014 | 45506 | std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) { | |
1015 | // Check if a logical and operator is applied | ||
1016 |
2/2✓ Branch 1 taken 45448 times.
✓ Branch 2 taken 58 times.
|
45506 | if (node->children.size() == 1) |
1017 |
3/4✓ Branch 1 taken 45448 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 45434 times.
✓ Branch 6 taken 14 times.
|
90896 | return visit(node->operands().front()); |
1018 | |||
1019 | // Visit leftmost operand | ||
1020 |
3/6✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 58 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 58 times.
✗ Branch 9 not taken.
|
58 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1021 |
2/10✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
58 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
1022 | // Loop through all remaining operands | ||
1023 |
3/4✓ Branch 1 taken 123 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 65 times.
✓ Branch 6 taken 58 times.
|
123 | for (size_t i = 1; i < node->operands().size(); i++) { |
1024 |
3/6✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 65 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 65 times.
✗ Branch 9 not taken.
|
65 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands()[i])); |
1025 |
2/10✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
65 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
1026 |
1/2✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
|
65 | currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)}; |
1027 | } | ||
1028 | |||
1029 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
1030 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | return currentOperand; |
1031 | } | ||
1032 | |||
1033 | 45571 | std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) { | |
1034 | // Check if a bitwise or operator is applied | ||
1035 |
2/2✓ Branch 1 taken 45538 times.
✓ Branch 2 taken 33 times.
|
45571 | if (node->children.size() == 1) |
1036 |
3/4✓ Branch 1 taken 45538 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 45525 times.
✓ Branch 6 taken 13 times.
|
91076 | return visit(node->operands().front()); |
1037 | |||
1038 | // Visit leftmost operand | ||
1039 |
3/6✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 33 times.
✗ Branch 9 not taken.
|
33 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1040 |
2/10✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
33 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
1041 | // Loop through all remaining operands | ||
1042 |
3/4✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 36 times.
✓ Branch 6 taken 32 times.
|
68 | for (size_t i = 1; i < node->operands().size(); i++) { |
1043 |
3/6✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 36 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 36 times.
✗ Branch 9 not taken.
|
36 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands()[i])); |
1044 |
2/10✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
36 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
1045 |
2/2✓ Branch 1 taken 35 times.
✓ Branch 2 taken 1 times.
|
36 | currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)}; |
1046 | } | ||
1047 | |||
1048 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
1049 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | return currentOperand; |
1050 | } | ||
1051 | |||
1052 | 45607 | std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) { | |
1053 | // Check if a bitwise xor operator is applied | ||
1054 |
2/2✓ Branch 1 taken 45603 times.
✓ Branch 2 taken 4 times.
|
45607 | if (node->children.size() == 1) |
1055 |
3/4✓ Branch 1 taken 45603 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 45590 times.
✓ Branch 6 taken 13 times.
|
91206 | return visit(node->operands().front()); |
1056 | |||
1057 | // Visit leftmost operand | ||
1058 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
|
4 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1059 |
2/10✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
4 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
1060 | // Loop through all remaining operands | ||
1061 |
3/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 4 times.
|
11 | for (size_t i = 1; i < node->operands().size(); i++) { |
1062 |
3/6✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
|
7 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands()[i])); |
1063 |
2/10✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
7 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
1064 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)}; |
1065 | } | ||
1066 | |||
1067 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
1068 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | return currentOperand; |
1069 | } | ||
1070 | |||
1071 | 45614 | std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) { | |
1072 | // Check if a bitwise and operator is applied | ||
1073 |
2/2✓ Branch 1 taken 45584 times.
✓ Branch 2 taken 30 times.
|
45614 | if (node->children.size() == 1) |
1074 |
3/4✓ Branch 1 taken 45584 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 45571 times.
✓ Branch 6 taken 13 times.
|
91168 | return visit(node->operands().front()); |
1075 | |||
1076 | // Visit leftmost operand | ||
1077 |
3/6✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 30 times.
✗ Branch 9 not taken.
|
30 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1078 |
2/10✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
30 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
1079 | // Loop through all remaining operands | ||
1080 |
3/4✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 33 times.
✓ Branch 6 taken 30 times.
|
63 | for (size_t i = 1; i < node->operands().size(); i++) { |
1081 |
3/6✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 33 times.
✗ Branch 9 not taken.
|
33 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands()[i])); |
1082 |
2/10✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
33 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
1083 |
1/2✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
|
33 | currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)}; |
1084 | } | ||
1085 | |||
1086 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
1087 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | return currentOperand; |
1088 | } | ||
1089 | |||
1090 | 45647 | std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) { | |
1091 | // Check if at least one equality operator is applied | ||
1092 |
2/2✓ Branch 1 taken 41953 times.
✓ Branch 2 taken 3694 times.
|
45647 | if (node->children.size() == 1) |
1093 |
3/4✓ Branch 1 taken 41953 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 41941 times.
✓ Branch 6 taken 12 times.
|
83906 | return visit(node->operands().front()); |
1094 | |||
1095 | // Visit right side first, then left side | ||
1096 |
3/6✓ Branch 1 taken 3694 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3694 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3694 times.
✗ Branch 9 not taken.
|
3694 | auto rhs = std::any_cast<ExprResult>(visit(node->operands()[1])); |
1097 |
2/10✓ Branch 1 taken 3694 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3694 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
3694 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
1098 |
3/6✓ Branch 1 taken 3694 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3694 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3694 times.
✗ Branch 9 not taken.
|
3694 | auto lhs = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1099 |
2/10✓ Branch 1 taken 3694 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3694 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
3694 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
1100 | |||
1101 | // Check if we need the string runtime to perform a string comparison | ||
1102 |
10/14✓ Branch 1 taken 3694 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 118 times.
✓ Branch 4 taken 3576 times.
✓ Branch 6 taken 118 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 117 times.
✓ Branch 9 taken 1 times.
✓ Branch 11 taken 117 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 117 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 117 times.
✓ Branch 16 taken 3577 times.
|
3811 | if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT()) |
1103 |
1/2✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
|
117 | sourceFile->requestRuntimeModule(STRING_RT); |
1104 | |||
1105 | // Check operator | ||
1106 | 3694 | ExprResult result; | |
1107 |
2/2✓ Branch 0 taken 2379 times.
✓ Branch 1 taken 1315 times.
|
3694 | if (node->op == EqualityExprNode::OP_EQUAL) // Operator was equal |
1108 |
2/2✓ Branch 1 taken 2378 times.
✓ Branch 2 taken 1 times.
|
2379 | result = opRuleManager.getEqualResultType(node, lhs, rhs, 0); |
1109 |
1/2✓ Branch 0 taken 1315 times.
✗ Branch 1 not taken.
|
1315 | else if (node->op == EqualityExprNode::OP_NOT_EQUAL) // Operator was not equal |
1110 |
1/2✓ Branch 1 taken 1315 times.
✗ Branch 2 not taken.
|
1315 | result = opRuleManager.getNotEqualResultType(node, lhs, rhs, 0); |
1111 | else | ||
1112 | − | throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE | |
1113 | |||
1114 |
1/2✓ Branch 1 taken 3693 times.
✗ Branch 2 not taken.
|
3693 | node->setEvaluatedSymbolType(result.type, manIdx); |
1115 |
1/2✓ Branch 1 taken 3693 times.
✗ Branch 2 not taken.
|
3693 | return result; |
1116 | } | ||
1117 | |||
1118 | 49341 | std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) { | |
1119 | // Check if a relational operator is applied | ||
1120 |
2/2✓ Branch 1 taken 46791 times.
✓ Branch 2 taken 2550 times.
|
49341 | if (node->children.size() == 1) |
1121 |
3/4✓ Branch 1 taken 46791 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 46780 times.
✓ Branch 6 taken 11 times.
|
93582 | return visit(node->operands().front()); |
1122 | |||
1123 | // Visit right side first, then left side | ||
1124 |
3/6✓ Branch 1 taken 2550 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2550 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2550 times.
✗ Branch 9 not taken.
|
2550 | auto rhs = std::any_cast<ExprResult>(visit(node->operands()[1])); |
1125 |
6/10✓ Branch 1 taken 2550 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2549 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
|
2550 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
1126 |
3/6✓ Branch 1 taken 2549 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2549 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2549 times.
✗ Branch 9 not taken.
|
2549 | auto lhs = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1127 |
2/10✓ Branch 1 taken 2549 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2549 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
2549 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
1128 | |||
1129 | // Check operator | ||
1130 | 2549 | QualType resultType; | |
1131 |
2/2✓ Branch 0 taken 1476 times.
✓ Branch 1 taken 1073 times.
|
2549 | if (node->op == RelationalExprNode::OP_LESS) // Operator was less |
1132 |
1/2✓ Branch 1 taken 1476 times.
✗ Branch 2 not taken.
|
1476 | resultType = OpRuleManager::getLessResultType(node, lhs, rhs); |
1133 |
2/2✓ Branch 0 taken 246 times.
✓ Branch 1 taken 827 times.
|
1073 | else if (node->op == RelationalExprNode::OP_GREATER) // Operator was greater |
1134 |
2/2✓ Branch 1 taken 245 times.
✓ Branch 2 taken 1 times.
|
246 | resultType = OpRuleManager::getGreaterResultType(node, lhs, rhs); |
1135 |
2/2✓ Branch 0 taken 263 times.
✓ Branch 1 taken 564 times.
|
827 | else if (node->op == RelationalExprNode::OP_LESS_EQUAL) // Operator was less equal |
1136 |
1/2✓ Branch 1 taken 263 times.
✗ Branch 2 not taken.
|
263 | resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs); |
1137 |
1/2✓ Branch 0 taken 564 times.
✗ Branch 1 not taken.
|
564 | else if (node->op == RelationalExprNode::OP_GREATER_EQUAL) // Operator was greater equal |
1138 |
1/2✓ Branch 1 taken 564 times.
✗ Branch 2 not taken.
|
564 | resultType = OpRuleManager::getGreaterEqualResultType(node, lhs, rhs); |
1139 | else | ||
1140 | − | throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE | |
1141 | |||
1142 |
2/4✓ Branch 1 taken 2548 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2548 times.
✗ Branch 5 not taken.
|
2548 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)}; |
1143 | } | ||
1144 | |||
1145 | 51890 | std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) { | |
1146 | // Check if at least one shift operator is applied | ||
1147 |
2/2✓ Branch 1 taken 51873 times.
✓ Branch 2 taken 17 times.
|
51890 | if (node->children.size() == 1) |
1148 |
3/4✓ Branch 1 taken 51873 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 51862 times.
✓ Branch 6 taken 11 times.
|
103746 | return visit(node->operands().front()); |
1149 | |||
1150 | // Visit right side first, then left | ||
1151 |
3/6✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 17 times.
✗ Branch 9 not taken.
|
17 | auto rhs = std::any_cast<ExprResult>(visit(node->operands()[1])); |
1152 |
2/10✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
17 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
1153 |
3/6✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 17 times.
✗ Branch 9 not taken.
|
17 | auto lhs = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1154 |
2/10✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
17 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
1155 | |||
1156 | // Check operator | ||
1157 | 17 | ExprResult currentResult; | |
1158 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 7 times.
|
17 | if (node->op == ShiftExprNode::OP_SHIFT_LEFT) // Operator was shl |
1159 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | currentResult = opRuleManager.getShiftLeftResultType(node, lhs, rhs, 0); |
1160 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | else if (node->op == ShiftExprNode::OP_SHIFT_RIGHT) // Operator was shr |
1161 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | currentResult = opRuleManager.getShiftRightResultType(node, lhs, rhs, 0); |
1162 | else | ||
1163 | − | throw CompilerError(UNHANDLED_BRANCH, "ShiftExpr fall-through"); // GCOV_EXCL_LINE | |
1164 | |||
1165 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
1166 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | return currentResult; |
1167 | } | ||
1168 | |||
1169 | 51907 | std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) { | |
1170 | // Check if at least one additive operator is applied | ||
1171 |
2/2✓ Branch 1 taken 48885 times.
✓ Branch 2 taken 3022 times.
|
51907 | if (node->children.size() == 1) |
1172 |
3/4✓ Branch 1 taken 48885 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 48875 times.
✓ Branch 6 taken 10 times.
|
97770 | return visit(node->operands().front()); |
1173 | |||
1174 | // Visit leftmost operand | ||
1175 |
3/6✓ Branch 1 taken 3022 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3022 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3022 times.
✗ Branch 9 not taken.
|
3022 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1176 |
2/10✓ Branch 1 taken 3022 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3022 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
3022 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
1177 | |||
1178 | // Loop through remaining operands | ||
1179 |
2/2✓ Branch 1 taken 3437 times.
✓ Branch 2 taken 3021 times.
|
6458 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
1180 | // Visit next operand | ||
1181 |
1/2✓ Branch 1 taken 3437 times.
✗ Branch 2 not taken.
|
3437 | MultiplicativeExprNode *operand = node->operands()[i + 1]; |
1182 |
2/4✓ Branch 1 taken 3437 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3437 times.
✗ Branch 5 not taken.
|
3437 | auto operandResult = std::any_cast<ExprResult>(visit(operand)); |
1183 |
2/10✓ Branch 1 taken 3437 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3437 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
3437 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
1184 | |||
1185 | // Check operator | ||
1186 | 3437 | const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first; | |
1187 |
2/2✓ Branch 0 taken 2178 times.
✓ Branch 1 taken 1259 times.
|
3437 | if (op == AdditiveExprNode::OP_PLUS) |
1188 |
2/2✓ Branch 1 taken 2177 times.
✓ Branch 2 taken 1 times.
|
2178 | currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i); |
1189 |
1/2✓ Branch 0 taken 1259 times.
✗ Branch 1 not taken.
|
1259 | else if (op == AdditiveExprNode::OP_MINUS) |
1190 |
1/2✓ Branch 1 taken 1259 times.
✗ Branch 2 not taken.
|
1259 | currentResult = opRuleManager.getMinusResultType(node, currentResult, operandResult, i); |
1191 | else | ||
1192 | − | throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE | |
1193 | |||
1194 | // Push the new item and pop the old one on the other side of the queue | ||
1195 |
1/2✓ Branch 1 taken 3436 times.
✗ Branch 2 not taken.
|
3436 | node->opQueue.emplace(op, currentResult.type); |
1196 | 3436 | node->opQueue.pop(); | |
1197 | } | ||
1198 | |||
1199 |
1/2✓ Branch 1 taken 3021 times.
✗ Branch 2 not taken.
|
3021 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
1200 |
1/2✓ Branch 1 taken 3021 times.
✗ Branch 2 not taken.
|
3021 | return currentResult; |
1201 | } | ||
1202 | |||
1203 | 55344 | std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) { | |
1204 | // Check if at least one multiplicative operator is applied | ||
1205 |
2/2✓ Branch 1 taken 54500 times.
✓ Branch 2 taken 844 times.
|
55344 | if (node->children.size() == 1) |
1206 |
3/4✓ Branch 1 taken 54500 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 54491 times.
✓ Branch 6 taken 9 times.
|
109000 | return visit(node->operands().front()); |
1207 | |||
1208 | // Visit leftmost operand | ||
1209 |
3/6✓ Branch 1 taken 844 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 844 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 844 times.
✗ Branch 9 not taken.
|
844 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands()[0])); |
1210 |
2/10✓ Branch 1 taken 844 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 844 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
844 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
1211 | // Loop through remaining operands | ||
1212 |
2/2✓ Branch 1 taken 868 times.
✓ Branch 2 taken 843 times.
|
1711 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
1213 | // Visit next operand | ||
1214 |
1/2✓ Branch 1 taken 868 times.
✗ Branch 2 not taken.
|
868 | CastExprNode *operand = node->operands()[i + 1]; |
1215 |
2/4✓ Branch 1 taken 868 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 868 times.
✗ Branch 5 not taken.
|
868 | auto operandResult = std::any_cast<ExprResult>(visit(operand)); |
1216 |
2/10✓ Branch 1 taken 868 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 868 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
868 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
1217 | |||
1218 | // Check operator | ||
1219 | 868 | const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first; | |
1220 |
2/2✓ Branch 0 taken 654 times.
✓ Branch 1 taken 214 times.
|
868 | if (op == MultiplicativeExprNode::OP_MUL) |
1221 |
2/2✓ Branch 1 taken 653 times.
✓ Branch 2 taken 1 times.
|
654 | currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i); |
1222 |
2/2✓ Branch 0 taken 205 times.
✓ Branch 1 taken 9 times.
|
214 | else if (op == MultiplicativeExprNode::OP_DIV) |
1223 |
1/2✓ Branch 1 taken 205 times.
✗ Branch 2 not taken.
|
205 | currentResult = opRuleManager.getDivResultType(node, currentResult, operandResult, i); |
1224 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | else if (op == MultiplicativeExprNode::OP_REM) |
1225 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | currentResult = OpRuleManager::getRemResultType(node, currentResult, operandResult); |
1226 | else | ||
1227 | − | throw CompilerError(UNHANDLED_BRANCH, "Multiplicative fall-through"); // GCOV_EXCL_LINE | |
1228 | |||
1229 | // Push the new item and pop the old one on the other side of the queue | ||
1230 |
1/2✓ Branch 1 taken 867 times.
✗ Branch 2 not taken.
|
867 | node->opQueue.emplace(op, currentResult.type); |
1231 | 867 | node->opQueue.pop(); | |
1232 | } | ||
1233 | |||
1234 |
1/2✓ Branch 1 taken 843 times.
✗ Branch 2 not taken.
|
843 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
1235 |
1/2✓ Branch 1 taken 843 times.
✗ Branch 2 not taken.
|
843 | return currentResult; |
1236 | } | ||
1237 | |||
1238 | 56212 | std::any TypeChecker::visitCastExpr(CastExprNode *node) { | |
1239 | // Check if cast is applied | ||
1240 |
2/2✓ Branch 0 taken 53855 times.
✓ Branch 1 taken 2357 times.
|
56212 | if (!node->isCast) |
1241 |
3/4✓ Branch 1 taken 53855 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 53846 times.
✓ Branch 5 taken 9 times.
|
53855 | return visit(node->prefixUnaryExpr()); |
1242 | |||
1243 | // Visit source type | ||
1244 |
3/6✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2357 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2357 times.
✗ Branch 8 not taken.
|
2357 | const auto src = std::any_cast<ExprResult>(visit(node->prefixUnaryExpr())); |
1245 |
2/10✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2357 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
2357 | HANDLE_UNRESOLVED_TYPE_ER(src.type) |
1246 | // Visit destination type | ||
1247 |
3/6✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2357 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2357 times.
✗ Branch 8 not taken.
|
2357 | const auto dstType = std::any_cast<QualType>(visit(node->dataType())); |
1248 |
2/10✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2357 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
2357 | HANDLE_UNRESOLVED_TYPE_ER(dstType) |
1249 | |||
1250 | // Check for identity cast | ||
1251 |
3/4✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1006 times.
✓ Branch 4 taken 1351 times.
|
2357 | if (src.type == dstType) { |
1252 |
2/4✓ Branch 1 taken 1006 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1006 times.
✗ Branch 5 not taken.
|
1006 | const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified."); |
1253 |
1/2✓ Branch 1 taken 1006 times.
✗ Branch 2 not taken.
|
1006 | sourceFile->compilerOutput.warnings.push_back(warning); |
1254 | 1006 | } | |
1255 | |||
1256 | // Get result type | ||
1257 |
1/2✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
|
2357 | const QualType resultType = opRuleManager.getCastResultType(node, dstType, src); |
1258 | |||
1259 |
3/4✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 200 times.
✓ Branch 4 taken 2157 times.
|
2357 | SymbolTableEntry *entry = src.type.isSameContainerTypeAs(dstType) ? src.entry : nullptr; |
1260 |
2/4✓ Branch 1 taken 2357 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2357 times.
✗ Branch 5 not taken.
|
2357 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry}; |
1261 | } | ||
1262 | |||
1263 | 61834 | std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { | |
1264 | // Reset access scope | ||
1265 | 61834 | accessScope = nullptr; | |
1266 | |||
1267 | // If no operator is applied, simply visit the postfix unary expression | ||
1268 |
2/2✓ Branch 0 taken 60995 times.
✓ Branch 1 taken 839 times.
|
61834 | if (node->op == PrefixUnaryExprNode::OP_NONE) |
1269 |
3/4✓ Branch 1 taken 60995 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 60987 times.
✓ Branch 5 taken 8 times.
|
60995 | return visit(node->postfixUnaryExpr()); |
1270 | |||
1271 | // Visit the right side | ||
1272 |
1/2✓ Branch 1 taken 839 times.
✗ Branch 2 not taken.
|
839 | PrefixUnaryExprNode *rhsNode = node->prefixUnary(); |
1273 |
2/4✓ Branch 1 taken 839 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 839 times.
✗ Branch 5 not taken.
|
839 | auto operand = std::any_cast<ExprResult>(visit(rhsNode)); |
1274 | 839 | auto [operandType, operandEntry] = operand; | |
1275 |
6/10✓ Branch 1 taken 839 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 838 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
|
839 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
1276 | // Determine action, based on the given operator | ||
1277 |
7/8✓ Branch 0 taken 16 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 561 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 162 times.
✓ Branch 6 taken 63 times.
✗ Branch 7 not taken.
|
838 | switch (node->op) { |
1278 | 16 | case PrefixUnaryExprNode::OP_MINUS: | |
1279 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | operandType = OpRuleManager::getPrefixMinusResultType(node, operand); |
1280 | 16 | break; | |
1281 | 28 | case PrefixUnaryExprNode::OP_PLUS_PLUS: | |
1282 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | operandType = opRuleManager.getPrefixPlusPlusResultType(node, operand); |
1283 | |||
1284 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 3 times.
|
28 | if (operandEntry) { |
1285 | // In case the lhs is captured, notify the capture about the write access | ||
1286 |
2/4✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 25 times.
|
25 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
1287 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
1288 | |||
1289 | // Update the state of the variable | ||
1290 |
1/2✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
|
25 | operandEntry->updateState(INITIALIZED, node, false); |
1291 | } | ||
1292 | |||
1293 | 28 | break; | |
1294 | 7 | case PrefixUnaryExprNode::OP_MINUS_MINUS: | |
1295 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
|
7 | operandType = opRuleManager.getPrefixMinusMinusResultType(node, operand); |
1296 | |||
1297 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
|
6 | if (operandEntry) { |
1298 | // In case the lhs is captured, notify the capture about the write access | ||
1299 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
|
3 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
1300 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
1301 | |||
1302 | // Update the state of the variable | ||
1303 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | operandEntry->updateState(INITIALIZED, node, false); |
1304 | } | ||
1305 | |||
1306 | 6 | break; | |
1307 | 561 | case PrefixUnaryExprNode::OP_NOT: | |
1308 |
1/2✓ Branch 1 taken 561 times.
✗ Branch 2 not taken.
|
561 | operandType = OpRuleManager::getPrefixNotResultType(node, operand); |
1309 | 561 | break; | |
1310 | 1 | case PrefixUnaryExprNode::OP_BITWISE_NOT: | |
1311 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operand); |
1312 | 1 | break; | |
1313 | 162 | case PrefixUnaryExprNode::OP_DEREFERENCE: | |
1314 |
1/2✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
|
162 | operandType = OpRuleManager::getPrefixMulResultType(node, operand); |
1315 | 162 | break; | |
1316 | 63 | case PrefixUnaryExprNode::OP_ADDRESS_OF: | |
1317 |
1/2✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
|
63 | operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand); |
1318 | 63 | break; | |
1319 | ✗ | default: | |
1320 | − | throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
1321 | } | ||
1322 | |||
1323 |
2/4✓ Branch 1 taken 837 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 837 times.
✗ Branch 5 not taken.
|
837 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
1324 | } | ||
1325 | |||
1326 | 77053 | std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { | |
1327 | // If no operator is applied, simply visit the atomic expression | ||
1328 |
2/2✓ Branch 0 taken 60995 times.
✓ Branch 1 taken 16058 times.
|
77053 | if (node->op == PostfixUnaryExprNode::OP_NONE) |
1329 |
3/4✓ Branch 1 taken 60995 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 60988 times.
✓ Branch 5 taken 7 times.
|
60995 | return visit(node->atomicExpr()); |
1330 | |||
1331 | // Visit left side | ||
1332 |
1/2✓ Branch 1 taken 16058 times.
✗ Branch 2 not taken.
|
16058 | PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr(); |
1333 |
2/4✓ Branch 1 taken 16058 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16058 times.
✗ Branch 5 not taken.
|
16058 | auto lhs = std::any_cast<ExprResult>(visit(lhsNode)); |
1334 | 16058 | auto [lhsType, lhsEntry] = lhs; | |
1335 |
6/10✓ Branch 1 taken 16058 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 16052 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
|
16058 | HANDLE_UNRESOLVED_TYPE_ER(lhsType) |
1336 | |||
1337 |
4/5✓ Branch 0 taken 2328 times.
✓ Branch 1 taken 12101 times.
✓ Branch 2 taken 1353 times.
✓ Branch 3 taken 270 times.
✗ Branch 4 not taken.
|
16052 | switch (node->op) { |
1338 | 2328 | case PostfixUnaryExprNode::OP_SUBSCRIPT: { | |
1339 |
1/2✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
|
2328 | lhsType = lhsType.removeReferenceWrapper(); |
1340 | |||
1341 | // Check if we can apply the subscript operator on the lhs type | ||
1342 |
2/4✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2328 times.
|
2328 | if (!lhsType.isOneOf({TY_ARRAY, TY_STRING, TY_PTR})) |
1343 | ✗ | SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE, | |
1344 | "Can only apply subscript operator on array type, got " + lhsType.getName(true)) | ||
1345 | |||
1346 | // Visit index assignment | ||
1347 |
1/2✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
|
2328 | AssignExprNode *indexAssignExpr = node->assignExpr(); |
1348 |
2/4✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2328 times.
✗ Branch 5 not taken.
|
2328 | QualType indexType = std::any_cast<ExprResult>(visit(indexAssignExpr)).type; |
1349 |
2/10✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2328 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
2328 | HANDLE_UNRESOLVED_TYPE_ER(indexType) |
1350 | // Check if the index is of the right type | ||
1351 |
3/4✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2327 times.
|
2328 | if (!indexType.isOneOf({TY_INT, TY_LONG})) |
1352 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
3 | SOFT_ERROR_ER(node, ARRAY_INDEX_NOT_INT_OR_LONG, "Array index must be of type int or long") |
1353 | |||
1354 | // Check if we have an unsafe operation | ||
1355 |
6/10✓ Branch 1 taken 2327 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1546 times.
✓ Branch 4 taken 781 times.
✓ Branch 6 taken 1546 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1546 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2327 times.
|
2327 | if (lhsType.isPtr() && !currentScope->doesAllowUnsafeOperations()) |
1356 | ✗ | SOFT_ERROR_ER( | |
1357 | node, UNSAFE_OPERATION_IN_SAFE_CONTEXT, | ||
1358 | "The subscript operator on pointers is an unsafe operation. Use unsafe blocks if you know what you are doing.") | ||
1359 | |||
1360 | // Check if we have a hardcoded array index | ||
1361 |
11/14✓ Branch 1 taken 2327 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 136 times.
✓ Branch 4 taken 2191 times.
✓ Branch 6 taken 136 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 96 times.
✓ Branch 9 taken 40 times.
✓ Branch 11 taken 96 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 34 times.
✓ Branch 14 taken 62 times.
✓ Branch 15 taken 34 times.
✓ Branch 16 taken 2293 times.
|
2327 | if (lhsType.isArray() && lhsType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) { |
1362 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue; |
1363 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | const unsigned int constSize = lhsType.getArraySize(); |
1364 | // Check if we are accessing out-of-bounds memory | ||
1365 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (constIndex >= static_cast<int32_t>(constSize)) { |
1366 | 1 | const std::string idxStr = std::to_string(constIndex); | |
1367 | 1 | const std::string sizeStr = std::to_string(constSize); | |
1368 |
7/14✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
|
1 | SOFT_ERROR_ER(node, ARRAY_INDEX_OUT_OF_BOUNDS, |
1369 | "You are trying to access element with index " + idxStr + " of an array with size " + sizeStr) | ||
1370 | 1 | } | |
1371 | } | ||
1372 | |||
1373 | // Get item type | ||
1374 |
1/2✓ Branch 1 taken 2326 times.
✗ Branch 2 not taken.
|
2326 | lhsType = lhsType.getContained(); |
1375 | |||
1376 | // Remove heap specifier | ||
1377 | 2326 | lhsType.getSpecifiers().isHeap = false; | |
1378 | |||
1379 | 2326 | break; | |
1380 | } | ||
1381 | 12101 | case PostfixUnaryExprNode::OP_MEMBER_ACCESS: { | |
1382 | 12101 | const std::string &fieldName = node->identifier; | |
1383 | |||
1384 | // Check if lhs is enum or strobj | ||
1385 | 12101 | QualType lhsBaseTy = lhsType; | |
1386 |
1/2✓ Branch 1 taken 12101 times.
✗ Branch 2 not taken.
|
12101 | autoDeReference(lhsBaseTy); |
1387 |
3/4✓ Branch 1 taken 12101 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 12100 times.
|
12101 | if (!lhsBaseTy.is(TY_STRUCT)) |
1388 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_MEMBER_ACCESS, "Cannot apply member access operator on " + lhsType.getName(false)) |
1389 | |||
1390 | // Retrieve registry entry | ||
1391 |
1/2✓ Branch 1 taken 12100 times.
✗ Branch 2 not taken.
|
12100 | const std::string &structName = lhsBaseTy.getSubType(); |
1392 |
1/2✓ Branch 1 taken 12100 times.
✗ Branch 2 not taken.
|
12100 | Scope *structScope = lhsBaseTy.getBodyScope(); |
1393 | |||
1394 | // If we only have the generic struct scope, lookup the concrete manifestation scope | ||
1395 |
2/2✓ Branch 0 taken 75 times.
✓ Branch 1 taken 12025 times.
|
12100 | if (structScope->isGenericScope) { |
1396 | 75 | Scope *matchScope = structScope->parent; | |
1397 |
2/4✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 75 times.
✗ Branch 5 not taken.
|
75 | Struct *spiceStruct = StructManager::match(matchScope, structName, lhsBaseTy.getTemplateTypes(), node); |
1398 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
|
75 | assert(spiceStruct != nullptr); |
1399 | 75 | structScope = spiceStruct->scope; | |
1400 | } | ||
1401 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12100 times.
|
12100 | assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope |
1402 | |||
1403 | // Get accessed field | ||
1404 | 12100 | std::vector<size_t> indexPath; | |
1405 |
1/2✓ Branch 1 taken 12100 times.
✗ Branch 2 not taken.
|
12100 | SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath); |
1406 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12098 times.
|
12100 | if (!memberEntry) |
1407 |
7/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
|
2 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Field '" + node->identifier + "' not found in struct " + structName) |
1408 |
1/2✓ Branch 1 taken 12098 times.
✗ Branch 2 not taken.
|
12098 | const QualType memberType = memberEntry->getQualType(); |
1409 | |||
1410 | // Check for insufficient visibility | ||
1411 |
8/14✓ Branch 1 taken 12098 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 67 times.
✓ Branch 4 taken 12031 times.
✓ Branch 6 taken 67 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 67 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 67 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 67 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 12098 times.
|
12098 | if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().getBase().isPublic()) |
1412 | ✗ | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access field '" + fieldName + "' due to its private visibility") | |
1413 | |||
1414 | // Set field to used | ||
1415 | 12098 | memberEntry->used = true; | |
1416 | |||
1417 | // Overwrite type and entry of left side with member type and entry | ||
1418 | 12098 | lhsType = memberType; | |
1419 | 12098 | lhsEntry = memberEntry; | |
1420 | 12098 | break; | |
1421 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12098 times.
|
12100 | } |
1422 | 1353 | case PostfixUnaryExprNode::OP_PLUS_PLUS: { | |
1423 |
2/2✓ Branch 0 taken 1348 times.
✓ Branch 1 taken 5 times.
|
1353 | if (lhsEntry) { |
1424 | // In case the lhs is captured, notify the capture about the write access | ||
1425 |
3/4✓ Branch 1 taken 1348 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1344 times.
|
1348 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsEntry->name); lhsCapture) |
1426 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | lhsCapture->setAccessType(READ_WRITE); |
1427 | |||
1428 | // Update the state of the variable | ||
1429 |
1/2✓ Branch 1 taken 1348 times.
✗ Branch 2 not taken.
|
1348 | lhsEntry->updateState(INITIALIZED, node, false); |
1430 | } | ||
1431 | |||
1432 |
2/2✓ Branch 1 taken 1352 times.
✓ Branch 2 taken 1 times.
|
1353 | auto [type, entry] = opRuleManager.getPostfixPlusPlusResultType(node, lhs, 0); |
1433 | 1352 | lhsType = type; | |
1434 | 1352 | lhsEntry = entry; | |
1435 | 1352 | break; | |
1436 | } | ||
1437 | 270 | case PostfixUnaryExprNode::OP_MINUS_MINUS: { | |
1438 |
2/2✓ Branch 0 taken 266 times.
✓ Branch 1 taken 4 times.
|
270 | if (lhsEntry) { |
1439 | // In case the lhs is captured, notify the capture about the write access | ||
1440 |
2/4✓ Branch 1 taken 266 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 266 times.
|
266 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsEntry->name); lhsCapture) |
1441 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
1442 | |||
1443 | // Update the state of the variable | ||
1444 |
1/2✓ Branch 1 taken 266 times.
✗ Branch 2 not taken.
|
266 | lhsEntry->updateState(INITIALIZED, node, false); |
1445 | } | ||
1446 | |||
1447 |
1/2✓ Branch 1 taken 270 times.
✗ Branch 2 not taken.
|
270 | ExprResult result = opRuleManager.getPostfixMinusMinusResultType(node, lhs, 0); |
1448 | 270 | lhsType = result.type; | |
1449 | 270 | lhsEntry = result.entry; | |
1450 | 270 | break; | |
1451 | } | ||
1452 | ✗ | default: | |
1453 | − | throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
1454 | } | ||
1455 | |||
1456 |
2/4✓ Branch 1 taken 16046 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 16046 times.
|
16046 | if (lhsType.is(TY_INVALID)) { |
1457 | ✗ | const std::string varName = lhsEntry ? lhsEntry->name : ""; | |
1458 | ✗ | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Variable '" + varName + "' was referenced before declared") | |
1459 | ✗ | } | |
1460 | |||
1461 |
2/4✓ Branch 1 taken 16046 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16046 times.
✗ Branch 5 not taken.
|
16046 | return ExprResult{node->setEvaluatedSymbolType(lhsType, manIdx), lhsEntry}; |
1462 | } | ||
1463 | |||
1464 | 60995 | std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) { | |
1465 | // Check if constant | ||
1466 |
3/4✓ Branch 1 taken 60995 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11919 times.
✓ Branch 4 taken 49076 times.
|
60995 | if (node->constant()) |
1467 |
2/4✓ Branch 1 taken 11919 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11919 times.
✗ Branch 5 not taken.
|
11919 | return visit(node->constant()); |
1468 | |||
1469 | // Check if value | ||
1470 |
3/4✓ Branch 1 taken 49076 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11362 times.
✓ Branch 4 taken 37714 times.
|
49076 | if (node->value()) |
1471 |
3/4✓ Branch 1 taken 11362 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11358 times.
✓ Branch 5 taken 4 times.
|
11362 | return visit(node->value()); |
1472 | |||
1473 | // Check for builtin calls | ||
1474 |
3/4✓ Branch 1 taken 37714 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 651 times.
✓ Branch 4 taken 37063 times.
|
37714 | if (node->printfCall()) |
1475 |
2/4✓ Branch 1 taken 651 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 651 times.
✗ Branch 5 not taken.
|
651 | return visit(node->printfCall()); |
1476 |
3/4✓ Branch 1 taken 37063 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 119 times.
✓ Branch 4 taken 36944 times.
|
37063 | if (node->sizeofCall()) |
1477 |
2/4✓ Branch 1 taken 119 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 119 times.
✗ Branch 5 not taken.
|
119 | return visit(node->sizeofCall()); |
1478 |
3/4✓ Branch 1 taken 36944 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 36933 times.
|
36944 | if (node->alignofCall()) |
1479 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
|
11 | return visit(node->alignofCall()); |
1480 |
3/4✓ Branch 1 taken 36933 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 36897 times.
|
36933 | if (node->lenCall()) |
1481 |
2/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
|
36 | return visit(node->lenCall()); |
1482 |
3/4✓ Branch 1 taken 36897 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 366 times.
✓ Branch 4 taken 36531 times.
|
36897 | if (node->panicCall()) |
1483 |
2/4✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 366 times.
✗ Branch 5 not taken.
|
366 | return visit(node->panicCall()); |
1484 |
3/4✓ Branch 1 taken 36531 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 36530 times.
|
36531 | if (node->sysCall()) |
1485 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | return visit(node->sysCall()); |
1486 | |||
1487 | // Check for assign expression within parentheses | ||
1488 |
3/4✓ Branch 1 taken 36530 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 523 times.
✓ Branch 4 taken 36007 times.
|
36530 | if (node->assignExpr()) |
1489 |
3/4✓ Branch 1 taken 523 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 520 times.
✓ Branch 5 taken 3 times.
|
523 | return visit(node->assignExpr()); |
1490 | |||
1491 | // Identifier (local or global variable access) | ||
1492 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36007 times.
|
36007 | assert(!node->fqIdentifier.empty()); |
1493 |
1/2✓ Branch 0 taken 36007 times.
✗ Branch 1 not taken.
|
36007 | if (!accessScope) |
1494 | 36007 | accessScope = currentScope; | |
1495 | |||
1496 | // Check if a local or global variable can be found by searching for the name | ||
1497 | 36007 | SymbolTableEntry *varEntry = nullptr; | |
1498 |
2/2✓ Branch 1 taken 35758 times.
✓ Branch 2 taken 249 times.
|
36007 | if (node->identifierFragments.size() == 1) |
1499 | 71516 | varEntry = accessScope->lookup(node->identifierFragments.back()); | |
1500 | |||
1501 | // If no local or global was found, search in the name registry | ||
1502 |
2/2✓ Branch 0 taken 308 times.
✓ Branch 1 taken 35699 times.
|
36007 | if (!varEntry) { |
1503 |
1/2✓ Branch 1 taken 308 times.
✗ Branch 2 not taken.
|
308 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier); |
1504 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 307 times.
|
308 | if (!registryEntry) |
1505 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found") |
1506 | 307 | varEntry = registryEntry->targetEntry; | |
1507 | 307 | accessScope = registryEntry->targetScope; | |
1508 | } | ||
1509 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36006 times.
|
36006 | assert(varEntry != nullptr); |
1510 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36006 times.
|
36006 | assert(accessScope != nullptr); |
1511 |
1/2✓ Branch 1 taken 36006 times.
✗ Branch 2 not taken.
|
36006 | AtomicExprNode::VarAccessData &data = node->data.at(manIdx); |
1512 |
1/2✓ Branch 1 taken 36006 times.
✗ Branch 2 not taken.
|
36006 | data = {varEntry, accessScope, accessScope->symbolTable.lookupCapture(varEntry->name)}; |
1513 |
1/2✓ Branch 1 taken 36006 times.
✗ Branch 2 not taken.
|
36006 | const QualType varType = varEntry->getQualType(); |
1514 |
6/10✓ Branch 1 taken 36006 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 35998 times.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
|
36006 | HANDLE_UNRESOLVED_TYPE_ER(varType) |
1515 | |||
1516 |
7/8✓ Branch 1 taken 35998 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 35954 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 35 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 35989 times.
|
35998 | if (varType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && varEntry->global) { |
1517 | // Check if overloaded function was referenced | ||
1518 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | const std::vector<Function *> *manifestations = varEntry->declNode->getFctManifestations(varEntry->name); |
1519 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
|
9 | if (manifestations->size() > 1) |
1520 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
3 | SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Overloaded functions / functions with optional params cannot be referenced") |
1521 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 7 times.
|
8 | if (!manifestations->front()->templateTypes.empty()) |
1522 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
3 | SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Generic functions cannot be referenced") |
1523 | // Set referenced function to used | ||
1524 | 7 | Function *referencedFunction = manifestations->front(); | |
1525 | 7 | referencedFunction->used = true; | |
1526 | 7 | referencedFunction->entry->used = true; | |
1527 | } | ||
1528 | |||
1529 |
3/4✓ Branch 1 taken 35996 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 35994 times.
|
35996 | if (varType.is(TY_INVALID)) |
1530 |
6/12✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
|
2 | SOFT_ERROR_ER(node, USED_BEFORE_DECLARED, "Symbol '" + varEntry->name + "' was used before declared.") |
1531 | |||
1532 | // The base type should be a primitive, struct, interface, function or procedure | ||
1533 |
1/2✓ Branch 1 taken 35994 times.
✗ Branch 2 not taken.
|
35994 | const QualType baseType = varType.getBase(); |
1534 |
6/10✓ Branch 1 taken 35994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13572 times.
✓ Branch 4 taken 22422 times.
✓ Branch 6 taken 13572 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 13572 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 35994 times.
|
35994 | if (!baseType.isPrimitive() && !baseType.isOneOf({TY_STRUCT, TY_INTERFACE, TY_FUNCTION, TY_PROCEDURE, TY_DYN})) |
1535 | ✗ | SOFT_ERROR_ER(node, INVALID_SYMBOL_ACCESS, "A symbol of type " + varType.getName(false) + " cannot be accessed here") | |
1536 | |||
1537 | // Check if is an imported variable | ||
1538 |
3/4✓ Branch 1 taken 35994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 171 times.
✓ Branch 4 taken 35823 times.
|
35994 | if (accessScope->isImportedBy(rootScope)) { |
1539 | // Check if the entry is public | ||
1540 |
8/10✓ Branch 0 taken 54 times.
✓ Branch 1 taken 117 times.
✓ Branch 3 taken 54 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 54 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 53 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 170 times.
|
171 | if (varEntry->scope->type != ScopeType::ENUM && !varEntry->getQualType().isPublic()) |
1541 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access '" + varEntry->name + "' due to its private visibility") |
1542 | } | ||
1543 | |||
1544 | // Check if we have seen a 'this.' prefix, because the generator needs that | ||
1545 |
6/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 35992 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 35992 times.
|
35993 | if (varEntry->scope->type == ScopeType::STRUCT && node->identifierFragments.front() != THIS_VARIABLE_NAME) |
1546 |
6/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, |
1547 | "The symbol '" + node->fqIdentifier + "' could not be found. Missing 'this.' prefix?") | ||
1548 | |||
1549 | // Set symbol table entry to used | ||
1550 | 35992 |