#include #include 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(); }