GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 91.2% 228 / 2 / 252
Functions: 100.0% 7 / 0 / 7
Branches: 51.6% 373 / 4 / 727

src/typechecker/TypeCheckMeta.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "TypeChecker.h"
4
5 #include <SourceFile.h>
6 #include <ast/ASTNodes.h>
7 #include <global/GlobalResourceManager.h>
8 #include <model/GenericType.h>
9 #include <symboltablebuilder/Scope.h>
10 #include <typechecker/FunctionManager.h>
11 #include <typechecker/InterfaceManager.h>
12 #include <typechecker/MacroDefs.h>
13 #include <typechecker/StructManager.h>
14
15 namespace spice::compiler {
16
17 18608 std::any TypeChecker::visitParamLst(ParamLstNode *node) {
18 18608 NamedParamList namedParams;
19 18608 bool metOptional = false;
20
21
2/2
✓ Branch 32 → 4 taken 29977 times.
✓ Branch 32 → 33 taken 18608 times.
48585 for (DeclStmtNode *param : node->params) {
22 // Visit param
23
2/4
✓ Branch 5 → 6 taken 29977 times.
✗ Branch 5 → 40 not taken.
✓ Branch 6 → 7 taken 29977 times.
✗ Branch 6 → 38 not taken.
29977 const auto paramType = std::any_cast<QualType>(visit(param));
24
25 // Check if the type could be inferred. Dyn without a default value is forbidden
26
3/4
✓ Branch 8 → 9 taken 29977 times.
✗ Branch 8 → 54 not taken.
✓ Branch 9 → 10 taken 3 times.
✓ Branch 9 → 16 taken 29974 times.
29977 if (paramType.is(TY_DYN)) {
27
3/6
✓ Branch 10 → 11 taken 3 times.
✗ Branch 10 → 45 not taken.
✓ Branch 11 → 12 taken 3 times.
✗ Branch 11 → 43 not taken.
✓ Branch 12 → 13 taken 3 times.
✗ Branch 12 → 41 not taken.
3 softError(node, FCT_PARAM_IS_TYPE_DYN, "Type of parameter '" + param->varName + "' is invalid");
28 9 continue;
29 }
30
31 // Ensure that no optional param comes after a mandatory param
32
2/2
✓ Branch 16 → 17 taken 2760 times.
✓ Branch 16 → 18 taken 27214 times.
29974 if (param->hasAssignment) {
33 2760 metOptional = true;
34
2/2
✓ Branch 18 → 19 taken 6 times.
✓ Branch 18 → 26 taken 27208 times.
27214 } else if (metOptional) {
35
2/4
✓ Branch 21 → 22 taken 6 times.
✗ Branch 21 → 49 not taken.
✓ Branch 22 → 23 taken 6 times.
✗ Branch 22 → 47 not taken.
6 softError(param, INVALID_PARAM_ORDER, "Mandatory parameters must go before any optional parameters");
36 6 continue;
37 }
38
39 // Add parameter to named param list
40
1/2
✓ Branch 27 → 28 taken 29968 times.
✗ Branch 27 → 53 not taken.
29968 namedParams.push_back({param->varName.c_str(), paramType, metOptional});
41 }
42
43
1/2
✓ Branch 33 → 34 taken 18608 times.
✗ Branch 33 → 56 not taken.
37216 return namedParams;
44 18608 }
45
46 1561 std::any TypeChecker::visitField(FieldNode *node) {
47
2/4
✓ Branch 2 → 3 taken 1561 times.
✗ Branch 2 → 37 not taken.
✓ Branch 3 → 4 taken 1561 times.
✗ Branch 3 → 35 not taken.
1561 auto fieldType = std::any_cast<QualType>(visit(node->dataType));
48
4/6
✓ Branch 5 → 6 taken 1561 times.
✗ Branch 5 → 50 not taken.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 9 taken 1560 times.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 50 not taken.
1561 HANDLE_UNRESOLVED_TYPE_QT(fieldType)
49
50
2/2
✓ Branch 9 → 10 taken 233 times.
✓ Branch 9 → 31 taken 1327 times.
1560 if (TernaryExprNode *defaultValueNode = node->defaultValue) {
51
2/4
✓ Branch 10 → 11 taken 233 times.
✗ Branch 10 → 40 not taken.
✓ Branch 11 → 12 taken 233 times.
✗ Branch 11 → 38 not taken.
233 const QualType defaultValueType = std::any_cast<ExprResult>(visit(defaultValueNode)).type;
52
2/6
✓ Branch 13 → 14 taken 233 times.
✗ Branch 13 → 49 not taken.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 233 times.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 49 not taken.
234 HANDLE_UNRESOLVED_TYPE_QT(defaultValueType)
53
3/4
✓ Branch 17 → 18 taken 233 times.
✗ Branch 17 → 49 not taken.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 29 taken 232 times.
233 if (!fieldType.matches(defaultValueType, false, true, true))
54
4/8
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 44 not taken.
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 42 not taken.
✓ Branch 25 → 26 taken 1 time.
✗ Branch 25 → 48 not taken.
✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 48 not taken.
3 SOFT_ERROR_QT(node, FIELD_TYPE_NOT_MATCHING, "Type of the default values does not match the field type")
55 }
56
57
1/2
✓ Branch 31 → 32 taken 1559 times.
✗ Branch 31 → 50 not taken.
1559 return fieldType;
58 }
59
60 245 std::any TypeChecker::visitSignature(SignatureNode *node) {
61 245 const bool isFunction = node->signatureType == SignatureNode::SignatureType::TYPE_FUNCTION;
62
63 // Retrieve function template types
64 245 std::vector<GenericType> usedGenericTypes;
65
2/2
✓ Branch 2 → 3 taken 126 times.
✓ Branch 2 → 33 taken 119 times.
245 if (node->hasTemplateTypes) {
66
2/2
✓ Branch 31 → 5 taken 126 times.
✓ Branch 31 → 32 taken 125 times.
251 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
67 // Visit template type
68
2/4
✓ Branch 6 → 7 taken 126 times.
✗ Branch 6 → 108 not taken.
✓ Branch 7 → 8 taken 126 times.
✗ Branch 7 → 106 not taken.
126 auto templateType = std::any_cast<QualType>(visit(dataType));
69
2/4
✓ Branch 9 → 10 taken 126 times.
✗ Branch 9 → 117 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 13 taken 126 times.
126 if (templateType.is(TY_UNRESOLVED))
70 return static_cast<std::vector<Function *> *>(nullptr);
71 // Check if it is a generic type
72
3/4
✓ Branch 13 → 14 taken 126 times.
✗ Branch 13 → 117 not taken.
✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 23 taken 125 times.
126 if (!templateType.is(TY_GENERIC)) {
73
2/4
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 112 not taken.
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 110 not taken.
1 softError(dataType, EXPECTED_GENERIC_TYPE, "A template list can only contain generic types");
74
1/2
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 116 not taken.
1 return static_cast<std::vector<Function *> *>(nullptr);
75 }
76 // Convert generic symbol type to generic type
77
2/4
✓ Branch 23 → 24 taken 125 times.
✗ Branch 23 → 117 not taken.
✓ Branch 24 → 25 taken 125 times.
✗ Branch 24 → 117 not taken.
125 const GenericType *genericType = rootScope->lookupGenericTypeStrict(templateType.getSubType());
78
1/2
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 125 times.
125 assert(genericType != nullptr);
79
1/2
✓ Branch 27 → 28 taken 125 times.
✗ Branch 27 → 117 not taken.
125 usedGenericTypes.push_back(*genericType);
80 }
81 }
82
83 // Visit return type
84
1/2
✓ Branch 33 → 34 taken 244 times.
✗ Branch 33 → 161 not taken.
244 QualType returnType(TY_DYN);
85
2/2
✓ Branch 34 → 35 taken 191 times.
✓ Branch 34 → 51 taken 53 times.
244 if (isFunction) {
86
2/4
✓ Branch 35 → 36 taken 191 times.
✗ Branch 35 → 121 not taken.
✓ Branch 36 → 37 taken 191 times.
✗ Branch 36 → 119 not taken.
191 returnType = std::any_cast<QualType>(visit(node->returnType));
87
2/4
✓ Branch 38 → 39 taken 191 times.
✗ Branch 38 → 161 not taken.
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 42 taken 191 times.
191 if (returnType.is(TY_UNRESOLVED))
88 return static_cast<std::vector<Function *> *>(nullptr);
89
90
3/4
✓ Branch 42 → 43 taken 191 times.
✗ Branch 42 → 161 not taken.
✓ Branch 43 → 44 taken 1 time.
✓ Branch 43 → 51 taken 190 times.
191 if (!returnType.isCoveredByGenericTypeList(usedGenericTypes))
91
2/4
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 126 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 124 not taken.
2 softError(node->returnType, GENERIC_TYPE_NOT_IN_TEMPLATE,
92 "Generic return type not included in the template type list of the function");
93 }
94
95 // Visit params
96 244 QualTypeList paramTypes;
97 244 ParamList paramList;
98
2/2
✓ Branch 51 → 52 taken 8 times.
✓ Branch 51 → 80 taken 236 times.
244 if (node->hasParams) {
99
1/2
✓ Branch 53 → 54 taken 8 times.
✗ Branch 53 → 157 not taken.
8 paramList.reserve(node->paramTypeLst->dataTypes.size());
100
2/2
✓ Branch 78 → 56 taken 10 times.
✓ Branch 78 → 79 taken 8 times.
18 for (DataTypeNode *param : node->paramTypeLst->dataTypes) {
101
2/4
✓ Branch 57 → 58 taken 10 times.
✗ Branch 57 → 132 not taken.
✓ Branch 58 → 59 taken 10 times.
✗ Branch 58 → 130 not taken.
10 auto paramType = std::any_cast<QualType>(visit(param));
102
2/4
✓ Branch 60 → 61 taken 10 times.
✗ Branch 60 → 141 not taken.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 64 taken 10 times.
10 if (paramType.is(TY_UNRESOLVED))
103 return static_cast<std::vector<Function *> *>(nullptr);
104
105 // Check if the type is present in the template for generic types
106
3/4
✓ Branch 64 → 65 taken 10 times.
✗ Branch 64 → 141 not taken.
✓ Branch 65 → 66 taken 2 times.
✓ Branch 65 → 73 taken 8 times.
10 if (!paramType.isCoveredByGenericTypeList(usedGenericTypes)) {
107
2/4
✓ Branch 68 → 69 taken 2 times.
✗ Branch 68 → 136 not taken.
✓ Branch 69 → 70 taken 2 times.
✗ Branch 69 → 134 not taken.
2 softError(node->paramTypeLst, GENERIC_TYPE_NOT_IN_TEMPLATE,
108 "Generic param type not included in the template type list of the function");
109 2 continue;
110 }
111
112
1/2
✓ Branch 73 → 74 taken 8 times.
✗ Branch 73 → 141 not taken.
8 paramTypes.push_back(paramType);
113
1/2
✓ Branch 74 → 75 taken 8 times.
✗ Branch 74 → 140 not taken.
8 paramList.push_back({paramType, false});
114 }
115 }
116
117 // Build signature object
118
5/10
✓ Branch 80 → 81 taken 244 times.
✗ Branch 80 → 152 not taken.
✓ Branch 81 → 82 taken 244 times.
✗ Branch 81 → 149 not taken.
✓ Branch 82 → 83 taken 244 times.
✗ Branch 82 → 146 not taken.
✓ Branch 83 → 84 taken 244 times.
✗ Branch 83 → 145 not taken.
✓ Branch 84 → 85 taken 244 times.
✗ Branch 84 → 143 not taken.
244 const Function signature(node->methodName, nullptr, QualType(TY_DYN), returnType, paramList, usedGenericTypes, node);
119
120 // Add signature to current scope
121
1/2
✓ Branch 88 → 89 taken 244 times.
✗ Branch 88 → 155 not taken.
244 Function *manifestation = FunctionManager::insert(currentScope, signature, &node->signatureManifestations);
122 244 manifestation->entry = node->entry;
123 244 manifestation->used = true;
124
125 // Prepare signature type
126
2/2
✓ Branch 89 → 90 taken 191 times.
✓ Branch 89 → 91 taken 53 times.
244 const SuperType superType = isFunction ? TY_FUNCTION : TY_PROCEDURE;
127
2/4
✓ Branch 92 → 93 taken 244 times.
✗ Branch 92 → 153 not taken.
✓ Branch 93 → 94 taken 244 times.
✗ Branch 93 → 153 not taken.
244 QualType signatureType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
128 244 signatureType.setQualifiers(node->signatureQualifiers);
129
130 // Set entry to signature type
131
1/2
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 97 taken 244 times.
244 assert(node->entry != nullptr);
132
1/2
✓ Branch 97 → 98 taken 244 times.
✗ Branch 97 → 155 not taken.
244 node->entry->updateType(signatureType, false);
133 244 node->entry->used = true;
134
135
1/2
✓ Branch 98 → 99 taken 244 times.
✗ Branch 98 → 154 not taken.
244 return &node->signatureManifestations;
136 245 }
137
138 67789 std::any TypeChecker::visitDataType(DataTypeNode *node) {
139 // Visit base data type
140
2/4
✓ Branch 2 → 3 taken 67789 times.
✗ Branch 2 → 219 not taken.
✓ Branch 3 → 4 taken 67789 times.
✗ Branch 3 → 217 not taken.
67789 auto type = std::any_cast<QualType>(visit(node->baseDataType));
141
4/6
✓ Branch 5 → 6 taken 67789 times.
✗ Branch 5 → 320 not taken.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 9 taken 67786 times.
✓ Branch 7 → 8 taken 3 times.
✗ Branch 7 → 320 not taken.
67789 HANDLE_UNRESOLVED_TYPE_QT(type)
142
143
1/2
✓ Branch 9 → 10 taken 67786 times.
✗ Branch 9 → 320 not taken.
67786 std::queue<DataTypeNode::TypeModifier> tmQueue = node->tmQueue;
144
2/2
✓ Branch 108 → 11 taken 16119 times.
✓ Branch 108 → 109 taken 67779 times.
83898 while (!tmQueue.empty()) {
145
1/2
✓ Branch 12 → 13 taken 16119 times.
✗ Branch 12 → 269 not taken.
16119 auto [modifierType, hasSize, hardcodedSize, sizeVarName] = tmQueue.front();
146
147 // Only the outermost array can have an unknown size
148
8/10
✓ Branch 13 → 14 taken 16119 times.
✗ Branch 13 → 267 not taken.
✓ Branch 14 → 15 taken 41 times.
✓ Branch 14 → 18 taken 16078 times.
✓ Branch 15 → 16 taken 41 times.
✗ Branch 15 → 267 not taken.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 18 taken 40 times.
✓ Branch 19 → 20 taken 1 time.
✓ Branch 19 → 30 taken 16118 times.
16119 if (type.isArray() && type.getArraySize() == ARRAY_SIZE_UNKNOWN)
149
4/8
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 222 not taken.
✓ Branch 23 → 24 taken 1 time.
✗ Branch 23 → 220 not taken.
✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 226 not taken.
✓ Branch 27 → 28 taken 1 time.
✗ Branch 27 → 226 not taken.
3 SOFT_ERROR_QT(node, ARRAY_SIZE_INVALID,
150 "Usage of incomplete array type. Only the outermost array type may have unknown size")
151
152
3/4
✓ Branch 30 → 31 taken 7474 times.
✓ Branch 30 → 33 taken 8491 times.
✓ Branch 30 → 35 taken 153 times.
✗ Branch 30 → 92 not taken.
16118 switch (modifierType) {
153 7474 case DataTypeNode::TypeModifierType::TYPE_PTR: {
154
2/2
✓ Branch 31 → 32 taken 7472 times.
✓ Branch 31 → 227 taken 2 times.
7474 type = type.toPtr(node);
155 7472 break;
156 }
157 8491 case DataTypeNode::TypeModifierType::TYPE_REF: {
158
1/2
✓ Branch 33 → 34 taken 8491 times.
✗ Branch 33 → 228 not taken.
8491 type = type.toRef(node);
159 8491 break;
160 }
161 153 case DataTypeNode::TypeModifierType::TYPE_ARRAY: {
162 153 const std::string &varName = sizeVarName;
163
2/2
✓ Branch 36 → 37 taken 35 times.
✓ Branch 36 → 78 taken 118 times.
153 if (!varName.empty()) {
164
1/2
✓ Branch 37 → 38 taken 35 times.
✗ Branch 37 → 267 not taken.
35 const SymbolTableEntry *globalVar = rootScope->lookupStrict(varName);
165
2/2
✓ Branch 40 → 41 taken 1 time.
✓ Branch 40 → 50 taken 34 times.
35 if (!globalVar)
166
5/10
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 233 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 231 not taken.
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 229 not taken.
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 235 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 235 not taken.
1 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_VARIABLE, "Could not find global variable '" + varName + "' ")
167
4/6
✓ Branch 50 → 51 taken 34 times.
✗ Branch 50 → 267 not taken.
✓ Branch 51 → 52 taken 34 times.
✗ Branch 51 → 267 not taken.
✓ Branch 52 → 53 taken 1 time.
✓ Branch 52 → 63 taken 33 times.
34 if (!globalVar->getQualType().isConst())
168
4/8
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 238 not taken.
✓ Branch 56 → 57 taken 1 time.
✗ Branch 56 → 236 not taken.
✓ Branch 59 → 60 taken 1 time.
✗ Branch 59 → 242 not taken.
✓ Branch 60 → 61 taken 1 time.
✗ Branch 60 → 242 not taken.
3 SOFT_ERROR_QT(node, EXPECTED_CONST_VARIABLE, "The size of the array must be known at compile time")
169
4/6
✓ Branch 63 → 64 taken 33 times.
✗ Branch 63 → 267 not taken.
✓ Branch 64 → 65 taken 33 times.
✗ Branch 64 → 267 not taken.
✓ Branch 65 → 66 taken 1 time.
✓ Branch 65 → 76 taken 32 times.
33 if (!globalVar->getQualType().is(TY_INT))
170
4/8
✓ Branch 68 → 69 taken 1 time.
✗ Branch 68 → 245 not taken.
✓ Branch 69 → 70 taken 1 time.
✗ Branch 69 → 243 not taken.
✓ Branch 72 → 73 taken 1 time.
✗ Branch 72 → 249 not taken.
✓ Branch 73 → 74 taken 1 time.
✗ Branch 73 → 249 not taken.
3 SOFT_ERROR_QT(node, OPERATOR_WRONG_DATA_TYPE, "Expected variable of type int")
171
1/2
✓ Branch 76 → 77 taken 32 times.
✗ Branch 76 → 267 not taken.
32 hardcodedSize = globalVar->declNode->getCompileTimeValue().intValue;
172 }
173
174
3/4
✓ Branch 78 → 79 taken 95 times.
✓ Branch 78 → 90 taken 55 times.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 90 taken 95 times.
150 if (hasSize && hardcodedSize <= 1)
175 SOFT_ERROR_QT(node, ARRAY_SIZE_INVALID, "The size of an array must be > 1 and explicitly stated")
176
2/2
✓ Branch 90 → 91 taken 149 times.
✓ Branch 90 → 257 taken 1 time.
150 type = type.toArr(node, hardcodedSize);
177 149 break;
178 }
179 default: // GCOV_EXCL_LINE
180 throw CompilerError(UNHANDLED_BRANCH, "Modifier type fall-through"); // GCOV_EXCL_LINE
181 }
182 16112 tmQueue.pop();
183
2/2
✓ Branch 103 → 104 taken 16112 times.
✓ Branch 103 → 106 taken 4 times.
16119 }
184
185 // Attach the qualifiers to the type
186
2/2
✓ Branch 109 → 110 taken 27947 times.
✓ Branch 109 → 210 taken 39832 times.
67779 if (node->qualifierLst) {
187
1/2
✓ Branch 110 → 111 taken 27947 times.
✗ Branch 110 → 316 not taken.
27947 const QualType baseType = type.getBase();
188
2/2
✓ Branch 207 → 113 taken 31955 times.
✓ Branch 207 → 208 taken 27945 times.
59900 for (const QualifierNode *qualifier : node->qualifierLst->qualifiers) {
189
2/2
✓ Branch 114 → 115 taken 14254 times.
✓ Branch 114 → 117 taken 17701 times.
31955 if (qualifier->type == QualifierNode::QualifierType::TY_CONST) {
190 14254 type.getQualifiers().isConst = true;
191
2/2
✓ Branch 117 → 118 taken 6 times.
✓ Branch 117 → 132 taken 17695 times.
17701 } else if (qualifier->type == QualifierNode::QualifierType::TY_SIGNED) {
192
2/4
✓ Branch 118 → 119 taken 6 times.
✗ Branch 118 → 270 not taken.
✗ Branch 119 → 120 not taken.
✓ Branch 119 → 129 taken 6 times.
6 if (!baseType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BYTE, TY_CHAR, TY_GENERIC}))
193 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "Cannot use this qualifier on type " + baseType.getName(false))
194 6 type.getQualifiers().isSigned = true;
195 6 type.getQualifiers().isUnsigned = false;
196
2/2
✓ Branch 132 → 133 taken 12015 times.
✓ Branch 132 → 147 taken 5680 times.
17695 } else if (qualifier->type == QualifierNode::QualifierType::TY_UNSIGNED) {
197
2/4
✓ Branch 133 → 134 taken 12015 times.
✗ Branch 133 → 278 not taken.
✗ Branch 134 → 135 not taken.
✓ Branch 134 → 144 taken 12015 times.
12015 if (!baseType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BYTE, TY_CHAR, TY_GENERIC}))
198 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "Cannot use this qualifier on type " + baseType.getName(false))
199 12015 type.getQualifiers().isSigned = false;
200 12015 type.getQualifiers().isUnsigned = true;
201
2/2
✓ Branch 147 → 148 taken 4818 times.
✓ Branch 147 → 162 taken 862 times.
5680 } else if (qualifier->type == QualifierNode::QualifierType::TY_HEAP) {
202 // Heap variables can only be pointers
203
4/6
✓ Branch 148 → 149 taken 4818 times.
✗ Branch 148 → 287 not taken.
✓ Branch 149 → 150 taken 4818 times.
✗ Branch 149 → 286 not taken.
✓ Branch 150 → 151 taken 1 time.
✓ Branch 150 → 160 taken 4817 times.
4818 if (!type.removeReferenceWrapper().isOneOf({TY_PTR, TY_ARRAY, TY_STRING}))
204
5/10
✓ Branch 151 → 152 taken 1 time.
✗ Branch 151 → 292 not taken.
✓ Branch 152 → 153 taken 1 time.
✗ Branch 152 → 290 not taken.
✓ Branch 153 → 154 taken 1 time.
✗ Branch 153 → 288 not taken.
✓ Branch 156 → 157 taken 1 time.
✗ Branch 156 → 294 not taken.
✓ Branch 157 → 158 taken 1 time.
✗ Branch 157 → 294 not taken.
1 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT,
205 "The heap qualifier can only be applied to symbols of pointer type, you provided " +
206 baseType.getName(false))
207
208 4817 type.getQualifiers().isHeap = true;
209
3/4
✓ Branch 162 → 163 taken 7 times.
✓ Branch 162 → 178 taken 855 times.
✓ Branch 163 → 164 taken 7 times.
✗ Branch 163 → 178 not taken.
862 } else if (qualifier->type == QualifierNode::QualifierType::TY_COMPOSITION && node->isFieldType) {
210
3/4
✓ Branch 164 → 165 taken 7 times.
✗ Branch 164 → 315 not taken.
✓ Branch 165 → 166 taken 1 time.
✓ Branch 165 → 176 taken 6 times.
7 if (!type.is(TY_STRUCT))
211
4/8
✓ Branch 168 → 169 taken 1 time.
✗ Branch 168 → 297 not taken.
✓ Branch 169 → 170 taken 1 time.
✗ Branch 169 → 295 not taken.
✓ Branch 172 → 173 taken 1 time.
✗ Branch 172 → 301 not taken.
✓ Branch 173 → 174 taken 1 time.
✗ Branch 173 → 301 not taken.
3 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "The compose qualifier can only be used on plain struct fields")
212 6 type.getQualifiers().isComposition = true;
213
4/6
✓ Branch 178 → 179 taken 855 times.
✗ Branch 178 → 183 not taken.
✓ Branch 179 → 180 taken 611 times.
✓ Branch 179 → 181 taken 244 times.
✓ Branch 180 → 181 taken 611 times.
✗ Branch 180 → 183 not taken.
855 } else if (qualifier->type == QualifierNode::QualifierType::TY_PUBLIC && (node->isFieldType || node->isGlobalType)) {
214 855 type.getQualifiers().isPublic = true;
215 } else {
216 auto entryName = "local variable";
217 if (node->isGlobalType)
218 entryName = "global variable";
219 else if (node->isFieldType)
220 entryName = "field";
221 else if (node->isParamType)
222 entryName = "param";
223 else if (node->isReturnType)
224 entryName = "return variable";
225 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT,
226 "Cannot use this qualifier on a " + std::string(entryName) + " definition")
227 }
228 }
229 }
230
231
2/4
✓ Branch 210 → 211 taken 67777 times.
✗ Branch 210 → 317 not taken.
✓ Branch 211 → 212 taken 67777 times.
✗ Branch 211 → 317 not taken.
67777 return node->setEvaluatedSymbolType(type, manIdx);
232 67786 }
233
234 67789 std::any TypeChecker::visitBaseDataType(BaseDataTypeNode *node) {
235
11/11
✓ Branch 2 → 3 taken 696 times.
✓ Branch 2 → 8 taken 4203 times.
✓ Branch 2 → 13 taken 1318 times.
✓ Branch 2 → 18 taken 11614 times.
✓ Branch 2 → 23 taken 3048 times.
✓ Branch 2 → 28 taken 8898 times.
✓ Branch 2 → 33 taken 7611 times.
✓ Branch 2 → 38 taken 4986 times.
✓ Branch 2 → 43 taken 24793 times.
✓ Branch 2 → 55 taken 136 times.
✓ Branch 2 → 67 taken 486 times.
67789 switch (node->type) {
236 696 case BaseDataTypeNode::Type::TYPE_DOUBLE:
237
3/6
✓ Branch 3 → 4 taken 696 times.
✗ Branch 3 → 73 not taken.
✓ Branch 4 → 5 taken 696 times.
✗ Branch 4 → 73 not taken.
✓ Branch 5 → 6 taken 696 times.
✗ Branch 5 → 73 not taken.
696 return node->setEvaluatedSymbolType(QualType(TY_DOUBLE), manIdx);
238 4203 case BaseDataTypeNode::Type::TYPE_INT:
239
3/6
✓ Branch 8 → 9 taken 4203 times.
✗ Branch 8 → 75 not taken.
✓ Branch 9 → 10 taken 4203 times.
✗ Branch 9 → 75 not taken.
✓ Branch 10 → 11 taken 4203 times.
✗ Branch 10 → 75 not taken.
4203 return node->setEvaluatedSymbolType(QualType(TY_INT), manIdx);
240 1318 case BaseDataTypeNode::Type::TYPE_SHORT:
241
3/6
✓ Branch 13 → 14 taken 1318 times.
✗ Branch 13 → 77 not taken.
✓ Branch 14 → 15 taken 1318 times.
✗ Branch 14 → 77 not taken.
✓ Branch 15 → 16 taken 1318 times.
✗ Branch 15 → 77 not taken.
1318 return node->setEvaluatedSymbolType(QualType(TY_SHORT), manIdx);
242 11614 case BaseDataTypeNode::Type::TYPE_LONG:
243
3/6
✓ Branch 18 → 19 taken 11614 times.
✗ Branch 18 → 79 not taken.
✓ Branch 19 → 20 taken 11614 times.
✗ Branch 19 → 79 not taken.
✓ Branch 20 → 21 taken 11614 times.
✗ Branch 20 → 79 not taken.
11614 return node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx);
244 3048 case BaseDataTypeNode::Type::TYPE_BYTE:
245
3/6
✓ Branch 23 → 24 taken 3048 times.
✗ Branch 23 → 81 not taken.
✓ Branch 24 → 25 taken 3048 times.
✗ Branch 24 → 81 not taken.
✓ Branch 25 → 26 taken 3048 times.
✗ Branch 25 → 81 not taken.
3048 return node->setEvaluatedSymbolType(QualType(TY_BYTE), manIdx);
246 8898 case BaseDataTypeNode::Type::TYPE_CHAR:
247
3/6
✓ Branch 28 → 29 taken 8898 times.
✗ Branch 28 → 83 not taken.
✓ Branch 29 → 30 taken 8898 times.
✗ Branch 29 → 83 not taken.
✓ Branch 30 → 31 taken 8898 times.
✗ Branch 30 → 83 not taken.
8898 return node->setEvaluatedSymbolType(QualType(TY_CHAR), manIdx);
248 7611 case BaseDataTypeNode::Type::TYPE_STRING:
249
3/6
✓ Branch 33 → 34 taken 7611 times.
✗ Branch 33 → 85 not taken.
✓ Branch 34 → 35 taken 7611 times.
✗ Branch 34 → 85 not taken.
✓ Branch 35 → 36 taken 7611 times.
✗ Branch 35 → 85 not taken.
7611 return node->setEvaluatedSymbolType(QualType(TY_STRING), manIdx);
250 4986 case BaseDataTypeNode::Type::TYPE_BOOL:
251
3/6
✓ Branch 38 → 39 taken 4986 times.
✗ Branch 38 → 87 not taken.
✓ Branch 39 → 40 taken 4986 times.
✗ Branch 39 → 87 not taken.
✓ Branch 40 → 41 taken 4986 times.
✗ Branch 40 → 87 not taken.
4986 return node->setEvaluatedSymbolType(QualType(TY_BOOL), manIdx);
252 24793 case BaseDataTypeNode::Type::TYPE_CUSTOM: {
253
2/4
✓ Branch 43 → 44 taken 24793 times.
✗ Branch 43 → 91 not taken.
✓ Branch 44 → 45 taken 24793 times.
✗ Branch 44 → 89 not taken.
24793 const auto customType = std::any_cast<QualType>(visit(node->customDataType));
254
4/6
✓ Branch 46 → 47 taken 24793 times.
✗ Branch 46 → 93 not taken.
✓ Branch 47 → 48 taken 3 times.
✓ Branch 47 → 50 taken 24790 times.
✓ Branch 48 → 49 taken 3 times.
✗ Branch 48 → 93 not taken.
24793 HANDLE_UNRESOLVED_TYPE_QT(customType)
255
2/4
✓ Branch 50 → 51 taken 24790 times.
✗ Branch 50 → 92 not taken.
✓ Branch 51 → 52 taken 24790 times.
✗ Branch 51 → 92 not taken.
24790 return node->setEvaluatedSymbolType(customType, manIdx);
256 }
257 136 case BaseDataTypeNode::Type::TYPE_FUNCTION: {
258
2/4
✓ Branch 55 → 56 taken 136 times.
✗ Branch 55 → 96 not taken.
✓ Branch 56 → 57 taken 136 times.
✗ Branch 56 → 94 not taken.
136 const auto functionType = std::any_cast<QualType>(visit(node->functionDataType));
259
2/6
✓ Branch 58 → 59 taken 136 times.
✗ Branch 58 → 98 not taken.
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 62 taken 136 times.
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 98 not taken.
136 HANDLE_UNRESOLVED_TYPE_QT(functionType)
260
2/4
✓ Branch 62 → 63 taken 136 times.
✗ Branch 62 → 97 not taken.
✓ Branch 63 → 64 taken 136 times.
✗ Branch 63 → 97 not taken.
136 return node->setEvaluatedSymbolType(functionType, manIdx);
261 }
262 486 default:
263
3/6
✓ Branch 67 → 68 taken 486 times.
✗ Branch 67 → 99 not taken.
✓ Branch 68 → 69 taken 486 times.
✗ Branch 68 → 99 not taken.
✓ Branch 69 → 70 taken 486 times.
✗ Branch 69 → 99 not taken.
486 return node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx);
264 }
265 }
266
267 24793 std::any TypeChecker::visitCustomDataType(CustomDataTypeNode *node) {
268 // It is a struct type -> get the access scope
269
1/2
✓ Branch 3 → 4 taken 24793 times.
✗ Branch 3 → 240 not taken.
24793 const std::string firstFragment = node->typeNameFragments.front();
270
271 // Check this type requires a runtime module
272
2/2
✓ Branch 5 → 6 taken 24766 times.
✓ Branch 5 → 7 taken 27 times.
24793 if (node->typeNameFragments.size() == 1)
273
1/2
✓ Branch 6 → 7 taken 24766 times.
✗ Branch 6 → 238 not taken.
24766 ensureLoadedRuntimeForTypeName(firstFragment);
274
275 // A type can either be a single fragment like "Test" or multiple fragments "a.b.Test", which means it is imported.
276 24793 bool isImported = node->typeNameFragments.size() > 1;
277
3/4
✓ Branch 8 → 9 taken 24793 times.
✗ Branch 8 → 238 not taken.
✓ Branch 9 → 10 taken 13693 times.
✓ Branch 9 → 25 taken 11100 times.
24793 if (const QualType *genericType = rootScope->lookupGenericTypeStrict(firstFragment)) {
278
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 13693 times.
13693 assert(!isImported);
279 // Take the concrete replacement type for the name of this generic type if available
280
4/6
✓ Branch 12 → 13 taken 13693 times.
✗ Branch 12 → 238 not taken.
✓ Branch 13 → 14 taken 4896 times.
✓ Branch 13 → 16 taken 8797 times.
✓ Branch 14 → 15 taken 4896 times.
✗ Branch 14 → 238 not taken.
13693 const QualType &symbolType = typeMapping.contains(firstFragment) ? typeMapping.at(firstFragment) : *genericType;
281
282 // Check if the replacement requires a runtime module
283
3/4
✓ Branch 17 → 18 taken 13693 times.
✗ Branch 17 → 238 not taken.
✓ Branch 18 → 19 taken 690 times.
✓ Branch 18 → 21 taken 13003 times.
13693 if (symbolType.is(TY_STRUCT))
284
2/4
✓ Branch 19 → 20 taken 690 times.
✗ Branch 19 → 238 not taken.
✓ Branch 20 → 21 taken 690 times.
✗ Branch 20 → 238 not taken.
690 ensureLoadedRuntimeForTypeName(symbolType.getSubType());
285
286
2/4
✓ Branch 21 → 22 taken 13693 times.
✗ Branch 21 → 180 not taken.
✓ Branch 22 → 23 taken 13693 times.
✗ Branch 22 → 180 not taken.
13693 return node->setEvaluatedSymbolType(symbolType, manIdx);
287 }
288
289 // Check if the type exists in the exported names registry
290
1/2
✓ Branch 25 → 26 taken 11100 times.
✗ Branch 25 → 238 not taken.
11100 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqTypeName);
291
2/2
✓ Branch 26 → 27 taken 2 times.
✓ Branch 26 → 36 taken 11098 times.
11100 if (!registryEntry)
292
5/10
✓ Branch 27 → 28 taken 2 times.
✗ Branch 27 → 185 not taken.
✓ Branch 28 → 29 taken 2 times.
✗ Branch 28 → 183 not taken.
✓ Branch 29 → 30 taken 2 times.
✗ Branch 29 → 181 not taken.
✓ Branch 32 → 33 taken 2 times.
✗ Branch 32 → 187 not taken.
✓ Branch 33 → 34 taken 2 times.
✗ Branch 33 → 187 not taken.
2 SOFT_ERROR_QT(node, UNKNOWN_DATATYPE, "Unknown datatype '" + node->fqTypeName + "'")
293
2/4
✓ Branch 36 → 37 taken 11098 times.
✗ Branch 36 → 39 not taken.
✓ Branch 37 → 38 taken 11098 times.
✗ Branch 37 → 39 not taken.
11098 assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr);
294 11098 SymbolTableEntry *entry = registryEntry->targetEntry;
295
1/2
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 11098 times.
11098 assert(entry != nullptr);
296 11098 entry->used = true;
297 11098 Scope *defScope = registryEntry->targetScope->parent;
298
1/2
✓ Branch 42 → 43 taken 11098 times.
✗ Branch 42 → 238 not taken.
11098 QualType entryType = entry->getQualType();
299
300 // Enums can early-return
301
3/4
✓ Branch 43 → 44 taken 11098 times.
✗ Branch 43 → 238 not taken.
✓ Branch 44 → 45 taken 116 times.
✓ Branch 44 → 49 taken 10982 times.
11098 if (entryType.is(TY_ENUM))
302
2/4
✓ Branch 45 → 46 taken 116 times.
✗ Branch 45 → 188 not taken.
✓ Branch 46 → 47 taken 116 times.
✗ Branch 46 → 188 not taken.
232 return QualType(TY_INT);
303
304
3/4
✓ Branch 49 → 50 taken 10982 times.
✗ Branch 49 → 189 not taken.
✓ Branch 50 → 51 taken 9983 times.
✓ Branch 50 → 152 taken 999 times.
10982 if (entryType.isOneOf({TY_STRUCT, TY_INTERFACE})) {
305
2/4
✓ Branch 51 → 52 taken 9983 times.
✗ Branch 51 → 53 not taken.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 9983 times.
9983 assert(dynamic_cast<DataTypeNode *>(node->parent->parent) != nullptr);
306
307 // Collect the concrete template types
308 9983 bool allTemplateTypesConcrete = true;
309 9983 QualTypeList templateTypes;
310
2/2
✓ Branch 56 → 57 taken 2751 times.
✓ Branch 56 → 88 taken 7232 times.
9983 if (node->templateTypeLst) {
311
1/2
✗ Branch 57 → 58 not taken.
✓ Branch 57 → 59 taken 2751 times.
2751 assert(defScope != nullptr);
312
1/2
✓ Branch 59 → 60 taken 2751 times.
✗ Branch 59 → 220 not taken.
2751 isImported = defScope->isImportedBy(rootScope);
313
314
1/2
✓ Branch 61 → 62 taken 2751 times.
✗ Branch 61 → 220 not taken.
2751 templateTypes.reserve(node->templateTypeLst->dataTypes.size());
315
2/2
✓ Branch 85 → 64 taken 3684 times.
✓ Branch 85 → 86 taken 2751 times.
6435 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
316
2/4
✓ Branch 65 → 66 taken 3684 times.
✗ Branch 65 → 192 not taken.
✓ Branch 66 → 67 taken 3684 times.
✗ Branch 66 → 190 not taken.
3684 auto templateType = std::any_cast<QualType>(visit(dataType));
317
2/6
✓ Branch 68 → 69 taken 3684 times.
✗ Branch 68 → 194 not taken.
✗ Branch 69 → 70 not taken.
✓ Branch 69 → 72 taken 3684 times.
✗ Branch 70 → 71 not taken.
✗ Branch 70 → 194 not taken.
3684 HANDLE_UNRESOLVED_TYPE_QT(templateType)
318
2/4
✓ Branch 72 → 73 taken 3684 times.
✗ Branch 72 → 194 not taken.
✗ Branch 73 → 74 not taken.
✓ Branch 73 → 75 taken 3684 times.
3684 if (entryType.is(TY_GENERIC)) {
319 allTemplateTypesConcrete = false;
320
2/2
✓ Branch 75 → 76 taken 1277 times.
✓ Branch 75 → 82 taken 2407 times.
3684 } else if (isImported) {
321 // Introduce the local type to the imported source file
322
1/2
✓ Branch 76 → 77 taken 1277 times.
✗ Branch 76 → 193 not taken.
1277 [[maybe_unused]] QualType importedType = mapLocalTypeToImportedScopeType(defScope, templateType);
323
3/6
✓ Branch 77 → 78 taken 1277 times.
✗ Branch 77 → 193 not taken.
✓ Branch 78 → 79 taken 1277 times.
✗ Branch 78 → 193 not taken.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 81 taken 1277 times.
1277 assert(importedType.is(templateType.getSuperType()));
324 }
325
1/2
✓ Branch 82 → 83 taken 3684 times.
✗ Branch 82 → 194 not taken.
3684 templateTypes.push_back(templateType);
326 }
327
1/2
✓ Branch 86 → 87 taken 2751 times.
✗ Branch 86 → 196 not taken.
2751 entryType = entryType.getWithTemplateTypes(templateTypes);
328 }
329
330 // Check if struct is defined before the current code location, if defined in the same source file
331 9983 const CodeLoc &declCodeLoc = entry->declNode->codeLoc;
332 9983 const CodeLoc &codeLoc = node->codeLoc;
333
6/6
✓ Branch 89 → 90 taken 7760 times.
✓ Branch 89 → 97 taken 2223 times.
✓ Branch 95 → 96 taken 1 time.
✓ Branch 95 → 97 taken 7759 times.
✓ Branch 98 → 99 taken 1 time.
✓ Branch 98 → 124 taken 9982 times.
17743 if (declCodeLoc.sourceFile->filePath == codeLoc.sourceFile->filePath && declCodeLoc > codeLoc) {
334
2/4
✓ Branch 99 → 100 taken 1 time.
✗ Branch 99 → 220 not taken.
✓ Branch 100 → 101 taken 1 time.
✗ Branch 100 → 111 not taken.
1 if (entryType.is(TY_STRUCT)) {
335
4/8
✓ Branch 103 → 104 taken 1 time.
✗ Branch 103 → 199 not taken.
✓ Branch 104 → 105 taken 1 time.
✗ Branch 104 → 197 not taken.
✓ Branch 107 → 108 taken 1 time.
✗ Branch 107 → 203 not taken.
✓ Branch 108 → 109 taken 1 time.
✗ Branch 108 → 203 not taken.
3 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_STRUCT, "Structs must be defined before usage")
336 } else {
337 assert(entryType.is(TY_INTERFACE));
338 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_INTERFACE, "Interfaces must be defined before usage")
339 }
340 }
341
342
1/2
✓ Branch 124 → 125 taken 9982 times.
✗ Branch 124 → 146 not taken.
9982 if (allTemplateTypesConcrete) { // Only do the next step, if we have concrete template types
343 // Set the struct/interface instance to used, if found
344 // Here, it is allowed to accept, that the struct/interface cannot be found, because there are self-referencing ones
345
3/4
✓ Branch 125 → 126 taken 9982 times.
✗ Branch 125 → 220 not taken.
✓ Branch 126 → 127 taken 9767 times.
✓ Branch 126 → 135 taken 215 times.
9982 if (entryType.is(TY_STRUCT)) {
346
1/2
✓ Branch 128 → 129 taken 9767 times.
✗ Branch 128 → 214 not taken.
9767 const std::string structName = node->typeNameFragments.back();
347
3/4
✓ Branch 129 → 130 taken 9767 times.
✗ Branch 129 → 212 not taken.
✓ Branch 130 → 131 taken 9717 times.
✓ Branch 130 → 133 taken 50 times.
9767 if (const Struct *spiceStruct = StructManager::match(defScope, structName, templateTypes, node))
348
1/2
✓ Branch 131 → 132 taken 9717 times.
✗ Branch 131 → 211 not taken.
9717 entryType = entryType.getWithBodyScope(spiceStruct->scope);
349 9767 } else {
350
2/4
✓ Branch 135 → 136 taken 215 times.
✗ Branch 135 → 218 not taken.
✗ Branch 136 → 137 not taken.
✓ Branch 136 → 138 taken 215 times.
215 assert(entryType.is(TY_INTERFACE));
351
1/2
✓ Branch 139 → 140 taken 215 times.
✗ Branch 139 → 218 not taken.
215 const std::string interfaceName = node->typeNameFragments.back();
352
2/4
✓ Branch 140 → 141 taken 215 times.
✗ Branch 140 → 216 not taken.
✓ Branch 141 → 142 taken 215 times.
✗ Branch 141 → 144 not taken.
215 if (const Interface *spiceInterface = InterfaceManager::match(defScope, interfaceName, templateTypes, node))
353
1/2
✓ Branch 142 → 143 taken 215 times.
✗ Branch 142 → 215 not taken.
215 entryType = entryType.getWithBodyScope(spiceInterface->scope);
354 215 }
355 }
356
357
2/4
✓ Branch 146 → 147 taken 9982 times.
✗ Branch 146 → 219 not taken.
✓ Branch 147 → 148 taken 9982 times.
✗ Branch 147 → 219 not taken.
9982 return node->setEvaluatedSymbolType(entryType, manIdx);
358 9983 }
359
360
2/4
✓ Branch 152 → 153 taken 999 times.
✗ Branch 152 → 238 not taken.
✓ Branch 153 → 154 taken 999 times.
✗ Branch 153 → 159 not taken.
999 if (entryType.is(TY_ALIAS))
361
3/6
✓ Branch 154 → 155 taken 999 times.
✗ Branch 154 → 223 not taken.
✓ Branch 155 → 156 taken 999 times.
✗ Branch 155 → 223 not taken.
✓ Branch 156 → 157 taken 999 times.
✗ Branch 156 → 223 not taken.
999 return node->setEvaluatedSymbolType(entryType.getAliased(entry), manIdx);
362
363 // We tried everything to resolve it, but this type is still unknown
364 const bool isInvalid = entryType.is(TY_INVALID);
365 SOFT_ERROR_QT(node, EXPECTED_TYPE, isInvalid ? "Used type before declared" : "Expected type, but got " + entryType.getName())
366 24793 }
367
368 136 std::any TypeChecker::visitFunctionDataType(FunctionDataTypeNode *node) {
369 // Visit return type
370
1/2
✓ Branch 2 → 3 taken 136 times.
✗ Branch 2 → 71 not taken.
136 QualType returnType(TY_DYN);
371
2/2
✓ Branch 3 → 4 taken 37 times.
✓ Branch 3 → 23 taken 99 times.
136 if (node->isFunction) {
372
2/4
✓ Branch 4 → 5 taken 37 times.
✗ Branch 4 → 53 not taken.
✓ Branch 5 → 6 taken 37 times.
✗ Branch 5 → 51 not taken.
37 returnType = std::any_cast<QualType>(visit(node->returnType));
373
2/6
✓ Branch 7 → 8 taken 37 times.
✗ Branch 7 → 71 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 11 taken 37 times.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 71 not taken.
37 HANDLE_UNRESOLVED_TYPE_QT(returnType)
374
2/4
✓ Branch 11 → 12 taken 37 times.
✗ Branch 11 → 71 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 23 taken 37 times.
37 if (returnType.is(TY_DYN))
375 SOFT_ERROR_ER(node->returnType, UNEXPECTED_DYN_TYPE, "Function types cannot have return type dyn")
376 }
377
378 // Visit param types
379 136 QualTypeList paramTypes;
380
2/2
✓ Branch 23 → 24 taken 83 times.
✓ Branch 23 → 39 taken 53 times.
136 if (const TypeLstNode *paramTypeListNode = node->paramTypeLst; paramTypeListNode != nullptr) {
381
2/2
✓ Branch 37 → 26 taken 112 times.
✓ Branch 37 → 38 taken 83 times.
195 for (DataTypeNode *paramTypeNode : paramTypeListNode->dataTypes) {
382
2/4
✓ Branch 27 → 28 taken 112 times.
✗ Branch 27 → 64 not taken.
✓ Branch 28 → 29 taken 112 times.
✗ Branch 28 → 62 not taken.
112 auto paramType = std::any_cast<QualType>(visit(paramTypeNode));
383
2/6
✓ Branch 30 → 31 taken 112 times.
✗ Branch 30 → 65 not taken.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 34 taken 112 times.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 65 not taken.
112 HANDLE_UNRESOLVED_TYPE_QT(returnType)
384
1/2
✓ Branch 34 → 35 taken 112 times.
✗ Branch 34 → 65 not taken.
112 paramTypes.push_back(paramType);
385 }
386 }
387
388 // Build function type
389
2/2
✓ Branch 39 → 40 taken 37 times.
✓ Branch 39 → 41 taken 99 times.
136 const SuperType superType = node->isFunction ? TY_FUNCTION : TY_PROCEDURE;
390
2/4
✓ Branch 42 → 43 taken 136 times.
✗ Branch 42 → 67 not taken.
✓ Branch 43 → 44 taken 136 times.
✗ Branch 43 → 67 not taken.
136 const QualType functionType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
391
392
2/4
✓ Branch 44 → 45 taken 136 times.
✗ Branch 44 → 68 not taken.
✓ Branch 45 → 46 taken 136 times.
✗ Branch 45 → 68 not taken.
136 return node->setEvaluatedSymbolType(functionType, manIdx);
393 136 }
394
395 } // namespace spice::compiler
396