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 | 71707 | std::any TypeChecker::visitAssignExpr(AssignExprNode *node) { | |
13 | // Check if ternary | ||
14 |
2/2✓ Branch 2 → 3 taken 65401 times.
✓ Branch 2 → 10 taken 6306 times.
|
71707 | if (node->ternaryExpr) { |
15 |
3/4✓ Branch 3 → 4 taken 65386 times.
✓ Branch 3 → 97 taken 15 times.
✓ Branch 4 → 5 taken 65386 times.
✗ Branch 4 → 95 not taken.
|
65401 | auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr)); |
16 |
1/2✓ Branch 6 → 7 taken 65386 times.
✗ Branch 6 → 98 not taken.
|
65386 | node->setEvaluatedSymbolType(result.type, manIdx); |
17 |
1/2✓ Branch 7 → 8 taken 65386 times.
✗ Branch 7 → 98 not taken.
|
65386 | return result; |
18 | } | ||
19 | |||
20 | // Check if assignment | ||
21 |
1/2✓ Branch 10 → 11 taken 6306 times.
✗ Branch 10 → 86 not taken.
|
6306 | if (node->op != AssignExprNode::AssignOp::OP_NONE) { |
22 | // Visit the right side first | ||
23 |
2/4✓ Branch 11 → 12 taken 6306 times.
✗ Branch 11 → 101 not taken.
✓ Branch 12 → 13 taken 6306 times.
✗ Branch 12 → 99 not taken.
|
6306 | auto rhs = std::any_cast<ExprResult>(visit(node->rhs)); |
24 | 6306 | auto [rhsType, rhsEntry] = rhs; | |
25 |
5/8✓ Branch 14 → 15 taken 6306 times.
✗ Branch 14 → 120 not taken.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 20 taken 6305 times.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 102 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 102 not taken.
|
6306 | HANDLE_UNRESOLVED_TYPE_ER(rhsType) |
26 | // Then visit the left side | ||
27 |
2/4✓ Branch 20 → 21 taken 6305 times.
✗ Branch 20 → 105 not taken.
✓ Branch 21 → 22 taken 6305 times.
✗ Branch 21 → 103 not taken.
|
6305 | auto lhs = std::any_cast<ExprResult>(visit(node->lhs)); |
28 | 6305 | auto [lhsType, lhsVar] = lhs; | |
29 |
5/8✓ Branch 23 → 24 taken 6305 times.
✗ Branch 23 → 120 not taken.
✓ Branch 24 → 25 taken 1 time.
✓ Branch 24 → 29 taken 6304 times.
✓ Branch 25 → 26 taken 1 time.
✗ Branch 25 → 106 not taken.
✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 106 not taken.
|
6305 | HANDLE_UNRESOLVED_TYPE_ER(lhsType) |
30 | |||
31 | // Take a look at the operator | ||
32 |
2/2✓ Branch 29 → 30 taken 5596 times.
✓ Branch 29 → 42 taken 708 times.
|
6304 | if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) { |
33 |
8/10✓ Branch 30 → 31 taken 5595 times.
✓ Branch 30 → 37 taken 1 time.
✓ Branch 31 → 32 taken 5595 times.
✗ Branch 31 → 120 not taken.
✓ Branch 32 → 33 taken 4423 times.
✓ Branch 32 → 37 taken 1172 times.
✓ Branch 34 → 35 taken 4423 times.
✗ Branch 34 → 120 not taken.
✓ Branch 35 → 36 taken 1417 times.
✓ Branch 35 → 37 taken 3006 times.
|
5596 | const bool isDecl = lhs.entry != nullptr && lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized(); |
34 |
2/2✓ Branch 38 → 39 taken 5595 times.
✓ Branch 38 → 107 taken 1 time.
|
5596 | 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 39 → 40 taken 2670 times.
✓ Branch 39 → 72 taken 2925 times.
✓ Branch 40 → 41 taken 212 times.
✓ Branch 40 → 72 taken 2458 times.
|
5595 | if (rhsEntry != nullptr && rhsEntry->anonymous) |
38 |
1/2✓ Branch 41 → 72 taken 212 times.
✗ Branch 41 → 120 not taken.
|
212 | currentScope->symbolTable.deleteAnonymous(rhsEntry->name); |
39 |
2/2✓ Branch 42 → 43 taken 252 times.
✓ Branch 42 → 45 taken 456 times.
|
708 | } else if (node->op == AssignExprNode::AssignOp::OP_PLUS_EQUAL) { |
40 |
1/2✓ Branch 43 → 44 taken 252 times.
✗ Branch 43 → 108 not taken.
|
252 | rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type; |
41 |
2/2✓ Branch 45 → 46 taken 33 times.
✓ Branch 45 → 48 taken 423 times.
|
456 | } else if (node->op == AssignExprNode::AssignOp::OP_MINUS_EQUAL) { |
42 |
1/2✓ Branch 46 → 47 taken 33 times.
✗ Branch 46 → 109 not taken.
|
33 | rhsType = opRuleManager.getMinusEqualResultType(node, lhs, rhs, 0).type; |
43 |
2/2✓ Branch 48 → 49 taken 40 times.
✓ Branch 48 → 51 taken 383 times.
|
423 | } else if (node->op == AssignExprNode::AssignOp::OP_MUL_EQUAL) { |
44 |
1/2✓ Branch 49 → 50 taken 40 times.
✗ Branch 49 → 110 not taken.
|
40 | rhsType = opRuleManager.getMulEqualResultType(node, lhs, rhs, 0).type; |
45 |
2/2✓ Branch 51 → 52 taken 45 times.
✓ Branch 51 → 54 taken 338 times.
|
383 | } else if (node->op == AssignExprNode::AssignOp::OP_DIV_EQUAL) { |
46 |
1/2✓ Branch 52 → 53 taken 45 times.
✗ Branch 52 → 111 not taken.
|
45 | rhsType = opRuleManager.getDivEqualResultType(node, lhs, rhs, 0).type; |
47 |
2/2✓ Branch 54 → 55 taken 6 times.
✓ Branch 54 → 57 taken 332 times.
|
338 | } else if (node->op == AssignExprNode::AssignOp::OP_REM_EQUAL) { |
48 |
1/2✓ Branch 55 → 56 taken 6 times.
✗ Branch 55 → 112 not taken.
|
6 | rhsType = opRuleManager.getRemEqualResultType(node, lhs, rhs); |
49 |
2/2✓ Branch 57 → 58 taken 2 times.
✓ Branch 57 → 60 taken 330 times.
|
332 | } else if (node->op == AssignExprNode::AssignOp::OP_SHL_EQUAL) { |
50 |
1/2✓ Branch 58 → 59 taken 2 times.
✗ Branch 58 → 113 not taken.
|
2 | rhsType = opRuleManager.getSHLEqualResultType(node, lhs, rhs); |
51 |
2/2✓ Branch 60 → 61 taken 3 times.
✓ Branch 60 → 63 taken 327 times.
|
330 | } else if (node->op == AssignExprNode::AssignOp::OP_SHR_EQUAL) { |
52 |
1/2✓ Branch 61 → 62 taken 3 times.
✗ Branch 61 → 114 not taken.
|
3 | rhsType = opRuleManager.getSHREqualResultType(node, lhs, rhs); |
53 |
2/2✓ Branch 63 → 64 taken 1 time.
✓ Branch 63 → 66 taken 326 times.
|
327 | } else if (node->op == AssignExprNode::AssignOp::OP_AND_EQUAL) { |
54 |
1/2✓ Branch 64 → 65 taken 1 time.
✗ Branch 64 → 115 not taken.
|
1 | rhsType = opRuleManager.getAndEqualResultType(node, lhs, rhs); |
55 |
2/2✓ Branch 66 → 67 taken 1 time.
✓ Branch 66 → 69 taken 325 times.
|
326 | } else if (node->op == AssignExprNode::AssignOp::OP_OR_EQUAL) { |
56 |
1/2✓ Branch 67 → 68 taken 1 time.
✗ Branch 67 → 116 not taken.
|
1 | rhsType = opRuleManager.getOrEqualResultType(node, lhs, rhs); |
57 |
1/2✓ Branch 69 → 70 taken 325 times.
✗ Branch 69 → 72 not taken.
|
325 | } else if (node->op == AssignExprNode::AssignOp::OP_XOR_EQUAL) { |
58 |
1/2✓ Branch 70 → 71 taken 325 times.
✗ Branch 70 → 117 not taken.
|
325 | rhsType = opRuleManager.getXorEqualResultType(node, lhs, rhs); |
59 | } | ||
60 | |||
61 |
1/2✓ Branch 72 → 73 taken 6303 times.
✗ Branch 72 → 81 not taken.
|
6303 | if (lhsVar) { // Variable is involved on the left side |
62 | // Perform type inference | ||
63 |
3/4✓ Branch 73 → 74 taken 6303 times.
✗ Branch 73 → 120 not taken.
✓ Branch 74 → 75 taken 1 time.
✓ Branch 74 → 76 taken 6302 times.
|
6303 | if (lhsType.is(TY_DYN)) |
64 |
1/2✓ Branch 75 → 76 taken 1 time.
✗ Branch 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 76 → 77 taken 6303 times.
✗ Branch 76 → 120 not taken.
✓ Branch 77 → 78 taken 3 times.
✓ Branch 77 → 79 taken 6300 times.
|
6303 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsVar->name); lhsCapture) |
68 |
1/2✓ Branch 78 → 79 taken 3 times.
✗ Branch 78 → 120 not taken.
|
3 | lhsCapture->setAccessType(READ_WRITE); |
69 | |||
70 | // Update the state of the variable | ||
71 |
1/2✓ Branch 79 → 80 taken 6303 times.
✗ Branch 79 → 118 not taken.
|
6303 | lhsVar->updateState(INITIALIZED, node); |
72 | } | ||
73 | |||
74 |
2/4✓ Branch 81 → 82 taken 6303 times.
✗ Branch 81 → 119 not taken.
✓ Branch 82 → 83 taken 6303 times.
✗ Branch 82 → 119 not taken.
|
6303 | return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)}; |
75 | } | ||
76 | |||
77 | − | throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE | |
78 | } | ||
79 | |||
80 | 66152 | std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) { | |
81 | // Check if there is a ternary operator applied | ||
82 |
2/2✓ Branch 2 → 3 taken 65675 times.
✓ Branch 2 → 5 taken 477 times.
|
66152 | if (!node->falseExpr) |
83 |
2/2✓ Branch 3 → 4 taken 65660 times.
✓ Branch 3 → 150 taken 15 times.
|
65675 | return visit(node->condition); |
84 | |||
85 | // Visit condition | ||
86 |
2/4✓ Branch 5 → 6 taken 477 times.
✗ Branch 5 → 115 not taken.
✓ Branch 6 → 7 taken 477 times.
✗ Branch 6 → 113 not taken.
|
477 | const auto condition = std::any_cast<ExprResult>(visit(node->condition)); |
87 |
2/8✓ Branch 8 → 9 taken 477 times.
✗ Branch 8 → 150 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 14 taken 477 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 116 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 116 not taken.
|
477 | HANDLE_UNRESOLVED_TYPE_ER(condition.type) |
88 |
6/10✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 16 taken 476 times.
✓ Branch 16 → 17 taken 476 times.
✗ Branch 16 → 117 not taken.
✓ Branch 17 → 18 taken 476 times.
✗ Branch 17 → 117 not taken.
✓ Branch 18 → 19 taken 476 times.
✓ Branch 18 → 20 taken 1 time.
✗ Branch 117 → 118 not taken.
✗ Branch 117 → 119 not taken.
|
477 | const auto trueExpr = node->isShortened ? condition : std::any_cast<ExprResult>(visit(node->trueExpr)); |
89 | 477 | const auto [trueType, trueEntry] = trueExpr; | |
90 |
2/8✓ Branch 20 → 21 taken 477 times.
✗ Branch 20 → 150 not taken.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 26 taken 477 times.
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 121 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 121 not taken.
|
477 | HANDLE_UNRESOLVED_TYPE_ER(trueType) |
91 |
2/4✓ Branch 26 → 27 taken 477 times.
✗ Branch 26 → 124 not taken.
✓ Branch 27 → 28 taken 477 times.
✗ Branch 27 → 122 not taken.
|
477 | const auto falseExpr = std::any_cast<ExprResult>(visit(node->falseExpr)); |
92 | 477 | const auto [falseType, falseEntry] = falseExpr; | |
93 |
2/8✓ Branch 29 → 30 taken 477 times.
✗ Branch 29 → 150 not taken.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 35 taken 477 times.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 125 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 125 not taken.
|
477 | HANDLE_UNRESOLVED_TYPE_ER(falseType) |
94 | |||
95 | // Check if the condition evaluates to bool | ||
96 |
3/4✓ Branch 35 → 36 taken 477 times.
✗ Branch 35 → 150 not taken.
✓ Branch 36 → 37 taken 1 time.
✓ Branch 36 → 47 taken 476 times.
|
477 | if (!condition.type.is(TY_BOOL)) |
97 |
4/8✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 128 not taken.
✓ Branch 40 → 41 taken 1 time.
✗ Branch 40 → 126 not taken.
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 132 not taken.
✓ Branch 44 → 45 taken 1 time.
✗ Branch 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 47 → 48 taken 476 times.
✗ Branch 47 → 150 not taken.
|
476 | const QualType trueTypeModified = trueType.removeReferenceWrapper(); |
101 |
1/2✓ Branch 48 → 49 taken 476 times.
✗ Branch 48 → 150 not taken.
|
476 | const QualType falseTypeModified = falseType.removeReferenceWrapper(); |
102 |
3/4✓ Branch 49 → 50 taken 476 times.
✗ Branch 49 → 150 not taken.
✓ Branch 50 → 51 taken 1 time.
✓ Branch 50 → 66 taken 475 times.
|
476 | if (!trueTypeModified.matches(falseTypeModified, false, true, false)) |
103 |
8/16✓ Branch 51 → 52 taken 1 time.
✗ Branch 51 → 146 not taken.
✓ Branch 52 → 53 taken 1 time.
✗ Branch 52 → 141 not taken.
✓ Branch 53 → 54 taken 1 time.
✗ Branch 53 → 139 not taken.
✓ Branch 54 → 55 taken 1 time.
✗ Branch 54 → 137 not taken.
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 135 not taken.
✓ Branch 56 → 57 taken 1 time.
✗ Branch 56 → 133 not taken.
✓ Branch 62 → 63 taken 1 time.
✗ Branch 62 → 148 not taken.
✓ Branch 63 → 64 taken 1 time.
✗ Branch 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 | 475 | bool removedAnonymousSymbols = false; | |
110 |
2/2✓ Branch 66 → 67 taken 127 times.
✓ Branch 66 → 78 taken 348 times.
|
475 | if (trueEntry) { |
111 |
2/2✓ Branch 67 → 68 taken 80 times.
✓ Branch 67 → 70 taken 47 times.
|
127 | if (trueEntry->anonymous) { |
112 |
1/2✓ Branch 68 → 69 taken 80 times.
✗ Branch 68 → 150 not taken.
|
80 | currentScope->symbolTable.deleteAnonymous(trueEntry->name); |
113 | 80 | removedAnonymousSymbols = true; | |
114 |
8/10✓ Branch 70 → 71 taken 47 times.
✗ Branch 70 → 150 not taken.
✓ Branch 71 → 72 taken 39 times.
✓ Branch 71 → 75 taken 8 times.
✓ Branch 72 → 73 taken 39 times.
✗ Branch 72 → 150 not taken.
✓ Branch 73 → 74 taken 8 times.
✓ Branch 73 → 75 taken 31 times.
✓ Branch 76 → 77 taken 8 times.
✓ Branch 76 → 78 taken 39 times.
|
47 | } else if (!trueType.isRef() && !trueType.isTriviallyCopyable(node)) { |
115 | 8 | node->trueSideCallsCopyCtor = true; | |
116 | } | ||
117 | } | ||
118 |
2/2✓ Branch 78 → 79 taken 315 times.
✓ Branch 78 → 90 taken 160 times.
|
475 | if (falseEntry) { |
119 |
2/2✓ Branch 79 → 80 taken 79 times.
✓ Branch 79 → 82 taken 236 times.
|
315 | if (falseEntry->anonymous) { |
120 |
1/2✓ Branch 80 → 81 taken 79 times.
✗ Branch 80 → 150 not taken.
|
79 | currentScope->symbolTable.deleteAnonymous(falseEntry->name); |
121 | 79 | removedAnonymousSymbols = true; | |
122 |
8/10✓ Branch 82 → 83 taken 236 times.
✗ Branch 82 → 150 not taken.
✓ Branch 83 → 84 taken 227 times.
✓ Branch 83 → 87 taken 9 times.
✓ Branch 84 → 85 taken 227 times.
✗ Branch 84 → 150 not taken.
✓ Branch 85 → 86 taken 8 times.
✓ Branch 85 → 87 taken 219 times.
✓ Branch 88 → 89 taken 8 times.
✓ Branch 88 → 90 taken 228 times.
|
236 | } 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 | 475 | const QualType &resultType = trueType; | |
129 | 475 | SymbolTableEntry *anonymousSymbol = nullptr; | |
130 |
4/4✓ Branch 90 → 91 taken 467 times.
✓ Branch 90 → 92 taken 8 times.
✓ Branch 91 → 92 taken 2 times.
✓ Branch 91 → 93 taken 465 times.
|
475 | const bool calledCopyCtor = node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor; |
131 |
9/10✓ Branch 94 → 95 taken 393 times.
✓ Branch 94 → 98 taken 82 times.
✓ Branch 95 → 96 taken 387 times.
✓ Branch 95 → 98 taken 6 times.
✓ Branch 96 → 97 taken 387 times.
✗ Branch 96 → 150 not taken.
✓ Branch 97 → 98 taken 8 times.
✓ Branch 97 → 99 taken 379 times.
✓ Branch 100 → 101 taken 96 times.
✓ Branch 100 → 103 taken 379 times.
|
475 | if (removedAnonymousSymbols || calledCopyCtor || resultType.isRef()) |
132 |
1/2✓ Branch 101 → 102 taken 96 times.
✗ Branch 101 → 150 not taken.
|
96 | anonymousSymbol = currentScope->symbolTable.insertAnonymous(resultType, node); |
133 | |||
134 | // Look up the copy ctor if at least one side needs it | ||
135 |
4/4✓ Branch 103 → 104 taken 467 times.
✓ Branch 103 → 105 taken 8 times.
✓ Branch 104 → 105 taken 2 times.
✓ Branch 104 → 107 taken 465 times.
|
475 | if (node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor) |
136 |
1/2✓ Branch 105 → 106 taken 10 times.
✗ Branch 105 → 150 not taken.
|
10 | node->calledCopyCtor = matchCopyCtor(trueTypeModified, node); |
137 | |||
138 |
2/4✓ Branch 107 → 108 taken 475 times.
✗ Branch 107 → 149 not taken.
✓ Branch 108 → 109 taken 475 times.
✗ Branch 108 → 149 not taken.
|
475 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), anonymousSymbol}; |
139 | } | ||
140 | |||
141 | 67105 | std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) { | |
142 | // Check if a logical or operator is applied | ||
143 |
2/2✓ Branch 3 → 4 taken 66210 times.
✓ Branch 3 → 7 taken 895 times.
|
67105 | if (node->operands.size() == 1) |
144 |
2/2✓ Branch 5 → 6 taken 66196 times.
✓ Branch 5 → 46 taken 14 times.
|
66210 | return visit(node->operands.front()); |
145 | |||
146 | // Visit leftmost operand | ||
147 |
2/4✓ Branch 8 → 9 taken 895 times.
✗ Branch 8 → 39 not taken.
✓ Branch 9 → 10 taken 895 times.
✗ Branch 9 → 37 not taken.
|
895 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
148 |
2/8✓ Branch 11 → 12 taken 895 times.
✗ Branch 11 → 46 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 895 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 40 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 40 not taken.
|
895 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
149 | |||
150 | // Loop through all remaining operands | ||
151 |
2/2✓ Branch 31 → 18 taken 1147 times.
✓ Branch 31 → 32 taken 894 times.
|
2041 | for (size_t i = 1; i < node->operands.size(); i++) { |
152 |
2/4✓ Branch 19 → 20 taken 1147 times.
✗ Branch 19 → 43 not taken.
✓ Branch 20 → 21 taken 1147 times.
✗ Branch 20 → 41 not taken.
|
1147 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
153 |
2/8✓ Branch 22 → 23 taken 1147 times.
✗ Branch 22 → 45 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 1147 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 44 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 44 not taken.
|
1147 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
154 |
2/2✓ Branch 28 → 29 taken 1146 times.
✓ Branch 28 → 45 taken 1 time.
|
1147 | currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)}; |
155 | } | ||
156 | |||
157 |
1/2✓ Branch 32 → 33 taken 894 times.
✗ Branch 32 → 46 not taken.
|
894 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
158 |
1/2✓ Branch 33 → 34 taken 894 times.
✗ Branch 33 → 46 not taken.
|
894 | return currentOperand; |
159 | } | ||
160 | |||
161 | 68252 | std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) { | |
162 | // Check if a logical and operator is applied | ||
163 |
2/2✓ Branch 3 → 4 taken 68085 times.
✓ Branch 3 → 7 taken 167 times.
|
68252 | if (node->operands.size() == 1) |
164 |
2/2✓ Branch 5 → 6 taken 68071 times.
✓ Branch 5 → 46 taken 14 times.
|
68085 | return visit(node->operands.front()); |
165 | |||
166 | // Visit leftmost operand | ||
167 |
2/4✓ Branch 8 → 9 taken 167 times.
✗ Branch 8 → 39 not taken.
✓ Branch 9 → 10 taken 167 times.
✗ Branch 9 → 37 not taken.
|
167 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
168 |
2/8✓ Branch 11 → 12 taken 167 times.
✗ Branch 11 → 46 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 167 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 40 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 40 not taken.
|
167 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
169 | |||
170 | // Loop through all remaining operands | ||
171 |
2/2✓ Branch 31 → 18 taken 202 times.
✓ Branch 31 → 32 taken 167 times.
|
369 | for (size_t i = 1; i < node->operands.size(); i++) { |
172 |
2/4✓ Branch 19 → 20 taken 202 times.
✗ Branch 19 → 43 not taken.
✓ Branch 20 → 21 taken 202 times.
✗ Branch 20 → 41 not taken.
|
202 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
173 |
2/8✓ Branch 22 → 23 taken 202 times.
✗ Branch 22 → 45 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 202 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 44 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 44 not taken.
|
202 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
174 |
1/2✓ Branch 28 → 29 taken 202 times.
✗ Branch 28 → 45 not taken.
|
202 | currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)}; |
175 | } | ||
176 | |||
177 |
1/2✓ Branch 32 → 33 taken 167 times.
✗ Branch 32 → 46 not taken.
|
167 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
178 |
1/2✓ Branch 33 → 34 taken 167 times.
✗ Branch 33 → 46 not taken.
|
167 | return currentOperand; |
179 | } | ||
180 | |||
181 | 68454 | std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) { | |
182 | // Check if a bitwise or operator is applied | ||
183 |
2/2✓ Branch 3 → 4 taken 68375 times.
✓ Branch 3 → 7 taken 79 times.
|
68454 | if (node->operands.size() == 1) |
184 |
2/2✓ Branch 5 → 6 taken 68362 times.
✓ Branch 5 → 46 taken 13 times.
|
68375 | return visit(node->operands.front()); |
185 | |||
186 | // Visit leftmost operand | ||
187 |
2/4✓ Branch 8 → 9 taken 79 times.
✗ Branch 8 → 39 not taken.
✓ Branch 9 → 10 taken 79 times.
✗ Branch 9 → 37 not taken.
|
79 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
188 |
2/8✓ Branch 11 → 12 taken 79 times.
✗ Branch 11 → 46 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 79 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 40 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 40 not taken.
|
79 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
189 | |||
190 | // Loop through all remaining operands | ||
191 |
2/2✓ Branch 31 → 18 taken 82 times.
✓ Branch 31 → 32 taken 78 times.
|
160 | for (size_t i = 1; i < node->operands.size(); i++) { |
192 |
2/4✓ Branch 19 → 20 taken 82 times.
✗ Branch 19 → 43 not taken.
✓ Branch 20 → 21 taken 82 times.
✗ Branch 20 → 41 not taken.
|
82 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
193 |
2/8✓ Branch 22 → 23 taken 82 times.
✗ Branch 22 → 45 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 82 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 44 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 44 not taken.
|
82 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
194 |
2/2✓ Branch 28 → 29 taken 81 times.
✓ Branch 28 → 45 taken 1 time.
|
82 | currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)}; |
195 | } | ||
196 | |||
197 |
1/2✓ Branch 32 → 33 taken 78 times.
✗ Branch 32 → 46 not taken.
|
78 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
198 |
1/2✓ Branch 33 → 34 taken 78 times.
✗ Branch 33 → 46 not taken.
|
78 | return currentOperand; |
199 | } | ||
200 | |||
201 | 68536 | std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) { | |
202 | // Check if a bitwise xor operator is applied | ||
203 |
2/2✓ Branch 3 → 4 taken 68525 times.
✓ Branch 3 → 7 taken 11 times.
|
68536 | if (node->operands.size() == 1) |
204 |
2/2✓ Branch 5 → 6 taken 68512 times.
✓ Branch 5 → 46 taken 13 times.
|
68525 | return visit(node->operands.front()); |
205 | |||
206 | // Visit leftmost operand | ||
207 |
2/4✓ Branch 8 → 9 taken 11 times.
✗ Branch 8 → 39 not taken.
✓ Branch 9 → 10 taken 11 times.
✗ Branch 9 → 37 not taken.
|
11 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
208 |
2/8✓ Branch 11 → 12 taken 11 times.
✗ Branch 11 → 46 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 11 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 40 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 40 not taken.
|
11 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
209 | |||
210 | // Loop through all remaining operands | ||
211 |
2/2✓ Branch 31 → 18 taken 14 times.
✓ Branch 31 → 32 taken 11 times.
|
25 | for (size_t i = 1; i < node->operands.size(); i++) { |
212 |
2/4✓ Branch 19 → 20 taken 14 times.
✗ Branch 19 → 43 not taken.
✓ Branch 20 → 21 taken 14 times.
✗ Branch 20 → 41 not taken.
|
14 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
213 |
2/8✓ Branch 22 → 23 taken 14 times.
✗ Branch 22 → 45 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 14 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 44 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 44 not taken.
|
14 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
214 |
1/2✓ Branch 28 → 29 taken 14 times.
✗ Branch 28 → 45 not taken.
|
14 | currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)}; |
215 | } | ||
216 | |||
217 |
1/2✓ Branch 32 → 33 taken 11 times.
✗ Branch 32 → 46 not taken.
|
11 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
218 |
1/2✓ Branch 33 → 34 taken 11 times.
✗ Branch 33 → 46 not taken.
|
11 | return currentOperand; |
219 | } | ||
220 | |||
221 | 68550 | std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) { | |
222 | // Check if a bitwise and operator is applied | ||
223 |
2/2✓ Branch 3 → 4 taken 68523 times.
✓ Branch 3 → 7 taken 27 times.
|
68550 | if (node->operands.size() == 1) |
224 |
2/2✓ Branch 5 → 6 taken 68510 times.
✓ Branch 5 → 46 taken 13 times.
|
68523 | return visit(node->operands.front()); |
225 | |||
226 | // Visit leftmost operand | ||
227 |
2/4✓ Branch 8 → 9 taken 27 times.
✗ Branch 8 → 39 not taken.
✓ Branch 9 → 10 taken 27 times.
✗ Branch 9 → 37 not taken.
|
27 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
228 |
2/8✓ Branch 11 → 12 taken 27 times.
✗ Branch 11 → 46 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 27 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 40 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 40 not taken.
|
27 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
229 | |||
230 | // Loop through all remaining operands | ||
231 |
2/2✓ Branch 31 → 18 taken 30 times.
✓ Branch 31 → 32 taken 27 times.
|
57 | for (size_t i = 1; i < node->operands.size(); i++) { |
232 |
2/4✓ Branch 19 → 20 taken 30 times.
✗ Branch 19 → 43 not taken.
✓ Branch 20 → 21 taken 30 times.
✗ Branch 20 → 41 not taken.
|
30 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
233 |
2/8✓ Branch 22 → 23 taken 30 times.
✗ Branch 22 → 45 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 30 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 44 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 44 not taken.
|
30 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
234 |
1/2✓ Branch 28 → 29 taken 30 times.
✗ Branch 28 → 45 not taken.
|
30 | currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)}; |
235 | } | ||
236 | |||
237 |
1/2✓ Branch 32 → 33 taken 27 times.
✗ Branch 32 → 46 not taken.
|
27 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
238 |
1/2✓ Branch 33 → 34 taken 27 times.
✗ Branch 33 → 46 not taken.
|
27 | return currentOperand; |
239 | } | ||
240 | |||
241 | 68580 | std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) { | |
242 | // Check if at least one equality operator is applied | ||
243 |
2/2✓ Branch 3 → 4 taken 63489 times.
✓ Branch 3 → 7 taken 5091 times.
|
68580 | if (node->operands.size() == 1) |
244 |
2/2✓ Branch 5 → 6 taken 63477 times.
✓ Branch 5 → 73 taken 12 times.
|
63489 | return visit(node->operands.front()); |
245 | |||
246 | // Visit right side first, then left side | ||
247 |
2/4✓ Branch 8 → 9 taken 5091 times.
✗ Branch 8 → 58 not taken.
✓ Branch 9 → 10 taken 5091 times.
✗ Branch 9 → 56 not taken.
|
5091 | const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1])); |
248 |
2/8✓ Branch 11 → 12 taken 5091 times.
✗ Branch 11 → 73 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 5091 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 59 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 59 not taken.
|
5091 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
249 |
2/4✓ Branch 18 → 19 taken 5091 times.
✗ Branch 18 → 62 not taken.
✓ Branch 19 → 20 taken 5091 times.
✗ Branch 19 → 60 not taken.
|
5091 | const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0])); |
250 |
2/8✓ Branch 21 → 22 taken 5091 times.
✗ Branch 21 → 73 not taken.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 27 taken 5091 times.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 63 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 63 not taken.
|
5091 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
251 | |||
252 | // Check if we need the string runtime to perform a string comparison | ||
253 |
10/14✓ Branch 27 → 28 taken 5091 times.
✗ Branch 27 → 73 not taken.
✓ Branch 28 → 29 taken 138 times.
✓ Branch 28 → 36 taken 4953 times.
✓ Branch 29 → 30 taken 138 times.
✗ Branch 29 → 73 not taken.
✓ Branch 30 → 31 taken 137 times.
✓ Branch 30 → 36 taken 1 time.
✓ Branch 31 → 32 taken 137 times.
✗ Branch 31 → 73 not taken.
✓ Branch 34 → 35 taken 137 times.
✗ Branch 34 → 36 not taken.
✓ Branch 37 → 38 taken 137 times.
✓ Branch 37 → 39 taken 4954 times.
|
5228 | if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT()) |
254 |
1/2✓ Branch 38 → 39 taken 137 times.
✗ Branch 38 → 73 not taken.
|
137 | sourceFile->requestRuntimeModule(STRING_RT); |
255 | |||
256 | // Check operator | ||
257 | 5091 | ExprResult result; | |
258 |
2/2✓ Branch 39 → 40 taken 3614 times.
✓ Branch 39 → 41 taken 1477 times.
|
5091 | if (node->op == EqualityExprNode::EqualityOp::OP_EQUAL) // Operator was equal |
259 |
2/2✓ Branch 40 → 51 taken 3613 times.
✓ Branch 40 → 73 taken 1 time.
|
3614 | result = opRuleManager.getEqualResultType(node, lhs, rhs, 0); |
260 |
1/2✓ Branch 41 → 42 taken 1477 times.
✗ Branch 41 → 43 not taken.
|
1477 | else if (node->op == EqualityExprNode::EqualityOp::OP_NOT_EQUAL) // Operator was not equal |
261 |
1/2✓ Branch 42 → 51 taken 1477 times.
✗ Branch 42 → 73 not taken.
|
1477 | 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 51 → 52 taken 5090 times.
✗ Branch 51 → 73 not taken.
|
5090 | node->setEvaluatedSymbolType(result.type, manIdx); |
266 |
1/2✓ Branch 52 → 53 taken 5090 times.
✗ Branch 52 → 73 not taken.
|
5090 | return result; |
267 | } | ||
268 | |||
269 | 73671 | std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) { | |
270 | // Check if a relational operator is applied | ||
271 |
2/2✓ Branch 3 → 4 taken 70052 times.
✓ Branch 3 → 7 taken 3619 times.
|
73671 | if (node->operands.size() == 1) |
272 |
2/2✓ Branch 5 → 6 taken 70041 times.
✓ Branch 5 → 75 taken 11 times.
|
70052 | return visit(node->operands.front()); |
273 | |||
274 | // Visit right side first, then left side | ||
275 |
2/4✓ Branch 8 → 9 taken 3619 times.
✗ Branch 8 → 55 not taken.
✓ Branch 9 → 10 taken 3619 times.
✗ Branch 9 → 53 not taken.
|
3619 | const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1])); |
276 |
5/8✓ Branch 11 → 12 taken 3619 times.
✗ Branch 11 → 75 not taken.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 17 taken 3618 times.
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 56 not taken.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 56 not taken.
|
3619 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
277 |
2/4✓ Branch 18 → 19 taken 3618 times.
✗ Branch 18 → 59 not taken.
✓ Branch 19 → 20 taken 3618 times.
✗ Branch 19 → 57 not taken.
|
3618 | const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0])); |
278 |
2/8✓ Branch 21 → 22 taken 3618 times.
✗ Branch 21 → 75 not taken.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 27 taken 3618 times.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 60 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 60 not taken.
|
3618 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
279 | |||
280 | // Check operator | ||
281 | 3618 | QualType resultType; | |
282 |
2/2✓ Branch 27 → 28 taken 1784 times.
✓ Branch 27 → 30 taken 1834 times.
|
3618 | if (node->op == RelationalExprNode::RelationalOp::OP_LESS) // Operator was less |
283 |
1/2✓ Branch 28 → 29 taken 1784 times.
✗ Branch 28 → 61 not taken.
|
1784 | resultType = OpRuleManager::getLessResultType(node, lhs, rhs); |
284 |
2/2✓ Branch 30 → 31 taken 497 times.
✓ Branch 30 → 33 taken 1337 times.
|
1834 | else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER) // Operator was greater |
285 |
2/2✓ Branch 31 → 32 taken 496 times.
✓ Branch 31 → 62 taken 1 time.
|
497 | resultType = OpRuleManager::getGreaterResultType(node, lhs, rhs); |
286 |
2/2✓ Branch 33 → 34 taken 373 times.
✓ Branch 33 → 36 taken 964 times.
|
1337 | else if (node->op == RelationalExprNode::RelationalOp::OP_LESS_EQUAL) // Operator was less equal |
287 |
1/2✓ Branch 34 → 35 taken 373 times.
✗ Branch 34 → 63 not taken.
|
373 | resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs); |
288 |
1/2✓ Branch 36 → 37 taken 964 times.
✗ Branch 36 → 39 not taken.
|
964 | else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER_EQUAL) // Operator was greater equal |
289 |
1/2✓ Branch 37 → 38 taken 964 times.
✗ Branch 37 → 64 not taken.
|
964 | resultType = OpRuleManager::getGreaterEqualResultType(node, lhs, rhs); |
290 | else | ||
291 | − | throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE | |
292 | |||
293 |
2/4✓ Branch 47 → 48 taken 3617 times.
✗ Branch 47 → 74 not taken.
✓ Branch 48 → 49 taken 3617 times.
✗ Branch 48 → 74 not taken.
|
3617 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)}; |
294 | } | ||
295 | |||
296 | 77289 | std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) { | |
297 | // Check if at least one shift operator is applied | ||
298 |
2/2✓ Branch 3 → 4 taken 77176 times.
✓ Branch 3 → 7 taken 113 times.
|
77289 | if (node->operands.size() == 1) |
299 |
2/2✓ Branch 5 → 6 taken 77165 times.
✓ Branch 5 → 69 taken 11 times.
|
77176 | return visit(node->operands.front()); |
300 | |||
301 | // Visit leftmost operand | ||
302 |
2/4✓ Branch 8 → 9 taken 113 times.
✗ Branch 8 → 53 not taken.
✓ Branch 9 → 10 taken 113 times.
✗ Branch 9 → 51 not taken.
|
113 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
303 |
2/8✓ Branch 11 → 12 taken 113 times.
✗ Branch 11 → 69 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 113 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 54 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 54 not taken.
|
113 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
304 | |||
305 | // Loop through remaining operands | ||
306 |
2/2✓ Branch 45 → 18 taken 153 times.
✓ Branch 45 → 46 taken 113 times.
|
266 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
307 |
2/4✓ Branch 19 → 20 taken 153 times.
✗ Branch 19 → 57 not taken.
✓ Branch 20 → 21 taken 153 times.
✗ Branch 20 → 55 not taken.
|
153 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
308 |
2/8✓ Branch 22 → 23 taken 153 times.
✗ Branch 22 → 68 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 153 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 58 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 58 not taken.
|
153 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
309 | |||
310 | // Check operator | ||
311 | 153 | const ShiftExprNode::ShiftOp &op = node->opQueue.front().first; | |
312 |
2/2✓ Branch 29 → 30 taken 97 times.
✓ Branch 29 → 31 taken 56 times.
|
153 | if (op == ShiftExprNode::ShiftOp::OP_SHIFT_LEFT) |
313 |
1/2✓ Branch 30 → 41 taken 97 times.
✗ Branch 30 → 68 not taken.
|
97 | currentResult = opRuleManager.getShiftLeftResultType(node, currentResult, operandResult, i); |
314 |
1/2✓ Branch 31 → 32 taken 56 times.
✗ Branch 31 → 33 not taken.
|
56 | else if (op == ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT) |
315 |
1/2✓ Branch 32 → 41 taken 56 times.
✗ Branch 32 → 68 not taken.
|
56 | 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 41 → 42 taken 153 times.
✗ Branch 41 → 68 not taken.
|
153 | node->opQueue.emplace(op, currentResult.type); |
321 | 153 | node->opQueue.pop(); | |
322 | } | ||
323 | |||
324 |
1/2✓ Branch 46 → 47 taken 113 times.
✗ Branch 46 → 69 not taken.
|
113 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
325 |
1/2✓ Branch 47 → 48 taken 113 times.
✗ Branch 47 → 69 not taken.
|
113 | return currentResult; |
326 | } | ||
327 | |||
328 | 77442 | std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) { | |
329 | // Check if at least one additive operator is applied | ||
330 |
2/2✓ Branch 3 → 4 taken 73349 times.
✓ Branch 3 → 7 taken 4093 times.
|
77442 | if (node->operands.size() == 1) |
331 |
2/2✓ Branch 5 → 6 taken 73339 times.
✓ Branch 5 → 69 taken 10 times.
|
73349 | return visit(node->operands.front()); |
332 | |||
333 | // Visit leftmost operand | ||
334 |
2/4✓ Branch 8 → 9 taken 4093 times.
✗ Branch 8 → 53 not taken.
✓ Branch 9 → 10 taken 4093 times.
✗ Branch 9 → 51 not taken.
|
4093 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
335 |
2/8✓ Branch 11 → 12 taken 4093 times.
✗ Branch 11 → 69 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 4093 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 54 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 54 not taken.
|
4093 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
336 | |||
337 | // Loop through remaining operands | ||
338 |
2/2✓ Branch 45 → 18 taken 4672 times.
✓ Branch 45 → 46 taken 4092 times.
|
8764 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
339 |
2/4✓ Branch 19 → 20 taken 4672 times.
✗ Branch 19 → 57 not taken.
✓ Branch 20 → 21 taken 4672 times.
✗ Branch 20 → 55 not taken.
|
4672 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
340 |
2/8✓ Branch 22 → 23 taken 4672 times.
✗ Branch 22 → 68 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 4672 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 58 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 58 not taken.
|
4672 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
341 | |||
342 | // Check operator | ||
343 | 4672 | const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first; | |
344 |
2/2✓ Branch 29 → 30 taken 2868 times.
✓ Branch 29 → 31 taken 1804 times.
|
4672 | if (op == AdditiveExprNode::AdditiveOp::OP_PLUS) |
345 |
2/2✓ Branch 30 → 41 taken 2867 times.
✓ Branch 30 → 68 taken 1 time.
|
2868 | currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i); |
346 |
1/2✓ Branch 31 → 32 taken 1804 times.
✗ Branch 31 → 33 not taken.
|
1804 | else if (op == AdditiveExprNode::AdditiveOp::OP_MINUS) |
347 |
1/2✓ Branch 32 → 41 taken 1804 times.
✗ Branch 32 → 68 not taken.
|
1804 | 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 41 → 42 taken 4671 times.
✗ Branch 41 → 68 not taken.
|
4671 | node->opQueue.emplace(op, currentResult.type); |
353 | 4671 | node->opQueue.pop(); | |
354 | } | ||
355 | |||
356 |
1/2✓ Branch 46 → 47 taken 4092 times.
✗ Branch 46 → 69 not taken.
|
4092 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
357 |
1/2✓ Branch 47 → 48 taken 4092 times.
✗ Branch 47 → 69 not taken.
|
4092 | return currentResult; |
358 | } | ||
359 | |||
360 | 82114 | std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) { | |
361 | // Check if at least one multiplicative operator is applied | ||
362 |
2/2✓ Branch 3 → 4 taken 81247 times.
✓ Branch 3 → 7 taken 867 times.
|
82114 | if (node->operands.size() == 1) |
363 |
2/2✓ Branch 5 → 6 taken 81238 times.
✓ Branch 5 → 71 taken 9 times.
|
81247 | return visit(node->operands.front()); |
364 | |||
365 | // Visit leftmost operand | ||
366 |
2/4✓ Branch 8 → 9 taken 867 times.
✗ Branch 8 → 55 not taken.
✓ Branch 9 → 10 taken 867 times.
✗ Branch 9 → 53 not taken.
|
867 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
367 |
2/8✓ Branch 11 → 12 taken 867 times.
✗ Branch 11 → 71 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 17 taken 867 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 56 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 56 not taken.
|
867 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
368 | // Loop through remaining operands | ||
369 |
2/2✓ Branch 47 → 18 taken 891 times.
✓ Branch 47 → 48 taken 866 times.
|
1757 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
370 |
2/4✓ Branch 19 → 20 taken 891 times.
✗ Branch 19 → 59 not taken.
✓ Branch 20 → 21 taken 891 times.
✗ Branch 20 → 57 not taken.
|
891 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
371 |
2/8✓ Branch 22 → 23 taken 891 times.
✗ Branch 22 → 70 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 28 taken 891 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 60 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 60 not taken.
|
891 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
372 | |||
373 | // Check operator | ||
374 | 891 | const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first; | |
375 |
2/2✓ Branch 29 → 30 taken 741 times.
✓ Branch 29 → 31 taken 150 times.
|
891 | if (op == MultiplicativeExprNode::MultiplicativeOp::OP_MUL) |
376 |
2/2✓ Branch 30 → 43 taken 740 times.
✓ Branch 30 → 70 taken 1 time.
|
741 | currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i); |
377 |
2/2✓ Branch 31 → 32 taken 138 times.
✓ Branch 31 → 33 taken 12 times.
|
150 | else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_DIV) |
378 |
1/2✓ Branch 32 → 43 taken 138 times.
✗ Branch 32 → 70 not taken.
|
138 | currentResult = opRuleManager.getDivResultType(node, currentResult, operandResult, i); |
379 |
1/2✓ Branch 33 → 34 taken 12 times.
✗ Branch 33 → 35 not taken.
|
12 | else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_REM) |
380 |
1/2✓ Branch 34 → 43 taken 12 times.
✗ Branch 34 → 70 not taken.
|
12 | 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 43 → 44 taken 890 times.
✗ Branch 43 → 70 not taken.
|
890 | node->opQueue.emplace(op, currentResult.type); |
386 | 890 | node->opQueue.pop(); | |
387 | } | ||
388 | |||
389 |
1/2✓ Branch 48 → 49 taken 866 times.
✗ Branch 48 → 71 not taken.
|
866 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
390 |
1/2✓ Branch 49 → 50 taken 866 times.
✗ Branch 49 → 71 not taken.
|
866 | return currentResult; |
391 | } | ||
392 | |||
393 | 83005 | std::any TypeChecker::visitCastExpr(CastExprNode *node) { | |
394 | // Check if cast is applied | ||
395 |
2/2✓ Branch 2 → 3 taken 80552 times.
✓ Branch 2 → 5 taken 2453 times.
|
83005 | if (!node->isCast) |
396 |
2/2✓ Branch 3 → 4 taken 80543 times.
✓ Branch 3 → 65 taken 9 times.
|
80552 | return visit(node->prefixUnaryExpr); |
397 | |||
398 | // Visit destination type | ||
399 |
2/4✓ Branch 5 → 6 taken 2453 times.
✗ Branch 5 → 49 not taken.
✓ Branch 6 → 7 taken 2453 times.
✗ Branch 6 → 47 not taken.
|
2453 | const auto dstType = std::any_cast<QualType>(visit(node->dataType)); |
400 |
2/8✓ Branch 8 → 9 taken 2453 times.
✗ Branch 8 → 65 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 14 taken 2453 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 50 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 50 not taken.
|
2453 | HANDLE_UNRESOLVED_TYPE_ER(dstType) |
401 | // Visit source type | ||
402 |
2/4✓ Branch 14 → 15 taken 2453 times.
✗ Branch 14 → 53 not taken.
✓ Branch 15 → 16 taken 2453 times.
✗ Branch 15 → 51 not taken.
|
2453 | const auto src = std::any_cast<ExprResult>(visit(node->assignExpr)); |
403 |
2/8✓ Branch 17 → 18 taken 2453 times.
✗ Branch 17 → 65 not taken.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 23 taken 2453 times.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 54 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 54 not taken.
|
2453 | HANDLE_UNRESOLVED_TYPE_ER(src.type) |
404 | |||
405 | // Check for identity cast | ||
406 |
3/4✓ Branch 23 → 24 taken 2453 times.
✗ Branch 23 → 65 not taken.
✓ Branch 24 → 25 taken 241 times.
✓ Branch 24 → 34 taken 2212 times.
|
2453 | if (src.type == dstType) { |
407 |
2/4✓ Branch 27 → 28 taken 241 times.
✗ Branch 27 → 57 not taken.
✓ Branch 28 → 29 taken 241 times.
✗ Branch 28 → 55 not taken.
|
241 | const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified."); |
408 |
1/2✓ Branch 31 → 32 taken 241 times.
✗ Branch 31 → 61 not taken.
|
241 | sourceFile->compilerOutput.warnings.push_back(warning); |
409 | 241 | } | |
410 | |||
411 | // Get result type | ||
412 |
1/2✓ Branch 34 → 35 taken 2453 times.
✗ Branch 34 → 65 not taken.
|
2453 | const QualType resultType = opRuleManager.getCastResultType(node, dstType, src); |
413 | |||
414 |
1/2✓ Branch 35 → 36 taken 2453 times.
✗ Branch 35 → 65 not taken.
|
2453 | const bool typesMatch = dstType.matches(src.type, false, true, true); |
415 |
1/2✓ Branch 36 → 37 taken 2453 times.
✗ Branch 36 → 65 not taken.
|
2453 | const bool sameContainerType = src.type.isSameContainerTypeAs(dstType); |
416 |
4/4✓ Branch 37 → 38 taken 2212 times.
✓ Branch 37 → 39 taken 241 times.
✓ Branch 38 → 39 taken 131 times.
✓ Branch 38 → 40 taken 2081 times.
|
2453 | SymbolTableEntry *entry = typesMatch || sameContainerType ? src.entry : nullptr; |
417 |
2/4✓ Branch 41 → 42 taken 2453 times.
✗ Branch 41 → 64 not taken.
✓ Branch 42 → 43 taken 2453 times.
✗ Branch 42 → 64 not taken.
|
2453 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry}; |
418 | } | ||
419 | |||
420 | 87936 | std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { | |
421 | // If no operator is applied, simply visit the postfix unary expression | ||
422 |
2/2✓ Branch 2 → 3 taken 86857 times.
✓ Branch 2 → 5 taken 1079 times.
|
87936 | if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE) |
423 |
2/2✓ Branch 3 → 4 taken 86849 times.
✓ Branch 3 → 78 taken 8 times.
|
86857 | return visit(node->postfixUnaryExpr); |
424 | |||
425 | // Visit the right side | ||
426 | 1079 | PrefixUnaryExprNode *rhsNode = node->prefixUnaryExpr; | |
427 |
2/4✓ Branch 5 → 6 taken 1079 times.
✗ Branch 5 → 57 not taken.
✓ Branch 6 → 7 taken 1079 times.
✗ Branch 6 → 55 not taken.
|
1079 | auto operand = std::any_cast<ExprResult>(visit(rhsNode)); |
428 | 1079 | auto [operandType, operandEntry] = operand; | |
429 |
5/8✓ Branch 8 → 9 taken 1079 times.
✗ Branch 8 → 78 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 14 taken 1078 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 58 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 58 not taken.
|
1079 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
430 | // Determine action, based on the given operator | ||
431 |
7/8✓ Branch 14 → 15 taken 16 times.
✓ Branch 14 → 17 taken 23 times.
✓ Branch 14 → 25 taken 8 times.
✓ Branch 14 → 33 taken 731 times.
✓ Branch 14 → 35 taken 1 time.
✓ Branch 14 → 37 taken 207 times.
✓ Branch 14 → 39 taken 92 times.
✗ Branch 14 → 41 not taken.
|
1078 | switch (node->op) { |
432 | 16 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS: | |
433 |
1/2✓ Branch 15 → 16 taken 16 times.
✗ Branch 15 → 59 not taken.
|
16 | operandType = OpRuleManager::getPrefixMinusResultType(node, operand); |
434 | 16 | break; | |
435 | 23 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_PLUS_PLUS: | |
436 |
1/2✓ Branch 17 → 18 taken 23 times.
✗ Branch 17 → 60 not taken.
|
23 | operandType = opRuleManager.getPrefixPlusPlusResultType(node, operand); |
437 | |||
438 |
2/2✓ Branch 18 → 19 taken 20 times.
✓ Branch 18 → 24 taken 3 times.
|
23 | if (operandEntry) { |
439 | // In case the lhs is captured, notify the capture about the write access | ||
440 |
2/4✓ Branch 19 → 20 taken 20 times.
✗ Branch 19 → 78 not taken.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 20 times.
|
20 | 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 22 → 23 taken 20 times.
✗ Branch 22 → 61 not taken.
|
20 | operandEntry->updateState(INITIALIZED, node); |
445 | } | ||
446 | |||
447 | 23 | break; | |
448 | 8 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS_MINUS: | |
449 |
2/2✓ Branch 25 → 26 taken 7 times.
✓ Branch 25 → 62 taken 1 time.
|
8 | operandType = opRuleManager.getPrefixMinusMinusResultType(node, operand); |
450 | |||
451 |
2/2✓ Branch 26 → 27 taken 4 times.
✓ Branch 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 27 → 28 taken 4 times.
✗ Branch 27 → 78 not taken.
✗ Branch 28 → 29 not taken.
✓ Branch 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 30 → 31 taken 4 times.
✗ Branch 30 → 63 not taken.
|
4 | operandEntry->updateState(INITIALIZED, node); |
458 | } | ||
459 | |||
460 | 7 | break; | |
461 | 731 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT: | |
462 |
1/2✓ Branch 33 → 34 taken 731 times.
✗ Branch 33 → 64 not taken.
|
731 | operandType = OpRuleManager::getPrefixNotResultType(node, operand); |
463 | 731 | break; | |
464 | 1 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_BITWISE_NOT: | |
465 |
1/2✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 65 not taken.
|
1 | operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operand); |
466 | 1 | break; | |
467 | 207 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE: | |
468 |
1/2✓ Branch 37 → 38 taken 207 times.
✗ Branch 37 → 66 not taken.
|
207 | operandType = OpRuleManager::getPrefixMulResultType(node, operand); |
469 | 207 | break; | |
470 | 92 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF: | |
471 |
1/2✓ Branch 39 → 40 taken 92 times.
✗ Branch 39 → 67 not taken.
|
92 | operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand); |
472 | 92 | break; | |
473 | − | default: // GCOV_EXCL_LINE | |
474 | − | throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
475 | } | ||
476 | |||
477 |
2/4✓ Branch 49 → 50 taken 1077 times.
✗ Branch 49 → 77 not taken.
✓ Branch 50 → 51 taken 1077 times.
✗ Branch 50 → 77 not taken.
|
1077 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
478 | } | ||
479 | |||
480 | 108025 | std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { | |
481 | // If no operator is applied, simply visit the atomic expression | ||
482 |
2/2✓ Branch 2 → 3 taken 86857 times.
✓ Branch 2 → 5 taken 21168 times.
|
108025 | if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE) |
483 |
2/2✓ Branch 3 → 4 taken 86850 times.
✓ Branch 3 → 316 taken 7 times.
|
86857 | return visit(node->atomicExpr); |
484 | |||
485 | // Visit left side | ||
486 | 21168 | PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr; | |
487 |
2/4✓ Branch 5 → 6 taken 21168 times.
✗ Branch 5 → 211 not taken.
✓ Branch 6 → 7 taken 21168 times.
✗ Branch 6 → 209 not taken.
|
21168 | auto operand = std::any_cast<ExprResult>(visit(lhsNode)); |
488 | 21168 | auto [operandType, operandEntry] = operand; | |
489 |
5/8✓ Branch 8 → 9 taken 21168 times.
✗ Branch 8 → 316 not taken.
✓ Branch 9 → 10 taken 6 times.
✓ Branch 9 → 14 taken 21162 times.
✓ Branch 10 → 11 taken 6 times.
✗ Branch 10 → 212 not taken.
✓ Branch 11 → 12 taken 6 times.
✗ Branch 11 → 212 not taken.
|
21168 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
490 | |||
491 |
4/5✓ Branch 14 → 15 taken 3225 times.
✓ Branch 14 → 101 taken 15807 times.
✓ Branch 14 → 159 taken 1731 times.
✓ Branch 14 → 167 taken 399 times.
✗ Branch 14 → 175 not taken.
|
21162 | switch (node->op) { |
492 | 3225 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: { | |
493 | // Visit index assignment | ||
494 | 3225 | AssignExprNode *indexAssignExpr = node->subscriptIndexExpr; | |
495 |
2/4✓ Branch 15 → 16 taken 3225 times.
✗ Branch 15 → 215 not taken.
✓ Branch 16 → 17 taken 3225 times.
✗ Branch 16 → 213 not taken.
|
3225 | const auto index = std::any_cast<ExprResult>(visit(indexAssignExpr)); |
496 |
2/8✓ Branch 18 → 19 taken 3225 times.
✗ Branch 18 → 258 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 24 taken 3225 times.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 216 not taken.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 216 not taken.
|
3225 | 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 24 → 25 taken 3225 times.
✗ Branch 24 → 217 not taken.
|
3225 | const auto [type, _] = opRuleManager.isOperatorOverloadingFctAvailable<2>(node, OP_FCT_SUBSCRIPT, {operand, index}, 0); |
500 |
3/4✓ Branch 25 → 26 taken 3225 times.
✗ Branch 25 → 258 not taken.
✓ Branch 26 → 27 taken 114 times.
✓ Branch 26 → 28 taken 3111 times.
|
3225 | if (!type.is(TY_INVALID)) { |
501 | 114 | operandType = type; | |
502 | 3223 | break; | |
503 | } | ||
504 | |||
505 |
1/2✓ Branch 28 → 29 taken 3111 times.
✗ Branch 28 → 218 not taken.
|
3111 | operandType = operandType.removeReferenceWrapper(); |
506 | |||
507 | // Check if the index is of the right type | ||
508 |
3/4✓ Branch 29 → 30 taken 3111 times.
✗ Branch 29 → 219 not taken.
✓ Branch 30 → 31 taken 1 time.
✓ Branch 30 → 41 taken 3110 times.
|
3111 | if (!index.type.isOneOf({TY_INT, TY_LONG})) |
509 |
4/8✓ Branch 33 → 34 taken 1 time.
✗ Branch 33 → 222 not taken.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 220 not taken.
✓ Branch 37 → 38 taken 1 time.
✗ Branch 37 → 226 not taken.
✓ Branch 38 → 39 taken 1 time.
✗ Branch 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 41 → 42 taken 3110 times.
✗ Branch 41 → 227 not taken.
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 52 taken 3110 times.
|
3110 | 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 52 → 53 taken 3110 times.
✗ Branch 52 → 258 not taken.
✓ Branch 53 → 54 taken 2235 times.
✓ Branch 53 → 57 taken 875 times.
✓ Branch 54 → 55 taken 2235 times.
✗ Branch 54 → 258 not taken.
✗ Branch 55 → 56 not taken.
✓ Branch 55 → 57 taken 2235 times.
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 69 taken 3110 times.
|
3110 | 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 69 → 70 taken 3110 times.
✗ Branch 69 → 258 not taken.
✓ Branch 70 → 71 taken 140 times.
✓ Branch 70 → 76 taken 2970 times.
✓ Branch 71 → 72 taken 140 times.
✗ Branch 71 → 258 not taken.
✓ Branch 72 → 73 taken 99 times.
✓ Branch 72 → 76 taken 41 times.
✓ Branch 73 → 74 taken 99 times.
✗ Branch 73 → 258 not taken.
✓ Branch 74 → 75 taken 34 times.
✓ Branch 74 → 76 taken 65 times.
✓ Branch 77 → 78 taken 34 times.
✓ Branch 77 → 96 taken 3076 times.
|
3110 | if (operandType.isArray() && operandType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) { |
524 |
1/2✓ Branch 78 → 79 taken 34 times.
✗ Branch 78 → 258 not taken.
|
34 | const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue; |
525 |
1/2✓ Branch 79 → 80 taken 34 times.
✗ Branch 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 80 → 81 taken 1 time.
✓ Branch 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 83 → 84 taken 1 time.
✗ Branch 83 → 248 not taken.
✓ Branch 84 → 85 taken 1 time.
✗ Branch 84 → 246 not taken.
✓ Branch 85 → 86 taken 1 time.
✗ Branch 85 → 244 not taken.
✓ Branch 86 → 87 taken 1 time.
✗ Branch 86 → 242 not taken.
✓ Branch 90 → 91 taken 1 time.
✗ Branch 90 → 251 not taken.
✓ Branch 91 → 92 taken 1 time.
✗ Branch 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 96 → 97 taken 3109 times.
✗ Branch 96 → 257 not taken.
|
3109 | operandType = operandType.getContained(); |
537 | |||
538 | // Remove heap qualifier | ||
539 | 3109 | operandType.getQualifiers().isHeap = false; | |
540 | |||
541 | 3109 | break; | |
542 | } | ||
543 | 15807 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: { | |
544 | 15807 | const std::string &fieldName = node->identifier; | |
545 | |||
546 | // Check if lhs is enum or strobj | ||
547 |
1/2✓ Branch 101 → 102 taken 15807 times.
✗ Branch 101 → 286 not taken.
|
15807 | const QualType lhsBaseTy = operandType.autoDeReference(); |
548 |
3/4✓ Branch 102 → 103 taken 15807 times.
✗ Branch 102 → 286 not taken.
✓ Branch 103 → 104 taken 1 time.
✓ Branch 103 → 113 taken 15806 times.
|
15807 | if (!lhsBaseTy.is(TY_STRUCT)) |
549 |
5/10✓ Branch 104 → 105 taken 1 time.
✗ Branch 104 → 263 not taken.
✓ Branch 105 → 106 taken 1 time.
✗ Branch 105 → 261 not taken.
✓ Branch 106 → 107 taken 1 time.
✗ Branch 106 → 259 not taken.
✓ Branch 109 → 110 taken 1 time.
✗ Branch 109 → 265 not taken.
✓ Branch 110 → 111 taken 1 time.
✗ Branch 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 113 → 114 taken 15806 times.
✗ Branch 113 → 286 not taken.
|
15806 | const std::string &structName = lhsBaseTy.getSubType(); |
553 |
1/2✓ Branch 114 → 115 taken 15806 times.
✗ Branch 114 → 286 not taken.
|
15806 | Scope *structScope = lhsBaseTy.getBodyScope(); |
554 | |||
555 | // If we only have the generic struct scope, lookup the concrete manifestation scope | ||
556 |
2/2✓ Branch 115 → 116 taken 119 times.
✓ Branch 115 → 120 taken 15687 times.
|
15806 | if (structScope->isGenericScope) { |
557 |
1/2✓ Branch 116 → 117 taken 119 times.
✗ Branch 116 → 286 not taken.
|
119 | const Struct *spiceStruct = lhsBaseTy.getStruct(node); |
558 |
1/2✗ Branch 117 → 118 not taken.
✓ Branch 117 → 119 taken 119 times.
|
119 | assert(spiceStruct != nullptr); |
559 | 119 | structScope = spiceStruct->scope; | |
560 | } | ||
561 |
1/2✗ Branch 120 → 121 not taken.
✓ Branch 120 → 122 taken 15806 times.
|
15806 | assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope |
562 | |||
563 | // Get accessed field | ||
564 | 15806 | std::vector<size_t> indexPath; | |
565 |
1/2✓ Branch 122 → 123 taken 15806 times.
✗ Branch 122 → 284 not taken.
|
15806 | SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath); |
566 |
2/2✓ Branch 123 → 124 taken 2 times.
✓ Branch 123 → 135 taken 15804 times.
|
15806 | if (!memberEntry) |
567 |
6/12✓ Branch 124 → 125 taken 2 times.
✗ Branch 124 → 272 not taken.
✓ Branch 125 → 126 taken 2 times.
✗ Branch 125 → 270 not taken.
✓ Branch 126 → 127 taken 2 times.
✗ Branch 126 → 268 not taken.
✓ Branch 127 → 128 taken 2 times.
✗ Branch 127 → 266 not taken.
✓ Branch 131 → 132 taken 2 times.
✗ Branch 131 → 275 not taken.
✓ Branch 132 → 133 taken 2 times.
✗ Branch 132 → 275 not taken.
|
2 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Field '" + node->identifier + "' not found in struct " + structName) |
568 |
1/2✓ Branch 135 → 136 taken 15804 times.
✗ Branch 135 → 284 not taken.
|
15804 | const QualType memberType = memberEntry->getQualType(); |
569 | |||
570 | // Check for insufficient visibility | ||
571 |
8/14✓ Branch 136 → 137 taken 15804 times.
✗ Branch 136 → 276 not taken.
✓ Branch 137 → 138 taken 79 times.
✓ Branch 137 → 143 taken 15725 times.
✓ Branch 138 → 139 taken 79 times.
✗ Branch 138 → 276 not taken.
✓ Branch 139 → 140 taken 79 times.
✗ Branch 139 → 276 not taken.
✓ Branch 140 → 141 taken 79 times.
✗ Branch 140 → 276 not taken.
✗ Branch 141 → 142 not taken.
✓ Branch 141 → 143 taken 79 times.
✗ Branch 144 → 145 not taken.
✓ Branch 144 → 154 taken 15804 times.
|
15804 | 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 | 15804 | memberEntry->used = true; | |
576 | |||
577 | // Overwrite type and entry of left side with member type and entry | ||
578 | 15804 | operandType = memberType; | |
579 | 15804 | operandEntry = memberEntry; | |
580 | 15804 | break; | |
581 |
2/2✓ Branch 156 → 157 taken 2 times.
✓ Branch 156 → 158 taken 15804 times.
|
15806 | } |
582 | 1731 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: { | |
583 |
2/2✓ Branch 159 → 160 taken 1730 times.
✓ Branch 159 → 287 taken 1 time.
|
1731 | operandType = opRuleManager.getPostfixPlusPlusResultType(node, operand, 0).type; |
584 | |||
585 |
2/2✓ Branch 160 → 161 taken 1726 times.
✓ Branch 160 → 166 taken 4 times.
|
1730 | if (operandEntry) { |
586 | // In case the lhs is captured, notify the capture about the write access | ||
587 |
3/4✓ Branch 161 → 162 taken 1726 times.
✗ Branch 161 → 316 not taken.
✓ Branch 162 → 163 taken 4 times.
✓ Branch 162 → 164 taken 1722 times.
|
1726 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
588 |
1/2✓ Branch 163 → 164 taken 4 times.
✗ Branch 163 → 316 not taken.
|
4 | lhsCapture->setAccessType(READ_WRITE); |
589 | |||
590 | // Update the state of the variable | ||
591 |
1/2✓ Branch 164 → 165 taken 1726 times.
✗ Branch 164 → 288 not taken.
|
1726 | operandEntry->updateState(INITIALIZED, node); |
592 | } | ||
593 | |||
594 | 1730 | break; | |
595 | } | ||
596 | 399 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: { | |
597 |
1/2✓ Branch 167 → 168 taken 399 times.
✗ Branch 167 → 289 not taken.
|
399 | operandType = opRuleManager.getPostfixMinusMinusResultType(node, operand, 0).type; |
598 | |||
599 |
2/2✓ Branch 168 → 169 taken 395 times.
✓ Branch 168 → 174 taken 4 times.
|
399 | if (operandEntry) { |
600 | // In case the lhs is captured, notify the capture about the write access | ||
601 |
2/4✓ Branch 169 → 170 taken 395 times.
✗ Branch 169 → 316 not taken.
✗ Branch 170 → 171 not taken.
✓ Branch 170 → 172 taken 395 times.
|
395 | 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 172 → 173 taken 395 times.
✗ Branch 172 → 290 not taken.
|
395 | operandEntry->updateState(INITIALIZED, node); |
606 | } | ||
607 | |||
608 | 399 | break; | |
609 | } | ||
610 | − | default: // GCOV_EXCL_LINE | |
611 | − | throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
612 | } | ||
613 | |||
614 |
2/4✓ Branch 183 → 184 taken 21156 times.
✗ Branch 183 → 316 not taken.
✗ Branch 184 → 185 not taken.
✓ Branch 184 → 203 taken 21156 times.
|
21156 | 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 203 → 204 taken 21156 times.
✗ Branch 203 → 315 not taken.
✓ Branch 204 → 205 taken 21156 times.
✗ Branch 204 → 315 not taken.
|
21156 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
620 | } | ||
621 | |||
622 | 86857 | std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) { | |
623 | // Check if constant | ||
624 |
2/2✓ Branch 2 → 3 taken 17048 times.
✓ Branch 2 → 5 taken 69809 times.
|
86857 | if (node->constant) |
625 |
1/2✓ Branch 3 → 4 taken 17048 times.
✗ Branch 3 → 219 not taken.
|
17048 | return visit(node->constant); |
626 | |||
627 | // Check if value | ||
628 |
2/2✓ Branch 5 → 6 taken 17079 times.
✓ Branch 5 → 8 taken 52730 times.
|
69809 | if (node->value) |
629 |
2/2✓ Branch 6 → 7 taken 17075 times.
✓ Branch 6 → 219 taken 4 times.
|
17079 | return visit(node->value); |
630 | |||
631 | // Check for builtin calls | ||
632 |
2/2✓ Branch 8 → 9 taken 1679 times.
✓ Branch 8 → 11 taken 51051 times.
|
52730 | if (node->builtinCall) |
633 |
1/2✓ Branch 9 → 10 taken 1679 times.
✗ Branch 9 → 219 not taken.
|
1679 | return visit(node->builtinCall); |
634 | |||
635 | // Check for assign expression within parentheses | ||
636 |
2/2✓ Branch 11 → 12 taken 555 times.
✓ Branch 11 → 14 taken 50496 times.
|
51051 | if (node->assignExpr) |
637 |
2/2✓ Branch 12 → 13 taken 552 times.
✓ Branch 12 → 219 taken 3 times.
|
555 | return visit(node->assignExpr); |
638 | |||
639 | // Identifier (local or global variable access) | ||
640 |
1/2✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 50496 times.
|
50496 | assert(!node->fqIdentifier.empty()); |
641 | |||
642 |
1/2✓ Branch 17 → 18 taken 50496 times.
✗ Branch 17 → 219 not taken.
|
50496 | auto &[entry, accessScope, capture] = node->data.at(manIdx); |
643 | 50496 | accessScope = currentScope; | |
644 | |||
645 | // Check if a local or global variable can be found by searching for the name | ||
646 |
2/2✓ Branch 19 → 20 taken 50211 times.
✓ Branch 19 → 25 taken 285 times.
|
50496 | if (node->identifierFragments.size() == 1) |
647 | 100422 | entry = accessScope->lookup(node->identifierFragments.back()); | |
648 | |||
649 | // If no local or global was found, search in the name registry | ||
650 |
2/2✓ Branch 25 → 26 taken 361 times.
✓ Branch 25 → 38 taken 50135 times.
|
50496 | if (!entry) { |
651 |
1/2✓ Branch 26 → 27 taken 361 times.
✗ Branch 26 → 219 not taken.
|
361 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier); |
652 |
2/2✓ Branch 27 → 28 taken 1 time.
✓ Branch 27 → 37 taken 360 times.
|
361 | if (!registryEntry) |
653 |
5/10✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 167 not taken.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 165 not taken.
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 163 not taken.
✓ Branch 33 → 34 taken 1 time.
✗ Branch 33 → 169 not taken.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 169 not taken.
|
1 | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found") |
654 | 360 | entry = registryEntry->targetEntry; | |
655 | 360 | accessScope = registryEntry->targetScope; | |
656 | } | ||
657 |
1/2✗ Branch 38 → 39 not taken.
✓ Branch 38 → 40 taken 50495 times.
|
50495 | assert(entry != nullptr); |
658 | 50495 | entry->used = true; | |
659 |
1/2✓ Branch 40 → 41 taken 50495 times.
✗ Branch 40 → 219 not taken.
|
50495 | capture = accessScope->symbolTable.lookupCapture(entry->name); |
660 | |||
661 |
1/2✓ Branch 41 → 42 taken 50495 times.
✗ Branch 41 → 219 not taken.
|
50495 | const QualType varType = entry->getQualType(); |
662 |
5/8✓ Branch 42 → 43 taken 50495 times.
✗ Branch 42 → 219 not taken.
✓ Branch 43 → 44 taken 9 times.
✓ Branch 43 → 48 taken 50486 times.
✓ Branch 44 → 45 taken 9 times.
✗ Branch 44 → 170 not taken.
✓ Branch 45 → 46 taken 9 times.
✗ Branch 45 → 170 not taken.
|
50495 | HANDLE_UNRESOLVED_TYPE_ER(varType) |
663 |
3/4✓ Branch 48 → 49 taken 50486 times.
✗ Branch 48 → 219 not taken.
✓ Branch 49 → 50 taken 2 times.
✓ Branch 49 → 59 taken 50484 times.
|
50486 | if (varType.is(TY_INVALID)) |
664 |
5/10✓ Branch 50 → 51 taken 2 times.
✗ Branch 50 → 175 not taken.
✓ Branch 51 → 52 taken 2 times.
✗ Branch 51 → 173 not taken.
✓ Branch 52 → 53 taken 2 times.
✗ Branch 52 → 171 not taken.
✓ Branch 55 → 56 taken 2 times.
✗ Branch 55 → 177 not taken.
✓ Branch 56 → 57 taken 2 times.
✗ Branch 56 → 177 not taken.
|
2 | SOFT_ERROR_ER(node, USED_BEFORE_DECLARED, "Symbol '" + entry->name + "' was used before declared.") |
665 | |||
666 |
7/8✓ Branch 59 → 60 taken 50484 times.
✗ Branch 59 → 178 not taken.
✓ Branch 60 → 61 taken 25 times.
✓ Branch 60 → 63 taken 50459 times.
✓ Branch 61 → 62 taken 9 times.
✓ Branch 61 → 63 taken 16 times.
✓ Branch 64 → 65 taken 9 times.
✓ Branch 64 → 93 taken 50475 times.
|
50484 | if (varType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && entry->global) { |
667 | // Check if overloaded function was referenced | ||
668 |
1/2✓ Branch 65 → 66 taken 9 times.
✗ Branch 65 → 219 not taken.
|
9 | const std::vector<Function *> *manifestations = entry->declNode->getFctManifestations(entry->name); |
669 |
2/2✓ Branch 67 → 68 taken 1 time.
✓ Branch 67 → 78 taken 8 times.
|
9 | if (manifestations->size() > 1) |
670 |
4/8✓ Branch 70 → 71 taken 1 time.
✗ Branch 70 → 181 not taken.
✓ Branch 71 → 72 taken 1 time.
✗ Branch 71 → 179 not taken.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 185 not taken.
✓ Branch 75 → 76 taken 1 time.
✗ Branch 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 80 → 81 taken 1 time.
✓ Branch 80 → 91 taken 7 times.
|
8 | if (!manifestations->front()->templateTypes.empty()) |
672 |
4/8✓ Branch 83 → 84 taken 1 time.
✗ Branch 83 → 188 not taken.
✓ Branch 84 → 85 taken 1 time.
✗ Branch 84 → 186 not taken.
✓ Branch 87 → 88 taken 1 time.
✗ Branch 87 → 192 not taken.
✓ Branch 88 → 89 taken 1 time.
✗ Branch 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 93 → 94 taken 50482 times.
✗ Branch 93 → 219 not taken.
|
50482 | const QualType baseType = varType.getBase(); |
681 |
6/10✓ Branch 94 → 95 taken 50482 times.
✗ Branch 94 → 219 not taken.
✓ Branch 95 → 96 taken 2 times.
✓ Branch 95 → 99 taken 50480 times.
✓ Branch 96 → 97 taken 2 times.
✗ Branch 96 → 219 not taken.
✗ Branch 97 → 98 not taken.
✓ Branch 97 → 99 taken 2 times.
✗ Branch 100 → 101 not taken.
✓ Branch 100 → 112 taken 50482 times.
|
50482 | 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 112 → 113 taken 1 time.
✓ Branch 112 → 117 taken 50481 times.
✓ Branch 114 → 115 taken 1 time.
✗ Branch 114 → 219 not taken.
✓ Branch 115 → 116 taken 1 time.
✗ Branch 115 → 117 not taken.
✓ Branch 118 → 119 taken 1 time.
✓ Branch 118 → 128 taken 50481 times.
|
50482 | if (entry->scope->type == ScopeType::STRUCT && node->identifierFragments.front() != THIS_VARIABLE_NAME) |
686 |
5/10✓ Branch 119 → 120 taken 1 time.
✗ Branch 119 → 207 not taken.
✓ Branch 120 → 121 taken 1 time.
✗ Branch 120 → 205 not taken.
✓ Branch 121 → 122 taken 1 time.
✗ Branch 121 → 203 not taken.
✓ Branch 124 → 125 taken 1 time.
✗ Branch 124 → 209 not taken.
✓ Branch 125 → 126 taken 1 time.
✗ Branch 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 128 → 129 taken 50481 times.
✗ Branch 128 → 219 not taken.
✓ Branch 129 → 130 taken 199 times.
✓ Branch 129 → 132 taken 50282 times.
✓ Branch 130 → 131 taken 78 times.
✓ Branch 130 → 132 taken 121 times.
✓ Branch 133 → 134 taken 78 times.
✓ Branch 133 → 147 taken 50403 times.
|
50481 | if (accessScope->isImportedBy(rootScope) && accessScope->type != ScopeType::ENUM) |
692 |
5/8✓ Branch 134 → 135 taken 78 times.
✗ Branch 134 → 210 not taken.
✓ Branch 135 → 136 taken 78 times.
✗ Branch 135 → 210 not taken.
✓ Branch 136 → 137 taken 78 times.
✗ Branch 136 → 210 not taken.
✓ Branch 137 → 138 taken 1 time.
✓ Branch 137 → 147 taken 77 times.
|
78 | if (!entry->getQualType().getBase().isPublic()) |
693 |
5/10✓ Branch 138 → 139 taken 1 time.
✗ Branch 138 → 215 not taken.
✓ Branch 139 → 140 taken 1 time.
✗ Branch 139 → 213 not taken.
✓ Branch 140 → 141 taken 1 time.
✗ Branch 140 → 211 not taken.
✓ Branch 143 → 144 taken 1 time.
✗ Branch 143 → 217 not taken.
✓ Branch 144 → 145 taken 1 time.
✗ Branch 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 147 → 148 taken 280 times.
✓ Branch 147 → 149 taken 50200 times.
|
50480 | if (entry->scope->type == ScopeType::ENUM) |
697 | 280 | accessScope = entry->scope; | |
698 | |||
699 | // For struct access, use access scope of the struct | ||
700 |
3/4✓ Branch 149 → 150 taken 50480 times.
✗ Branch 149 → 219 not taken.
✓ Branch 150 → 151 taken 17930 times.
✓ Branch 150 → 157 taken 32550 times.
|
50480 | if (baseType.is(TY_STRUCT)) { |
701 |
1/2✓ Branch 151 → 152 taken 17930 times.
✗ Branch 151 → 219 not taken.
|
17930 | const std::string &structName = baseType.getSubType(); |
702 |
1/2✓ Branch 152 → 153 taken 17930 times.
✗ Branch 152 → 219 not taken.
|
17930 | const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(structName); |
703 |
1/2✗ Branch 153 → 154 not taken.
✓ Branch 153 → 155 taken 17930 times.
|
17930 | assert(nameRegistryEntry != nullptr); |
704 | 17930 | accessScope = nameRegistryEntry->targetScope; | |
705 |
1/2✗ Branch 155 → 156 not taken.
✓ Branch 155 → 157 taken 17930 times.
|
17930 | assert(accessScope != nullptr); |
706 | } | ||
707 | |||
708 |
2/4✓ Branch 157 → 158 taken 50480 times.
✗ Branch 157 → 218 not taken.
✓ Branch 158 → 159 taken 50480 times.
✗ Branch 158 → 218 not taken.
|
50480 | return ExprResult{node->setEvaluatedSymbolType(varType, manIdx), entry}; |
709 | } | ||
710 | |||
711 | } // namespace spice::compiler | ||
712 |