GCC Code Coverage Report


Directory: ../
File: src/typechecker/TypeCheckMeta.cpp
Date: 2025-10-27 22:48:14
Coverage Exec Excl Total
Lines: 91.2% 228 2 252
Functions: 100.0% 7 0 7
Branches: 51.6% 372 4 725

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