GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 88.9% 16 / 2 / 20
Functions: 100.0% 3 / 0 / 3
Branches: 36.7% 11 / 12 / 42

src/objectemitter/TPDEObjectEmitter.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "TPDEObjectEmitter.h"
4
5 #include <fstream>
6 #include <memory>
7 #include <vector>
8
9 #include <exception/CompilerError.h>
10
11 #include <llvm/IR/Module.h>
12 #include <llvm/TargetParser/Triple.h>
13
14 #include <tpde-llvm/LLVMCompiler.hpp>
15
16 namespace spice::compiler {
17
18 1 TPDEObjectEmitter::TPDEObjectEmitter(llvm::Module &module) : module(module) {}
19
20 1 void TPDEObjectEmitter::emit(const std::filesystem::path &objectPath) const {
21
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 90 not taken.
1 const std::string objectPathString = objectPath.string();
22
23 // Create a TPDE compiler for the module's target triple
24
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 88 not taken.
1 const llvm::Triple triple(module.getTargetTriple());
25
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 86 not taken.
1 const std::unique_ptr<tpde_llvm::LLVMCompiler> compiler = tpde_llvm::LLVMCompiler::create(triple);
26
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 16 taken 1 time.
1 if (!compiler)
27 throw CompilerError(WRONG_OUTPUT_TYPE,
28 "The TPDE backend does not support target triple '" + triple.str() + "'"); // GCOV_EXCL_LINE
29
30 // Compile to an in-memory ELF object
31 1 std::vector<uint8_t> objBytes;
32
2/4
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 82 not taken.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 29 taken 1 time.
1 if (!compiler->compile_to_elf(module, objBytes))
33 throw CompilerError(WRONG_OUTPUT_TYPE, "TPDE failed to compile module '" + module.getName().str() + "'");
34
35 // Write to the requested path
36
1/2
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 82 not taken.
1 std::ofstream out(objectPathString, std::ios::binary);
37
2/4
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 80 not taken.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 39 taken 1 time.
1 if (!out)
38 throw CompilerError(CANT_OPEN_OUTPUT_FILE, "File '" + objectPathString + "' could not be opened"); // GCOV_EXCL_LINE
39
1/2
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 80 not taken.
1 out.write(reinterpret_cast<const char *>(objBytes.data()), static_cast<std::streamsize>(objBytes.size()));
40
1/2
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 80 not taken.
1 out.flush();
41 1 }
42
43 1 void TPDEObjectEmitter::getASMString(std::string &output) const {
44 // TPDE emits ELF bytes directly and does not expose an assembly listing.
45 output = "; Assembly listing is not available under the TPDE backend.\n"
46 1 "; Use --backend=llvm to obtain assembly output.\n";
47 1 }
48
49 } // namespace spice::compiler
50