Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "IRGenerator.h" | ||
4 | |||
5 | #include <ast/ASTNodes.h> | ||
6 | |||
7 | #include <llvm/IR/Module.h> | ||
8 | |||
9 | namespace spice::compiler { | ||
10 | |||
11 | 55087 | std::any IRGenerator::visitAssignExpr(const AssignExprNode *node) { | |
12 | 55087 | diGenerator.setSourceLocation(node); | |
13 | |||
14 | // Visit ternary expression | ||
15 |
2/2✓ Branch 0 (3→4) taken 50009 times.
✓ Branch 1 (3→5) taken 5078 times.
|
55087 | if (node->ternaryExpr) |
16 | 50009 | return visit(node->ternaryExpr); | |
17 | |||
18 | // Assign or compound assign operation | ||
19 |
1/2✓ Branch 0 (5→6) taken 5078 times.
✗ Branch 1 (5→60) not taken.
|
5078 | if (node->op != AssignExprNode::AssignOp::OP_NONE) { |
20 | 5078 | const PrefixUnaryExprNode *lhsNode = node->lhs; | |
21 | 5078 | const AssignExprNode *rhsNode = node->rhs; | |
22 | |||
23 | // Normal assignment | ||
24 |
2/2✓ Branch 0 (6→7) taken 4554 times.
✓ Branch 1 (6→11) taken 524 times.
|
5078 | if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) |
25 |
2/4✓ Branch 0 (7→8) taken 4554 times.
✗ Branch 1 (7→69) not taken.
✓ Branch 2 (8→9) taken 4554 times.
✗ Branch 3 (8→69) not taken.
|
4554 | return doAssignment(lhsNode, rhsNode, node); |
26 | |||
27 | // Compound assignment | ||
28 | // Get symbol types of left and right side | ||
29 |
1/2✓ Branch 0 (11→12) taken 524 times.
✗ Branch 1 (11→85) not taken.
|
524 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
30 |
1/2✓ Branch 0 (12→13) taken 524 times.
✗ Branch 1 (12→85) not taken.
|
524 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
31 | |||
32 | // Retrieve rhs | ||
33 |
2/4✓ Branch 0 (13→14) taken 524 times.
✗ Branch 1 (13→72) not taken.
✓ Branch 2 (14→15) taken 524 times.
✗ Branch 3 (14→70) not taken.
|
524 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
34 | // Retrieve lhs | ||
35 |
2/4✓ Branch 0 (16→17) taken 524 times.
✗ Branch 1 (16→75) not taken.
✓ Branch 2 (17→18) taken 524 times.
✗ Branch 3 (17→73) not taken.
|
524 | auto lhs = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
36 | |||
37 | 524 | LLVMExprResult result; | |
38 |
10/11✓ Branch 0 (19→20) taken 218 times.
✓ Branch 1 (19→22) taken 27 times.
✓ Branch 2 (19→24) taken 15 times.
✓ Branch 3 (19→26) taken 35 times.
✓ Branch 4 (19→28) taken 5 times.
✓ Branch 5 (19→30) taken 1 times.
✓ Branch 6 (19→32) taken 2 times.
✓ Branch 7 (19→34) taken 1 times.
✓ Branch 8 (19→36) taken 1 times.
✓ Branch 9 (19→38) taken 219 times.
✗ Branch 10 (19→40) not taken.
|
524 | switch (node->op) { |
39 | 218 | case AssignExprNode::AssignOp::OP_PLUS_EQUAL: | |
40 |
1/2✓ Branch 0 (20→21) taken 218 times.
✗ Branch 1 (20→85) not taken.
|
218 | result = conversionManager.getPlusEqualInst(node, lhs, lhsSTy, rhs, rhsSTy, 0); |
41 | 218 | break; | |
42 | 27 | case AssignExprNode::AssignOp::OP_MINUS_EQUAL: | |
43 |
1/2✓ Branch 0 (22→23) taken 27 times.
✗ Branch 1 (22→85) not taken.
|
27 | result = conversionManager.getMinusEqualInst(node, lhs, lhsSTy, rhs, rhsSTy, 0); |
44 | 27 | break; | |
45 | 15 | case AssignExprNode::AssignOp::OP_MUL_EQUAL: | |
46 |
1/2✓ Branch 0 (24→25) taken 15 times.
✗ Branch 1 (24→85) not taken.
|
15 | result = conversionManager.getMulEqualInst(node, lhs, lhsSTy, rhs, rhsSTy, 0); |
47 | 15 | break; | |
48 | 35 | case AssignExprNode::AssignOp::OP_DIV_EQUAL: | |
49 |
1/2✓ Branch 0 (26→27) taken 35 times.
✗ Branch 1 (26→85) not taken.
|
35 | result = conversionManager.getDivEqualInst(node, lhs, lhsSTy, rhs, rhsSTy, 0); |
50 | 35 | break; | |
51 | 5 | case AssignExprNode::AssignOp::OP_REM_EQUAL: | |
52 |
1/2✓ Branch 0 (28→29) taken 5 times.
✗ Branch 1 (28→85) not taken.
|
5 | result = conversionManager.getRemEqualInst(node, lhs, lhsSTy, rhs, rhsSTy); |
53 | 5 | break; | |
54 | 1 | case AssignExprNode::AssignOp::OP_SHL_EQUAL: | |
55 |
1/2✓ Branch 0 (30→31) taken 1 times.
✗ Branch 1 (30→85) not taken.
|
1 | result = conversionManager.getSHLEqualInst(node, lhs, lhsSTy, rhs, rhsSTy); |
56 | 1 | break; | |
57 | 2 | case AssignExprNode::AssignOp::OP_SHR_EQUAL: | |
58 |
1/2✓ Branch 0 (32→33) taken 2 times.
✗ Branch 1 (32→85) not taken.
|
2 | result = conversionManager.getSHREqualInst(node, lhs, lhsSTy, rhs, rhsSTy); |
59 | 2 | break; | |
60 | 1 | case AssignExprNode::AssignOp::OP_AND_EQUAL: | |
61 |
1/2✓ Branch 0 (34→35) taken 1 times.
✗ Branch 1 (34→85) not taken.
|
1 | result = conversionManager.getAndEqualInst(node, lhs, lhsSTy, rhs, rhsSTy); |
62 | 1 | break; | |
63 | 1 | case AssignExprNode::AssignOp::OP_OR_EQUAL: | |
64 |
1/2✓ Branch 0 (36→37) taken 1 times.
✗ Branch 1 (36→85) not taken.
|
1 | result = conversionManager.getOrEqualInst(node, lhs, lhsSTy, rhs, rhsSTy); |
65 | 1 | break; | |
66 | 219 | case AssignExprNode::AssignOp::OP_XOR_EQUAL: | |
67 |
1/2✓ Branch 0 (38→39) taken 219 times.
✗ Branch 1 (38→85) not taken.
|
219 | result = conversionManager.getXorEqualInst(node, lhs, lhsSTy, rhs, rhsSTy); |
68 | 219 | break; | |
69 | − | default: // GCOV_EXCL_LINE | |
70 | − | throw CompilerError(UNHANDLED_BRANCH, "Assign op fall-through"); // GCOV_EXCL_LINE | |
71 | } | ||
72 | |||
73 |
1/2✗ Branch 0 (48→49) not taken.
✓ Branch 1 (48→51) taken 524 times.
|
524 | if (result.ptr) { // The operation allocated more memory |
74 | ✗ | if (lhs.entry) | |
75 | ✗ | lhs.entry->updateAddress(result.ptr); | |
76 |
2/2✓ Branch 0 (51→52) taken 396 times.
✓ Branch 1 (51→57) taken 128 times.
|
524 | } else if (result.value) { // The operation only updated the value |
77 | // Store the result | ||
78 | 396 | lhs.value = result.value; | |
79 |
5/6✓ Branch 0 (52→53) taken 176 times.
✓ Branch 1 (52→55) taken 220 times.
✓ Branch 2 (53→54) taken 2 times.
✓ Branch 3 (53→55) taken 174 times.
✓ Branch 4 (56→57) taken 396 times.
✗ Branch 5 (56→85) not taken.
|
396 | insertStore(lhs.value, lhs.ptr, lhs.entry && lhs.entry->isVolatile); |
80 | } | ||
81 |
1/2✓ Branch 0 (57→58) taken 524 times.
✗ Branch 1 (57→85) not taken.
|
524 | return lhs; |
82 | } | ||
83 | |||
84 | // This is a fallthrough case -> throw an error | ||
85 | − | throw CompilerError(UNHANDLED_BRANCH, "AssignStmt fall-through"); // GCOV_EXCL_LINE | |
86 | } | ||
87 | |||
88 | 50249 | std::any IRGenerator::visitTernaryExpr(const TernaryExprNode *node) { | |
89 | 50249 | diGenerator.setSourceLocation(node); | |
90 | |||
91 | // Check if only one operand is present -> loop through | ||
92 |
2/2✓ Branch 0 (3→4) taken 49942 times.
✓ Branch 1 (3→5) taken 307 times.
|
50249 | if (!node->falseExpr) |
93 | 49942 | return visit(node->condition); | |
94 | |||
95 | // It is a ternary | ||
96 | // Retrieve the condition value | ||
97 | 307 | llvm::Value *condValue = resolveValue(node->condition); | |
98 |
2/2✓ Branch 0 (6→7) taken 1 times.
✓ Branch 1 (6→8) taken 306 times.
|
307 | const LogicalOrExprNode *trueNode = node->isShortened ? node->condition : node->trueExpr; |
99 | 307 | const LogicalOrExprNode *falseNode = node->falseExpr; | |
100 | |||
101 | 307 | llvm::Value *resultValue = nullptr; | |
102 | 307 | llvm::Value *resultPtr = nullptr; | |
103 | 307 | SymbolTableEntry *anonymousSymbol = nullptr; | |
104 |
6/6✓ Branch 0 (10→11) taken 27 times.
✓ Branch 1 (10→14) taken 280 times.
✓ Branch 2 (12→13) taken 26 times.
✓ Branch 3 (12→14) taken 1 times.
✓ Branch 4 (15→16) taken 26 times.
✓ Branch 5 (15→21) taken 281 times.
|
307 | if (trueNode->hasCompileTimeValue() && falseNode->hasCompileTimeValue()) { |
105 | // If both are constants, we can simply emit a selection instruction | ||
106 | 26 | llvm::Value *trueValue = resolveValue(trueNode); | |
107 | 26 | llvm::Value *falseValue = resolveValue(falseNode); | |
108 |
2/4✓ Branch 0 (18→19) taken 26 times.
✗ Branch 1 (18→151) not taken.
✓ Branch 2 (19→20) taken 26 times.
✗ Branch 3 (19→151) not taken.
|
26 | resultValue = builder.CreateSelect(condValue, trueValue, falseValue); |
109 | } else { | ||
110 | // We have at least one non-constant value, use branching to not perform both sides | ||
111 |
1/2✓ Branch 0 (21→22) taken 281 times.
✗ Branch 1 (21→210) not taken.
|
281 | const std::string codeLoc = node->codeLoc.toPrettyLineAndColumn(); |
112 |
2/4✓ Branch 0 (22→23) taken 281 times.
✗ Branch 1 (22→154) not taken.
✓ Branch 2 (23→24) taken 281 times.
✗ Branch 3 (23→152) not taken.
|
281 | llvm::BasicBlock *condTrue = createBlock("cond.true." + codeLoc); |
113 |
2/4✓ Branch 0 (25→26) taken 281 times.
✗ Branch 1 (25→157) not taken.
✓ Branch 2 (26→27) taken 281 times.
✗ Branch 3 (26→155) not taken.
|
281 | llvm::BasicBlock *condFalse = createBlock("cond.false." + codeLoc); |
114 |
2/4✓ Branch 0 (28→29) taken 281 times.
✗ Branch 1 (28→160) not taken.
✓ Branch 2 (29→30) taken 281 times.
✗ Branch 3 (29→158) not taken.
|
281 | llvm::BasicBlock *condExit = createBlock("cond.exit." + codeLoc); |
115 | |||
116 | // Jump from original block to true or false block, depending on condition | ||
117 |
1/2✓ Branch 0 (31→32) taken 281 times.
✗ Branch 1 (31→208) not taken.
|
281 | insertCondJump(condValue, condTrue, condFalse); |
118 | |||
119 | // Fill true block | ||
120 |
1/2✓ Branch 0 (32→33) taken 281 times.
✗ Branch 1 (32→208) not taken.
|
281 | switchToBlock(condTrue); |
121 |
1/2✓ Branch 0 (33→34) taken 281 times.
✗ Branch 1 (33→208) not taken.
|
281 | const QualType &resultType = node->getEvaluatedSymbolType(manIdx); |
122 | 281 | llvm::Value *trueValue = nullptr; | |
123 | 281 | llvm::Value *truePtr = nullptr; | |
124 |
7/8✓ Branch 0 (34→35) taken 273 times.
✓ Branch 1 (34→37) taken 8 times.
✓ Branch 2 (35→36) taken 273 times.
✗ Branch 3 (35→208) not taken.
✓ Branch 4 (36→37) taken 8 times.
✓ Branch 5 (36→38) taken 265 times.
✓ Branch 6 (39→40) taken 16 times.
✓ Branch 7 (39→42) taken 265 times.
|
281 | if (node->falseSideCallsCopyCtor || resultType.isRef()) { // both sides or only the false side needs copy ctor call |
125 |
1/2✓ Branch 0 (40→41) taken 16 times.
✗ Branch 1 (40→208) not taken.
|
16 | truePtr = resolveAddress(trueNode); |
126 |
2/2✓ Branch 0 (42→43) taken 2 times.
✓ Branch 1 (42→59) taken 263 times.
|
265 | } else if (node->trueSideCallsCopyCtor) { // only true side needs copy ctor call |
127 |
1/2✓ Branch 0 (43→44) taken 2 times.
✗ Branch 1 (43→208) not taken.
|
2 | llvm::Value *originalPtr = resolveAddress(trueNode); |
128 |
3/6✓ Branch 0 (47→48) taken 2 times.
✗ Branch 1 (47→161) not taken.
✓ Branch 2 (48→49) taken 2 times.
✗ Branch 3 (48→161) not taken.
✓ Branch 4 (49→50) taken 2 times.
✗ Branch 5 (49→161) not taken.
|
2 | truePtr = insertAlloca(trueNode->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile)); |
129 |
2/4✓ Branch 0 (54→55) taken 2 times.
✗ Branch 1 (54→169) not taken.
✓ Branch 2 (55→56) taken 2 times.
✗ Branch 3 (55→167) not taken.
|
6 | generateCtorOrDtorCall(truePtr, node->calledCopyCtor, {originalPtr}); |
130 | } else { // neither true nor false side need copy ctor call | ||
131 |
1/2✓ Branch 0 (59→60) taken 263 times.
✗ Branch 1 (59→208) not taken.
|
263 | trueValue = resolveValue(trueNode); |
132 | } | ||
133 | // Set the true block to the current insert point, since it could have changed in the meantime | ||
134 | 281 | condTrue = builder.GetInsertBlock(); | |
135 |
1/2✓ Branch 0 (62→63) taken 281 times.
✗ Branch 1 (62→208) not taken.
|
281 | insertJump(condExit); |
136 | |||
137 | // Fill false block | ||
138 |
1/2✓ Branch 0 (63→64) taken 281 times.
✗ Branch 1 (63→208) not taken.
|
281 | switchToBlock(condFalse); |
139 | 281 | llvm::Value *falseValue = nullptr; | |
140 | 281 | llvm::Value *falsePtr = nullptr; | |
141 |
7/8✓ Branch 0 (64→65) taken 273 times.
✓ Branch 1 (64→67) taken 8 times.
✓ Branch 2 (65→66) taken 273 times.
✗ Branch 3 (65→208) not taken.
✓ Branch 4 (66→67) taken 8 times.
✓ Branch 5 (66→68) taken 265 times.
✓ Branch 6 (69→70) taken 16 times.
✓ Branch 7 (69→72) taken 265 times.
|
281 | if (node->trueSideCallsCopyCtor || resultType.isRef()) { // both sides or only the true side needs copy ctor call |
142 |
1/2✓ Branch 0 (70→71) taken 16 times.
✗ Branch 1 (70→208) not taken.
|
16 | falsePtr = resolveAddress(falseNode); |
143 |
2/2✓ Branch 0 (72→73) taken 2 times.
✓ Branch 1 (72→89) taken 263 times.
|
265 | } else if (node->falseSideCallsCopyCtor) { // only false side needs copy ctor call |
144 |
1/2✓ Branch 0 (73→74) taken 2 times.
✗ Branch 1 (73→208) not taken.
|
2 | llvm::Value *originalPtr = resolveAddress(falseNode); |
145 |
3/6✓ Branch 0 (77→78) taken 2 times.
✗ Branch 1 (77→174) not taken.
✓ Branch 2 (78→79) taken 2 times.
✗ Branch 3 (78→174) not taken.
✓ Branch 4 (79→80) taken 2 times.
✗ Branch 5 (79→174) not taken.
|
2 | falsePtr = insertAlloca(falseNode->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile)); |
146 |
2/4✓ Branch 0 (84→85) taken 2 times.
✗ Branch 1 (84→182) not taken.
✓ Branch 2 (85→86) taken 2 times.
✗ Branch 3 (85→180) not taken.
|
6 | generateCtorOrDtorCall(falsePtr, node->calledCopyCtor, {originalPtr}); |
147 | } else { // neither true nor false side need copy ctor call | ||
148 |
1/2✓ Branch 0 (89→90) taken 263 times.
✗ Branch 1 (89→208) not taken.
|
263 | falseValue = resolveValue(falseNode); |
149 | } | ||
150 | // Set the true block to the current insert point, since it could have changed in the meantime | ||
151 | 281 | condFalse = builder.GetInsertBlock(); | |
152 |
1/2✓ Branch 0 (92→93) taken 281 times.
✗ Branch 1 (92→208) not taken.
|
281 | insertJump(condExit); |
153 | |||
154 | // Fill the exit block | ||
155 |
1/2✓ Branch 0 (93→94) taken 281 times.
✗ Branch 1 (93→208) not taken.
|
281 | switchToBlock(condExit); |
156 |
9/10✓ Branch 0 (94→95) taken 273 times.
✓ Branch 1 (94→98) taken 8 times.
✓ Branch 2 (95→96) taken 271 times.
✓ Branch 3 (95→98) taken 2 times.
✓ Branch 4 (96→97) taken 271 times.
✗ Branch 5 (96→208) not taken.
✓ Branch 6 (97→98) taken 8 times.
✓ Branch 7 (97→99) taken 263 times.
✓ Branch 8 (100→101) taken 18 times.
✓ Branch 9 (100→124) taken 263 times.
|
281 | if (node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor || resultType.isRef()) { // one side calls copy ctor |
157 |
3/6✓ Branch 0 (101→102) taken 18 times.
✗ Branch 1 (101→187) not taken.
✓ Branch 2 (102→103) taken 18 times.
✗ Branch 3 (102→187) not taken.
✓ Branch 4 (103→104) taken 18 times.
✗ Branch 5 (103→187) not taken.
|
18 | llvm::PHINode *phiInst = builder.CreatePHI(builder.getPtrTy(), 2, "cond.result"); |
158 |
1/2✓ Branch 0 (104→105) taken 18 times.
✗ Branch 1 (104→208) not taken.
|
18 | phiInst->addIncoming(truePtr, condTrue); |
159 |
1/2✓ Branch 0 (105→106) taken 18 times.
✗ Branch 1 (105→208) not taken.
|
18 | phiInst->addIncoming(falsePtr, condFalse); |
160 |
4/4✓ Branch 0 (106→107) taken 8 times.
✓ Branch 1 (106→122) taken 10 times.
✓ Branch 2 (107→108) taken 6 times.
✓ Branch 3 (107→122) taken 2 times.
|
18 | if (node->trueSideCallsCopyCtor && node->falseSideCallsCopyCtor) { // both sides need copy ctor call |
161 |
2/4✓ Branch 0 (111→112) taken 6 times.
✗ Branch 1 (111→188) not taken.
✓ Branch 2 (112→113) taken 6 times.
✗ Branch 3 (112→188) not taken.
|
6 | resultPtr = insertAlloca(resultType.toLLVMType(sourceFile)); |
162 |
2/4✓ Branch 0 (117→118) taken 6 times.
✗ Branch 1 (117→196) not taken.
✓ Branch 2 (118→119) taken 6 times.
✗ Branch 3 (118→194) not taken.
|
18 | generateCtorOrDtorCall(resultPtr, node->calledCopyCtor, {phiInst}); |
163 | } else { | ||
164 | 12 | resultPtr = phiInst; | |
165 | } | ||
166 | } else { // neither true nor false side calls copy ctor | ||
167 |
1/2✗ Branch 0 (124→125) not taken.
✓ Branch 1 (124→126) taken 263 times.
|
263 | assert(trueValue != nullptr); |
168 |
3/6✓ Branch 0 (126→127) taken 263 times.
✗ Branch 1 (126→201) not taken.
✓ Branch 2 (127→128) taken 263 times.
✗ Branch 3 (127→201) not taken.
✓ Branch 4 (128→129) taken 263 times.
✗ Branch 5 (128→201) not taken.
|
263 | llvm::PHINode *phiInst = builder.CreatePHI(resultType.toLLVMType(sourceFile), 2, "cond.result"); |
169 |
1/2✓ Branch 0 (129→130) taken 263 times.
✗ Branch 1 (129→208) not taken.
|
263 | phiInst->addIncoming(trueValue, condTrue); |
170 |
1/2✓ Branch 0 (130→131) taken 263 times.
✗ Branch 1 (130→208) not taken.
|
263 | phiInst->addIncoming(falseValue, condFalse); |
171 | 263 | resultValue = phiInst; | |
172 | } | ||
173 | |||
174 | // If we have an anonymous symbol for this ternary expr, make sure that it has an address to reference. | ||
175 |
1/2✓ Branch 0 (132→133) taken 281 times.
✗ Branch 1 (132→208) not taken.
|
281 | anonymousSymbol = currentScope->symbolTable.lookupAnonymous(node->codeLoc); |
176 |
2/2✓ Branch 0 (133→134) taken 6 times.
✓ Branch 1 (133→145) taken 275 times.
|
281 | if (anonymousSymbol != nullptr) { |
177 |
1/2✗ Branch 0 (134→135) not taken.
✓ Branch 1 (134→144) taken 6 times.
|
6 | if (!resultPtr) { |
178 | ✗ | resultPtr = insertAlloca(anonymousSymbol->getQualType().toLLVMType(sourceFile)); | |
179 | ✗ | insertStore(resultValue, resultPtr); | |
180 | } | ||
181 |
1/2✓ Branch 0 (144→145) taken 6 times.
✗ Branch 1 (144→208) not taken.
|
6 | anonymousSymbol->updateAddress(resultPtr); |
182 | } | ||
183 | 281 | } | |
184 | |||
185 |
1/2✓ Branch 0 (147→148) taken 307 times.
✗ Branch 1 (147→211) not taken.
|
614 | return LLVMExprResult{.value = resultValue, .ptr = resultPtr, .entry = anonymousSymbol}; |
186 | } | ||
187 | |||
188 | 50863 | std::any IRGenerator::visitLogicalOrExpr(const LogicalOrExprNode *node) { | |
189 |
1/2✓ Branch 0 (2→3) taken 50863 times.
✗ Branch 1 (2→96) not taken.
|
50863 | diGenerator.setSourceLocation(node); |
190 | |||
191 | // Check if only one operand is present -> loop through | ||
192 |
2/2✓ Branch 0 (4→5) taken 50063 times.
✓ Branch 1 (4→8) taken 800 times.
|
50863 | if (node->operands.size() == 1) |
193 |
1/2✓ Branch 0 (6→7) taken 50063 times.
✗ Branch 1 (6→96) not taken.
|
50063 | return visit(node->operands.front()); |
194 | |||
195 | // It is a logical or expression | ||
196 | // Create exit block for short-circuiting | ||
197 |
1/2✓ Branch 0 (8→9) taken 800 times.
✗ Branch 1 (8→96) not taken.
|
800 | const std::string codeLoc = node->codeLoc.toPrettyLineAndColumn(); |
198 |
2/4✓ Branch 0 (9→10) taken 800 times.
✗ Branch 1 (9→73) not taken.
✓ Branch 2 (10→11) taken 800 times.
✗ Branch 3 (10→71) not taken.
|
800 | llvm::BasicBlock *bExit = createBlock("lor.exit." + codeLoc); |
199 | |||
200 | // Visit the first operand | ||
201 |
1/2✓ Branch 0 (13→14) taken 800 times.
✗ Branch 1 (13→94) not taken.
|
800 | llvm::Value *firstOperandValue = resolveValue(node->operands.front()); |
202 | |||
203 | // Prepare an array for value-to-block-mapping | ||
204 | 800 | std::vector<std::pair<llvm::BasicBlock *, llvm::Value *>> shortCircuitBlocks; | |
205 |
1/2✓ Branch 0 (15→16) taken 800 times.
✗ Branch 1 (15→92) not taken.
|
800 | shortCircuitBlocks.reserve(node->operands.size()); |
206 | // The first element is the first operand value with the original block | ||
207 |
1/2✓ Branch 0 (17→18) taken 800 times.
✗ Branch 1 (17→74) not taken.
|
800 | shortCircuitBlocks.emplace_back(builder.GetInsertBlock(), firstOperandValue); |
208 | // Create a block for each additional operand and save it to the mapping | ||
209 |
2/2✓ Branch 0 (31→19) taken 1031 times.
✓ Branch 1 (31→32) taken 800 times.
|
1831 | for (size_t i = 1; i < node->operands.size(); i++) |
210 |
6/12✓ Branch 0 (19→20) taken 1031 times.
✗ Branch 1 (19→83) not taken.
✓ Branch 2 (20→21) taken 1031 times.
✗ Branch 3 (20→81) not taken.
✓ Branch 4 (21→22) taken 1031 times.
✗ Branch 5 (21→79) not taken.
✓ Branch 6 (22→23) taken 1031 times.
✗ Branch 7 (22→77) not taken.
✓ Branch 8 (23→24) taken 1031 times.
✗ Branch 9 (23→75) not taken.
✓ Branch 10 (24→25) taken 1031 times.
✗ Branch 11 (24→75) not taken.
|
1031 | shortCircuitBlocks.emplace_back(createBlock("lor." + std::to_string(i) + "." + codeLoc), nullptr); |
211 | // Create conditional jump to the exit block if the first operand was true, otherwise to the next block | ||
212 |
2/4✓ Branch 0 (32→33) taken 800 times.
✗ Branch 1 (32→92) not taken.
✓ Branch 2 (33→34) taken 800 times.
✗ Branch 3 (33→92) not taken.
|
800 | insertCondJump(firstOperandValue, bExit, shortCircuitBlocks.at(1).first); |
213 | |||
214 | // Create block for each operand | ||
215 |
2/2✓ Branch 0 (50→35) taken 1031 times.
✓ Branch 1 (50→51) taken 800 times.
|
1831 | for (size_t i = 1; i < node->operands.size(); i++) { |
216 | // Switch to the next block | ||
217 |
2/4✓ Branch 0 (35→36) taken 1031 times.
✗ Branch 1 (35→92) not taken.
✓ Branch 2 (36→37) taken 1031 times.
✗ Branch 3 (36→92) not taken.
|
1031 | switchToBlock(shortCircuitBlocks.at(i).first); |
218 | // Evaluate operand and save the result in the mapping | ||
219 |
2/4✓ Branch 0 (38→39) taken 1031 times.
✗ Branch 1 (38→92) not taken.
✓ Branch 2 (39→40) taken 1031 times.
✗ Branch 3 (39→92) not taken.
|
1031 | shortCircuitBlocks.at(i).second = resolveValue(node->operands[i]); |
220 | // Replace the array entry with the current insert block, since the insert block could have changed in the meantime | ||
221 |
1/2✓ Branch 0 (41→42) taken 1031 times.
✗ Branch 1 (41→92) not taken.
|
1031 | shortCircuitBlocks.at(i).first = builder.GetInsertBlock(); |
222 | // Check if there are more blocks to process | ||
223 |
2/2✓ Branch 0 (43→44) taken 800 times.
✓ Branch 1 (43→45) taken 231 times.
|
1031 | if (i == node->operands.size() - 1) { |
224 | // Insert a simple jump to the exit block for the last block | ||
225 |
1/2✓ Branch 0 (44→48) taken 800 times.
✗ Branch 1 (44→92) not taken.
|
800 | insertJump(bExit); |
226 | } else { | ||
227 | // Create conditional jump to the exit block if the first operand was true, otherwise to the next block | ||
228 |
3/6✓ Branch 0 (45→46) taken 231 times.
✗ Branch 1 (45→92) not taken.
✓ Branch 2 (46→47) taken 231 times.
✗ Branch 3 (46→92) not taken.
✓ Branch 4 (47→48) taken 231 times.
✗ Branch 5 (47→92) not taken.
|
231 | insertCondJump(shortCircuitBlocks.at(i).second, bExit, shortCircuitBlocks.at(i + 1).first); |
229 | } | ||
230 | } | ||
231 | |||
232 | // Get the result with the phi node | ||
233 |
1/2✓ Branch 0 (51→52) taken 800 times.
✗ Branch 1 (51→92) not taken.
|
800 | switchToBlock(bExit); |
234 |
2/4✓ Branch 0 (52→53) taken 800 times.
✗ Branch 1 (52→89) not taken.
✓ Branch 2 (55→56) taken 800 times.
✗ Branch 3 (55→89) not taken.
|
800 | llvm::PHINode *result = builder.CreatePHI(firstOperandValue->getType(), node->operands.size(), "lor_phi"); |
235 |
2/2✓ Branch 0 (64→58) taken 1831 times.
✓ Branch 1 (64→65) taken 800 times.
|
2631 | for (const auto &[incomingBlock, value] : shortCircuitBlocks) |
236 |
1/2✓ Branch 0 (61→62) taken 1831 times.
✗ Branch 1 (61→90) not taken.
|
1831 | result->addIncoming(value, incomingBlock); |
237 | |||
238 | // Return the result | ||
239 |
1/2✓ Branch 0 (65→66) taken 800 times.
✗ Branch 1 (65→91) not taken.
|
800 | return LLVMExprResult{.value = result}; |
240 | 800 | } | |
241 | |||
242 | 51894 | std::any IRGenerator::visitLogicalAndExpr(const LogicalAndExprNode *node) { | |
243 |
1/2✓ Branch 0 (2→3) taken 51894 times.
✗ Branch 1 (2→96) not taken.
|
51894 | diGenerator.setSourceLocation(node); |
244 | |||
245 | // Check if only one operand is present -> loop through | ||
246 |
2/2✓ Branch 0 (4→5) taken 51761 times.
✓ Branch 1 (4→8) taken 133 times.
|
51894 | if (node->operands.size() == 1) |
247 |
1/2✓ Branch 0 (6→7) taken 51761 times.
✗ Branch 1 (6→96) not taken.
|
51761 | return visit(node->operands.front()); |
248 | |||
249 | // It is a logical and expression | ||
250 | // Create exit block for short-circuiting | ||
251 |
1/2✓ Branch 0 (8→9) taken 133 times.
✗ Branch 1 (8→96) not taken.
|
133 | const std::string codeLoc = node->codeLoc.toPrettyLineAndColumn(); |
252 |
2/4✓ Branch 0 (9→10) taken 133 times.
✗ Branch 1 (9→73) not taken.
✓ Branch 2 (10→11) taken 133 times.
✗ Branch 3 (10→71) not taken.
|
133 | llvm::BasicBlock *bExit = createBlock("land.exit." + codeLoc); |
253 | |||
254 | // Visit the first operand | ||
255 |
1/2✓ Branch 0 (13→14) taken 133 times.
✗ Branch 1 (13→94) not taken.
|
133 | llvm::Value *firstOperandValue = resolveValue(node->operands.front()); |
256 | |||
257 | // Prepare an array for value-to-block-mapping | ||
258 | 133 | std::vector<std::pair<llvm::BasicBlock *, llvm::Value *>> shortCircuitBlocks; | |
259 |
1/2✓ Branch 0 (15→16) taken 133 times.
✗ Branch 1 (15→92) not taken.
|
133 | shortCircuitBlocks.reserve(node->operands.size()); |
260 | // The first element is the first operand value with the original block | ||
261 |
1/2✓ Branch 0 (17→18) taken 133 times.
✗ Branch 1 (17→74) not taken.
|
133 | shortCircuitBlocks.emplace_back(builder.GetInsertBlock(), firstOperandValue); |
262 | // Create a block for each additional operand and save it to the mapping | ||
263 |
2/2✓ Branch 0 (31→19) taken 166 times.
✓ Branch 1 (31→32) taken 133 times.
|
299 | for (size_t i = 1; i < node->operands.size(); i++) |
264 |
6/12✓ Branch 0 (19→20) taken 166 times.
✗ Branch 1 (19→83) not taken.
✓ Branch 2 (20→21) taken 166 times.
✗ Branch 3 (20→81) not taken.
✓ Branch 4 (21→22) taken 166 times.
✗ Branch 5 (21→79) not taken.
✓ Branch 6 (22→23) taken 166 times.
✗ Branch 7 (22→77) not taken.
✓ Branch 8 (23→24) taken 166 times.
✗ Branch 9 (23→75) not taken.
✓ Branch 10 (24→25) taken 166 times.
✗ Branch 11 (24→75) not taken.
|
166 | shortCircuitBlocks.emplace_back(createBlock("land." + std::to_string(i) + "." + codeLoc), nullptr); |
265 | // Create conditional jump to the exit block if the first operand was true, otherwise to the next block | ||
266 |
2/4✓ Branch 0 (32→33) taken 133 times.
✗ Branch 1 (32→92) not taken.
✓ Branch 2 (33→34) taken 133 times.
✗ Branch 3 (33→92) not taken.
|
133 | insertCondJump(firstOperandValue, shortCircuitBlocks.at(1).first, bExit); |
267 | |||
268 | // Create block for each operand | ||
269 |
2/2✓ Branch 0 (50→35) taken 166 times.
✓ Branch 1 (50→51) taken 133 times.
|
299 | for (size_t i = 1; i < node->operands.size(); i++) { |
270 | // Switch to the next block | ||
271 |
2/4✓ Branch 0 (35→36) taken 166 times.
✗ Branch 1 (35→92) not taken.
✓ Branch 2 (36→37) taken 166 times.
✗ Branch 3 (36→92) not taken.
|
166 | switchToBlock(shortCircuitBlocks.at(i).first); |
272 | // Evaluate operand and save the result in the mapping | ||
273 |
2/4✓ Branch 0 (38→39) taken 166 times.
✗ Branch 1 (38→92) not taken.
✓ Branch 2 (39→40) taken 166 times.
✗ Branch 3 (39→92) not taken.
|
166 | shortCircuitBlocks.at(i).second = resolveValue(node->operands[i]); |
274 | // Replace the array entry with the current insert block, since the insert block could have changed in the meantime | ||
275 |
1/2✓ Branch 0 (41→42) taken 166 times.
✗ Branch 1 (41→92) not taken.
|
166 | shortCircuitBlocks.at(i).first = builder.GetInsertBlock(); |
276 | // Check if there are more blocks to process | ||
277 |
2/2✓ Branch 0 (43→44) taken 133 times.
✓ Branch 1 (43→45) taken 33 times.
|
166 | if (i == node->operands.size() - 1) { |
278 | // Insert a simple jump to the exit block for the last block | ||
279 |
1/2✓ Branch 0 (44→48) taken 133 times.
✗ Branch 1 (44→92) not taken.
|
133 | insertJump(bExit); |
280 | } else { | ||
281 | // Create conditional jump to the exit block if the operand was true, otherwise to the next block | ||
282 |
3/6✓ Branch 0 (45→46) taken 33 times.
✗ Branch 1 (45→92) not taken.
✓ Branch 2 (46→47) taken 33 times.
✗ Branch 3 (46→92) not taken.
✓ Branch 4 (47→48) taken 33 times.
✗ Branch 5 (47→92) not taken.
|
33 | insertCondJump(shortCircuitBlocks.at(i).second, shortCircuitBlocks.at(i + 1).first, bExit); |
283 | } | ||
284 | } | ||
285 | |||
286 | // Get the result with the phi node | ||
287 |
1/2✓ Branch 0 (51→52) taken 133 times.
✗ Branch 1 (51→92) not taken.
|
133 | switchToBlock(bExit); |
288 |
2/4✓ Branch 0 (52→53) taken 133 times.
✗ Branch 1 (52→89) not taken.
✓ Branch 2 (55→56) taken 133 times.
✗ Branch 3 (55→89) not taken.
|
133 | llvm::PHINode *result = builder.CreatePHI(firstOperandValue->getType(), node->operands.size(), "land_phi"); |
289 |
2/2✓ Branch 0 (64→58) taken 299 times.
✓ Branch 1 (64→65) taken 133 times.
|
432 | for (const auto &[incomingBlock, value] : shortCircuitBlocks) |
290 |
1/2✓ Branch 0 (61→62) taken 299 times.
✗ Branch 1 (61→90) not taken.
|
299 | result->addIncoming(value, incomingBlock); |
291 | |||
292 | // Return the result | ||
293 |
1/2✓ Branch 0 (65→66) taken 133 times.
✗ Branch 1 (65→91) not taken.
|
133 | return LLVMExprResult{.value = result}; |
294 | 133 | } | |
295 | |||
296 | 52060 | std::any IRGenerator::visitBitwiseOrExpr(const BitwiseOrExprNode *node) { | |
297 |
1/2✓ Branch 0 (2→3) taken 52060 times.
✗ Branch 1 (2→34) not taken.
|
52060 | diGenerator.setSourceLocation(node); |
298 | |||
299 | // Check if only one operand is present -> loop through | ||
300 |
2/2✓ Branch 0 (4→5) taken 51998 times.
✓ Branch 1 (4→8) taken 62 times.
|
52060 | if (node->operands.size() == 1) |
301 |
1/2✓ Branch 0 (6→7) taken 51998 times.
✗ Branch 1 (6→34) not taken.
|
51998 | return visit(node->operands.front()); |
302 | |||
303 | // It is a bitwise or expression | ||
304 | // Evaluate first operand | ||
305 | 62 | const BitwiseXorExprNode *lhsNode = node->operands.front(); | |
306 |
1/2✓ Branch 0 (9→10) taken 62 times.
✗ Branch 1 (9→34) not taken.
|
62 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
307 |
2/4✓ Branch 0 (10→11) taken 62 times.
✗ Branch 1 (10→29) not taken.
✓ Branch 2 (11→12) taken 62 times.
✗ Branch 3 (11→27) not taken.
|
62 | auto result = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
308 | |||
309 | // Evaluate all additional operands | ||
310 |
2/2✓ Branch 0 (22→14) taken 63 times.
✓ Branch 1 (22→23) taken 62 times.
|
125 | for (size_t i = 1; i < node->operands.size(); i++) { |
311 | // Evaluate the operand | ||
312 | 63 | const BitwiseXorExprNode *rhsNode = node->operands[i]; | |
313 |
1/2✓ Branch 0 (15→16) taken 63 times.
✗ Branch 1 (15→33) not taken.
|
63 | const QualType rhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
314 |
2/4✓ Branch 0 (16→17) taken 63 times.
✗ Branch 1 (16→32) not taken.
✓ Branch 2 (17→18) taken 63 times.
✗ Branch 3 (17→30) not taken.
|
63 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
315 |
1/2✓ Branch 0 (19→20) taken 63 times.
✗ Branch 1 (19→33) not taken.
|
63 | result = conversionManager.getBitwiseOrInst(node, result, lhsSTy, rhs, rhsSTy, i - 1); |
316 | } | ||
317 | |||
318 | // Return result | ||
319 |
1/2✓ Branch 0 (23→24) taken 62 times.
✗ Branch 1 (23→34) not taken.
|
62 | return result; |
320 | } | ||
321 | |||
322 | 52123 | std::any IRGenerator::visitBitwiseXorExpr(const BitwiseXorExprNode *node) { | |
323 |
1/2✓ Branch 0 (2→3) taken 52123 times.
✗ Branch 1 (2→34) not taken.
|
52123 | diGenerator.setSourceLocation(node); |
324 | |||
325 | // Check if only one operand is present -> loop through | ||
326 |
2/2✓ Branch 0 (4→5) taken 52121 times.
✓ Branch 1 (4→8) taken 2 times.
|
52123 | if (node->operands.size() == 1) |
327 |
1/2✓ Branch 0 (6→7) taken 52121 times.
✗ Branch 1 (6→34) not taken.
|
52121 | return visit(node->operands.front()); |
328 | |||
329 | // It is a bitwise xor expression | ||
330 | // Evaluate first operand | ||
331 | 2 | const BitwiseAndExprNode *lhsNode = node->operands.front(); | |
332 |
1/2✓ Branch 0 (9→10) taken 2 times.
✗ Branch 1 (9→34) not taken.
|
2 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
333 |
2/4✓ Branch 0 (10→11) taken 2 times.
✗ Branch 1 (10→29) not taken.
✓ Branch 2 (11→12) taken 2 times.
✗ Branch 3 (11→27) not taken.
|
2 | auto result = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
334 | |||
335 | // Evaluate all additional operands | ||
336 |
2/2✓ Branch 0 (22→14) taken 3 times.
✓ Branch 1 (22→23) taken 2 times.
|
5 | for (size_t i = 1; i < node->operands.size(); i++) { |
337 | // Evaluate the operand | ||
338 | 3 | const BitwiseAndExprNode *rhsNode = node->operands[i]; | |
339 |
1/2✓ Branch 0 (15→16) taken 3 times.
✗ Branch 1 (15→33) not taken.
|
3 | const QualType rhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
340 |
2/4✓ Branch 0 (16→17) taken 3 times.
✗ Branch 1 (16→32) not taken.
✓ Branch 2 (17→18) taken 3 times.
✗ Branch 3 (17→30) not taken.
|
3 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
341 |
1/2✓ Branch 0 (19→20) taken 3 times.
✗ Branch 1 (19→33) not taken.
|
3 | result = conversionManager.getBitwiseXorInst(node, result, lhsSTy, rhs, rhsSTy); |
342 | } | ||
343 | |||
344 | // Return result | ||
345 |
1/2✓ Branch 0 (23→24) taken 2 times.
✗ Branch 1 (23→34) not taken.
|
2 | return result; |
346 | } | ||
347 | |||
348 | 52126 | std::any IRGenerator::visitBitwiseAndExpr(const BitwiseAndExprNode *node) { | |
349 |
1/2✓ Branch 0 (2→3) taken 52126 times.
✗ Branch 1 (2→34) not taken.
|
52126 | diGenerator.setSourceLocation(node); |
350 | |||
351 | // Check if only one operand is present -> loop through | ||
352 |
2/2✓ Branch 0 (4→5) taken 52098 times.
✓ Branch 1 (4→8) taken 28 times.
|
52126 | if (node->operands.size() == 1) |
353 |
1/2✓ Branch 0 (6→7) taken 52098 times.
✗ Branch 1 (6→34) not taken.
|
52098 | return visit(node->operands.front()); |
354 | |||
355 | // It is a bitwise and expression | ||
356 | // Evaluate first operand | ||
357 | 28 | const EqualityExprNode *lhsNode = node->operands.front(); | |
358 |
1/2✓ Branch 0 (9→10) taken 28 times.
✗ Branch 1 (9→34) not taken.
|
28 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
359 |
2/4✓ Branch 0 (10→11) taken 28 times.
✗ Branch 1 (10→29) not taken.
✓ Branch 2 (11→12) taken 28 times.
✗ Branch 3 (11→27) not taken.
|
28 | auto result = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
360 | |||
361 | // Evaluate all additional operands | ||
362 |
2/2✓ Branch 0 (22→14) taken 29 times.
✓ Branch 1 (22→23) taken 28 times.
|
57 | for (size_t i = 1; i < node->operands.size(); i++) { |
363 | // Evaluate the operand | ||
364 | 29 | const EqualityExprNode *rhsNode = node->operands[i]; | |
365 |
1/2✓ Branch 0 (15→16) taken 29 times.
✗ Branch 1 (15→33) not taken.
|
29 | const QualType rhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
366 |
2/4✓ Branch 0 (16→17) taken 29 times.
✗ Branch 1 (16→32) not taken.
✓ Branch 2 (17→18) taken 29 times.
✗ Branch 3 (17→30) not taken.
|
29 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
367 |
1/2✓ Branch 0 (19→20) taken 29 times.
✗ Branch 1 (19→33) not taken.
|
29 | result = conversionManager.getBitwiseAndInst(rhsNode, result, lhsSTy, rhs, rhsSTy, i - 1); |
368 | } | ||
369 | |||
370 | // Return result | ||
371 |
1/2✓ Branch 0 (23→24) taken 28 times.
✗ Branch 1 (23→34) not taken.
|
28 | return result; |
372 | } | ||
373 | |||
374 | 52155 | std::any IRGenerator::visitEqualityExpr(const EqualityExprNode *node) { | |
375 |
1/2✓ Branch 0 (2→3) taken 52155 times.
✗ Branch 1 (2→50) not taken.
|
52155 | diGenerator.setSourceLocation(node); |
376 | |||
377 | // Check if only one operand is present -> loop through | ||
378 |
2/2✓ Branch 0 (4→5) taken 47795 times.
✓ Branch 1 (4→8) taken 4360 times.
|
52155 | if (node->operands.size() == 1) |
379 |
1/2✓ Branch 0 (6→7) taken 47795 times.
✗ Branch 1 (6→50) not taken.
|
47795 | return visit(node->operands.front()); |
380 | |||
381 | // It is an equality expression | ||
382 | // Evaluate lhs | ||
383 | 4360 | const RelationalExprNode *lhsNode = node->operands[0]; | |
384 |
1/2✓ Branch 0 (9→10) taken 4360 times.
✗ Branch 1 (9→50) not taken.
|
4360 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
385 |
2/4✓ Branch 0 (10→11) taken 4360 times.
✗ Branch 1 (10→37) not taken.
✓ Branch 2 (11→12) taken 4360 times.
✗ Branch 3 (11→35) not taken.
|
4360 | auto result = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
386 | |||
387 | // Evaluate rhs | ||
388 | 4360 | const RelationalExprNode *rhsNode = node->operands[1]; | |
389 |
1/2✓ Branch 0 (14→15) taken 4360 times.
✗ Branch 1 (14→50) not taken.
|
4360 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
390 |
2/4✓ Branch 0 (15→16) taken 4360 times.
✗ Branch 1 (15→40) not taken.
✓ Branch 2 (16→17) taken 4360 times.
✗ Branch 3 (16→38) not taken.
|
4360 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
391 | |||
392 | // Retrieve the result value, based on the exact operator | ||
393 |
2/3✓ Branch 0 (18→19) taken 3081 times.
✓ Branch 1 (18→21) taken 1279 times.
✗ Branch 2 (18→23) not taken.
|
4360 | switch (node->op) { |
394 | 3081 | case EqualityExprNode::EqualityOp::OP_EQUAL: | |
395 |
1/2✓ Branch 0 (19→20) taken 3081 times.
✗ Branch 1 (19→50) not taken.
|
3081 | result = conversionManager.getEqualInst(node, result, lhsSTy, rhs, rhsSTy, 0); |
396 | 3081 | break; | |
397 | 1279 | case EqualityExprNode::EqualityOp::OP_NOT_EQUAL: | |
398 |
1/2✓ Branch 0 (21→22) taken 1279 times.
✗ Branch 1 (21→50) not taken.
|
1279 | result = conversionManager.getNotEqualInst(node, result, lhsSTy, rhs, rhsSTy, 0); |
399 | 1279 | break; | |
400 | − | default: // GCOV_EXCL_LINE | |
401 | − | throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE | |
402 | } | ||
403 | |||
404 | // Return the result | ||
405 |
1/2✓ Branch 0 (31→32) taken 4360 times.
✗ Branch 1 (31→50) not taken.
|
4360 | return result; |
406 | } | ||
407 | |||
408 | 56515 | std::any IRGenerator::visitRelationalExpr(const RelationalExprNode *node) { | |
409 |
1/2✓ Branch 0 (2→3) taken 56515 times.
✗ Branch 1 (2→54) not taken.
|
56515 | diGenerator.setSourceLocation(node); |
410 | |||
411 | // Check if only one operand is present -> loop through | ||
412 |
2/2✓ Branch 0 (4→5) taken 53598 times.
✓ Branch 1 (4→8) taken 2917 times.
|
56515 | if (node->operands.size() == 1) |
413 |
1/2✓ Branch 0 (6→7) taken 53598 times.
✗ Branch 1 (6→54) not taken.
|
53598 | return visit(node->operands.front()); |
414 | |||
415 | // It is a relational expression | ||
416 | // Evaluate lhs | ||
417 | 2917 | const ShiftExprNode *lhsNode = node->operands[0]; | |
418 |
1/2✓ Branch 0 (9→10) taken 2917 times.
✗ Branch 1 (9→54) not taken.
|
2917 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
419 |
2/4✓ Branch 0 (10→11) taken 2917 times.
✗ Branch 1 (10→41) not taken.
✓ Branch 2 (11→12) taken 2917 times.
✗ Branch 3 (11→39) not taken.
|
2917 | auto result = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
420 | |||
421 | // Evaluate rhs | ||
422 | 2917 | const ShiftExprNode *rhsNode = node->operands[1]; | |
423 |
1/2✓ Branch 0 (14→15) taken 2917 times.
✗ Branch 1 (14→54) not taken.
|
2917 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
424 |
2/4✓ Branch 0 (15→16) taken 2917 times.
✗ Branch 1 (15→44) not taken.
✓ Branch 2 (16→17) taken 2917 times.
✗ Branch 3 (16→42) not taken.
|
2917 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
425 | |||
426 | // Retrieve the result value, based on the exact operator | ||
427 |
4/5✓ Branch 0 (18→19) taken 1484 times.
✓ Branch 1 (18→21) taken 364 times.
✓ Branch 2 (18→23) taken 317 times.
✓ Branch 3 (18→25) taken 752 times.
✗ Branch 4 (18→27) not taken.
|
2917 | switch (node->op) { |
428 | 1484 | case RelationalExprNode::RelationalOp::OP_LESS: | |
429 |
1/2✓ Branch 0 (19→20) taken 1484 times.
✗ Branch 1 (19→54) not taken.
|
1484 | result = conversionManager.getLessInst(node, result, lhsSTy, rhs, rhsSTy); |
430 | 1484 | break; | |
431 | 364 | case RelationalExprNode::RelationalOp::OP_GREATER: | |
432 |
1/2✓ Branch 0 (21→22) taken 364 times.
✗ Branch 1 (21→54) not taken.
|
364 | result = conversionManager.getGreaterInst(node, result, lhsSTy, rhs, rhsSTy); |
433 | 364 | break; | |
434 | 317 | case RelationalExprNode::RelationalOp::OP_LESS_EQUAL: | |
435 |
1/2✓ Branch 0 (23→24) taken 317 times.
✗ Branch 1 (23→54) not taken.
|
317 | result = conversionManager.getLessEqualInst(node, result, lhsSTy, rhs, rhsSTy); |
436 | 317 | break; | |
437 | 752 | case RelationalExprNode::RelationalOp::OP_GREATER_EQUAL: | |
438 |
1/2✓ Branch 0 (25→26) taken 752 times.
✗ Branch 1 (25→54) not taken.
|
752 | result = conversionManager.getGreaterEqualInst(node, result, lhsSTy, rhs, rhsSTy); |
439 | 752 | break; | |
440 | − | default: // GCOV_EXCL_LINE | |
441 | − | throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE | |
442 | } | ||
443 | |||
444 | // Return the result | ||
445 |
1/2✓ Branch 0 (35→36) taken 2917 times.
✗ Branch 1 (35→54) not taken.
|
2917 | return result; |
446 | } | ||
447 | |||
448 | 59432 | std::any IRGenerator::visitShiftExpr(const ShiftExprNode *node) { | |
449 |
1/2✓ Branch 0 (2→3) taken 59432 times.
✗ Branch 1 (2→64) not taken.
|
59432 | diGenerator.setSourceLocation(node); |
450 | |||
451 | // Check if only one operand is present -> loop through | ||
452 |
2/2✓ Branch 0 (4→5) taken 59395 times.
✓ Branch 1 (4→8) taken 37 times.
|
59432 | if (node->operands.size() == 1) |
453 |
1/2✓ Branch 0 (6→7) taken 59395 times.
✗ Branch 1 (6→64) not taken.
|
59395 | return visit(node->operands.front()); |
454 | |||
455 | // It is a shift expression | ||
456 | // Evaluate first operand | ||
457 | 37 | const AdditiveExprNode *lhsNode = node->operands.front(); | |
458 |
1/2✓ Branch 0 (9→10) taken 37 times.
✗ Branch 1 (9→64) not taken.
|
37 | QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
459 |
2/4✓ Branch 0 (10→11) taken 37 times.
✗ Branch 1 (10→48) not taken.
✓ Branch 2 (11→12) taken 37 times.
✗ Branch 3 (11→46) not taken.
|
37 | auto lhs = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
460 | |||
461 |
1/2✓ Branch 0 (13→14) taken 37 times.
✗ Branch 1 (13→64) not taken.
|
37 | auto opQueue = node->opQueue; |
462 | 37 | size_t operandIndex = 1; | |
463 |
2/2✓ Branch 0 (40→15) taken 61 times.
✓ Branch 1 (40→41) taken 37 times.
|
98 | while (!opQueue.empty()) { |
464 | 61 | const size_t operatorIndex = operandIndex - 1; | |
465 | // Evaluate next operand | ||
466 | 61 | const AdditiveExprNode *rhsNode = node->operands[operandIndex++]; | |
467 |
1/2✗ Branch 0 (16→17) not taken.
✓ Branch 1 (16→18) taken 61 times.
|
61 | assert(rhsNode != nullptr); |
468 |
1/2✓ Branch 0 (18→19) taken 61 times.
✗ Branch 1 (18→61) not taken.
|
61 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
469 |
2/4✓ Branch 0 (19→20) taken 61 times.
✗ Branch 1 (19→51) not taken.
✓ Branch 2 (20→21) taken 61 times.
✗ Branch 3 (20→49) not taken.
|
61 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
470 | |||
471 | // Retrieve the result, based on the exact operator | ||
472 |
2/3✓ Branch 0 (23→24) taken 56 times.
✓ Branch 1 (23→26) taken 5 times.
✗ Branch 2 (23→28) not taken.
|
61 | switch (opQueue.front().first) { |
473 | 56 | case ShiftExprNode::ShiftOp::OP_SHIFT_LEFT: | |
474 |
1/2✓ Branch 0 (24→25) taken 56 times.
✗ Branch 1 (24→61) not taken.
|
56 | lhs = conversionManager.getShiftLeftInst(node, lhs, lhsSTy, rhs, rhsSTy, operatorIndex); |
475 | 56 | break; | |
476 | 5 | case ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT: | |
477 |
1/2✓ Branch 0 (26→27) taken 5 times.
✗ Branch 1 (26→61) not taken.
|
5 | lhs = conversionManager.getShiftRightInst(node, lhs, lhsSTy, rhs, rhsSTy, operatorIndex); |
478 | 5 | break; | |
479 | − | default: // GCOV_EXCL_LINE | |
480 | − | throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE | |
481 | } | ||
482 | |||
483 | // Retrieve the new lhs symbol type | ||
484 | 61 | lhsSTy = opQueue.front().second; | |
485 | |||
486 | 61 | opQueue.pop(); | |
487 | } | ||
488 | |||
489 | // Return the result | ||
490 |
1/2✓ Branch 0 (41→42) taken 37 times.
✗ Branch 1 (41→62) not taken.
|
37 | return lhs; |
491 | 37 | } | |
492 | |||
493 | 59493 | std::any IRGenerator::visitAdditiveExpr(const AdditiveExprNode *node) { | |
494 |
1/2✓ Branch 0 (2→3) taken 59493 times.
✗ Branch 1 (2→64) not taken.
|
59493 | diGenerator.setSourceLocation(node); |
495 | |||
496 | // Check if only one operand is present -> loop through | ||
497 |
2/2✓ Branch 0 (4→5) taken 56126 times.
✓ Branch 1 (4→8) taken 3367 times.
|
59493 | if (node->operands.size() == 1) |
498 |
1/2✓ Branch 0 (6→7) taken 56126 times.
✗ Branch 1 (6→64) not taken.
|
56126 | return visit(node->operands.front()); |
499 | |||
500 | // It is an additive expression | ||
501 | // Evaluate first operand | ||
502 | 3367 | const MultiplicativeExprNode *lhsNode = node->operands[0]; | |
503 |
1/2✓ Branch 0 (9→10) taken 3367 times.
✗ Branch 1 (9→64) not taken.
|
3367 | QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
504 |
2/4✓ Branch 0 (10→11) taken 3367 times.
✗ Branch 1 (10→48) not taken.
✓ Branch 2 (11→12) taken 3367 times.
✗ Branch 3 (11→46) not taken.
|
3367 | auto lhs = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
505 | |||
506 |
1/2✓ Branch 0 (13→14) taken 3367 times.
✗ Branch 1 (13→64) not taken.
|
3367 | auto opQueue = node->opQueue; |
507 | 3367 | size_t operandIndex = 1; | |
508 |
2/2✓ Branch 0 (40→15) taken 3832 times.
✓ Branch 1 (40→41) taken 3367 times.
|
7199 | while (!opQueue.empty()) { |
509 | 3832 | const size_t operatorIndex = operandIndex - 1; | |
510 | // Evaluate next operand | ||
511 | 3832 | const MultiplicativeExprNode *rhsNode = node->operands[operandIndex++]; | |
512 |
1/2✗ Branch 0 (16→17) not taken.
✓ Branch 1 (16→18) taken 3832 times.
|
3832 | assert(rhsNode != nullptr); |
513 |
1/2✓ Branch 0 (18→19) taken 3832 times.
✗ Branch 1 (18→61) not taken.
|
3832 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
514 |
2/4✓ Branch 0 (19→20) taken 3832 times.
✗ Branch 1 (19→51) not taken.
✓ Branch 2 (20→21) taken 3832 times.
✗ Branch 3 (20→49) not taken.
|
3832 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
515 | |||
516 | // Retrieve the result, based on the exact operator | ||
517 |
2/3✓ Branch 0 (23→24) taken 2285 times.
✓ Branch 1 (23→26) taken 1547 times.
✗ Branch 2 (23→28) not taken.
|
3832 | switch (opQueue.front().first) { |
518 | 2285 | case AdditiveExprNode::AdditiveOp::OP_PLUS: | |
519 |
1/2✓ Branch 0 (24→25) taken 2285 times.
✗ Branch 1 (24→61) not taken.
|
2285 | lhs = conversionManager.getPlusInst(node, lhs, lhsSTy, rhs, rhsSTy, operatorIndex); |
520 | 2285 | break; | |
521 | 1547 | case AdditiveExprNode::AdditiveOp::OP_MINUS: | |
522 |
1/2✓ Branch 0 (26→27) taken 1547 times.
✗ Branch 1 (26→61) not taken.
|
1547 | lhs = conversionManager.getMinusInst(node, lhs, lhsSTy, rhs, rhsSTy, operatorIndex); |
523 | 1547 | break; | |
524 | − | default: // GCOV_EXCL_LINE | |
525 | − | throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE | |
526 | } | ||
527 | |||
528 | // Retrieve the new lhs symbol type | ||
529 | 3832 | lhsSTy = opQueue.front().second; | |
530 | |||
531 | 3832 | opQueue.pop(); | |
532 | } | ||
533 | |||
534 | // Return the result | ||
535 |
1/2✓ Branch 0 (41→42) taken 3367 times.
✗ Branch 1 (41→62) not taken.
|
3367 | return lhs; |
536 | 3367 | } | |
537 | |||
538 | 63325 | std::any IRGenerator::visitMultiplicativeExpr(const MultiplicativeExprNode *node) { | |
539 |
1/2✓ Branch 0 (2→3) taken 63325 times.
✗ Branch 1 (2→66) not taken.
|
63325 | diGenerator.setSourceLocation(node); |
540 | |||
541 | // Check if only one operand is present -> loop through | ||
542 |
2/2✓ Branch 0 (4→5) taken 62491 times.
✓ Branch 1 (4→8) taken 834 times.
|
63325 | if (node->operands.size() == 1) |
543 |
1/2✓ Branch 0 (6→7) taken 62491 times.
✗ Branch 1 (6→66) not taken.
|
62491 | return visit(node->operands.front()); |
544 | |||
545 | // It is an additive expression | ||
546 | // Evaluate first operand | ||
547 | 834 | const CastExprNode *lhsNode = node->operands[0]; | |
548 |
1/2✓ Branch 0 (9→10) taken 834 times.
✗ Branch 1 (9→66) not taken.
|
834 | QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
549 |
2/4✓ Branch 0 (10→11) taken 834 times.
✗ Branch 1 (10→50) not taken.
✓ Branch 2 (11→12) taken 834 times.
✗ Branch 3 (11→48) not taken.
|
834 | auto result = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
550 | |||
551 |
1/2✓ Branch 0 (13→14) taken 834 times.
✗ Branch 1 (13→66) not taken.
|
834 | auto opQueue = node->opQueue; |
552 | 834 | size_t operandIndex = 1; | |
553 |
2/2✓ Branch 0 (42→15) taken 854 times.
✓ Branch 1 (42→43) taken 834 times.
|
1688 | while (!opQueue.empty()) { |
554 | 854 | const size_t operatorIndex = operandIndex - 1; | |
555 | // Evaluate next operand | ||
556 | 854 | const CastExprNode *rhsNode = node->operands[operandIndex++]; | |
557 |
1/2✗ Branch 0 (16→17) not taken.
✓ Branch 1 (16→18) taken 854 times.
|
854 | assert(rhsNode != nullptr); |
558 |
1/2✓ Branch 0 (18→19) taken 854 times.
✗ Branch 1 (18→63) not taken.
|
854 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
559 |
2/4✓ Branch 0 (19→20) taken 854 times.
✗ Branch 1 (19→53) not taken.
✓ Branch 2 (20→21) taken 854 times.
✗ Branch 3 (20→51) not taken.
|
854 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
560 | |||
561 | // Retrieve the result, based on the exact operator | ||
562 |
3/4✓ Branch 0 (23→24) taken 640 times.
✓ Branch 1 (23→26) taken 205 times.
✓ Branch 2 (23→28) taken 9 times.
✗ Branch 3 (23→30) not taken.
|
854 | switch (opQueue.front().first) { |
563 | 640 | case MultiplicativeExprNode::MultiplicativeOp::OP_MUL: | |
564 |
1/2✓ Branch 0 (24→25) taken 640 times.
✗ Branch 1 (24→63) not taken.
|
640 | result = conversionManager.getMulInst(node, result, lhsSTy, rhs, rhsSTy, operatorIndex); |
565 | 640 | break; | |
566 | 205 | case MultiplicativeExprNode::MultiplicativeOp::OP_DIV: | |
567 |
1/2✓ Branch 0 (26→27) taken 205 times.
✗ Branch 1 (26→63) not taken.
|
205 | result = conversionManager.getDivInst(node, result, lhsSTy, rhs, rhsSTy, operatorIndex); |
568 | 205 | break; | |
569 | 9 | case MultiplicativeExprNode::MultiplicativeOp::OP_REM: | |
570 |
1/2✓ Branch 0 (28→29) taken 9 times.
✗ Branch 1 (28→63) not taken.
|
9 | result = conversionManager.getRemInst(node, result, lhsSTy, rhs, rhsSTy); |
571 | 9 | break; | |
572 | − | default: // GCOV_EXCL_LINE | |
573 | − | throw CompilerError(UNHANDLED_BRANCH, "MultiplicativeExpr fall-through"); // GCOV_EXCL_LINE | |
574 | } | ||
575 | |||
576 | // Retrieve the new lhs symbol type | ||
577 | 854 | lhsSTy = opQueue.front().second; | |
578 | 854 | opQueue.pop(); | |
579 | } | ||
580 | |||
581 | // Return the result | ||
582 |
1/2✓ Branch 0 (43→44) taken 834 times.
✗ Branch 1 (43→64) not taken.
|
834 | return result; |
583 | 834 | } | |
584 | |||
585 | 64179 | std::any IRGenerator::visitCastExpr(const CastExprNode *node) { | |
586 |
1/2✓ Branch 0 (2→3) taken 64179 times.
✗ Branch 1 (2→19) not taken.
|
64179 | diGenerator.setSourceLocation(node); |
587 | |||
588 | // Check if only one operand is present -> loop through | ||
589 |
2/2✓ Branch 0 (3→4) taken 61667 times.
✓ Branch 1 (3→6) taken 2512 times.
|
64179 | if (!node->isCast) |
590 |
1/2✓ Branch 0 (4→5) taken 61667 times.
✗ Branch 1 (4→19) not taken.
|
61667 | return visit(node->prefixUnaryExpr); |
591 | |||
592 | // It is a cast expression | ||
593 | // Retrieve target symbol type | ||
594 |
1/2✓ Branch 0 (6→7) taken 2512 times.
✗ Branch 1 (6→19) not taken.
|
2512 | const QualType targetSTy = node->getEvaluatedSymbolType(manIdx); |
595 | |||
596 | // Evaluate rhs | ||
597 | 2512 | const PrefixUnaryExprNode *rhsNode = node->prefixUnaryExpr; | |
598 |
1/2✓ Branch 0 (7→8) taken 2512 times.
✗ Branch 1 (7→19) not taken.
|
2512 | const QualType rhsSTy = rhsNode->getEvaluatedSymbolType(manIdx); |
599 |
2/4✓ Branch 0 (8→9) taken 2512 times.
✗ Branch 1 (8→18) not taken.
✓ Branch 2 (9→10) taken 2512 times.
✗ Branch 3 (9→16) not taken.
|
2512 | auto rhs = std::any_cast<LLVMExprResult>(visit(rhsNode)); |
600 | |||
601 | // Retrieve the result value | ||
602 |
1/2✓ Branch 0 (11→12) taken 2512 times.
✗ Branch 1 (11→19) not taken.
|
2512 | const LLVMExprResult result = conversionManager.getCastInst(node, targetSTy, rhs, rhsSTy); |
603 | |||
604 | // Return the result | ||
605 |
1/2✓ Branch 0 (12→13) taken 2512 times.
✗ Branch 1 (12→19) not taken.
|
2512 | return result; |
606 | } | ||
607 | |||
608 | 70129 | std::any IRGenerator::visitPrefixUnaryExpr(const PrefixUnaryExprNode *node) { | |
609 |
1/2✓ Branch 0 (2→3) taken 70129 times.
✗ Branch 1 (2→107) not taken.
|
70129 | diGenerator.setSourceLocation(node); |
610 | |||
611 | // If no operator is applied, simply visit the atomic expression | ||
612 |
2/2✓ Branch 0 (3→4) taken 69257 times.
✓ Branch 1 (3→6) taken 872 times.
|
70129 | if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE) |
613 |
1/2✓ Branch 0 (4→5) taken 69257 times.
✗ Branch 1 (4→107) not taken.
|
69257 | return visit(node->postfixUnaryExpr); |
614 | |||
615 | // Evaluate lhs | ||
616 | 872 | const PrefixUnaryExprNode *lhsNode = node->prefixUnaryExpr; | |
617 |
1/2✓ Branch 0 (6→7) taken 872 times.
✗ Branch 1 (6→107) not taken.
|
872 | const QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
618 |
2/4✓ Branch 0 (7→8) taken 872 times.
✗ Branch 1 (7→77) not taken.
✓ Branch 2 (8→9) taken 872 times.
✗ Branch 3 (8→75) not taken.
|
872 | auto lhs = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
619 | |||
620 |
7/8✓ Branch 0 (10→11) taken 16 times.
✓ Branch 1 (10→21) taken 28 times.
✓ Branch 2 (10→37) taken 4 times.
✓ Branch 3 (10→53) taken 589 times.
✓ Branch 4 (10→56) taken 1 times.
✓ Branch 5 (10→59) taken 163 times.
✓ Branch 6 (10→61) taken 71 times.
✗ Branch 7 (10→63) not taken.
|
872 | switch (node->op) { |
621 | 16 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS: { | |
622 | // Execute operation | ||
623 |
1/2✓ Branch 0 (11→12) taken 16 times.
✗ Branch 1 (11→107) not taken.
|
16 | lhs = conversionManager.getPrefixMinusInst(node, lhs, lhsSTy); |
624 | |||
625 | // This operator can not work in-place, so we need additional memory | ||
626 |
1/2✓ Branch 0 (16→17) taken 16 times.
✗ Branch 1 (16→78) not taken.
|
16 | lhs.ptr = insertAlloca(lhs.value->getType()); |
627 | |||
628 | // Store the new value | ||
629 |
1/2✓ Branch 0 (19→20) taken 16 times.
✗ Branch 1 (19→107) not taken.
|
16 | insertStore(lhs.value, lhs.ptr); |
630 | |||
631 | 16 | break; | |
632 | } | ||
633 | 28 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_PLUS_PLUS: { | |
634 | // Make sure the value is present | ||
635 |
1/2✓ Branch 0 (21→22) taken 28 times.
✗ Branch 1 (21→107) not taken.
|
28 | resolveValue(lhsNode, lhs); |
636 | |||
637 | // Execute operation | ||
638 |
1/2✓ Branch 0 (22→23) taken 28 times.
✗ Branch 1 (22→84) not taken.
|
28 | lhs.value = conversionManager.getPrefixPlusPlusInst(node, lhs, lhsSTy).value; |
639 | |||
640 | // If this operation happens on a volatile variable, store the value directly | ||
641 |
3/4✓ Branch 0 (23→24) taken 27 times.
✓ Branch 1 (23→26) taken 1 times.
✗ Branch 2 (24→25) not taken.
✓ Branch 3 (24→26) taken 27 times.
|
28 | if (lhs.entry && lhs.entry->isVolatile) |
642 | ✗ | insertStore(lhs.value, lhs.ptr, true); | |
643 | |||
644 | // Save to the existing address if possible, otherwise (e.g. for literals) allocate new space | ||
645 |
2/2✓ Branch 0 (26→27) taken 1 times.
✓ Branch 1 (26→35) taken 27 times.
|
28 | if (!lhs.ptr) |
646 |
1/2✓ Branch 0 (31→32) taken 1 times.
✗ Branch 1 (31→85) not taken.
|
1 | lhs.ptr = insertAlloca(lhs.value->getType()); |
647 | |||
648 | // Store the new value | ||
649 |
1/2✓ Branch 0 (35→36) taken 28 times.
✗ Branch 1 (35→107) not taken.
|
28 | insertStore(lhs.value, lhs.ptr); |
650 | |||
651 | 28 | break; | |
652 | } | ||
653 | 4 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS_MINUS: { | |
654 | // Make sure the value is present | ||
655 |
1/2✓ Branch 0 (37→38) taken 4 times.
✗ Branch 1 (37→107) not taken.
|
4 | resolveValue(lhsNode, lhs); |
656 | |||
657 | // Execute operation | ||
658 |
1/2✓ Branch 0 (38→39) taken 4 times.
✗ Branch 1 (38→91) not taken.
|
4 | lhs.value = conversionManager.getPrefixMinusMinusInst(node, lhs, lhsSTy).value; |
659 | |||
660 | // If this operation happens on a volatile variable, store the value directly | ||
661 |
3/4✓ Branch 0 (39→40) taken 3 times.
✓ Branch 1 (39→42) taken 1 times.
✗ Branch 2 (40→41) not taken.
✓ Branch 3 (40→42) taken 3 times.
|
4 | if (lhs.entry && lhs.entry->isVolatile) |
662 | ✗ | insertStore(lhs.value, lhs.ptr, true); | |
663 | |||
664 | // Save to the existing address if possible, otherwise (e.g. for literals) allocate new space | ||
665 |
2/2✓ Branch 0 (42→43) taken 1 times.
✓ Branch 1 (42→51) taken 3 times.
|
4 | if (!lhs.ptr) |
666 |
1/2✓ Branch 0 (47→48) taken 1 times.
✗ Branch 1 (47→92) not taken.
|
1 | lhs.ptr = insertAlloca(lhs.value->getType()); |
667 | |||
668 | // Store the new value | ||
669 |
1/2✓ Branch 0 (51→52) taken 4 times.
✗ Branch 1 (51→107) not taken.
|
4 | insertStore(lhs.value, lhs.ptr); |
670 | |||
671 | 4 | break; | |
672 | } | ||
673 | 589 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT: { | |
674 | // Make sure the value is present | ||
675 |
1/2✓ Branch 0 (53→54) taken 589 times.
✗ Branch 1 (53→107) not taken.
|
589 | resolveValue(lhsNode, lhs); |
676 | |||
677 | // Execute operation | ||
678 |
1/2✓ Branch 0 (54→55) taken 589 times.
✗ Branch 1 (54→107) not taken.
|
589 | lhs = conversionManager.getPrefixNotInst(node, lhs, lhsSTy); |
679 | |||
680 | 589 | break; | |
681 | } | ||
682 | 1 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_BITWISE_NOT: { | |
683 | // Make sure the value is present | ||
684 |
1/2✓ Branch 0 (56→57) taken 1 times.
✗ Branch 1 (56→107) not taken.
|
1 | resolveValue(lhsNode, lhs); |
685 | |||
686 | // Execute operation | ||
687 |
1/2✓ Branch 0 (57→58) taken 1 times.
✗ Branch 1 (57→107) not taken.
|
1 | lhs = conversionManager.getPrefixBitwiseNotInst(node, lhs, lhsSTy); |
688 | |||
689 | 1 | break; | |
690 | } | ||
691 | 163 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE: { | |
692 | // Make sure the value is present | ||
693 |
1/2✓ Branch 0 (59→60) taken 163 times.
✗ Branch 1 (59→107) not taken.
|
163 | resolveValue(lhsNode, lhs); |
694 | |||
695 | // Execute operation | ||
696 | 163 | lhs.ptr = lhs.value; | |
697 | |||
698 | // Reset the value | ||
699 | 163 | lhs.value = nullptr; | |
700 | |||
701 | 163 | break; | |
702 | } | ||
703 | 71 | case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF: { | |
704 | // Make sure the address is present | ||
705 |
1/2✓ Branch 0 (61→62) taken 71 times.
✗ Branch 1 (61→107) not taken.
|
71 | resolveAddress(lhs); |
706 | |||
707 | // Execute operation | ||
708 | 71 | lhs.value = lhs.ptr; | |
709 | |||
710 | // Reset the address | ||
711 | 71 | lhs.ptr = nullptr; | |
712 | |||
713 | 71 | break; | |
714 | } | ||
715 | − | default: // GCOV_EXCL_LINE | |
716 | − | throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
717 | } | ||
718 | |||
719 |
1/2✓ Branch 0 (71→72) taken 872 times.
✗ Branch 1 (71→107) not taken.
|
872 | return lhs; |
720 | } | ||
721 | |||
722 | 86982 | std::any IRGenerator::visitPostfixUnaryExpr(const PostfixUnaryExprNode *node) { | |
723 |
1/2✓ Branch 0 (2→3) taken 86982 times.
✗ Branch 1 (2→243) not taken.
|
86982 | diGenerator.setSourceLocation(node); |
724 | |||
725 | // If no operator is applied, simply visit the atomic expression | ||
726 |
2/2✓ Branch 0 (3→4) taken 69257 times.
✓ Branch 1 (3→6) taken 17725 times.
|
86982 | if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE) |
727 |
1/2✓ Branch 0 (4→5) taken 69257 times.
✗ Branch 1 (4→243) not taken.
|
69257 | return visit(node->atomicExpr); |
728 | |||
729 | // Evaluate lhs | ||
730 | 17725 | const PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr; | |
731 |
1/2✓ Branch 0 (6→7) taken 17725 times.
✗ Branch 1 (6→243) not taken.
|
17725 | QualType lhsSTy = lhsNode->getEvaluatedSymbolType(manIdx); |
732 |
2/4✓ Branch 0 (7→8) taken 17725 times.
✗ Branch 1 (7→165) not taken.
✓ Branch 2 (8→9) taken 17725 times.
✗ Branch 3 (8→163) not taken.
|
17725 | auto lhs = std::any_cast<LLVMExprResult>(visit(lhsNode)); |
733 | |||
734 |
4/5✓ Branch 0 (10→11) taken 2738 times.
✓ Branch 1 (10→64) taken 13215 times.
✓ Branch 2 (10→103) taken 1442 times.
✓ Branch 3 (10→127) taken 330 times.
✗ Branch 4 (10→151) not taken.
|
17725 | switch (node->op) { |
735 | 2738 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: { | |
736 | 2738 | const AssignExprNode *indexExpr = node->subscriptIndexExpr; | |
737 | |||
738 | // Check if we need to generate a call to an overloaded operator function | ||
739 |
3/4✓ Branch 0 (11→12) taken 2738 times.
✗ Branch 1 (11→201) not taken.
✓ Branch 2 (12→13) taken 86 times.
✓ Branch 3 (12→29) taken 2652 times.
|
2738 | if (conversionManager.callsOverloadedOpFct(node, 0)) { |
740 |
1/2✓ Branch 0 (13→14) taken 86 times.
✗ Branch 1 (13→166) not taken.
|
86 | ResolverFct lhsV = [&] { return resolveValue(lhsSTy, lhs); }; |
741 | 172 | ResolverFct lhsP = [&] { return resolveAddress(lhs); }; | |
742 | 168 | ResolverFct idxV = [&] { return resolveValue(indexExpr); }; | |
743 | 90 | ResolverFct idxP = [&] { return resolveAddress(indexExpr); }; | |
744 | 86 | lhs = conversionManager.callOperatorOverloadFct<2>(node, {lhsV, lhsP, idxV, idxP}, 0); | |
745 | 86 | break; | |
746 | 86 | } | |
747 | |||
748 |
1/2✓ Branch 0 (29→30) taken 2652 times.
✗ Branch 1 (29→184) not taken.
|
2652 | lhsSTy = lhsSTy.removeReferenceWrapper(); |
749 | |||
750 | // Get the index value | ||
751 |
1/2✓ Branch 0 (30→31) taken 2652 times.
✗ Branch 1 (30→201) not taken.
|
2652 | llvm::Value *indexValue = resolveValue(indexExpr); |
752 | // Come up with the address | ||
753 |
8/10✓ Branch 0 (31→32) taken 2652 times.
✗ Branch 1 (31→201) not taken.
✓ Branch 2 (32→33) taken 135 times.
✓ Branch 3 (32→36) taken 2517 times.
✓ Branch 4 (33→34) taken 135 times.
✗ Branch 5 (33→201) not taken.
✓ Branch 6 (34→35) taken 95 times.
✓ Branch 7 (34→36) taken 40 times.
✓ Branch 8 (37→38) taken 95 times.
✓ Branch 9 (37→49) taken 2557 times.
|
2652 | if (lhsSTy.isArray() && lhsSTy.getArraySize() != ARRAY_SIZE_UNKNOWN) { // Array |
754 | // Make sure the address is present | ||
755 |
1/2✓ Branch 0 (38→39) taken 95 times.
✗ Branch 1 (38→192) not taken.
|
95 | resolveAddress(lhs); |
756 | |||
757 | // Calculate address of array item | ||
758 |
1/2✓ Branch 0 (39→40) taken 95 times.
✗ Branch 1 (39→192) not taken.
|
95 | llvm::Type *lhsTy = lhsSTy.toLLVMType(sourceFile); |
759 |
1/2✓ Branch 0 (40→41) taken 95 times.
✗ Branch 1 (40→192) not taken.
|
95 | llvm::Value *indices[2] = {builder.getInt64(0), indexValue}; |
760 |
1/2✓ Branch 0 (45→46) taken 95 times.
✗ Branch 1 (45→185) not taken.
|
95 | lhs.ptr = insertInBoundsGEP(lhsTy, lhs.ptr, indices); |
761 | } else { // Pointer | ||
762 | // Make sure the value is present | ||
763 |
1/2✓ Branch 0 (49→50) taken 2557 times.
✗ Branch 1 (49→201) not taken.
|
2557 | resolveValue(lhsNode, lhs); |
764 |
1/2✗ Branch 0 (50→51) not taken.
✓ Branch 1 (50→52) taken 2557 times.
|
2557 | assert(lhs.value != nullptr); |
765 | |||
766 | // Now the pointer is the value | ||
767 | 2557 | lhs.ptr = lhs.value; | |
768 | |||
769 |
2/4✓ Branch 0 (52→53) taken 2557 times.
✗ Branch 1 (52→193) not taken.
✓ Branch 2 (53→54) taken 2557 times.
✗ Branch 3 (53→193) not taken.
|
2557 | llvm::Type *lhsTy = lhsSTy.getContained().toLLVMType(sourceFile); |
770 | // Calculate address of pointer item | ||
771 |
1/2✓ Branch 0 (58→59) taken 2557 times.
✗ Branch 1 (58→194) not taken.
|
2557 | lhs.ptr = insertInBoundsGEP(lhsTy, lhs.ptr, indexValue); |
772 | } | ||
773 | |||
774 | // Reset value and entry | ||
775 | 2652 | lhs.value = nullptr; | |
776 | 2652 | lhs.entry = nullptr; | |
777 | 2652 | break; | |
778 | } | ||
779 | 13215 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: { | |
780 | // Get the address of the struct instance | ||
781 |
1/2✓ Branch 0 (64→65) taken 13215 times.
✗ Branch 1 (64→219) not taken.
|
13215 | resolveAddress(lhs); |
782 |
1/2✓ Branch 0 (65→66) taken 13215 times.
✗ Branch 1 (65→202) not taken.
|
13215 | lhsSTy = lhsSTy.removeReferenceWrapper(); |
783 | |||
784 | // Auto de-reference pointer | ||
785 |
1/2✓ Branch 0 (66→67) taken 13215 times.
✗ Branch 1 (66→219) not taken.
|
13215 | autoDeReferencePtr(lhs.ptr, lhsSTy); |
786 |
2/4✓ Branch 0 (67→68) taken 13215 times.
✗ Branch 1 (67→219) not taken.
✗ Branch 2 (68→69) not taken.
✓ Branch 3 (68→70) taken 13215 times.
|
13215 | assert(lhsSTy.is(TY_STRUCT)); |
787 | |||
788 | // Retrieve struct scope | ||
789 | 13215 | const std::string &fieldName = node->identifier; | |
790 |
1/2✓ Branch 0 (70→71) taken 13215 times.
✗ Branch 1 (70→219) not taken.
|
13215 | Scope *structScope = lhsSTy.getBodyScope(); |
791 | |||
792 | // Retrieve field entry | ||
793 | 13215 | std::vector<size_t> indexPath; | |
794 |
1/2✓ Branch 0 (71→72) taken 13215 times.
✗ Branch 1 (71→217) not taken.
|
13215 | lhs.entry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath); |
795 |
1/2✗ Branch 0 (72→73) not taken.
✓ Branch 1 (72→74) taken 13215 times.
|
13215 | assert(lhs.entry != nullptr); |
796 |
1/2✓ Branch 0 (74→75) taken 13215 times.
✗ Branch 1 (74→217) not taken.
|
13215 | const QualType fieldSymbolType = lhs.entry->getQualType(); |
797 | |||
798 | // Get address of the field in the struct instance | ||
799 |
2/4✓ Branch 0 (75→76) taken 13215 times.
✗ Branch 1 (75→206) not taken.
✓ Branch 2 (78→79) taken 13215 times.
✗ Branch 3 (78→203) not taken.
|
26430 | std::vector<llvm::Value *> indices = {builder.getInt64(0)}; |
800 |
2/2✓ Branch 0 (87→82) taken 13221 times.
✓ Branch 1 (87→88) taken 13215 times.
|
26436 | for (const size_t index : indexPath) |
801 |
2/4✓ Branch 0 (83→84) taken 13221 times.
✗ Branch 1 (83→207) not taken.
✓ Branch 2 (84→85) taken 13221 times.
✗ Branch 3 (84→207) not taken.
|
13221 | indices.push_back(builder.getInt32(index)); |
802 |
1/2✓ Branch 0 (88→89) taken 13215 times.
✗ Branch 1 (88→215) not taken.
|
13215 | const std::string name = fieldName + "_addr"; |
803 |
3/6✓ Branch 0 (89→90) taken 13215 times.
✗ Branch 1 (89→212) not taken.
✓ Branch 2 (91→92) taken 13215 times.
✗ Branch 3 (91→209) not taken.
✓ Branch 4 (92→93) taken 13215 times.
✗ Branch 5 (92→209) not taken.
|
13215 | llvm::Value *memberAddr = insertInBoundsGEP(lhsSTy.toLLVMType(sourceFile), lhs.ptr, indices, name); |
804 | |||
805 | // Set as ptr or refPtr, depending on the type | ||
806 |
3/4✓ Branch 0 (94→95) taken 13215 times.
✗ Branch 1 (94→213) not taken.
✓ Branch 2 (95→96) taken 152 times.
✓ Branch 3 (95→97) taken 13063 times.
|
13215 | if (fieldSymbolType.isRef()) { |
807 | 152 | lhs.ptr = nullptr; | |
808 | 152 | lhs.refPtr = memberAddr; | |
809 | } else { | ||
810 | 13063 | lhs.ptr = memberAddr; | |
811 | 13063 | lhs.refPtr = nullptr; | |
812 | } | ||
813 | |||
814 | // Reset the value | ||
815 | 13215 | lhs.value = nullptr; | |
816 | 13215 | break; | |
817 | 13215 | } | |
818 | 1442 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: { | |
819 | // Make sure a value is present | ||
820 |
1/2✓ Branch 0 (103→104) taken 1442 times.
✗ Branch 1 (103→226) not taken.
|
1442 | resolveValue(lhsNode, lhs); |
821 | |||
822 | // Allocate new local variable if required | ||
823 |
2/2✓ Branch 0 (104→105) taken 2 times.
✓ Branch 1 (104→115) taken 1440 times.
|
1442 | if (!lhs.ptr) { |
824 |
1/2✗ Branch 0 (105→106) not taken.
✓ Branch 1 (105→107) taken 2 times.
|
2 | assert(lhs.value != nullptr); |
825 |
1/2✓ Branch 0 (111→112) taken 2 times.
✗ Branch 1 (111→220) not taken.
|
2 | lhs.ptr = insertAlloca(lhs.value->getType()); |
826 | } | ||
827 | |||
828 | // Execute operation | ||
829 |
1/2✓ Branch 0 (115→116) taken 1442 times.
✗ Branch 1 (115→226) not taken.
|
1442 | const LLVMExprResult result = conversionManager.getPostfixPlusPlusInst(node, lhs, lhsSTy, 0); |
830 | |||
831 | // Save the new value to the old address | ||
832 |
3/4✓ Branch 0 (116→117) taken 1442 times.
✗ Branch 1 (116→226) not taken.
✓ Branch 2 (117→118) taken 9 times.
✓ Branch 3 (117→119) taken 1433 times.
|
1442 | if (conversionManager.callsOverloadedOpFct(node, 0)) { |
833 | 9 | lhs.value = result.value; | |
834 | 9 | lhs.ptr = result.ptr; | |
835 | } else { | ||
836 |
5/6✓ Branch 0 (119→120) taken 1431 times.
✓ Branch 1 (119→122) taken 2 times.
✓ Branch 2 (120→121) taken 3 times.
✓ Branch 3 (120→122) taken 1428 times.
✓ Branch 4 (123→124) taken 1433 times.
✗ Branch 5 (123→226) not taken.
|
1433 | insertStore(result.value, lhs.ptr, lhs.entry && lhs.entry->isVolatile); |
837 | 1433 | lhs.ptr = nullptr; | |
838 | } | ||
839 | 1442 | break; | |
840 | } | ||
841 | 330 | case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: { | |
842 | // Make sure a value is present | ||
843 |
1/2✓ Branch 0 (127→128) taken 330 times.
✗ Branch 1 (127→233) not taken.
|
330 | resolveValue(lhsNode, lhs); |
844 | |||
845 | // Allocate new local variable if required | ||
846 |
2/2✓ Branch 0 (128→129) taken 2 times.
✓ Branch 1 (128→139) taken 328 times.
|
330 | if (!lhs.ptr) { |
847 |
1/2✗ Branch 0 (129→130) not taken.
✓ Branch 1 (129→131) taken 2 times.
|
2 | assert(lhs.value != nullptr); |
848 |
1/2✓ Branch 0 (135→136) taken 2 times.
✗ Branch 1 (135→227) not taken.
|
2 | lhs.ptr = insertAlloca(lhs.value->getType()); |
849 | } | ||
850 | |||
851 | // Execute operation | ||
852 |
1/2✓ Branch 0 (139→140) taken 330 times.
✗ Branch 1 (139→233) not taken.
|
330 | const LLVMExprResult result = conversionManager.getPostfixMinusMinusInst(node, lhs, lhsSTy, 0); |
853 | |||
854 | // Save the new value to the old address | ||
855 |
3/4✓ Branch 0 (140→141) taken 330 times.
✗ Branch 1 (140→233) not taken.
✓ Branch 2 (141→142) taken 7 times.
✓ Branch 3 (141→143) taken 323 times.
|
330 | if (conversionManager.callsOverloadedOpFct(node, 0)) { |
856 | 7 | lhs.value = result.value; | |
857 | 7 | lhs.ptr = result.ptr; | |
858 | } else { | ||
859 |
4/6✓ Branch 0 (143→144) taken 321 times.
✓ Branch 1 (143→146) taken 2 times.
✗ Branch 2 (144→145) not taken.
✓ Branch 3 (144→146) taken 321 times.
✓ Branch 4 (147→148) taken 323 times.
✗ Branch 5 (147→233) not taken.
|
323 | insertStore(result.value, lhs.ptr, lhs.entry && lhs.entry->isVolatile); |
860 | 323 | lhs.ptr = nullptr; | |
861 | } | ||
862 | 330 | break; | |
863 | } | ||
864 | − | default: // GCOV_EXCL_LINE | |
865 | − | throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE | |
866 | } | ||
867 | |||
868 |
1/2✓ Branch 0 (159→160) taken 17725 times.
✗ Branch 1 (159→243) not taken.
|
17725 | return lhs; |
869 |
5/14✓ Branch 0 (17→18) taken 86 times.
✗ Branch 1 (17→169) not taken.
✓ Branch 2 (18→19) taken 86 times.
✗ Branch 3 (18→169) not taken.
✓ Branch 4 (19→20) taken 86 times.
✗ Branch 5 (19→169) not taken.
✓ Branch 6 (20→21) taken 86 times.
✗ Branch 7 (20→169) not taken.
✓ Branch 8 (21→22) taken 86 times.
✗ Branch 9 (21→167) not taken.
✗ Branch 10 (169→170) not taken.
✗ Branch 11 (169→173) not taken.
✗ Branch 12 (171→172) not taken.
✗ Branch 13 (171→173) not taken.
|
86 | } |
870 | |||
871 | 69257 | std::any IRGenerator::visitAtomicExpr(const AtomicExprNode *node) { | |
872 |
1/2✓ Branch 0 (2→3) taken 69257 times.
✗ Branch 1 (2→89) not taken.
|
69257 | diGenerator.setSourceLocation(node); |
873 | |||
874 | // If constant | ||
875 |
2/2✓ Branch 0 (3→4) taken 12043 times.
✓ Branch 1 (3→10) taken 57214 times.
|
69257 | if (node->constant) { |
876 |
2/4✓ Branch 0 (4→5) taken 12043 times.
✗ Branch 1 (4→81) not taken.
✓ Branch 2 (5→6) taken 12043 times.
✗ Branch 3 (5→79) not taken.
|
12043 | const auto constantValue = std::any_cast<llvm::Constant *>(visit(node->constant)); |
877 |
1/2✓ Branch 0 (7→8) taken 12043 times.
✗ Branch 1 (7→82) not taken.
|
24086 | return LLVMExprResult{.constant = constantValue}; |
878 | } | ||
879 | |||
880 | // If value | ||
881 |
2/2✓ Branch 0 (10→11) taken 13823 times.
✓ Branch 1 (10→13) taken 43391 times.
|
57214 | if (node->value) |
882 |
1/2✓ Branch 0 (11→12) taken 13823 times.
✗ Branch 1 (11→89) not taken.
|
13823 | return visit(node->value); |
883 | |||
884 | // Is assign expression | ||
885 |
2/2✓ Branch 0 (13→14) taken 501 times.
✓ Branch 1 (13→16) taken 42890 times.
|
43391 | if (node->assignExpr) |
886 |
1/2✓ Branch 0 (14→15) taken 501 times.
✗ Branch 1 (14→89) not taken.
|
501 | return visit(node->assignExpr); |
887 | |||
888 | // Check for builtin calls | ||
889 |
2/2✓ Branch 0 (16→17) taken 1355 times.
✓ Branch 1 (16→19) taken 41535 times.
|
42890 | if (node->builtinCall) |
890 |
1/2✓ Branch 0 (17→18) taken 1355 times.
✗ Branch 1 (17→89) not taken.
|
1355 | return visit(node->builtinCall); |
891 | |||
892 | // Identifier (local or global variable access) | ||
893 |
1/2✗ Branch 0 (20→21) not taken.
✓ Branch 1 (20→22) taken 41535 times.
|
41535 | assert(!node->identifierFragments.empty()); |
894 | |||
895 | // Get symbol table entry | ||
896 |
1/2✓ Branch 0 (22→23) taken 41535 times.
✗ Branch 1 (22→89) not taken.
|
41535 | const auto &[varEntry, accessScope, capture] = node->data.at(manIdx); |
897 |
1/2✗ Branch 0 (23→24) not taken.
✓ Branch 1 (23→25) taken 41535 times.
|
41535 | assert(varEntry != nullptr); |
898 |
1/2✗ Branch 0 (25→26) not taken.
✓ Branch 1 (25→27) taken 41535 times.
|
41535 | assert(accessScope != nullptr); |
899 |
1/2✓ Branch 0 (27→28) taken 41535 times.
✗ Branch 1 (27→89) not taken.
|
41535 | const QualType varSymbolType = varEntry->getQualType(); |
900 |
1/2✓ Branch 0 (28→29) taken 41535 times.
✗ Branch 1 (28→89) not taken.
|
41535 | llvm::Type *varType = varSymbolType.toLLVMType(sourceFile); |
901 | |||
902 | // Check if external global variable | ||
903 |
7/8✓ Branch 0 (29→30) taken 1277 times.
✓ Branch 1 (29→33) taken 40258 times.
✓ Branch 2 (30→31) taken 1277 times.
✗ Branch 3 (30→89) not taken.
✓ Branch 4 (31→32) taken 53 times.
✓ Branch 5 (31→33) taken 1224 times.
✓ Branch 6 (34→35) taken 53 times.
✓ Branch 7 (34→38) taken 41482 times.
|
41535 | if (varEntry->global && accessScope->isImportedBy(rootScope)) { |
904 | // External global variables need to be declared and allocated in the current module | ||
905 |
1/2✓ Branch 0 (36→37) taken 53 times.
✗ Branch 1 (36→83) not taken.
|
53 | llvm::Value *varAddress = module->getOrInsertGlobal(varEntry->name, varType); |
906 |
1/2✓ Branch 0 (37→38) taken 53 times.
✗ Branch 1 (37→89) not taken.
|
53 | varEntry->updateAddress(varAddress); |
907 | } | ||
908 | |||
909 | // Check if enum item | ||
910 |
2/2✓ Branch 0 (38→39) taken 236 times.
✓ Branch 1 (38→50) taken 41299 times.
|
41535 | if (accessScope->type == ScopeType::ENUM) { |
911 |
1/2✓ Branch 0 (39→40) taken 236 times.
✗ Branch 1 (39→41) not taken.
|
236 | const auto itemNode = spice_pointer_cast<const EnumItemNode *>(varEntry->declNode); |
912 |
1/2✓ Branch 0 (46→47) taken 236 times.
✗ Branch 1 (46→89) not taken.
|
236 | llvm::Constant *constantItemValue = llvm::ConstantInt::get(varType, itemNode->itemValue); |
913 |
1/2✓ Branch 0 (47→48) taken 236 times.
✗ Branch 1 (47→84) not taken.
|
472 | return LLVMExprResult{.constant = constantItemValue, .entry = varEntry}; |
914 | } | ||
915 | |||
916 |
1/2✓ Branch 0 (50→51) taken 41299 times.
✗ Branch 1 (50→89) not taken.
|
41299 | llvm::Value *address = varEntry->getAddress(); |
917 |
1/2✗ Branch 0 (51→52) not taken.
✓ Branch 1 (51→53) taken 41299 times.
|
41299 | assert(address != nullptr); |
918 | |||
919 | // If this is a function/procedure reference, return it as value | ||
920 |
7/8✓ Branch 0 (53→54) taken 1277 times.
✓ Branch 1 (53→57) taken 40022 times.
✓ Branch 2 (54→55) taken 1277 times.
✗ Branch 3 (54→85) not taken.
✓ Branch 4 (55→56) taken 4 times.
✓ Branch 5 (55→57) taken 1273 times.
✓ Branch 6 (58→59) taken 4 times.
✓ Branch 7 (58→63) taken 41295 times.
|
41299 | if (varEntry->global && varSymbolType.isOneOf({TY_FUNCTION, TY_PROCEDURE})) { |
921 |
1/2✓ Branch 0 (59→60) taken 4 times.
✗ Branch 1 (59→89) not taken.
|
4 | llvm::Value *fatPtr = buildFatFctPtr(nullptr, nullptr, address); |
922 |
1/2✓ Branch 0 (60→61) taken 4 times.
✗ Branch 1 (60→86) not taken.
|
8 | return LLVMExprResult{.ptr = fatPtr, .entry = varEntry}; |
923 | } | ||
924 | |||
925 | // Load the address of the referenced variable | ||
926 |
10/12✓ Branch 0 (63→64) taken 41295 times.
✗ Branch 1 (63→89) not taken.
✓ Branch 2 (64→65) taken 38447 times.
✓ Branch 3 (64→68) taken 2848 times.
✓ Branch 4 (65→66) taken 29 times.
✓ Branch 5 (65→69) taken 38418 times.
✓ Branch 6 (66→67) taken 29 times.
✗ Branch 7 (66→89) not taken.
✓ Branch 8 (67→68) taken 11 times.
✓ Branch 9 (67→69) taken 18 times.
✓ Branch 10 (70→71) taken 2859 times.
✓ Branch 11 (70→74) taken 38436 times.
|
41295 | if (varSymbolType.isRef() || (capture && capture->getMode() == BY_REFERENCE)) |
927 |
1/2✓ Branch 0 (71→72) taken 2859 times.
✗ Branch 1 (71→87) not taken.
|
5718 | return LLVMExprResult{.refPtr = address, .entry = varEntry}; |
928 | |||
929 |
1/2✓ Branch 0 (74→75) taken 38436 times.
✗ Branch 1 (74→88) not taken.
|
76872 | return LLVMExprResult{.ptr = address, .entry = varEntry}; |
930 | } | ||
931 | |||
932 | } // namespace spice::compiler | ||
933 |