Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "TypeChecker.h" | ||
4 | |||
5 | #include <SourceFile.h> | ||
6 | #include <ast/ASTNodes.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 | 17119 | std::any TypeChecker::visitValue(ValueNode *node) { | |
17 | // Function call | ||
18 |
2/2✓ Branch 2 → 3 taken 15043 times.
✓ Branch 2 → 4 taken 2076 times.
|
17119 | if (node->fctCall) |
19 | 15043 | return visit(node->fctCall); | |
20 | |||
21 | // Array initialization | ||
22 |
2/2✓ Branch 4 → 5 taken 74 times.
✓ Branch 4 → 6 taken 2002 times.
|
2076 | if (node->arrayInitialization) |
23 | 74 | return visit(node->arrayInitialization); | |
24 | |||
25 | // Struct instantiation | ||
26 |
2/2✓ Branch 6 → 7 taken 290 times.
✓ Branch 6 → 8 taken 1712 times.
|
2002 | if (node->structInstantiation) |
27 | 290 | return visit(node->structInstantiation); | |
28 | |||
29 | // Lambda function | ||
30 |
2/2✓ Branch 8 → 9 taken 12 times.
✓ Branch 8 → 10 taken 1700 times.
|
1712 | if (node->lambdaFunc) |
31 | 12 | return visit(node->lambdaFunc); | |
32 | |||
33 | // Lambda procedure | ||
34 |
2/2✓ Branch 10 → 11 taken 28 times.
✓ Branch 10 → 12 taken 1672 times.
|
1700 | if (node->lambdaProc) |
35 | 28 | return visit(node->lambdaProc); | |
36 | |||
37 | // Lambda expression | ||
38 |
2/2✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 14 taken 1671 times.
|
1672 | if (node->lambdaExpr) |
39 | 1 | return visit(node->lambdaExpr); | |
40 | |||
41 | // Typed nil | ||
42 |
1/2✓ Branch 14 → 15 taken 1671 times.
✗ Branch 14 → 41 not taken.
|
1671 | if (node->isNil) { |
43 |
2/4✓ Branch 15 → 16 taken 1671 times.
✗ Branch 15 → 52 not taken.
✓ Branch 16 → 17 taken 1671 times.
✗ Branch 16 → 50 not taken.
|
1671 | const auto nilType = std::any_cast<QualType>(visit(node->nilType)); |
44 |
2/8✓ Branch 18 → 19 taken 1671 times.
✗ Branch 18 → 62 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 24 taken 1671 times.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 53 not taken.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 53 not taken.
|
1671 | HANDLE_UNRESOLVED_TYPE_ER(nilType) |
45 |
2/4✓ Branch 24 → 25 taken 1671 times.
✗ Branch 24 → 62 not taken.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 36 taken 1671 times.
|
1671 | if (nilType.is(TY_DYN)) |
46 | ✗ | SOFT_ERROR_ER(node->nilType, UNEXPECTED_DYN_TYPE, "Nil must have an explicit type") | |
47 |
2/4✓ Branch 36 → 37 taken 1671 times.
✗ Branch 36 → 61 not taken.
✓ Branch 37 → 38 taken 1671 times.
✗ Branch 37 → 61 not taken.
|
1671 | return ExprResult{node->setEvaluatedSymbolType(nilType, manIdx)}; |
48 | } | ||
49 | |||
50 | − | throw CompilerError(UNHANDLED_BRANCH, "Value fall-through"); // GCOV_EXCL_LINE | |
51 | } | ||
52 | |||
53 | 19996 | std::any TypeChecker::visitConstant(ConstantNode *node) { | |
54 | SuperType superType; | ||
55 |
7/9✓ Branch 2 → 3 taken 418 times.
✓ Branch 2 → 4 taken 3514 times.
✓ Branch 2 → 5 taken 582 times.
✓ Branch 2 → 6 taken 7388 times.
✗ Branch 2 → 7 not taken.
✓ Branch 2 → 8 taken 2291 times.
✓ Branch 2 → 9 taken 3409 times.
✓ Branch 2 → 10 taken 2394 times.
✗ Branch 2 → 11 not taken.
|
19996 | switch (node->type) { |
56 | 418 | case ConstantNode::PrimitiveValueType::TYPE_DOUBLE: | |
57 | 418 | superType = TY_DOUBLE; | |
58 | 418 | break; | |
59 | 3514 | case ConstantNode::PrimitiveValueType::TYPE_INT: | |
60 | 3514 | superType = TY_INT; | |
61 | 3514 | break; | |
62 | 582 | case ConstantNode::PrimitiveValueType::TYPE_SHORT: | |
63 | 582 | superType = TY_SHORT; | |
64 | 582 | break; | |
65 | 7388 | case ConstantNode::PrimitiveValueType::TYPE_LONG: | |
66 | 7388 | superType = TY_LONG; | |
67 | 7388 | break; | |
68 | ✗ | case ConstantNode::PrimitiveValueType::TYPE_BYTE: | |
69 | ✗ | superType = TY_BYTE; | |
70 | ✗ | break; | |
71 | 2291 | case ConstantNode::PrimitiveValueType::TYPE_CHAR: | |
72 | 2291 | superType = TY_CHAR; | |
73 | 2291 | break; | |
74 | 3409 | case ConstantNode::PrimitiveValueType::TYPE_STRING: | |
75 | 3409 | superType = TY_STRING; | |
76 | 3409 | break; | |
77 | 2394 | case ConstantNode::PrimitiveValueType::TYPE_BOOL: | |
78 | 2394 | superType = TY_BOOL; | |
79 | 2394 | break; | |
80 | − | default: // GCOV_EXCL_LINE | |
81 | − | throw CompilerError(UNHANDLED_BRANCH, "Constant fall-through"); // GCOV_EXCL_LINE | |
82 | } | ||
83 |
3/6✓ Branch 19 → 20 taken 19996 times.
✗ Branch 19 → 34 not taken.
✓ Branch 20 → 21 taken 19996 times.
✗ Branch 20 → 34 not taken.
✓ Branch 21 → 22 taken 19996 times.
✗ Branch 21 → 34 not taken.
|
19996 | return ExprResult{node->setEvaluatedSymbolType(QualType(superType), manIdx)}; |
84 | } | ||
85 | |||
86 | 15043 | std::any TypeChecker::visitFctCall(FctCallNode *node) { | |
87 |
1/2✓ Branch 2 → 3 taken 15043 times.
✗ Branch 2 → 501 not taken.
|
15043 | FctCallNode::FctCallData &data = node->data.at(manIdx); |
88 | 15043 | auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
89 | |||
90 | // Retrieve arg types | ||
91 | 15043 | args.clear(); | |
92 |
2/2✓ Branch 4 → 5 taken 11626 times.
✓ Branch 4 → 28 taken 3417 times.
|
15043 | if (node->hasArgs) { |
93 |
1/2✓ Branch 6 → 7 taken 11626 times.
✗ Branch 6 → 501 not taken.
|
11626 | args.reserve(node->argLst->args.size()); |
94 |
2/2✓ Branch 26 → 9 taken 18121 times.
✓ Branch 26 → 27 taken 11626 times.
|
29747 | for (AssignExprNode *arg : node->argLst->args) { |
95 | // Visit argument | ||
96 |
2/4✓ Branch 10 → 11 taken 18121 times.
✗ Branch 10 → 386 not taken.
✓ Branch 11 → 12 taken 18121 times.
✗ Branch 11 → 384 not taken.
|
18121 | const auto argResult = std::any_cast<ExprResult>(visit(arg)); |
97 |
2/8✓ Branch 13 → 14 taken 18121 times.
✗ Branch 13 → 389 not taken.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 19 taken 18121 times.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 387 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 387 not taken.
|
18121 | HANDLE_UNRESOLVED_TYPE_ER(argResult.type) |
98 |
2/4✓ Branch 19 → 20 taken 18121 times.
✗ Branch 19 → 389 not taken.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 18121 times.
|
18121 | assert(!argResult.type.hasAnyGenericParts()); |
99 | // Save arg type to arg types list | ||
100 |
1/2✓ Branch 23 → 24 taken 18121 times.
✗ Branch 23 → 388 not taken.
|
18121 | args.emplace_back(argResult.type, argResult.isTemporary()); |
101 | } | ||
102 | } | ||
103 | |||
104 | // Retrieve entry of the first fragment | ||
105 | 15043 | const std::string &firstFrag = node->functionNameFragments.front(); | |
106 |
1/2✓ Branch 29 → 30 taken 15043 times.
✗ Branch 29 → 501 not taken.
|
15043 | SymbolTableEntry *firstFragEntry = currentScope->lookup(firstFrag); |
107 |
2/2✓ Branch 32 → 33 taken 9422 times.
✓ Branch 32 → 70 taken 5621 times.
|
15043 | if (firstFragEntry) { |
108 | // Check if we have seen a 'this.' prefix, because the generator needs that | ||
109 |
6/8✓ Branch 33 → 34 taken 1 time.
✓ Branch 33 → 37 taken 9421 times.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 401 not taken.
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 37 not taken.
✓ Branch 38 → 39 taken 1 time.
✓ Branch 38 → 48 taken 9421 times.
|
9422 | if (firstFragEntry->scope->type == ScopeType::STRUCT && firstFrag != THIS_VARIABLE_NAME) |
110 |
5/10✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 395 not taken.
✓ Branch 40 → 41 taken 1 time.
✗ Branch 40 → 393 not taken.
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 391 not taken.
✓ Branch 44 → 45 taken 1 time.
✗ Branch 44 → 397 not taken.
✓ Branch 45 → 46 taken 1 time.
✗ Branch 45 → 397 not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, |
111 | "The symbol '" + firstFrag + "' could not be found. Missing 'this.' prefix?") | ||
112 | |||
113 | 9421 | firstFragEntry->used = true; | |
114 | // Decide of which type the function call is | ||
115 |
2/4✓ Branch 48 → 49 taken 9421 times.
✗ Branch 48 → 401 not taken.
✓ Branch 49 → 50 taken 9421 times.
✗ Branch 49 → 401 not taken.
|
9421 | const QualType &baseType = firstFragEntry->getQualType().getBase(); |
116 |
5/8✓ Branch 50 → 51 taken 9421 times.
✗ Branch 50 → 401 not taken.
✓ Branch 51 → 52 taken 4 times.
✓ Branch 51 → 56 taken 9417 times.
✓ Branch 52 → 53 taken 4 times.
✗ Branch 52 → 398 not taken.
✓ Branch 53 → 54 taken 4 times.
✗ Branch 53 → 398 not taken.
|
9421 | HANDLE_UNRESOLVED_TYPE_ER(baseType) |
117 |
3/4✓ Branch 56 → 57 taken 9417 times.
✗ Branch 56 → 399 not taken.
✓ Branch 57 → 58 taken 7060 times.
✓ Branch 57 → 61 taken 2357 times.
|
9417 | if (baseType.isOneOf({TY_STRUCT, TY_INTERFACE})) { |
118 |
2/2✓ Branch 58 → 59 taken 1022 times.
✓ Branch 58 → 60 taken 6038 times.
|
7060 | if (firstFragEntry->scope->type == ScopeType::GLOBAL) |
119 | 1022 | callType = FctCallNode::FctCallType::TYPE_CTOR; | |
120 | else | ||
121 | 6038 | callType = FctCallNode::FctCallType::TYPE_METHOD; | |
122 |
7/8✓ Branch 61 → 62 taken 2357 times.
✗ Branch 61 → 400 not taken.
✓ Branch 62 → 63 taken 2289 times.
✓ Branch 62 → 65 taken 68 times.
✓ Branch 63 → 64 taken 48 times.
✓ Branch 63 → 65 taken 2241 times.
✓ Branch 66 → 67 taken 48 times.
✓ Branch 66 → 68 taken 2309 times.
|
2357 | } else if (baseType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && firstFragEntry->scope->type != ScopeType::GLOBAL) { |
123 | 48 | callType = FctCallNode::FctCallType::TYPE_FCT_PTR; | |
124 | } | ||
125 | } | ||
126 | |||
127 | // Get struct name. Retrieve it from alias if required | ||
128 |
1/2✓ Branch 70 → 71 taken 15038 times.
✗ Branch 70 → 501 not taken.
|
15038 | const auto &[structEntry, isAlias] = rootScope->symbolTable.lookupWithAliasResolution(node->fqFunctionName); |
129 |
4/6✓ Branch 73 → 74 taken 1 time.
✓ Branch 73 → 77 taken 15037 times.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 501 not taken.
✓ Branch 75 → 76 taken 1 time.
✗ Branch 75 → 501 not taken.
|
15038 | const std::string &fqFunctionName = isAlias ? structEntry->getQualType().getSubType() : node->fqFunctionName; |
130 | |||
131 | // Get the concrete template types | ||
132 | 15038 | templateTypes.clear(); | |
133 |
2/2✓ Branch 79 → 80 taken 1 time.
✓ Branch 79 → 99 taken 15037 times.
|
15038 | if (isAlias) { |
134 | // Retrieve concrete template types from type alias | ||
135 |
3/6✓ Branch 80 → 81 taken 1 time.
✗ Branch 80 → 501 not taken.
✓ Branch 81 → 82 taken 1 time.
✗ Branch 81 → 501 not taken.
✓ Branch 82 → 83 taken 1 time.
✗ Branch 82 → 501 not taken.
|
1 | templateTypes = structEntry->getQualType().getTemplateTypes(); |
136 | // Check if the aliased type specified template types and the struct instantiation does | ||
137 |
3/6✓ Branch 84 → 85 taken 1 time.
✗ Branch 84 → 87 not taken.
✗ Branch 85 → 86 not taken.
✓ Branch 85 → 87 taken 1 time.
✗ Branch 88 → 89 not taken.
✓ Branch 88 → 99 taken 1 time.
|
1 | if (!templateTypes.empty() && node->hasTemplateTypes) |
138 | ✗ | SOFT_ERROR_ER(node->templateTypeLst, ALIAS_WITH_TEMPLATE_LIST, "The aliased type already has a template list") | |
139 | } | ||
140 | |||
141 | // Get concrete template types | ||
142 |
2/2✓ Branch 99 → 100 taken 609 times.
✓ Branch 99 → 135 taken 14429 times.
|
15038 | if (node->hasTemplateTypes) { |
143 |
2/2✓ Branch 133 → 102 taken 723 times.
✓ Branch 133 → 134 taken 609 times.
|
1332 | for (DataTypeNode *templateTypeNode : node->templateTypeLst->dataTypes) { |
144 |
2/4✓ Branch 103 → 104 taken 723 times.
✗ Branch 103 → 411 not taken.
✓ Branch 104 → 105 taken 723 times.
✗ Branch 104 → 409 not taken.
|
723 | auto templateType = std::any_cast<QualType>(visit(templateTypeNode)); |
145 |
2/4✓ Branch 106 → 107 taken 723 times.
✗ Branch 106 → 412 not taken.
✗ Branch 107 → 108 not taken.
✓ Branch 107 → 109 taken 723 times.
|
723 | assert(!templateType.isOneOf({TY_DYN, TY_INVALID})); |
146 | |||
147 | // Abort if the type is unresolved | ||
148 |
2/4✓ Branch 109 → 110 taken 723 times.
✗ Branch 109 → 422 not taken.
✗ Branch 110 → 111 not taken.
✓ Branch 110 → 117 taken 723 times.
|
723 | if (templateType.is(TY_UNRESOLVED)) |
149 | ✗ | HANDLE_UNRESOLVED_TYPE_ER(templateType) | |
150 | |||
151 | // Check if the given type is generic | ||
152 |
2/4✓ Branch 117 → 118 taken 723 times.
✗ Branch 117 → 422 not taken.
✗ Branch 118 → 119 not taken.
✓ Branch 118 → 129 taken 723 times.
|
723 | if (templateType.is(TY_GENERIC)) |
153 | ✗ | SOFT_ERROR_ER(templateTypeNode, EXPECTED_NON_GENERIC_TYPE, "You must specify a concrete type here") | |
154 | |||
155 |
1/2✓ Branch 129 → 130 taken 723 times.
✗ Branch 129 → 422 not taken.
|
723 | templateTypes.push_back(templateType); |
156 | } | ||
157 | } | ||
158 | |||
159 | // Check if this is a method call or a normal function call | ||
160 |
2/2✓ Branch 136 → 137 taken 6038 times.
✓ Branch 136 → 151 taken 9000 times.
|
15038 | if (data.isMethodCall()) { |
161 | // This is a method call | ||
162 |
1/2✓ Branch 137 → 138 taken 6038 times.
✗ Branch 137 → 501 not taken.
|
6038 | thisType = firstFragEntry->getQualType(); |
163 |
2/4✓ Branch 138 → 139 taken 6038 times.
✗ Branch 138 → 424 not taken.
✓ Branch 139 → 140 taken 6038 times.
✗ Branch 139 → 424 not taken.
|
6038 | Scope *structBodyScope = thisType.getBase().getBodyScope(); |
164 |
1/2✗ Branch 140 → 141 not taken.
✓ Branch 140 → 142 taken 6038 times.
|
6038 | assert(structBodyScope != nullptr); |
165 |
3/4✓ Branch 142 → 143 taken 6038 times.
✗ Branch 142 → 501 not taken.
✓ Branch 143 → 144 taken 2 times.
✓ Branch 143 → 149 taken 6036 times.
|
6038 | if (!visitMethodCall(node, structBodyScope)) // Check if soft errors occurred |
166 |
3/6✓ Branch 144 → 145 taken 2 times.
✗ Branch 144 → 425 not taken.
✓ Branch 145 → 146 taken 2 times.
✗ Branch 145 → 425 not taken.
✓ Branch 146 → 147 taken 2 times.
✗ Branch 146 → 425 not taken.
|
2 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)}; |
167 |
1/2✗ Branch 149 → 150 not taken.
✓ Branch 149 → 187 taken 6036 times.
|
6036 | assert(calleeParentScope != nullptr); |
168 |
2/2✓ Branch 152 → 153 taken 48 times.
✓ Branch 152 → 166 taken 8952 times.
|
9000 | } else if (data.isFctPtrCall()) { |
169 | // This is a function pointer call | ||
170 |
2/4✓ Branch 153 → 154 taken 48 times.
✗ Branch 153 → 430 not taken.
✓ Branch 154 → 155 taken 48 times.
✗ Branch 154 → 430 not taken.
|
48 | const QualType &functionType = firstFragEntry->getQualType().getBase(); |
171 |
2/4✓ Branch 155 → 156 taken 48 times.
✗ Branch 155 → 427 not taken.
✗ Branch 156 → 157 not taken.
✓ Branch 156 → 158 taken 48 times.
|
48 | assert(functionType.isOneOf({TY_FUNCTION, TY_PROCEDURE})); |
172 |
2/4✓ Branch 158 → 159 taken 48 times.
✗ Branch 158 → 430 not taken.
✗ Branch 159 → 160 not taken.
✓ Branch 159 → 165 taken 48 times.
|
48 | if (!visitFctPtrCall(node, functionType)) // Check if soft errors occurred |
173 | ✗ | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)}; | |
174 | } else { | ||
175 | // This is an ordinary function call | ||
176 |
3/4✓ Branch 167 → 168 taken 1027 times.
✓ Branch 167 → 171 taken 7925 times.
✗ Branch 169 → 170 not taken.
✓ Branch 169 → 171 taken 1027 times.
|
8952 | assert(data.isOrdinaryCall() || data.isCtorCall()); |
177 |
5/6✓ Branch 171 → 172 taken 8952 times.
✗ Branch 171 → 433 not taken.
✓ Branch 172 → 173 taken 8950 times.
✓ Branch 172 → 431 taken 2 times.
✓ Branch 174 → 175 taken 4 times.
✓ Branch 174 → 180 taken 8946 times.
|
8954 | if (!visitOrdinaryFctCall(node, fqFunctionName)) // Check if soft errors occurred |
178 |
3/6✓ Branch 175 → 176 taken 4 times.
✗ Branch 175 → 434 not taken.
✓ Branch 176 → 177 taken 4 times.
✗ Branch 176 → 434 not taken.
✓ Branch 177 → 178 taken 4 times.
✗ Branch 177 → 434 not taken.
|
4 | return ExprResult{node->setEvaluatedSymbolType(QualType(TY_UNRESOLVED), manIdx)}; |
179 |
1/2✗ Branch 180 → 181 not taken.
✓ Branch 180 → 182 taken 8946 times.
|
8946 | assert(calleeParentScope != nullptr); |
180 | |||
181 | // If the call is no ordinary call, it must be a constructor, which takes a struct as this type. | ||
182 |
4/6✓ Branch 183 → 184 taken 2271 times.
✓ Branch 183 → 187 taken 6675 times.
✓ Branch 184 → 185 taken 2271 times.
✗ Branch 184 → 501 not taken.
✗ Branch 185 → 186 not taken.
✓ Branch 185 → 187 taken 2271 times.
|
8946 | assert(data.isOrdinaryCall() || data.thisType.is(TY_STRUCT)); |
183 | } | ||
184 | |||
185 |
2/2✓ Branch 188 → 189 taken 14982 times.
✓ Branch 188 → 260 taken 48 times.
|
15030 | if (!data.isFctPtrCall()) { |
186 | // Check if we were able to find a function | ||
187 |
2/2✓ Branch 189 → 190 taken 12 times.
✓ Branch 189 → 227 taken 14970 times.
|
14982 | if (!callee) { |
188 | // Build error message | ||
189 |
6/10✓ Branch 191 → 192 taken 2 times.
✓ Branch 191 → 195 taken 10 times.
✓ Branch 194 → 197 taken 2 times.
✗ Branch 194 → 436 not taken.
✓ Branch 196 → 197 taken 10 times.
✗ Branch 196 → 436 not taken.
✓ Branch 197 → 198 taken 2 times.
✓ Branch 197 → 200 taken 10 times.
✗ Branch 436 → 437 not taken.
✗ Branch 436 → 439 not taken.
|
14 | const std::string functionName = data.isCtorCall() ? CTOR_FUNCTION_NAME : node->functionNameFragments.back(); |
190 | 12 | ParamList errArgTypes; | |
191 |
1/2✓ Branch 201 → 202 taken 12 times.
✗ Branch 201 → 456 not taken.
|
12 | errArgTypes.reserve(args.size()); |
192 |
5/8✓ Branch 202 → 203 taken 12 times.
✗ Branch 202 → 442 not taken.
✓ Branch 203 → 204 taken 12 times.
✗ Branch 203 → 442 not taken.
✓ Branch 204 → 205 taken 12 times.
✗ Branch 204 → 442 not taken.
✓ Branch 210 → 206 taken 7 times.
✓ Branch 210 → 211 taken 12 times.
|
19 | for (const auto &type : args | std::views::keys) |
193 |
1/2✓ Branch 207 → 208 taken 7 times.
✗ Branch 207 → 441 not taken.
|
7 | errArgTypes.push_back({type, false}); |
194 |
2/4✓ Branch 212 → 213 taken 12 times.
✗ Branch 212 → 443 not taken.
✓ Branch 213 → 214 taken 12 times.
✗ Branch 213 → 443 not taken.
|
12 | const std::string signature = Function::getSignature(functionName, thisType, QualType(TY_DYN), errArgTypes, {}, false); |
195 | // Throw error | ||
196 |
5/10✓ Branch 215 → 216 taken 12 times.
✗ Branch 215 → 451 not taken.
✓ Branch 216 → 217 taken 12 times.
✗ Branch 216 → 449 not taken.
✓ Branch 217 → 218 taken 12 times.
✗ Branch 217 → 447 not taken.
✓ Branch 220 → 221 taken 12 times.
✗ Branch 220 → 453 not taken.
✓ Branch 221 → 222 taken 12 times.
✗ Branch 221 → 453 not taken.
|
12 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_FUNCTION, "Function/procedure '" + signature + "' could not be found") |
197 | 12 | } | |
198 | |||
199 | // Check if we need to request a re-visit, because the function body was not type-checked yet | ||
200 |
1/2✓ Branch 227 → 228 taken 14970 times.
✗ Branch 227 → 501 not taken.
|
14970 | requestRevisitIfRequired(callee); |
201 | |||
202 | // Get function entry from function object | ||
203 | 14970 | SymbolTableEntry *functionEntry = callee->entry; | |
204 | |||
205 | // Check if the called function has sufficient visibility | ||
206 |
1/2✓ Branch 228 → 229 taken 14970 times.
✗ Branch 228 → 501 not taken.
|
14970 | isImported = calleeParentScope->isImportedBy(rootScope); |
207 |
8/10✓ Branch 229 → 230 taken 4386 times.
✓ Branch 229 → 234 taken 10584 times.
✓ Branch 230 → 231 taken 4386 times.
✗ Branch 230 → 501 not taken.
✓ Branch 231 → 232 taken 4386 times.
✗ Branch 231 → 501 not taken.
✓ Branch 232 → 233 taken 1 time.
✓ Branch 232 → 234 taken 4385 times.
✓ Branch 235 → 236 taken 1 time.
✓ Branch 235 → 260 taken 14969 times.
|
14970 | if (isImported && !functionEntry->getQualType().isPublic()) { |
208 |
1/2✓ Branch 236 → 237 taken 1 time.
✗ Branch 236 → 477 not taken.
|
1 | const QualType functionEntryType = functionEntry->getQualType(); |
209 |
1/2✓ Branch 237 → 238 taken 1 time.
✗ Branch 237 → 477 not taken.
|
1 | const std::string signature = callee->getSignature(); |
210 |
2/4✓ Branch 238 → 239 taken 1 time.
✗ Branch 238 → 475 not taken.
✓ Branch 239 → 240 taken 1 time.
✗ Branch 239 → 249 not taken.
|
1 | if (functionEntryType.is(TY_FUNCTION)) |
211 |
5/10✓ Branch 240 → 241 taken 1 time.
✗ Branch 240 → 465 not taken.
✓ Branch 241 → 242 taken 1 time.
✗ Branch 241 → 463 not taken.
✓ Branch 242 → 243 taken 1 time.
✗ Branch 242 → 461 not taken.
✓ Branch 245 → 246 taken 1 time.
✗ Branch 245 → 467 not taken.
✓ Branch 246 → 247 taken 1 time.
✗ Branch 246 → 467 not taken.
|
1 | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Function '" + signature + "' has insufficient visibility") |
212 | else | ||
213 | ✗ | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Procedure '" + signature + "' has insufficient visibility") | |
214 | 1 | } | |
215 | } | ||
216 | |||
217 | // Generate arg infos | ||
218 |
2/2✓ Branch 260 → 261 taken 11614 times.
✓ Branch 260 → 302 taken 3403 times.
|
15017 | if (node->hasArgs) { |
219 | 11614 | QualTypeList paramTypes; | |
220 |
2/2✓ Branch 262 → 263 taken 25 times.
✓ Branch 262 → 269 taken 11589 times.
|
11614 | if (data.isFctPtrCall()) { |
221 |
2/4✓ Branch 263 → 264 taken 25 times.
✗ Branch 263 → 479 not taken.
✓ Branch 264 → 265 taken 25 times.
✗ Branch 264 → 479 not taken.
|
25 | const QualType &functionType = firstFragEntry->getQualType().getBase(); |
222 |
1/2✓ Branch 265 → 266 taken 25 times.
✗ Branch 265 → 478 not taken.
|
25 | paramTypes = functionType.getFunctionParamTypes(); |
223 | } else { | ||
224 |
1/2✗ Branch 269 → 270 not taken.
✓ Branch 269 → 271 taken 11589 times.
|
11589 | assert(callee != nullptr); |
225 |
1/2✓ Branch 271 → 272 taken 11589 times.
✗ Branch 271 → 480 not taken.
|
11589 | paramTypes = callee->getParamTypes(); |
226 | } | ||
227 | |||
228 | 11614 | node->argLst->argInfos.clear(); | |
229 |
2/2✓ Branch 295 → 277 taken 18106 times.
✓ Branch 295 → 296 taken 11614 times.
|
29720 | for (size_t argIdx = 0; argIdx < args.size(); argIdx++) { |
230 |
1/2✓ Branch 277 → 278 taken 18106 times.
✗ Branch 277 → 482 not taken.
|
18106 | const QualType &expectedType = paramTypes.at(argIdx); |
231 |
1/2✓ Branch 278 → 279 taken 18106 times.
✗ Branch 278 → 482 not taken.
|
18106 | const auto &[actualType, _] = args.at(argIdx); |
232 | |||
233 | 18106 | Function *copyCtor = nullptr; | |
234 |
10/14✓ Branch 281 → 282 taken 18106 times.
✗ Branch 281 → 482 not taken.
✓ Branch 282 → 283 taken 32 times.
✓ Branch 282 → 288 taken 18074 times.
✓ Branch 283 → 284 taken 32 times.
✗ Branch 283 → 482 not taken.
✓ Branch 284 → 285 taken 32 times.
✗ Branch 284 → 288 not taken.
✓ Branch 285 → 286 taken 32 times.
✗ Branch 285 → 482 not taken.
✓ Branch 286 → 287 taken 14 times.
✓ Branch 286 → 288 taken 18 times.
✓ Branch 289 → 290 taken 14 times.
✓ Branch 289 → 292 taken 18092 times.
|
18106 | if (expectedType.is(TY_STRUCT) && actualType.is(TY_STRUCT) && !actualType.isTriviallyCopyable(node)) { |
235 |
1/2✓ Branch 290 → 291 taken 14 times.
✗ Branch 290 → 482 not taken.
|
14 | copyCtor = matchCopyCtor(actualType, node); |
236 | // Insert anonymous symbol to track the dtor call of the copy | ||
237 |
1/2✓ Branch 291 → 292 taken 14 times.
✗ Branch 291 → 482 not taken.
|
14 | currentScope->symbolTable.insertAnonymous(actualType, node, argIdx + 1); // +1 because 0 is reserved for return value |
238 | } | ||
239 | |||
240 |
1/2✓ Branch 292 → 293 taken 18106 times.
✗ Branch 292 → 481 not taken.
|
18106 | node->argLst->argInfos.push_back(ArgLstNode::ArgInfo{copyCtor}); |
241 | } | ||
242 |
1/2✗ Branch 298 → 299 not taken.
✓ Branch 298 → 300 taken 11614 times.
|
11614 | assert(node->argLst->argInfos.size() == node->argLst->args.size()); |
243 | 11614 | } | |
244 | |||
245 | // Retrieve return type | ||
246 |
6/10✓ Branch 303 → 304 taken 48 times.
✓ Branch 303 → 308 taken 14969 times.
✓ Branch 304 → 305 taken 48 times.
✗ Branch 304 → 485 not taken.
✓ Branch 305 → 306 taken 48 times.
✗ Branch 305 → 485 not taken.
✓ Branch 306 → 307 taken 48 times.
✗ Branch 306 → 485 not taken.
✓ Branch 308 → 309 taken 14969 times.
✗ Branch 308 → 485 not taken.
|
29986 | const bool isFct = data.isFctPtrCall() ? firstFragEntry->getQualType().getBase().is(TY_FUNCTION) : callee->isFunction(); |
247 | 15017 | QualType returnType; | |
248 |
2/2✓ Branch 313 → 314 taken 48 times.
✓ Branch 313 → 321 taken 14969 times.
|
15017 | if (data.isFctPtrCall()) { |
249 |
6/10✓ Branch 314 → 315 taken 20 times.
✓ Branch 314 → 319 taken 28 times.
✓ Branch 315 → 316 taken 20 times.
✗ Branch 315 → 486 not taken.
✓ Branch 316 → 317 taken 20 times.
✗ Branch 316 → 486 not taken.
✓ Branch 317 → 318 taken 20 times.
✗ Branch 317 → 486 not taken.
✓ Branch 319 → 320 taken 28 times.
✗ Branch 319 → 486 not taken.
|
48 | returnType = isFct ? firstFragEntry->getQualType().getBase().getFunctionReturnType() : QualType(TY_BOOL); |
250 |
2/2✓ Branch 322 → 323 taken 2269 times.
✓ Branch 322 → 324 taken 12700 times.
|
14969 | } else if (data.isCtorCall()) { |
251 | 2269 | returnType = thisType; | |
252 |
3/4✓ Branch 324 → 325 taken 12700 times.
✗ Branch 324 → 501 not taken.
✓ Branch 327 → 328 taken 2908 times.
✓ Branch 327 → 330 taken 9792 times.
|
25400 | } else if (callee->isProcedure()) { |
253 |
1/2✓ Branch 328 → 329 taken 2908 times.
✗ Branch 328 → 488 not taken.
|
2908 | returnType = QualType(TY_DYN); |
254 | } else { | ||
255 | 9792 | returnType = callee->returnType; | |
256 | } | ||
257 |
1/2✓ Branch 331 → 332 taken 15017 times.
✗ Branch 331 → 501 not taken.
|
15017 | const QualType returnBaseType = returnType.getBase(); |
258 | |||
259 | // Make sure this source file knows about the return type | ||
260 |
3/4✓ Branch 332 → 333 taken 15017 times.
✗ Branch 332 → 501 not taken.
✓ Branch 333 → 334 taken 3602 times.
✓ Branch 333 → 337 taken 11415 times.
|
15017 | if (returnBaseType.is(TY_STRUCT)) |
261 |
2/4✓ Branch 334 → 335 taken 3602 times.
✗ Branch 334 → 489 not taken.
✓ Branch 335 → 336 taken 3602 times.
✗ Branch 335 → 489 not taken.
|
3602 | returnType = mapImportedScopeTypeToLocalType(returnBaseType.getBodyScope(), returnType); |
262 | |||
263 | // Add anonymous symbol to keep track of dtor call, if non-trivially destructible | ||
264 | 15017 | SymbolTableEntry *anonymousSymbol = nullptr; | |
265 |
8/10✓ Branch 337 → 338 taken 15017 times.
✗ Branch 337 → 501 not taken.
✓ Branch 338 → 339 taken 3149 times.
✓ Branch 338 → 342 taken 11868 times.
✓ Branch 339 → 340 taken 3149 times.
✗ Branch 339 → 501 not taken.
✓ Branch 340 → 341 taken 2078 times.
✓ Branch 340 → 342 taken 1071 times.
✓ Branch 343 → 344 taken 2078 times.
✓ Branch 343 → 346 taken 12939 times.
|
15017 | if (returnType.is(TY_STRUCT) && !returnType.isTriviallyDestructible(node)) |
266 |
1/2✓ Branch 344 → 345 taken 2078 times.
✗ Branch 344 → 501 not taken.
|
2078 | anonymousSymbol = currentScope->symbolTable.insertAnonymous(returnType, node); |
267 | |||
268 | // Remove public qualifier to not have public local variables | ||
269 | 15017 | returnType.getQualifiers().isPublic = false; | |
270 | |||
271 | // Check if the return value gets discarded | ||
272 |
7/8✓ Branch 347 → 348 taken 9812 times.
✓ Branch 347 → 351 taken 5205 times.
✓ Branch 348 → 349 taken 9812 times.
✗ Branch 348 → 501 not taken.
✓ Branch 349 → 350 taken 234 times.
✓ Branch 349 → 351 taken 9578 times.
✓ Branch 352 → 353 taken 234 times.
✓ Branch 352 → 378 taken 14783 times.
|
15017 | if (isFct && !node->hasReturnValueReceiver()) { |
273 | // Check if we want to ignore the discarded return value | ||
274 | 234 | bool ignoreUnusedReturnValue = false; | |
275 |
2/2✓ Branch 354 → 355 taken 231 times.
✓ Branch 354 → 375 taken 3 times.
|
234 | if (!data.isFctPtrCall()) { |
276 |
1/2✗ Branch 355 → 356 not taken.
✓ Branch 355 → 357 taken 231 times.
|
231 | assert(callee != nullptr); |
277 |
1/2✓ Branch 357 → 358 taken 231 times.
✗ Branch 357 → 359 not taken.
|
231 | auto fctDef = dynamic_cast<const FctDefNode *>(callee->declNode); |
278 |
12/18✓ Branch 360 → 361 taken 117 times.
✓ Branch 360 → 368 taken 114 times.
✓ Branch 361 → 362 taken 27 times.
✓ Branch 361 → 368 taken 90 times.
✓ Branch 364 → 365 taken 27 times.
✗ Branch 364 → 490 not taken.
✓ Branch 365 → 366 taken 27 times.
✗ Branch 365 → 490 not taken.
✓ Branch 366 → 367 taken 26 times.
✓ Branch 366 → 368 taken 1 time.
✓ Branch 369 → 370 taken 27 times.
✓ Branch 369 → 371 taken 204 times.
✓ Branch 371 → 372 taken 27 times.
✓ Branch 371 → 374 taken 204 times.
✗ Branch 490 → 491 not taken.
✗ Branch 490 → 492 not taken.
✗ Branch 494 → 495 not taken.
✗ Branch 494 → 497 not taken.
|
285 | ignoreUnusedReturnValue = fctDef && fctDef->attrs && fctDef->attrs->attrLst->hasAttr(ATTR_IGNORE_UNUSED_RETURN_VALUE); |
279 | } | ||
280 | |||
281 |
2/2✓ Branch 375 → 376 taken 208 times.
✓ Branch 375 → 378 taken 26 times.
|
234 | if (!ignoreUnusedReturnValue) |
282 |
1/2✓ Branch 376 → 377 taken 208 times.
✗ Branch 376 → 499 not taken.
|
208 | warnings.emplace_back(node->codeLoc, UNUSED_RETURN_VALUE, "The return value of the function call is unused"); |
283 | } | ||
284 | |||
285 |
2/4✓ Branch 378 → 379 taken 15017 times.
✗ Branch 378 → 500 not taken.
✓ Branch 379 → 380 taken 15017 times.
✗ Branch 379 → 500 not taken.
|
15017 | return ExprResult{node->setEvaluatedSymbolType(returnType, manIdx), anonymousSymbol}; |
286 | } | ||
287 | |||
288 | 8952 | bool TypeChecker::visitOrdinaryFctCall(FctCallNode *node, std::string fqFunctionName) { | |
289 |
1/2✓ Branch 2 → 3 taken 8952 times.
✗ Branch 2 → 106 not taken.
|
8952 | FctCallNode::FctCallData &data = node->data.at(manIdx); |
290 | 8952 | auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
291 | |||
292 | // Check if this is a well-known ctor/fct call | ||
293 |
2/2✓ Branch 4 → 5 taken 8890 times.
✓ Branch 4 → 7 taken 62 times.
|
8952 | if (node->functionNameFragments.size() == 1) { |
294 |
1/2✓ Branch 5 → 6 taken 8890 times.
✗ Branch 5 → 106 not taken.
|
8890 | ensureLoadedRuntimeForTypeName(fqFunctionName); |
295 |
1/2✓ Branch 6 → 7 taken 8890 times.
✗ Branch 6 → 106 not taken.
|
8890 | ensureLoadedRuntimeForFunctionName(fqFunctionName); |
296 | } | ||
297 | |||
298 | // Check if the type is generic (possible in case of ctor call) | ||
299 |
1/2✓ Branch 7 → 8 taken 8952 times.
✗ Branch 7 → 106 not taken.
|
8952 | const QualType *genericType = rootScope->lookupGenericTypeStrict(fqFunctionName); |
300 |
6/8✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 12 taken 8951 times.
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 106 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 12 not taken.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 19 taken 8951 times.
|
8952 | if (genericType && typeMapping.contains(fqFunctionName)) { |
301 |
1/2✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 106 not taken.
|
1 | const QualType &replacementType = typeMapping.at(fqFunctionName); |
302 |
2/4✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 106 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 19 not taken.
|
1 | if (replacementType.is(TY_STRUCT)) |
303 |
2/4✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 106 not taken.
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 106 not taken.
|
1 | fqFunctionName = replacementType.getSubType(); |
304 | } | ||
305 | |||
306 | // Check if the exported name registry contains that function name | ||
307 |
1/2✓ Branch 19 → 20 taken 8952 times.
✗ Branch 19 → 106 not taken.
|
8952 | const NameRegistryEntry *functionRegistryEntry = sourceFile->getNameRegistryEntry(fqFunctionName); |
308 |
2/2✓ Branch 20 → 21 taken 3 times.
✓ Branch 20 → 29 taken 8949 times.
|
8952 | if (!functionRegistryEntry) { |
309 |
2/4✓ Branch 22 → 23 taken 3 times.
✗ Branch 22 → 86 not taken.
✓ Branch 23 → 24 taken 3 times.
✗ Branch 23 → 84 not taken.
|
3 | const std::string msg = "Function/procedure/struct '" + node->functionNameFragments.back() + "' could not be found"; |
310 |
1/2✓ Branch 25 → 26 taken 3 times.
✗ Branch 25 → 87 not taken.
|
3 | SOFT_ERROR_BOOL(node, REFERENCED_UNDEFINED_FUNCTION, msg) |
311 | 3 | } | |
312 | 8949 | const SymbolTableEntry *functionEntry = functionRegistryEntry->targetEntry; | |
313 | 8949 | calleeParentScope = functionRegistryEntry->targetScope; | |
314 | |||
315 | // Check if the target symbol is a struct -> this must be a constructor call | ||
316 |
1/2✓ Branch 30 → 31 taken 8949 times.
✗ Branch 30 → 106 not taken.
|
8949 | std::string functionName = node->functionNameFragments.back(); |
317 |
7/10✓ Branch 31 → 32 taken 8949 times.
✗ Branch 31 → 36 not taken.
✓ Branch 32 → 33 taken 8949 times.
✗ Branch 32 → 104 not taken.
✓ Branch 33 → 34 taken 8949 times.
✗ Branch 33 → 104 not taken.
✓ Branch 34 → 35 taken 2272 times.
✓ Branch 34 → 36 taken 6677 times.
✓ Branch 37 → 38 taken 2272 times.
✓ Branch 37 → 54 taken 6677 times.
|
8949 | if (functionEntry != nullptr && functionEntry->getQualType().is(TY_STRUCT)) { |
318 | 2272 | callType = FctCallNode::FctCallType::TYPE_CTOR; | |
319 |
1/2✓ Branch 38 → 39 taken 2272 times.
✗ Branch 38 → 104 not taken.
|
2272 | functionName = CTOR_FUNCTION_NAME; |
320 | |||
321 | 2272 | const NameRegistryEntry *structRegistryEntry = functionRegistryEntry; | |
322 | 2272 | const SymbolTableEntry *structEntry = functionEntry; | |
323 | |||
324 | // Substantiate potentially generic this struct | ||
325 |
2/4✓ Branch 39 → 40 taken 2272 times.
✗ Branch 39 → 104 not taken.
✓ Branch 40 → 41 taken 2272 times.
✗ Branch 40 → 104 not taken.
|
2272 | const Struct *thisStruct = structEntry->getQualType().getStruct(node, templateTypes); |
326 |
2/2✓ Branch 41 → 42 taken 1 time.
✓ Branch 41 → 51 taken 2271 times.
|
2272 | if (!thisStruct) { |
327 |
1/2✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 97 not taken.
|
1 | const std::string signature = Struct::getSignature(structRegistryEntry->targetEntry->name, templateTypes); |
328 |
2/4✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 92 not taken.
✓ Branch 44 → 45 taken 1 time.
✗ Branch 44 → 90 not taken.
|
1 | const std::string errorMsg = "Could not find struct candidate for struct '" + signature + "'. Do the template types match?"; |
329 |
1/2✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 93 not taken.
|
1 | SOFT_ERROR_BOOL(node, UNKNOWN_DATATYPE, errorMsg) |
330 | 1 | } | |
331 | |||
332 | // Set the 'this' type of the function to the struct type | ||
333 |
2/4✓ Branch 51 → 52 taken 2271 times.
✗ Branch 51 → 98 not taken.
✓ Branch 52 → 53 taken 2271 times.
✗ Branch 52 → 98 not taken.
|
2271 | thisType = structEntry->getQualType().getWithBodyScope(thisStruct->scope); |
334 | 2271 | calleeParentScope = thisStruct->scope; | |
335 | } | ||
336 | |||
337 | // Attach the concrete template types to the 'this' type | ||
338 |
7/8✓ Branch 54 → 55 taken 8948 times.
✗ Branch 54 → 104 not taken.
✓ Branch 55 → 56 taken 2271 times.
✓ Branch 55 → 59 taken 6677 times.
✓ Branch 57 → 58 taken 374 times.
✓ Branch 57 → 59 taken 1897 times.
✓ Branch 60 → 61 taken 374 times.
✓ Branch 60 → 63 taken 8574 times.
|
8948 | if (!thisType.is(TY_DYN) && !templateTypes.empty()) |
339 |
1/2✓ Branch 61 → 62 taken 374 times.
✗ Branch 61 → 99 not taken.
|
374 | thisType = thisType.getWithTemplateTypes(templateTypes); |
340 | |||
341 | // Map local arg types to imported types | ||
342 |
5/8✓ Branch 63 → 64 taken 8948 times.
✗ Branch 63 → 101 not taken.
✓ Branch 64 → 65 taken 8948 times.
✗ Branch 64 → 101 not taken.
✓ Branch 65 → 66 taken 8948 times.
✗ Branch 65 → 101 not taken.
✓ Branch 71 → 67 taken 13788 times.
✓ Branch 71 → 72 taken 8948 times.
|
22736 | for (QualType &argType : args | std::views::keys) |
343 |
1/2✓ Branch 68 → 69 taken 13788 times.
✗ Branch 68 → 100 not taken.
|
13788 | argType = mapLocalTypeToImportedScopeType(calleeParentScope, argType); |
344 | |||
345 | // Map local template types to imported types | ||
346 |
2/2✓ Branch 78 → 74 taken 724 times.
✓ Branch 78 → 79 taken 8948 times.
|
9672 | for (QualType &templateType : templateTypes) |
347 |
1/2✓ Branch 75 → 76 taken 724 times.
✗ Branch 75 → 102 not taken.
|
724 | templateType = mapLocalTypeToImportedScopeType(calleeParentScope, templateType); |
348 | |||
349 | // Retrieve function object | ||
350 | 8948 | Scope *matchScope = calleeParentScope; | |
351 |
2/2✓ Branch 79 → 80 taken 8946 times.
✓ Branch 79 → 104 taken 2 times.
|
8948 | callee = FunctionManager::match(this, matchScope, functionName, data.thisType, data.args, templateTypes, false, node); |
352 | |||
353 | 8946 | return true; | |
354 | 8949 | } | |
355 | |||
356 | 48 | bool TypeChecker::visitFctPtrCall(const FctCallNode *node, const QualType &functionType) const { | |
357 |
1/2✓ Branch 2 → 3 taken 48 times.
✗ Branch 2 → 75 not taken.
|
48 | const FctCallNode::FctCallData &data = node->data.at(manIdx); |
358 | 48 | const auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
359 | |||
360 | // Check if the given argument types match the type | ||
361 |
1/2✓ Branch 3 → 4 taken 48 times.
✗ Branch 3 → 75 not taken.
|
48 | const QualTypeList expectedArgTypes = functionType.getFunctionParamTypes(); |
362 |
1/2✗ Branch 6 → 7 not taken.
✓ Branch 6 → 14 taken 48 times.
|
48 | if (args.size() != expectedArgTypes.size()) |
363 | ✗ | SOFT_ERROR_BOOL(node, REFERENCED_UNDEFINED_FUNCTION, "Expected and actual number of arguments do not match") | |
364 | |||
365 | // Create resolver function, that always returns a nullptr | ||
366 | 48 | TypeMatcher::ResolverFct resolverFct = [](const std::string &) { return nullptr; }; | |
367 | |||
368 |
2/2✓ Branch 41 → 16 taken 31 times.
✓ Branch 41 → 42 taken 48 times.
|
79 | for (size_t i = 0; i < args.size(); i++) { |
369 |
1/2✓ Branch 16 → 17 taken 31 times.
✗ Branch 16 → 71 not taken.
|
31 | const QualType &actualType = args.at(i).first; |
370 |
1/2✓ Branch 17 → 18 taken 31 times.
✗ Branch 17 → 71 not taken.
|
31 | const QualType &expectedType = expectedArgTypes.at(i); |
371 |
2/4✓ Branch 19 → 20 taken 31 times.
✗ Branch 19 → 68 not taken.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 34 taken 31 times.
|
31 | if (TypeMapping tm; !TypeMatcher::matchRequestedToCandidateType(expectedType, actualType, tm, resolverFct, false)) |
372 |
1/16✗ Branch 21 → 22 not taken.
✗ Branch 21 → 66 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 61 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 59 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 57 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 55 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 53 not taken.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 53 not taken.
✓ Branch 36 → 37 taken 31 times.
✗ Branch 36 → 39 not taken.
|
31 | SOFT_ERROR_BOOL(node->argLst->args.at(i), REFERENCED_UNDEFINED_FUNCTION, |
373 | "Expected " + expectedType.getName(false) + " but got " + actualType.getName(false)) | ||
374 | } | ||
375 | 48 | return true; | |
376 | 48 | } | |
377 | |||
378 | 6038 | bool TypeChecker::visitMethodCall(FctCallNode *node, Scope *structScope) { | |
379 | 6038 | FctCallNode::FctCallData &data = node->data.at(manIdx); | |
380 | 6038 | auto &[callType, isImported, templateTypes, thisType, args, callee, calleeParentScope] = data; | |
381 | |||
382 | // Traverse through structs - the first fragment is already looked up and the last one is the method name | ||
383 |
2/2✓ Branch 41 → 4 taken 836 times.
✓ Branch 41 → 42 taken 6036 times.
|
6872 | for (size_t i = 1; i < node->functionNameFragments.size() - 1; i++) { |
384 | 836 | const std::string &identifier = node->functionNameFragments.at(i); | |
385 | |||
386 | // Retrieve field entry | ||
387 | 836 | SymbolTableEntry *fieldEntry = structScope->lookupStrict(identifier); | |
388 |
2/2✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 24 taken 835 times.
|
836 | if (!fieldEntry) { |
389 |
1/2✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 82 not taken.
|
1 | std::stringstream errorMsg; |
390 |
1/2✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 80 not taken.
|
1 | errorMsg << "The type '"; |
391 |
3/6✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 75 not taken.
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 75 not taken.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 73 not taken.
|
1 | errorMsg << thisType.getBase().getName(false, true); |
392 |
3/6✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 80 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 80 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 80 not taken.
|
1 | errorMsg << "' does not have a member with the name '" << identifier << "'"; |
393 |
2/4✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 79 not taken.
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 77 not taken.
|
1 | SOFT_ERROR_BOOL(node, ACCESS_TO_NON_EXISTING_MEMBER, errorMsg.str()) |
394 | 1 | } | |
395 |
5/8✓ Branch 24 → 25 taken 835 times.
✗ Branch 24 → 84 not taken.
✓ Branch 25 → 26 taken 835 times.
✗ Branch 25 → 84 not taken.
✓ Branch 26 → 27 taken 835 times.
✗ Branch 26 → 83 not taken.
✓ Branch 27 → 28 taken 1 time.
✓ Branch 27 → 34 taken 834 times.
|
835 | if (!fieldEntry->getQualType().getBase().isOneOf({TY_STRUCT, TY_INTERFACE})) |
396 |
3/6✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 89 not taken.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 87 not taken.
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 85 not taken.
|
1 | SOFT_ERROR_BOOL(node, INVALID_MEMBER_ACCESS, |
397 | "Cannot call a method on '" + identifier + "', since it is no struct or interface") | ||
398 | 834 | fieldEntry->used = true; | |
399 | |||
400 | // Get struct type and scope | ||
401 | 834 | thisType = fieldEntry->getQualType(); | |
402 |
2/4✓ Branch 35 → 36 taken 834 times.
✗ Branch 35 → 91 not taken.
✓ Branch 36 → 37 taken 834 times.
✗ Branch 36 → 91 not taken.
|
834 | structScope = thisType.getBase().getBodyScope(); |
403 |
1/2✗ Branch 37 → 38 not taken.
✓ Branch 37 → 39 taken 834 times.
|
834 | assert(structScope != nullptr); |
404 | } | ||
405 | |||
406 |
1/2✗ Branch 43 → 44 not taken.
✓ Branch 43 → 51 taken 6036 times.
|
6036 | if (thisType.is(TY_INTERFACE)) |
407 | ✗ | SOFT_ERROR_BOOL(node, INVALID_MEMBER_ACCESS, "Cannot call a method on an interface") | |
408 | |||
409 | // Map local arg types to imported types | ||
410 | 6036 | Scope *matchScope = calleeParentScope = structScope; | |
411 |
5/8✓ Branch 51 → 52 taken 6036 times.
✗ Branch 51 → 99 not taken.
✓ Branch 52 → 53 taken 6036 times.
✗ Branch 52 → 99 not taken.
✓ Branch 53 → 54 taken 6036 times.
✗ Branch 53 → 99 not taken.
✓ Branch 59 → 55 taken 4296 times.
✓ Branch 59 → 60 taken 6036 times.
|
10332 | for (QualType &argType : args | std::views::keys) |
412 |
1/2✓ Branch 56 → 57 taken 4296 times.
✗ Branch 56 → 98 not taken.
|
4296 | argType = mapLocalTypeToImportedScopeType(calleeParentScope, argType); |
413 | |||
414 | // Map local template types to imported types | ||
415 |
1/2✗ Branch 66 → 62 not taken.
✓ Branch 66 → 67 taken 6036 times.
|
6036 | for (QualType &templateType : templateTypes) |
416 | ✗ | templateType = mapLocalTypeToImportedScopeType(calleeParentScope, templateType); | |
417 | |||
418 | // 'this' type | ||
419 |
1/2✓ Branch 67 → 68 taken 6036 times.
✗ Branch 67 → 102 not taken.
|
6036 | thisType = thisType.autoDeReference(); |
420 |
1/2✓ Branch 68 → 69 taken 6036 times.
✗ Branch 68 → 103 not taken.
|
6036 | thisType = mapLocalTypeToImportedScopeType(calleeParentScope, thisType); |
421 | |||
422 | // Retrieve function object | ||
423 | 6036 | const std::string &functionName = node->functionNameFragments.back(); | |
424 | 6036 | callee = FunctionManager::match(this, matchScope, functionName, thisType, args, templateTypes, false, node); | |
425 | |||
426 | 6036 | return true; | |
427 | } | ||
428 | |||
429 | 74 | std::any TypeChecker::visitArrayInitialization(ArrayInitializationNode *node) { | |
430 |
5/6✓ Branch 2 → 3 taken 73 times.
✓ Branch 2 → 5 taken 1 time.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 73 times.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 18 taken 73 times.
|
74 | if (!node->itemLst || node->itemLst->args.empty()) |
431 |
4/8✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 68 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 66 not taken.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 72 not taken.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 72 not taken.
|
3 | SOFT_ERROR_ER(node, ARRAY_SIZE_INVALID, "Array initializers must at least contain one value"); |
432 | 73 | node->actualSize = node->itemLst->args.size(); | |
433 | |||
434 |
1/2✓ Branch 19 → 20 taken 73 times.
✗ Branch 19 → 97 not taken.
|
73 | QualType actualItemType(TY_DYN); |
435 | // Check if all values have the same type | ||
436 |
2/2✓ Branch 55 → 22 taken 491 times.
✓ Branch 55 → 56 taken 72 times.
|
563 | for (AssignExprNode *arg : node->itemLst->args) { |
437 |
2/4✓ Branch 23 → 24 taken 491 times.
✗ Branch 23 → 75 not taken.
✓ Branch 24 → 25 taken 491 times.
✗ Branch 24 → 73 not taken.
|
491 | const QualType itemType = std::any_cast<ExprResult>(visit(arg)).type; |
438 |
2/8✓ Branch 26 → 27 taken 491 times.
✗ Branch 26 → 94 not taken.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 32 taken 491 times.
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 77 not taken.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 77 not taken.
|
491 | HANDLE_UNRESOLVED_TYPE_ER(itemType) |
439 |
3/4✓ Branch 32 → 33 taken 491 times.
✗ Branch 32 → 94 not taken.
✓ Branch 33 → 34 taken 73 times.
✓ Branch 33 → 35 taken 418 times.
|
491 | if (actualItemType.is(TY_DYN)) // Perform type inference |
440 | 73 | actualItemType = itemType; | |
441 |
3/4✓ Branch 35 → 36 taken 418 times.
✗ Branch 35 → 94 not taken.
✓ Branch 36 → 37 taken 1 time.
✓ Branch 36 → 52 taken 417 times.
|
418 | else if (itemType != actualItemType) // Check if types are matching |
442 |
8/16✓ Branch 37 → 38 taken 1 time.
✗ Branch 37 → 91 not taken.
✓ Branch 38 → 39 taken 1 time.
✗ Branch 38 → 86 not taken.
✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 84 not taken.
✓ Branch 40 → 41 taken 1 time.
✗ Branch 40 → 82 not taken.
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 80 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 78 not taken.
✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 93 not taken.
✓ Branch 49 → 50 taken 1 time.
✗ Branch 49 → 93 not taken.
|
1 | SOFT_ERROR_ER(arg, ARRAY_ITEM_TYPE_NOT_MATCHING, |
443 | "All provided values have to be of the same data type. You provided " + actualItemType.getName(false) + | ||
444 | " and " + itemType.getName(false)) | ||
445 | } | ||
446 |
2/4✓ Branch 56 → 57 taken 72 times.
✗ Branch 56 → 97 not taken.
✗ Branch 57 → 58 not taken.
✓ Branch 57 → 59 taken 72 times.
|
72 | assert(!actualItemType.is(TY_DYN)); |
447 | |||
448 |
1/2✓ Branch 59 → 60 taken 72 times.
✗ Branch 59 → 97 not taken.
|
72 | const QualType arrayType = actualItemType.toArr(node, node->actualSize, true); |
449 |
2/4✓ Branch 60 → 61 taken 72 times.
✗ Branch 60 → 96 not taken.
✓ Branch 61 → 62 taken 72 times.
✗ Branch 61 → 96 not taken.
|
72 | return ExprResult{node->setEvaluatedSymbolType(arrayType, manIdx)}; |
450 | } | ||
451 | |||
452 | 290 | std::any TypeChecker::visitStructInstantiation(StructInstantiationNode *node) { | |
453 | // Retrieve struct name | ||
454 |
1/2✓ Branch 2 → 3 taken 290 times.
✗ Branch 2 → 264 not taken.
|
290 | const auto [aliasedEntry, isAlias] = rootScope->symbolTable.lookupWithAliasResolution(node->fqStructName); |
455 |
4/6✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 9 taken 289 times.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 264 not taken.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 264 not taken.
|
290 | const std::string &structName = isAlias ? aliasedEntry->getQualType().getSubType() : node->fqStructName; |
456 | |||
457 | // Retrieve struct | ||
458 |
1/2✓ Branch 10 → 11 taken 290 times.
✗ Branch 10 → 264 not taken.
|
290 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(structName); |
459 |
2/2✓ Branch 11 → 12 taken 1 time.
✓ Branch 11 → 21 taken 289 times.
|
290 | if (!registryEntry) |
460 |
5/10✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 195 not taken.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 193 not taken.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 191 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 197 not taken.
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 197 not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, "Cannot find struct '" + structName + "'") |
461 |
2/4✓ Branch 21 → 22 taken 289 times.
✗ Branch 21 → 24 not taken.
✓ Branch 22 → 23 taken 289 times.
✗ Branch 22 → 24 not taken.
|
289 | assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr); |
462 | 289 | SymbolTableEntry *structEntry = registryEntry->targetEntry; | |
463 | |||
464 | // Check visibility | ||
465 |
9/12✓ Branch 25 → 26 taken 289 times.
✗ Branch 25 → 264 not taken.
✓ Branch 26 → 27 taken 289 times.
✗ Branch 26 → 264 not taken.
✓ Branch 27 → 28 taken 62 times.
✓ Branch 27 → 31 taken 227 times.
✓ Branch 28 → 29 taken 62 times.
✗ Branch 28 → 264 not taken.
✓ Branch 29 → 30 taken 1 time.
✓ Branch 29 → 31 taken 61 times.
✓ Branch 32 → 33 taken 1 time.
✓ Branch 32 → 42 taken 288 times.
|
289 | if (!structEntry->getQualType().isPublic() && structEntry->scope->isImportedBy(currentScope)) |
466 |
5/10✓ Branch 33 → 34 taken 1 time.
✗ Branch 33 → 202 not taken.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 200 not taken.
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 198 not taken.
✓ Branch 38 → 39 taken 1 time.
✗ Branch 38 → 204 not taken.
✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 204 not taken.
|
1 | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Struct '" + structName + "' has insufficient visibility") |
467 | |||
468 | // Get struct type | ||
469 |
1/2✓ Branch 42 → 43 taken 288 times.
✗ Branch 42 → 264 not taken.
|
288 | QualType structType = structEntry->getQualType(); |
470 | |||
471 | // Get the concrete template types | ||
472 | 288 | QualTypeList concreteTemplateTypes; | |
473 |
2/2✓ Branch 43 → 44 taken 1 time.
✓ Branch 43 → 63 taken 287 times.
|
288 | if (isAlias) { |
474 | // Retrieve concrete template types from type alias | ||
475 |
3/6✓ Branch 44 → 45 taken 1 time.
✗ Branch 44 → 262 not taken.
✓ Branch 45 → 46 taken 1 time.
✗ Branch 45 → 262 not taken.
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 262 not taken.
|
1 | concreteTemplateTypes = aliasedEntry->getQualType().getTemplateTypes(); |
476 | // Check if the aliased type specified template types and the struct instantiation does | ||
477 |
3/6✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 51 not taken.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 1 time.
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 63 taken 1 time.
|
1 | if (!concreteTemplateTypes.empty() && node->templateTypeLst) |
478 | ✗ | SOFT_ERROR_ER(node->templateTypeLst, ALIAS_WITH_TEMPLATE_LIST, "The aliased type already has a template list") | |
479 | } | ||
480 | |||
481 |
2/2✓ Branch 63 → 64 taken 19 times.
✓ Branch 63 → 96 taken 269 times.
|
288 | if (node->templateTypeLst) { |
482 |
1/2✓ Branch 65 → 66 taken 19 times.
✗ Branch 65 → 262 not taken.
|
19 | concreteTemplateTypes.reserve(node->templateTypeLst->dataTypes.size()); |
483 |
2/2✓ Branch 94 → 68 taken 31 times.
✓ Branch 94 → 95 taken 19 times.
|
50 | for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) { |
484 |
2/4✓ Branch 69 → 70 taken 31 times.
✗ Branch 69 → 214 not taken.
✓ Branch 70 → 71 taken 31 times.
✗ Branch 70 → 212 not taken.
|
31 | auto concreteType = std::any_cast<QualType>(visit(dataType)); |
485 |
2/8✓ Branch 72 → 73 taken 31 times.
✗ Branch 72 → 223 not taken.
✗ Branch 73 → 74 not taken.
✓ Branch 73 → 78 taken 31 times.
✗ Branch 74 → 75 not taken.
✗ Branch 74 → 215 not taken.
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 215 not taken.
|
31 | HANDLE_UNRESOLVED_TYPE_ER(concreteType) |
486 | // Check if generic type | ||
487 |
2/4✓ Branch 78 → 79 taken 31 times.
✗ Branch 78 → 223 not taken.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 90 taken 31 times.
|
31 | if (concreteType.is(TY_GENERIC)) |
488 | ✗ | SOFT_ERROR_ER(dataType, EXPECTED_NON_GENERIC_TYPE, "Struct instantiations may only take concrete template types") | |
489 |
1/2✓ Branch 90 → 91 taken 31 times.
✗ Branch 90 → 223 not taken.
|
31 | concreteTemplateTypes.push_back(concreteType); |
490 | } | ||
491 | } | ||
492 | |||
493 | // Get the struct instance | ||
494 |
2/4✓ Branch 96 → 97 taken 288 times.
✗ Branch 96 → 262 not taken.
✓ Branch 97 → 98 taken 288 times.
✗ Branch 97 → 262 not taken.
|
288 | Struct *spiceStruct = node->instantiatedStructs.at(manIdx) = structType.getStructAndAdjustType(node, concreteTemplateTypes); |
495 |
1/2✗ Branch 98 → 99 not taken.
✓ Branch 98 → 110 taken 288 times.
|
288 | if (!spiceStruct) |
496 | ✗ | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_STRUCT, | |
497 | "Struct '" + Struct::getSignature(structName, concreteTemplateTypes) + "' could not be found") | ||
498 | |||
499 | // Struct instantiation for an inheriting struct is forbidden, because the vtable needs to be initialized and this is done in | ||
500 | // the ctor of the struct, which is never called in case of struct instantiation | ||
501 |
2/2✓ Branch 111 → 112 taken 1 time.
✓ Branch 111 → 122 taken 287 times.
|
288 | if (!spiceStruct->interfaceTypes.empty()) |
502 |
4/8✓ Branch 114 → 115 taken 1 time.
✗ Branch 114 → 237 not taken.
✓ Branch 115 → 116 taken 1 time.
✗ Branch 115 → 235 not taken.
✓ Branch 118 → 119 taken 1 time.
✗ Branch 118 → 241 not taken.
✓ Branch 119 → 120 taken 1 time.
✗ Branch 119 → 241 not taken.
|
3 | SOFT_ERROR_ER(node, INVALID_STRUCT_INSTANTIATION, "Struct instantiations for inheriting structs are forbidden") |
503 | |||
504 | // Check if the number of fields matches | ||
505 |
2/2✓ Branch 122 → 123 taken 273 times.
✓ Branch 122 → 166 taken 14 times.
|
287 | if (node->fieldLst) { // Check if any fields are passed. Empty braces are also allowed |
506 |
2/2✓ Branch 125 → 126 taken 1 time.
✓ Branch 125 → 136 taken 272 times.
|
273 | if (spiceStruct->fieldTypes.size() != node->fieldLst->args.size()) |
507 |
4/8✓ Branch 128 → 129 taken 1 time.
✗ Branch 128 → 244 not taken.
✓ Branch 129 → 130 taken 1 time.
✗ Branch 129 → 242 not taken.
✓ Branch 132 → 133 taken 1 time.
✗ Branch 132 → 248 not taken.
✓ Branch 133 → 134 taken 1 time.
✗ Branch 133 → 248 not taken.
|
3 | SOFT_ERROR_ER(node->fieldLst, NUMBER_OF_FIELDS_NOT_MATCHING, |
508 | "You've passed too less/many field values. Pass either none or all of them") | ||
509 | |||
510 | // Check if the field types are matching | ||
511 | 272 | const size_t fieldCount = spiceStruct->fieldTypes.size(); | |
512 |
1/2✓ Branch 137 → 138 taken 272 times.
✗ Branch 137 → 262 not taken.
|
272 | const size_t explicitFieldsStartIdx = spiceStruct->scope->getFieldCount() - fieldCount; |
513 |
2/2✓ Branch 165 → 139 taken 407 times.
✓ Branch 165 → 178 taken 271 times.
|
678 | for (size_t i = 0; i < node->fieldLst->args.size(); i++) { |
514 | // Get actual type | ||
515 |
1/2✓ Branch 139 → 140 taken 407 times.
✗ Branch 139 → 253 not taken.
|
407 | AssignExprNode *assignExpr = node->fieldLst->args.at(i); |
516 |
2/4✓ Branch 140 → 141 taken 407 times.
✗ Branch 140 → 251 not taken.
✓ Branch 141 → 142 taken 407 times.
✗ Branch 141 → 249 not taken.
|
407 | auto fieldResult = std::any_cast<ExprResult>(visit(assignExpr)); |
517 |
2/8✓ Branch 143 → 144 taken 407 times.
✗ Branch 143 → 253 not taken.
✗ Branch 144 → 145 not taken.
✓ Branch 144 → 149 taken 407 times.
✗ Branch 145 → 146 not taken.
✗ Branch 145 → 252 not taken.
✗ Branch 146 → 147 not taken.
✗ Branch 146 → 252 not taken.
|
407 | HANDLE_UNRESOLVED_TYPE_ER(fieldResult.type) |
518 | // Get expected type | ||
519 |
1/2✗ Branch 149 → 150 not taken.
✓ Branch 149 → 151 taken 407 times.
|
407 | SymbolTableEntry *expectedField = spiceStruct->scope->lookupField(explicitFieldsStartIdx + i); |
520 |
1/2✗ Branch 154 → 155 not taken.
✓ Branch 154 → 156 taken 407 times.
|
407 | assert(expectedField != nullptr); |
521 |
1/2✓ Branch 156 → 157 taken 407 times.
✗ Branch 156 → 253 not taken.
|
407 | const ExprResult expected = {expectedField->getQualType(), expectedField}; |
522 |
1/2✓ Branch 157 → 158 taken 407 times.
✗ Branch 157 → 253 not taken.
|
407 | const bool rhsIsImmediate = assignExpr->hasCompileTimeValue(); |
523 | |||
524 | // Check if actual type matches expected type | ||
525 |
2/2✓ Branch 158 → 159 taken 406 times.
✓ Branch 158 → 253 taken 1 time.
|
407 | (void)opRuleManager.getFieldAssignResultType(assignExpr, expected, fieldResult, rhsIsImmediate, true); |
526 | |||
527 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
528 |
4/4✓ Branch 159 → 160 taken 111 times.
✓ Branch 159 → 163 taken 295 times.
✓ Branch 160 → 161 taken 3 times.
✓ Branch 160 → 163 taken 108 times.
|
406 | if (fieldResult.entry != nullptr && fieldResult.entry->anonymous) { |
529 |
1/2✓ Branch 161 → 162 taken 3 times.
✗ Branch 161 → 253 not taken.
|
3 | currentScope->symbolTable.deleteAnonymous(fieldResult.entry->name); |
530 | 3 | fieldResult.entry = nullptr; | |
531 | } | ||
532 | } | ||
533 | } else { | ||
534 |
2/4✓ Branch 166 → 167 taken 14 times.
✗ Branch 166 → 262 not taken.
✗ Branch 167 → 168 not taken.
✓ Branch 167 → 178 taken 14 times.
|
57 | if (std::ranges::any_of(spiceStruct->fieldTypes, [](const QualType &fieldType) { return fieldType.isRef(); })) |
535 | ✗ | SOFT_ERROR_ER(node, REFERENCE_WITHOUT_INITIALIZER, | |
536 | "The struct takes at least one reference field. You need to instantiate it with all fields.") | ||
537 | } | ||
538 | |||
539 | // Update type of struct entry | ||
540 |
1/2✓ Branch 178 → 179 taken 285 times.
✗ Branch 178 → 262 not taken.
|
285 | structEntry->updateType(structType, true); |
541 | |||
542 | // Add anonymous symbol to keep track of dtor call, if non-trivially destructible | ||
543 | 285 | SymbolTableEntry *anonymousEntry = nullptr; | |
544 |
3/4✓ Branch 179 → 180 taken 285 times.
✗ Branch 179 → 262 not taken.
✓ Branch 180 → 181 taken 23 times.
✓ Branch 180 → 183 taken 262 times.
|
285 | if (!structType.isTriviallyDestructible(node)) |
545 |
1/2✓ Branch 181 → 182 taken 23 times.
✗ Branch 181 → 262 not taken.
|
23 | anonymousEntry = currentScope->symbolTable.insertAnonymous(structType, node); |
546 | |||
547 | // Remove public qualifier to not have public local variables | ||
548 | 285 | structType.getQualifiers().isPublic = false; | |
549 | |||
550 |
2/4✓ Branch 184 → 185 taken 285 times.
✗ Branch 184 → 261 not taken.
✓ Branch 185 → 186 taken 285 times.
✗ Branch 185 → 261 not taken.
|
285 | return ExprResult{node->setEvaluatedSymbolType(structType, manIdx), anonymousEntry}; |
551 | 288 | } | |
552 | |||
553 | 12 | std::any TypeChecker::visitLambdaFunc(LambdaFuncNode *node) { | |
554 | // Check if all control paths in the lambda body return | ||
555 | 12 | bool returnsOnAllControlPaths = true; | |
556 |
3/4✓ Branch 2 → 3 taken 12 times.
✗ Branch 2 → 186 not taken.
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 14 taken 11 times.
|
12 | if (!node->returnsOnAllControlPaths(&returnsOnAllControlPaths)) |
557 |
4/8✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 112 not taken.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 110 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 116 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 116 not taken.
|
3 | SOFT_ERROR_ER(node, MISSING_RETURN_STMT, "Not all control paths of this lambda function have a return statement") |
558 | |||
559 | // Change to function scope | ||
560 |
2/4✓ Branch 14 → 15 taken 11 times.
✗ Branch 14 → 119 not taken.
✓ Branch 15 → 16 taken 11 times.
✗ Branch 15 → 117 not taken.
|
11 | Scope *bodyScope = currentScope->getChildScope(node->getScopeId()); |
561 |
1/2✓ Branch 17 → 18 taken 11 times.
✗ Branch 17 → 120 not taken.
|
11 | ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY); |
562 | |||
563 | // Visit return type | ||
564 |
2/4✓ Branch 18 → 19 taken 11 times.
✗ Branch 18 → 123 not taken.
✓ Branch 19 → 20 taken 11 times.
✗ Branch 19 → 121 not taken.
|
11 | const auto returnType = std::any_cast<QualType>(visit(node->returnType)); |
565 |
2/8✓ Branch 21 → 22 taken 11 times.
✗ Branch 21 → 184 not taken.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 27 taken 11 times.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 124 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 124 not taken.
|
11 | HANDLE_UNRESOLVED_TYPE_ER(returnType) |
566 |
3/4✓ Branch 27 → 28 taken 11 times.
✗ Branch 27 → 184 not taken.
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 39 taken 10 times.
|
11 | if (returnType.is(TY_DYN)) |
567 |
4/8✓ Branch 31 → 32 taken 1 time.
✗ Branch 31 → 127 not taken.
✓ Branch 32 → 33 taken 1 time.
✗ Branch 32 → 125 not taken.
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 131 not taken.
✓ Branch 36 → 37 taken 1 time.
✗ Branch 36 → 131 not taken.
|
3 | SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Dyn return types are not allowed") |
568 | |||
569 | // Set the type of the result variable | ||
570 |
1/2✓ Branch 41 → 42 taken 10 times.
✗ Branch 41 → 134 not taken.
|
30 | SymbolTableEntry *resultVarEntry = currentScope->lookupStrict(RETURN_VARIABLE_NAME); |
571 |
1/2✗ Branch 47 → 48 not taken.
✓ Branch 47 → 49 taken 10 times.
|
10 | assert(resultVarEntry != nullptr); |
572 |
1/2✓ Branch 49 → 50 taken 10 times.
✗ Branch 49 → 184 not taken.
|
10 | resultVarEntry->updateType(returnType, true); |
573 | 10 | resultVarEntry->used = true; | |
574 | |||
575 | // Visit parameters | ||
576 | 10 | QualTypeList paramTypes; | |
577 | 10 | ParamList paramList; | |
578 |
2/2✓ Branch 50 → 51 taken 6 times.
✓ Branch 50 → 72 taken 4 times.
|
10 | if (node->hasParams) { |
579 | // Visit param list to retrieve the param names | ||
580 |
2/4✓ Branch 51 → 52 taken 6 times.
✗ Branch 51 → 140 not taken.
✓ Branch 52 → 53 taken 6 times.
✗ Branch 52 → 138 not taken.
|
6 | auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst)); |
581 |
2/2✓ Branch 69 → 56 taken 10 times.
✓ Branch 69 → 70 taken 6 times.
|
16 | for (const auto &[name, qualType, isOptional] : namedParamList) { |
582 |
1/2✗ Branch 57 → 58 not taken.
✓ Branch 57 → 65 taken 10 times.
|
10 | if (isOptional) |
583 | ✗ | softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters"); | |
584 | |||
585 |
1/2✓ Branch 65 → 66 taken 10 times.
✗ Branch 65 → 148 not taken.
|
10 | paramTypes.push_back(qualType); |
586 |
1/2✓ Branch 66 → 67 taken 10 times.
✗ Branch 66 → 147 not taken.
|
10 | paramList.push_back({qualType, isOptional}); |
587 | } | ||
588 | 6 | } | |
589 | |||
590 | // Visit lambda body | ||
591 |
2/2✓ Branch 72 → 73 taken 9 times.
✓ Branch 72 → 152 taken 1 time.
|
10 | visit(node->body); |
592 | |||
593 | // Leave function body scope | ||
594 |
1/2✓ Branch 74 → 75 taken 9 times.
✗ Branch 74 → 180 not taken.
|
9 | scopeHandle.leaveScopeEarly(); |
595 | |||
596 | // Prepare type of function | ||
597 |
1/2✓ Branch 75 → 76 taken 9 times.
✗ Branch 75 → 153 not taken.
|
9 | const QualType functionType = QualType(TY_FUNCTION) |
598 |
1/2✓ Branch 76 → 77 taken 9 times.
✗ Branch 76 → 153 not taken.
|
9 | .getWithFunctionParamAndReturnTypes(returnType, paramTypes) |
599 |
1/2✓ Branch 78 → 79 taken 9 times.
✗ Branch 78 → 153 not taken.
|
9 | .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty()); |
600 | |||
601 | // Create function object | ||
602 |
2/4✓ Branch 79 → 80 taken 9 times.
✗ Branch 79 → 157 not taken.
✓ Branch 80 → 81 taken 9 times.
✗ Branch 80 → 155 not taken.
|
9 | const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn(); |
603 |
4/8✓ Branch 83 → 84 taken 9 times.
✗ Branch 83 → 166 not taken.
✓ Branch 84 → 85 taken 9 times.
✗ Branch 84 → 163 not taken.
✓ Branch 85 → 86 taken 9 times.
✗ Branch 85 → 162 not taken.
✓ Branch 87 → 88 taken 9 times.
✗ Branch 87 → 158 not taken.
|
9 | node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), returnType, paramList, {}, node); |
604 |
1/2✓ Branch 93 → 94 taken 9 times.
✗ Branch 93 → 178 not taken.
|
9 | node->manifestations.at(manIdx).bodyScope = bodyScope; |
605 |
3/6✓ Branch 94 → 95 taken 9 times.
✗ Branch 94 → 175 not taken.
✓ Branch 95 → 96 taken 9 times.
✗ Branch 95 → 173 not taken.
✓ Branch 96 → 97 taken 9 times.
✗ Branch 96 → 171 not taken.
|
9 | node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx); |
606 | |||
607 | // Check special requirements if this is an async lambda | ||
608 |
1/2✓ Branch 100 → 101 taken 9 times.
✗ Branch 100 → 178 not taken.
|
9 | (void)checkAsyncLambdaCaptureRules(node, node->lambdaAttr); |
609 | |||
610 |
2/4✓ Branch 101 → 102 taken 9 times.
✗ Branch 101 → 177 not taken.
✓ Branch 102 → 103 taken 9 times.
✗ Branch 102 → 177 not taken.
|
9 | return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)}; |
611 | 13 | } | |
612 | |||
613 | 28 | std::any TypeChecker::visitLambdaProc(LambdaProcNode *node) { | |
614 | // Mark unreachable statements | ||
615 | 28 | bool doSetPredecessorsUnreachable = true; | |
616 |
1/2✓ Branch 2 → 3 taken 28 times.
✗ Branch 2 → 123 not taken.
|
28 | node->returnsOnAllControlPaths(&doSetPredecessorsUnreachable); |
617 | |||
618 | // Change to function scope | ||
619 |
2/4✓ Branch 3 → 4 taken 28 times.
✗ Branch 3 → 71 not taken.
✓ Branch 4 → 5 taken 28 times.
✗ Branch 4 → 69 not taken.
|
28 | Scope *bodyScope = currentScope->getChildScope(node->getScopeId()); |
620 |
1/2✓ Branch 6 → 7 taken 28 times.
✗ Branch 6 → 72 not taken.
|
28 | ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY); |
621 | |||
622 | // Visit parameters | ||
623 | 28 | QualTypeList paramTypes; | |
624 | 28 | ParamList paramList; | |
625 |
2/2✓ Branch 7 → 8 taken 7 times.
✓ Branch 7 → 29 taken 21 times.
|
28 | if (node->hasParams) { |
626 | // Visit param list to retrieve the param names | ||
627 |
2/4✓ Branch 8 → 9 taken 7 times.
✗ Branch 8 → 75 not taken.
✓ Branch 9 → 10 taken 7 times.
✗ Branch 9 → 73 not taken.
|
7 | auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst)); |
628 |
2/2✓ Branch 26 → 13 taken 11 times.
✓ Branch 26 → 27 taken 7 times.
|
18 | for (const auto &[_, qualType, isOptional] : namedParamList) { |
629 |
2/2✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 22 taken 10 times.
|
11 | if (isOptional) |
630 |
2/4✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 78 not taken.
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 76 not taken.
|
2 | softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters"); |
631 | |||
632 |
1/2✓ Branch 22 → 23 taken 11 times.
✗ Branch 22 → 83 not taken.
|
11 | paramTypes.push_back(qualType); |
633 |
1/2✓ Branch 23 → 24 taken 11 times.
✗ Branch 23 → 82 not taken.
|
11 | paramList.push_back({qualType, isOptional}); |
634 | } | ||
635 | 7 | } | |
636 | |||
637 | // Visit lambda body | ||
638 |
1/2✓ Branch 29 → 30 taken 28 times.
✗ Branch 29 → 87 not taken.
|
28 | visit(node->body); |
639 | |||
640 | // Leave function body scope | ||
641 |
1/2✓ Branch 31 → 32 taken 28 times.
✗ Branch 31 → 117 not taken.
|
28 | scopeHandle.leaveScopeEarly(); |
642 | |||
643 | // Prepare type of function | ||
644 |
1/2✓ Branch 32 → 33 taken 28 times.
✗ Branch 32 → 89 not taken.
|
28 | const QualType functionType = QualType(TY_PROCEDURE) |
645 |
2/4✓ Branch 33 → 34 taken 28 times.
✗ Branch 33 → 88 not taken.
✓ Branch 34 → 35 taken 28 times.
✗ Branch 34 → 88 not taken.
|
28 | .getWithFunctionParamAndReturnTypes(QualType(TY_DYN), paramTypes) |
646 |
1/2✓ Branch 36 → 37 taken 28 times.
✗ Branch 36 → 88 not taken.
|
28 | .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty()); |
647 | |||
648 | // Create function object | ||
649 |
2/4✓ Branch 37 → 38 taken 28 times.
✗ Branch 37 → 93 not taken.
✓ Branch 38 → 39 taken 28 times.
✗ Branch 38 → 91 not taken.
|
28 | const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn(); |
650 |
5/10✓ Branch 41 → 42 taken 28 times.
✗ Branch 41 → 103 not taken.
✓ Branch 42 → 43 taken 28 times.
✗ Branch 42 → 100 not taken.
✓ Branch 43 → 44 taken 28 times.
✗ Branch 43 → 99 not taken.
✓ Branch 44 → 45 taken 28 times.
✗ Branch 44 → 98 not taken.
✓ Branch 46 → 47 taken 28 times.
✗ Branch 46 → 94 not taken.
|
28 | node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), QualType(TY_DYN), paramList, {}, node); |
651 |
1/2✓ Branch 52 → 53 taken 28 times.
✗ Branch 52 → 115 not taken.
|
28 | node->manifestations.at(manIdx).bodyScope = bodyScope; |
652 |
3/6✓ Branch 53 → 54 taken 28 times.
✗ Branch 53 → 112 not taken.
✓ Branch 54 → 55 taken 28 times.
✗ Branch 54 → 110 not taken.
✓ Branch 55 → 56 taken 28 times.
✗ Branch 55 → 108 not taken.
|
28 | node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx); |
653 | |||
654 | // Check special requirements if this is an async lambda | ||
655 |
1/2✓ Branch 59 → 60 taken 28 times.
✗ Branch 59 → 115 not taken.
|
28 | (void)checkAsyncLambdaCaptureRules(node, node->lambdaAttr); |
656 | |||
657 |
2/4✓ Branch 60 → 61 taken 28 times.
✗ Branch 60 → 114 not taken.
✓ Branch 61 → 62 taken 28 times.
✗ Branch 61 → 114 not taken.
|
56 | return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)}; |
658 | 28 | } | |
659 | |||
660 | 1 | std::any TypeChecker::visitLambdaExpr(LambdaExprNode *node) { | |
661 | // Change to function scope | ||
662 |
2/4✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 90 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 88 not taken.
|
1 | Scope *bodyScope = currentScope->getChildScope(node->getScopeId()); |
663 |
1/2✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 91 not taken.
|
1 | ScopeHandle scopeHandle(this, bodyScope, ScopeType::LAMBDA_BODY); |
664 | |||
665 | // Visit parameters | ||
666 | 1 | QualTypeList paramTypes; | |
667 | 1 | ParamList paramList; | |
668 |
1/2✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 28 not taken.
|
1 | if (node->hasParams) { |
669 | // Visit param list to retrieve the param names | ||
670 |
2/4✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 94 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 92 not taken.
|
1 | auto namedParamList = std::any_cast<NamedParamList>(visit(node->paramLst)); |
671 |
2/2✓ Branch 25 → 12 taken 2 times.
✓ Branch 25 → 26 taken 1 time.
|
3 | for (const NamedParam ¶m : namedParamList) { |
672 |
1/2✗ Branch 13 → 14 not taken.
✓ Branch 13 → 21 taken 2 times.
|
2 | if (param.isOptional) |
673 | ✗ | softError(node, LAMBDA_WITH_OPTIONAL_PARAMS, "Lambdas cannot have optional parameters"); | |
674 | |||
675 |
1/2✓ Branch 21 → 22 taken 2 times.
✗ Branch 21 → 102 not taken.
|
2 | paramTypes.push_back(param.qualType); |
676 |
1/2✓ Branch 22 → 23 taken 2 times.
✗ Branch 22 → 101 not taken.
|
2 | paramList.push_back({param.qualType, param.isOptional}); |
677 | } | ||
678 | 1 | } | |
679 | |||
680 | // Visit lambda expression | ||
681 |
2/4✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 108 not taken.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 106 not taken.
|
1 | const QualType returnType = std::any_cast<ExprResult>(visit(node->lambdaExpr)).type; |
682 |
2/8✓ Branch 31 → 32 taken 1 time.
✗ Branch 31 → 145 not taken.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 37 taken 1 time.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 110 not taken.
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 110 not taken.
|
1 | HANDLE_UNRESOLVED_TYPE_ER(returnType) |
683 |
2/4✓ Branch 37 → 38 taken 1 time.
✗ Branch 37 → 145 not taken.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 49 taken 1 time.
|
1 | if (returnType.is(TY_DYN)) |
684 | ✗ | SOFT_ERROR_ER(node, UNEXPECTED_DYN_TYPE, "Dyn return types are not allowed") | |
685 | |||
686 | // Leave function body scope | ||
687 |
1/2✓ Branch 49 → 50 taken 1 time.
✗ Branch 49 → 145 not taken.
|
1 | scopeHandle.leaveScopeEarly(); |
688 | |||
689 | // Prepare type of function | ||
690 |
2/4✓ Branch 50 → 51 taken 1 time.
✗ Branch 50 → 145 not taken.
✗ Branch 51 → 52 not taken.
✓ Branch 51 → 53 taken 1 time.
|
1 | const SuperType superType = returnType.is(TY_DYN) ? TY_PROCEDURE : TY_FUNCTION; |
691 |
1/2✓ Branch 54 → 55 taken 1 time.
✗ Branch 54 → 118 not taken.
|
1 | const QualType functionType = QualType(superType) |
692 |
1/2✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 118 not taken.
|
1 | .getWithFunctionParamAndReturnTypes(returnType, paramTypes) |
693 |
1/2✓ Branch 57 → 58 taken 1 time.
✗ Branch 57 → 118 not taken.
|
1 | .getWithLambdaCaptures(!bodyScope->symbolTable.captures.empty()); |
694 | |||
695 | // Create function object | ||
696 |
2/4✓ Branch 58 → 59 taken 1 time.
✗ Branch 58 → 122 not taken.
✓ Branch 59 → 60 taken 1 time.
✗ Branch 59 → 120 not taken.
|
1 | const std::string fctName = "lambda." + node->codeLoc.toPrettyLineAndColumn(); |
697 |
4/8✓ Branch 62 → 63 taken 1 time.
✗ Branch 62 → 131 not taken.
✓ Branch 63 → 64 taken 1 time.
✗ Branch 63 → 128 not taken.
✓ Branch 64 → 65 taken 1 time.
✗ Branch 64 → 127 not taken.
✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 123 not taken.
|
1 | node->manifestations.at(manIdx) = Function(fctName, nullptr, QualType(TY_DYN), returnType, paramList, {}, node); |
698 |
1/2✓ Branch 72 → 73 taken 1 time.
✗ Branch 72 → 143 not taken.
|
1 | node->manifestations.at(manIdx).bodyScope = bodyScope; |
699 |
3/6✓ Branch 73 → 74 taken 1 time.
✗ Branch 73 → 140 not taken.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 138 not taken.
✓ Branch 75 → 76 taken 1 time.
✗ Branch 75 → 136 not taken.
|
1 | node->manifestations.at(manIdx).mangleSuffix = "." + std::to_string(manIdx); |
700 | |||
701 |
2/4✓ Branch 79 → 80 taken 1 time.
✗ Branch 79 → 142 not taken.
✓ Branch 80 → 81 taken 1 time.
✗ Branch 80 → 142 not taken.
|
1 | return ExprResult{node->setEvaluatedSymbolType(functionType, manIdx)}; |
702 | 1 | } | |
703 | |||
704 | } // namespace spice::compiler | ||
705 |