GCC Code Coverage Report


Directory: ../
File: src/irgenerator/GenBuiltinFunctions.cpp
Date: 2025-11-06 00:20:37
Coverage Exec Excl Total
Lines: 95.0% 114 1 121
Functions: 100.0% 8 0 8
Branches: 51.5% 168 0 326

Line Branch Exec Source
1 // Copyright (c) 2021-2025 ChilliBits. All rights reserved.
2
3 #include "IRGenerator.h"
4 #include "global/TypeRegistry.h"
5
6 #include <ast/ASTNodes.h>
7 #include <global/GlobalResourceManager.h>
8 #include <llvm/IR/InlineAsm.h>
9
10 #include <llvm/IR/Module.h>
11
12 namespace spice::compiler {
13
14 1609 std::any IRGenerator::visitBuiltinCall(const BuiltinCallNode *node) {
15
2/2
✓ Branch 2 → 3 taken 732 times.
✓ Branch 2 → 4 taken 877 times.
1609 if (node->printfCall)
16 732 return visit(node->printfCall);
17
2/2
✓ Branch 4 → 5 taken 149 times.
✓ Branch 4 → 6 taken 728 times.
877 if (node->sizeofCall)
18 149 return visit(node->sizeofCall);
19
2/2
✓ Branch 6 → 7 taken 11 times.
✓ Branch 6 → 8 taken 717 times.
728 if (node->alignofCall)
20 11 return visit(node->alignofCall);
21
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 10 taken 715 times.
717 if (node->typeidCall)
22 2 return visit(node->typeidCall);
23
2/2
✓ Branch 10 → 11 taken 47 times.
✓ Branch 10 → 12 taken 668 times.
715 if (node->lenCall)
24 47 return visit(node->lenCall);
25
2/2
✓ Branch 12 → 13 taken 667 times.
✓ Branch 12 → 14 taken 1 time.
668 if (node->panicCall)
26 667 return visit(node->panicCall);
27
1/2
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 16 not taken.
1 if (node->sysCall)
28 1 return visit(node->sysCall);
29 assert_fail("Unknown builtin call"); // LCOV_EXCL_LINE
30 return nullptr; // LCOV_EXCL_LINE
31 }
32
33 732 std::any IRGenerator::visitPrintfCall(const PrintfCallNode *node) {
34 // Retrieve printf function
35
1/2
✓ Branch 2 → 3 taken 732 times.
✗ Branch 2 → 119 not taken.
732 llvm::Function *printfFct = stdFunctionManager.getPrintfFct();
36
37 // Push the template string as first argument
38 732 std::vector<llvm::Value *> printfArgs;
39
2/4
✓ Branch 5 → 6 taken 732 times.
✗ Branch 5 → 80 not taken.
✓ Branch 6 → 7 taken 732 times.
✗ Branch 6 → 78 not taken.
1464 llvm::Constant *templateString = createGlobalStringConst("printf.str.", node->templatedString, node->codeLoc);
40
1/2
✓ Branch 9 → 10 taken 732 times.
✗ Branch 9 → 84 not taken.
732 printfArgs.push_back(templateString);
41
42 // Collect replacement arguments
43
2/2
✓ Branch 62 → 12 taken 623 times.
✓ Branch 62 → 63 taken 732 times.
1355 for (const AssignExprNode *arg : node->args) {
44 // Retrieve type of argument
45
1/2
✓ Branch 13 → 14 taken 623 times.
✗ Branch 13 → 111 not taken.
623 const QualType argSymbolType = arg->getEvaluatedSymbolType(manIdx);
46
47 // Re-map some values
48 llvm::Value *argVal;
49
2/4
✓ Branch 14 → 15 taken 623 times.
✗ Branch 14 → 111 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 28 taken 623 times.
623 if (argSymbolType.isArray()) {
50 llvm::Value *argValPtr = resolveAddress(arg);
51 llvm::Value *indices[2] = {builder.getInt64(0), builder.getInt32(0)};
52 llvm::Type *argType = argSymbolType.toLLVMType(sourceFile);
53 argVal = insertInBoundsGEP(argType, argValPtr, indices);
54
4/6
✓ Branch 28 → 29 taken 623 times.
✗ Branch 28 → 93 not taken.
✓ Branch 29 → 30 taken 623 times.
✗ Branch 29 → 93 not taken.
✓ Branch 30 → 31 taken 58 times.
✓ Branch 30 → 48 taken 565 times.
623 } else if (argSymbolType.getBase().isStringObj()) {
55
1/2
✓ Branch 31 → 32 taken 58 times.
✗ Branch 31 → 111 not taken.
58 llvm::Value *argValPtr = resolveAddress(arg);
56
2/4
✓ Branch 32 → 33 taken 58 times.
✗ Branch 32 → 94 not taken.
✓ Branch 33 → 34 taken 58 times.
✗ Branch 33 → 94 not taken.
58 llvm::Type *argBaseType = argSymbolType.getBase().toLLVMType(sourceFile);
57
1/2
✓ Branch 37 → 38 taken 58 times.
✗ Branch 37 → 95 not taken.
58 argValPtr = insertStructGEP(argBaseType, argValPtr, 0);
58
3/6
✓ Branch 42 → 43 taken 58 times.
✗ Branch 42 → 103 not taken.
✓ Branch 43 → 44 taken 58 times.
✗ Branch 43 → 101 not taken.
✓ Branch 44 → 45 taken 58 times.
✗ Branch 44 → 101 not taken.
116 argVal = insertLoad(builder.getPtrTy(), argValPtr);
59 } else {
60
1/2
✓ Branch 48 → 49 taken 565 times.
✗ Branch 48 → 111 not taken.
565 argVal = resolveValue(arg);
61 }
62
63 // Extend all integer types lower than 32 bit to 32 bit
64
4/6
✓ Branch 50 → 51 taken 623 times.
✗ Branch 50 → 108 not taken.
✓ Branch 51 → 52 taken 623 times.
✗ Branch 51 → 107 not taken.
✓ Branch 52 → 53 taken 83 times.
✓ Branch 52 → 59 taken 540 times.
623 if (argSymbolType.removeReferenceWrapper().isOneOf({TY_SHORT, TY_BYTE, TY_CHAR, TY_BOOL}))
65
5/10
✓ Branch 53 → 54 taken 83 times.
✗ Branch 53 → 110 not taken.
✓ Branch 54 → 55 taken 83 times.
✗ Branch 54 → 109 not taken.
✓ Branch 55 → 56 taken 83 times.
✗ Branch 55 → 109 not taken.
✓ Branch 56 → 57 taken 83 times.
✗ Branch 56 → 109 not taken.
✓ Branch 57 → 58 taken 83 times.
✗ Branch 57 → 109 not taken.
83 argVal = builder.CreateIntCast(argVal, builder.getInt32Ty(), argSymbolType.removeReferenceWrapper().isSigned());
66
67
1/2
✓ Branch 59 → 60 taken 623 times.
✗ Branch 59 → 111 not taken.
623 printfArgs.push_back(argVal);
68 }
69
70 // Call printf function
71
3/6
✓ Branch 63 → 64 taken 732 times.
✗ Branch 63 → 115 not taken.
✓ Branch 65 → 66 taken 732 times.
✗ Branch 65 → 113 not taken.
✓ Branch 66 → 67 taken 732 times.
✗ Branch 66 → 113 not taken.
732 llvm::CallInst *callInst = builder.CreateCall(printfFct, printfArgs);
72
73 // Add noundef attribute to return value and all arguments
74
1/2
✓ Branch 67 → 68 taken 732 times.
✗ Branch 67 → 117 not taken.
732 callInst->addRetAttr(llvm::Attribute::NoUndef);
75
2/2
✓ Branch 72 → 69 taken 1355 times.
✓ Branch 72 → 73 taken 732 times.
2087 for (size_t i = 0; i < printfArgs.size(); i++)
76
1/2
✓ Branch 69 → 70 taken 1355 times.
✗ Branch 69 → 117 not taken.
1355 callInst->addParamAttr(i, llvm::Attribute::NoUndef);
77
78
1/2
✓ Branch 73 → 74 taken 732 times.
✗ Branch 73 → 116 not taken.
1464 return LLVMExprResult{.value = callInst};
79 732 }
80
81 149 std::any IRGenerator::visitSizeofCall(const SizeofCallNode *node) {
82 llvm::Type *type;
83
2/2
✓ Branch 2 → 3 taken 126 times.
✓ Branch 2 → 7 taken 23 times.
149 if (node->isType) { // Size of type
84
2/4
✓ Branch 3 → 4 taken 126 times.
✗ Branch 3 → 20 not taken.
✓ Branch 4 → 5 taken 126 times.
✗ Branch 4 → 18 not taken.
126 type = any_cast<llvm::Type *>(visit(node->dataType));
85 } else { // Size of value
86
2/4
✓ Branch 7 → 8 taken 23 times.
✗ Branch 7 → 22 not taken.
✓ Branch 8 → 9 taken 23 times.
✗ Branch 8 → 22 not taken.
23 type = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
87 }
88 // Calculate size at compile-time
89
1/2
✓ Branch 11 → 12 taken 149 times.
✗ Branch 11 → 22 not taken.
149 const llvm::TypeSize sizeInBytes = module->getDataLayout().getTypeAllocSize(type);
90
91 // Return size value
92
2/4
✓ Branch 12 → 13 taken 149 times.
✗ Branch 12 → 22 not taken.
✓ Branch 13 → 14 taken 149 times.
✗ Branch 13 → 22 not taken.
149 llvm::Value *sizeValue = builder.getInt64(sizeInBytes);
93
1/2
✓ Branch 14 → 15 taken 149 times.
✗ Branch 14 → 21 not taken.
298 return LLVMExprResult{.value = sizeValue};
94 }
95
96 11 std::any IRGenerator::visitAlignofCall(const AlignofCallNode *node) {
97 llvm::Type *type;
98
2/2
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 7 taken 10 times.
11 if (node->isType) { // Align of type
99
2/4
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 20 not taken.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 18 not taken.
1 type = any_cast<llvm::Type *>(visit(node->dataType));
100 } else { // Align of value
101
2/4
✓ Branch 7 → 8 taken 10 times.
✗ Branch 7 → 22 not taken.
✓ Branch 8 → 9 taken 10 times.
✗ Branch 8 → 22 not taken.
10 type = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
102 }
103 // Calculate size at compile-time
104
1/2
✓ Branch 11 → 12 taken 11 times.
✗ Branch 11 → 22 not taken.
11 const llvm::Align alignmentInBytes = module->getDataLayout().getABITypeAlign(type);
105
106 // Return align value
107
1/2
✓ Branch 13 → 14 taken 11 times.
✗ Branch 13 → 22 not taken.
11 llvm::Value *alignValue = builder.getInt64(alignmentInBytes.value());
108
1/2
✓ Branch 14 → 15 taken 11 times.
✗ Branch 14 → 21 not taken.
22 return LLVMExprResult{.value = alignValue};
109 }
110
111 2 std::any IRGenerator::visitTypeidCall(const TypeidCallNode *node) {
112 // Return type id value
113
1/2
✓ Branch 2 → 3 taken 2 times.
✗ Branch 2 → 11 not taken.
2 const QualType qualType = node->assignExpr->getEvaluatedSymbolType(manIdx);
114
1/2
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 11 not taken.
2 const uint64_t typeId = TypeRegistry::getTypeHash(*qualType.getType());
115
1/2
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 11 not taken.
2 llvm::Value *typeIdValue = builder.getInt64(typeId);
116
1/2
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 10 not taken.
4 return LLVMExprResult{.value = typeIdValue};
117 }
118
119 47 std::any IRGenerator::visitLenCall(const LenCallNode *node) {
120 // Check if the length is fixed and known via the symbol type
121
1/2
✓ Branch 2 → 3 taken 47 times.
✗ Branch 2 → 32 not taken.
47 QualType symbolType = node->assignExpr->getEvaluatedSymbolType(manIdx);
122
1/2
✓ Branch 3 → 4 taken 47 times.
✗ Branch 3 → 26 not taken.
47 symbolType = symbolType.removeReferenceWrapper();
123
124 llvm::Value *lengthValue;
125
3/4
✓ Branch 4 → 5 taken 47 times.
✗ Branch 4 → 32 not taken.
✓ Branch 5 → 6 taken 23 times.
✓ Branch 5 → 13 taken 24 times.
47 if (symbolType.is(TY_STRING)) {
126
1/2
✓ Branch 6 → 7 taken 23 times.
✗ Branch 6 → 32 not taken.
23 llvm::Function *getRawLengthFct = stdFunctionManager.getStringGetRawLengthStringFct();
127
4/8
✓ Branch 7 → 8 taken 23 times.
✗ Branch 7 → 30 not taken.
✓ Branch 8 → 9 taken 23 times.
✗ Branch 8 → 28 not taken.
✓ Branch 10 → 11 taken 23 times.
✗ Branch 10 → 27 not taken.
✓ Branch 11 → 12 taken 23 times.
✗ Branch 11 → 27 not taken.
23 lengthValue = builder.CreateCall(getRawLengthFct, resolveValue(node->assignExpr));
128 } else {
129
4/8
✓ Branch 13 → 14 taken 24 times.
✗ Branch 13 → 32 not taken.
✓ Branch 14 → 15 taken 24 times.
✗ Branch 14 → 18 not taken.
✓ Branch 15 → 16 taken 24 times.
✗ Branch 15 → 32 not taken.
✓ Branch 16 → 17 taken 24 times.
✗ Branch 16 → 18 not taken.
24 assert(symbolType.isArray() && symbolType.getArraySize() != ARRAY_SIZE_UNKNOWN);
130 // Return length value
131
2/4
✓ Branch 19 → 20 taken 24 times.
✗ Branch 19 → 32 not taken.
✓ Branch 20 → 21 taken 24 times.
✗ Branch 20 → 32 not taken.
24 lengthValue = builder.getInt64(symbolType.getArraySize());
132 }
133
1/2
✓ Branch 22 → 23 taken 47 times.
✗ Branch 22 → 31 not taken.
94 return LLVMExprResult{.value = lengthValue};
134 }
135
136 667 std::any IRGenerator::visitPanicCall(const PanicCallNode *node) {
137
1/2
✓ Branch 2 → 3 taken 667 times.
✗ Branch 2 → 147 not taken.
667 llvm::PointerType *ptrTy = builder.getPtrTy();
138
139 // Get value for stderr
140 llvm::Value *stdErr;
141
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 12 taken 667 times.
667 if (cliOptions.targetTriple.isOSWindows()) {
142 llvm::Function *getAcrtIOFuncFct = stdFunctionManager.getAcrtIOFuncFct();
143 stdErr = builder.CreateCall(getAcrtIOFuncFct, {builder.getInt32(/*constant for stderr*/ 2)});
144 } else {
145 667 constexpr auto globalName = "stderr";
146
2/4
✓ Branch 12 → 13 taken 667 times.
✗ Branch 12 → 89 not taken.
✓ Branch 13 → 14 taken 667 times.
✗ Branch 13 → 89 not taken.
667 module->getOrInsertGlobal(globalName, ptrTy);
147
2/4
✓ Branch 14 → 15 taken 667 times.
✗ Branch 14 → 90 not taken.
✓ Branch 15 → 16 taken 667 times.
✗ Branch 15 → 90 not taken.
667 llvm::GlobalVariable *stdErrPtr = module->getNamedGlobal(globalName);
148
1/2
✓ Branch 16 → 17 taken 667 times.
✗ Branch 16 → 147 not taken.
667 stdErrPtr->setLinkage(llvm::GlobalVariable::ExternalLinkage);
149 667 stdErrPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
150
2/4
✓ Branch 18 → 19 taken 667 times.
✗ Branch 18 → 91 not taken.
✓ Branch 19 → 20 taken 667 times.
✗ Branch 19 → 91 not taken.
667 stdErrPtr->setAlignment(llvm::MaybeAlign(8));
151
2/4
✓ Branch 22 → 23 taken 667 times.
✗ Branch 22 → 94 not taken.
✓ Branch 23 → 24 taken 667 times.
✗ Branch 23 → 92 not taken.
1334 stdErr = insertLoad(ptrTy, stdErrPtr);
152 }
153
154 // Create constant for error message
155
1/2
✓ Branch 27 → 28 taken 667 times.
✗ Branch 27 → 147 not taken.
667 const std::string codeLoc = node->codeLoc.toPrettyString();
156
5/10
✓ Branch 28 → 29 taken 667 times.
✗ Branch 28 → 108 not taken.
✓ Branch 29 → 30 taken 667 times.
✗ Branch 29 → 104 not taken.
✓ Branch 30 → 31 taken 667 times.
✗ Branch 30 → 102 not taken.
✓ Branch 31 → 32 taken 667 times.
✗ Branch 31 → 100 not taken.
✓ Branch 32 → 33 taken 667 times.
✗ Branch 32 → 98 not taken.
667 const std::string templateStr = "Program panicked at " + codeLoc + ": %s\n" + node->getErrorMessage() + "\n";
157
4/8
✓ Branch 39 → 40 taken 667 times.
✗ Branch 39 → 115 not taken.
✓ Branch 40 → 41 taken 667 times.
✗ Branch 40 → 113 not taken.
✓ Branch 41 → 42 taken 667 times.
✗ Branch 41 → 111 not taken.
✓ Branch 43 → 44 taken 667 times.
✗ Branch 43 → 110 not taken.
1334 llvm::GlobalVariable *globalString = builder.CreateGlobalString(templateStr, getUnusedGlobalName(ANON_GLOBAL_STRING_NAME));
158
159 // If the output should be comparable, fix alignment to 4 bytes
160
1/2
✓ Branch 47 → 48 taken 667 times.
✗ Branch 47 → 51 not taken.
667 if (cliOptions.comparableOutput)
161
2/4
✓ Branch 48 → 49 taken 667 times.
✗ Branch 48 → 121 not taken.
✓ Branch 49 → 50 taken 667 times.
✗ Branch 49 → 121 not taken.
667 globalString->setAlignment(llvm::Align(4));
162
163 // Get actual error message
164
1/2
✓ Branch 51 → 52 taken 667 times.
✗ Branch 51 → 143 not taken.
667 llvm::Value *errorObjPtr = resolveAddress(node->assignExpr);
165
2/4
✓ Branch 52 → 53 taken 667 times.
✗ Branch 52 → 143 not taken.
✓ Branch 53 → 54 taken 667 times.
✗ Branch 53 → 143 not taken.
667 llvm::Type *errorObjTy = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
166
1/2
✓ Branch 57 → 58 taken 667 times.
✗ Branch 57 → 122 not taken.
667 llvm::Value *errorMessagePtr = insertStructGEP(errorObjTy, errorObjPtr, 1);
167
2/4
✓ Branch 62 → 63 taken 667 times.
✗ Branch 62 → 130 not taken.
✓ Branch 63 → 64 taken 667 times.
✗ Branch 63 → 128 not taken.
667 llvm::Value *errorMessage = insertLoad(ptrTy, errorMessagePtr);
168
169 // Print the error message to stderr
170
1/2
✓ Branch 66 → 67 taken 667 times.
✗ Branch 66 → 143 not taken.
667 llvm::Function *fprintfFct = stdFunctionManager.getFPrintfFct();
171
3/6
✓ Branch 67 → 68 taken 667 times.
✗ Branch 67 → 137 not taken.
✓ Branch 69 → 70 taken 667 times.
✗ Branch 69 → 134 not taken.
✓ Branch 70 → 71 taken 667 times.
✗ Branch 70 → 134 not taken.
667 builder.CreateCall(fprintfFct, {stdErr, globalString, errorMessage});
172
173 // Generate call to exit()
174
1/2
✓ Branch 71 → 72 taken 667 times.
✗ Branch 71 → 143 not taken.
667 llvm::Function *exitFct = stdFunctionManager.getExitFct();
175
4/8
✓ Branch 72 → 73 taken 667 times.
✗ Branch 72 → 141 not taken.
✓ Branch 73 → 74 taken 667 times.
✗ Branch 73 → 139 not taken.
✓ Branch 75 → 76 taken 667 times.
✗ Branch 75 → 138 not taken.
✓ Branch 76 → 77 taken 667 times.
✗ Branch 76 → 138 not taken.
667 builder.CreateCall(exitFct, builder.getInt32(EXIT_FAILURE));
176 // Create unreachable instruction
177
1/2
✓ Branch 77 → 78 taken 667 times.
✗ Branch 77 → 143 not taken.
667 builder.CreateUnreachable();
178 // Unreachable counts as terminator
179
2/4
✓ Branch 78 → 79 taken 667 times.
✗ Branch 78 → 143 not taken.
✓ Branch 79 → 80 taken 667 times.
✗ Branch 79 → 143 not taken.
667 terminateBlock(node->getNextOuterStmtLst());
180
181
1/2
✓ Branch 80 → 81 taken 667 times.
✗ Branch 80 → 142 not taken.
1334 return nullptr;
182 667 }
183
184 1 std::any IRGenerator::visitSysCall(const SysCallNode *node) {
185 // Determine the required number of operands.
186 // (We assume at least one argument is provided: the syscall number.)
187 1 const auto requiredRegs = static_cast<uint8_t>(node->args.size());
188
2/4
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 6 not taken.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
1 assert(requiredRegs >= 1 && requiredRegs <= 6);
189
190 // Create the asm and constraint strings based on the required number of registers.
191
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 79 not taken.
1 const std::string asmString = getSysCallAsmString(requiredRegs);
192
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 77 not taken.
1 const std::string constraints = getSysCallConstraintString(requiredRegs);
193
194 // Create the LLVM function type for the inline asm with only the needed operands.
195
1/2
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 75 not taken.
1 llvm::Type *int64Ty = builder.getInt64Ty();
196
1/2
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 55 not taken.
1 const std::vector argTypes(requiredRegs, int64Ty);
197
2/4
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 58 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 58 not taken.
1 llvm::FunctionType *fctType = llvm::FunctionType::get(builder.getVoidTy(), argTypes, false);
198
1/2
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 59 not taken.
1 llvm::InlineAsm *inlineAsm = llvm::InlineAsm::get(fctType, asmString, constraints, true);
199
200 // Build the argument list (each provided argument is converted to i64).
201 1 std::vector<llvm::Value *> argValues;
202
1/2
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 71 not taken.
1 argValues.reserve(requiredRegs);
203
2/2
✓ Branch 42 → 22 taken 4 times.
✓ Branch 42 → 43 taken 1 time.
5 for (uint8_t i = 0; i < requiredRegs; i++) {
204
1/2
✓ Branch 22 → 23 taken 4 times.
✗ Branch 22 → 71 not taken.
4 const AssignExprNode *argNode = node->args.at(i);
205
1/2
✓ Branch 23 → 24 taken 4 times.
✗ Branch 23 → 71 not taken.
4 const QualType &argType = argNode->getEvaluatedSymbolType(manIdx);
206
2/4
✓ Branch 24 → 25 taken 4 times.
✗ Branch 24 → 61 not taken.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 4 times.
4 assert(argType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BOOL, TY_BYTE, TY_PTR, TY_STRING}));
207
3/4
✓ Branch 27 → 28 taken 4 times.
✗ Branch 27 → 62 not taken.
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 35 taken 3 times.
4 if (argType.isOneOf({TY_PTR, TY_STRING}))
208
5/10
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 63 not taken.
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 63 not taken.
✓ Branch 31 → 32 taken 1 time.
✗ Branch 31 → 63 not taken.
✓ Branch 32 → 33 taken 1 time.
✗ Branch 32 → 63 not taken.
✓ Branch 33 → 34 taken 1 time.
✗ Branch 33 → 63 not taken.
1 argValues.push_back(builder.CreatePtrToInt(resolveValue(argNode), builder.getInt64Ty()));
209 else
210
5/10
✓ Branch 35 → 36 taken 3 times.
✗ Branch 35 → 65 not taken.
✓ Branch 36 → 37 taken 3 times.
✗ Branch 36 → 65 not taken.
✓ Branch 37 → 38 taken 3 times.
✗ Branch 37 → 65 not taken.
✓ Branch 38 → 39 taken 3 times.
✗ Branch 38 → 65 not taken.
✓ Branch 39 → 40 taken 3 times.
✗ Branch 39 → 65 not taken.
3 argValues.push_back(builder.CreateZExt(resolveValue(argNode), builder.getInt64Ty()));
211 }
212
213 // Generate the call using only the required number of arguments.
214
3/6
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 69 not taken.
✓ Branch 45 → 46 taken 1 time.
✗ Branch 45 → 67 not taken.
✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 67 not taken.
1 llvm::Value *result = builder.CreateCall(inlineAsm, argValues);
215
216
1/2
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 70 not taken.
2 return LLVMExprResult{.value = result};
217 1 }
218
219 } // namespace spice::compiler
220