bloat-buster/src/emitter.cpp
2025-05-06 10:32:42 -06:00

80 lines
2.9 KiB
C++

#include <compiler.h>
#include <llvm.h>
fn void llvm_initialize(Module* module)
{
llvm_initialize_all();
auto context = LLVMContextCreate();
auto m = llvm_context_create_module(context, module->name);
auto builder = LLVMCreateBuilderInContext(context);
llvm::DIBuilder* di_builder = 0;
llvm::DICompileUnit* di_compile_unit = 0;
llvm::DIFile* di_file = 0;
if (module->has_debug_info)
{
di_builder = LLVMCreateDIBuilder(m);
auto last_slash = string_last_character(module->path, '/');
if (last_slash == string_no_match)
{
report_error();
}
auto directory = module->path(0, last_slash);
auto file_name = module->path(last_slash + 1);
auto file = LLVMDIBuilderCreateFile(di_builder, file_name.pointer, file_name.length, directory.pointer, directory.length);
auto producer_name = string_literal("bloat buster");
auto is_optimized = build_mode_is_optimized(module->build_mode);
auto flags = string_literal("");
u32 runtime_version = 0;
auto split_name = string_literal("");
auto sysroot = string_literal("");
auto sdk = string_literal("");
di_compile_unit = LLVMDIBuilderCreateCompileUnit(di_builder, DwarfSourceLanguage::C17, file, producer_name.pointer, producer_name.length, is_optimized, flags.pointer, flags.length, runtime_version, split_name.pointer, split_name.length, DwarfEmissionKind::full, 0, 0, is_optimized, sysroot.pointer, sysroot.length, sdk.pointer, sdk.length);
module->scope.llvm = (llvm::DIScope*)di_compile_unit;
}
module->llvm = {
.context = context,
.module = m,
.builder = builder,
.di_builder = di_builder,
.file = di_file,
.compile_unit = di_compile_unit,
.pointer_type = LLVMPointerTypeInContext(context),
.void_type = LLVMVoidTypeInContext(context),
.intrinsic_table = {
.trap = LLVMLookupIntrinsicID(split_string_literal("llvm.trap")),
.va_start = LLVMLookupIntrinsicID(split_string_literal("llvm.va_start")),
.va_end = LLVMLookupIntrinsicID(split_string_literal("llvm.va_end")),
.va_copy = LLVMLookupIntrinsicID(split_string_literal("llvm.va_copy")),
},
};
}
void emit(Module* module)
{
llvm_initialize(module);
for (auto* global = module->first_global; global; global = global->next)
{
switch (global->variable.storage->id)
{
case ValueId::function:
case ValueId::external_function:
{
auto function_type = &global->variable.storage->type->pointer.element_type->function;
trap_raw();
} break;
case ValueId::global:
{
trap_raw();
} break;
default: report_error();
}
trap_raw();
}
trap_raw();
}