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 <symboltablebuilder/SymbolTableBuilder.h> | ||
9 | #include <typechecker/MacroDefs.h> | ||
10 | |||
11 | namespace spice::compiler { | ||
12 | |||
13 | 17255 | std::any TypeChecker::visitStmtLst(StmtLstNode *node) { | |
14 | // Visit nodes in this scope | ||
15 |
2/2✓ Branch 0 (15→4) taken 33207 times.
✓ Branch 1 (15→16) taken 17224 times.
|
50431 | for (StmtNode *stmt : node->statements) { |
16 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 33207 times.
|
33207 | if (!stmt) |
17 | ✗ | continue; | |
18 | // Print warning if statement is unreachable | ||
19 |
2/2✓ Branch 0 (7→8) taken 7 times.
✓ Branch 1 (7→10) taken 33200 times.
|
33207 | if (stmt->unreachable) { |
20 |
1/2✓ Branch 0 (8→9) taken 7 times.
✗ Branch 1 (8→20) not taken.
|
7 | warnings.emplace_back(stmt->codeLoc, UNREACHABLE_CODE, "This statement is unreachable"); |
21 | 7 | continue; | |
22 | } | ||
23 | // Visit the statement | ||
24 |
2/2✓ Branch 0 (10→11) taken 33169 times.
✓ Branch 1 (10→21) taken 31 times.
|
33200 | visit(stmt); |
25 | } | ||
26 | |||
27 | // Do cleanup of this scope, e.g. dtor calls for struct instances | ||
28 | 17224 | doScopeCleanup(node); | |
29 | |||
30 |
1/2✓ Branch 0 (17→18) taken 17224 times.
✗ Branch 1 (17→23) not taken.
|
17224 | return nullptr; |
31 | } | ||
32 | |||
33 | 28215 | std::any TypeChecker::visitDeclStmt(DeclStmtNode *node) { | |
34 | // Retrieve entry of the lhs variable | ||
35 |
1/2✓ Branch 0 (2→3) taken 28215 times.
✗ Branch 1 (2→179) not taken.
|
28215 | SymbolTableEntry *localVarEntry = currentScope->lookupStrict(node->varName); |
36 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 28215 times.
|
28215 | assert(localVarEntry != nullptr); |
37 | |||
38 | 28215 | QualType localVarType; | |
39 |
2/2✓ Branch 0 (7→8) taken 8690 times.
✓ Branch 1 (7→56) taken 19525 times.
|
28215 | if (node->hasAssignment) { |
40 | // Visit the right side | ||
41 |
3/4✓ Branch 0 (8→9) taken 8685 times.
✓ Branch 1 (8→129) taken 5 times.
✓ Branch 2 (9→10) taken 8685 times.
✗ Branch 3 (9→127) not taken.
|
8690 | auto rhs = std::any_cast<ExprResult>(visit(node->assignExpr)); |
42 | 8685 | auto [rhsTy, rhsEntry] = rhs; | |
43 | |||
44 | // Visit data type | ||
45 |
3/4✓ Branch 0 (11→12) taken 8682 times.
✓ Branch 1 (11→132) taken 3 times.
✓ Branch 2 (12→13) taken 8682 times.
✗ Branch 3 (12→130) not taken.
|
8685 | localVarType = std::any_cast<QualType>(visit(node->dataType)); |
46 | |||
47 | // Check if type has to be inferred or both types are fixed | ||
48 |
8/10✓ Branch 0 (14→15) taken 8682 times.
✗ Branch 1 (14→148) not taken.
✓ Branch 2 (15→16) taken 8678 times.
✓ Branch 3 (15→19) taken 4 times.
✓ Branch 4 (16→17) taken 8678 times.
✗ Branch 5 (16→148) not taken.
✓ Branch 6 (17→18) taken 8657 times.
✓ Branch 7 (17→19) taken 21 times.
✓ Branch 8 (20→21) taken 8657 times.
✓ Branch 9 (20→45) taken 25 times.
|
8682 | if (!localVarType.is(TY_UNRESOLVED) && !rhsTy.is(TY_UNRESOLVED)) { |
49 | 8657 | const ExprResult lhsResult = {localVarType, localVarEntry}; | |
50 |
2/2✓ Branch 0 (21→22) taken 8647 times.
✓ Branch 1 (21→146) taken 10 times.
|
8657 | const auto [type, copyCtor] = opRuleManager.getAssignResultType(node, lhsResult, rhs, true); |
51 | 8647 | localVarType = type; | |
52 | 8647 | node->calledCopyCtor = copyCtor; | |
53 | |||
54 | // If this is a struct type, check if the type is known. If not, error out | ||
55 |
8/14✓ Branch 0 (24→25) taken 8647 times.
✗ Branch 1 (24→134) not taken.
✓ Branch 2 (25→26) taken 1072 times.
✓ Branch 3 (25→31) taken 7575 times.
✓ Branch 4 (26→27) taken 1072 times.
✗ Branch 5 (26→134) not taken.
✓ Branch 6 (27→28) taken 1072 times.
✗ Branch 7 (27→134) not taken.
✓ Branch 8 (28→29) taken 1072 times.
✗ Branch 9 (28→134) not taken.
✗ Branch 10 (29→30) not taken.
✓ Branch 11 (29→31) taken 1072 times.
✗ Branch 12 (32→33) not taken.
✓ Branch 13 (32→44) taken 8647 times.
|
8647 | if (localVarType.isBase(TY_STRUCT) && !sourceFile->getNameRegistryEntry(localVarType.getBase().getSubType())) { |
56 | ✗ | const std::string structName = localVarType.getBase().getSubType(); | |
57 | ✗ | softError(node->dataType, UNKNOWN_DATATYPE, "Unknown struct type '" + structName + "'. Forgot to import?"); | |
58 | ✗ | localVarType = QualType(TY_UNRESOLVED); | |
59 | ✗ | } | |
60 | } else { | ||
61 |
1/2✓ Branch 0 (45→46) taken 25 times.
✗ Branch 1 (45→147) not taken.
|
25 | localVarType = QualType(TY_UNRESOLVED); |
62 | } | ||
63 | |||
64 | // If there is an anonymous entry attached (e.g. for struct instantiation) and we take over ownership, delete it | ||
65 |
9/10✓ Branch 0 (47→48) taken 8672 times.
✗ Branch 1 (47→148) not taken.
✓ Branch 2 (48→49) taken 8533 times.
✓ Branch 3 (48→52) taken 139 times.
✓ Branch 4 (49→50) taken 1634 times.
✓ Branch 5 (49→52) taken 6899 times.
✓ Branch 6 (50→51) taken 737 times.
✓ Branch 7 (50→52) taken 897 times.
✓ Branch 8 (53→54) taken 737 times.
✓ Branch 9 (53→55) taken 7935 times.
|
8672 | if (!localVarType.isRef() && rhsEntry != nullptr && rhsEntry->anonymous) |
66 |
1/2✓ Branch 0 (54→55) taken 737 times.
✗ Branch 1 (54→148) not taken.
|
737 | currentScope->symbolTable.deleteAnonymous(rhsEntry->name); |
67 | } else { | ||
68 | // Visit data type | ||
69 |
2/4✓ Branch 0 (56→57) taken 19525 times.
✗ Branch 1 (56→151) not taken.
✓ Branch 2 (57→58) taken 19525 times.
✗ Branch 3 (57→149) not taken.
|
19525 | localVarType = std::any_cast<QualType>(visit(node->dataType)); |
70 | |||
71 | // References with no initialization are illegal | ||
72 |
9/10✓ Branch 0 (59→60) taken 19525 times.
✗ Branch 1 (59→179) not taken.
✓ Branch 2 (60→61) taken 5757 times.
✓ Branch 3 (60→64) taken 13768 times.
✓ Branch 4 (61→62) taken 70 times.
✓ Branch 5 (61→64) taken 5687 times.
✓ Branch 6 (62→63) taken 1 times.
✓ Branch 7 (62→64) taken 69 times.
✓ Branch 8 (65→66) taken 1 times.
✓ Branch 9 (65→73) taken 19524 times.
|
19525 | if (localVarType.isRef() && !node->isFctParam && !node->isForEachItem) |
73 |
2/4✓ Branch 0 (68→69) taken 1 times.
✗ Branch 1 (68→155) not taken.
✓ Branch 2 (69→70) taken 1 times.
✗ Branch 3 (69→153) not taken.
|
2 | softError(node, REFERENCE_WITHOUT_INITIALIZER, "References must always be initialized directly"); |
74 | |||
75 | // If this is a struct, check for the default ctor | ||
76 |
9/10✓ Branch 0 (73→74) taken 19525 times.
✗ Branch 1 (73→179) not taken.
✓ Branch 2 (74→75) taken 657 times.
✓ Branch 3 (74→78) taken 18868 times.
✓ Branch 4 (75→76) taken 163 times.
✓ Branch 5 (75→78) taken 494 times.
✓ Branch 6 (76→77) taken 154 times.
✓ Branch 7 (76→78) taken 9 times.
✓ Branch 8 (79→80) taken 154 times.
✓ Branch 9 (79→120) taken 19371 times.
|
19525 | if (localVarType.is(TY_STRUCT) && !node->isFctParam && !node->isForEachItem) { |
77 |
1/2✓ Branch 0 (80→81) taken 154 times.
✗ Branch 1 (80→179) not taken.
|
154 | Scope *matchScope = localVarType.getBodyScope(); |
78 |
1/2✗ Branch 0 (81→82) not taken.
✓ Branch 1 (81→83) taken 154 times.
|
154 | assert(matchScope != nullptr); |
79 | // Check if we are required to call a ctor | ||
80 |
1/2✓ Branch 0 (83→84) taken 154 times.
✗ Branch 1 (83→179) not taken.
|
154 | const Struct *spiceStruct = localVarType.getStruct(node); |
81 |
1/2✗ Branch 0 (84→85) not taken.
✓ Branch 1 (84→86) taken 154 times.
|
154 | assert(spiceStruct != nullptr); |
82 |
1/2✓ Branch 0 (86→87) taken 154 times.
✗ Branch 1 (86→88) not taken.
|
154 | auto structDeclNode = spice_pointer_cast<StructDefNode *>(spiceStruct->declNode); |
83 |
5/6✓ Branch 0 (93→94) taken 154 times.
✗ Branch 1 (93→179) not taken.
✓ Branch 2 (94→95) taken 153 times.
✓ Branch 3 (94→96) taken 1 times.
✓ Branch 4 (95→96) taken 20 times.
✓ Branch 5 (95→97) taken 133 times.
|
154 | node->isCtorCallRequired = matchScope->hasRefFields() || structDeclNode->emitVTable; |
84 | // Check if we have a no-args ctor to call | ||
85 |
1/2✓ Branch 0 (98→99) taken 154 times.
✗ Branch 1 (98→179) not taken.
|
154 | const std::string &structName = localVarType.getSubType(); |
86 | 154 | const QualType &thisType = localVarType; | |
87 |
2/4✓ Branch 0 (103→104) taken 154 times.
✗ Branch 1 (103→161) not taken.
✓ Branch 2 (104→105) taken 154 times.
✗ Branch 3 (104→159) not taken.
|
462 | node->calledInitCtor = FunctionManager::match(this, matchScope, CTOR_FUNCTION_NAME, thisType, {}, {}, false, node); |
88 |
4/4✓ Branch 0 (109→110) taken 15 times.
✓ Branch 1 (109→120) taken 139 times.
✓ Branch 2 (110→111) taken 2 times.
✓ Branch 3 (110→120) taken 13 times.
|
154 | if (!node->calledInitCtor && node->isCtorCallRequired) |
89 |
5/10✓ Branch 0 (111→112) taken 2 times.
✗ Branch 1 (111→175) not taken.
✓ Branch 2 (112→113) taken 2 times.
✗ Branch 3 (112→173) not taken.
✓ Branch 4 (113→114) taken 2 times.
✗ Branch 5 (113→171) not taken.
✓ Branch 6 (116→117) taken 2 times.
✗ Branch 7 (116→177) not taken.
✓ Branch 8 (117→118) taken 2 times.
✗ Branch 9 (117→177) not taken.
|
2 | SOFT_ERROR_QT(node, MISSING_NO_ARGS_CTOR, "Struct '" + structName + "' misses a no-args constructor") |
90 | } | ||
91 | } | ||
92 | |||
93 | // Update the type of the variable | ||
94 |
1/2✓ Branch 0 (120→121) taken 28195 times.
✗ Branch 1 (120→179) not taken.
|
28195 | localVarEntry->updateType(localVarType, true); |
95 |
1/2✓ Branch 0 (121→122) taken 28195 times.
✗ Branch 1 (121→179) not taken.
|
28195 | node->entries.at(manIdx) = localVarEntry; |
96 | |||
97 | // Update the state of the variable | ||
98 |
1/2✓ Branch 0 (122→123) taken 28195 times.
✗ Branch 1 (122→178) not taken.
|
28195 | localVarEntry->updateState(INITIALIZED, node); |
99 | |||
100 |
1/2✓ Branch 0 (123→124) taken 28195 times.
✗ Branch 1 (123→179) not taken.
|
28195 | return localVarType; |
101 | } | ||
102 | |||
103 | 8103 | std::any TypeChecker::visitReturnStmt(ReturnStmtNode *node) { | |
104 | // Retrieve return variable entry | ||
105 |
1/2✓ Branch 0 (4→5) taken 8103 times.
✗ Branch 1 (4→68) not taken.
|
24309 | SymbolTableEntry *returnVar = currentScope->lookup(RETURN_VARIABLE_NAME); |
106 | 8103 | const bool isFunction = returnVar != nullptr; | |
107 |
4/6✓ Branch 0 (10→11) taken 8052 times.
✓ Branch 1 (10→13) taken 51 times.
✓ Branch 2 (11→12) taken 8052 times.
✗ Branch 3 (11→91) not taken.
✓ Branch 4 (13→14) taken 51 times.
✗ Branch 5 (13→91) not taken.
|
8103 | const QualType returnType = isFunction ? returnVar->getQualType() : QualType(TY_DYN); |
108 | |||
109 | // Check if procedure with return value | ||
110 |
2/2✓ Branch 0 (14→15) taken 51 times.
✓ Branch 1 (14→28) taken 8052 times.
|
8103 | if (!isFunction) { |
111 |
2/2✓ Branch 0 (15→16) taken 2 times.
✓ Branch 1 (15→26) taken 49 times.
|
51 | if (node->hasReturnValue) |
112 |
4/8✓ Branch 0 (18→19) taken 2 times.
✗ Branch 1 (18→74) not taken.
✓ Branch 2 (19→20) taken 2 times.
✗ Branch 3 (19→72) not taken.
✓ Branch 4 (22→23) taken 2 times.
✗ Branch 5 (22→78) not taken.
✓ Branch 6 (23→24) taken 2 times.
✗ Branch 7 (23→78) not taken.
|
6 | SOFT_ERROR_ER(node->assignExpr, RETURN_WITH_VALUE_IN_PROCEDURE, "Return with value in procedure is not allowed") |
113 |
1/2✓ Branch 0 (26→27) taken 49 times.
✗ Branch 1 (26→79) not taken.
|
49 | return nullptr; |
114 | } | ||
115 | |||
116 |
7/8✓ Branch 0 (28→29) taken 6 times.
✓ Branch 1 (28→33) taken 8046 times.
✓ Branch 2 (30→31) taken 6 times.
✗ Branch 3 (30→91) not taken.
✓ Branch 4 (31→32) taken 2 times.
✓ Branch 5 (31→33) taken 4 times.
✓ Branch 6 (34→35) taken 2 times.
✓ Branch 7 (34→45) taken 8050 times.
|
8052 | if (!node->hasReturnValue && !returnVar->getLifecycle().isInitialized()) |
117 |
4/8✓ Branch 0 (37→38) taken 2 times.
✗ Branch 1 (37→82) not taken.
✓ Branch 2 (38→39) taken 2 times.
✗ Branch 3 (38→80) not taken.
✓ Branch 4 (41→42) taken 2 times.
✗ Branch 5 (41→86) not taken.
✓ Branch 6 (42→43) taken 2 times.
✗ Branch 7 (42→86) not taken.
|
6 | SOFT_ERROR_QT(node, RETURN_WITHOUT_VALUE_RESULT, "Return without value, but result variable is not initialized yet") |
118 | |||
119 |
2/2✓ Branch 0 (45→46) taken 4 times.
✓ Branch 1 (45→48) taken 8046 times.
|
8050 | if (!node->hasReturnValue) |
120 |
1/2✓ Branch 0 (46→47) taken 4 times.
✗ Branch 1 (46→87) not taken.
|
4 | return nullptr; |
121 | |||
122 | // Visit right side | ||
123 |
2/4✓ Branch 0 (48→49) taken 8046 times.
✗ Branch 1 (48→90) not taken.
✓ Branch 2 (49→50) taken 8046 times.
✗ Branch 3 (49→88) not taken.
|
8046 | const auto rhs = std::any_cast<ExprResult>(visit(node->assignExpr)); |
124 |
2/6✓ Branch 0 (51→52) taken 8046 times.
✗ Branch 1 (51→91) not taken.
✗ Branch 2 (52→53) not taken.
✓ Branch 3 (52→55) taken 8046 times.
✗ Branch 4 (53→54) not taken.
✗ Branch 5 (53→91) not taken.
|
8046 | HANDLE_UNRESOLVED_TYPE_QT(rhs.type) |
125 | |||
126 | // Check if types match | ||
127 | 8046 | const ExprResult returnResult = {returnType, returnVar}; | |
128 |
2/2✓ Branch 0 (55→56) taken 8043 times.
✓ Branch 1 (55→91) taken 3 times.
|
8046 | auto [_, copyCtor] = opRuleManager.getAssignResultType(node->assignExpr, returnResult, rhs, false, true, ERROR_MSG_RETURN); |
129 | 8043 | node->calledCopyCtor = copyCtor; | |
130 | |||
131 | // Check if the dtor call on the return value can be skipped | ||
132 |
2/2✓ Branch 0 (58→59) taken 2074 times.
✓ Branch 1 (58→62) taken 5969 times.
|
8043 | if (rhs.entry != nullptr) { |
133 |
2/2✓ Branch 0 (59→60) taken 704 times.
✓ Branch 1 (59→61) taken 1370 times.
|
2074 | if (rhs.entry->anonymous) { |
134 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
135 |
1/2✓ Branch 0 (60→62) taken 704 times.
✗ Branch 1 (60→91) not taken.
|
704 | currentScope->symbolTable.deleteAnonymous(rhs.entry->name); |
136 | } else { | ||
137 | // Otherwise omit the destructor call, because the caller destructs the value | ||
138 | 1370 | rhs.entry->omitDtorCall = true; | |
139 | } | ||
140 | } | ||
141 | |||
142 |
1/2✓ Branch 0 (62→63) taken 8043 times.
✗ Branch 1 (62→91) not taken.
|
8043 | return node->returnType = returnType; |
143 | } | ||
144 | |||
145 | 107 | std::any TypeChecker::visitBreakStmt(BreakStmtNode *node) { | |
146 | // Check if the stated number is valid | ||
147 |
2/2✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→12) taken 106 times.
|
107 | if (node->breakTimes < 1) |
148 |
4/8✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→30) not taken.
✓ Branch 2 (5→6) taken 1 times.
✗ Branch 3 (5→28) not taken.
✓ Branch 4 (8→9) taken 1 times.
✗ Branch 5 (8→34) not taken.
✓ Branch 6 (9→10) taken 1 times.
✗ Branch 7 (9→34) not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "Break count must be >= 1, you provided " + std::to_string(node->breakTimes)) |
149 | |||
150 | // Check if we can break this often | ||
151 | 106 | const unsigned int maxBreaks = currentScope->getLoopNestingDepth(); | |
152 |
2/2✓ Branch 0 (13→14) taken 1 times.
✓ Branch 1 (13→25) taken 105 times.
|
106 | if (static_cast<unsigned int>(node->breakTimes) > maxBreaks) |
153 |
5/10✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→39) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→37) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→35) not taken.
✓ Branch 6 (21→22) taken 1 times.
✗ Branch 7 (21→44) not taken.
✓ Branch 8 (22→23) taken 1 times.
✗ Branch 9 (22→44) not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "We can only break " + std::to_string(maxBreaks) + " time(s) here") |
154 | |||
155 |
1/2✓ Branch 0 (25→26) taken 105 times.
✗ Branch 1 (25→45) not taken.
|
105 | return nullptr; |
156 | } | ||
157 | |||
158 | 359 | std::any TypeChecker::visitContinueStmt(ContinueStmtNode *node) { | |
159 | // Check if the stated number is valid | ||
160 |
2/2✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→12) taken 358 times.
|
359 | if (node->continueTimes < 1) |
161 |
4/8✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→30) not taken.
✓ Branch 2 (5→6) taken 1 times.
✗ Branch 3 (5→28) not taken.
✓ Branch 4 (8→9) taken 1 times.
✗ Branch 5 (8→34) not taken.
✓ Branch 6 (9→10) taken 1 times.
✗ Branch 7 (9→34) not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER, |
162 | "Continue count must be >= 1, you provided " + std::to_string(node->continueTimes)) | ||
163 | |||
164 | // Check if we can continue this often | ||
165 | 358 | const unsigned int maxContinues = currentScope->getLoopNestingDepth(); | |
166 |
2/2✓ Branch 0 (13→14) taken 1 times.
✓ Branch 1 (13→25) taken 357 times.
|
358 | if (static_cast<unsigned int>(node->continueTimes) > maxContinues) |
167 |
5/10✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→39) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→37) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→35) not taken.
✓ Branch 6 (21→22) taken 1 times.
✗ Branch 7 (21→44) not taken.
✓ Branch 8 (22→23) taken 1 times.
✗ Branch 9 (22→44) not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER, "We can only continue " + std::to_string(maxContinues) + " time(s) here") |
168 | |||
169 |
1/2✓ Branch 0 (25→26) taken 357 times.
✗ Branch 1 (25→45) not taken.
|
357 | return nullptr; |
170 | } | ||
171 | |||
172 | 6 | std::any TypeChecker::visitFallthroughStmt(FallthroughStmtNode *node) { | |
173 | // Check if we can do a fallthrough here | ||
174 |
2/2✓ Branch 0 (3→4) taken 2 times.
✓ Branch 1 (3→14) taken 4 times.
|
6 | if (!currentScope->isInCaseBranch()) |
175 |
4/8✓ Branch 0 (6→7) taken 2 times.
✗ Branch 1 (6→19) not taken.
✓ Branch 2 (7→8) taken 2 times.
✗ Branch 3 (7→17) not taken.
✓ Branch 4 (10→11) taken 2 times.
✗ Branch 5 (10→23) not taken.
✓ Branch 6 (11→12) taken 2 times.
✗ Branch 7 (11→23) not taken.
|
6 | SOFT_ERROR_ER(node, FALLTHROUGH_NOT_ALLOWED, "Fallthrough is only allowed in case branches") |
176 | |||
177 |
1/2✓ Branch 0 (14→15) taken 4 times.
✗ Branch 1 (14→24) not taken.
|
4 | return nullptr; |
178 | } | ||
179 | |||
180 | 709 | std::any TypeChecker::visitAssertStmt(AssertStmtNode *node) { | |
181 | // Visit condition | ||
182 |
2/4✓ Branch 0 (2→3) taken 709 times.
✗ Branch 1 (2→29) not taken.
✓ Branch 2 (3→4) taken 709 times.
✗ Branch 3 (3→27) not taken.
|
709 | const QualType conditionType = std::any_cast<ExprResult>(visit(node->assignExpr)).type; |
183 |
2/8✓ Branch 0 (5→6) taken 709 times.
✗ Branch 1 (5→40) not taken.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→11) taken 709 times.
✗ Branch 4 (7→8) not taken.
✗ Branch 5 (7→31) not taken.
✗ Branch 6 (8→9) not taken.
✗ Branch 7 (8→31) not taken.
|
709 | HANDLE_UNRESOLVED_TYPE_ER(conditionType) |
184 | |||
185 | // Check if condition evaluates to bool | ||
186 |
3/4✓ Branch 0 (11→12) taken 709 times.
✗ Branch 1 (11→40) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→23) taken 708 times.
|
709 | if (!conditionType.is(TY_BOOL)) |
187 |
4/8✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→34) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→32) not taken.
✓ Branch 4 (19→20) taken 1 times.
✗ Branch 5 (19→38) not taken.
✓ Branch 6 (20→21) taken 1 times.
✗ Branch 7 (20→38) not taken.
|
3 | SOFT_ERROR_ER(node->assignExpr, ASSERTION_CONDITION_BOOL, "The asserted condition must be of type bool") |
188 | |||
189 |
1/2✓ Branch 0 (23→24) taken 708 times.
✗ Branch 1 (23→39) not taken.
|
708 | return nullptr; |
190 | } | ||
191 | |||
192 | } // namespace spice::compiler | ||
193 |