GCC Code Coverage Report


Directory: ../
File: src/typechecker/TypeCheckerExpressions.cpp
Date: 2025-03-05 01:50:32
Exec Total Coverage
Lines: 395 405 97.5%
Functions: 16 16 100.0%
Branches: 690 1231 56.1%

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