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/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 50646 std::any TypeChecker::visitParamLst(ParamLstNode *node) {
18 50646 NamedParamList namedParams;
19 50646 bool metOptional = false;
20
21
2/2
✓ Branch 58 → 4 taken 75544 times.
✓ Branch 58 → 59 taken 50646 times.
176836 for (DeclStmtNode *param : node->params) {
22 // Visit param
23
2/4
✓ Branch 6 → 7 taken 75544 times.
✗ Branch 6 → 66 not taken.
✓ Branch 7 → 8 taken 75544 times.
✗ Branch 7 → 64 not taken.
75544 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 75544 times.
✗ Branch 9 → 96 not taken.
✓ Branch 10 → 11 taken 3 times.
✓ Branch 10 → 17 taken 75541 times.
75544 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 7258 times.
✓ Branch 17 → 19 taken 68283 times.
75541 if (param->hasAssignment) {
33 7258 metOptional = true;
34
2/2
✓ Branch 19 → 20 taken 6 times.
✓ Branch 19 → 27 taken 68277 times.
68283 } 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 40046 times.
✓ Branch 27 → 31 taken 35489 times.
✓ Branch 28 → 29 taken 40046 times.
✗ Branch 28 → 96 not taken.
✓ Branch 29 → 30 taken 47 times.
✓ Branch 29 → 31 taken 39999 times.
✓ Branch 32 → 33 taken 47 times.
✓ Branch 32 → 45 taken 75488 times.
75535 if (typeCheckerMode == TC_MODE_POST && !paramType.isTriviallyCopyable(param)) {
42
2/4
✓ Branch 34 → 35 taken 47 times.
✗ Branch 34 → 85 not taken.
✓ Branch 35 → 36 taken 47 times.
✗ Branch 35 → 83 not taken.
94 const std::string message = "Parameter '" + param->varName + "' has the non-trivially copyable type '" +
43
2/4
✓ Branch 33 → 34 taken 47 times.
✗ Branch 33 → 89 not taken.
✓ Branch 36 → 37 taken 47 times.
✗ Branch 36 → 81 not taken.
141 paramType.getName() +
44 "' and is passed by value, which requires an implicit copy on every call. Consider "
45
1/2
✓ Branch 37 → 38 taken 47 times.
✗ Branch 37 → 79 not taken.
47 "passing it by reference instead.";
46
1/2
✓ Branch 42 → 43 taken 47 times.
✗ Branch 42 → 91 not taken.
47 warnings.emplace_back(param->codeLoc, NON_TRIVIAL_TYPE_PASSED_BY_VALUE, message);
47 47 }
48
49 // Add parameter to named param list
50
1/2
✓ Branch 46 → 47 taken 75535 times.
✗ Branch 46 → 95 not taken.
75535 namedParams.push_back({param->varName.c_str(), paramType, metOptional});
51 }
52
53
1/2
✓ Branch 59 → 60 taken 50646 times.
✗ Branch 59 → 98 not taken.
101292 return namedParams;
54 50646 }
55
56 5641 std::any TypeChecker::visitField(FieldNode *node) {
57
2/4
✓ Branch 2 → 3 taken 5641 times.
✗ Branch 2 → 37 not taken.
✓ Branch 3 → 4 taken 5641 times.
✗ Branch 3 → 35 not taken.
5641 auto fieldType = std::any_cast<QualType>(visit(node->dataType));
58
4/6
✓ Branch 5 → 6 taken 5641 times.
✗ Branch 5 → 50 not taken.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 9 taken 5640 times.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 50 not taken.
5641 HANDLE_UNRESOLVED_TYPE_QT(fieldType)
59
60
2/2
✓ Branch 9 → 10 taken 1769 times.
✓ Branch 9 → 31 taken 3871 times.
5640 if (ExprNode *defaultValueNode = node->defaultValue) {
61
2/4
✓ Branch 10 → 11 taken 1769 times.
✗ Branch 10 → 40 not taken.
✓ Branch 11 → 12 taken 1769 times.
✗ Branch 11 → 38 not taken.
1769 const QualType defaultValueType = std::any_cast<ExprResult>(visit(defaultValueNode)).type;
62
2/6
✓ Branch 13 → 14 taken 1769 times.
✗ Branch 13 → 49 not taken.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 1769 times.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 49 not taken.
1770 HANDLE_UNRESOLVED_TYPE_QT(defaultValueType)
63
3/4
✓ Branch 17 → 18 taken 1769 times.
✗ Branch 17 → 49 not taken.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 29 taken 1768 times.
1769 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 5639 times.
✗ Branch 31 → 50 not taken.
5639 return fieldType;
68 }
69
70 2364 std::any TypeChecker::visitSignature(SignatureNode *node) {
71 2364 const bool isFunction = node->signatureType == SignatureNode::SignatureType::TYPE_FUNCTION;
72
73 // Retrieve function template types
74 2364 std::vector<GenericType> usedGenericTypes;
75
2/2
✓ Branch 2 → 3 taken 246 times.
✓ Branch 2 → 43 taken 2118 times.
2364 if (node->hasTemplateTypes) {
76
2/2
✓ Branch 41 → 5 taken 246 times.
✓ Branch 41 → 42 taken 245 times.
737 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
77 // Visit template type
78
2/4
✓ Branch 7 → 8 taken 246 times.
✗ Branch 7 → 129 not taken.
✓ Branch 8 → 9 taken 246 times.
✗ Branch 8 → 127 not taken.
246 auto templateType = std::any_cast<QualType>(visit(dataType));
79
2/4
✓ Branch 10 → 11 taken 246 times.
✗ Branch 10 → 138 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 15 taken 246 times.
246 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 246 times.
✗ Branch 15 → 138 not taken.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 26 taken 245 times.
246 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 245 times.
✗ Branch 26 → 138 not taken.
✓ Branch 27 → 28 taken 245 times.
✗ Branch 27 → 138 not taken.
245 const GenericType *genericType = rootScope->lookupGenericTypeStrict(templateType.getSubType());
88
1/2
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 245 times.
245 assert(genericType != nullptr);
89
1/2
✓ Branch 30 → 31 taken 245 times.
✗ Branch 30 → 138 not taken.
245 usedGenericTypes.push_back(*genericType);
90 }
91 }
92
93 // Visit return type
94
1/2
✓ Branch 43 → 44 taken 2363 times.
✗ Branch 43 → 182 not taken.
2363 QualType returnType(TY_DYN);
95
2/2
✓ Branch 44 → 45 taken 2234 times.
✓ Branch 44 → 62 taken 129 times.
2363 if (isFunction) {
96
2/4
✓ Branch 45 → 46 taken 2234 times.
✗ Branch 45 → 142 not taken.
✓ Branch 46 → 47 taken 2234 times.
✗ Branch 46 → 140 not taken.
2234 returnType = std::any_cast<QualType>(visit(node->returnType));
97
2/4
✓ Branch 48 → 49 taken 2234 times.
✗ Branch 48 → 182 not taken.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 53 taken 2234 times.
2234 if (returnType.is(TY_UNRESOLVED))
98 return static_cast<std::vector<Function *> *>(nullptr);
99
100
3/4
✓ Branch 53 → 54 taken 2234 times.
✗ Branch 53 → 182 not taken.
✓ Branch 54 → 55 taken 1 time.
✓ Branch 54 → 62 taken 2233 times.
2234 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 2363 QualTypeList paramTypes;
107 2363 ParamList paramList;
108
2/2
✓ Branch 62 → 63 taken 1442 times.
✓ Branch 62 → 101 taken 921 times.
2363 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 2363 times.
✗ Branch 101 → 173 not taken.
✓ Branch 102 → 103 taken 2363 times.
✗ Branch 102 → 170 not taken.
✓ Branch 103 → 104 taken 2363 times.
✗ Branch 103 → 167 not taken.
✓ Branch 104 → 105 taken 2363 times.
✗ Branch 104 → 166 not taken.
✓ Branch 105 → 106 taken 2363 times.
✗ Branch 105 → 164 not taken.
2363 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 2363 times.
✗ Branch 109 → 176 not taken.
2363 Function *manifestation = FunctionManager::insert(currentScope, signature, &node->signatureManifestations);
132 2363 manifestation->entry = node->entry;
133 2363 manifestation->used = true;
134
135 // Prepare signature type
136
2/2
✓ Branch 110 → 111 taken 2234 times.
✓ Branch 110 → 112 taken 129 times.
2363 const SuperType superType = isFunction ? TY_FUNCTION : TY_PROCEDURE;
137
2/4
✓ Branch 113 → 114 taken 2363 times.
✗ Branch 113 → 174 not taken.
✓ Branch 114 → 115 taken 2363 times.
✗ Branch 114 → 174 not taken.
2363 QualType signatureType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
138 2363 signatureType.setQualifiers(node->signatureQualifiers);
139
140 // Set entry to signature type
141
1/2
✗ Branch 116 → 117 not taken.
✓ Branch 116 → 118 taken 2363 times.
2363 assert(node->entry != nullptr);
142
1/2
✓ Branch 118 → 119 taken 2363 times.
✗ Branch 118 → 176 not taken.
2363 node->entry->updateType(signatureType, false);
143 2363 node->entry->used = true;
144
145
1/2
✓ Branch 119 → 120 taken 2363 times.
✗ Branch 119 → 175 not taken.
2363 return &node->signatureManifestations;
146 2364 }
147
148 192836 std::any TypeChecker::visitDataType(DataTypeNode *node) {
149 // Visit base data type
150
2/4
✓ Branch 2 → 3 taken 192836 times.
✗ Branch 2 → 227 not taken.
✓ Branch 3 → 4 taken 192836 times.
✗ Branch 3 → 225 not taken.
192836 auto type = std::any_cast<QualType>(visit(node->baseDataType));
151
4/6
✓ Branch 5 → 6 taken 192836 times.
✗ Branch 5 → 328 not taken.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 9 taken 192833 times.
✓ Branch 7 → 8 taken 3 times.
✗ Branch 7 → 328 not taken.
192836 HANDLE_UNRESOLVED_TYPE_QT(type)
152
153
1/2
✓ Branch 9 → 10 taken 192833 times.
✗ Branch 9 → 328 not taken.
192833 std::queue<DataTypeNode::TypeModifier> tmQueue = node->tmQueue;
154
2/2
✓ Branch 108 → 11 taken 58548 times.
✓ Branch 108 → 109 taken 192826 times.
251374 while (!tmQueue.empty()) {
155
1/2
✓ Branch 12 → 13 taken 58548 times.
✗ Branch 12 → 277 not taken.
58548 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 58548 times.
✗ Branch 13 → 275 not taken.
✓ Branch 14 → 15 taken 50 times.
✓ Branch 14 → 18 taken 58498 times.
✓ Branch 15 → 16 taken 50 times.
✗ Branch 15 → 275 not taken.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 18 taken 49 times.
✓ Branch 19 → 20 taken 1 time.
✓ Branch 19 → 30 taken 58547 times.
58548 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 33137 times.
✓ Branch 30 → 33 taken 25127 times.
✓ Branch 30 → 35 taken 283 times.
✗ Branch 30 → 92 not taken.
58547 switch (modifierType) {
163 33137 case DataTypeNode::TypeModifierType::TYPE_PTR: {
164
2/2
✓ Branch 31 → 32 taken 33135 times.
✓ Branch 31 → 235 taken 2 times.
33137 type = type.toPtr(node);
165 33135 break;
166 }
167 25127 case DataTypeNode::TypeModifierType::TYPE_REF: {
168
1/2
✓ Branch 33 → 34 taken 25127 times.
✗ Branch 33 → 236 not taken.
25127 type = type.toRef(node);
169 25127 break;
170 }
171 283 case DataTypeNode::TypeModifierType::TYPE_ARRAY: {
172 283 const std::string &varName = sizeVarName;
173
2/2
✓ Branch 36 → 37 taken 52 times.
✓ Branch 36 → 78 taken 231 times.
283 if (!varName.empty()) {
174
1/2
✓ Branch 37 → 38 taken 52 times.
✗ Branch 37 → 275 not taken.
52 const SymbolTableEntry *globalVar = rootScope->lookupStrict(varName);
175
2/2
✓ Branch 40 → 41 taken 1 time.
✓ Branch 40 → 50 taken 51 times.
52 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 51 times.
✗ Branch 50 → 275 not taken.
✓ Branch 51 → 52 taken 51 times.
✗ Branch 51 → 275 not taken.
✓ Branch 52 → 53 taken 1 time.
✓ Branch 52 → 63 taken 50 times.
51 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 50 times.
✗ Branch 63 → 275 not taken.
✓ Branch 64 → 65 taken 50 times.
✗ Branch 64 → 275 not taken.
✓ Branch 65 → 66 taken 1 time.
✓ Branch 65 → 76 taken 49 times.
50 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 49 times.
✗ Branch 76 → 275 not taken.
49 hardcodedSize = globalVar->declNode->getCompileTimeValue(manIdx).intValue;
182 }
183
184
3/4
✓ Branch 78 → 79 taken 152 times.
✓ Branch 78 → 90 taken 128 times.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 90 taken 152 times.
280 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 279 times.
✓ Branch 90 → 265 taken 1 time.
280 type = type.toArr(node, hardcodedSize);
187 279 break;
188 }
189 default: // GCOV_EXCL_LINE
190 throw CompilerError(UNHANDLED_BRANCH, "Modifier type fall-through"); // GCOV_EXCL_LINE
191 }
192 58541 tmQueue.pop();
193
2/2
✓ Branch 103 → 104 taken 58541 times.
✓ Branch 103 → 106 taken 4 times.
58548 }
194
195 // Attach the qualifiers to the type
196
2/2
✓ Branch 109 → 110 taken 73506 times.
✓ Branch 109 → 218 taken 119320 times.
192826 if (node->qualifierLst) {
197
1/2
✓ Branch 110 → 111 taken 73506 times.
✗ Branch 110 → 324 not taken.
73506 const QualType baseType = type.getBase();
198
2/2
✓ Branch 215 → 113 taken 83769 times.
✓ Branch 215 → 216 taken 73504 times.
230779 for (const QualifierNode *qualifier : node->qualifierLst->qualifiers) {
199
2/2
✓ Branch 115 → 116 taken 35108 times.
✓ Branch 115 → 118 taken 48661 times.
83769 if (qualifier->type == QualifierNode::QualifierType::TY_CONST) {
200 35108 type.getQualifiers().isConst = true;
201
2/2
✓ Branch 118 → 119 taken 6 times.
✓ Branch 118 → 133 taken 48655 times.
48661 } 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 27807 times.
✓ Branch 133 → 148 taken 20848 times.
48655 } else if (qualifier->type == QualifierNode::QualifierType::TY_UNSIGNED) {
207
2/4
✓ Branch 134 → 135 taken 27807 times.
✗ Branch 134 → 286 not taken.
✗ Branch 135 → 136 not taken.
✓ Branch 135 → 145 taken 27807 times.
27807 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 27807 type.getQualifiers().isSigned = false;
210 27807 type.getQualifiers().isUnsigned = true;
211
2/2
✓ Branch 148 → 149 taken 16136 times.
✓ Branch 148 → 163 taken 4712 times.
20848 } else if (qualifier->type == QualifierNode::QualifierType::TY_HEAP) {
212 // Heap variables can only be pointers
213
4/6
✓ Branch 149 → 150 taken 16136 times.
✗ Branch 149 → 295 not taken.
✓ Branch 150 → 151 taken 16136 times.
✗ Branch 150 → 294 not taken.
✓ Branch 151 → 152 taken 1 time.
✓ Branch 151 → 161 taken 16135 times.
16136 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 16135 type.getQualifiers().isHeap = true;
219
3/4
✓ Branch 163 → 164 taken 1258 times.
✓ Branch 163 → 179 taken 3454 times.
✓ Branch 164 → 165 taken 1258 times.
✗ Branch 164 → 179 not taken.
4712 } 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 3454 times.
✗ Branch 179 → 184 not taken.
✓ Branch 180 → 181 taken 1258 times.
✓ Branch 180 → 182 taken 2196 times.
✓ Branch 181 → 182 taken 1258 times.
✗ Branch 181 → 184 not taken.
3454 } else if (qualifier->type == QualifierNode::QualifierType::TY_PUBLIC && (node->isFieldType || node->isGlobalType)) {
224 3454 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 192824 times.
✗ Branch 218 → 325 not taken.
✓ Branch 219 → 220 taken 192824 times.
✗ Branch 219 → 325 not taken.
385648 return node->setEvaluatedSymbolType(type, manIdx);
242 192833 }
243
244 192836 std::any TypeChecker::visitBaseDataType(BaseDataTypeNode *node) {
245
11/11
✓ Branch 2 → 3 taken 2497 times.
✓ Branch 2 → 8 taken 9681 times.
✓ Branch 2 → 13 taken 2538 times.
✓ Branch 2 → 18 taken 27360 times.
✓ Branch 2 → 23 taken 9971 times.
✓ Branch 2 → 28 taken 18221 times.
✓ Branch 2 → 33 taken 16154 times.
✓ Branch 2 → 38 taken 12207 times.
✓ Branch 2 → 43 taken 92367 times.
✓ Branch 2 → 55 taken 289 times.
✓ Branch 2 → 67 taken 1551 times.
192836 switch (node->type) {
246 2497 case BaseDataTypeNode::Type::TYPE_DOUBLE:
247
3/6
✓ Branch 3 → 4 taken 2497 times.
✗ Branch 3 → 73 not taken.
✓ Branch 4 → 5 taken 2497 times.
✗ Branch 4 → 73 not taken.
✓ Branch 5 → 6 taken 2497 times.
✗ Branch 5 → 73 not taken.
4994 return node->setEvaluatedSymbolType(QualType(TY_DOUBLE), manIdx);
248 9681 case BaseDataTypeNode::Type::TYPE_INT:
249
3/6
✓ Branch 8 → 9 taken 9681 times.
✗ Branch 8 → 75 not taken.
✓ Branch 9 → 10 taken 9681 times.
✗ Branch 9 → 75 not taken.
✓ Branch 10 → 11 taken 9681 times.
✗ Branch 10 → 75 not taken.
19362 return node->setEvaluatedSymbolType(QualType(TY_INT), manIdx);
250 2538 case BaseDataTypeNode::Type::TYPE_SHORT:
251
3/6
✓ Branch 13 → 14 taken 2538 times.
✗ Branch 13 → 77 not taken.
✓ Branch 14 → 15 taken 2538 times.
✗ Branch 14 → 77 not taken.
✓ Branch 15 → 16 taken 2538 times.
✗ Branch 15 → 77 not taken.
5076 return node->setEvaluatedSymbolType(QualType(TY_SHORT), manIdx);
252 27360 case BaseDataTypeNode::Type::TYPE_LONG:
253
3/6
✓ Branch 18 → 19 taken 27360 times.
✗ Branch 18 → 79 not taken.
✓ Branch 19 → 20 taken 27360 times.
✗ Branch 19 → 79 not taken.
✓ Branch 20 → 21 taken 27360 times.
✗ Branch 20 → 79 not taken.
54720 return node->setEvaluatedSymbolType(QualType(TY_LONG), manIdx);
254 9971 case BaseDataTypeNode::Type::TYPE_BYTE:
255
3/6
✓ Branch 23 → 24 taken 9971 times.
✗ Branch 23 → 81 not taken.
✓ Branch 24 → 25 taken 9971 times.
✗ Branch 24 → 81 not taken.
✓ Branch 25 → 26 taken 9971 times.
✗ Branch 25 → 81 not taken.
19942 return node->setEvaluatedSymbolType(QualType(TY_BYTE), manIdx);
256 18221 case BaseDataTypeNode::Type::TYPE_CHAR:
257
3/6
✓ Branch 28 → 29 taken 18221 times.
✗ Branch 28 → 83 not taken.
✓ Branch 29 → 30 taken 18221 times.
✗ Branch 29 → 83 not taken.
✓ Branch 30 → 31 taken 18221 times.
✗ Branch 30 → 83 not taken.
36442 return node->setEvaluatedSymbolType(QualType(TY_CHAR), manIdx);
258 16154 case BaseDataTypeNode::Type::TYPE_STRING:
259
3/6
✓ Branch 33 → 34 taken 16154 times.
✗ Branch 33 → 85 not taken.
✓ Branch 34 → 35 taken 16154 times.
✗ Branch 34 → 85 not taken.
✓ Branch 35 → 36 taken 16154 times.
✗ Branch 35 → 85 not taken.
32308 return node->setEvaluatedSymbolType(QualType(TY_STRING), manIdx);
260 12207 case BaseDataTypeNode::Type::TYPE_BOOL:
261
3/6
✓ Branch 38 → 39 taken 12207 times.
✗ Branch 38 → 87 not taken.
✓ Branch 39 → 40 taken 12207 times.
✗ Branch 39 → 87 not taken.
✓ Branch 40 → 41 taken 12207 times.
✗ Branch 40 → 87 not taken.
24414 return node->setEvaluatedSymbolType(QualType(TY_BOOL), manIdx);
262 92367 case BaseDataTypeNode::Type::TYPE_CUSTOM: {
263
2/4
✓ Branch 43 → 44 taken 92367 times.
✗ Branch 43 → 91 not taken.
✓ Branch 44 → 45 taken 92367 times.
✗ Branch 44 → 89 not taken.
92367 const auto customType = std::any_cast<QualType>(visit(node->customDataType));
264
4/6
✓ Branch 46 → 47 taken 92367 times.
✗ Branch 46 → 93 not taken.
✓ Branch 47 → 48 taken 3 times.
✓ Branch 47 → 50 taken 92364 times.
✓ Branch 48 → 49 taken 3 times.
✗ Branch 48 → 93 not taken.
92367 HANDLE_UNRESOLVED_TYPE_QT(customType)
265
2/4
✓ Branch 50 → 51 taken 92364 times.
✗ Branch 50 → 92 not taken.
✓ Branch 51 → 52 taken 92364 times.
✗ Branch 51 → 92 not taken.
184728 return node->setEvaluatedSymbolType(customType, manIdx);
266 }
267 289 case BaseDataTypeNode::Type::TYPE_FUNCTION: {
268
2/4
✓ Branch 55 → 56 taken 289 times.
✗ Branch 55 → 96 not taken.
✓ Branch 56 → 57 taken 289 times.
✗ Branch 56 → 94 not taken.
289 const auto functionType = std::any_cast<QualType>(visit(node->functionDataType));
269
2/6
✓ Branch 58 → 59 taken 289 times.
✗ Branch 58 → 98 not taken.
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 62 taken 289 times.
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 98 not taken.
289 HANDLE_UNRESOLVED_TYPE_QT(functionType)
270
2/4
✓ Branch 62 → 63 taken 289 times.
✗ Branch 62 → 97 not taken.
✓ Branch 63 → 64 taken 289 times.
✗ Branch 63 → 97 not taken.
578 return node->setEvaluatedSymbolType(functionType, manIdx);
271 }
272 1551 default:
273
3/6
✓ Branch 67 → 68 taken 1551 times.
✗ Branch 67 → 99 not taken.
✓ Branch 68 → 69 taken 1551 times.
✗ Branch 68 → 99 not taken.
✓ Branch 69 → 70 taken 1551 times.
✗ Branch 69 → 99 not taken.
3102 return node->setEvaluatedSymbolType(QualType(TY_DYN), manIdx);
274 }
275 }
276
277 92367 std::any TypeChecker::visitCustomDataType(CustomDataTypeNode *node) {
278 // It is a struct type -> get the access scope
279
1/2
✓ Branch 3 → 4 taken 92367 times.
✗ Branch 3 → 257 not taken.
92367 const std::string firstFragment = node->typeNameFragments.front();
280
281 // Check this type requires a runtime module
282
2/2
✓ Branch 5 → 6 taken 92224 times.
✓ Branch 5 → 7 taken 143 times.
92367 if (node->typeNameFragments.size() == 1)
283
1/2
✓ Branch 6 → 7 taken 92224 times.
✗ Branch 6 → 255 not taken.
92224 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 92367 bool isImported = node->typeNameFragments.size() > 1;
287
3/4
✓ Branch 8 → 9 taken 92367 times.
✗ Branch 8 → 255 not taken.
✓ Branch 9 → 10 taken 38113 times.
✓ Branch 9 → 27 taken 54254 times.
92367 if (const QualType *genericType = rootScope->lookupGenericTypeStrict(firstFragment)) {
288
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 38113 times.
38113 assert(!isImported);
289 // Take the concrete replacement type for the name of this generic type if available
290
1/2
✓ Branch 12 → 13 taken 38113 times.
✗ Branch 12 → 197 not taken.
38113 const auto it = typeMapping.find(firstFragment);
291
2/2
✓ Branch 15 → 16 taken 19194 times.
✓ Branch 15 → 17 taken 18919 times.
38113 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 38113 times.
✗ Branch 19 → 197 not taken.
✓ Branch 20 → 21 taken 8417 times.
✓ Branch 20 → 23 taken 29696 times.
38113 if (symbolType.is(TY_STRUCT))
295
2/4
✓ Branch 21 → 22 taken 8417 times.
✗ Branch 21 → 197 not taken.
✓ Branch 22 → 23 taken 8417 times.
✗ Branch 22 → 197 not taken.
8417 ensureLoadedRuntimeForTypeName(symbolType.getSubType());
296
297
2/4
✓ Branch 23 → 24 taken 38113 times.
✗ Branch 23 → 196 not taken.
✓ Branch 24 → 25 taken 38113 times.
✗ Branch 24 → 196 not taken.
76226 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 54254 times.
✗ Branch 27 → 255 not taken.
54254 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqTypeName);
302
2/2
✓ Branch 28 → 29 taken 2 times.
✓ Branch 28 → 38 taken 54252 times.
54254 if (!registryEntry)
303
5/10
✓ Branch 29 → 30 taken 2 times.
✗ Branch 29 → 202 not taken.
✓ Branch 30 → 31 taken 2 times.
✗ Branch 30 → 200 not taken.
✓ Branch 31 → 32 taken 2 times.
✗ Branch 31 → 198 not taken.
✓ Branch 34 → 35 taken 2 times.
✗ Branch 34 → 204 not taken.
✓ Branch 35 → 36 taken 2 times.
✗ Branch 35 → 204 not taken.
4 SOFT_ERROR_QT(node, UNKNOWN_DATATYPE, "Unknown datatype '" + node->fqTypeName + "'")
304
2/4
✓ Branch 38 → 39 taken 54252 times.
✗ Branch 38 → 41 not taken.
✓ Branch 39 → 40 taken 54252 times.
✗ Branch 39 → 41 not taken.
54252 assert(registryEntry->targetEntry != nullptr && registryEntry->targetScope != nullptr);
305 54252 SymbolTableEntry *entry = registryEntry->targetEntry;
306
1/2
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 44 taken 54252 times.
54252 assert(entry != nullptr);
307 54252 entry->used = true;
308 54252 Scope *defScope = registryEntry->targetScope->parent;
309
1/2
✓ Branch 44 → 45 taken 54252 times.
✗ Branch 44 → 255 not taken.
54252 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 54252 times.
✗ Branch 45 → 255 not taken.
✓ Branch 46 → 47 taken 1023 times.
✓ Branch 46 → 50 taken 53229 times.
54252 if (entryType.is(TY_INVALID)) {
316
1/2
✓ Branch 47 → 48 taken 1023 times.
✗ Branch 47 → 255 not taken.
1023 assignDeferredOpaqueType(entry);
317
1/2
✓ Branch 48 → 49 taken 1023 times.
✗ Branch 48 → 255 not taken.
1023 entryType = entry->getQualType();
318 }
319
320 // Enums can early-return
321
3/4
✓ Branch 50 → 51 taken 54252 times.
✗ Branch 50 → 255 not taken.
✓ Branch 51 → 52 taken 1301 times.
✓ Branch 51 → 56 taken 52951 times.
54252 if (entryType.is(TY_ENUM))
322
2/4
✓ Branch 52 → 53 taken 1301 times.
✗ Branch 52 → 205 not taken.
✓ Branch 53 → 54 taken 1301 times.
✗ Branch 53 → 205 not taken.
2602 return QualType(TY_INT);
323
324
3/4
✓ Branch 56 → 57 taken 52951 times.
✗ Branch 56 → 206 not taken.
✓ Branch 57 → 58 taken 46995 times.
✓ Branch 57 → 168 taken 5956 times.
52951 if (entryType.isOneOf({TY_STRUCT, TY_INTERFACE})) {
325
2/4
✓ Branch 58 → 59 taken 46995 times.
✗ Branch 58 → 60 not taken.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 63 taken 46995 times.
46995 assert(dynamic_cast<DataTypeNode *>(node->parent->parent) != nullptr);
326
327 // Collect the concrete template types
328 46995 bool allTemplateTypesConcrete = true;
329 46995 QualTypeList templateTypes;
330
2/2
✓ Branch 63 → 64 taken 11166 times.
✓ Branch 63 → 104 taken 35829 times.
46995 if (node->templateTypeLst) {
331
1/2
✗ Branch 64 → 65 not taken.
✓ Branch 64 → 66 taken 11166 times.
11166 assert(defScope != nullptr);
332
1/2
✓ Branch 66 → 67 taken 11166 times.
✗ Branch 66 → 237 not taken.
11166 isImported = defScope->isImportedBy(rootScope);
333
334
1/2
✓ Branch 68 → 69 taken 11166 times.
✗ Branch 68 → 237 not taken.
11166 templateTypes.reserve(node->templateTypeLst->dataTypes.size());
335
2/2
✓ Branch 101 → 71 taken 14081 times.
✓ Branch 101 → 102 taken 11166 times.
36413 for (DataTypeNode *dataType : node->templateTypeLst->dataTypes) {
336
2/4
✓ Branch 73 → 74 taken 14081 times.
✗ Branch 73 → 209 not taken.
✓ Branch 74 → 75 taken 14081 times.
✗ Branch 74 → 207 not taken.
14081 auto templateType = std::any_cast<QualType>(visit(dataType));
337
2/6
✓ Branch 76 → 77 taken 14081 times.
✗ Branch 76 → 211 not taken.
✗ Branch 77 → 78 not taken.
✓ Branch 77 → 80 taken 14081 times.
✗ Branch 78 → 79 not taken.
✗ Branch 78 → 211 not taken.
14081 HANDLE_UNRESOLVED_TYPE_QT(templateType)
338
2/4
✓ Branch 80 → 81 taken 14081 times.
✗ Branch 80 → 211 not taken.
✗ Branch 81 → 82 not taken.
✓ Branch 81 → 83 taken 14081 times.
14081 if (entryType.is(TY_GENERIC)) {
339 allTemplateTypesConcrete = false;
340
2/2
✓ Branch 83 → 84 taken 4877 times.
✓ Branch 83 → 90 taken 9204 times.
14081 } else if (isImported) {
341 // Introduce the local type to the imported source file
342
1/2
✓ Branch 84 → 85 taken 4877 times.
✗ Branch 84 → 210 not taken.
4877 [[maybe_unused]] QualType importedType = mapLocalTypeToImportedScopeType(defScope, templateType);
343
3/6
✓ Branch 85 → 86 taken 4877 times.
✗ Branch 85 → 210 not taken.
✓ Branch 86 → 87 taken 4877 times.
✗ Branch 86 → 210 not taken.
✗ Branch 87 → 88 not taken.
✓ Branch 87 → 89 taken 4877 times.
4877 assert(importedType.is(templateType.getSuperType()));
344 }
345
1/2
✓ Branch 90 → 91 taken 14081 times.
✗ Branch 90 → 211 not taken.
14081 templateTypes.push_back(templateType);
346 }
347
1/2
✓ Branch 102 → 103 taken 11166 times.
✗ Branch 102 → 213 not taken.
11166 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 46995 const CodeLoc &declCodeLoc = entry->declNode->codeLoc;
353 46995 const CodeLoc &codeLoc = node->codeLoc;
354
6/6
✓ Branch 105 → 106 taken 24475 times.
✓ Branch 105 → 113 taken 22520 times.
✓ Branch 111 → 112 taken 1 time.
✓ Branch 111 → 113 taken 24474 times.
✓ Branch 114 → 115 taken 1 time.
✓ Branch 114 → 140 taken 46994 times.
71470 if (declCodeLoc.sourceFile->filePath == codeLoc.sourceFile->filePath && declCodeLoc > codeLoc) {
355
2/4
✓ Branch 115 → 116 taken 1 time.
✗ Branch 115 → 237 not taken.
✓ Branch 116 → 117 taken 1 time.
✗ Branch 116 → 127 not taken.
1 if (entryType.is(TY_STRUCT)) {
356
4/8
✓ Branch 119 → 120 taken 1 time.
✗ Branch 119 → 216 not taken.
✓ Branch 120 → 121 taken 1 time.
✗ Branch 120 → 214 not taken.
✓ Branch 123 → 124 taken 1 time.
✗ Branch 123 → 220 not taken.
✓ Branch 124 → 125 taken 1 time.
✗ Branch 124 → 220 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 140 → 141 taken 46994 times.
✗ Branch 140 → 162 not taken.
46994 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 141 → 142 taken 46994 times.
✗ Branch 141 → 237 not taken.
✓ Branch 142 → 143 taken 42213 times.
✓ Branch 142 → 151 taken 4781 times.
46994 if (entryType.is(TY_STRUCT)) {
367
1/2
✓ Branch 144 → 145 taken 42213 times.
✗ Branch 144 → 231 not taken.
42213 const std::string structName = node->typeNameFragments.back();
368
3/4
✓ Branch 145 → 146 taken 42213 times.
✗ Branch 145 → 229 not taken.
✓ Branch 146 → 147 taken 41009 times.
✓ Branch 146 → 149 taken 1204 times.
42213 if (const Struct *spiceStruct = StructManager::match(defScope, structName, templateTypes, node))
369
1/2
✓ Branch 147 → 148 taken 41009 times.
✗ Branch 147 → 228 not taken.
41009 entryType = entryType.getWithBodyScope(spiceStruct->scope);
370 42213 } else {
371
2/4
✓ Branch 151 → 152 taken 4781 times.
✗ Branch 151 → 235 not taken.
✗ Branch 152 → 153 not taken.
✓ Branch 152 → 154 taken 4781 times.
4781 assert(entryType.is(TY_INTERFACE));
372
1/2
✓ Branch 155 → 156 taken 4781 times.
✗ Branch 155 → 235 not taken.
4781 const std::string interfaceName = node->typeNameFragments.back();
373
3/4
✓ Branch 156 → 157 taken 4781 times.
✗ Branch 156 → 233 not taken.
✓ Branch 157 → 158 taken 4466 times.
✓ Branch 157 → 160 taken 315 times.
4781 if (const Interface *spiceInterface = InterfaceManager::match(defScope, interfaceName, templateTypes, node))
374
1/2
✓ Branch 158 → 159 taken 4466 times.
✗ Branch 158 → 232 not taken.
4466 entryType = entryType.getWithBodyScope(spiceInterface->scope);
375 4781 }
376 }
377
378
2/4
✓ Branch 162 → 163 taken 46994 times.
✗ Branch 162 → 236 not taken.
✓ Branch 163 → 164 taken 46994 times.
✗ Branch 163 → 236 not taken.
93988 return node->setEvaluatedSymbolType(entryType, manIdx);
379 46995 }
380
381
2/4
✓ Branch 168 → 169 taken 5956 times.
✗ Branch 168 → 255 not taken.
✓ Branch 169 → 170 taken 5956 times.
✗ Branch 169 → 175 not taken.
5956 if (entryType.is(TY_ALIAS))
382
3/6
✓ Branch 170 → 171 taken 5956 times.
✗ Branch 170 → 240 not taken.
✓ Branch 171 → 172 taken 5956 times.
✗ Branch 171 → 240 not taken.
✓ Branch 172 → 173 taken 5956 times.
✗ Branch 172 → 240 not taken.
11912 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 92367 }
388
389 289 std::any TypeChecker::visitFunctionDataType(FunctionDataTypeNode *node) {
390 // Visit return type
391
1/2
✓ Branch 2 → 3 taken 289 times.
✗ Branch 2 → 80 not taken.
289 QualType returnType(TY_DYN);
392
2/2
✓ Branch 3 → 4 taken 56 times.
✓ Branch 3 → 23 taken 233 times.
289 if (node->isFunction) {
393
2/4
✓ Branch 4 → 5 taken 56 times.
✗ Branch 4 → 62 not taken.
✓ Branch 5 → 6 taken 56 times.
✗ Branch 5 → 60 not taken.
56 returnType = std::any_cast<QualType>(visit(node->returnType));
394
2/6
✓ Branch 7 → 8 taken 56 times.
✗ Branch 7 → 80 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 11 taken 56 times.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 80 not taken.
56 HANDLE_UNRESOLVED_TYPE_QT(returnType)
395
2/4
✓ Branch 11 → 12 taken 56 times.
✗ Branch 11 → 80 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 23 taken 56 times.
56 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 289 QualTypeList paramTypes;
401
2/2
✓ Branch 23 → 24 taken 210 times.
✓ Branch 23 → 48 taken 79 times.
289 if (const TypeLstNode *paramTypeListNode = node->paramTypeLst; paramTypeListNode != nullptr) {
402
2/2
✓ Branch 46 → 26 taken 266 times.
✓ Branch 46 → 47 taken 210 times.
686 for (DataTypeNode *paramTypeNode : paramTypeListNode->dataTypes) {
403
2/4
✓ Branch 28 → 29 taken 266 times.
✗ Branch 28 → 73 not taken.
✓ Branch 29 → 30 taken 266 times.
✗ Branch 29 → 71 not taken.
266 auto paramType = std::any_cast<QualType>(visit(paramTypeNode));
404
2/6
✓ Branch 31 → 32 taken 266 times.
✗ Branch 31 → 74 not taken.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 35 taken 266 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 74 not taken.
266 HANDLE_UNRESOLVED_TYPE_QT(returnType)
405
1/2
✓ Branch 35 → 36 taken 266 times.
✗ Branch 35 → 74 not taken.
266 paramTypes.push_back(paramType);
406 }
407 }
408
409 // Build function type
410
2/2
✓ Branch 48 → 49 taken 56 times.
✓ Branch 48 → 50 taken 233 times.
289 const SuperType superType = node->isFunction ? TY_FUNCTION : TY_PROCEDURE;
411
2/4
✓ Branch 51 → 52 taken 289 times.
✗ Branch 51 → 76 not taken.
✓ Branch 52 → 53 taken 289 times.
✗ Branch 52 → 76 not taken.
289 const QualType functionType = QualType(superType).getWithFunctionParamAndReturnTypes(returnType, paramTypes);
412
413
2/4
✓ Branch 53 → 54 taken 289 times.
✗ Branch 53 → 77 not taken.
✓ Branch 54 → 55 taken 289 times.
✗ Branch 54 → 77 not taken.
578 return node->setEvaluatedSymbolType(functionType, manIdx);
414 289 }
415
416 } // namespace spice::compiler
417