GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 91.6% 240 / 2 / 264
Functions: 100.0% 7 / 0 / 7
Branches: 52.2% 391 / 4 / 753

src/typechecker/TypeCheckerMeta.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 56474 std::any TypeChecker::visitParamLst(ParamLstNode *node) {
18 56474 NamedParamList namedParams;
19 56474 bool metOptional = false;
20
21
2/2
✓ Branch 58 → 4 taken 84199 times.
✓ Branch 58 → 59 taken 56474 times.
197147 for (DeclStmtNode *param : node->params) {
22 // Visit param
23
2/4
✓ Branch 6 → 7 taken 84199 times.
✗ Branch 6 → 66 not taken.
✓ Branch 7 → 8 taken 84199 times.
✗ Branch 7 → 64 not taken.
84199 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 9 → 10 taken 84199 times.
✗ Branch 9 → 96 not taken.
✓ Branch 10 → 11 taken 3 times.
✓ Branch 10 → 17 taken 84196 times.
84199 if (paramType.is(TY_DYN)) {
27
3/6
✓ Branch 11 → 12 taken 3 times.
✗ Branch 11 → 71 not taken.
✓ Branch 12 → 13 taken 3 times.
✗ Branch 12 → 69 not taken.
✓ Branch 13 → 14 taken 3 times.
✗ Branch 13 → 67 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 17 → 18 taken 7849 times.
✓ Branch 17 → 19 taken 76347 times.
84196 if (param->hasAssignment) {
33 7849 metOptional = true;
34
2/2
✓ Branch 19 → 20 taken 6 times.
✓ Branch 19 → 27 taken 76341 times.
76347 } else if (metOptional) {
35
2/4
✓ Branch 22 → 23 taken 6 times.
✗ Branch 22 → 75 not taken.
✓ Branch 23 → 24 taken 6 times.
✗ Branch 23 → 73 not taken.
6 softError(param, INVALID_PARAM_ORDER, "Mandatory parameters must go before any optional parameters");
36 6 continue;
37 }
38
39 // Warn about non-trivially copyable types being passed by value, since that requires an implicit copy on every call.
40 // Only check in the check stage (not the prepare stage), because generic param types are not substantiated yet there.
41
7/8
✓ Branch 27 → 28 taken 44339 times.
✓ Branch 27 → 31 taken 39851 times.
✓ Branch 28 → 29 taken 44339 times.
✗ Branch 28 → 96 not taken.
✓ Branch 29 → 30 taken 52 times.
✓ Branch 29 → 31 taken 44287 times.
✓ Branch 32 → 33 taken 52 times.
✓ Branch 32 → 45 taken 84138 times.
84190 if (typeCheckerMode == TC_MODE_POST && !paramType.isTriviallyCopyable(param)) {
42
2/4
✓ Branch 34 → 35 taken 52 times.
✗ Branch 34 → 85 not taken.
✓ Branch 35 → 36 taken 52 times.
✗ Branch 35 → 83 not taken.
104 const std::string message = "Parameter '" + param->varName + "' has the non-trivially copyable type '" +
43
2/4
✓ Branch 33 → 34 taken 52 times.
✗ Branch 33 → 89 not taken.
✓ Branch 36 → 37 taken 52 times.
✗ Branch 36 → 81 not taken.
156 paramType.getName() +
44 "' and is passed by value, which requires an implicit copy on every call. Consider "
45
1/2
✓ Branch 37 → 38 taken 52 times.
✗ Branch 37 → 79 not taken.
52 "passing it by reference instead.";
46
1/2
✓ Branch 42 → 43 taken 52 times.
✗ Branch 42 → 91 not taken.
52 warnings.emplace_back(param->codeLoc, NON_TRIVIAL_TYPE_PASSED_BY_VALUE, message);
47 52 }
48
49 // Add parameter to named param list
50
1/2
✓ Branch 46 → 47 taken 84190 times.
✗ Branch 46 → 95 not taken.
84190 namedParams.push_back({param->varName.c_str(), paramType, metOptional});
51 }
52
53
1/2
✓ Branch 59 → 60 taken 56474 times.
✗ Branch 59 → 98 not taken.
112948 return namedParams;
54 56474 }
55
56 6177 std::any TypeChecker::visitField(FieldNode *node) {
57
2/4
✓ Branch 2 → 3 taken 6177 times.
✗ Branch 2 → 37 not taken.
✓ Branch 3 → 4 taken 6177 times.
✗ Branch 3 → 35 not taken.
6177 auto fieldType = std::any_cast<QualType>(visit(node->dataType));
58
4/6
✓ Branch 5 → 6 taken 6177 times.
✗ Branch 5 → 50 not taken.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 9 taken 6176 times.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 50 not taken.
6177 HANDLE_UNRESOLVED_TYPE_QT(fieldType)
59
60
2/2
✓ Branch 9 → 10 taken 1920 times.
✓ Branch 9 → 31 taken 4256 times.
6176 if (ExprNode *defaultValueNode = node->defaultValue) {
61
2/4
✓ Branch 10 → 11 taken 1920 times.
✗ Branch 10 → 40 not taken.
✓ Branch 11 → 12 taken 1920 times.
✗ Branch 11 → 38 not taken.
1920 const QualType defaultValueType = std::any_cast<ExprResult>(visit(defaultValueNode)).type;
62
2/6
✓ Branch 13 → 14 taken 1920 times.
✗ Branch 13 → 49 not taken.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 1920 times.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 49 not taken.
1921 HANDLE_UNRESOLVED_TYPE_QT(defaultValueType)
63
3/4
✓ Branch 17 → 18 taken 1920 times.
✗ Branch 17 → 49 not taken.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 29 taken 1919 times.
1920 if (!fieldType.matches(defaultValueType, false, true, true))
64
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.
4 SOFT_ERROR_QT(node, FIELD_TYPE_NOT_MATCHING, "Type of the default values does not match the field type")
65 }
66
67
1/2
✓ Branch 31 → 32 taken 6175 times.
✗ Branch 31 → 50 not taken.
6175 return fieldType;
68 }
69
70 2433 std::any TypeChecker::visitSignature(SignatureNode *node) {
71 2433 const bool isFunction = node->signatureType == SignatureNode::SignatureType::TYPE_FUNCTION;
72
73 // Retrieve function template types
74 2433 std::vector<GenericType> usedGenericTypes;
75
2/2
✓ Branch 2 → 3 taken 286 times.
✓ Branch 2 → 43 taken 2147 times.
2433 if (node->hasTemplateTypes) {
76
2/2
✓ Branch 41 → 5 taken 286 times.
✓ Branch 41 → 42 taken 285 times.
857 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
77 // Visit template type
78
2/4
✓ Branch 7 → 8 taken 286 times.
✗ Branch 7 → 129 not taken.
✓ Branch 8 → 9 taken 286 times.
✗ Branch 8 → 127 not taken.
286 auto templateType = std::any_cast<QualType>(visit(dataType));
79
2/4
✓ Branch 10 → 11 taken 286 times.
✗ Branch 10 → 138 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 15 taken 286 times.
286 if (templateType.is(TY_UNRESOLVED))
80 return static_cast<std::vector<Function *> *>(nullptr);
81 // Check if it is a generic type
82
3/4
✓ Branch 15 → 16 taken 286 times.
✗ Branch 15 → 138 not taken.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 26 taken 285 times.
286 if (!templateType.is(TY_GENERIC)) {
83
2/4
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 133 not taken.
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 131 not taken.
1 softError(dataType, EXPECTED_GENERIC_TYPE, "A template list can only contain generic types");
84
1/2
✓ Branch 23 → 24 taken 1 time.
✗ Branch 23 → 137 not taken.
2 return static_cast<std::vector<Function *> *>(nullptr);
85 }
86 // Convert generic symbol type to generic type
87
2/4
✓ Branch 26 → 27 taken 285 times.
✗ Branch 26 → 138 not taken.
✓ Branch 27 → 28 taken 285 times.
✗ Branch 27 → 138 not taken.
285 const GenericType *genericType = rootScope->lookupGenericTypeStrict(templateType.getSubType());
88
1/2
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 285 times.
285 assert(genericType != nullptr);
89
1/2
✓ Branch 30 → 31 taken 285 times.
✗ Branch 30 → 138 not taken.
285 usedGenericTypes.push_back(*genericType);
90 }
91 }
92
93 // Visit return type
94
1/2
✓ Branch 43 → 44 taken 2432 times.
✗ Branch 43 → 182 not taken.
2432 QualType returnType(TY_DYN);
95
2/2
✓ Branch 44 → 45 taken 2290 times.
✓ Branch 44 → 62 taken 142 times.
2432 if (isFunction) {
96
2/4
✓ Branch 45 → 46 taken 2290 times.
✗ Branch 45 → 142 not taken.
✓ Branch 46 → 47 taken 2290 times.
✗ Branch 46 → 140 not taken.
2290 returnType = std::any_cast<QualType>(visit(node->returnType));
97
2/4
✓ Branch 48 → 49 taken 2290 times.
✗ Branch 48 → 182 not taken.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 53 taken 2290 times.
2290 if (returnType.is(TY_UNRESOLVED))
98 return static_cast<std::vector<Function *> *>(nullptr);
99
100
3/4
✓ Branch 53 → 54 taken 2290 times.
✗ Branch 53 → 182 not taken.
✓ Branch 54 → 55 taken 1 time.
✓ Branch 54 → 62 taken 2289 times.
2290 if (!returnType.isCoveredByGenericTypeList(usedGenericTypes))
101
1/2
✓ Branch 58 → 59 taken 1 time.
✗ Branch 58 → 145 not taken.
1 softError(node->returnType, GENERIC_TYPE_NOT_IN_TEMPLATE,
102
1/2
✓ Branch 57 → 58 taken 1 time.
✗ Branch 57 → 147 not taken.
3 "Generic return type not included in the template type list of the function");
103 }
104
105 // Visit params
106 2432 QualTypeList paramTypes;
107 2432 ParamList paramList;
108
2/2
✓ Branch 62 → 63 taken 1442 times.
✓ Branch 62 → 101 taken 990 times.
2432 if (node->hasParams) {
109
1/2
✓ Branch 64 → 65 taken 1442 times.
✗ Branch 64 → 178 not taken.
1442 paramList.reserve(node->paramTypeLst->dataTypes.size());
110
2/2
✓ Branch 99 → 67 taken 1524 times.
✓ Branch 99 → 100 taken 1442 times.
4408 for (DataTypeNode *param : node->paramTypeLst->dataTypes) {
111
2/4
✓ Branch 69 → 70 taken 1524 times.
✗ Branch 69 → 153 not taken.
✓ Branch 70 → 71 taken 1524 times.
✗ Branch 70 → 151 not taken.
1524 auto paramType = std::any_cast<QualType>(visit(param));
112
2/4
✓ Branch 72 → 73 taken 1524 times.
✗ Branch 72 → 162 not taken.
✗ Branch 73 → 74 not taken.
✓ Branch 73 → 77 taken 1524 times.
1524 if (paramType.is(TY_UNRESOLVED))
113 return static_cast<std::vector<Function *> *>(nullptr);
114
115 // Check if the type is present in the template for generic types
116
3/4
✓ Branch 77 → 78 taken 1524 times.
✗ Branch 77 → 162 not taken.
✓ Branch 78 → 79 taken 2 times.
✓ Branch 78 → 86 taken 1522 times.
1524 if (!paramType.isCoveredByGenericTypeList(usedGenericTypes)) {
117
1/2
✓ Branch 82 → 83 taken 2 times.
✗ Branch 82 → 155 not taken.
2 softError(node->paramTypeLst, GENERIC_TYPE_NOT_IN_TEMPLATE,
118
1/2
✓ Branch 81 → 82 taken 2 times.
✗ Branch 81 → 157 not taken.
4 "Generic param type not included in the template type list of the function");
119 2 continue;
120 }
121
122
1/2
✓ Branch 86 → 87 taken 1522 times.
✗ Branch 86 → 162 not taken.
1522 paramTypes.push_back(paramType);
123
1/2
✓ Branch 87 → 88 taken 1522 times.
✗ Branch 87 → 161 not taken.
1522 paramList.push_back({paramType, false});
124 }
125 }
126
127 // Build signature object
128
5/10
✓ Branch 101 → 102 taken 2432 times.
✗ Branch 101 → 173 not taken.
✓ Branch 102 → 103 taken 2432 times.
✗ Branch 102 → 170 not taken.
✓ Branch 103 → 104 taken 2432 times.
✗ Branch 103 → 167 not taken.
✓ Branch 104 → 105 taken 2432 times.
✗ Branch 104 → 166 not taken.
✓ Branch 105 → 106 taken 2432 times.
✗ Branch 105 → 164 not taken.
2432 const Function signature(node->methodName, nullptr, QualType(TY_DYN), returnType, paramList, usedGenericTypes, node);
129
130 // Add signature to current scope
131
1/2
✓ Branch 109 → 110 taken 2432 times.
✗ Branch 109 → 176 not taken.
2432 Function *manifestation = FunctionManager::insert(currentScope, signature, &node->signatureManifestations);
132 2432 manifestation->entry = node->entry;
133 2432 manifestation->used = true;
134
135 // Prepare signature type
136
2/2
✓ Branch 110 → 111 taken 2290 times.
✓ Branch 110 → 112 taken 142 times.
2432 const SuperType superType = isFunction ? TY_FUNCTION : TY_PROCEDURE;
137
2/4
✓ Branch 113 → 114 taken 2432 times.
✗ Branch 113 → 174 not taken.
✓ Branch 114 → 115 taken 2432 times.
✗ Branch 114 → 174 not taken.
2432 QualType signatureType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
138 2432 signatureType.setQualifiers(node->signatureQualifiers);
139
140 // Set entry to signature type
141
1/2
✗ Branch 116 → 117 not taken.
✓ Branch 116 → 118 taken 2432 times.
2432 assert(node->entry != nullptr);
142
1/2
✓ Branch 118 → 119 taken 2432 times.
✗ Branch 118 → 176 not taken.
2432 node->entry->updateType(signatureType, false);
143 2432 node->entry->used = true;
144
145
1/2
✓ Branch 119 → 120 taken 2432 times.
✗ Branch 119 → 175 not taken.
2432 return &node->signatureManifestations;
146 2433 }
147
148 215565 std::any TypeChecker::visitDataType(DataTypeNode *node) {
149 // Visit base data type
150
2/4
✓ Branch 2 → 3 taken 215565 times.
✗ Branch 2 → 227 not taken.
✓ Branch 3 → 4 taken 215565 times.
✗ Branch 3 → 225 not taken.
215565 auto type = std::any_cast<QualType>(visit(node->baseDataType));
151
4/6
✓ Branch 5 → 6 taken 215565 times.
✗ Branch 5 → 328 not taken.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 9 taken 215562 times.
✓ Branch 7 → 8 taken 3 times.
✗ Branch 7 → 328 not taken.
215565 HANDLE_UNRESOLVED_TYPE_QT(type)
152
153
1/2
✓ Branch 9 → 10 taken 215562 times.
✗ Branch 9 → 328 not taken.
215562 std::queue<DataTypeNode::TypeModifier> tmQueue = node->tmQueue;
154
2/2
✓ Branch 108 → 11 taken 65906 times.
✓ Branch 108 → 109 taken 215555 times.
281461 while (!tmQueue.empty()) {
155
1/2
✓ Branch 12 → 13 taken 65906 times.
✗ Branch 12 → 277 not taken.
65906 auto [modifierType, hasSize, hardcodedSize, sizeVarName] = tmQueue.front();
156
157 // Only the outermost array can have an unknown size
158
8/10
✓ Branch 13 → 14 taken 65906 times.
✗ Branch 13 → 275 not taken.
✓ Branch 14 → 15 taken 52 times.
✓ Branch 14 → 18 taken 65854 times.
✓ Branch 15 → 16 taken 52 times.
✗ Branch 15 → 275 not taken.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 18 taken 51 times.
✓ Branch 19 → 20 taken 1 time.
✓ Branch 19 → 30 taken 65905 times.
65906 if (type.isArray() && type.getArraySize() == ARRAY_SIZE_UNKNOWN)
159
4/8
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 230 not taken.
✓ Branch 23 → 24 taken 1 time.
✗ Branch 23 → 228 not taken.
✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 234 not taken.
✓ Branch 27 → 28 taken 1 time.
✗ Branch 27 → 234 not taken.
4 SOFT_ERROR_QT(node, ARRAY_SIZE_INVALID,
160 "Usage of incomplete array type. Only the outermost array type may have unknown size")
161
162
3/4
✓ Branch 30 → 31 taken 37902 times.
✓ Branch 30 → 33 taken 27640 times.
✓ Branch 30 → 35 taken 363 times.
✗ Branch 30 → 92 not taken.
65905 switch (modifierType) {
163 37902 case DataTypeNode::TypeModifierType::TYPE_PTR: {
164
2/2
✓ Branch 31 → 32 taken 37900 times.
✓ Branch 31 → 235 taken 2 times.
37902 type = type.toPtr(node);
165 37900 break;
166 }
167 27640 case DataTypeNode::TypeModifierType::TYPE_REF: {
168
1/2
✓ Branch 33 → 34 taken 27640 times.
✗ Branch 33 → 236 not taken.
27640 type = type.toRef(node);
169 27640 break;
170 }
171 363 case DataTypeNode::TypeModifierType::TYPE_ARRAY: {
172 363 const std::string &varName = sizeVarName;
173
2/2
✓ Branch 36 → 37 taken 58 times.
✓ Branch 36 → 78 taken 305 times.
363 if (!varName.empty()) {
174
1/2
✓ Branch 37 → 38 taken 58 times.
✗ Branch 37 → 275 not taken.
58 const SymbolTableEntry *globalVar = rootScope->lookupStrict(varName);
175
2/2
✓ Branch 40 → 41 taken 1 time.
✓ Branch 40 → 50 taken 57 times.
58 if (!globalVar)
176
5/10
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 241 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 239 not taken.
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 237 not taken.
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 243 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 243 not taken.
2 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_VARIABLE, "Could not find global variable '" + varName + "' ")
177
4/6
✓ Branch 50 → 51 taken 57 times.
✗ Branch 50 → 275 not taken.
✓ Branch 51 → 52 taken 57 times.
✗ Branch 51 → 275 not taken.
✓ Branch 52 → 53 taken 1 time.
✓ Branch 52 → 63 taken 56 times.
57 if (!globalVar->getQualType().isConst())
178
4/8
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 246 not taken.
✓ Branch 56 → 57 taken 1 time.
✗ Branch 56 → 244 not taken.
✓ Branch 59 → 60 taken 1 time.
✗ Branch 59 → 250 not taken.
✓ Branch 60 → 61 taken 1 time.
✗ Branch 60 → 250 not taken.
4 SOFT_ERROR_QT(node, EXPECTED_CONST_VARIABLE, "The size of the array must be known at compile time")
179
4/6
✓ Branch 63 → 64 taken 56 times.
✗ Branch 63 → 275 not taken.
✓ Branch 64 → 65 taken 56 times.
✗ Branch 64 → 275 not taken.
✓ Branch 65 → 66 taken 1 time.
✓ Branch 65 → 76 taken 55 times.
56 if (!globalVar->getQualType().is(TY_INT))
180
4/8
✓ Branch 68 → 69 taken 1 time.
✗ Branch 68 → 253 not taken.
✓ Branch 69 → 70 taken 1 time.
✗ Branch 69 → 251 not taken.
✓ Branch 72 → 73 taken 1 time.
✗ Branch 72 → 257 not taken.
✓ Branch 73 → 74 taken 1 time.
✗ Branch 73 → 257 not taken.
4 SOFT_ERROR_QT(node, OPERATOR_WRONG_DATA_TYPE, "Expected variable of type int")
181
1/2
✓ Branch 76 → 77 taken 55 times.
✗ Branch 76 → 275 not taken.
55 hardcodedSize = globalVar->declNode->getCompileTimeValue(manIdx).intValue;
182 }
183
184
3/4
✓ Branch 78 → 79 taken 198 times.
✓ Branch 78 → 90 taken 162 times.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 90 taken 198 times.
360 if (hasSize && hardcodedSize <= 1)
185 SOFT_ERROR_QT(node, ARRAY_SIZE_INVALID, "The size of an array must be > 1 and explicitly stated")
186
2/2
✓ Branch 90 → 91 taken 359 times.
✓ Branch 90 → 265 taken 1 time.
360 type = type.toArr(node, hardcodedSize);
187 359 break;
188 }
189 default: // GCOV_EXCL_LINE
190 throw CompilerError(UNHANDLED_BRANCH, "Modifier type fall-through"); // GCOV_EXCL_LINE
191 }
192 65899 tmQueue.pop();
193
2/2
✓ Branch 103 → 104 taken 65899 times.
✓ Branch 103 → 106 taken 4 times.
65906 }
194
195 // Attach the qualifiers to the type
196
2/2
✓ Branch 109 → 110 taken 83154 times.
✓ Branch 109 → 218 taken 132401 times.
215555 if (node->qualifierLst) {
197
1/2
✓ Branch 110 → 111 taken 83154 times.
✗ Branch 110 → 324 not taken.
83154 const QualType baseType = type.getBase();
198
2/2
✓ Branch 215 → 113 taken 94880 times.
✓ Branch 215 → 216 taken 83152 times.
261186 for (const QualifierNode *qualifier : node->qualifierLst->qualifiers) {
199
2/2
✓ Branch 115 → 116 taken 39035 times.
✓ Branch 115 → 118 taken 55845 times.
94880 if (qualifier->type == QualifierNode::QualifierType::TY_CONST) {
200 39035 type.getQualifiers().isConst = true;
201
2/2
✓ Branch 118 → 119 taken 6 times.
✓ Branch 118 → 133 taken 55839 times.
55845 } else if (qualifier->type == QualifierNode::QualifierType::TY_SIGNED) {
202
2/4
✓ Branch 119 → 120 taken 6 times.
✗ Branch 119 → 278 not taken.
✗ Branch 120 → 121 not taken.
✓ Branch 120 → 130 taken 6 times.
6 if (!baseType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BYTE, TY_CHAR, TY_GENERIC}))
203 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "Cannot use this qualifier on type " + baseType.getName(false))
204 6 type.getQualifiers().isSigned = true;
205 6 type.getQualifiers().isUnsigned = false;
206
2/2
✓ Branch 133 → 134 taken 32781 times.
✓ Branch 133 → 148 taken 23058 times.
55839 } else if (qualifier->type == QualifierNode::QualifierType::TY_UNSIGNED) {
207
2/4
✓ Branch 134 → 135 taken 32781 times.
✗ Branch 134 → 286 not taken.
✗ Branch 135 → 136 not taken.
✓ Branch 135 → 145 taken 32781 times.
32781 if (!baseType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BYTE, TY_CHAR, TY_GENERIC}))
208 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "Cannot use this qualifier on type " + baseType.getName(false))
209 32781 type.getQualifiers().isSigned = false;
210 32781 type.getQualifiers().isUnsigned = true;
211
2/2
✓ Branch 148 → 149 taken 18107 times.
✓ Branch 148 → 163 taken 4951 times.
23058 } else if (qualifier->type == QualifierNode::QualifierType::TY_HEAP) {
212 // Heap variables can only be pointers
213
4/6
✓ Branch 149 → 150 taken 18107 times.
✗ Branch 149 → 295 not taken.
✓ Branch 150 → 151 taken 18107 times.
✗ Branch 150 → 294 not taken.
✓ Branch 151 → 152 taken 1 time.
✓ Branch 151 → 161 taken 18106 times.
18107 if (!type.removeReferenceWrapper().isOneOf({TY_PTR, TY_ARRAY, TY_STRING}))
214
5/10
✓ Branch 152 → 153 taken 1 time.
✗ Branch 152 → 300 not taken.
✓ Branch 153 → 154 taken 1 time.
✗ Branch 153 → 298 not taken.
✓ Branch 154 → 155 taken 1 time.
✗ Branch 154 → 296 not taken.
✓ Branch 157 → 158 taken 1 time.
✗ Branch 157 → 302 not taken.
✓ Branch 158 → 159 taken 1 time.
✗ Branch 158 → 302 not taken.
2 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT,
215 "The heap qualifier can only be applied to symbols of pointer type, you provided " +
216 baseType.getName(false))
217
218 18106 type.getQualifiers().isHeap = true;
219
3/4
✓ Branch 163 → 164 taken 1258 times.
✓ Branch 163 → 179 taken 3693 times.
✓ Branch 164 → 165 taken 1258 times.
✗ Branch 164 → 179 not taken.
4951 } else if (qualifier->type == QualifierNode::QualifierType::TY_COMPOSITION && node->isFieldType) {
220
3/4
✓ Branch 165 → 166 taken 1258 times.
✗ Branch 165 → 323 not taken.
✓ Branch 166 → 167 taken 1 time.
✓ Branch 166 → 177 taken 1257 times.
1258 if (!type.is(TY_STRUCT))
221
4/8
✓ Branch 169 → 170 taken 1 time.
✗ Branch 169 → 305 not taken.
✓ Branch 170 → 171 taken 1 time.
✗ Branch 170 → 303 not taken.
✓ Branch 173 → 174 taken 1 time.
✗ Branch 173 → 309 not taken.
✓ Branch 174 → 175 taken 1 time.
✗ Branch 174 → 309 not taken.
4 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT, "The compose qualifier can only be used on plain struct fields")
222 1257 type.getQualifiers().isComposition = true;
223
4/6
✓ Branch 179 → 180 taken 3693 times.
✗ Branch 179 → 184 not taken.
✓ Branch 180 → 181 taken 1340 times.
✓ Branch 180 → 182 taken 2353 times.
✓ Branch 181 → 182 taken 1340 times.
✗ Branch 181 → 184 not taken.
3693 } else if (qualifier->type == QualifierNode::QualifierType::TY_PUBLIC && (node->isFieldType || node->isGlobalType)) {
224 3693 type.getQualifiers().isPublic = true;
225 } else {
226 auto entryName = "local variable";
227 if (node->isGlobalType)
228 entryName = "global variable";
229 else if (node->isFieldType)
230 entryName = "field";
231 else if (node->isParamType)
232 entryName = "param";
233 else if (node->isReturnType)
234 entryName = "return variable";
235 SOFT_ERROR_QT(qualifier, QUALIFIER_AT_ILLEGAL_CONTEXT,
236 "Cannot use this qualifier on a " + std::string(entryName) + " definition")
237 }
238 }
239 }
240
241
2/4
✓ Branch 218 → 219 taken 215553 times.
✗ Branch 218 → 325 not taken.
✓ Branch 219 → 220 taken 215553 times.
✗ Branch 219 → 325 not taken.
431106 return node->setEvaluatedSymbolType(type, manIdx);
242 215562 }
243
244 215565 std::any TypeChecker::visitBaseDataType(BaseDataTypeNode *node) {
245
11/11
✓ Branch 2 → 3 taken 2799 times.
✓ Branch 2 → 8 taken 11365 times.
✓ Branch 2 → 13 taken 2771 times.
✓ Branch 2 → 18 taken 32468 times.
✓ Branch 2 → 23 taken 11513 times.
✓ Branch 2 → 28 taken 22604 times.
✓ Branch 2 → 33 taken 18547 times.
✓ Branch 2 → 38 taken 13455 times.
✓ Branch 2 → 43 taken 98013 times.
✓ Branch 2 → 55 taken 371 times.
✓ Branch 2 → 67 taken 1659 times.
215565 switch (node->type) {
246 2799 case BaseDataTypeNode::Type::TYPE_DOUBLE:
247
3/6
✓ Branch 3 → 4 taken 2799 times.
✗ Branch 3 → 73 not taken.
✓ Branch 4 → 5 taken 2799 times.
✗ Branch 4 → 73 not taken.
✓ Branch 5 → 6 taken 2799 times.
✗ Branch 5 → 73 not taken.
5598 return node->setEvaluatedSymbolType(QualType(TY_DOUBLE), manIdx);
248 11365 case BaseDataTypeNode::Type::TYPE_INT:
249
3/6
✓ Branch 8 → 9 taken 11365 times.
✗ Branch 8 → 75 not taken.
✓ Branch 9 → 10 taken 11365 times.
✗ Branch 9 → 75 not taken.
✓ Branch 10 → 11 taken 11365 times.
✗ Branch 10 → 75 not taken.
22730 return node->setEvaluatedSymbolType(QualType(TY_INT), manIdx);
250 2771 case BaseDataTypeNode::Type::TYPE_SHORT:
251
3/6
✓ Branch 13 → 14 taken 2771 times.
✗ Branch 13 → 77 not taken.
✓ Branch 14 → 15 taken 2771 times.
✗ Branch 14 → 77 not taken.
✓ Branch 15 → 16 taken 2771 times.
✗ Branch 15 → 77 not taken.
5542 return node->setEvaluatedSymbolType(QualType(TY_SHORT), manIdx);
252 32468 case BaseDataTypeNode::Type::TYPE_LONG:
253
3/6
✓ Branch 18 → 19 taken 32468 times.
✗ Branch 18 → 79 not taken.
✓ Branch 19 → 20 taken 32468 times.
✗ Branch 19 → 79 not taken.
✓ Branch 20 → 21 taken 32468 times.
✗ Branch 20 → 79 not taken.
64936 return node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx);
254 11513 case BaseDataTypeNode::Type::TYPE_BYTE:
255
3/6
✓ Branch 23 → 24 taken 11513 times.
✗ Branch 23 → 81 not taken.
✓ Branch 24 → 25 taken 11513 times.
✗ Branch 24 → 81 not taken.
✓ Branch 25 → 26 taken 11513 times.
✗ Branch 25 → 81 not taken.
23026 return node->setEvaluatedSymbolType(QualType(TY_BYTE), manIdx);
256 22604 case BaseDataTypeNode::Type::TYPE_CHAR:
257
3/6
✓ Branch 28 → 29 taken 22604 times.
✗ Branch 28 → 83 not taken.
✓ Branch 29 → 30 taken 22604 times.
✗ Branch 29 → 83 not taken.
✓ Branch 30 → 31 taken 22604 times.
✗ Branch 30 → 83 not taken.
45208 return node->setEvaluatedSymbolType(QualType(TY_CHAR), manIdx);
258 18547 case BaseDataTypeNode::Type::TYPE_STRING:
259
3/6
✓ Branch 33 → 34 taken 18547 times.
✗ Branch 33 → 85 not taken.
✓ Branch 34 → 35 taken 18547 times.
✗ Branch 34 → 85 not taken.
✓ Branch 35 → 36 taken 18547 times.
✗ Branch 35 → 85 not taken.
37094 return node->setEvaluatedSymbolType(QualType(TY_STRING), manIdx);
260 13455 case BaseDataTypeNode::Type::TYPE_BOOL:
261
3/6
✓ Branch 38 → 39 taken 13455 times.
✗ Branch 38 → 87 not taken.
✓ Branch 39 → 40 taken 13455 times.
✗ Branch 39 → 87 not taken.
✓ Branch 40 → 41 taken 13455 times.
✗ Branch 40 → 87 not taken.
26910 return node->setEvaluatedSymbolType(QualType(TY_BOOL), manIdx);
262 98013 case BaseDataTypeNode::Type::TYPE_CUSTOM: {
263
2/4
✓ Branch 43 → 44 taken 98013 times.
✗ Branch 43 → 91 not taken.
✓ Branch 44 → 45 taken 98013 times.
✗ Branch 44 → 89 not taken.
98013 const auto customType = std::any_cast<QualType>(visit(node->customDataType));
264
4/6
✓ Branch 46 → 47 taken 98013 times.
✗ Branch 46 → 93 not taken.
✓ Branch 47 → 48 taken 3 times.
✓ Branch 47 → 50 taken 98010 times.
✓ Branch 48 → 49 taken 3 times.
✗ Branch 48 → 93 not taken.
98013 HANDLE_UNRESOLVED_TYPE_QT(customType)
265
2/4
✓ Branch 50 → 51 taken 98010 times.
✗ Branch 50 → 92 not taken.
✓ Branch 51 → 52 taken 98010 times.
✗ Branch 51 → 92 not taken.
196020 return node->setEvaluatedSymbolType(customType, manIdx);
266 }
267 371 case BaseDataTypeNode::Type::TYPE_FUNCTION: {
268
2/4
✓ Branch 55 → 56 taken 371 times.
✗ Branch 55 → 96 not taken.
✓ Branch 56 → 57 taken 371 times.
✗ Branch 56 → 94 not taken.
371 const auto functionType = std::any_cast<QualType>(visit(node->functionDataType));
269
2/6
✓ Branch 58 → 59 taken 371 times.
✗ Branch 58 → 98 not taken.
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 62 taken 371 times.
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 98 not taken.
371 HANDLE_UNRESOLVED_TYPE_QT(functionType)
270
2/4
✓ Branch 62 → 63 taken 371 times.
✗ Branch 62 → 97 not taken.
✓ Branch 63 → 64 taken 371 times.
✗ Branch 63 → 97 not taken.
742 return node->setEvaluatedSymbolType(functionType, manIdx);
271 }
272 1659 default:
273
3/6
✓ Branch 67 → 68 taken 1659 times.
✗ Branch 67 → 99 not taken.
✓ Branch 68 → 69 taken 1659 times.
✗ Branch 68 → 99 not taken.
✓ Branch 69 → 70 taken 1659 times.
✗ Branch 69 → 99 not taken.
3318 return node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx);
274 }
275 }
276
277 98013 std::any TypeChecker::visitCustomDataType(CustomDataTypeNode *node) {
278 // It is a struct type -> get the access scope
279
1/2
✓ Branch 3 → 4 taken 98013 times.
✗ Branch 3 → 259 not taken.
98013 const std::string firstFragment = node->typeNameFragments.front();
280
281 // Check this type requires a runtime module
282
2/2
✓ Branch 5 → 6 taken 97870 times.
✓ Branch 5 → 7 taken 143 times.
98013 if (node->typeNameFragments.size() == 1)
283
1/2
✓ Branch 6 → 7 taken 97870 times.
✗ Branch 6 → 257 not taken.
97870 ensureLoadedRuntimeForTypeName(firstFragment);
284
285 // A type can either be a single fragment like "Test" or multiple fragments "a.b.Test", which means it is imported.
286 98013 bool isImported = node->typeNameFragments.size() > 1;
287
3/4
✓ Branch 8 → 9 taken 98013 times.
✗ Branch 8 → 257 not taken.
✓ Branch 9 → 10 taken 40553 times.
✓ Branch 9 → 27 taken 57460 times.
98013 if (const QualType *genericType = rootScope->lookupGenericTypeStrict(firstFragment)) {
288
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 40553 times.
40553 assert(!isImported);
289 // Take the concrete replacement type for the name of this generic type if available
290
1/2
✓ Branch 12 → 13 taken 40553 times.
✗ Branch 12 → 199 not taken.
40553 const auto it = typeMapping.find(firstFragment);
291
2/2
✓ Branch 15 → 16 taken 21223 times.
✓ Branch 15 → 17 taken 19330 times.
40553 const QualType &symbolType = it != typeMapping.end() ? it->second : *genericType;
292
293 // Check if the replacement requires a runtime module
294
3/4
✓ Branch 19 → 20 taken 40553 times.
✗ Branch 19 → 199 not taken.
✓ Branch 20 → 21 taken 7316 times.
✓ Branch 20 → 23 taken 33237 times.
40553 if (symbolType.is(TY_STRUCT))
295
2/4
✓ Branch 21 → 22 taken 7316 times.
✗ Branch 21 → 199 not taken.
✓ Branch 22 → 23 taken 7316 times.
✗ Branch 22 → 199 not taken.
7316 ensureLoadedRuntimeForTypeName(symbolType.getSubType());
296
297
2/4
✓ Branch 23 → 24 taken 40553 times.
✗ Branch 23 → 198 not taken.
✓ Branch 24 → 25 taken 40553 times.
✗ Branch 24 → 198 not taken.
81106 return node->setEvaluatedSymbolType(symbolType, manIdx);
298 }
299
300 // Check if the type exists in the exported names registry
301
1/2
✓ Branch 27 → 28 taken 57460 times.
✗ Branch 27 → 257 not taken.
57460 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqTypeName);
302
2/2
✓ Branch 28 → 29 taken 2 times.
✓ Branch 28 → 38 taken 57458 times.
57460 if (!registryEntry)
303
5/10
✓ Branch 29 → 30 taken 2 times.
✗ Branch 29 → 204 not taken.
✓ Branch 30 → 31 taken 2 times.
✗ Branch 30 → 202 not taken.
✓ Branch 31 → 32 taken 2 times.
✗ Branch 31 → 200 not taken.
✓ Branch 34 → 35 taken 2 times.
✗ Branch 34 → 206 not taken.
✓ Branch 35 → 36 taken 2 times.
✗ Branch 35 → 206 not taken.
4 SOFT_ERROR_QT(node, UNKNOWN_DATATYPE, "Unknown datatype '" + node->fqTypeName + "'")
304
2/4
✓ Branch 38 → 39 taken 57458 times.
✗ Branch 38 → 41 not taken.
✓ Branch 39 → 40 taken 57458 times.
✗ Branch 39 → 41 not taken.
57458 assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr);
305 57458 SymbolTableEntry *entry = registryEntry->targetEntry;
306
1/2
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 44 taken 57458 times.
57458 assert(entry != nullptr);
307 57458 entry->used = true;
308 57458 Scope *defScope = registryEntry->targetScope->parent;
309
1/2
✓ Branch 44 → 45 taken 57458 times.
✗ Branch 44 → 257 not taken.
57458 QualType entryType = entry->getQualType();
310
311 // With circular imports, two structs/interfaces in mutually importing files can reference each other, so neither can be
312 // prepared strictly before the other. If we reach one here before it has been prepared (its type is still invalid),
313 // assign its opaque type now - an implicit forward declaration. The full prepare pass assigns the identical interned
314 // type later and additionally fills in the body and manifestations.
315
3/4
✓ Branch 45 → 46 taken 57458 times.
✗ Branch 45 → 257 not taken.
✓ Branch 46 → 47 taken 1023 times.
✓ Branch 46 → 50 taken 56435 times.
57458 if (entryType.is(TY_INVALID)) {
316
1/2
✓ Branch 47 → 48 taken 1023 times.
✗ Branch 47 → 257 not taken.
1023 assignDeferredOpaqueType(entry);
317
1/2
✓ Branch 48 → 49 taken 1023 times.
✗ Branch 48 → 257 not taken.
1023 entryType = entry->getQualType();
318 }
319
320 // Enums can early-return
321
3/4
✓ Branch 50 → 51 taken 57458 times.
✗ Branch 50 → 257 not taken.
✓ Branch 51 → 52 taken 1368 times.
✓ Branch 51 → 56 taken 56090 times.
57458 if (entryType.is(TY_ENUM))
322
2/4
✓ Branch 52 → 53 taken 1368 times.
✗ Branch 52 → 207 not taken.
✓ Branch 53 → 54 taken 1368 times.
✗ Branch 53 → 207 not taken.
2736 return QualType(TY_INT);
323
324
3/4
✓ Branch 56 → 57 taken 56090 times.
✗ Branch 56 → 208 not taken.
✓ Branch 57 → 58 taken 49758 times.
✓ Branch 57 → 170 taken 6332 times.
56090 if (entryType.isOneOf({TY_STRUCT, TY_INTERFACE})) {
325
2/4
✓ Branch 58 → 59 taken 49758 times.
✗ Branch 58 → 60 not taken.
✗ Branch 63 → 64 not taken.
✓ Branch 63 → 65 taken 49758 times.
99516 assert(is<DataTypeNode *>(node->parent->parent));
326
327 // Collect the concrete template types
328 49758 bool allTemplateTypesConcrete = true;
329 49758 QualTypeList templateTypes;
330
2/2
✓ Branch 65 → 66 taken 11102 times.
✓ Branch 65 → 106 taken 38656 times.
49758 if (node->templateTypeLst) {
331
1/2
✗ Branch 66 → 67 not taken.
✓ Branch 66 → 68 taken 11102 times.
11102 assert(defScope != nullptr);
332
1/2
✓ Branch 68 → 69 taken 11102 times.
✗ Branch 68 → 239 not taken.
11102 isImported = defScope->isImportedBy(rootScope);
333
334
1/2
✓ Branch 70 → 71 taken 11102 times.
✗ Branch 70 → 239 not taken.
11102 templateTypes.reserve(node->templateTypeLst->dataTypes.size());
335
2/2
✓ Branch 103 → 73 taken 14920 times.
✓ Branch 103 → 104 taken 11102 times.
37124 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
336
2/4
✓ Branch 75 → 76 taken 14920 times.
✗ Branch 75 → 211 not taken.
✓ Branch 76 → 77 taken 14920 times.
✗ Branch 76 → 209 not taken.
14920 auto templateType = std::any_cast<QualType>(visit(dataType));
337
2/6
✓ Branch 78 → 79 taken 14920 times.
✗ Branch 78 → 213 not taken.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 82 taken 14920 times.
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 213 not taken.
14920 HANDLE_UNRESOLVED_TYPE_QT(templateType)
338
2/4
✓ Branch 82 → 83 taken 14920 times.
✗ Branch 82 → 213 not taken.
✗ Branch 83 → 84 not taken.
✓ Branch 83 → 85 taken 14920 times.
14920 if (entryType.is(TY_GENERIC)) {
339 allTemplateTypesConcrete = false;
340
2/2
✓ Branch 85 → 86 taken 5404 times.
✓ Branch 85 → 92 taken 9516 times.
14920 } else if (isImported) {
341 // Introduce the local type to the imported source file
342
1/2
✓ Branch 86 → 87 taken 5404 times.
✗ Branch 86 → 212 not taken.
5404 [[maybe_unused]] QualType importedType = mapLocalTypeToImportedScopeType(defScope, templateType);
343
3/6
✓ Branch 87 → 88 taken 5404 times.
✗ Branch 87 → 212 not taken.
✓ Branch 88 → 89 taken 5404 times.
✗ Branch 88 → 212 not taken.
✗ Branch 89 → 90 not taken.
✓ Branch 89 → 91 taken 5404 times.
5404 assert(importedType.is(templateType.getSuperType()));
344 }
345
1/2
✓ Branch 92 → 93 taken 14920 times.
✗ Branch 92 → 213 not taken.
14920 templateTypes.push_back(templateType);
346 }
347
1/2
✓ Branch 104 → 105 taken 11102 times.
✗ Branch 104 → 215 not taken.
11102 entryType = entryType.getWithTemplateTypes(templateTypes);
348 }
349
350 // Check if struct is defined before the current code location, if defined in the same source file. Across files
351 // (e.g. circular imports) the order does not matter, so the check only applies within the same source file.
352 49758 const CodeLoc &declCodeLoc = entry->declNode->codeLoc;
353 49758 const CodeLoc &codeLoc = node->codeLoc;
354
6/6
✓ Branch 107 → 108 taken 24367 times.
✓ Branch 107 → 115 taken 25391 times.
✓ Branch 113 → 114 taken 1 time.
✓ Branch 113 → 115 taken 24366 times.
✓ Branch 116 → 117 taken 1 time.
✓ Branch 116 → 142 taken 49757 times.
74125 if (declCodeLoc.sourceFile->filePath == codeLoc.sourceFile->filePath && declCodeLoc > codeLoc) {
355
2/4
✓ Branch 117 → 118 taken 1 time.
✗ Branch 117 → 239 not taken.
✓ Branch 118 → 119 taken 1 time.
✗ Branch 118 → 129 not taken.
1 if (entryType.is(TY_STRUCT)) {
356
4/8
✓ Branch 121 → 122 taken 1 time.
✗ Branch 121 → 218 not taken.
✓ Branch 122 → 123 taken 1 time.
✗ Branch 122 → 216 not taken.
✓ Branch 125 → 126 taken 1 time.
✗ Branch 125 → 222 not taken.
✓ Branch 126 → 127 taken 1 time.
✗ Branch 126 → 222 not taken.
4 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_STRUCT, "Structs must be defined before usage")
357 } else {
358 assert(entryType.is(TY_INTERFACE));
359 SOFT_ERROR_QT(node, REFERENCED_UNDEFINED_INTERFACE, "Interfaces must be defined before usage")
360 }
361 }
362
363
1/2
✓ Branch 142 → 143 taken 49757 times.
✗ Branch 142 → 164 not taken.
49757 if (allTemplateTypesConcrete) { // Only do the next step, if we have concrete template types
364 // Set the struct/interface instance to used, if found
365 // Here, it is allowed to accept, that the struct/interface cannot be found, because there are self-referencing ones
366
3/4
✓ Branch 143 → 144 taken 49757 times.
✗ Branch 143 → 239 not taken.
✓ Branch 144 → 145 taken 44958 times.
✓ Branch 144 → 153 taken 4799 times.
49757 if (entryType.is(TY_STRUCT)) {
367
1/2
✓ Branch 146 → 147 taken 44958 times.
✗ Branch 146 → 233 not taken.
44958 const std::string structName = node->typeNameFragments.back();
368
3/4
✓ Branch 147 → 148 taken 44958 times.
✗ Branch 147 → 231 not taken.
✓ Branch 148 → 149 taken 43769 times.
✓ Branch 148 → 151 taken 1189 times.
44958 if (const Struct *spiceStruct = StructManager::match(defScope, structName, templateTypes, node))
369
1/2
✓ Branch 149 → 150 taken 43769 times.
✗ Branch 149 → 230 not taken.
43769 entryType = entryType.getWithBodyScope(spiceStruct->scope);
370 44958 } else {
371
2/4
✓ Branch 153 → 154 taken 4799 times.
✗ Branch 153 → 237 not taken.
✗ Branch 154 → 155 not taken.
✓ Branch 154 → 156 taken 4799 times.
4799 assert(entryType.is(TY_INTERFACE));
372
1/2
✓ Branch 157 → 158 taken 4799 times.
✗ Branch 157 → 237 not taken.
4799 const std::string interfaceName = node->typeNameFragments.back();
373
3/4
✓ Branch 158 → 159 taken 4799 times.
✗ Branch 158 → 235 not taken.
✓ Branch 159 → 160 taken 4484 times.
✓ Branch 159 → 162 taken 315 times.
4799 if (const Interface *spiceInterface = InterfaceManager::match(defScope, interfaceName, templateTypes, node))
374
1/2
✓ Branch 160 → 161 taken 4484 times.
✗ Branch 160 → 234 not taken.
4484 entryType = entryType.getWithBodyScope(spiceInterface->scope);
375 4799 }
376 }
377
378
2/4
✓ Branch 164 → 165 taken 49757 times.
✗ Branch 164 → 238 not taken.
✓ Branch 165 → 166 taken 49757 times.
✗ Branch 165 → 238 not taken.
99514 return node->setEvaluatedSymbolType(entryType, manIdx);
379 49758 }
380
381
2/4
✓ Branch 170 → 171 taken 6332 times.
✗ Branch 170 → 257 not taken.
✓ Branch 171 → 172 taken 6332 times.
✗ Branch 171 → 177 not taken.
6332 if (entryType.is(TY_ALIAS))
382
3/6
✓ Branch 172 → 173 taken 6332 times.
✗ Branch 172 → 242 not taken.
✓ Branch 173 → 174 taken 6332 times.
✗ Branch 173 → 242 not taken.
✓ Branch 174 → 175 taken 6332 times.
✗ Branch 174 → 242 not taken.
12664 return node->setEvaluatedSymbolType(entryType.getAliased(entry), manIdx);
383
384 // We tried everything to resolve it, but this type is still unknown
385 const bool isInvalid = entryType.is(TY_INVALID);
386 SOFT_ERROR_QT(node, EXPECTED_TYPE, isInvalid ? "Used type before declared" : "Expected type, but got " + entryType.getName())
387 98013 }
388
389 371 std::any TypeChecker::visitFunctionDataType(FunctionDataTypeNode *node) {
390 // Visit return type
391
1/2
✓ Branch 2 → 3 taken 371 times.
✗ Branch 2 → 80 not taken.
371 QualType returnType(TY_DYN);
392
2/2
✓ Branch 3 → 4 taken 132 times.
✓ Branch 3 → 23 taken 239 times.
371 if (node->isFunction) {
393
2/4
✓ Branch 4 → 5 taken 132 times.
✗ Branch 4 → 62 not taken.
✓ Branch 5 → 6 taken 132 times.
✗ Branch 5 → 60 not taken.
132 returnType = std::any_cast<QualType>(visit(node->returnType));
394
2/6
✓ Branch 7 → 8 taken 132 times.
✗ Branch 7 → 80 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 11 taken 132 times.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 80 not taken.
132 HANDLE_UNRESOLVED_TYPE_QT(returnType)
395
2/4
✓ Branch 11 → 12 taken 132 times.
✗ Branch 11 → 80 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 23 taken 132 times.
132 if (returnType.is(TY_DYN))
396 SOFT_ERROR_ER(node->returnType, UNEXPECTED_DYN_TYPE, "Function types cannot have return type dyn")
397 }
398
399 // Visit param types
400 371 QualTypeList paramTypes;
401
2/2
✓ Branch 23 → 24 taken 283 times.
✓ Branch 23 → 48 taken 88 times.
371 if (const TypeLstNode *paramTypeListNode = node->paramTypeLst; paramTypeListNode != nullptr) {
402
2/2
✓ Branch 46 → 26 taken 358 times.
✓ Branch 46 → 47 taken 283 times.
924 for (DataTypeNode *paramTypeNode : paramTypeListNode->dataTypes) {
403
2/4
✓ Branch 28 → 29 taken 358 times.
✗ Branch 28 → 73 not taken.
✓ Branch 29 → 30 taken 358 times.
✗ Branch 29 → 71 not taken.
358 auto paramType = std::any_cast<QualType>(visit(paramTypeNode));
404
2/6
✓ Branch 31 → 32 taken 358 times.
✗ Branch 31 → 74 not taken.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 35 taken 358 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 74 not taken.
358 HANDLE_UNRESOLVED_TYPE_QT(returnType)
405
1/2
✓ Branch 35 → 36 taken 358 times.
✗ Branch 35 → 74 not taken.
358 paramTypes.push_back(paramType);
406 }
407 }
408
409 // Build function type
410
2/2
✓ Branch 48 → 49 taken 132 times.
✓ Branch 48 → 50 taken 239 times.
371 const SuperType superType = node->isFunction ? TY_FUNCTION : TY_PROCEDURE;
411
2/4
✓ Branch 51 → 52 taken 371 times.
✗ Branch 51 → 76 not taken.
✓ Branch 52 → 53 taken 371 times.
✗ Branch 52 → 76 not taken.
371 const QualType functionType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
412
413
2/4
✓ Branch 53 → 54 taken 371 times.
✗ Branch 53 → 77 not taken.
✓ Branch 54 → 55 taken 371 times.
✗ Branch 54 → 77 not taken.
742 return node->setEvaluatedSymbolType(functionType, manIdx);
414 371 }
415
416 } // namespace spice::compiler
417