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 <global/GlobalResourceManager.h> | ||
7 | #include <symboltablebuilder/SymbolTableBuilder.h> | ||
8 | #include <typechecker/MacroDefs.h> | ||
9 | |||
10 | namespace spice::compiler { | ||
11 | |||
12 | 65357 | std::any TypeChecker::visitAssignExpr(AssignExprNode *node) { | |
13 | // Check if ternary | ||
14 |
2/2✓ Branch 0 (2→3) taken 59719 times.
✓ Branch 1 (2→10) taken 5638 times.
|
65357 | if (node->ternaryExpr) { |
15 |
3/4✓ Branch 0 (3→4) taken 59704 times.
✓ Branch 1 (3→97) taken 15 times.
✓ Branch 2 (4→5) taken 59704 times.
✗ Branch 3 (4→95) not taken.
|
59719 | auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr)); |
16 |
1/2✓ Branch 0 (6→7) taken 59704 times.
✗ Branch 1 (6→98) not taken.
|
59704 | node->setEvaluatedSymbolType(result.type, manIdx); |
17 |
1/2✓ Branch 0 (7→8) taken 59704 times.
✗ Branch 1 (7→98) not taken.
|
59704 | return result; |
18 | } | ||
19 | |||
20 | // Check if assignment | ||
21 |
1/2✓ Branch 0 (10→11) taken 5638 times.
✗ Branch 1 (10→86) not taken.
|
5638 | if (node->op != AssignExprNode::AssignOp::OP_NONE) { |
22 | // Visit the right side first | ||
23 |
2/4✓ Branch 0 (11→12) taken 5638 times.
✗ Branch 1 (11→101) not taken.
✓ Branch 2 (12→13) taken 5638 times.
✗ Branch 3 (12→99) not taken.
|
5638 | auto rhs = std::any_cast<ExprResult>(visit(node->rhs)); |
24 | 5638 | auto [rhsType, rhsEntry] = rhs; | |
25 |
5/8✓ Branch 0 (14→15) taken 5638 times.
✗ Branch 1 (14→120) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→20) taken 5637 times.
✓ Branch 4 (16→17) taken 1 times.
✗ Branch 5 (16→102) not taken.
✓ Branch 6 (17→18) taken 1 times.
✗ Branch 7 (17→102) not taken.
|
5638 | HANDLE_UNRESOLVED_TYPE_ER(rhsType) |
26 | // Then visit the left side | ||
27 |
2/4✓ Branch 0 (20→21) taken 5637 times.
✗ Branch 1 (20→105) not taken.
✓ Branch 2 (21→22) taken 5637 times.
✗ Branch 3 (21→103) not taken.
|
5637 | auto lhs = std::any_cast<ExprResult>(visit(node->lhs)); |
28 | 5637 | auto [lhsType, lhsVar] = lhs; | |
29 |
5/8✓ Branch 0 (23→24) taken 5637 times.
✗ Branch 1 (23→120) not taken.
✓ Branch 2 (24→25) taken 1 times.
✓ Branch 3 (24→29) taken 5636 times.
✓ Branch 4 (25→26) taken 1 times.
✗ Branch 5 (25→106) not taken.
✓ Branch 6 (26→27) taken 1 times.
✗ Branch 7 (26→106) not taken.
|
5637 | HANDLE_UNRESOLVED_TYPE_ER(lhsType) |
30 | |||
31 | // Take a look at the operator | ||
32 |
2/2✓ Branch 0 (29→30) taken 5025 times.
✓ Branch 1 (29→42) taken 611 times.
|
5636 | if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) { |
33 |
8/10✓ Branch 0 (30→31) taken 5024 times.
✓ Branch 1 (30→37) taken 1 times.
✓ Branch 2 (31→32) taken 5024 times.
✗ Branch 3 (31→120) not taken.
✓ Branch 4 (32→33) taken 4011 times.
✓ Branch 5 (32→37) taken 1013 times.
✓ Branch 6 (34→35) taken 4011 times.
✗ Branch 7 (34→120) not taken.
✓ Branch 8 (35→36) taken 1295 times.
✓ Branch 9 (35→37) taken 2716 times.
|
5025 | const bool isDecl = lhs.entry != nullptr && lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized(); |
34 |
2/2✓ Branch 0 (38→39) taken 5024 times.
✓ Branch 1 (38→107) taken 1 times.
|
5025 | rhsType = opRuleManager.getAssignResultType(node, lhs, rhs, isDecl).first; |
35 | |||
36 | // If there is an anonymous entry attached (e.g. for struct instantiation), delete it | ||
37 |
4/4✓ Branch 0 (39→40) taken 2345 times.
✓ Branch 1 (39→72) taken 2679 times.
✓ Branch 2 (40→41) taken 146 times.
✓ Branch 3 (40→72) taken 2199 times.
|
5024 | if (rhsEntry != nullptr && rhsEntry->anonymous) |
38 |
1/2✓ Branch 0 (41→72) taken 146 times.
✗ Branch 1 (41→120) not taken.
|
146 | currentScope->symbolTable.deleteAnonymous(rhsEntry->name); |
39 |
2/2✓ Branch 0 (42→43) taken 248 times.
✓ Branch 1 (42→45) taken 363 times.
|
611 | } else if (node->op == AssignExprNode::AssignOp::OP_PLUS_EQUAL) { |
40 |
1/2✓ Branch 0 (43→44) taken 248 times.
✗ Branch 1 (43→108) not taken.
|
248 | rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type; |
41 |
2/2✓ Branch 0 (45→46) taken 33 times.
✓ Branch 1 (45→48) taken 330 times.
|
363 | } else if (node->op == AssignExprNode::AssignOp::OP_MINUS_EQUAL) { |
42 |
1/2✓ Branch 0 (46→47) taken 33 times.
✗ Branch 1 (46→109) not taken.
|
33 | rhsType = opRuleManager.getMinusEqualResultType(node, lhs, rhs, 0).type; |
43 |
2/2✓ Branch 0 (48→49) taken 19 times.
✓ Branch 1 (48→51) taken 311 times.
|
330 | } else if (node->op == AssignExprNode::AssignOp::OP_MUL_EQUAL) { |
44 |
1/2✓ Branch 0 (49→50) taken 19 times.
✗ Branch 1 (49→110) not taken.
|
19 | rhsType = opRuleManager.getMulEqualResultType(node, lhs, rhs, 0).type; |
45 |
2/2✓ Branch 0 (51→52) taken 45 times.
✓ Branch 1 (51→54) taken 266 times.
|
311 | } else if (node->op == AssignExprNode::AssignOp::OP_DIV_EQUAL) { |
46 |
1/2✓ Branch 0 (52→53) taken 45 times.
✗ Branch 1 (52→111) not taken.
|
45 | rhsType = opRuleManager.getDivEqualResultType(node, lhs, rhs, 0).type; |
47 |
2/2✓ Branch 0 (54→55) taken 6 times.
✓ Branch 1 (54→57) taken 260 times.
|
266 | } else if (node->op == AssignExprNode::AssignOp::OP_REM_EQUAL) { |
48 |
1/2✓ Branch 0 (55→56) taken 6 times.
✗ Branch 1 (55→112) not taken.
|
6 | rhsType = opRuleManager.getRemEqualResultType(node, lhs, rhs); |
49 |
2/2✓ Branch 0 (57→58) taken 2 times.
✓ Branch 1 (57→60) taken 258 times.
|
260 | } else if (node->op == AssignExprNode::AssignOp::OP_SHL_EQUAL) { |
50 |
1/2✓ Branch 0 (58→59) taken 2 times.
✗ Branch 1 (58→113) not taken.
|
2 | rhsType = opRuleManager.getSHLEqualResultType(node, lhs, rhs); |
51 |
2/2✓ Branch 0 (60→61) taken 3 times.
✓ Branch 1 (60→63) taken 255 times.
|
258 | } else if (node->op == AssignExprNode::AssignOp::OP_SHR_EQUAL) { |
52 |
1/2✓ Branch 0 (61→62) taken 3 times.
✗ Branch 1 (61→114) not taken.
|
3 | rhsType = opRuleManager.getSHREqualResultType(node, lhs, rhs); |
53 |
2/2✓ Branch 0 (63→64) taken 1 times.
✓ Branch 1 (63→66) taken 254 times.
|
255 | } else if (node->op == AssignExprNode::AssignOp::OP_AND_EQUAL) { |
54 |
1/2✓ Branch 0 (64→65) taken 1 times.
✗ Branch 1 (64→115) not taken.
|
1 | rhsType = opRuleManager.getAndEqualResultType(node, lhs, rhs); |
55 |
2/2✓ Branch 0 (66→67) taken 1 times.
✓ Branch 1 (66→69) taken 253 times.
|
254 | } else if (node->op == AssignExprNode::AssignOp::OP_OR_EQUAL) { |
56 |
1/2✓ Branch 0 (67→68) taken 1 times.
✗ Branch 1 (67→116) not taken.
|
1 | rhsType = opRuleManager.getOrEqualResultType(node, lhs, rhs); |
57 |
1/2✓ Branch 0 (69→70) taken 253 times.
✗ Branch 1 (69→72) not taken.
|
253 | } else if (node->op == AssignExprNode::AssignOp::OP_XOR_EQUAL) { |
58 |
1/2✓ Branch 0 (70→71) taken 253 times.
✗ Branch 1 (70→117) not taken.
|
253 | rhsType = opRuleManager.getXorEqualResultType(node, lhs, rhs); |
59 | } | ||
60 | |||
61 |
1/2✓ Branch 0 (72→73) taken 5635 times.
✗ Branch 1 (72→81) not taken.
|
5635 | if (lhsVar) { // Variable is involved on the left side |
62 | // Perform type inference | ||
63 |
3/4✓ Branch 0 (73→74) taken 5635 times.
✗ Branch 1 (73→120) not taken.
✓ Branch 2 (74→75) taken 1 times.
✓ Branch 3 (74→76) taken 5634 times.
|
5635 | if (lhsType.is(TY_DYN)) |
64 |
1/2✓ Branch 0 (75→76) taken 1 times.
✗ Branch 1 (75→120) not taken.
|
1 | lhsVar->updateType(rhsType, false); |
65 | |||
66 | // In case the lhs variable is captured, notify the capture about the write access | ||
67 |
3/4✓ Branch 0 (76→77) taken 5635 times.
✗ Branch 1 (76→120) not taken.
✓ Branch 2 (77→78) taken 3 times.
✓ Branch 3 (77→79) taken 5632 times.
|
5635 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsVar->name); lhsCapture) |
68 |
1/2✓ Branch 0 (78→79) taken 3 times.
✗ Branch 1 (78→120) not taken.
|
3 | lhsCapture->setAccessType(READ_WRITE); |
69 | |||
70 | // Update the state of the variable | ||
71 |
1/2✓ Branch 0 (79→80) taken 5635 times.
✗ Branch 1 (79→118) not taken.
|
5635 | lhsVar->updateState(INITIALIZED, node); |
72 | } | ||
73 | |||
74 |
2/4✓ Branch 0 (81→82) taken 5635 times.
✗ Branch 1 (81→119) not taken.
✓ Branch 2 (82→83) taken 5635 times.
✗ Branch 3 (82→119) not taken.
|
5635 | return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)}; |
75 | } | ||
76 | |||
77 | − | throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE | |
78 | } | ||
79 | |||
80 | 60347 | std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) { | |
81 | // Check if there is a ternary operator applied | ||
82 |
2/2✓ Branch 0 (2→3) taken 59977 times.
✓ Branch 1 (2→5) taken 370 times.
|
60347 | if (!node->falseExpr) |
83 |
2/2✓ Branch 0 (3→4) taken 59962 times.
✓ Branch 1 (3→150) taken 15 times.
|
59977 | return visit(node->condition); |
84 | |||
85 | // Visit condition | ||
86 |
2/4✓ Branch 0 (5→6) taken 370 times.
✗ Branch 1 (5→115) not taken.
✓ Branch 2 (6→7) taken 370 times.
✗ Branch 3 (6→113) not taken.
|
370 | const auto condition = std::any_cast<ExprResult>(visit(node->condition)); |
87 |
2/8✓ Branch 0 (8→9) taken 370 times.
✗ Branch 1 (8→150) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 370 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→116) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→116) not taken.
|
370 | HANDLE_UNRESOLVED_TYPE_ER(condition.type) |
88 |
6/10✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→16) taken 369 times.
✓ Branch 2 (16→17) taken 369 times.
✗ Branch 3 (16→117) not taken.
✓ Branch 4 (17→18) taken 369 times.
✗ Branch 5 (17→117) not taken.
✓ Branch 6 (18→19) taken 369 times.
✓ Branch 7 (18→20) taken 1 times.
✗ Branch 8 (117→118) not taken.
✗ Branch 9 (117→119) not taken.
|
370 | const auto trueExpr = node->isShortened ? condition : std::any_cast<ExprResult>(visit(node->trueExpr)); |
89 | 370 | const auto [trueType, trueEntry] = trueExpr; | |
90 |
2/8✓ Branch 0 (20→21) taken 370 times.
✗ Branch 1 (20→150) not taken.
✗ Branch 2 (21→22) not taken.
✓ Branch 3 (21→26) taken 370 times.
✗ Branch 4 (22→23) not taken.
✗ Branch 5 (22→121) not taken.
✗ Branch 6 (23→24) not taken.
✗ Branch 7 (23→121) not taken.
|
370 | HANDLE_UNRESOLVED_TYPE_ER(trueType) |
91 |
2/4✓ Branch 0 (26→27) taken 370 times.
✗ Branch 1 (26→124) not taken.
✓ Branch 2 (27→28) taken 370 times.
✗ Branch 3 (27→122) not taken.
|
370 | const auto falseExpr = std::any_cast<ExprResult>(visit(node->falseExpr)); |
92 | 370 | const auto [falseType, falseEntry] = falseExpr; | |
93 |
2/8✓ Branch 0 (29→30) taken 370 times.
✗ Branch 1 (29→150) not taken.
✗ Branch 2 (30→31) not taken.
✓ Branch 3 (30→35) taken 370 times.
✗ Branch 4 (31→32) not taken.
✗ Branch 5 (31→125) not taken.
✗ Branch 6 (32→33) not taken.
✗ Branch 7 (32→125) not taken.
|
370 | HANDLE_UNRESOLVED_TYPE_ER(falseType) |
94 | |||
95 | // Check if the condition evaluates to bool | ||
96 |
3/4✓ Branch 0 (35→36) taken 370 times.
✗ Branch 1 (35→150) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→47) taken 369 times.
|
370 | if (!condition.type.is(TY_BOOL)) |
97 |
4/8✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→128) not taken.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→126) not taken.
✓ Branch 4 (43→44) taken 1 times.
✗ Branch 5 (43→132) not taken.
✓ Branch 6 (44→45) taken 1 times.
✗ Branch 7 (44→132) not taken.
|
3 | SOFT_ERROR_ER(node->condition, OPERATOR_WRONG_DATA_TYPE, "Condition operand in ternary must be a bool") |
98 | |||
99 | // Check if trueType and falseType are matching | ||
100 |
1/2✓ Branch 0 (47→48) taken 369 times.
✗ Branch 1 (47→150) not taken.
|
369 | const QualType trueTypeModified = trueType.removeReferenceWrapper(); |
101 |
1/2✓ Branch 0 (48→49) taken 369 times.
✗ Branch 1 (48→150) not taken.
|
369 | const QualType falseTypeModified = falseType.removeReferenceWrapper(); |
102 |
3/4✓ Branch 0 (49→50) taken 369 times.
✗ Branch 1 (49→150) not taken.
✓ Branch 2 (50→51) taken 1 times.
✓ Branch 3 (50→66) taken 368 times.
|
369 | if (!trueTypeModified.matches(falseTypeModified, false, true, false)) |
103 |
8/16✓ Branch 0 (51→52) taken 1 times.
✗ Branch 1 (51→146) not taken.
✓ Branch 2 (52→53) taken 1 times.
✗ Branch 3 (52→141) not taken.
✓ Branch 4 (53→54) taken 1 times.
✗ Branch 5 (53→139) not taken.
✓ Branch 6 (54→55) taken 1 times.
✗ Branch 7 (54→137) not taken.
✓ Branch 8 (55→56) taken 1 times.
✗ Branch 9 (55→135) not taken.
✓ Branch 10 (56→57) taken 1 times.
✗ Branch 11 (56→133) not taken.
✓ Branch 12 (62→63) taken 1 times.
✗ Branch 13 (62→148) not taken.
✓ Branch 14 (63→64) taken 1 times.
✗ Branch 15 (63→148) not taken.
|
1 | SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE, |
104 | "True and false operands in ternary must be of same data type. Got " + trueType.getName(true) + " and " + | ||
105 | falseType.getName(true)) | ||
106 | |||
107 | // If there is an anonymous symbol attached to left or right, remove it, | ||
108 | // since the result takes over the ownership of any destructible object. | ||
109 | 368 | bool removedAnonymousSymbols = false; | |
110 |
2/2✓ Branch 0 (66→67) taken 115 times.
✓ Branch 1 (66→78) taken 253 times.
|
368 | if (trueEntry) { |
111 |
2/2✓ Branch 0 (67→68) taken 68 times.
✓ Branch 1 (67→70) taken 47 times.
|
115 | if (trueEntry->anonymous) { |
112 |
1/2✓ Branch 0 (68→69) taken 68 times.
✗ Branch 1 (68→150) not taken.
|
68 | currentScope->symbolTable.deleteAnonymous(trueEntry->name); |
113 | 68 | removedAnonymousSymbols = true; | |
114 |
8/10✓ Branch 0 (70→71) taken 47 times.
✗ Branch 1 (70→150) not taken.
✓ Branch 2 (71→72) taken 39 times.
✓ Branch 3 (71→75) taken 8 times.
✓ Branch 4 (72→73) taken 39 times.
✗ Branch 5 (72→150) not taken.
✓ Branch 6 (73→74) taken 8 times.
✓ Branch 7 (73→75) taken 31 times.
✓ Branch 8 (76→77) taken 8 times.
✓ Branch 9 (76→78) taken 39 times.
|
47 | } else if (!trueType.isRef() && !trueType.isTriviallyCopyable(node)) { |
115 | 8 | node->trueSideCallsCopyCtor = true; | |
116 | } | ||
117 | } | ||
118 |
2/2✓ Branch 0 (78→79) taken 293 times.
✓ Branch 1 (78→90) taken 75 times.
|
368 | if (falseEntry) { |
119 |
2/2✓ Branch 0 (79→80) taken 67 times.
✓ Branch 1 (79→82) taken 226 times.
|
293 | if (falseEntry->anonymous) { |
120 |
1/2✓ Branch 0 (80→81) taken 67 times.
✗ Branch 1 (80→150) not taken.
|
67 | currentScope->symbolTable.deleteAnonymous(falseEntry->name); |
121 | 67 | removedAnonymousSymbols = true; | |
122 |
8/10✓ Branch 0 (82→83) taken 226 times.
✗ Branch 1 (82→150) not taken.
✓ Branch 2 (83→84) taken 217 times.
✓ Branch 3 (83→87) taken 9 times.
✓ Branch 4 (84→85) taken 217 times.
✗ Branch 5 (84→150) not taken.
✓ Branch 6 (85→86) taken 8 times.
✓ Branch 7 (85→87) taken 209 times.
✓ Branch 8 (88→89) taken 8 times.
✓ Branch 9 (88→90) taken 218 times.
|
226 | } else if (!falseType.isRef() && !falseType.isTriviallyCopyable(node)) { |
123 | 8 | node->falseSideCallsCopyCtor = true; | |
124 | } | ||
125 | } | ||
126 | |||
127 | // Create a new anonymous symbol for the result if required | ||
128 | 368 | const QualType &resultType = trueType; | |
129 | 368 | SymbolTableEntry *anonymousSymbol = nullptr; | |
130 |
4/4✓ Branch 0 (90→91) taken 360 times.
✓ Branch 1 (90→92) taken 8 times.
✓ Branch 2 (91→92) taken 2 times.
✓ Branch 3 (91→93) taken 358 times.
|
368 | const bool calledCopyCtor = node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor; |
131 |
9/10✓ Branch 0 (94→95) taken 298 times.
✓ Branch 1 (94→98) taken 70 times.
✓ Branch 2 (95→96) taken 292 times.
✓ Branch 3 (95→98) taken 6 times.
✓ Branch 4 (96→97) taken 292 times.
✗ Branch 5 (96→150) not taken.
✓ Branch 6 (97→98) taken 8 times.
✓ Branch 7 (97→99) taken 284 times.
✓ Branch 8 (100→101) taken 84 times.
✓ Branch 9 (100→103) taken 284 times.
|
368 | if (removedAnonymousSymbols || calledCopyCtor || resultType.isRef()) |
132 |
1/2✓ Branch 0 (101→102) taken 84 times.
✗ Branch 1 (101→150) not taken.
|
84 | anonymousSymbol = currentScope->symbolTable.insertAnonymous(resultType, node); |
133 | |||
134 | // Look up the copy ctor if at least one side needs it | ||
135 |
4/4✓ Branch 0 (103→104) taken 360 times.
✓ Branch 1 (103→105) taken 8 times.
✓ Branch 2 (104→105) taken 2 times.
✓ Branch 3 (104→107) taken 358 times.
|
368 | if (node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor) |
136 |
1/2✓ Branch 0 (105→106) taken 10 times.
✗ Branch 1 (105→150) not taken.
|
10 | node->calledCopyCtor = matchCopyCtor(trueTypeModified, node); |
137 | |||
138 |
2/4✓ Branch 0 (107→108) taken 368 times.
✗ Branch 1 (107→149) not taken.
✓ Branch 2 (108→109) taken 368 times.
✗ Branch 3 (108→149) not taken.
|
368 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), anonymousSymbol}; |
139 | } | ||
140 | |||
141 | 61086 | std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) { | |
142 | // Check if a logical or operator is applied | ||
143 |
2/2✓ Branch 0 (3→4) taken 60231 times.
✓ Branch 1 (3→7) taken 855 times.
|
61086 | if (node->operands.size() == 1) |
144 |
2/2✓ Branch 0 (5→6) taken 60217 times.
✓ Branch 1 (5→46) taken 14 times.
|
60231 | return visit(node->operands.front()); |
145 | |||
146 | // Visit leftmost operand | ||
147 |
2/4✓ Branch 0 (8→9) taken 855 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 855 times.
✗ Branch 3 (9→37) not taken.
|
855 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
148 |
2/8✓ Branch 0 (11→12) taken 855 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 855 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
|
855 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
149 | |||
150 | // Loop through all remaining operands | ||
151 |
2/2✓ Branch 0 (31→18) taken 1098 times.
✓ Branch 1 (31→32) taken 854 times.
|
1952 | for (size_t i = 1; i < node->operands.size(); i++) { |
152 |
2/4✓ Branch 0 (19→20) taken 1098 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 1098 times.
✗ Branch 3 (20→41) not taken.
|
1098 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
153 |
2/8✓ Branch 0 (22→23) taken 1098 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 1098 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
|
1098 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
154 |
2/2✓ Branch 0 (28→29) taken 1097 times.
✓ Branch 1 (28→45) taken 1 times.
|
1098 | currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)}; |
155 | } | ||
156 | |||
157 |
1/2✓ Branch 0 (32→33) taken 854 times.
✗ Branch 1 (32→46) not taken.
|
854 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
158 |
1/2✓ Branch 0 (33→34) taken 854 times.
✗ Branch 1 (33→46) not taken.
|
854 | return currentOperand; |
159 | } | ||
160 | |||
161 | 62184 | std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) { | |
162 | // Check if a logical and operator is applied | ||
163 |
2/2✓ Branch 0 (3→4) taken 62038 times.
✓ Branch 1 (3→7) taken 146 times.
|
62184 | if (node->operands.size() == 1) |
164 |
2/2✓ Branch 0 (5→6) taken 62024 times.
✓ Branch 1 (5→46) taken 14 times.
|
62038 | return visit(node->operands.front()); |
165 | |||
166 | // Visit leftmost operand | ||
167 |
2/4✓ Branch 0 (8→9) taken 146 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 146 times.
✗ Branch 3 (9→37) not taken.
|
146 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
168 |
2/8✓ Branch 0 (11→12) taken 146 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 146 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
|
146 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
169 | |||
170 | // Loop through all remaining operands | ||
171 |
2/2✓ Branch 0 (31→18) taken 181 times.
✓ Branch 1 (31→32) taken 146 times.
|
327 | for (size_t i = 1; i < node->operands.size(); i++) { |
172 |
2/4✓ Branch 0 (19→20) taken 181 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 181 times.
✗ Branch 3 (20→41) not taken.
|
181 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
173 |
2/8✓ Branch 0 (22→23) taken 181 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 181 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
|
181 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
174 |
1/2✓ Branch 0 (28→29) taken 181 times.
✗ Branch 1 (28→45) not taken.
|
181 | currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)}; |
175 | } | ||
176 | |||
177 |
1/2✓ Branch 0 (32→33) taken 146 times.
✗ Branch 1 (32→46) not taken.
|
146 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
178 |
1/2✓ Branch 0 (33→34) taken 146 times.
✗ Branch 1 (33→46) not taken.
|
146 | return currentOperand; |
179 | } | ||
180 | |||
181 | 62365 | std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) { | |
182 | // Check if a bitwise or operator is applied | ||
183 |
2/2✓ Branch 0 (3→4) taken 62298 times.
✓ Branch 1 (3→7) taken 67 times.
|
62365 | if (node->operands.size() == 1) |
184 |
2/2✓ Branch 0 (5→6) taken 62285 times.
✓ Branch 1 (5→46) taken 13 times.
|
62298 | return visit(node->operands.front()); |
185 | |||
186 | // Visit leftmost operand | ||
187 |
2/4✓ Branch 0 (8→9) taken 67 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 67 times.
✗ Branch 3 (9→37) not taken.
|
67 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
188 |
2/8✓ Branch 0 (11→12) taken 67 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 67 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
|
67 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
189 | |||
190 | // Loop through all remaining operands | ||
191 |
2/2✓ Branch 0 (31→18) taken 70 times.
✓ Branch 1 (31→32) taken 66 times.
|
136 | for (size_t i = 1; i < node->operands.size(); i++) { |
192 |
2/4✓ Branch 0 (19→20) taken 70 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 70 times.
✗ Branch 3 (20→41) not taken.
|
70 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
193 |
2/8✓ Branch 0 (22→23) taken 70 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 70 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
|
70 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
194 |
2/2✓ Branch 0 (28→29) taken 69 times.
✓ Branch 1 (28→45) taken 1 times.
|
70 | currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)}; |
195 | } | ||
196 | |||
197 |
1/2✓ Branch 0 (32→33) taken 66 times.
✗ Branch 1 (32→46) not taken.
|
66 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
198 |
1/2✓ Branch 0 (33→34) taken 66 times.
✗ Branch 1 (33→46) not taken.
|
66 | return currentOperand; |
199 | } | ||
200 | |||
201 | 62435 | std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) { | |
202 | // Check if a bitwise xor operator is applied | ||
203 |
2/2✓ Branch 0 (3→4) taken 62431 times.
✓ Branch 1 (3→7) taken 4 times.
|
62435 | if (node->operands.size() == 1) |
204 |
2/2✓ Branch 0 (5→6) taken 62418 times.
✓ Branch 1 (5→46) taken 13 times.
|
62431 | return visit(node->operands.front()); |
205 | |||
206 | // Visit leftmost operand | ||
207 |
2/4✓ Branch 0 (8→9) taken 4 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 4 times.
✗ Branch 3 (9→37) not taken.
|
4 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
208 |
2/8✓ Branch 0 (11→12) taken 4 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
|
4 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
209 | |||
210 | // Loop through all remaining operands | ||
211 |
2/2✓ Branch 0 (31→18) taken 7 times.
✓ Branch 1 (31→32) taken 4 times.
|
11 | for (size_t i = 1; i < node->operands.size(); i++) { |
212 |
2/4✓ Branch 0 (19→20) taken 7 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 7 times.
✗ Branch 3 (20→41) not taken.
|
7 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
213 |
2/8✓ Branch 0 (22→23) taken 7 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 7 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
|
7 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
214 |
1/2✓ Branch 0 (28→29) taken 7 times.
✗ Branch 1 (28→45) not taken.
|
7 | currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)}; |
215 | } | ||
216 | |||
217 |
1/2✓ Branch 0 (32→33) taken 4 times.
✗ Branch 1 (32→46) not taken.
|
4 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
218 |
1/2✓ Branch 0 (33→34) taken 4 times.
✗ Branch 1 (33→46) not taken.
|
4 | return currentOperand; |
219 | } | ||
220 | |||
221 | 62442 | std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) { | |
222 | // Check if a bitwise and operator is applied | ||
223 |
2/2✓ Branch 0 (3→4) taken 62410 times.
✓ Branch 1 (3→7) taken 32 times.
|
62442 | if (node->operands.size() == 1) |
224 |
2/2✓ Branch 0 (5→6) taken 62397 times.
✓ Branch 1 (5→46) taken 13 times.
|
62410 | return visit(node->operands.front()); |
225 | |||
226 | // Visit leftmost operand | ||
227 |
2/4✓ Branch 0 (8→9) taken 32 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 32 times.
✗ Branch 3 (9→37) not taken.
|
32 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
228 |
2/8✓ Branch 0 (11→12) taken 32 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 32 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
|
32 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
229 | |||
230 | // Loop through all remaining operands | ||
231 |
2/2✓ Branch 0 (31→18) taken 35 times.
✓ Branch 1 (31→32) taken 32 times.
|
67 | for (size_t i = 1; i < node->operands.size(); i++) { |
232 |
2/4✓ Branch 0 (19→20) taken 35 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 35 times.
✗ Branch 3 (20→41) not taken.
|
35 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
233 |
2/8✓ Branch 0 (22→23) taken 35 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 35 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
|
35 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
234 |
1/2✓ Branch 0 (28→29) taken 35 times.
✗ Branch 1 (28→45) not taken.
|
35 | currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)}; |
235 | } | ||
236 | |||
237 |
1/2✓ Branch 0 (32→33) taken 32 times.
✗ Branch 1 (32→46) not taken.
|
32 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
238 |
1/2✓ Branch 0 (33→34) taken 32 times.
✗ Branch 1 (33→46) not taken.
|
32 | return currentOperand; |
239 | } | ||
240 | |||
241 | 62477 | std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) { | |
242 | // Check if at least one equality operator is applied | ||
243 |
2/2✓ Branch 0 (3→4) taken 57722 times.
✓ Branch 1 (3→7) taken 4755 times.
|
62477 | if (node->operands.size() == 1) |
244 |
2/2✓ Branch 0 (5→6) taken 57710 times.
✓ Branch 1 (5→73) taken 12 times.
|
57722 | return visit(node->operands.front()); |
245 | |||
246 | // Visit right side first, then left side | ||
247 |
2/4✓ Branch 0 (8→9) taken 4755 times.
✗ Branch 1 (8→58) not taken.
✓ Branch 2 (9→10) taken 4755 times.
✗ Branch 3 (9→56) not taken.
|
4755 | const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1])); |
248 |
2/8✓ Branch 0 (11→12) taken 4755 times.
✗ Branch 1 (11→73) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4755 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→59) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→59) not taken.
|
4755 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
249 |
2/4✓ Branch 0 (18→19) taken 4755 times.
✗ Branch 1 (18→62) not taken.
✓ Branch 2 (19→20) taken 4755 times.
✗ Branch 3 (19→60) not taken.
|
4755 | const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0])); |
250 |
2/8✓ Branch 0 (21→22) taken 4755 times.
✗ Branch 1 (21→73) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 4755 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→63) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→63) not taken.
|
4755 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
251 | |||
252 | // Check if we need the string runtime to perform a string comparison | ||
253 |
10/14✓ Branch 0 (27→28) taken 4755 times.
✗ Branch 1 (27→73) not taken.
✓ Branch 2 (28→29) taken 115 times.
✓ Branch 3 (28→36) taken 4640 times.
✓ Branch 4 (29→30) taken 115 times.
✗ Branch 5 (29→73) not taken.
✓ Branch 6 (30→31) taken 114 times.
✓ Branch 7 (30→36) taken 1 times.
✓ Branch 8 (31→32) taken 114 times.
✗ Branch 9 (31→73) not taken.
✓ Branch 10 (34→35) taken 114 times.
✗ Branch 11 (34→36) not taken.
✓ Branch 12 (37→38) taken 114 times.
✓ Branch 13 (37→39) taken 4641 times.
|
4869 | if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT()) |
254 |
1/2✓ Branch 0 (38→39) taken 114 times.
✗ Branch 1 (38→73) not taken.
|
114 | sourceFile->requestRuntimeModule(STRING_RT); |
255 | |||
256 | // Check operator | ||
257 | 4755 | ExprResult result; | |
258 |
2/2✓ Branch 0 (39→40) taken 3377 times.
✓ Branch 1 (39→41) taken 1378 times.
|
4755 | if (node->op == EqualityExprNode::EqualityOp::OP_EQUAL) // Operator was equal |
259 |
2/2✓ Branch 0 (40→51) taken 3376 times.
✓ Branch 1 (40→73) taken 1 times.
|
3377 | result = opRuleManager.getEqualResultType(node, lhs, rhs, 0); |
260 |
1/2✓ Branch 0 (41→42) taken 1378 times.
✗ Branch 1 (41→43) not taken.
|
1378 | else if (node->op == EqualityExprNode::EqualityOp::OP_NOT_EQUAL) // Operator was not equal |
261 |
1/2✓ Branch 0 (42→51) taken 1378 times.
✗ Branch 1 (42→73) not taken.
|
1378 | result = opRuleManager.getNotEqualResultType(node, lhs, rhs, 0); |
262 | else | ||
263 | − | throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE | |
264 | |||
265 |
1/2✓ Branch 0 (51→52) taken 4754 times.
✗ Branch 1 (51→73) not taken.
|
4754 | node->setEvaluatedSymbolType(result.type, manIdx); |
266 |
1/2✓ Branch 0 (52→53) taken 4754 times.
✗ Branch 1 (52→73) not taken.
|
4754 | return result; |
267 | } | ||
268 | |||
269 | 67232 | std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) { | |
270 | // Check if a relational operator is applied | ||
271 |
2/2✓ Branch 0 (3→4) taken 63805 times.
✓ Branch 1 (3→7) taken 3427 times.
|
67232 | if (node->operands.size() == 1) |
272 |
2/2✓ Branch 0 (5→6) taken 63794 times.
✓ Branch 1 (5→75) taken 11 times.
|
63805 | return visit(node->operands.front()); |
273 | |||
274 | // Visit right side first, then left side | ||
275 |
2/4✓ Branch 0 (8→9) taken 3427 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 3427 times.
✗ Branch 3 (9→53) not taken.
|
3427 | const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1])); |
276 |
5/8✓ Branch 0 (11→12) taken 3427 times.
✗ Branch 1 (11→75) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→17) taken 3426 times.
✓ Branch 4 (13→14) taken 1 times.
✗ Branch 5 (13→56) not taken.
✓ Branch 6 (14→15) taken 1 times.
✗ Branch 7 (14→56) not taken.
|
3427 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
277 |
2/4✓ Branch 0 (18→19) taken 3426 times.
✗ Branch 1 (18→59) not taken.
✓ Branch 2 (19→20) taken 3426 times.
✗ Branch 3 (19→57) not taken.
|
3426 | const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0])); |
278 |
2/8✓ Branch 0 (21→22) taken 3426 times.
✗ Branch 1 (21→75) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 3426 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→60) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→60) not taken.
|
3426 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
279 | |||
280 | // Check operator | ||
281 | 3426 | QualType resultType; | |
282 |
2/2✓ Branch 0 (27→28) taken 1707 times.
✓ Branch 1 (27→30) taken 1719 times.
|
3426 | if (node->op == RelationalExprNode::RelationalOp::OP_LESS) // Operator was less |
283 |
1/2✓ Branch 0 (28→29) taken 1707 times.
✗ Branch 1 (28→61) not taken.
|
1707 | resultType = OpRuleManager::getLessResultType(node, lhs, rhs); |
284 |
2/2✓ Branch 0 (30→31) taken 477 times.
✓ Branch 1 (30→33) taken 1242 times.
|
1719 | else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER) // Operator was greater |
285 |
2/2✓ Branch 0 (31→32) taken 476 times.
✓ Branch 1 (31→62) taken 1 times.
|
477 | resultType = OpRuleManager::getGreaterResultType(node, lhs, rhs); |
286 |
2/2✓ Branch 0 (33→34) taken 361 times.
✓ Branch 1 (33→36) taken 881 times.
|
1242 | else if (node->op == RelationalExprNode::RelationalOp::OP_LESS_EQUAL) // Operator was less equal |
287 |
1/2✓ Branch 0 (34→35) taken 361 times.
✗ Branch 1 (34→63) not taken.
|
361 | resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs); |
288 |
1/2✓ Branch 0 (36→37) taken 881 times.
✗ Branch 1 (36→39) not taken.
|
881 | else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER_EQUAL) // Operator was greater equal |
289 |
1/2✓ Branch 0 (37→38) taken 881 times.
✗ Branch 1 (37→64) not taken.
|
881 | resultType = OpRuleManager::getGreaterEqualResultType(node, lhs, rhs); |
290 | else | ||
291 | − | throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE | |
292 | |||
293 |
2/4✓ Branch 0 (47→48) taken 3425 times.
✗ Branch 1 (47→74) not taken.
✓ Branch 2 (48→49) taken 3425 times.
✗ Branch 3 (48→74) not taken.
|
3425 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)}; |
294 | } | ||
295 | |||
296 | 70658 | std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) { | |
297 | // Check if at least one shift operator is applied | ||
298 |
2/2✓ Branch 0 (3→4) taken 70596 times.
✓ Branch 1 (3→7) taken 62 times.
|
70658 | if (node->operands.size() == 1) |
299 |
2/2✓ Branch 0 (5→6) taken 70585 times.
✓ Branch 1 (5→69) taken 11 times.
|
70596 | return visit(node->operands.front()); |
300 | |||
301 | // Visit leftmost operand | ||
302 |
2/4✓ Branch 0 (8→9) taken 62 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 62 times.
✗ Branch 3 (9→51) not taken.
|
62 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
303 |
2/8✓ Branch 0 (11→12) taken 62 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 62 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→54) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→54) not taken.
|
62 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
304 | |||
305 | // Loop through remaining operands | ||
306 |
2/2✓ Branch 0 (45→18) taken 102 times.
✓ Branch 1 (45→46) taken 62 times.
|
164 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
307 |
2/4✓ Branch 0 (19→20) taken 102 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 102 times.
✗ Branch 3 (20→55) not taken.
|
102 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
308 |
2/8✓ Branch 0 (22→23) taken 102 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 102 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→58) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→58) not taken.
|
102 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
309 | |||
310 | // Check operator | ||
311 | 102 | const ShiftExprNode::ShiftOp &op = node->opQueue.front().first; | |
312 |
2/2✓ Branch 0 (29→30) taken 95 times.
✓ Branch 1 (29→31) taken 7 times.
|
102 | if (op == ShiftExprNode::ShiftOp::OP_SHIFT_LEFT) |
313 |
1/2✓ Branch 0 (30→41) taken 95 times.
✗ Branch 1 (30→68) not taken.
|
95 | currentResult = opRuleManager.getShiftLeftResultType(node, currentResult, operandResult, i); |
314 |
1/2✓ Branch 0 (31→32) taken 7 times.
✗ Branch 1 (31→33) not taken.
|
7 | else if (op == ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT) |
315 |
1/2✓ Branch 0 (32→41) taken 7 times.
✗ Branch 1 (32→68) not taken.
|
7 | currentResult = opRuleManager.getShiftRightResultType(node, currentResult, operandResult, i); |
316 | else | ||
317 | − | throw CompilerError(UNHANDLED_BRANCH, "ShiftExpr fall-through"); // GCOV_EXCL_LINE | |
318 | |||
319 | // Push the new item and pop the old one on the other side of the queue | ||
320 |
1/2✓ Branch 0 (41→42) taken 102 times.
✗ Branch 1 (41→68) not taken.
|
102 | node->opQueue.emplace(op, currentResult.type); |
321 | 102 | node->opQueue.pop(); | |
322 | } | ||
323 | |||
324 |
1/2✓ Branch 0 (46→47) taken 62 times.
✗ Branch 1 (46→69) not taken.
|
62 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
325 |
1/2✓ Branch 0 (47→48) taken 62 times.
✗ Branch 1 (47→69) not taken.
|
62 | return currentResult; |
326 | } | ||
327 | |||
328 | 70760 | std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) { | |
329 | // Check if at least one additive operator is applied | ||
330 |
2/2✓ Branch 0 (3→4) taken 66919 times.
✓ Branch 1 (3→7) taken 3841 times.
|
70760 | if (node->operands.size() == 1) |
331 |
2/2✓ Branch 0 (5→6) taken 66909 times.
✓ Branch 1 (5→69) taken 10 times.
|
66919 | return visit(node->operands.front()); |
332 | |||
333 | // Visit leftmost operand | ||
334 |
2/4✓ Branch 0 (8→9) taken 3841 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 3841 times.
✗ Branch 3 (9→51) not taken.
|
3841 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
335 |
2/8✓ Branch 0 (11→12) taken 3841 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 3841 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→54) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→54) not taken.
|
3841 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
336 | |||
337 | // Loop through remaining operands | ||
338 |
2/2✓ Branch 0 (45→18) taken 4388 times.
✓ Branch 1 (45→46) taken 3840 times.
|
8228 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
339 |
2/4✓ Branch 0 (19→20) taken 4388 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 4388 times.
✗ Branch 3 (20→55) not taken.
|
4388 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
340 |
2/8✓ Branch 0 (22→23) taken 4388 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 4388 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→58) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→58) not taken.
|
4388 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
341 | |||
342 | // Check operator | ||
343 | 4388 | const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first; | |
344 |
2/2✓ Branch 0 (29→30) taken 2638 times.
✓ Branch 1 (29→31) taken 1750 times.
|
4388 | if (op == AdditiveExprNode::AdditiveOp::OP_PLUS) |
345 |
2/2✓ Branch 0 (30→41) taken 2637 times.
✓ Branch 1 (30→68) taken 1 times.
|
2638 | currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i); |
346 |
1/2✓ Branch 0 (31→32) taken 1750 times.
✗ Branch 1 (31→33) not taken.
|
1750 | else if (op == AdditiveExprNode::AdditiveOp::OP_MINUS) |
347 |
1/2✓ Branch 0 (32→41) taken 1750 times.
✗ Branch 1 (32→68) not taken.
|
1750 | currentResult = opRuleManager.getMinusResultType(node, currentResult, operandResult, i); |
348 | else | ||
349 | − | throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE | |
350 | |||
351 | // Push the new item and pop the old one on the other side of the queue | ||
352 |
1/2✓ Branch 0 (41→42) taken 4387 times.
✗ Branch 1 (41→68) not taken.
|
4387 | node->opQueue.emplace(op, currentResult.type); |
353 | 4387 | node->opQueue.pop(); | |
354 | } | ||
355 | |||
356 |
1/2✓ Branch 0 (46→47) taken 3840 times.
✗ Branch 1 (46→69) not taken.
|
3840 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
357 |
1/2✓ Branch 0 (47→48) taken 3840 times.
✗ Branch 1 (47→69) not taken.
|
3840 | return currentResult; |
358 | } | ||
359 | |||
360 | 75148 | std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) { | |
361 | // Check if at least one multiplicative operator is applied | ||
362 |
2/2✓ Branch 0 (3→4) taken 74323 times.
✓ Branch 1 (3→7) taken 825 times.
|
75148 | if (node->operands.size() == 1) |
363 |
2/2✓ Branch 0 (5→6) taken 74314 times.
✓ Branch 1 (5→71) taken 9 times.
|
74323 | return visit(node->operands.front()); |
364 | |||
365 | // Visit leftmost operand | ||
366 |
2/4✓ Branch 0 (8→9) taken 825 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 825 times.
✗ Branch 3 (9→53) not taken.
|
825 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
367 |
2/8✓ Branch 0 (11→12) taken 825 times.
✗ Branch 1 (11→71) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 825 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→56) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→56) not taken.
|
825 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
368 | // Loop through remaining operands | ||
369 |
2/2✓ Branch 0 (47→18) taken 849 times.
✓ Branch 1 (47→48) taken 824 times.
|
1673 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
370 |
2/4✓ Branch 0 (19→20) taken 849 times.
✗ Branch 1 (19→59) not taken.
✓ Branch 2 (20→21) taken 849 times.
✗ Branch 3 (20→57) not taken.
|
849 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
371 |
2/8✓ Branch 0 (22→23) taken 849 times.
✗ Branch 1 (22→70) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 849 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→60) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→60) not taken.
|
849 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
372 | |||
373 | // Check operator | ||
374 | 849 | const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first; | |
375 |
2/2✓ Branch 0 (29→30) taken 704 times.
✓ Branch 1 (29→31) taken 145 times.
|
849 | if (op == MultiplicativeExprNode::MultiplicativeOp::OP_MUL) |
376 |
2/2✓ Branch 0 (30→43) taken 703 times.
✓ Branch 1 (30→70) taken 1 times.
|
704 | currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i); |
377 |
2/2✓ Branch 0 (31→32) taken 135 times.
✓ Branch 1 (31→33) taken 10 times.
|
145 | else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_DIV) |
378 |
1/2✓ Branch 0 (32→43) taken 135 times.
✗ Branch 1 (32→70) not taken.
|
135 | currentResult = opRuleManager.getDivResultType(node, currentResult, operandResult, i); |
379 |
1/2✓ Branch 0 (33→34) taken 10 times.
✗ Branch 1 (33→35) not taken.
|
10 | else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_REM) |
380 |
1/2✓ Branch 0 (34→43) taken 10 times.
✗ Branch 1 (34→70) not taken.
|
10 | currentResult = OpRuleManager::getRemResultType(node, currentResult, operandResult); |
381 | else | ||
382 | − | throw CompilerError(UNHANDLED_BRANCH, "Multiplicative fall-through"); // GCOV_EXCL_LINE | |
383 | |||
384 | // Push the new item and pop the old one on the other side of the queue | ||
385 |
1/2✓ Branch 0 (43→44) taken 848 times.
✗ Branch 1 (43→70) not taken.
|
848 | node->opQueue.emplace(op, currentResult.type); |
386 | 848 | node->opQueue.pop(); | |
387 | } | ||
388 | |||
389 |
1/2✓ Branch 0 (48→49) taken 824 times.
✗ Branch 1 (48→71) not taken.
|
824 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
390 |
1/2✓ Branch 0 (49→50) taken 824 times.
✗ Branch 1 (49→71) not taken.
|
824 | return currentResult; |
391 | } | ||
392 | |||
393 | 75997 | std::any TypeChecker::visitCastExpr(CastExprNode *node) { | |
394 | // Check if cast is applied | ||
395 |
2/2✓ Branch 0 (2→3) taken 74172 times.
✓ Branch 1 (2→5) taken 1825 times.
|
75997 | if (!node->isCast) |
396 |
2/2✓ Branch 0 (3→4) taken 74163 times.
✓ Branch 1 (3→65) taken 9 times.
|
74172 | return visit(node->prefixUnaryExpr); |
397 | |||
398 | // Visit destination type | ||
399 |
2/4✓ Branch 0 (5→6) taken 1825 times.
✗ Branch 1 (5→49) not taken.
✓ Branch 2 (6→7) taken 1825 times.
✗ Branch 3 (6→47) not taken.
|
1825 | const auto dstType = std::any_cast<QualType>(visit(node->dataType)); |
400 |
2/8✓ Branch 0 (8→9) taken 1825 times.
✗ Branch 1 (8→65) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 1825 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→50) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→50) not taken.
|
1825 | HANDLE_UNRESOLVED_TYPE_ER(dstType) |
401 | // Visit source type | ||
402 |
2/4✓ Branch 0 (14→15) taken 1825 times.
✗ Branch 1 (14→53) not taken.
✓ Branch 2 (15→16) taken 1825 times.
✗ Branch 3 (15→51) not taken.
|
1825 | const auto src = std::any_cast<ExprResult>(visit(node->assignExpr)); |
403 |
2/8✓ Branch 0 (17→18) taken 1825 times.
✗ Branch 1 (17→65) not taken.
✗ Branch 2 (18→19) not taken.
✓ Branch 3 (18→23) taken 1825 times.
✗ Branch 4 (19→20) not taken.
✗ Branch 5 (19→54) not taken.
✗ Branch 6 (20→21) not taken.
✗ Branch 7 (20→54) not taken.
|
1825 | HANDLE_UNRESOLVED_TYPE_ER(src.type) |
404 | |||
405 | // Check for identity cast | ||
406 |
3/4✓ Branch 0 (23→24) taken 1825 times.
✗ Branch 1 (23→65) not taken.
✓ Branch 2 (24→25) taken 227 times.
✓ Branch 3 (24→34) taken 1598 times.
|
1825 | if (src.type == dstType) { |
407 |
2/4✓ Branch 0 (27→28) taken 227 times.
✗ Branch 1 (27→57) not taken.
✓ Branch 2 (28→29) taken 227 times.
✗ Branch 3 (28→55) not taken.
|
227 | const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified."); |
408 |
1/2✓ Branch 0 (31→32) taken 227 times.
✗ Branch 1 (31→61) not taken.
|
227 | sourceFile->compilerOutput.warnings.push_back(warning); |
409 | 227 | } | |
410 | |||
411 | // Get result type | ||
412 |
1/2✓ Branch 0 (34→35) taken 1825 times.
✗ Branch 1 (34→65) not taken.
|
1825 | const QualType resultType = opRuleManager.getCastResultType(node, dstType, src); |
413 | |||
414 |
1/2✓ Branch 0 (35→36) taken 1825 times.
✗ Branch 1 (35→65) not taken.
|
1825 | const bool typesMatch = dstType.matches(src.type, false, true, true); |
415 |
1/2✓ Branch 0 (36→37) taken 1825 times.
✗ Branch 1 (36→65) not taken.
|
1825 | const bool sameContainerType = src.type.isSameContainerTypeAs(dstType); |
416 |
4/4✓ Branch 0 (37→38) taken 1598 times.
✓ Branch 1 (37→39) taken 227 times.
✓ Branch 2 (38→39) taken 117 times.
✓ Branch 3 (38→40) taken 1481 times.
|
1825 | SymbolTableEntry *entry = typesMatch || sameContainerType ? src.entry : nullptr; |
417 |
2/4✓ Branch 0 (41→42) taken 1825 times.
✗ Branch 1 (41→64) not taken.
✓ Branch 2 (42→43) taken 1825 times.
✗ Branch 3 (42→64) not taken.
|
1825 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry}; |
418 | } | ||
419 | |||
420 | 80803 | std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { | |
421 | // If no operator is applied, simply visit the postfix unary expression | ||
422 |
2/2✓ Branch 0 (2→3) taken 79809 times.
✓ Branch 1 (2→5) taken 994 times.
|
80803 | if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE) |
423 |
2/2✓ Branch 0 (3→4) taken 79801 times.
✓ Branch 1 (3→78) taken 8 times.
|
79809 | return visit(node->postfixUnaryExpr); |
424 | |||
425 | // Visit the right side | ||
426 | 994 | PrefixUnaryExprNode *rhsNode = node->prefixUnaryExpr; | |
427 |
2/4✓ Branch 0 (5→6) taken 994 times.
✗ Branch 1 (5→57) not taken.
✓ Branch 2 (6→7) taken 994 times.
✗ Branch 3 (6→55) not taken.
|
994 | auto operand = std::any_cast<ExprResult>(visit(rhsNode)); |
428 | 994 | auto [operandType, operandEntry] = operand; | |
429 |
5/8✓ Branch 0 (8→9) taken 994 times.
✗ Branch 1 (8→78) not taken.
✓ Branch 2 (9→10) taken 1 times.
✓ Branch 3 (9→14) taken 993 times.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→58) not taken.
✓ Branch 6 (11→12) taken 1 times.
✗ Branch 7 (11→58) not taken.
|
994 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
430 | // Determine action, based on the given operator | ||
431 |
7/8✓ Branch 0 (14→15) taken 16 times.
✓ Branch 1 (14→17) taken 19 times.
✓ Branch 2 (14→25) taken 8 times.
✓ Branch 3 (14→33) taken 688 times.
✓ Branch 4 (14→35) taken 1 times.
✓ Branch 5 (14→37) taken 181 times.
✓ Branch 6 (14→39) taken 80 times.
✗ Branch 7 (14→41) not taken.
|
993 | switch (node->op) { |
432 | 16 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS: | |
433 |
1/2✓ Branch 0 (15→16) taken 16 times.
✗ Branch 1 (15→59) not taken.
|
16 | operandType = OpRuleManager::getPrefixMinusResultType(node, operand); |
434 | 16 | break; | |
435 | 19 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_PLUS_PLUS: | |
436 |
1/2✓ Branch 0 (17→18) taken 19 times.
✗ Branch 1 (17→60) not taken.
|
19 | operandType = opRuleManager.getPrefixPlusPlusResultType(node, operand); |
437 | |||
438 |
2/2✓ Branch 0 (18→19) taken 16 times.
✓ Branch 1 (18→24) taken 3 times.
|
19 | if (operandEntry) { |
439 | // In case the lhs is captured, notify the capture about the write access | ||
440 |
2/4✓ Branch 0 (19→20) taken 16 times.
✗ Branch 1 (19→78) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→22) taken 16 times.
|
16 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
441 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
442 | |||
443 | // Update the state of the variable | ||
444 |
1/2✓ Branch 0 (22→23) taken 16 times.
✗ Branch 1 (22→61) not taken.
|
16 | operandEntry->updateState(INITIALIZED, node); |
445 | } | ||
446 | |||
447 | 19 | break; | |
448 | 8 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS_MINUS: | |
449 |
2/2✓ Branch 0 (25→26) taken 7 times.
✓ Branch 1 (25→62) taken 1 times.
|
8 | operandType = opRuleManager.getPrefixMinusMinusResultType(node, operand); |
450 | |||
451 |
2/2✓ Branch 0 (26→27) taken 4 times.
✓ Branch 1 (26→32) taken 3 times.
|
7 | if (operandEntry) { |
452 | // In case the lhs is captured, notify the capture about the write access | ||
453 |
2/4✓ Branch 0 (27→28) taken 4 times.
✗ Branch 1 (27→78) not taken.
✗ Branch 2 (28→29) not taken.
✓ Branch 3 (28→30) taken 4 times.
|
4 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
454 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
455 | |||
456 | // Update the state of the variable | ||
457 |
1/2✓ Branch 0 (30→31) taken 4 times.
✗ Branch 1 (30→63) not taken.
|
4 | operandEntry->updateState(INITIALIZED, node); |
458 | } | ||
459 | |||
460 | 7 | break; | |
461 | 688 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT: | |
462 |
1/2✓ Branch 0 (33→34) taken 688 times.
✗ Branch 1 (33→64) not taken.
|
688 | operandType = OpRuleManager::getPrefixNotResultType(node, operand); |
463 | 688 | break; | |
464 | 1 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_BITWISE_NOT: | |
465 |
1/2✓ Branch 0 (35→36) taken 1 times.
✗ Branch 1 (35→65) not taken.
|
1 | operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operand); |
466 | 1 | break; | |
467 | 181 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE: | |
468 |
1/2✓ Branch 0 (37→38) taken 181 times.
✗ Branch 1 (37→66) not taken.
|
181 | operandType = OpRuleManager::getPrefixMulResultType(node, operand); |
469 | 181 | break; | |
470 | 80 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF: | |
471 |
1/2✓ Branch 0 (39→40) taken 80 times.
✗ Branch 1 (39→67) not taken.
|
80 | operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand); |
472 | 80 | break; | |
473 | − | default: // GCOV_EXCL_LINE | |
474 | − | throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
475 | } | ||
476 | |||
477 |
2/4✓ Branch 0 (49→50) taken 992 times.
✗ Branch 1 (49→77) not taken.
✓ Branch 2 (50→51) taken 992 times.
✗ Branch 3 (50→77) not taken.
|
992 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
478 | } | ||
479 | |||
480 | 99666 | std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { | |
481 | // If no operator is applied, simply visit the atomic expression | ||
482 |
2/2✓ Branch 0 (2→3) taken 79809 times.
✓ Branch 1 (2→5) taken 19857 times.
|
99666 | if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE) |
483 |
2/2✓ Branch 0 (3→4) taken 79802 times.
✓ Branch 1 (3→316) taken 7 times.
|
79809 | return visit(node->atomicExpr); |
484 | |||
485 | // Visit left side | ||
486 | 19857 | PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr; | |
487 |
2/4✓ Branch 0 (5→6) taken 19857 times.
✗ Branch 1 (5→211) not taken.
✓ Branch 2 (6→7) taken 19857 times.
✗ Branch 3 (6→209) not taken.
|
19857 | auto operand = std::any_cast<ExprResult>(visit(lhsNode)); |
488 | 19857 | auto [operandType, operandEntry] = operand; | |
489 |
5/8✓ Branch 0 (8→9) taken 19857 times.
✗ Branch 1 (8→316) not taken.
✓ Branch 2 (9→10) taken 6 times.
✓ Branch 3 (9→14) taken 19851 times.
✓ Branch 4 (10→11) taken 6 times.
✗ Branch 5 (10→212) not taken.
✓ Branch 6 (11→12) taken 6 times.
✗ Branch 7 (11→212) not taken.
|
19857 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
490 | |||
491 |
4/5✓ Branch 0 (14→15) taken 3111 times.
✓ Branch 1 (14→101) taken 14703 times.
✓ Branch 2 (14→159) taken 1653 times.
✓ Branch 3 (14→167) taken 384 times.
✗ Branch 4 (14→175) not taken.
|
19851 | switch (node->op) { |
492 | 3111 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: { | |
493 | // Visit index assignment | ||
494 | 3111 | AssignExprNode *indexAssignExpr = node->subscriptIndexExpr; | |
495 |
2/4✓ Branch 0 (15→16) taken 3111 times.
✗ Branch 1 (15→215) not taken.
✓ Branch 2 (16→17) taken 3111 times.
✗ Branch 3 (16→213) not taken.
|
3111 | const auto index = std::any_cast<ExprResult>(visit(indexAssignExpr)); |
496 |
2/8✓ Branch 0 (18→19) taken 3111 times.
✗ Branch 1 (18→258) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 3111 times.
✗ Branch 4 (20→21) not taken.
✗ Branch 5 (20→216) not taken.
✗ Branch 6 (21→22) not taken.
✗ Branch 7 (21→216) not taken.
|
3111 | HANDLE_UNRESOLVED_TYPE_ER(index.type) |
497 | |||
498 | // Check is there is an overloaded operator function available, if yes accept it | ||
499 |
1/2✓ Branch 0 (24→25) taken 3111 times.
✗ Branch 1 (24→217) not taken.
|
3111 | const auto [type, _] = opRuleManager.isOperatorOverloadingFctAvailable<2>(node, OP_FCT_SUBSCRIPT, {operand, index}, 0); |
500 |
3/4✓ Branch 0 (25→26) taken 3111 times.
✗ Branch 1 (25→258) not taken.
✓ Branch 2 (26→27) taken 111 times.
✓ Branch 3 (26→28) taken 3000 times.
|
3111 | if (!type.is(TY_INVALID)) { |
501 | 111 | operandType = type; | |
502 | 3109 | break; | |
503 | } | ||
504 | |||
505 |
1/2✓ Branch 0 (28→29) taken 3000 times.
✗ Branch 1 (28→218) not taken.
|
3000 | operandType = operandType.removeReferenceWrapper(); |
506 | |||
507 | // Check if the index is of the right type | ||
508 |
3/4✓ Branch 0 (29→30) taken 3000 times.
✗ Branch 1 (29→219) not taken.
✓ Branch 2 (30→31) taken 1 times.
✓ Branch 3 (30→41) taken 2999 times.
|
3000 | if (!index.type.isOneOf({TY_INT, TY_LONG})) |
509 |
4/8✓ Branch 0 (33→34) taken 1 times.
✗ Branch 1 (33→222) not taken.
✓ Branch 2 (34→35) taken 1 times.
✗ Branch 3 (34→220) not taken.
✓ Branch 4 (37→38) taken 1 times.
✗ Branch 5 (37→226) not taken.
✓ Branch 6 (38→39) taken 1 times.
✗ Branch 7 (38→226) not taken.
|
3 | SOFT_ERROR_ER(node, ARRAY_INDEX_NOT_INT_OR_LONG, "Array index must be of type int or long") |
510 | |||
511 | // Check if we can apply the subscript operator on the lhs type | ||
512 |
2/4✓ Branch 0 (41→42) taken 2999 times.
✗ Branch 1 (41→227) not taken.
✗ Branch 2 (42→43) not taken.
✓ Branch 3 (42→52) taken 2999 times.
|
2999 | if (!operandType.isOneOf({TY_ARRAY, TY_PTR, TY_STRING})) |
513 | ✗ | SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE, | |
514 | "Can only apply subscript operator on array type, got " + operandType.getName(true)) | ||
515 | |||
516 | // Check if we have an unsafe operation | ||
517 |
6/10✓ Branch 0 (52→53) taken 2999 times.
✗ Branch 1 (52→258) not taken.
✓ Branch 2 (53→54) taken 2155 times.
✓ Branch 3 (53→57) taken 844 times.
✓ Branch 4 (54→55) taken 2155 times.
✗ Branch 5 (54→258) not taken.
✗ Branch 6 (55→56) not taken.
✓ Branch 7 (55→57) taken 2155 times.
✗ Branch 8 (58→59) not taken.
✓ Branch 9 (58→69) taken 2999 times.
|
2999 | if (operandType.isPtr() && !currentScope->doesAllowUnsafeOperations()) |
518 | ✗ | SOFT_ERROR_ER( | |
519 | node, UNSAFE_OPERATION_IN_SAFE_CONTEXT, | ||
520 | "The subscript operator on pointers is an unsafe operation. Use unsafe blocks if you know what you are doing.") | ||
521 | |||
522 | // In case of compile time index value and known array size, perform a compile time out-of-bounds check | ||
523 |
11/14✓ Branch 0 (69→70) taken 2999 times.
✗ Branch 1 (69→258) not taken.
✓ Branch 2 (70→71) taken 140 times.
✓ Branch 3 (70→76) taken 2859 times.
✓ Branch 4 (71→72) taken 140 times.
✗ Branch 5 (71→258) not taken.
✓ Branch 6 (72→73) taken 99 times.
✓ Branch 7 (72→76) taken 41 times.
✓ Branch 8 (73→74) taken 99 times.
✗ Branch 9 (73→258) not taken.
✓ Branch 10 (74→75) taken 34 times.
✓ Branch 11 (74→76) taken 65 times.
✓ Branch 12 (77→78) taken 34 times.
✓ Branch 13 (77→96) taken 2965 times.
|
2999 | if (operandType.isArray() && operandType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) { |
524 |
1/2✓ Branch 0 (78→79) taken 34 times.
✗ Branch 1 (78→258) not taken.
|
34 | const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue; |
525 |
1/2✓ Branch 0 (79→80) taken 34 times.
✗ Branch 1 (79→258) not taken.
|
34 | const unsigned int constSize = operandType.getArraySize(); |
526 | // Check if we are accessing out-of-bounds memory | ||
527 |
2/2✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→96) taken 33 times.
|
34 | if (constIndex >= static_cast<int32_t>(constSize)) { |
528 | 1 | const std::string idxStr = std::to_string(constIndex); | |
529 | 1 | const std::string sizeStr = std::to_string(constSize); | |
530 |
6/12✓ Branch 0 (83→84) taken 1 times.
✗ Branch 1 (83→248) not taken.
✓ Branch 2 (84→85) taken 1 times.
✗ Branch 3 (84→246) not taken.
✓ Branch 4 (85→86) taken 1 times.
✗ Branch 5 (85→244) not taken.
✓ Branch 6 (86→87) taken 1 times.
✗ Branch 7 (86→242) not taken.
✓ Branch 8 (90→91) taken 1 times.
✗ Branch 9 (90→251) not taken.
✓ Branch 10 (91→92) taken 1 times.
✗ Branch 11 (91→251) not taken.
|
1 | SOFT_ERROR_ER(node, ARRAY_INDEX_OUT_OF_BOUNDS, |
531 | "You are trying to access element with index " + idxStr + " of an array with size " + sizeStr) | ||
532 | 1 | } | |
533 | } | ||
534 | |||
535 | // Get item type | ||
536 |
1/2✓ Branch 0 (96→97) taken 2998 times.
✗ Branch 1 (96→257) not taken.
|
2998 | operandType = operandType.getContained(); |
537 | |||
538 | // Remove heap qualifier | ||
539 | 2998 | operandType.getQualifiers().isHeap = false; | |
540 | |||
541 | 2998 | break; | |
542 | } | ||
543 | 14703 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: { | |
544 | 14703 | const std::string &fieldName = node->identifier; | |
545 | |||
546 | // Check if lhs is enum or strobj | ||
547 |
1/2✓ Branch 0 (101→102) taken 14703 times.
✗ Branch 1 (101→286) not taken.
|
14703 | const QualType lhsBaseTy = operandType.autoDeReference(); |
548 |
3/4✓ Branch 0 (102→103) taken 14703 times.
✗ Branch 1 (102→286) not taken.
✓ Branch 2 (103→104) taken 1 times.
✓ Branch 3 (103→113) taken 14702 times.
|
14703 | if (!lhsBaseTy.is(TY_STRUCT)) |
549 |
5/10✓ Branch 0 (104→105) taken 1 times.
✗ Branch 1 (104→263) not taken.
✓ Branch 2 (105→106) taken 1 times.
✗ Branch 3 (105→261) not taken.
✓ Branch 4 (106→107) taken 1 times.
✗ Branch 5 (106→259) not taken.
✓ Branch 6 (109→110) taken 1 times.
✗ Branch 7 (109→265) not taken.
✓ Branch 8 (110→111) taken 1 times.
✗ Branch 9 (110→265) not taken.
|
1 | SOFT_ERROR_ER(node, INVALID_MEMBER_ACCESS, "Cannot apply member access operator on " + operandType.getName(false)) |
550 | |||
551 | // Retrieve registry entry | ||
552 |
1/2✓ Branch 0 (113→114) taken 14702 times.
✗ Branch 1 (113→286) not taken.
|
14702 | const std::string &structName = lhsBaseTy.getSubType(); |
553 |
1/2✓ Branch 0 (114→115) taken 14702 times.
✗ Branch 1 (114→286) not taken.
|
14702 | Scope *structScope = lhsBaseTy.getBodyScope(); |
554 | |||
555 | // If we only have the generic struct scope, lookup the concrete manifestation scope | ||
556 |
2/2✓ Branch 0 (115→116) taken 78 times.
✓ Branch 1 (115→120) taken 14624 times.
|
14702 | if (structScope->isGenericScope) { |
557 |
1/2✓ Branch 0 (116→117) taken 78 times.
✗ Branch 1 (116→286) not taken.
|
78 | const Struct *spiceStruct = lhsBaseTy.getStruct(node); |
558 |
1/2✗ Branch 0 (117→118) not taken.
✓ Branch 1 (117→119) taken 78 times.
|
78 | assert(spiceStruct != nullptr); |
559 | 78 | structScope = spiceStruct->scope; | |
560 | } | ||
561 |
1/2✗ Branch 0 (120→121) not taken.
✓ Branch 1 (120→122) taken 14702 times.
|
14702 | assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope |
562 | |||
563 | // Get accessed field | ||
564 | 14702 | std::vector<size_t> indexPath; | |
565 |
1/2✓ Branch 0 (122→123) taken 14702 times.
✗ Branch 1 (122→284) not taken.
|
14702 | SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath); |
566 |
2/2✓ Branch 0 (123→124) taken 2 times.
✓ Branch 1 (123→135) taken 14700 times.
|
14702 | if (!memberEntry) |
567 |
6/12✓ Branch 0 (124→125) taken 2 times.
✗ Branch 1 (124→272) not taken.
✓ Branch 2 (125→126) taken 2 times.
✗ Branch 3 (125→270) not taken.
✓ Branch 4 (126→127) taken 2 times.
✗ Branch 5 (126→268) not taken.
✓ Branch 6 (127→128) taken 2 times.
✗ Branch 7 (127→266) not taken.
✓ Branch 8 (131→132) taken 2 times.
✗ Branch 9 (131→275) not taken.
✓ Branch 10 (132→133) taken 2 times.
✗ Branch 11 (132→275) not taken.
|
2 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Field '" + node->identifier + "' not found in struct " + structName) |
568 |
1/2✓ Branch 0 (135→136) taken 14700 times.
✗ Branch 1 (135→284) not taken.
|
14700 | const QualType memberType = memberEntry->getQualType(); |
569 | |||
570 | // Check for insufficient visibility | ||
571 |
8/14✓ Branch 0 (136→137) taken 14700 times.
✗ Branch 1 (136→276) not taken.
✓ Branch 2 (137→138) taken 74 times.
✓ Branch 3 (137→143) taken 14626 times.
✓ Branch 4 (138→139) taken 74 times.
✗ Branch 5 (138→276) not taken.
✓ Branch 6 (139→140) taken 74 times.
✗ Branch 7 (139→276) not taken.
✓ Branch 8 (140→141) taken 74 times.
✗ Branch 9 (140→276) not taken.
✗ Branch 10 (141→142) not taken.
✓ Branch 11 (141→143) taken 74 times.
✗ Branch 12 (144→145) not taken.
✓ Branch 13 (144→154) taken 14700 times.
|
14700 | if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().getBase().isPublic()) |
572 | ✗ | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access field '" + fieldName + "' due to its private visibility") | |
573 | |||
574 | // Set field to used | ||
575 | 14700 | memberEntry->used = true; | |
576 | |||
577 | // Overwrite type and entry of left side with member type and entry | ||
578 | 14700 | operandType = memberType; | |
579 | 14700 | operandEntry = memberEntry; | |
580 | 14700 | break; | |
581 |
2/2✓ Branch 0 (156→157) taken 2 times.
✓ Branch 1 (156→158) taken 14700 times.
|
14702 | } |
582 | 1653 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: { | |
583 |
2/2✓ Branch 0 (159→160) taken 1652 times.
✓ Branch 1 (159→287) taken 1 times.
|
1653 | operandType = opRuleManager.getPostfixPlusPlusResultType(node, operand, 0).type; |
584 | |||
585 |
2/2✓ Branch 0 (160→161) taken 1648 times.
✓ Branch 1 (160→166) taken 4 times.
|
1652 | if (operandEntry) { |
586 | // In case the lhs is captured, notify the capture about the write access | ||
587 |
3/4✓ Branch 0 (161→162) taken 1648 times.
✗ Branch 1 (161→316) not taken.
✓ Branch 2 (162→163) taken 4 times.
✓ Branch 3 (162→164) taken 1644 times.
|
1648 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
588 |
1/2✓ Branch 0 (163→164) taken 4 times.
✗ Branch 1 (163→316) not taken.
|
4 | lhsCapture->setAccessType(READ_WRITE); |
589 | |||
590 | // Update the state of the variable | ||
591 |
1/2✓ Branch 0 (164→165) taken 1648 times.
✗ Branch 1 (164→288) not taken.
|
1648 | operandEntry->updateState(INITIALIZED, node); |
592 | } | ||
593 | |||
594 | 1652 | break; | |
595 | } | ||
596 | 384 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: { | |
597 |
1/2✓ Branch 0 (167→168) taken 384 times.
✗ Branch 1 (167→289) not taken.
|
384 | operandType = opRuleManager.getPostfixMinusMinusResultType(node, operand, 0).type; |
598 | |||
599 |
2/2✓ Branch 0 (168→169) taken 380 times.
✓ Branch 1 (168→174) taken 4 times.
|
384 | if (operandEntry) { |
600 | // In case the lhs is captured, notify the capture about the write access | ||
601 |
2/4✓ Branch 0 (169→170) taken 380 times.
✗ Branch 1 (169→316) not taken.
✗ Branch 2 (170→171) not taken.
✓ Branch 3 (170→172) taken 380 times.
|
380 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
602 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
603 | |||
604 | // Update the state of the variable | ||
605 |
1/2✓ Branch 0 (172→173) taken 380 times.
✗ Branch 1 (172→290) not taken.
|
380 | operandEntry->updateState(INITIALIZED, node); |
606 | } | ||
607 | |||
608 | 384 | break; | |
609 | } | ||
610 | − | default: // GCOV_EXCL_LINE | |
611 | − | throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
612 | } | ||
613 | |||
614 |
2/4✓ Branch 0 (183→184) taken 19845 times.
✗ Branch 1 (183→316) not taken.
✗ Branch 2 (184→185) not taken.
✓ Branch 3 (184→203) taken 19845 times.
|
19845 | if (operandType.is(TY_INVALID)) { |
615 | ✗ | const std::string &varName = operandEntry ? operandEntry->name : ""; | |
616 | ✗ | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Variable '" + varName + "' was referenced before declared") | |
617 | ✗ | } | |
618 | |||
619 |
2/4✓ Branch 0 (203→204) taken 19845 times.
✗ Branch 1 (203→315) not taken.
✓ Branch 2 (204→205) taken 19845 times.
✗ Branch 3 (204→315) not taken.
|
19845 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
620 | } | ||
621 | |||
622 | 79809 | std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) { | |
623 | // Check if constant | ||
624 |
2/2✓ Branch 0 (2→3) taken 15568 times.
✓ Branch 1 (2→5) taken 64241 times.
|
79809 | if (node->constant) |
625 |
1/2✓ Branch 0 (3→4) taken 15568 times.
✗ Branch 1 (3→219) not taken.
|
15568 | return visit(node->constant); |
626 | |||
627 | // Check if value | ||
628 |
2/2✓ Branch 0 (5→6) taken 15407 times.
✓ Branch 1 (5→8) taken 48834 times.
|
64241 | if (node->value) |
629 |
2/2✓ Branch 0 (6→7) taken 15403 times.
✓ Branch 1 (6→219) taken 4 times.
|
15407 | return visit(node->value); |
630 | |||
631 | // Check for builtin calls | ||
632 |
2/2✓ Branch 0 (8→9) taken 1595 times.
✓ Branch 1 (8→11) taken 47239 times.
|
48834 | if (node->builtinCall) |
633 |
1/2✓ Branch 0 (9→10) taken 1595 times.
✗ Branch 1 (9→219) not taken.
|
1595 | return visit(node->builtinCall); |
634 | |||
635 | // Check for assign expression within parentheses | ||
636 |
2/2✓ Branch 0 (11→12) taken 525 times.
✓ Branch 1 (11→14) taken 46714 times.
|
47239 | if (node->assignExpr) |
637 |
2/2✓ Branch 0 (12→13) taken 522 times.
✓ Branch 1 (12→219) taken 3 times.
|
525 | return visit(node->assignExpr); |
638 | |||
639 | // Identifier (local or global variable access) | ||
640 |
1/2✗ Branch 0 (15→16) not taken.
✓ Branch 1 (15→17) taken 46714 times.
|
46714 | assert(!node->fqIdentifier.empty()); |
641 | |||
642 |
1/2✓ Branch 0 (17→18) taken 46714 times.
✗ Branch 1 (17→219) not taken.
|
46714 | auto &[entry, accessScope, capture] = node->data.at(manIdx); |
643 | 46714 | accessScope = currentScope; | |
644 | |||
645 | // Check if a local or global variable can be found by searching for the name | ||
646 |
2/2✓ Branch 0 (19→20) taken 46471 times.
✓ Branch 1 (19→25) taken 243 times.
|
46714 | if (node->identifierFragments.size() == 1) |
647 | 92942 | entry = accessScope->lookup(node->identifierFragments.back()); | |
648 | |||
649 | // If no local or global was found, search in the name registry | ||
650 |
2/2✓ Branch 0 (25→26) taken 319 times.
✓ Branch 1 (25→38) taken 46395 times.
|
46714 | if (!entry) { |
651 |
1/2✓ Branch 0 (26→27) taken 319 times.
✗ Branch 1 (26→219) not taken.
|
319 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier); |
652 |
2/2✓ Branch 0 (27→28) taken 1 times.
✓ Branch 1 (27→37) taken 318 times.
|
319 | if (!registryEntry) |
653 |
5/10✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→167) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→165) not taken.
✓ Branch 4 (30→31) taken 1 times.
✗ Branch 5 (30→163) not taken.
✓ Branch 6 (33→34) taken 1 times.
✗ Branch 7 (33→169) not taken.
✓ Branch 8 (34→35) taken 1 times.
✗ Branch 9 (34→169) not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found") |
654 | 318 | entry = registryEntry->targetEntry; | |
655 | 318 | accessScope = registryEntry->targetScope; | |
656 | } | ||
657 |
1/2✗ Branch 0 (38→39) not taken.
✓ Branch 1 (38→40) taken 46713 times.
|
46713 | assert(entry != nullptr); |
658 | 46713 | entry->used = true; | |
659 |
1/2✓ Branch 0 (40→41) taken 46713 times.
✗ Branch 1 (40→219) not taken.
|
46713 | capture = accessScope->symbolTable.lookupCapture(entry->name); |
660 | |||
661 |
1/2✓ Branch 0 (41→42) taken 46713 times.
✗ Branch 1 (41→219) not taken.
|
46713 | const QualType varType = entry->getQualType(); |
662 |
5/8✓ Branch 0 (42→43) taken 46713 times.
✗ Branch 1 (42→219) not taken.
✓ Branch 2 (43→44) taken 9 times.
✓ Branch 3 (43→48) taken 46704 times.
✓ Branch 4 (44→45) taken 9 times.
✗ Branch 5 (44→170) not taken.
✓ Branch 6 (45→46) taken 9 times.
✗ Branch 7 (45→170) not taken.
|
46713 | HANDLE_UNRESOLVED_TYPE_ER(varType) |
663 |
3/4✓ Branch 0 (48→49) taken 46704 times.
✗ Branch 1 (48→219) not taken.
✓ Branch 2 (49→50) taken 2 times.
✓ Branch 3 (49→59) taken 46702 times.
|
46704 | if (varType.is(TY_INVALID)) |
664 |
5/10✓ Branch 0 (50→51) taken 2 times.
✗ Branch 1 (50→175) not taken.
✓ Branch 2 (51→52) taken 2 times.
✗ Branch 3 (51→173) not taken.
✓ Branch 4 (52→53) taken 2 times.
✗ Branch 5 (52→171) not taken.
✓ Branch 6 (55→56) taken 2 times.
✗ Branch 7 (55→177) not taken.
✓ Branch 8 (56→57) taken 2 times.
✗ Branch 9 (56→177) not taken.
|
2 | SOFT_ERROR_ER(node, USED_BEFORE_DECLARED, "Symbol '" + entry->name + "' was used before declared.") |
665 | |||
666 |
7/8✓ Branch 0 (59→60) taken 46702 times.
✗ Branch 1 (59→178) not taken.
✓ Branch 2 (60→61) taken 25 times.
✓ Branch 3 (60→63) taken 46677 times.
✓ Branch 4 (61→62) taken 9 times.
✓ Branch 5 (61→63) taken 16 times.
✓ Branch 6 (64→65) taken 9 times.
✓ Branch 7 (64→93) taken 46693 times.
|
46702 | if (varType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && entry->global) { |
667 | // Check if overloaded function was referenced | ||
668 |
1/2✓ Branch 0 (65→66) taken 9 times.
✗ Branch 1 (65→219) not taken.
|
9 | const std::vector<Function *> *manifestations = entry->declNode->getFctManifestations(entry->name); |
669 |
2/2✓ Branch 0 (67→68) taken 1 times.
✓ Branch 1 (67→78) taken 8 times.
|
9 | if (manifestations->size() > 1) |
670 |
4/8✓ Branch 0 (70→71) taken 1 times.
✗ Branch 1 (70→181) not taken.
✓ Branch 2 (71→72) taken 1 times.
✗ Branch 3 (71→179) not taken.
✓ Branch 4 (74→75) taken 1 times.
✗ Branch 5 (74→185) not taken.
✓ Branch 6 (75→76) taken 1 times.
✗ Branch 7 (75→185) not taken.
|
3 | SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Overloaded functions / functions with optional params cannot be referenced") |
671 |
2/2✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→91) taken 7 times.
|
8 | if (!manifestations->front()->templateTypes.empty()) |
672 |
4/8✓ Branch 0 (83→84) taken 1 times.
✗ Branch 1 (83→188) not taken.
✓ Branch 2 (84→85) taken 1 times.
✗ Branch 3 (84→186) not taken.
✓ Branch 4 (87→88) taken 1 times.
✗ Branch 5 (87→192) not taken.
✓ Branch 6 (88→89) taken 1 times.
✗ Branch 7 (88→192) not taken.
|
3 | SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Generic functions cannot be referenced") |
673 | // Set referenced function to used | ||
674 | 7 | Function *referencedFunction = manifestations->front(); | |
675 | 7 | referencedFunction->used = true; | |
676 | 7 | referencedFunction->entry->used = true; | |
677 | } | ||
678 | |||
679 | // The base type should be an extended primitive | ||
680 |
1/2✓ Branch 0 (93→94) taken 46700 times.
✗ Branch 1 (93→219) not taken.
|
46700 | const QualType baseType = varType.getBase(); |
681 |
6/10✓ Branch 0 (94→95) taken 46700 times.
✗ Branch 1 (94→219) not taken.
✓ Branch 2 (95→96) taken 2 times.
✓ Branch 3 (95→99) taken 46698 times.
✓ Branch 4 (96→97) taken 2 times.
✗ Branch 5 (96→219) not taken.
✗ Branch 6 (97→98) not taken.
✓ Branch 7 (97→99) taken 2 times.
✗ Branch 8 (100→101) not taken.
✓ Branch 9 (100→112) taken 46700 times.
|
46700 | if (!baseType.isExtendedPrimitive() && !baseType.is(TY_DYN)) |
682 | ✗ | SOFT_ERROR_ER(node, INVALID_SYMBOL_ACCESS, "A symbol of type " + varType.getName(false) + " cannot be accessed here") | |
683 | |||
684 | // Check if we have seen a 'this.' prefix, because the generator needs that | ||
685 |
6/8✓ Branch 0 (112→113) taken 1 times.
✓ Branch 1 (112→117) taken 46699 times.
✓ Branch 2 (114→115) taken 1 times.
✗ Branch 3 (114→219) not taken.
✓ Branch 4 (115→116) taken 1 times.
✗ Branch 5 (115→117) not taken.
✓ Branch 6 (118→119) taken 1 times.
✓ Branch 7 (118→128) taken 46699 times.
|
46700 | if (entry->scope->type == ScopeType::STRUCT && node->identifierFragments.front() != THIS_VARIABLE_NAME) |
686 |
5/10✓ Branch 0 (119→120) taken 1 times.
✗ Branch 1 (119→207) not taken.
✓ Branch 2 (120→121) taken 1 times.
✗ Branch 3 (120→205) not taken.
✓ Branch 4 (121→122) taken 1 times.
✗ Branch 5 (121→203) not taken.
✓ Branch 6 (124→125) taken 1 times.
✗ Branch 7 (124→209) not taken.
✓ Branch 8 (125→126) taken 1 times.
✗ Branch 9 (125→209) not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, |
687 | "The symbol '" + node->fqIdentifier + "' could not be found. Missing 'this.' prefix?") | ||
688 | |||
689 | // Ensure that the entry is public, if the symbol is imported. | ||
690 | // An exception are enum items. There it is sufficient, that the enum itself is public. | ||
691 |
7/8✓ Branch 0 (128→129) taken 46699 times.
✗ Branch 1 (128→219) not taken.
✓ Branch 2 (129→130) taken 199 times.
✓ Branch 3 (129→132) taken 46500 times.
✓ Branch 4 (130→131) taken 78 times.
✓ Branch 5 (130→132) taken 121 times.
✓ Branch 6 (133→134) taken 78 times.
✓ Branch 7 (133→147) taken 46621 times.
|
46699 | if (accessScope->isImportedBy(rootScope) && accessScope->type != ScopeType::ENUM) |
692 |
5/8✓ Branch 0 (134→135) taken 78 times.
✗ Branch 1 (134→210) not taken.
✓ Branch 2 (135→136) taken 78 times.
✗ Branch 3 (135→210) not taken.
✓ Branch 4 (136→137) taken 78 times.
✗ Branch 5 (136→210) not taken.
✓ Branch 6 (137→138) taken 1 times.
✓ Branch 7 (137→147) taken 77 times.
|
78 | if (!entry->getQualType().getBase().isPublic()) |
693 |
5/10✓ Branch 0 (138→139) taken 1 times.
✗ Branch 1 (138→215) not taken.
✓ Branch 2 (139→140) taken 1 times.
✗ Branch 3 (139→213) not taken.
✓ Branch 4 (140→141) taken 1 times.
✗ Branch 5 (140→211) not taken.
✓ Branch 6 (143→144) taken 1 times.
✗ Branch 7 (143→217) not taken.
✓ Branch 8 (144→145) taken 1 times.
✗ Branch 9 (144→217) not taken.
|
1 | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access '" + entry->name + "' due to its private visibility") |
694 | |||
695 | // For enum item access, use access scope of the enum | ||
696 |
2/2✓ Branch 0 (147→148) taken 238 times.
✓ Branch 1 (147→149) taken 46460 times.
|
46698 | if (entry->scope->type == ScopeType::ENUM) |
697 | 238 | accessScope = entry->scope; | |
698 | |||
699 | // For struct access, use access scope of the struct | ||
700 |
3/4✓ Branch 0 (149→150) taken 46698 times.
✗ Branch 1 (149→219) not taken.
✓ Branch 2 (150→151) taken 16627 times.
✓ Branch 3 (150→157) taken 30071 times.
|
46698 | if (baseType.is(TY_STRUCT)) { |
701 |
1/2✓ Branch 0 (151→152) taken 16627 times.
✗ Branch 1 (151→219) not taken.
|
16627 | const std::string &structName = baseType.getSubType(); |
702 |
1/2✓ Branch 0 (152→153) taken 16627 times.
✗ Branch 1 (152→219) not taken.
|
16627 | const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(structName); |
703 |
1/2✗ Branch 0 (153→154) not taken.
✓ Branch 1 (153→155) taken 16627 times.
|
16627 | assert(nameRegistryEntry != nullptr); |
704 | 16627 | accessScope = nameRegistryEntry->targetScope; | |
705 |
1/2✗ Branch 0 (155→156) not taken.
✓ Branch 1 (155→157) taken 16627 times.
|
16627 | assert(accessScope != nullptr); |
706 | } | ||
707 | |||
708 |
2/4✓ Branch 0 (157→158) taken 46698 times.
✗ Branch 1 (157→218) not taken.
✓ Branch 2 (158→159) taken 46698 times.
✗ Branch 3 (158→218) not taken.
|
46698 | return ExprResult{node->setEvaluatedSymbolType(varType, manIdx), entry}; |
709 | } | ||
710 | |||
711 | } // namespace spice::compiler | ||
712 |