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 | 64248 | std::any TypeChecker::visitAssignExpr(AssignExprNode *node) { | |
13 | // Check if ternary | ||
14 |
2/2✓ Branch 0 (2→3) taken 58711 times.
✓ Branch 1 (2→10) taken 5537 times.
|
64248 | if (node->ternaryExpr) { |
15 |
3/4✓ Branch 0 (3→4) taken 58696 times.
✓ Branch 1 (3→97) taken 15 times.
✓ Branch 2 (4→5) taken 58696 times.
✗ Branch 3 (4→95) not taken.
|
58711 | auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr)); |
16 |
1/2✓ Branch 0 (6→7) taken 58696 times.
✗ Branch 1 (6→98) not taken.
|
58696 | node->setEvaluatedSymbolType(result.type, manIdx); |
17 |
1/2✓ Branch 0 (7→8) taken 58696 times.
✗ Branch 1 (7→98) not taken.
|
58696 | return result; |
18 | } | ||
19 | |||
20 | // Check if assignment | ||
21 |
1/2✓ Branch 0 (10→11) taken 5537 times.
✗ Branch 1 (10→86) not taken.
|
5537 | if (node->op != AssignExprNode::AssignOp::OP_NONE) { |
22 | // Visit the right side first | ||
23 |
2/4✓ Branch 0 (11→12) taken 5537 times.
✗ Branch 1 (11→101) not taken.
✓ Branch 2 (12→13) taken 5537 times.
✗ Branch 3 (12→99) not taken.
|
5537 | auto rhs = std::any_cast<ExprResult>(visit(node->rhs)); |
24 | 5537 | auto [rhsType, rhsEntry] = rhs; | |
25 |
5/8✓ Branch 0 (14→15) taken 5537 times.
✗ Branch 1 (14→120) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→20) taken 5536 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.
|
5537 | HANDLE_UNRESOLVED_TYPE_ER(rhsType) |
26 | // Then visit the left side | ||
27 |
2/4✓ Branch 0 (20→21) taken 5536 times.
✗ Branch 1 (20→105) not taken.
✓ Branch 2 (21→22) taken 5536 times.
✗ Branch 3 (21→103) not taken.
|
5536 | auto lhs = std::any_cast<ExprResult>(visit(node->lhs)); |
28 | 5536 | auto [lhsType, lhsVar] = lhs; | |
29 |
5/8✓ Branch 0 (23→24) taken 5536 times.
✗ Branch 1 (23→120) not taken.
✓ Branch 2 (24→25) taken 1 times.
✓ Branch 3 (24→29) taken 5535 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.
|
5536 | HANDLE_UNRESOLVED_TYPE_ER(lhsType) |
30 | |||
31 | // Take a look at the operator | ||
32 |
2/2✓ Branch 0 (29→30) taken 4938 times.
✓ Branch 1 (29→42) taken 597 times.
|
5535 | if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) { |
33 |
8/10✓ Branch 0 (30→31) taken 4937 times.
✓ Branch 1 (30→37) taken 1 times.
✓ Branch 2 (31→32) taken 4937 times.
✗ Branch 3 (31→120) not taken.
✓ Branch 4 (32→33) taken 3955 times.
✓ Branch 5 (32→37) taken 982 times.
✓ Branch 6 (34→35) taken 3955 times.
✗ Branch 7 (34→120) not taken.
✓ Branch 8 (35→36) taken 1275 times.
✓ Branch 9 (35→37) taken 2680 times.
|
4938 | const bool isDecl = lhs.entry != nullptr && lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized(); |
34 |
2/2✓ Branch 0 (38→39) taken 4937 times.
✓ Branch 1 (38→107) taken 1 times.
|
4938 | 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 2308 times.
✓ Branch 1 (39→72) taken 2629 times.
✓ Branch 2 (40→41) taken 138 times.
✓ Branch 3 (40→72) taken 2170 times.
|
4937 | if (rhsEntry != nullptr && rhsEntry->anonymous) |
38 |
1/2✓ Branch 0 (41→72) taken 138 times.
✗ Branch 1 (41→120) not taken.
|
138 | currentScope->symbolTable.deleteAnonymous(rhsEntry->name); |
39 |
2/2✓ Branch 0 (42→43) taken 242 times.
✓ Branch 1 (42→45) taken 355 times.
|
597 | } else if (node->op == AssignExprNode::AssignOp::OP_PLUS_EQUAL) { |
40 |
1/2✓ Branch 0 (43→44) taken 242 times.
✗ Branch 1 (43→108) not taken.
|
242 | rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type; |
41 |
2/2✓ Branch 0 (45→46) taken 33 times.
✓ Branch 1 (45→48) taken 322 times.
|
355 | } 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 303 times.
|
322 | } 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 40 times.
✓ Branch 1 (51→54) taken 263 times.
|
303 | } else if (node->op == AssignExprNode::AssignOp::OP_DIV_EQUAL) { |
46 |
1/2✓ Branch 0 (52→53) taken 40 times.
✗ Branch 1 (52→111) not taken.
|
40 | rhsType = opRuleManager.getDivEqualResultType(node, lhs, rhs, 0).type; |
47 |
2/2✓ Branch 0 (54→55) taken 6 times.
✓ Branch 1 (54→57) taken 257 times.
|
263 | } 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 255 times.
|
257 | } 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 252 times.
|
255 | } 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 251 times.
|
252 | } 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 250 times.
|
251 | } 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 250 times.
✗ Branch 1 (69→72) not taken.
|
250 | } else if (node->op == AssignExprNode::AssignOp::OP_XOR_EQUAL) { |
58 |
1/2✓ Branch 0 (70→71) taken 250 times.
✗ Branch 1 (70→117) not taken.
|
250 | rhsType = opRuleManager.getXorEqualResultType(node, lhs, rhs); |
59 | } | ||
60 | |||
61 |
1/2✓ Branch 0 (72→73) taken 5534 times.
✗ Branch 1 (72→81) not taken.
|
5534 | if (lhsVar) { // Variable is involved on the left side |
62 | // Perform type inference | ||
63 |
3/4✓ Branch 0 (73→74) taken 5534 times.
✗ Branch 1 (73→120) not taken.
✓ Branch 2 (74→75) taken 1 times.
✓ Branch 3 (74→76) taken 5533 times.
|
5534 | 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 5534 times.
✗ Branch 1 (76→120) not taken.
✓ Branch 2 (77→78) taken 3 times.
✓ Branch 3 (77→79) taken 5531 times.
|
5534 | 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 5534 times.
✗ Branch 1 (79→118) not taken.
|
5534 | lhsVar->updateState(INITIALIZED, node); |
72 | } | ||
73 | |||
74 |
2/4✓ Branch 0 (81→82) taken 5534 times.
✗ Branch 1 (81→119) not taken.
✓ Branch 2 (82→83) taken 5534 times.
✗ Branch 3 (82→119) not taken.
|
5534 | return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)}; |
75 | } | ||
76 | |||
77 | − | throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE | |
78 | } | ||
79 | |||
80 | 59339 | std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) { | |
81 | // Check if there is a ternary operator applied | ||
82 |
2/2✓ Branch 0 (2→3) taken 58973 times.
✓ Branch 1 (2→5) taken 366 times.
|
59339 | if (!node->falseExpr) |
83 |
2/2✓ Branch 0 (3→4) taken 58958 times.
✓ Branch 1 (3→162) taken 15 times.
|
58973 | return visit(node->condition); |
84 | |||
85 | // Visit condition | ||
86 |
2/4✓ Branch 0 (5→6) taken 366 times.
✗ Branch 1 (5→127) not taken.
✓ Branch 2 (6→7) taken 366 times.
✗ Branch 3 (6→125) not taken.
|
366 | const auto condition = std::any_cast<ExprResult>(visit(node->condition)); |
87 |
2/8✓ Branch 0 (8→9) taken 366 times.
✗ Branch 1 (8→162) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 366 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→128) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→128) not taken.
|
366 | HANDLE_UNRESOLVED_TYPE_ER(condition.type) |
88 |
6/10✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→16) taken 365 times.
✓ Branch 2 (16→17) taken 365 times.
✗ Branch 3 (16→129) not taken.
✓ Branch 4 (17→18) taken 365 times.
✗ Branch 5 (17→129) not taken.
✓ Branch 6 (18→19) taken 365 times.
✓ Branch 7 (18→20) taken 1 times.
✗ Branch 8 (129→130) not taken.
✗ Branch 9 (129→131) not taken.
|
366 | const auto trueExpr = node->isShortened ? condition : std::any_cast<ExprResult>(visit(node->trueExpr)); |
89 | 366 | const auto [trueType, trueEntry] = trueExpr; | |
90 |
2/8✓ Branch 0 (20→21) taken 366 times.
✗ Branch 1 (20→162) not taken.
✗ Branch 2 (21→22) not taken.
✓ Branch 3 (21→26) taken 366 times.
✗ Branch 4 (22→23) not taken.
✗ Branch 5 (22→133) not taken.
✗ Branch 6 (23→24) not taken.
✗ Branch 7 (23→133) not taken.
|
366 | HANDLE_UNRESOLVED_TYPE_ER(trueType) |
91 |
2/4✓ Branch 0 (26→27) taken 366 times.
✗ Branch 1 (26→136) not taken.
✓ Branch 2 (27→28) taken 366 times.
✗ Branch 3 (27→134) not taken.
|
366 | const auto falseExpr = std::any_cast<ExprResult>(visit(node->falseExpr)); |
92 | 366 | const auto [falseType, falseEntry] = falseExpr; | |
93 |
2/8✓ Branch 0 (29→30) taken 366 times.
✗ Branch 1 (29→162) not taken.
✗ Branch 2 (30→31) not taken.
✓ Branch 3 (30→35) taken 366 times.
✗ Branch 4 (31→32) not taken.
✗ Branch 5 (31→137) not taken.
✗ Branch 6 (32→33) not taken.
✗ Branch 7 (32→137) not taken.
|
366 | HANDLE_UNRESOLVED_TYPE_ER(falseType) |
94 | |||
95 | // Check if the condition evaluates to bool | ||
96 |
3/4✓ Branch 0 (35→36) taken 366 times.
✗ Branch 1 (35→162) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→47) taken 365 times.
|
366 | if (!condition.type.is(TY_BOOL)) |
97 |
4/8✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→140) not taken.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→138) not taken.
✓ Branch 4 (43→44) taken 1 times.
✗ Branch 5 (43→144) not taken.
✓ Branch 6 (44→45) taken 1 times.
✗ Branch 7 (44→144) 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 365 times.
✗ Branch 1 (47→162) not taken.
|
365 | const QualType trueTypeModified = trueType.removeReferenceWrapper(); |
101 |
1/2✓ Branch 0 (48→49) taken 365 times.
✗ Branch 1 (48→162) not taken.
|
365 | const QualType falseTypeModified = falseType.removeReferenceWrapper(); |
102 |
3/4✓ Branch 0 (49→50) taken 365 times.
✗ Branch 1 (49→162) not taken.
✓ Branch 2 (50→51) taken 1 times.
✓ Branch 3 (50→66) taken 364 times.
|
365 | if (!trueTypeModified.matches(falseTypeModified, false, true, false)) |
103 |
8/16✓ Branch 0 (51→52) taken 1 times.
✗ Branch 1 (51→158) not taken.
✓ Branch 2 (52→53) taken 1 times.
✗ Branch 3 (52→153) not taken.
✓ Branch 4 (53→54) taken 1 times.
✗ Branch 5 (53→151) not taken.
✓ Branch 6 (54→55) taken 1 times.
✗ Branch 7 (54→149) not taken.
✓ Branch 8 (55→56) taken 1 times.
✗ Branch 9 (55→147) not taken.
✓ Branch 10 (56→57) taken 1 times.
✗ Branch 11 (56→145) not taken.
✓ Branch 12 (62→63) taken 1 times.
✗ Branch 13 (62→160) not taken.
✓ Branch 14 (63→64) taken 1 times.
✗ Branch 15 (63→160) 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 |
4/4✓ Branch 0 (66→67) taken 115 times.
✓ Branch 1 (66→69) taken 249 times.
✓ Branch 2 (67→68) taken 68 times.
✓ Branch 3 (67→69) taken 47 times.
|
364 | const bool removeAnonymousSymbolTrueSide = trueEntry && trueEntry->anonymous; |
110 |
2/2✓ Branch 0 (70→71) taken 68 times.
✓ Branch 1 (70→72) taken 296 times.
|
364 | if (removeAnonymousSymbolTrueSide) { |
111 |
1/2✓ Branch 0 (71→82) taken 68 times.
✗ Branch 1 (71→162) not taken.
|
68 | currentScope->symbolTable.deleteAnonymous(trueEntry->name); |
112 |
11/14✓ Branch 0 (72→73) taken 47 times.
✓ Branch 1 (72→79) taken 249 times.
✓ Branch 2 (73→74) taken 47 times.
✗ Branch 3 (73→79) not taken.
✓ Branch 4 (74→75) taken 47 times.
✗ Branch 5 (74→162) not taken.
✓ Branch 6 (75→76) taken 39 times.
✓ Branch 7 (75→79) taken 8 times.
✓ Branch 8 (76→77) taken 39 times.
✗ Branch 9 (76→162) not taken.
✓ Branch 10 (77→78) taken 8 times.
✓ Branch 11 (77→79) taken 31 times.
✓ Branch 12 (80→81) taken 8 times.
✓ Branch 13 (80→82) taken 288 times.
|
296 | } else if (trueEntry && !trueEntry->anonymous && !trueType.isRef() && !trueType.isTriviallyCopyable(node)) { |
113 | 8 | node->trueSideCallsCopyCtor = true; | |
114 | } | ||
115 |
4/4✓ Branch 0 (82→83) taken 291 times.
✓ Branch 1 (82→85) taken 73 times.
✓ Branch 2 (83→84) taken 67 times.
✓ Branch 3 (83→85) taken 224 times.
|
364 | const bool removeAnonymousSymbolFalseSide = falseEntry && falseEntry->anonymous; |
116 |
2/2✓ Branch 0 (86→87) taken 67 times.
✓ Branch 1 (86→88) taken 297 times.
|
364 | if (removeAnonymousSymbolFalseSide) { |
117 |
1/2✓ Branch 0 (87→98) taken 67 times.
✗ Branch 1 (87→162) not taken.
|
67 | currentScope->symbolTable.deleteAnonymous(falseEntry->name); |
118 |
11/14✓ Branch 0 (88→89) taken 224 times.
✓ Branch 1 (88→95) taken 73 times.
✓ Branch 2 (89→90) taken 224 times.
✗ Branch 3 (89→95) not taken.
✓ Branch 4 (90→91) taken 224 times.
✗ Branch 5 (90→162) not taken.
✓ Branch 6 (91→92) taken 215 times.
✓ Branch 7 (91→95) taken 9 times.
✓ Branch 8 (92→93) taken 215 times.
✗ Branch 9 (92→162) not taken.
✓ Branch 10 (93→94) taken 8 times.
✓ Branch 11 (93→95) taken 207 times.
✓ Branch 12 (96→97) taken 8 times.
✓ Branch 13 (96→98) taken 289 times.
|
297 | } else if (falseEntry && !falseEntry->anonymous && !falseType.isRef() && !falseType.isTriviallyCopyable(node)) { |
119 | 8 | node->falseSideCallsCopyCtor = true; | |
120 | } | ||
121 | |||
122 | // Create a new anonymous symbol for the result if required | ||
123 | 364 | const QualType &resultType = trueType; | |
124 | 364 | SymbolTableEntry *anonymousSymbol = nullptr; | |
125 |
4/4✓ Branch 0 (98→99) taken 296 times.
✓ Branch 1 (98→100) taken 68 times.
✓ Branch 2 (99→100) taken 2 times.
✓ Branch 3 (99→101) taken 294 times.
|
364 | const bool removedAnonymousSymbols = removeAnonymousSymbolTrueSide || removeAnonymousSymbolFalseSide; |
126 |
4/4✓ Branch 0 (102→103) taken 356 times.
✓ Branch 1 (102→104) taken 8 times.
✓ Branch 2 (103→104) taken 2 times.
✓ Branch 3 (103→105) taken 354 times.
|
364 | const bool calledCopyCtor = node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor; |
127 |
9/10✓ Branch 0 (106→107) taken 294 times.
✓ Branch 1 (106→110) taken 70 times.
✓ Branch 2 (107→108) taken 288 times.
✓ Branch 3 (107→110) taken 6 times.
✓ Branch 4 (108→109) taken 288 times.
✗ Branch 5 (108→162) not taken.
✓ Branch 6 (109→110) taken 8 times.
✓ Branch 7 (109→111) taken 280 times.
✓ Branch 8 (112→113) taken 84 times.
✓ Branch 9 (112→115) taken 280 times.
|
364 | if (removedAnonymousSymbols || calledCopyCtor || resultType.isRef()) |
128 |
1/2✓ Branch 0 (113→114) taken 84 times.
✗ Branch 1 (113→162) not taken.
|
84 | anonymousSymbol = currentScope->symbolTable.insertAnonymous(resultType, node); |
129 | |||
130 | // Lookup copy ctor, if at least one side needs it | ||
131 |
4/4✓ Branch 0 (115→116) taken 356 times.
✓ Branch 1 (115→117) taken 8 times.
✓ Branch 2 (116→117) taken 2 times.
✓ Branch 3 (116→119) taken 354 times.
|
364 | if (node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor) |
132 |
1/2✓ Branch 0 (117→118) taken 10 times.
✗ Branch 1 (117→162) not taken.
|
10 | node->calledCopyCtor = matchCopyCtor(trueTypeModified, node); |
133 | |||
134 |
2/4✓ Branch 0 (119→120) taken 364 times.
✗ Branch 1 (119→161) not taken.
✓ Branch 2 (120→121) taken 364 times.
✗ Branch 3 (120→161) not taken.
|
364 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), anonymousSymbol}; |
135 | } | ||
136 | |||
137 | 60070 | std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) { | |
138 | // Check if a logical or operator is applied | ||
139 |
2/2✓ Branch 0 (3→4) taken 59228 times.
✓ Branch 1 (3→7) taken 842 times.
|
60070 | if (node->operands.size() == 1) |
140 |
2/2✓ Branch 0 (5→6) taken 59214 times.
✓ Branch 1 (5→46) taken 14 times.
|
59228 | return visit(node->operands.front()); |
141 | |||
142 | // Visit leftmost operand | ||
143 |
2/4✓ Branch 0 (8→9) taken 842 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 842 times.
✗ Branch 3 (9→37) not taken.
|
842 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
144 |
2/8✓ Branch 0 (11→12) taken 842 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 842 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.
|
842 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
145 | |||
146 | // Loop through all remaining operands | ||
147 |
2/2✓ Branch 0 (31→18) taken 1082 times.
✓ Branch 1 (31→32) taken 841 times.
|
1923 | for (size_t i = 1; i < node->operands.size(); i++) { |
148 |
2/4✓ Branch 0 (19→20) taken 1082 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 1082 times.
✗ Branch 3 (20→41) not taken.
|
1082 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
149 |
2/8✓ Branch 0 (22→23) taken 1082 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 1082 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.
|
1082 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
150 |
2/2✓ Branch 0 (28→29) taken 1081 times.
✓ Branch 1 (28→45) taken 1 times.
|
1082 | currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)}; |
151 | } | ||
152 | |||
153 |
1/2✓ Branch 0 (32→33) taken 841 times.
✗ Branch 1 (32→46) not taken.
|
841 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
154 |
1/2✓ Branch 0 (33→34) taken 841 times.
✗ Branch 1 (33→46) not taken.
|
841 | return currentOperand; |
155 | } | ||
156 | |||
157 | 61152 | std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) { | |
158 | // Check if a logical and operator is applied | ||
159 |
2/2✓ Branch 0 (3→4) taken 61007 times.
✓ Branch 1 (3→7) taken 145 times.
|
61152 | if (node->operands.size() == 1) |
160 |
2/2✓ Branch 0 (5→6) taken 60993 times.
✓ Branch 1 (5→46) taken 14 times.
|
61007 | return visit(node->operands.front()); |
161 | |||
162 | // Visit leftmost operand | ||
163 |
2/4✓ Branch 0 (8→9) taken 145 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 145 times.
✗ Branch 3 (9→37) not taken.
|
145 | auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0])); |
164 |
2/8✓ Branch 0 (11→12) taken 145 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 145 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.
|
145 | HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type) |
165 | |||
166 | // Loop through all remaining operands | ||
167 |
2/2✓ Branch 0 (31→18) taken 180 times.
✓ Branch 1 (31→32) taken 145 times.
|
325 | for (size_t i = 1; i < node->operands.size(); i++) { |
168 |
2/4✓ Branch 0 (19→20) taken 180 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 180 times.
✗ Branch 3 (20→41) not taken.
|
180 | auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i])); |
169 |
2/8✓ Branch 0 (22→23) taken 180 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 180 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.
|
180 | HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type) |
170 |
1/2✓ Branch 0 (28→29) taken 180 times.
✗ Branch 1 (28→45) not taken.
|
180 | currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)}; |
171 | } | ||
172 | |||
173 |
1/2✓ Branch 0 (32→33) taken 145 times.
✗ Branch 1 (32→46) not taken.
|
145 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
174 |
1/2✓ Branch 0 (33→34) taken 145 times.
✗ Branch 1 (33→46) not taken.
|
145 | return currentOperand; |
175 | } | ||
176 | |||
177 | 61332 | std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) { | |
178 | // Check if a bitwise or operator is applied | ||
179 |
2/2✓ Branch 0 (3→4) taken 61265 times.
✓ Branch 1 (3→7) taken 67 times.
|
61332 | if (node->operands.size() == 1) |
180 |
2/2✓ Branch 0 (5→6) taken 61252 times.
✓ Branch 1 (5→46) taken 13 times.
|
61265 | return visit(node->operands.front()); |
181 | |||
182 | // Visit leftmost operand | ||
183 |
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])); |
184 |
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) |
185 | |||
186 | // Loop through all remaining operands | ||
187 |
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++) { |
188 |
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])); |
189 |
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) |
190 |
2/2✓ Branch 0 (28→29) taken 69 times.
✓ Branch 1 (28→45) taken 1 times.
|
70 | currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)}; |
191 | } | ||
192 | |||
193 |
1/2✓ Branch 0 (32→33) taken 66 times.
✗ Branch 1 (32→46) not taken.
|
66 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
194 |
1/2✓ Branch 0 (33→34) taken 66 times.
✗ Branch 1 (33→46) not taken.
|
66 | return currentOperand; |
195 | } | ||
196 | |||
197 | 61402 | std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) { | |
198 | // Check if a bitwise xor operator is applied | ||
199 |
2/2✓ Branch 0 (3→4) taken 61398 times.
✓ Branch 1 (3→7) taken 4 times.
|
61402 | if (node->operands.size() == 1) |
200 |
2/2✓ Branch 0 (5→6) taken 61385 times.
✓ Branch 1 (5→46) taken 13 times.
|
61398 | return visit(node->operands.front()); |
201 | |||
202 | // Visit leftmost operand | ||
203 |
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])); |
204 |
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) |
205 | |||
206 | // Loop through all remaining operands | ||
207 |
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++) { |
208 |
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])); |
209 |
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) |
210 |
1/2✓ Branch 0 (28→29) taken 7 times.
✗ Branch 1 (28→45) not taken.
|
7 | currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)}; |
211 | } | ||
212 | |||
213 |
1/2✓ Branch 0 (32→33) taken 4 times.
✗ Branch 1 (32→46) not taken.
|
4 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
214 |
1/2✓ Branch 0 (33→34) taken 4 times.
✗ Branch 1 (33→46) not taken.
|
4 | return currentOperand; |
215 | } | ||
216 | |||
217 | 61409 | std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) { | |
218 | // Check if a bitwise and operator is applied | ||
219 |
2/2✓ Branch 0 (3→4) taken 61377 times.
✓ Branch 1 (3→7) taken 32 times.
|
61409 | if (node->operands.size() == 1) |
220 |
2/2✓ Branch 0 (5→6) taken 61364 times.
✓ Branch 1 (5→46) taken 13 times.
|
61377 | return visit(node->operands.front()); |
221 | |||
222 | // Visit leftmost operand | ||
223 |
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])); |
224 |
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) |
225 | |||
226 | // Loop through all remaining operands | ||
227 |
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++) { |
228 |
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])); |
229 |
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) |
230 |
1/2✓ Branch 0 (28→29) taken 35 times.
✗ Branch 1 (28→45) not taken.
|
35 | currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)}; |
231 | } | ||
232 | |||
233 |
1/2✓ Branch 0 (32→33) taken 32 times.
✗ Branch 1 (32→46) not taken.
|
32 | node->setEvaluatedSymbolType(currentOperand.type, manIdx); |
234 |
1/2✓ Branch 0 (33→34) taken 32 times.
✗ Branch 1 (33→46) not taken.
|
32 | return currentOperand; |
235 | } | ||
236 | |||
237 | 61444 | std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) { | |
238 | // Check if at least one equality operator is applied | ||
239 |
2/2✓ Branch 0 (3→4) taken 56755 times.
✓ Branch 1 (3→7) taken 4689 times.
|
61444 | if (node->operands.size() == 1) |
240 |
2/2✓ Branch 0 (5→6) taken 56743 times.
✓ Branch 1 (5→73) taken 12 times.
|
56755 | return visit(node->operands.front()); |
241 | |||
242 | // Visit right side first, then left side | ||
243 |
2/4✓ Branch 0 (8→9) taken 4689 times.
✗ Branch 1 (8→58) not taken.
✓ Branch 2 (9→10) taken 4689 times.
✗ Branch 3 (9→56) not taken.
|
4689 | const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1])); |
244 |
2/8✓ Branch 0 (11→12) taken 4689 times.
✗ Branch 1 (11→73) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4689 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.
|
4689 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
245 |
2/4✓ Branch 0 (18→19) taken 4689 times.
✗ Branch 1 (18→62) not taken.
✓ Branch 2 (19→20) taken 4689 times.
✗ Branch 3 (19→60) not taken.
|
4689 | const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0])); |
246 |
2/8✓ Branch 0 (21→22) taken 4689 times.
✗ Branch 1 (21→73) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 4689 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.
|
4689 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
247 | |||
248 | // Check if we need the string runtime to perform a string comparison | ||
249 |
10/14✓ Branch 0 (27→28) taken 4689 times.
✗ Branch 1 (27→73) not taken.
✓ Branch 2 (28→29) taken 115 times.
✓ Branch 3 (28→36) taken 4574 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 4575 times.
|
4803 | if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT()) |
250 |
1/2✓ Branch 0 (38→39) taken 114 times.
✗ Branch 1 (38→73) not taken.
|
114 | sourceFile->requestRuntimeModule(STRING_RT); |
251 | |||
252 | // Check operator | ||
253 | 4689 | ExprResult result; | |
254 |
2/2✓ Branch 0 (39→40) taken 3340 times.
✓ Branch 1 (39→41) taken 1349 times.
|
4689 | if (node->op == EqualityExprNode::EqualityOp::OP_EQUAL) // Operator was equal |
255 |
2/2✓ Branch 0 (40→51) taken 3339 times.
✓ Branch 1 (40→73) taken 1 times.
|
3340 | result = opRuleManager.getEqualResultType(node, lhs, rhs, 0); |
256 |
1/2✓ Branch 0 (41→42) taken 1349 times.
✗ Branch 1 (41→43) not taken.
|
1349 | else if (node->op == EqualityExprNode::EqualityOp::OP_NOT_EQUAL) // Operator was not equal |
257 |
1/2✓ Branch 0 (42→51) taken 1349 times.
✗ Branch 1 (42→73) not taken.
|
1349 | result = opRuleManager.getNotEqualResultType(node, lhs, rhs, 0); |
258 | else | ||
259 | − | throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE | |
260 | |||
261 |
1/2✓ Branch 0 (51→52) taken 4688 times.
✗ Branch 1 (51→73) not taken.
|
4688 | node->setEvaluatedSymbolType(result.type, manIdx); |
262 |
1/2✓ Branch 0 (52→53) taken 4688 times.
✗ Branch 1 (52→73) not taken.
|
4688 | return result; |
263 | } | ||
264 | |||
265 | 66133 | std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) { | |
266 | // Check if a relational operator is applied | ||
267 |
2/2✓ Branch 0 (3→4) taken 62746 times.
✓ Branch 1 (3→7) taken 3387 times.
|
66133 | if (node->operands.size() == 1) |
268 |
2/2✓ Branch 0 (5→6) taken 62735 times.
✓ Branch 1 (5→75) taken 11 times.
|
62746 | return visit(node->operands.front()); |
269 | |||
270 | // Visit right side first, then left side | ||
271 |
2/4✓ Branch 0 (8→9) taken 3387 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 3387 times.
✗ Branch 3 (9→53) not taken.
|
3387 | const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1])); |
272 |
5/8✓ Branch 0 (11→12) taken 3387 times.
✗ Branch 1 (11→75) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→17) taken 3386 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.
|
3387 | HANDLE_UNRESOLVED_TYPE_ER(rhs.type) |
273 |
2/4✓ Branch 0 (18→19) taken 3386 times.
✗ Branch 1 (18→59) not taken.
✓ Branch 2 (19→20) taken 3386 times.
✗ Branch 3 (19→57) not taken.
|
3386 | const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0])); |
274 |
2/8✓ Branch 0 (21→22) taken 3386 times.
✗ Branch 1 (21→75) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 3386 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.
|
3386 | HANDLE_UNRESOLVED_TYPE_ER(lhs.type) |
275 | |||
276 | // Check operator | ||
277 | 3386 | QualType resultType; | |
278 |
2/2✓ Branch 0 (27→28) taken 1688 times.
✓ Branch 1 (27→30) taken 1698 times.
|
3386 | if (node->op == RelationalExprNode::RelationalOp::OP_LESS) // Operator was less |
279 |
1/2✓ Branch 0 (28→29) taken 1688 times.
✗ Branch 1 (28→61) not taken.
|
1688 | resultType = OpRuleManager::getLessResultType(node, lhs, rhs); |
280 |
2/2✓ Branch 0 (30→31) taken 471 times.
✓ Branch 1 (30→33) taken 1227 times.
|
1698 | else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER) // Operator was greater |
281 |
2/2✓ Branch 0 (31→32) taken 470 times.
✓ Branch 1 (31→62) taken 1 times.
|
471 | resultType = OpRuleManager::getGreaterResultType(node, lhs, rhs); |
282 |
2/2✓ Branch 0 (33→34) taken 357 times.
✓ Branch 1 (33→36) taken 870 times.
|
1227 | else if (node->op == RelationalExprNode::RelationalOp::OP_LESS_EQUAL) // Operator was less equal |
283 |
1/2✓ Branch 0 (34→35) taken 357 times.
✗ Branch 1 (34→63) not taken.
|
357 | resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs); |
284 |
1/2✓ Branch 0 (36→37) taken 870 times.
✗ Branch 1 (36→39) not taken.
|
870 | else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER_EQUAL) // Operator was greater equal |
285 |
1/2✓ Branch 0 (37→38) taken 870 times.
✗ Branch 1 (37→64) not taken.
|
870 | resultType = OpRuleManager::getGreaterEqualResultType(node, lhs, rhs); |
286 | else | ||
287 | − | throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE | |
288 | |||
289 |
2/4✓ Branch 0 (47→48) taken 3385 times.
✗ Branch 1 (47→74) not taken.
✓ Branch 2 (48→49) taken 3385 times.
✗ Branch 3 (48→74) not taken.
|
3385 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)}; |
290 | } | ||
291 | |||
292 | 69519 | std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) { | |
293 | // Check if at least one shift operator is applied | ||
294 |
2/2✓ Branch 0 (3→4) taken 69457 times.
✓ Branch 1 (3→7) taken 62 times.
|
69519 | if (node->operands.size() == 1) |
295 |
2/2✓ Branch 0 (5→6) taken 69446 times.
✓ Branch 1 (5→69) taken 11 times.
|
69457 | return visit(node->operands.front()); |
296 | |||
297 | // Visit leftmost operand | ||
298 |
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])); |
299 |
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) |
300 | |||
301 | // Loop through remaining operands | ||
302 |
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++) { |
303 |
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])); |
304 |
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) |
305 | |||
306 | // Check operator | ||
307 | 102 | const ShiftExprNode::ShiftOp &op = node->opQueue.front().first; | |
308 |
2/2✓ Branch 0 (29→30) taken 95 times.
✓ Branch 1 (29→31) taken 7 times.
|
102 | if (op == ShiftExprNode::ShiftOp::OP_SHIFT_LEFT) |
309 |
1/2✓ Branch 0 (30→41) taken 95 times.
✗ Branch 1 (30→68) not taken.
|
95 | currentResult = opRuleManager.getShiftLeftResultType(node, currentResult, operandResult, i); |
310 |
1/2✓ Branch 0 (31→32) taken 7 times.
✗ Branch 1 (31→33) not taken.
|
7 | else if (op == ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT) |
311 |
1/2✓ Branch 0 (32→41) taken 7 times.
✗ Branch 1 (32→68) not taken.
|
7 | currentResult = opRuleManager.getShiftRightResultType(node, currentResult, operandResult, i); |
312 | else | ||
313 | − | throw CompilerError(UNHANDLED_BRANCH, "ShiftExpr fall-through"); // GCOV_EXCL_LINE | |
314 | |||
315 | // Push the new item and pop the old one on the other side of the queue | ||
316 |
1/2✓ Branch 0 (41→42) taken 102 times.
✗ Branch 1 (41→68) not taken.
|
102 | node->opQueue.emplace(op, currentResult.type); |
317 | 102 | node->opQueue.pop(); | |
318 | } | ||
319 | |||
320 |
1/2✓ Branch 0 (46→47) taken 62 times.
✗ Branch 1 (46→69) not taken.
|
62 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
321 |
1/2✓ Branch 0 (47→48) taken 62 times.
✗ Branch 1 (47→69) not taken.
|
62 | return currentResult; |
322 | } | ||
323 | |||
324 | 69621 | std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) { | |
325 | // Check if at least one additive operator is applied | ||
326 |
2/2✓ Branch 0 (3→4) taken 65841 times.
✓ Branch 1 (3→7) taken 3780 times.
|
69621 | if (node->operands.size() == 1) |
327 |
2/2✓ Branch 0 (5→6) taken 65831 times.
✓ Branch 1 (5→69) taken 10 times.
|
65841 | return visit(node->operands.front()); |
328 | |||
329 | // Visit leftmost operand | ||
330 |
2/4✓ Branch 0 (8→9) taken 3780 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 3780 times.
✗ Branch 3 (9→51) not taken.
|
3780 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
331 |
2/8✓ Branch 0 (11→12) taken 3780 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 3780 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.
|
3780 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
332 | |||
333 | // Loop through remaining operands | ||
334 |
2/2✓ Branch 0 (45→18) taken 4317 times.
✓ Branch 1 (45→46) taken 3779 times.
|
8096 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
335 |
2/4✓ Branch 0 (19→20) taken 4317 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 4317 times.
✗ Branch 3 (20→55) not taken.
|
4317 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
336 |
2/8✓ Branch 0 (22→23) taken 4317 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 4317 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.
|
4317 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
337 | |||
338 | // Check operator | ||
339 | 4317 | const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first; | |
340 |
2/2✓ Branch 0 (29→30) taken 2595 times.
✓ Branch 1 (29→31) taken 1722 times.
|
4317 | if (op == AdditiveExprNode::AdditiveOp::OP_PLUS) |
341 |
2/2✓ Branch 0 (30→41) taken 2594 times.
✓ Branch 1 (30→68) taken 1 times.
|
2595 | currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i); |
342 |
1/2✓ Branch 0 (31→32) taken 1722 times.
✗ Branch 1 (31→33) not taken.
|
1722 | else if (op == AdditiveExprNode::AdditiveOp::OP_MINUS) |
343 |
1/2✓ Branch 0 (32→41) taken 1722 times.
✗ Branch 1 (32→68) not taken.
|
1722 | currentResult = opRuleManager.getMinusResultType(node, currentResult, operandResult, i); |
344 | else | ||
345 | − | throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE | |
346 | |||
347 | // Push the new item and pop the old one on the other side of the queue | ||
348 |
1/2✓ Branch 0 (41→42) taken 4316 times.
✗ Branch 1 (41→68) not taken.
|
4316 | node->opQueue.emplace(op, currentResult.type); |
349 | 4316 | node->opQueue.pop(); | |
350 | } | ||
351 | |||
352 |
1/2✓ Branch 0 (46→47) taken 3779 times.
✗ Branch 1 (46→69) not taken.
|
3779 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
353 |
1/2✓ Branch 0 (47→48) taken 3779 times.
✗ Branch 1 (47→69) not taken.
|
3779 | return currentResult; |
354 | } | ||
355 | |||
356 | 73938 | std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) { | |
357 | // Check if at least one multiplicative operator is applied | ||
358 |
2/2✓ Branch 0 (3→4) taken 73120 times.
✓ Branch 1 (3→7) taken 818 times.
|
73938 | if (node->operands.size() == 1) |
359 |
2/2✓ Branch 0 (5→6) taken 73111 times.
✓ Branch 1 (5→71) taken 9 times.
|
73120 | return visit(node->operands.front()); |
360 | |||
361 | // Visit leftmost operand | ||
362 |
2/4✓ Branch 0 (8→9) taken 818 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 818 times.
✗ Branch 3 (9→53) not taken.
|
818 | auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0])); |
363 |
2/8✓ Branch 0 (11→12) taken 818 times.
✗ Branch 1 (11→71) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 818 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.
|
818 | HANDLE_UNRESOLVED_TYPE_ER(currentResult.type) |
364 | // Loop through remaining operands | ||
365 |
2/2✓ Branch 0 (47→18) taken 842 times.
✓ Branch 1 (47→48) taken 817 times.
|
1659 | for (size_t i = 0; i < node->opQueue.size(); i++) { |
366 |
2/4✓ Branch 0 (19→20) taken 842 times.
✗ Branch 1 (19→59) not taken.
✓ Branch 2 (20→21) taken 842 times.
✗ Branch 3 (20→57) not taken.
|
842 | auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1])); |
367 |
2/8✓ Branch 0 (22→23) taken 842 times.
✗ Branch 1 (22→70) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 842 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.
|
842 | HANDLE_UNRESOLVED_TYPE_ER(operandResult.type) |
368 | |||
369 | // Check operator | ||
370 | 842 | const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first; | |
371 |
2/2✓ Branch 0 (29→30) taken 698 times.
✓ Branch 1 (29→31) taken 144 times.
|
842 | if (op == MultiplicativeExprNode::MultiplicativeOp::OP_MUL) |
372 |
2/2✓ Branch 0 (30→43) taken 697 times.
✓ Branch 1 (30→70) taken 1 times.
|
698 | currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i); |
373 |
2/2✓ Branch 0 (31→32) taken 134 times.
✓ Branch 1 (31→33) taken 10 times.
|
144 | else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_DIV) |
374 |
1/2✓ Branch 0 (32→43) taken 134 times.
✗ Branch 1 (32→70) not taken.
|
134 | currentResult = opRuleManager.getDivResultType(node, currentResult, operandResult, i); |
375 |
1/2✓ Branch 0 (33→34) taken 10 times.
✗ Branch 1 (33→35) not taken.
|
10 | else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_REM) |
376 |
1/2✓ Branch 0 (34→43) taken 10 times.
✗ Branch 1 (34→70) not taken.
|
10 | currentResult = OpRuleManager::getRemResultType(node, currentResult, operandResult); |
377 | else | ||
378 | − | throw CompilerError(UNHANDLED_BRANCH, "Multiplicative fall-through"); // GCOV_EXCL_LINE | |
379 | |||
380 | // Push the new item and pop the old one on the other side of the queue | ||
381 |
1/2✓ Branch 0 (43→44) taken 841 times.
✗ Branch 1 (43→70) not taken.
|
841 | node->opQueue.emplace(op, currentResult.type); |
382 | 841 | node->opQueue.pop(); | |
383 | } | ||
384 | |||
385 |
1/2✓ Branch 0 (48→49) taken 817 times.
✗ Branch 1 (48→71) not taken.
|
817 | node->setEvaluatedSymbolType(currentResult.type, manIdx); |
386 |
1/2✓ Branch 0 (49→50) taken 817 times.
✗ Branch 1 (49→71) not taken.
|
817 | return currentResult; |
387 | } | ||
388 | |||
389 | 74780 | std::any TypeChecker::visitCastExpr(CastExprNode *node) { | |
390 | // Check if cast is applied | ||
391 |
2/2✓ Branch 0 (2→3) taken 72986 times.
✓ Branch 1 (2→5) taken 1794 times.
|
74780 | if (!node->isCast) |
392 |
2/2✓ Branch 0 (3→4) taken 72977 times.
✓ Branch 1 (3→65) taken 9 times.
|
72986 | return visit(node->prefixUnaryExpr); |
393 | |||
394 | // Visit destination type | ||
395 |
2/4✓ Branch 0 (5→6) taken 1794 times.
✗ Branch 1 (5→49) not taken.
✓ Branch 2 (6→7) taken 1794 times.
✗ Branch 3 (6→47) not taken.
|
1794 | const auto dstType = std::any_cast<QualType>(visit(node->dataType)); |
396 |
2/8✓ Branch 0 (8→9) taken 1794 times.
✗ Branch 1 (8→65) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 1794 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.
|
1794 | HANDLE_UNRESOLVED_TYPE_ER(dstType) |
397 | // Visit source type | ||
398 |
2/4✓ Branch 0 (14→15) taken 1794 times.
✗ Branch 1 (14→53) not taken.
✓ Branch 2 (15→16) taken 1794 times.
✗ Branch 3 (15→51) not taken.
|
1794 | const auto src = std::any_cast<ExprResult>(visit(node->assignExpr)); |
399 |
2/8✓ Branch 0 (17→18) taken 1794 times.
✗ Branch 1 (17→65) not taken.
✗ Branch 2 (18→19) not taken.
✓ Branch 3 (18→23) taken 1794 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.
|
1794 | HANDLE_UNRESOLVED_TYPE_ER(src.type) |
400 | |||
401 | // Check for identity cast | ||
402 |
3/4✓ Branch 0 (23→24) taken 1794 times.
✗ Branch 1 (23→65) not taken.
✓ Branch 2 (24→25) taken 213 times.
✓ Branch 3 (24→34) taken 1581 times.
|
1794 | if (src.type == dstType) { |
403 |
2/4✓ Branch 0 (27→28) taken 213 times.
✗ Branch 1 (27→57) not taken.
✓ Branch 2 (28→29) taken 213 times.
✗ Branch 3 (28→55) not taken.
|
213 | const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified."); |
404 |
1/2✓ Branch 0 (31→32) taken 213 times.
✗ Branch 1 (31→61) not taken.
|
213 | sourceFile->compilerOutput.warnings.push_back(warning); |
405 | 213 | } | |
406 | |||
407 | // Get result type | ||
408 |
1/2✓ Branch 0 (34→35) taken 1794 times.
✗ Branch 1 (34→65) not taken.
|
1794 | const QualType resultType = opRuleManager.getCastResultType(node, dstType, src); |
409 | |||
410 |
1/2✓ Branch 0 (35→36) taken 1794 times.
✗ Branch 1 (35→65) not taken.
|
1794 | const bool typesMatch = dstType.matches(src.type, false, true, true); |
411 |
1/2✓ Branch 0 (36→37) taken 1794 times.
✗ Branch 1 (36→65) not taken.
|
1794 | const bool sameContainerType = src.type.isSameContainerTypeAs(dstType); |
412 |
4/4✓ Branch 0 (37→38) taken 1581 times.
✓ Branch 1 (37→39) taken 213 times.
✓ Branch 2 (38→39) taken 117 times.
✓ Branch 3 (38→40) taken 1464 times.
|
1794 | SymbolTableEntry *entry = typesMatch || sameContainerType ? src.entry : nullptr; |
413 |
2/4✓ Branch 0 (41→42) taken 1794 times.
✗ Branch 1 (41→64) not taken.
✓ Branch 2 (42→43) taken 1794 times.
✗ Branch 3 (42→64) not taken.
|
1794 | return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry}; |
414 | } | ||
415 | |||
416 | 79475 | std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { | |
417 | // If no operator is applied, simply visit the postfix unary expression | ||
418 |
2/2✓ Branch 0 (2→3) taken 78522 times.
✓ Branch 1 (2→5) taken 953 times.
|
79475 | if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE) |
419 |
2/2✓ Branch 0 (3→4) taken 78514 times.
✓ Branch 1 (3→78) taken 8 times.
|
78522 | return visit(node->postfixUnaryExpr); |
420 | |||
421 | // Visit the right side | ||
422 | 953 | PrefixUnaryExprNode *rhsNode = node->prefixUnaryExpr; | |
423 |
2/4✓ Branch 0 (5→6) taken 953 times.
✗ Branch 1 (5→57) not taken.
✓ Branch 2 (6→7) taken 953 times.
✗ Branch 3 (6→55) not taken.
|
953 | auto operand = std::any_cast<ExprResult>(visit(rhsNode)); |
424 | 953 | auto [operandType, operandEntry] = operand; | |
425 |
5/8✓ Branch 0 (8→9) taken 953 times.
✗ Branch 1 (8→78) not taken.
✓ Branch 2 (9→10) taken 1 times.
✓ Branch 3 (9→14) taken 952 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.
|
953 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
426 | // Determine action, based on the given operator | ||
427 |
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 648 times.
✓ Branch 4 (14→35) taken 1 times.
✓ Branch 5 (14→37) taken 180 times.
✓ Branch 6 (14→39) taken 80 times.
✗ Branch 7 (14→41) not taken.
|
952 | switch (node->op) { |
428 | 16 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS: | |
429 |
1/2✓ Branch 0 (15→16) taken 16 times.
✗ Branch 1 (15→59) not taken.
|
16 | operandType = OpRuleManager::getPrefixMinusResultType(node, operand); |
430 | 16 | break; | |
431 | 19 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_PLUS_PLUS: | |
432 |
1/2✓ Branch 0 (17→18) taken 19 times.
✗ Branch 1 (17→60) not taken.
|
19 | operandType = opRuleManager.getPrefixPlusPlusResultType(node, operand); |
433 | |||
434 |
2/2✓ Branch 0 (18→19) taken 16 times.
✓ Branch 1 (18→24) taken 3 times.
|
19 | if (operandEntry) { |
435 | // In case the lhs is captured, notify the capture about the write access | ||
436 |
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) |
437 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
438 | |||
439 | // Update the state of the variable | ||
440 |
1/2✓ Branch 0 (22→23) taken 16 times.
✗ Branch 1 (22→61) not taken.
|
16 | operandEntry->updateState(INITIALIZED, node); |
441 | } | ||
442 | |||
443 | 19 | break; | |
444 | 8 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS_MINUS: | |
445 |
2/2✓ Branch 0 (25→26) taken 7 times.
✓ Branch 1 (25→62) taken 1 times.
|
8 | operandType = opRuleManager.getPrefixMinusMinusResultType(node, operand); |
446 | |||
447 |
2/2✓ Branch 0 (26→27) taken 4 times.
✓ Branch 1 (26→32) taken 3 times.
|
7 | if (operandEntry) { |
448 | // In case the lhs is captured, notify the capture about the write access | ||
449 |
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) |
450 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
451 | |||
452 | // Update the state of the variable | ||
453 |
1/2✓ Branch 0 (30→31) taken 4 times.
✗ Branch 1 (30→63) not taken.
|
4 | operandEntry->updateState(INITIALIZED, node); |
454 | } | ||
455 | |||
456 | 7 | break; | |
457 | 648 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT: | |
458 |
1/2✓ Branch 0 (33→34) taken 648 times.
✗ Branch 1 (33→64) not taken.
|
648 | operandType = OpRuleManager::getPrefixNotResultType(node, operand); |
459 | 648 | break; | |
460 | 1 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_BITWISE_NOT: | |
461 |
1/2✓ Branch 0 (35→36) taken 1 times.
✗ Branch 1 (35→65) not taken.
|
1 | operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operand); |
462 | 1 | break; | |
463 | 180 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE: | |
464 |
1/2✓ Branch 0 (37→38) taken 180 times.
✗ Branch 1 (37→66) not taken.
|
180 | operandType = OpRuleManager::getPrefixMulResultType(node, operand); |
465 | 180 | break; | |
466 | 80 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF: | |
467 |
1/2✓ Branch 0 (39→40) taken 80 times.
✗ Branch 1 (39→67) not taken.
|
80 | operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand); |
468 | 80 | break; | |
469 | − | default: // GCOV_EXCL_LINE | |
470 | − | throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
471 | } | ||
472 | |||
473 |
2/4✓ Branch 0 (49→50) taken 951 times.
✗ Branch 1 (49→77) not taken.
✓ Branch 2 (50→51) taken 951 times.
✗ Branch 3 (50→77) not taken.
|
951 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
474 | } | ||
475 | |||
476 | 98110 | std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { | |
477 | // If no operator is applied, simply visit the atomic expression | ||
478 |
2/2✓ Branch 0 (2→3) taken 78522 times.
✓ Branch 1 (2→5) taken 19588 times.
|
98110 | if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE) |
479 |
2/2✓ Branch 0 (3→4) taken 78515 times.
✓ Branch 1 (3→316) taken 7 times.
|
78522 | return visit(node->atomicExpr); |
480 | |||
481 | // Visit left side | ||
482 | 19588 | PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr; | |
483 |
2/4✓ Branch 0 (5→6) taken 19588 times.
✗ Branch 1 (5→211) not taken.
✓ Branch 2 (6→7) taken 19588 times.
✗ Branch 3 (6→209) not taken.
|
19588 | auto operand = std::any_cast<ExprResult>(visit(lhsNode)); |
484 | 19588 | auto [operandType, operandEntry] = operand; | |
485 |
5/8✓ Branch 0 (8→9) taken 19588 times.
✗ Branch 1 (8→316) not taken.
✓ Branch 2 (9→10) taken 6 times.
✓ Branch 3 (9→14) taken 19582 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.
|
19588 | HANDLE_UNRESOLVED_TYPE_ER(operandType) |
486 | |||
487 |
4/5✓ Branch 0 (14→15) taken 3071 times.
✓ Branch 1 (14→101) taken 14496 times.
✓ Branch 2 (14→159) taken 1635 times.
✓ Branch 3 (14→167) taken 380 times.
✗ Branch 4 (14→175) not taken.
|
19582 | switch (node->op) { |
488 | 3071 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: { | |
489 | // Visit index assignment | ||
490 | 3071 | AssignExprNode *indexAssignExpr = node->subscriptIndexExpr; | |
491 |
2/4✓ Branch 0 (15→16) taken 3071 times.
✗ Branch 1 (15→215) not taken.
✓ Branch 2 (16→17) taken 3071 times.
✗ Branch 3 (16→213) not taken.
|
3071 | const auto index = std::any_cast<ExprResult>(visit(indexAssignExpr)); |
492 |
2/8✓ Branch 0 (18→19) taken 3071 times.
✗ Branch 1 (18→258) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 3071 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.
|
3071 | HANDLE_UNRESOLVED_TYPE_ER(index.type) |
493 | |||
494 | // Check is there is an overloaded operator function available, if yes accept it | ||
495 |
1/2✓ Branch 0 (24→25) taken 3071 times.
✗ Branch 1 (24→217) not taken.
|
3071 | const auto [type, _] = opRuleManager.isOperatorOverloadingFctAvailable<2>(node, OP_FCT_SUBSCRIPT, {operand, index}, 0); |
496 |
3/4✓ Branch 0 (25→26) taken 3071 times.
✗ Branch 1 (25→258) not taken.
✓ Branch 2 (26→27) taken 110 times.
✓ Branch 3 (26→28) taken 2961 times.
|
3071 | if (!type.is(TY_INVALID)) { |
497 | 110 | operandType = type; | |
498 | 3069 | break; | |
499 | } | ||
500 | |||
501 |
1/2✓ Branch 0 (28→29) taken 2961 times.
✗ Branch 1 (28→218) not taken.
|
2961 | operandType = operandType.removeReferenceWrapper(); |
502 | |||
503 | // Check if the index is of the right type | ||
504 |
3/4✓ Branch 0 (29→30) taken 2961 times.
✗ Branch 1 (29→219) not taken.
✓ Branch 2 (30→31) taken 1 times.
✓ Branch 3 (30→41) taken 2960 times.
|
2961 | if (!index.type.isOneOf({TY_INT, TY_LONG})) |
505 |
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") |
506 | |||
507 | // Check if we can apply the subscript operator on the lhs type | ||
508 |
2/4✓ Branch 0 (41→42) taken 2960 times.
✗ Branch 1 (41→227) not taken.
✗ Branch 2 (42→43) not taken.
✓ Branch 3 (42→52) taken 2960 times.
|
2960 | if (!operandType.isOneOf({TY_ARRAY, TY_PTR, TY_STRING})) |
509 | ✗ | SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE, | |
510 | "Can only apply subscript operator on array type, got " + operandType.getName(true)) | ||
511 | |||
512 | // Check if we have an unsafe operation | ||
513 |
6/10✓ Branch 0 (52→53) taken 2960 times.
✗ Branch 1 (52→258) not taken.
✓ Branch 2 (53→54) taken 2125 times.
✓ Branch 3 (53→57) taken 835 times.
✓ Branch 4 (54→55) taken 2125 times.
✗ Branch 5 (54→258) not taken.
✗ Branch 6 (55→56) not taken.
✓ Branch 7 (55→57) taken 2125 times.
✗ Branch 8 (58→59) not taken.
✓ Branch 9 (58→69) taken 2960 times.
|
2960 | if (operandType.isPtr() && !currentScope->doesAllowUnsafeOperations()) |
514 | ✗ | SOFT_ERROR_ER( | |
515 | node, UNSAFE_OPERATION_IN_SAFE_CONTEXT, | ||
516 | "The subscript operator on pointers is an unsafe operation. Use unsafe blocks if you know what you are doing.") | ||
517 | |||
518 | // In case of compile time index value and known array size, perform a compile time out-of-bounds check | ||
519 |
11/14✓ Branch 0 (69→70) taken 2960 times.
✗ Branch 1 (69→258) not taken.
✓ Branch 2 (70→71) taken 140 times.
✓ Branch 3 (70→76) taken 2820 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 2926 times.
|
2960 | if (operandType.isArray() && operandType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) { |
520 |
1/2✓ Branch 0 (78→79) taken 34 times.
✗ Branch 1 (78→258) not taken.
|
34 | const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue; |
521 |
1/2✓ Branch 0 (79→80) taken 34 times.
✗ Branch 1 (79→258) not taken.
|
34 | const unsigned int constSize = operandType.getArraySize(); |
522 | // Check if we are accessing out-of-bounds memory | ||
523 |
2/2✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→96) taken 33 times.
|
34 | if (constIndex >= static_cast<int32_t>(constSize)) { |
524 | 1 | const std::string idxStr = std::to_string(constIndex); | |
525 | 1 | const std::string sizeStr = std::to_string(constSize); | |
526 |
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, |
527 | "You are trying to access element with index " + idxStr + " of an array with size " + sizeStr) | ||
528 | 1 | } | |
529 | } | ||
530 | |||
531 | // Get item type | ||
532 |
1/2✓ Branch 0 (96→97) taken 2959 times.
✗ Branch 1 (96→257) not taken.
|
2959 | operandType = operandType.getContained(); |
533 | |||
534 | // Remove heap qualifier | ||
535 | 2959 | operandType.getQualifiers().isHeap = false; | |
536 | |||
537 | 2959 | break; | |
538 | } | ||
539 | 14496 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: { | |
540 | 14496 | const std::string &fieldName = node->identifier; | |
541 | |||
542 | // Check if lhs is enum or strobj | ||
543 |
1/2✓ Branch 0 (101→102) taken 14496 times.
✗ Branch 1 (101→286) not taken.
|
14496 | const QualType lhsBaseTy = operandType.autoDeReference(); |
544 |
3/4✓ Branch 0 (102→103) taken 14496 times.
✗ Branch 1 (102→286) not taken.
✓ Branch 2 (103→104) taken 1 times.
✓ Branch 3 (103→113) taken 14495 times.
|
14496 | if (!lhsBaseTy.is(TY_STRUCT)) |
545 |
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)) |
546 | |||
547 | // Retrieve registry entry | ||
548 |
1/2✓ Branch 0 (113→114) taken 14495 times.
✗ Branch 1 (113→286) not taken.
|
14495 | const std::string &structName = lhsBaseTy.getSubType(); |
549 |
1/2✓ Branch 0 (114→115) taken 14495 times.
✗ Branch 1 (114→286) not taken.
|
14495 | Scope *structScope = lhsBaseTy.getBodyScope(); |
550 | |||
551 | // If we only have the generic struct scope, lookup the concrete manifestation scope | ||
552 |
2/2✓ Branch 0 (115→116) taken 78 times.
✓ Branch 1 (115→120) taken 14417 times.
|
14495 | if (structScope->isGenericScope) { |
553 |
1/2✓ Branch 0 (116→117) taken 78 times.
✗ Branch 1 (116→286) not taken.
|
78 | const Struct *spiceStruct = lhsBaseTy.getStruct(node); |
554 |
1/2✗ Branch 0 (117→118) not taken.
✓ Branch 1 (117→119) taken 78 times.
|
78 | assert(spiceStruct != nullptr); |
555 | 78 | structScope = spiceStruct->scope; | |
556 | } | ||
557 |
1/2✗ Branch 0 (120→121) not taken.
✓ Branch 1 (120→122) taken 14495 times.
|
14495 | assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope |
558 | |||
559 | // Get accessed field | ||
560 | 14495 | std::vector<size_t> indexPath; | |
561 |
1/2✓ Branch 0 (122→123) taken 14495 times.
✗ Branch 1 (122→284) not taken.
|
14495 | SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath); |
562 |
2/2✓ Branch 0 (123→124) taken 2 times.
✓ Branch 1 (123→135) taken 14493 times.
|
14495 | if (!memberEntry) |
563 |
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) |
564 |
1/2✓ Branch 0 (135→136) taken 14493 times.
✗ Branch 1 (135→284) not taken.
|
14493 | const QualType memberType = memberEntry->getQualType(); |
565 | |||
566 | // Check for insufficient visibility | ||
567 |
8/14✓ Branch 0 (136→137) taken 14493 times.
✗ Branch 1 (136→276) not taken.
✓ Branch 2 (137→138) taken 71 times.
✓ Branch 3 (137→143) taken 14422 times.
✓ Branch 4 (138→139) taken 71 times.
✗ Branch 5 (138→276) not taken.
✓ Branch 6 (139→140) taken 71 times.
✗ Branch 7 (139→276) not taken.
✓ Branch 8 (140→141) taken 71 times.
✗ Branch 9 (140→276) not taken.
✗ Branch 10 (141→142) not taken.
✓ Branch 11 (141→143) taken 71 times.
✗ Branch 12 (144→145) not taken.
✓ Branch 13 (144→154) taken 14493 times.
|
14493 | if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().getBase().isPublic()) |
568 | ✗ | SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access field '" + fieldName + "' due to its private visibility") | |
569 | |||
570 | // Set field to used | ||
571 | 14493 | memberEntry->used = true; | |
572 | |||
573 | // Overwrite type and entry of left side with member type and entry | ||
574 | 14493 | operandType = memberType; | |
575 | 14493 | operandEntry = memberEntry; | |
576 | 14493 | break; | |
577 |
2/2✓ Branch 0 (156→157) taken 2 times.
✓ Branch 1 (156→158) taken 14493 times.
|
14495 | } |
578 | 1635 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: { | |
579 |
2/2✓ Branch 0 (159→160) taken 1634 times.
✓ Branch 1 (159→287) taken 1 times.
|
1635 | operandType = opRuleManager.getPostfixPlusPlusResultType(node, operand, 0).type; |
580 | |||
581 |
2/2✓ Branch 0 (160→161) taken 1630 times.
✓ Branch 1 (160→166) taken 4 times.
|
1634 | if (operandEntry) { |
582 | // In case the lhs is captured, notify the capture about the write access | ||
583 |
3/4✓ Branch 0 (161→162) taken 1630 times.
✗ Branch 1 (161→316) not taken.
✓ Branch 2 (162→163) taken 4 times.
✓ Branch 3 (162→164) taken 1626 times.
|
1630 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
584 |
1/2✓ Branch 0 (163→164) taken 4 times.
✗ Branch 1 (163→316) not taken.
|
4 | lhsCapture->setAccessType(READ_WRITE); |
585 | |||
586 | // Update the state of the variable | ||
587 |
1/2✓ Branch 0 (164→165) taken 1630 times.
✗ Branch 1 (164→288) not taken.
|
1630 | operandEntry->updateState(INITIALIZED, node); |
588 | } | ||
589 | |||
590 | 1634 | break; | |
591 | } | ||
592 | 380 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: { | |
593 |
1/2✓ Branch 0 (167→168) taken 380 times.
✗ Branch 1 (167→289) not taken.
|
380 | operandType = opRuleManager.getPostfixMinusMinusResultType(node, operand, 0).type; |
594 | |||
595 |
2/2✓ Branch 0 (168→169) taken 376 times.
✓ Branch 1 (168→174) taken 4 times.
|
380 | if (operandEntry) { |
596 | // In case the lhs is captured, notify the capture about the write access | ||
597 |
2/4✓ Branch 0 (169→170) taken 376 times.
✗ Branch 1 (169→316) not taken.
✗ Branch 2 (170→171) not taken.
✓ Branch 3 (170→172) taken 376 times.
|
376 | if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture) |
598 | ✗ | lhsCapture->setAccessType(READ_WRITE); | |
599 | |||
600 | // Update the state of the variable | ||
601 |
1/2✓ Branch 0 (172→173) taken 376 times.
✗ Branch 1 (172→290) not taken.
|
376 | operandEntry->updateState(INITIALIZED, node); |
602 | } | ||
603 | |||
604 | 380 | break; | |
605 | } | ||
606 | − | default: // GCOV_EXCL_LINE | |
607 | − | throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
608 | } | ||
609 | |||
610 |
2/4✓ Branch 0 (183→184) taken 19576 times.
✗ Branch 1 (183→316) not taken.
✗ Branch 2 (184→185) not taken.
✓ Branch 3 (184→203) taken 19576 times.
|
19576 | if (operandType.is(TY_INVALID)) { |
611 | ✗ | const std::string &varName = operandEntry ? operandEntry->name : ""; | |
612 | ✗ | SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Variable '" + varName + "' was referenced before declared") | |
613 | ✗ | } | |
614 | |||
615 |
2/4✓ Branch 0 (203→204) taken 19576 times.
✗ Branch 1 (203→315) not taken.
✓ Branch 2 (204→205) taken 19576 times.
✗ Branch 3 (204→315) not taken.
|
19576 | return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry}; |
616 | } | ||
617 | |||
618 | 78522 | std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) { | |
619 | // Check if constant | ||
620 |
2/2✓ Branch 0 (2→3) taken 15391 times.
✓ Branch 1 (2→5) taken 63131 times.
|
78522 | if (node->constant) |
621 |
1/2✓ Branch 0 (3→4) taken 15391 times.
✗ Branch 1 (3→219) not taken.
|
15391 | return visit(node->constant); |
622 | |||
623 | // Check if value | ||
624 |
2/2✓ Branch 0 (5→6) taken 15097 times.
✓ Branch 1 (5→8) taken 48034 times.
|
63131 | if (node->value) |
625 |
2/2✓ Branch 0 (6→7) taken 15093 times.
✓ Branch 1 (6→219) taken 4 times.
|
15097 | return visit(node->value); |
626 | |||
627 | // Check for builtin calls | ||
628 |
2/2✓ Branch 0 (8→9) taken 1580 times.
✓ Branch 1 (8→11) taken 46454 times.
|
48034 | if (node->builtinCall) |
629 |
1/2✓ Branch 0 (9→10) taken 1580 times.
✗ Branch 1 (9→219) not taken.
|
1580 | return visit(node->builtinCall); |
630 | |||
631 | // Check for assign expression within parentheses | ||
632 |
2/2✓ Branch 0 (11→12) taken 520 times.
✓ Branch 1 (11→14) taken 45934 times.
|
46454 | if (node->assignExpr) |
633 |
2/2✓ Branch 0 (12→13) taken 517 times.
✓ Branch 1 (12→219) taken 3 times.
|
520 | return visit(node->assignExpr); |
634 | |||
635 | // Identifier (local or global variable access) | ||
636 |
1/2✗ Branch 0 (15→16) not taken.
✓ Branch 1 (15→17) taken 45934 times.
|
45934 | assert(!node->fqIdentifier.empty()); |
637 | |||
638 |
1/2✓ Branch 0 (17→18) taken 45934 times.
✗ Branch 1 (17→219) not taken.
|
45934 | auto &[entry, accessScope, capture] = node->data.at(manIdx); |
639 | 45934 | accessScope = currentScope; | |
640 | |||
641 | // Check if a local or global variable can be found by searching for the name | ||
642 |
2/2✓ Branch 0 (19→20) taken 45691 times.
✓ Branch 1 (19→25) taken 243 times.
|
45934 | if (node->identifierFragments.size() == 1) |
643 | 91382 | entry = accessScope->lookup(node->identifierFragments.back()); | |
644 | |||
645 | // If no local or global was found, search in the name registry | ||
646 |
2/2✓ Branch 0 (25→26) taken 316 times.
✓ Branch 1 (25→38) taken 45618 times.
|
45934 | if (!entry) { |
647 |
1/2✓ Branch 0 (26→27) taken 316 times.
✗ Branch 1 (26→219) not taken.
|
316 | const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier); |
648 |
2/2✓ Branch 0 (27→28) taken 1 times.
✓ Branch 1 (27→37) taken 315 times.
|
316 | if (!registryEntry) |
649 |
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") |
650 | 315 | entry = registryEntry->targetEntry; | |
651 | 315 | accessScope = registryEntry->targetScope; | |
652 | } | ||
653 |
1/2✗ Branch 0 (38→39) not taken.
✓ Branch 1 (38→40) taken 45933 times.
|
45933 | assert(entry != nullptr); |
654 | 45933 | entry->used = true; | |
655 |
1/2✓ Branch 0 (40→41) taken 45933 times.
✗ Branch 1 (40→219) not taken.
|
45933 | capture = accessScope->symbolTable.lookupCapture(entry->name); |
656 | |||
657 |
1/2✓ Branch 0 (41→42) taken 45933 times.
✗ Branch 1 (41→219) not taken.
|
45933 | const QualType varType = entry->getQualType(); |
658 |
5/8✓ Branch 0 (42→43) taken 45933 times.
✗ Branch 1 (42→219) not taken.
✓ Branch 2 (43→44) taken 9 times.
✓ Branch 3 (43→48) taken 45924 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.
|
45933 | HANDLE_UNRESOLVED_TYPE_ER(varType) |
659 |
3/4✓ Branch 0 (48→49) taken 45924 times.
✗ Branch 1 (48→219) not taken.
✓ Branch 2 (49→50) taken 2 times.
✓ Branch 3 (49→59) taken 45922 times.
|
45924 | if (varType.is(TY_INVALID)) |
660 |
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.") |
661 | |||
662 |
7/8✓ Branch 0 (59→60) taken 45922 times.
✗ Branch 1 (59→178) not taken.
✓ Branch 2 (60→61) taken 25 times.
✓ Branch 3 (60→63) taken 45897 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 45913 times.
|
45922 | if (varType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && entry->global) { |
663 | // Check if overloaded function was referenced | ||
664 |
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); |
665 |
2/2✓ Branch 0 (67→68) taken 1 times.
✓ Branch 1 (67→78) taken 8 times.
|
9 | if (manifestations->size() > 1) |
666 |
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") |
667 |
2/2✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→91) taken 7 times.
|
8 | if (!manifestations->front()->templateTypes.empty()) |
668 |
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") |
669 | // Set referenced function to used | ||
670 | 7 | Function *referencedFunction = manifestations->front(); | |
671 | 7 | referencedFunction->used = true; | |
672 | 7 | referencedFunction->entry->used = true; | |
673 | } | ||
674 | |||
675 | // The base type should be an extended primitive | ||
676 |
1/2✓ Branch 0 (93→94) taken 45920 times.
✗ Branch 1 (93→219) not taken.
|
45920 | const QualType baseType = varType.getBase(); |
677 |
6/10✓ Branch 0 (94→95) taken 45920 times.
✗ Branch 1 (94→219) not taken.
✓ Branch 2 (95→96) taken 2 times.
✓ Branch 3 (95→99) taken 45918 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 45920 times.
|
45920 | if (!baseType.isExtendedPrimitive() && !baseType.is(TY_DYN)) |
678 | ✗ | SOFT_ERROR_ER(node, INVALID_SYMBOL_ACCESS, "A symbol of type " + varType.getName(false) + " cannot be accessed here") | |
679 | |||
680 | // Check if we have seen a 'this.' prefix, because the generator needs that | ||
681 |
6/8✓ Branch 0 (112→113) taken 1 times.
✓ Branch 1 (112→117) taken 45919 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 45919 times.
|
45920 | if (entry->scope->type == ScopeType::STRUCT && node->identifierFragments.front() != THIS_VARIABLE_NAME) |
682 |
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, |
683 | "The symbol '" + node->fqIdentifier + "' could not be found. Missing 'this.' prefix?") | ||
684 | |||
685 | // Ensure that the entry is public, if the symbol is imported. | ||
686 | // An exception are enum items. There it is sufficient, that the enum itself is public. | ||
687 |
7/8✓ Branch 0 (128→129) taken 45919 times.
✗ Branch 1 (128→219) not taken.
✓ Branch 2 (129→130) taken 196 times.
✓ Branch 3 (129→132) taken 45723 times.
✓ Branch 4 (130→131) taken 75 times.
✓ Branch 5 (130→132) taken 121 times.
✓ Branch 6 (133→134) taken 75 times.
✓ Branch 7 (133→147) taken 45844 times.
|
45919 | if (accessScope->isImportedBy(rootScope) && accessScope->type != ScopeType::ENUM) |
688 |
5/8✓ Branch 0 (134→135) taken 75 times.
✗ Branch 1 (134→210) not taken.
✓ Branch 2 (135→136) taken 75 times.
✗ Branch 3 (135→210) not taken.
✓ Branch 4 (136→137) taken 75 times.
✗ Branch 5 (136→210) not taken.
✓ Branch 6 (137→138) taken 1 times.
✓ Branch 7 (137→147) taken 74 times.
|
75 | if (!entry->getQualType().getBase().isPublic()) |
689 |
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") |
690 | |||
691 | // For enum item access, use access scope of the enum | ||
692 |
2/2✓ Branch 0 (147→148) taken 238 times.
✓ Branch 1 (147→149) taken 45680 times.
|
45918 | if (entry->scope->type == ScopeType::ENUM) |
693 | 238 | accessScope = entry->scope; | |
694 | |||
695 | // For struct access, use access scope of the struct | ||
696 |
3/4✓ Branch 0 (149→150) taken 45918 times.
✗ Branch 1 (149→219) not taken.
✓ Branch 2 (150→151) taken 16381 times.
✓ Branch 3 (150→157) taken 29537 times.
|
45918 | if (baseType.is(TY_STRUCT)) { |
697 |
1/2✓ Branch 0 (151→152) taken 16381 times.
✗ Branch 1 (151→219) not taken.
|
16381 | const std::string &structName = baseType.getSubType(); |
698 |
1/2✓ Branch 0 (152→153) taken 16381 times.
✗ Branch 1 (152→219) not taken.
|
16381 | const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(structName); |
699 |
1/2✗ Branch 0 (153→154) not taken.
✓ Branch 1 (153→155) taken 16381 times.
|
16381 | assert(nameRegistryEntry != nullptr); |
700 | 16381 | accessScope = nameRegistryEntry->targetScope; | |
701 |
1/2✗ Branch 0 (155→156) not taken.
✓ Branch 1 (155→157) taken 16381 times.
|
16381 | assert(accessScope != nullptr); |
702 | } | ||
703 | |||
704 |
2/4✓ Branch 0 (157→158) taken 45918 times.
✗ Branch 1 (157→218) not taken.
✓ Branch 2 (158→159) taken 45918 times.
✗ Branch 3 (158→218) not taken.
|
45918 | return ExprResult{node->setEvaluatedSymbolType(varType, manIdx), entry}; |
705 | } | ||
706 | |||
707 | } // namespace spice::compiler | ||
708 |