1439 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
			
		
		
	
	
			1439 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
const lib = @import("lib.zig");
 | 
						|
const Arena = lib.Arena;
 | 
						|
const assert = lib.assert;
 | 
						|
const os = lib.os;
 | 
						|
const builtin = @import("builtin");
 | 
						|
const api = @import("llvm_api.zig");
 | 
						|
 | 
						|
/// This is a String which ABI-compatible with C++
 | 
						|
pub const String = extern struct {
 | 
						|
    pointer: ?[*]const u8 = null,
 | 
						|
    length: usize = 0,
 | 
						|
 | 
						|
    pub fn from_slice(slice: []const u8) String {
 | 
						|
        return String{
 | 
						|
            .pointer = slice.ptr,
 | 
						|
            .length = slice.len,
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_slice(string: String) ?[]const u8 {
 | 
						|
        if (string.length != 0) {
 | 
						|
            return string.pointer.?[0..string.length];
 | 
						|
        } else {
 | 
						|
            return null;
 | 
						|
        }
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const CodeModel = enum(u8) {
 | 
						|
    none = 0,
 | 
						|
    tiny = 1,
 | 
						|
    small = 2,
 | 
						|
    kernel = 3,
 | 
						|
    medium = 4,
 | 
						|
    large = 5,
 | 
						|
};
 | 
						|
 | 
						|
pub const RelocationModel = enum(u8) {
 | 
						|
    default = 0,
 | 
						|
    static = 1,
 | 
						|
    pic = 2,
 | 
						|
    dynamic_no_pic = 3,
 | 
						|
    ropi = 4,
 | 
						|
    rwpi = 5,
 | 
						|
    ropi_rwpi = 6,
 | 
						|
};
 | 
						|
 | 
						|
pub const CodeGenerationOptimizationLevel = enum(u8) {
 | 
						|
    none = 0, // -O0
 | 
						|
    less = 1, // -O1
 | 
						|
    default = 2, // -O2, -Os
 | 
						|
    aggressive = 3, // -O3
 | 
						|
};
 | 
						|
 | 
						|
pub const Target = opaque {
 | 
						|
    /// This is ABI-compatible with C++
 | 
						|
    pub const Options = extern struct {
 | 
						|
        flags0: packed struct(u64) {
 | 
						|
            unsafe_fp_math: u1,
 | 
						|
            no_infs_fp_math: u1,
 | 
						|
            no_nans_fp_math: u1,
 | 
						|
            no_trapping_fp_math: u1,
 | 
						|
            no_signed_zeroes_fp_math: u1,
 | 
						|
            approx_func_fp_match: u1,
 | 
						|
            enable_aix_extended_altivec_abi: u1,
 | 
						|
            honor_sign_dependent_rounding_fp_math: u1,
 | 
						|
            no_zeroes_in_bss: u1,
 | 
						|
            guaranteed_tail_call_optimization: u1,
 | 
						|
            stack_symbol_ordering: u1,
 | 
						|
            enable_fast_isel: u1,
 | 
						|
            enable_global_isel: u1,
 | 
						|
            global_isel_abort_mode: enum(u2) {
 | 
						|
                disable = 0,
 | 
						|
                enable = 1,
 | 
						|
                disable_with_diag = 2,
 | 
						|
            },
 | 
						|
            swift_async_frame_pointer: enum(u2) {
 | 
						|
                deployment_based = 0,
 | 
						|
                always = 1,
 | 
						|
                never = 2,
 | 
						|
            },
 | 
						|
            use_init_array: u1,
 | 
						|
            disable_integrated_assembler: u1,
 | 
						|
            function_sections: u1,
 | 
						|
            data_sections: u1,
 | 
						|
            ignore_xcoff_visibility: u1,
 | 
						|
            xcoff_traceback_table: u1,
 | 
						|
            unique_section_names: u1,
 | 
						|
            unique_basic_block_section_names: u1,
 | 
						|
            separate_named_sections: u1,
 | 
						|
            trap_unreachable: u1,
 | 
						|
            no_trap_after_noreturn: u1,
 | 
						|
            tls_size: u8,
 | 
						|
            emulated_tls: u1,
 | 
						|
            enable_tls_descriptors: u1,
 | 
						|
            enable_ipra: u1,
 | 
						|
            emit_stack_size_section: u1,
 | 
						|
            enable_machine_outliner: u1,
 | 
						|
            enable_machine_function_splitter: u1,
 | 
						|
            supports_default_outlining: u1,
 | 
						|
            emit_address_significance_table: u1,
 | 
						|
            bb_address_map: u1,
 | 
						|
            bb_sections: enum(u3) {
 | 
						|
                all = 0,
 | 
						|
                list = 1,
 | 
						|
                labels = 2,
 | 
						|
                preset = 3,
 | 
						|
                none = 4,
 | 
						|
            },
 | 
						|
            emit_call_site_information: u1,
 | 
						|
            supports_debug_entry_values: u1,
 | 
						|
            enable_debug_entry_values: u1,
 | 
						|
            value_tracking_variable_locations: u1,
 | 
						|
            force_dwarf_frame_section: u1,
 | 
						|
            xray_function_index: u1,
 | 
						|
            debug_strict_dwarf: u1,
 | 
						|
            hotpatch: u1,
 | 
						|
            ppc_gen_scalar_mass_entries: u1,
 | 
						|
            jmc_instrument: u1,
 | 
						|
            enable_cfi_fixup: u1,
 | 
						|
            mis_expect: u1,
 | 
						|
            xcoff_read_only_pointers: u1,
 | 
						|
            float_abi: enum(u2) {
 | 
						|
                default = 0,
 | 
						|
                soft = 1,
 | 
						|
                hard = 2,
 | 
						|
            },
 | 
						|
            thread_model: enum(u1) {
 | 
						|
                posix = 0,
 | 
						|
                single = 1,
 | 
						|
            },
 | 
						|
        },
 | 
						|
        flags1: packed struct(u32) {
 | 
						|
            fp_op_fusion_mode: enum(u2) {
 | 
						|
                fast = 0,
 | 
						|
                standard = 1,
 | 
						|
                strict = 2,
 | 
						|
            },
 | 
						|
            eabi_version: enum(u3) {
 | 
						|
                unknown = 0,
 | 
						|
                default = 1,
 | 
						|
                eabi4 = 2,
 | 
						|
                eabi5 = 3,
 | 
						|
                gnu = 4,
 | 
						|
            },
 | 
						|
            debugger_kind: enum(u3) {
 | 
						|
                default = 0,
 | 
						|
                gdb = 1,
 | 
						|
                lldb = 2,
 | 
						|
                sce = 3,
 | 
						|
                dbx = 4,
 | 
						|
            },
 | 
						|
            exception_handling: enum(u3) {
 | 
						|
                none = 0,
 | 
						|
                dwarf_cfi = 1,
 | 
						|
                setjmp_longjmp = 2,
 | 
						|
                arm = 3,
 | 
						|
                win_eh = 4,
 | 
						|
                wasm = 5,
 | 
						|
                aix = 6,
 | 
						|
                zos = 7,
 | 
						|
            },
 | 
						|
            reserved: PaddingType = 0,
 | 
						|
        },
 | 
						|
        loop_alignment: c_uint,
 | 
						|
        binutils_version: [2]c_int,
 | 
						|
        mc: MCTargetOptions,
 | 
						|
 | 
						|
        const padding_bit_count = 21;
 | 
						|
        const PaddingType = @Type(.{
 | 
						|
            .int = .{
 | 
						|
                .signedness = .unsigned,
 | 
						|
                .bits = padding_bit_count,
 | 
						|
            },
 | 
						|
        });
 | 
						|
        comptime {
 | 
						|
            assert(@sizeOf(Target.Options) == 136);
 | 
						|
            assert(padding_bit_count == 21);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn default() Target.Options {
 | 
						|
            return .{
 | 
						|
                .binutils_version = .{ 0, 0 },
 | 
						|
                .flags0 = .{
 | 
						|
                    .unsafe_fp_math = 0,
 | 
						|
                    .no_infs_fp_math = 0,
 | 
						|
                    .no_nans_fp_math = 0,
 | 
						|
                    .no_trapping_fp_math = 1,
 | 
						|
                    .no_signed_zeroes_fp_math = 0,
 | 
						|
                    .approx_func_fp_match = 0,
 | 
						|
                    .enable_aix_extended_altivec_abi = 0,
 | 
						|
                    .honor_sign_dependent_rounding_fp_math = 0,
 | 
						|
                    .no_zeroes_in_bss = 0,
 | 
						|
                    .guaranteed_tail_call_optimization = 0,
 | 
						|
                    .stack_symbol_ordering = 1,
 | 
						|
                    .enable_fast_isel = 0,
 | 
						|
                    .enable_global_isel = 0,
 | 
						|
                    .global_isel_abort_mode = .enable,
 | 
						|
                    .swift_async_frame_pointer = .always,
 | 
						|
                    .use_init_array = 0,
 | 
						|
                    .disable_integrated_assembler = 0,
 | 
						|
                    .function_sections = 0,
 | 
						|
                    .data_sections = 0,
 | 
						|
                    .ignore_xcoff_visibility = 0,
 | 
						|
                    .xcoff_traceback_table = 1,
 | 
						|
                    .unique_section_names = 1,
 | 
						|
                    .unique_basic_block_section_names = 0,
 | 
						|
                    .separate_named_sections = 0,
 | 
						|
                    .trap_unreachable = 0,
 | 
						|
                    .no_trap_after_noreturn = 0,
 | 
						|
                    .tls_size = 0,
 | 
						|
                    .emulated_tls = 0,
 | 
						|
                    .enable_tls_descriptors = 0,
 | 
						|
                    .enable_ipra = 0,
 | 
						|
                    .emit_stack_size_section = 0,
 | 
						|
                    .enable_machine_outliner = 0,
 | 
						|
                    .enable_machine_function_splitter = 0,
 | 
						|
                    .supports_default_outlining = 0,
 | 
						|
                    .emit_address_significance_table = 0,
 | 
						|
                    .bb_address_map = 0,
 | 
						|
                    .bb_sections = .none,
 | 
						|
                    .emit_call_site_information = 0,
 | 
						|
                    .supports_debug_entry_values = 0,
 | 
						|
                    .enable_debug_entry_values = 0,
 | 
						|
                    .value_tracking_variable_locations = 0,
 | 
						|
                    .force_dwarf_frame_section = 0,
 | 
						|
                    .xray_function_index = 1,
 | 
						|
                    .debug_strict_dwarf = 0,
 | 
						|
                    .hotpatch = 0,
 | 
						|
                    .ppc_gen_scalar_mass_entries = 0,
 | 
						|
                    .jmc_instrument = 0,
 | 
						|
                    .enable_cfi_fixup = 0,
 | 
						|
                    .mis_expect = 0,
 | 
						|
                    .xcoff_read_only_pointers = 0,
 | 
						|
                    .float_abi = .default,
 | 
						|
                    .thread_model = .posix,
 | 
						|
                },
 | 
						|
                .flags1 = .{
 | 
						|
                    .fp_op_fusion_mode = .standard,
 | 
						|
                    .eabi_version = .default,
 | 
						|
                    .debugger_kind = .default,
 | 
						|
                    .exception_handling = .none,
 | 
						|
                },
 | 
						|
                .loop_alignment = 0,
 | 
						|
                .mc = .{
 | 
						|
                    .abi_name = .{},
 | 
						|
                    .assembly_language = .{},
 | 
						|
                    .split_dwarf_file = .{},
 | 
						|
                    .as_secure_log_file = .{},
 | 
						|
                    .argv0 = null,
 | 
						|
                    .argv_pointer = null,
 | 
						|
                    .argv_count = 0,
 | 
						|
                    .integrated_assembler_search_path_pointer = null,
 | 
						|
                    .integrated_assembler_search_path_count = 0,
 | 
						|
                    .flags = .{
 | 
						|
                        .relax_all = 0,
 | 
						|
                        .no_exec_stack = 0,
 | 
						|
                        .fatal_warnings = 0,
 | 
						|
                        .no_warn = 0,
 | 
						|
                        .no_deprecated_warn = 0,
 | 
						|
                        .no_type_check = 0,
 | 
						|
                        .save_temp_labels = 0,
 | 
						|
                        .incremental_linker_compatible = 0,
 | 
						|
                        .fdpic = 0,
 | 
						|
                        .show_mc_encoding = 0,
 | 
						|
                        .show_mc_inst = 0,
 | 
						|
                        .asm_verbose = 0,
 | 
						|
                        .preserve_asm_comments = 1,
 | 
						|
                        .dwarf64 = 0,
 | 
						|
                        .crel = 0,
 | 
						|
                        .x86_relax_relocations = 1,
 | 
						|
                        .x86_sse2_avx = 0,
 | 
						|
                        .emit_dwarf_unwind = .default,
 | 
						|
                        .use_dwarf_directory = .default,
 | 
						|
                        .debug_compression_type = .none,
 | 
						|
                        .emit_compact_unwind_non_canonical = 0,
 | 
						|
                        .ppc_use_full_register_names = 0,
 | 
						|
                    },
 | 
						|
                },
 | 
						|
            };
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    pub const Machine = opaque {
 | 
						|
        /// This is ABI-compatible with C++
 | 
						|
        pub const Create = extern struct {
 | 
						|
            target_options: Target.Options,
 | 
						|
            cpu_triple: String,
 | 
						|
            cpu_model: String,
 | 
						|
            cpu_features: String,
 | 
						|
            code_model: CodeModel,
 | 
						|
            relocation_model: RelocationModel,
 | 
						|
            optimization_level: CodeGenerationOptimizationLevel,
 | 
						|
            jit: bool,
 | 
						|
            reserved: [padding_byte_count]u8 = [1]u8{0} ** padding_byte_count,
 | 
						|
 | 
						|
            const padding_byte_count = 4;
 | 
						|
            comptime {
 | 
						|
                assert(@sizeOf(Create) == 192);
 | 
						|
                assert(padding_byte_count == 4);
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        pub fn create(options: Create, error_message: *String) ?*Target.Machine {
 | 
						|
            const target_machine = api.llvm_create_target_machine(&options, error_message);
 | 
						|
            return target_machine;
 | 
						|
        }
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
pub const MCTargetOptions = extern struct {
 | 
						|
    abi_name: String,
 | 
						|
    assembly_language: String,
 | 
						|
    split_dwarf_file: String,
 | 
						|
    as_secure_log_file: String,
 | 
						|
    argv0: ?[*:0]const u8,
 | 
						|
    argv_pointer: ?[*]const String,
 | 
						|
    argv_count: u64,
 | 
						|
    integrated_assembler_search_path_pointer: ?[*]const String,
 | 
						|
    integrated_assembler_search_path_count: u64,
 | 
						|
    flags: packed struct(u32) {
 | 
						|
        relax_all: u1,
 | 
						|
        no_exec_stack: u1,
 | 
						|
        fatal_warnings: u1,
 | 
						|
        no_warn: u1,
 | 
						|
        no_deprecated_warn: u1,
 | 
						|
        no_type_check: u1,
 | 
						|
        save_temp_labels: u1,
 | 
						|
        incremental_linker_compatible: u1,
 | 
						|
        fdpic: u1,
 | 
						|
        show_mc_encoding: u1,
 | 
						|
        show_mc_inst: u1,
 | 
						|
        asm_verbose: u1,
 | 
						|
        preserve_asm_comments: u1,
 | 
						|
        dwarf64: u1,
 | 
						|
        crel: u1,
 | 
						|
        x86_relax_relocations: u1,
 | 
						|
        x86_sse2_avx: u1,
 | 
						|
        emit_dwarf_unwind: enum(u2) {
 | 
						|
            always = 0,
 | 
						|
            no_compact_unwind = 1,
 | 
						|
            default = 2,
 | 
						|
        },
 | 
						|
        use_dwarf_directory: enum(u2) {
 | 
						|
            disable = 0,
 | 
						|
            enable = 1,
 | 
						|
            default = 2,
 | 
						|
        },
 | 
						|
        debug_compression_type: enum(u2) {
 | 
						|
            none = 0,
 | 
						|
            zlib = 1,
 | 
						|
            zstd = 2,
 | 
						|
        },
 | 
						|
        emit_compact_unwind_non_canonical: u1,
 | 
						|
        ppc_use_full_register_names: u1,
 | 
						|
        reserved: PaddingType = 0,
 | 
						|
    },
 | 
						|
 | 
						|
    const padding_bit_count = 7;
 | 
						|
    const PaddingType = @Type(.{
 | 
						|
        .int = .{
 | 
						|
            .signedness = .unsigned,
 | 
						|
            .bits = 7,
 | 
						|
        },
 | 
						|
    });
 | 
						|
    comptime {
 | 
						|
        assert(@sizeOf(MCTargetOptions) == 112);
 | 
						|
        assert(padding_bit_count == 7);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const OptimizationLevel = enum(u3) {
 | 
						|
    O0 = 0,
 | 
						|
    O1 = 1,
 | 
						|
    O2 = 2,
 | 
						|
    O3 = 3,
 | 
						|
    Os = 4,
 | 
						|
    Oz = 5,
 | 
						|
 | 
						|
    fn prefers_size(optimization_level: OptimizationLevel) bool {
 | 
						|
        return switch (optimization_level) {
 | 
						|
            .O0, .O1, .Os, .Oz => true,
 | 
						|
            .O2, .O3 => false,
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    fn prefers_speed(optimization_level: OptimizationLevel) bool {
 | 
						|
        return !prefers_size(optimization_level);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
/// This is ABI-compatible with C++
 | 
						|
pub const OptimizationPipelineOptions = packed struct(u64) {
 | 
						|
    optimization_level: OptimizationLevel,
 | 
						|
    debug_info: u1,
 | 
						|
    loop_unrolling: u1,
 | 
						|
    loop_interleaving: u1,
 | 
						|
    loop_vectorization: u1,
 | 
						|
    slp_vectorization: u1,
 | 
						|
    merge_functions: u1,
 | 
						|
    call_graph_profile: u1,
 | 
						|
    unified_lto: u1,
 | 
						|
    assignment_tracking: u1,
 | 
						|
    verify_module: u1,
 | 
						|
    reserved: PaddingType = 0,
 | 
						|
 | 
						|
    const padding_bit_count = 51;
 | 
						|
    const PaddingType = @Type(.{
 | 
						|
        .int = .{
 | 
						|
            .signedness = .unsigned,
 | 
						|
            .bits = padding_bit_count,
 | 
						|
        },
 | 
						|
    });
 | 
						|
 | 
						|
    comptime {
 | 
						|
        assert(@sizeOf(OptimizationPipelineOptions) == @sizeOf(u64));
 | 
						|
        assert(padding_bit_count == 51);
 | 
						|
    }
 | 
						|
 | 
						|
    const Create = packed struct {
 | 
						|
        optimization_level: OptimizationLevel,
 | 
						|
        debug_info: u1,
 | 
						|
    };
 | 
						|
    pub fn default(create: Create) OptimizationPipelineOptions {
 | 
						|
        const pref_speed = @intFromBool(create.optimization_level.prefers_speed());
 | 
						|
        return .{
 | 
						|
            .optimization_level = create.optimization_level,
 | 
						|
            .debug_info = create.debug_info,
 | 
						|
            .loop_unrolling = pref_speed,
 | 
						|
            .loop_interleaving = pref_speed,
 | 
						|
            .loop_vectorization = pref_speed,
 | 
						|
            .slp_vectorization = pref_speed,
 | 
						|
            .merge_functions = pref_speed,
 | 
						|
            .call_graph_profile = 0,
 | 
						|
            .unified_lto = 0,
 | 
						|
            .assignment_tracking = create.debug_info,
 | 
						|
            .verify_module = @intFromBool(lib.optimization_mode == .ReleaseSafe or lib.optimization_mode == .Debug),
 | 
						|
        };
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
/// This is ABI-compatible with C++
 | 
						|
pub const CodeGenerationPipelineOptions = extern struct {
 | 
						|
    output_dwarf_file_path: String,
 | 
						|
    output_file_path: String,
 | 
						|
    flags: packed struct(u64) {
 | 
						|
        code_generation_file_type: enum(u2) {
 | 
						|
            assembly_file = 0,
 | 
						|
            object_file = 1,
 | 
						|
            null = 2,
 | 
						|
        },
 | 
						|
        optimize_when_possible: u1,
 | 
						|
        verify_module: u1,
 | 
						|
        reserved: PaddingType = 0,
 | 
						|
    },
 | 
						|
 | 
						|
    const padding_bit_count = 60;
 | 
						|
    const PaddingType = @Type(.{
 | 
						|
        .int = .{
 | 
						|
            .signedness = .unsigned,
 | 
						|
            .bits = padding_bit_count,
 | 
						|
        },
 | 
						|
    });
 | 
						|
 | 
						|
    comptime {
 | 
						|
        assert(@sizeOf(CodeGenerationPipelineOptions) == 5 * @sizeOf(u64));
 | 
						|
        assert(padding_bit_count == 60);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const CodeGenerationPipelineResult = enum(u8) {
 | 
						|
    success = 0,
 | 
						|
    failed_to_create_file = 1,
 | 
						|
    failed_to_add_emit_passes = 2,
 | 
						|
};
 | 
						|
 | 
						|
pub const Architecture = enum {
 | 
						|
    X86,
 | 
						|
};
 | 
						|
 | 
						|
pub const TargetInitializerOptions = struct {
 | 
						|
    asm_parser: bool = true,
 | 
						|
    asm_printer: bool = true,
 | 
						|
    disassembler: bool = false,
 | 
						|
};
 | 
						|
 | 
						|
const targets = [@typeInfo(Architecture).@"enum".fields.len]type{
 | 
						|
    api.get_initializer(.X86),
 | 
						|
};
 | 
						|
 | 
						|
pub const Context = opaque {
 | 
						|
    pub const create = api.LLVMContextCreate;
 | 
						|
 | 
						|
    pub fn create_module(context: *Context, name: []const u8) *Module {
 | 
						|
        return api.llvm_context_create_module(context, String.from_slice(name));
 | 
						|
    }
 | 
						|
 | 
						|
    pub const create_builder = api.LLVMCreateBuilderInContext;
 | 
						|
 | 
						|
    pub fn create_basic_block(context: *Context, name: []const u8, parent: *Function) *BasicBlock {
 | 
						|
        return api.llvm_context_create_basic_block(context, String.from_slice(name), parent);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_forward_declared_struct_type(context: *Context, name: []const u8) *Type.Struct {
 | 
						|
        return api.llvm_context_create_forward_declared_struct_type(context, String.from_slice(name));
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_struct_type(context: *Context, element_types: []const *Type, name: []const u8) *Type.Struct {
 | 
						|
        const is_packed = false;
 | 
						|
        return api.llvm_context_create_struct_type(context, element_types.ptr, @intCast(element_types.len), String.from_slice(name), is_packed);
 | 
						|
    }
 | 
						|
 | 
						|
    pub const get_struct_type = api.llvm_context_get_struct_type;
 | 
						|
 | 
						|
    pub const get_void_type = api.LLVMVoidTypeInContext;
 | 
						|
    pub const get_integer_type = api.LLVMIntTypeInContext;
 | 
						|
};
 | 
						|
 | 
						|
pub const BasicBlock = opaque {
 | 
						|
    pub const get_terminator = api.LLVMGetBasicBlockTerminator;
 | 
						|
};
 | 
						|
 | 
						|
pub const Module = opaque {
 | 
						|
    pub const create_di_builder = api.LLVMCreateDIBuilder;
 | 
						|
    pub const set_target = api.llvm_module_set_target;
 | 
						|
    pub const run_optimization_pipeline = api.llvm_module_run_optimization_pipeline;
 | 
						|
    pub const run_code_generation_pipeline = api.llvm_module_run_code_generation_pipeline;
 | 
						|
 | 
						|
    pub fn to_string(module: *Module) []const u8 {
 | 
						|
        return api.llvm_module_to_string(module).to_slice().?;
 | 
						|
    }
 | 
						|
 | 
						|
    pub const FunctionCreate = struct {
 | 
						|
        type: *Type.Function,
 | 
						|
        linkage: LinkageType,
 | 
						|
        address_space: c_uint = 0,
 | 
						|
        name: []const u8,
 | 
						|
    };
 | 
						|
 | 
						|
    pub fn create_function(module: *Module, create: FunctionCreate) *Function {
 | 
						|
        return api.llvm_module_create_function(module, create.type, create.linkage, create.address_space, String.from_slice(create.name));
 | 
						|
    }
 | 
						|
 | 
						|
    pub const GlobalCreate = struct {
 | 
						|
        type: *Type,
 | 
						|
        initial_value: *Constant,
 | 
						|
        name: []const u8,
 | 
						|
        before: ?*GlobalVariable = null,
 | 
						|
        address_space: c_uint = 0,
 | 
						|
        linkage: LinkageType,
 | 
						|
        thread_local_mode: ThreadLocalMode = .none,
 | 
						|
        is_constant: bool = false,
 | 
						|
        externally_initialized: bool = false,
 | 
						|
    };
 | 
						|
 | 
						|
    pub fn create_global_variable(module: *Module, create: GlobalCreate) *GlobalVariable {
 | 
						|
        return api.llvm_module_create_global_variable(module, create.type, create.is_constant, create.linkage, create.initial_value, String.from_slice(create.name), create.before, create.thread_local_mode, create.address_space, create.externally_initialized);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn verify(module: *Module) VerifyResult {
 | 
						|
        var result: VerifyResult = undefined;
 | 
						|
        var string: String = undefined;
 | 
						|
        result.success = api.llvm_module_verify(module, &string);
 | 
						|
        result.error_message = string.to_slice();
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const VerifyResult = struct {
 | 
						|
    error_message: ?[]const u8,
 | 
						|
    success: bool,
 | 
						|
};
 | 
						|
 | 
						|
pub const Builder = opaque {
 | 
						|
    pub const position_at_end = api.LLVMPositionBuilderAtEnd;
 | 
						|
 | 
						|
    pub const create_ret = api.LLVMBuildRet;
 | 
						|
 | 
						|
    pub fn create_ret_void(builder: *Builder) void {
 | 
						|
        builder.create_ret(null);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_add(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildAdd(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_sub(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildSub(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_mul(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildMul(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_sdiv(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildSDiv(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_udiv(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildUDiv(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_srem(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildSRem(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_urem(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildURem(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_shl(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildShl(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_ashr(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildAShr(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_lshr(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildLShr(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_and(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildAnd(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_or(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildOr(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_xor(builder: *Builder, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildXor(builder, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_alloca(builder: *Builder, ty: *Type, name: []const u8) *Value {
 | 
						|
        return api.llvm_builder_create_alloca(builder, ty, 0, String.from_slice(name));
 | 
						|
    }
 | 
						|
 | 
						|
    pub const create_store = api.LLVMBuildStore;
 | 
						|
 | 
						|
    pub fn create_load(builder: *Builder, ty: *Type, pointer: *Value) *Value {
 | 
						|
        return api.LLVMBuildLoad2(builder, ty, pointer, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn clear_current_debug_location(builder: *Builder) void {
 | 
						|
        return builder.set_current_debug_location(null);
 | 
						|
    }
 | 
						|
 | 
						|
    pub const set_current_debug_location = api.LLVMSetCurrentDebugLocation2;
 | 
						|
 | 
						|
    pub fn create_compare(builder: *Builder, predicate: IntPredicate, left: *Value, right: *Value) *Value {
 | 
						|
        return api.LLVMBuildICmp(builder, predicate, left, right, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub const create_conditional_branch = api.LLVMBuildCondBr;
 | 
						|
 | 
						|
    pub fn create_call(builder: *Builder, function_type: *Type.Function, function_value: *Value, arguments: []const *Value) *Value {
 | 
						|
        return api.LLVMBuildCall2(builder, function_type, function_value, arguments.ptr, @intCast(arguments.len), "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_struct_gep(builder: *Builder, struct_type: *Type.Struct, pointer: *Value, index: c_uint) *Value {
 | 
						|
        return api.LLVMBuildStructGEP2(builder, struct_type, pointer, index, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_gep(builder: *Builder, ty: *Type, aggregate: *Value, indices: []const *Value) *Value {
 | 
						|
        return api.LLVMBuildInBoundsGEP2(builder, ty, aggregate, indices.ptr, @intCast(indices.len), "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_insert_value(builder: *Builder, aggregate: *Value, element: *Value, index: c_uint) *Value {
 | 
						|
        return api.LLVMBuildInsertValue(builder, aggregate, element, index, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_zero_extend(builder: *Builder, value: *Value, destination_type: *Type) *Value {
 | 
						|
        return api.LLVMBuildZExt(builder, value, destination_type, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn create_sign_extend(builder: *Builder, value: *Value, destination_type: *Type) *Value {
 | 
						|
        return api.LLVMBuildSExt(builder, value, destination_type, "");
 | 
						|
    }
 | 
						|
 | 
						|
    pub const create_unreachable = api.LLVMBuildUnreachable;
 | 
						|
};
 | 
						|
 | 
						|
pub const GlobalValue = opaque {
 | 
						|
    pub const get_type = api.LLVMGlobalGetValueType;
 | 
						|
};
 | 
						|
 | 
						|
pub const GlobalVariable = opaque {
 | 
						|
    pub const add_debug_info = api.llvm_global_variable_add_debug_info;
 | 
						|
    pub fn to_value(global_variable: *GlobalVariable) *Value {
 | 
						|
        return @ptrCast(global_variable);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const Function = opaque {
 | 
						|
    pub fn get_type(function: *Function) *Type.Function {
 | 
						|
        return function.to_global_value().get_type().to_function();
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_value(function: *Function) *Value {
 | 
						|
        return @ptrCast(function);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_global_value(function: *Function) *GlobalValue {
 | 
						|
        return @ptrCast(function);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn verify(function: *Function) VerifyResult {
 | 
						|
        var result: VerifyResult = undefined;
 | 
						|
        var string: String = undefined;
 | 
						|
        result.success = api.llvm_function_verify(function, &string);
 | 
						|
        result.error_message = string.to_slice();
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
    pub const set_subprogram = api.LLVMSetSubprogram;
 | 
						|
    pub const get_subprogram = api.LLVMGetSubprogram;
 | 
						|
 | 
						|
    pub fn to_string(function: *Function) []const u8 {
 | 
						|
        return api.llvm_function_to_string(function).to_slice();
 | 
						|
    }
 | 
						|
 | 
						|
    pub const set_calling_convention = api.LLVMSetFunctionCallConv;
 | 
						|
    pub const get_calling_convention = api.LLVMGetFunctionCallConv;
 | 
						|
 | 
						|
    pub const get_arguments = api.LLVMGetParams;
 | 
						|
};
 | 
						|
 | 
						|
pub const Constant = opaque {
 | 
						|
    pub fn to_value(constant: *Constant) *Value {
 | 
						|
        return @ptrCast(constant);
 | 
						|
    }
 | 
						|
 | 
						|
    pub const Integer = opaque {
 | 
						|
        pub fn to_value(constant: *Constant.Integer) *Value {
 | 
						|
            return @ptrCast(constant);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    pub const Array = opaque {
 | 
						|
        pub fn to_value(constant: *Constant.Array) *Value {
 | 
						|
            return @ptrCast(constant);
 | 
						|
        }
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
pub const Argument = opaque {
 | 
						|
    pub fn to_value(argument: *Argument) *Value {
 | 
						|
        return @ptrCast(argument);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const Value = opaque {
 | 
						|
    pub const get_type = api.LLVMTypeOf;
 | 
						|
    pub const get_kind = api.LLVMGetValueKind;
 | 
						|
 | 
						|
    pub fn is_constant(value: *Value) bool {
 | 
						|
        return api.LLVMIsConstant(value) != 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_constant(value: *Value) *Constant {
 | 
						|
        assert(value.is_constant());
 | 
						|
        return @ptrCast(value);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_instruction(value: *Value) *Instruction {
 | 
						|
        assert(value.get_kind() == .Instruction);
 | 
						|
        return @ptrCast(value);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_function(value: *Value) *Function {
 | 
						|
        assert(value.get_kind() == .Function);
 | 
						|
        return @ptrCast(value);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn get_calling_convention(value: *Value) CallingConvention {
 | 
						|
        const kind = value.get_kind();
 | 
						|
        switch (kind) {
 | 
						|
            .Instruction => {
 | 
						|
                const instruction = value.to_instruction();
 | 
						|
                return instruction.get_calling_convention();
 | 
						|
            },
 | 
						|
            .Function => {
 | 
						|
                const function = value.to_function();
 | 
						|
                return function.get_calling_convention();
 | 
						|
            },
 | 
						|
            else => unreachable,
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    pub const Kind = enum(c_uint) {
 | 
						|
        Argument,
 | 
						|
        BasicBlock,
 | 
						|
        MemoryUse,
 | 
						|
        MemoryDef,
 | 
						|
        MemoryPhi,
 | 
						|
 | 
						|
        Function,
 | 
						|
        GlobalAlias,
 | 
						|
        GlobalIFunc,
 | 
						|
        GlobalVariable,
 | 
						|
        BlockAddress,
 | 
						|
        ConstantExpr,
 | 
						|
        ConstantArray,
 | 
						|
        ConstantStruct,
 | 
						|
        ConstantVector,
 | 
						|
 | 
						|
        UndefValue,
 | 
						|
        ConstantAggregateZero,
 | 
						|
        ConstantDataArray,
 | 
						|
        ConstantDataVector,
 | 
						|
        ConstantInt,
 | 
						|
        ConstantFP,
 | 
						|
        ConstantPointerNull,
 | 
						|
        ConstantTokenNone,
 | 
						|
 | 
						|
        MetadataAsValue,
 | 
						|
        InlineAsm,
 | 
						|
 | 
						|
        Instruction,
 | 
						|
        PoisonValue,
 | 
						|
        ConstantTargetNone,
 | 
						|
        ConstantPtrAuth,
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
pub const Instruction = opaque {
 | 
						|
    pub const set_calling_convention = api.LLVMSetInstructionCallConv;
 | 
						|
    pub const get_calling_convention = api.LLVMGetInstructionCallConv;
 | 
						|
};
 | 
						|
 | 
						|
pub const DI = struct {
 | 
						|
    pub const Builder = opaque {
 | 
						|
        pub fn create_file(builder: *DI.Builder, file_name: []const u8, directory: []const u8) *File {
 | 
						|
            return api.LLVMDIBuilderCreateFile(builder, String.from_slice(file_name), String.from_slice(directory));
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_compile_unit(builder: *DI.Builder, file: *DI.File, optimized: bool) *DI.CompileUnit {
 | 
						|
            return api.LLVMDIBuilderCreateCompileUnit(builder, .C17, file, String.from_slice("bloat buster"), @intFromBool(optimized), String{}, 0, String{}, .full, 0, 0, @intFromBool(optimized), String{}, String{});
 | 
						|
        }
 | 
						|
 | 
						|
        pub const finalize = api.LLVMDIBuilderFinalize;
 | 
						|
 | 
						|
        pub fn create_subroutine_type(builder: *DI.Builder, file: *DI.File, parameter_types: []const *DI.Type, flags: DI.Flags) *DI.Type.Subroutine {
 | 
						|
            return api.LLVMDIBuilderCreateSubroutineType(builder, file, parameter_types.ptr, @intCast(parameter_types.len), flags);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_function(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, linkage_name: []const u8, file: *DI.File, line_number: c_uint, subroutine_type: *DI.Type.Subroutine, local_to_unit: bool, is_definition: bool, scope_line: c_uint, flags: DI.Flags, is_optimized: bool) *DI.Subprogram {
 | 
						|
            return api.LLVMDIBuilderCreateFunction(builder, scope, String.from_slice(name), String.from_slice(linkage_name), file, line_number, subroutine_type, @intFromBool(local_to_unit), @intFromBool(is_definition), scope_line, flags, @intFromBool(is_optimized));
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_basic_type(builder: *DI.Builder, name: []const u8, bit_count: u64, dwarf_type: Dwarf.Type, flags: DI.Flags) *DI.Type {
 | 
						|
            return api.LLVMDIBuilderCreateBasicType(builder, name.ptr, name.len, bit_count, dwarf_type, flags);
 | 
						|
        }
 | 
						|
 | 
						|
        pub const finalize_subprogram = api.LLVMDIBuilderFinalizeSubprogram;
 | 
						|
 | 
						|
        pub fn create_expression(builder: *DI.Builder, slice: []const u64) *DI.Expression {
 | 
						|
            return api.LLVMDIBuilderCreateExpression(builder, slice.ptr, slice.len);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn null_expression(builder: *DI.Builder) *DI.Expression {
 | 
						|
            return api.LLVMDIBuilderCreateExpression(builder, null, 0);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_auto_variable(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, file: *DI.File, line: c_uint, auto_type: *DI.Type, always_preserve: bool, flags: DI.Flags, alignment_in_bits: u32) *DI.LocalVariable {
 | 
						|
            return api.LLVMDIBuilderCreateAutoVariable(builder, scope, name.ptr, name.len, file, line, auto_type, @intFromBool(always_preserve), flags, alignment_in_bits);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_parameter_variable(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, argument_number: c_uint, file: *DI.File, line: c_uint, parameter_type: *DI.Type, always_preserve: bool, flags: DI.Flags) *DI.LocalVariable {
 | 
						|
            return api.LLVMDIBuilderCreateParameterVariable(builder, scope, name.ptr, name.len, argument_number, file, line, parameter_type, @intFromBool(always_preserve), flags);
 | 
						|
        }
 | 
						|
 | 
						|
        pub const insert_declare_record_at_end = api.LLVMDIBuilderInsertDeclareRecordAtEnd;
 | 
						|
 | 
						|
        pub fn create_global_variable(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, linkage_name: []const u8, file: *DI.File, line: c_uint, global_type: *DI.Type, local_to_unit: bool, expression: *DI.Expression, align_in_bits: u32) *DI.GlobalVariableExpression {
 | 
						|
            const declaration: ?*DI.Metadata = null;
 | 
						|
            return api.LLVMDIBuilderCreateGlobalVariableExpression(builder, scope, name.ptr, name.len, linkage_name.ptr, linkage_name.len, file, line, global_type, @intFromBool(local_to_unit), expression, declaration, align_in_bits);
 | 
						|
        }
 | 
						|
 | 
						|
        pub const create_lexical_block = api.LLVMDIBuilderCreateLexicalBlock;
 | 
						|
 | 
						|
        pub fn create_replaceable_composite_type(builder: *DI.Builder, tag: c_uint, name: []const u8, scope: *DI.Scope, file: *DI.File, line: c_uint) *DI.Type.Composite {
 | 
						|
            return api.LLVMDIBuilderCreateReplaceableCompositeType(builder, tag, name.ptr, name.len, scope, file, line, 0, 0, 0, .{}, null, 0);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_array_type(builder: *DI.Builder, element_count: u64, align_in_bits: u32, element_type: *DI.Type, subscripts: []const *DI.Metadata) *DI.Type.Composite {
 | 
						|
            return api.LLVMDIBuilderCreateArrayType(builder, element_count, align_in_bits, element_type, subscripts.ptr, @intCast(subscripts.len));
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_struct_type(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, file: *DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, flags: DI.Flags, members: []const *DI.Type.Derived) *DI.Type.Composite {
 | 
						|
            const derived_from: ?*DI.Type = null;
 | 
						|
            const runtime_language: c_uint = 0;
 | 
						|
            const vtable_holder: ?*DI.Metadata = null;
 | 
						|
            const unique_id_pointer: ?[*]const u8 = null;
 | 
						|
            const unique_id_length: usize = 0;
 | 
						|
            return api.LLVMDIBuilderCreateStructType(builder, scope, name.ptr, name.len, file, line, bit_size, align_in_bits, flags, derived_from, members.ptr, @intCast(members.len), runtime_language, vtable_holder, unique_id_pointer, unique_id_length);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_member_type(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, file: *DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, bit_offset: u64, flags: DI.Flags, member_type: *DI.Type) *DI.Type.Derived {
 | 
						|
            return api.LLVMDIBuilderCreateMemberType(builder, scope, name.ptr, name.len, file, line, bit_size, align_in_bits, bit_offset, flags, member_type);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn create_bit_field_member_type(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, file: *DI.File, line: c_uint, bit_size: u64, bit_offset: u64, bit_storage_offset: u64, flags: DI.Flags, member_type: *DI.Type) *DI.Type.Derived {
 | 
						|
            return api.LLVMDIBuilderCreateBitFieldMemberType(builder, scope, name.ptr, name.len, file, line, bit_size, bit_offset, bit_storage_offset, flags, member_type);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    pub const create_debug_location = api.LLVMDIBuilderCreateDebugLocation;
 | 
						|
 | 
						|
    pub const CompileUnit = opaque {
 | 
						|
        pub fn to_scope(compile_unit: *DI.CompileUnit) *DI.Scope {
 | 
						|
            return @ptrCast(compile_unit);
 | 
						|
        }
 | 
						|
    };
 | 
						|
    pub const File = opaque {};
 | 
						|
    pub const Scope = opaque {};
 | 
						|
    pub const Subprogram = opaque {};
 | 
						|
    pub const Expression = opaque {};
 | 
						|
    pub const GlobalVariableExpression = opaque {};
 | 
						|
    pub const LexicalBlock = opaque {
 | 
						|
        pub fn to_scope(lexical_block: *LexicalBlock) *Scope {
 | 
						|
            return @ptrCast(lexical_block);
 | 
						|
        }
 | 
						|
    };
 | 
						|
    pub const LocalVariable = opaque {};
 | 
						|
    pub const Location = opaque {};
 | 
						|
    pub const Metadata = opaque {};
 | 
						|
    pub const Record = opaque {};
 | 
						|
 | 
						|
    pub const Type = opaque {
 | 
						|
        pub const Subroutine = opaque {
 | 
						|
            pub fn to_type(subroutine: *Subroutine) *DI.Type {
 | 
						|
                return @ptrCast(subroutine);
 | 
						|
            }
 | 
						|
        };
 | 
						|
        pub const Composite = opaque {
 | 
						|
            pub fn to_type(composite: *Composite) *DI.Type {
 | 
						|
                return @ptrCast(composite);
 | 
						|
            }
 | 
						|
 | 
						|
            pub const replace_all_uses_with = api.LLVMMetadataReplaceAllUsesWith;
 | 
						|
        };
 | 
						|
        pub const Derived = opaque {};
 | 
						|
    };
 | 
						|
 | 
						|
    pub const Flags = packed struct(u32) {
 | 
						|
        visibility: Visibility = .none,
 | 
						|
        forward_declaration: bool = false,
 | 
						|
        apple_block: bool = false,
 | 
						|
        block_by_ref_struct: bool = false,
 | 
						|
        virtual: bool = false,
 | 
						|
        artificial: bool = false,
 | 
						|
        explicit: bool = false,
 | 
						|
        prototyped: bool = false,
 | 
						|
        objective_c_class_complete: bool = false,
 | 
						|
        object_pointer: bool = false,
 | 
						|
        vector: bool = false,
 | 
						|
        static_member: bool = false,
 | 
						|
        lvalue_reference: bool = false,
 | 
						|
        rvalue_reference: bool = false,
 | 
						|
        reserved: bool = false,
 | 
						|
        inheritance: Inheritance = .none,
 | 
						|
        introduced_virtual: bool = false,
 | 
						|
        bit_field: bool = false,
 | 
						|
        no_return: bool = false,
 | 
						|
        type_pass_by_value: bool = false,
 | 
						|
        type_pass_by_reference: bool = false,
 | 
						|
        enum_class: bool = false,
 | 
						|
        thunk: bool = false,
 | 
						|
        non_trivial: bool = false,
 | 
						|
        big_endian: bool = false,
 | 
						|
        little_endian: bool = false,
 | 
						|
        all_calls_described: bool = false,
 | 
						|
        _: u3 = 0,
 | 
						|
 | 
						|
        const Visibility = enum(u2) {
 | 
						|
            none = 0,
 | 
						|
            private = 1,
 | 
						|
            protected = 2,
 | 
						|
            public = 3,
 | 
						|
        };
 | 
						|
        const Inheritance = enum(u2) {
 | 
						|
            none = 0,
 | 
						|
            single = 1,
 | 
						|
            multiple = 2,
 | 
						|
            virtual = 3,
 | 
						|
        };
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
pub const Type = opaque {
 | 
						|
    pub const Kind = enum(c_uint) {
 | 
						|
        Void,
 | 
						|
        Half,
 | 
						|
        Float,
 | 
						|
        Double,
 | 
						|
        X86_FP80,
 | 
						|
        FP128,
 | 
						|
        PPC_FP128,
 | 
						|
        Label,
 | 
						|
        Integer,
 | 
						|
        Function,
 | 
						|
        Struct,
 | 
						|
        Array,
 | 
						|
        Pointer,
 | 
						|
        Vector,
 | 
						|
        Metadata,
 | 
						|
        X86_MMX,
 | 
						|
        Token,
 | 
						|
        ScalableVector,
 | 
						|
        BFloat,
 | 
						|
        X86_AMX,
 | 
						|
        TargetExt,
 | 
						|
    };
 | 
						|
 | 
						|
    pub const get_kind = api.LLVMGetTypeKind;
 | 
						|
    pub const get_poison = api.LLVMGetPoison;
 | 
						|
 | 
						|
    pub fn to_integer(ty: *Type) *Type.Integer {
 | 
						|
        assert(ty.get_kind() == .Integer);
 | 
						|
        return @ptrCast(ty);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_function(ty: *Type) *Type.Function {
 | 
						|
        assert(ty.get_kind() == .Function);
 | 
						|
        return @ptrCast(ty);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn to_struct(ty: *Type) *Type.Struct {
 | 
						|
        assert(ty.get_kind() == .Struct);
 | 
						|
        return @ptrCast(ty);
 | 
						|
    }
 | 
						|
 | 
						|
    pub const Function = opaque {
 | 
						|
        pub const get_return_type = api.LLVMGetReturnType;
 | 
						|
        pub fn get(return_type: *Type, parameter_types: []const *Type, is_var_args: bool) *Type.Function {
 | 
						|
            return api.LLVMFunctionType(return_type, parameter_types.ptr, @intCast(parameter_types.len), @intFromBool(is_var_args));
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn to_type(function_type: *Type.Function) *Type {
 | 
						|
            return @ptrCast(function_type);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    pub const Integer = opaque {
 | 
						|
        pub const get_constant = api.LLVMConstInt;
 | 
						|
        pub fn to_type(integer: *Type.Integer) *Type {
 | 
						|
            return @ptrCast(integer);
 | 
						|
        }
 | 
						|
        pub const get_bit_count = api.llvm_integer_type_get_bit_count;
 | 
						|
    };
 | 
						|
 | 
						|
    pub const Struct = opaque {
 | 
						|
        pub fn to_type(struct_type: *Type.Struct) *Type {
 | 
						|
            return @ptrCast(struct_type);
 | 
						|
        }
 | 
						|
 | 
						|
        pub fn set_body(struct_type: *Type.Struct, element_types: []const *Type) void {
 | 
						|
            const is_packed = false;
 | 
						|
            api.LLVMStructSetBody(struct_type, element_types.ptr, @intCast(element_types.len), @intFromBool(is_packed));
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    pub const Array = opaque {
 | 
						|
        pub fn to_type(array_type: *Type.Array) *Type {
 | 
						|
            return @ptrCast(array_type);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    pub fn get_array_type(element_type: *Type, element_count: u64) *Type.Array {
 | 
						|
        return api.LLVMArrayType2(element_type, element_count);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn get_constant_array(element_type: *Type, values: []const *Constant) *Constant.Array {
 | 
						|
        return api.LLVMConstArray2(element_type, values.ptr, values.len);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub const Dwarf = struct {
 | 
						|
    pub const Type = enum(c_uint) {
 | 
						|
        void = 0x0,
 | 
						|
        address = 0x1,
 | 
						|
        boolean = 0x2,
 | 
						|
        complex_float = 0x3,
 | 
						|
        float = 0x4,
 | 
						|
        signed = 0x5,
 | 
						|
        signed_char = 0x6,
 | 
						|
        unsigned = 0x7,
 | 
						|
        unsigned_char = 0x8,
 | 
						|
 | 
						|
        // DWARF 3.
 | 
						|
        imaginary_float = 0x9,
 | 
						|
        packed_decimal = 0xa,
 | 
						|
        numeric_string = 0xb,
 | 
						|
        edited = 0xc,
 | 
						|
        signed_fixed = 0xd,
 | 
						|
        unsigned_fixed = 0xe,
 | 
						|
        decimal_float = 0xf,
 | 
						|
 | 
						|
        // DWARF 4.
 | 
						|
        UTF = 0x10,
 | 
						|
 | 
						|
        // DWARF 5.
 | 
						|
        UCS = 0x11,
 | 
						|
        ASCII = 0x12,
 | 
						|
 | 
						|
        // HP extensions.
 | 
						|
        HP_float80 = 0x80, // Floating-point (80 bit).
 | 
						|
        HP_complex_float80 = 0x81, // Complex floating-point (80 bit).
 | 
						|
        HP_float128 = 0x82, // Floating-point (128 bit).
 | 
						|
        HP_complex_float128 = 0x83, // Complex fp (128 bit).
 | 
						|
        HP_floathpintel = 0x84, // Floating-point (82 bit IA64).
 | 
						|
        HP_imaginary_float80 = 0x85,
 | 
						|
        HP_imaginary_float128 = 0x86,
 | 
						|
        HP_VAX_float = 0x88, // F or G floating.
 | 
						|
        HP_VAX_float_d = 0x89, // D floating.
 | 
						|
        HP_packed_decimal = 0x8a, // Cobol.
 | 
						|
        HP_zoned_decimal = 0x8b, // Cobol.
 | 
						|
        HP_edited = 0x8c, // Cobol.
 | 
						|
        HP_signed_fixed = 0x8d, // Cobol.
 | 
						|
        HP_unsigned_fixed = 0x8e, // Cobol.
 | 
						|
        HP_VAX_complex_float = 0x8f, // F or G floating complex.
 | 
						|
        HP_VAX_complex_float_d = 0x90, // D floating complex.
 | 
						|
    };
 | 
						|
 | 
						|
    pub const EmissionKind = enum(c_int) {
 | 
						|
        none,
 | 
						|
        full,
 | 
						|
        line_tables_only,
 | 
						|
    };
 | 
						|
 | 
						|
    pub const SourceLanguage = enum(c_int) {
 | 
						|
        C89,
 | 
						|
        C,
 | 
						|
        Ada83,
 | 
						|
        C_plus_plus,
 | 
						|
        Cobol74,
 | 
						|
        Cobol85,
 | 
						|
        Fortran77,
 | 
						|
        Fortran90,
 | 
						|
        Pascal83,
 | 
						|
        Modula2,
 | 
						|
        // New in DWARF v3:
 | 
						|
        Java,
 | 
						|
        C99,
 | 
						|
        Ada95,
 | 
						|
        Fortran95,
 | 
						|
        PLI,
 | 
						|
        ObjC,
 | 
						|
        ObjC_plus_plus,
 | 
						|
        UPC,
 | 
						|
        D,
 | 
						|
        // New in DWARF v4:
 | 
						|
        Python,
 | 
						|
        // New in DWARF v5:
 | 
						|
        OpenCL,
 | 
						|
        Go,
 | 
						|
        Modula3,
 | 
						|
        Haskell,
 | 
						|
        C_plus_plus_03,
 | 
						|
        C_plus_plus_11,
 | 
						|
        OCaml,
 | 
						|
        Rust,
 | 
						|
        C11,
 | 
						|
        Swift,
 | 
						|
        Julia,
 | 
						|
        Dylan,
 | 
						|
        C_plus_plus_14,
 | 
						|
        Fortran03,
 | 
						|
        Fortran08,
 | 
						|
        RenderScript,
 | 
						|
        BLISS,
 | 
						|
        Kotlin,
 | 
						|
        Zig,
 | 
						|
        Crystal,
 | 
						|
        C_plus_plus_17,
 | 
						|
        C_plus_plus_20,
 | 
						|
        C17,
 | 
						|
        Fortran18,
 | 
						|
        Ada2005,
 | 
						|
        Ada2012,
 | 
						|
        HIP,
 | 
						|
        Assembly,
 | 
						|
        C_sharp,
 | 
						|
        Mojo,
 | 
						|
        GLSL,
 | 
						|
        GLSL_ES,
 | 
						|
        HLSL,
 | 
						|
        OpenCL_CPP,
 | 
						|
        CPP_for_OpenCL,
 | 
						|
        SYCL,
 | 
						|
        Ruby,
 | 
						|
        Move,
 | 
						|
        Hylo,
 | 
						|
 | 
						|
        // Vendor extensions:
 | 
						|
        Mips_Assembler,
 | 
						|
        GOOGLE_RenderScript,
 | 
						|
        BORLAND_Delphi,
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
pub const IntPredicate = enum(c_int) {
 | 
						|
    eq = 32,
 | 
						|
    ne,
 | 
						|
    ugt,
 | 
						|
    uge,
 | 
						|
    ult,
 | 
						|
    ule,
 | 
						|
    sgt,
 | 
						|
    sge,
 | 
						|
    slt,
 | 
						|
    sle,
 | 
						|
};
 | 
						|
 | 
						|
pub const LinkageType = enum(c_int) {
 | 
						|
    ExternalLinkage,
 | 
						|
    AvailableExternallyLinkage,
 | 
						|
    LinkOnceAnyLinkage,
 | 
						|
    LinkOnceODRLinkage,
 | 
						|
    WeakAnyLinkage,
 | 
						|
    WeakODRLinkage,
 | 
						|
    AppendingLinkage,
 | 
						|
    InternalLinkage,
 | 
						|
    PrivateLinkage,
 | 
						|
    ExternalWeakLinkage,
 | 
						|
    CommonLinkage,
 | 
						|
};
 | 
						|
 | 
						|
pub const ThreadLocalMode = enum(c_uint) {
 | 
						|
    none = 0,
 | 
						|
};
 | 
						|
 | 
						|
pub const CallingConvention = enum(c_uint) {
 | 
						|
    c = 0,
 | 
						|
    fast = 8,
 | 
						|
    cold = 9,
 | 
						|
    ghc = 10,
 | 
						|
    hipe = 11,
 | 
						|
    anyreg = 13,
 | 
						|
    preserve_most = 14,
 | 
						|
    preserve_all = 15,
 | 
						|
    swift = 16,
 | 
						|
    cxx_fast_tls = 17,
 | 
						|
    x86_stdcall = 64,
 | 
						|
    x86_fastcall = 65,
 | 
						|
    arm_apcs = 66,
 | 
						|
    arm_aapcs = 67,
 | 
						|
    arm_aapcsvfp = 68,
 | 
						|
    msp430_interrupt = 69,
 | 
						|
    x86_thiscall = 70,
 | 
						|
    ptx_kernel = 71,
 | 
						|
    ptx_device = 72,
 | 
						|
    spir_func = 75,
 | 
						|
    spir_kernel = 76,
 | 
						|
    intel_oclbi = 77,
 | 
						|
    x86_64_system_v = 78,
 | 
						|
    win64 = 79,
 | 
						|
    x86_vector = 80,
 | 
						|
    hhvm = 81,
 | 
						|
    hhvmc = 82,
 | 
						|
    x86_interrupt = 83,
 | 
						|
    avr_interrupt = 84,
 | 
						|
    avr_signal = 85,
 | 
						|
    avr_builtin = 86,
 | 
						|
    amdgpu_vs = 87,
 | 
						|
    amdgpu_gs = 88,
 | 
						|
    amdgpu_ps = 89,
 | 
						|
    amdgpu_cs = 90,
 | 
						|
    amdgpu_kernel = 91,
 | 
						|
    x86_regcall = 92,
 | 
						|
    amdgpu_hs = 93,
 | 
						|
    msp430_builtin = 94,
 | 
						|
    amgpu_ls = 95,
 | 
						|
    amdgpu_es = 96,
 | 
						|
};
 | 
						|
 | 
						|
pub const lld = struct {
 | 
						|
    pub const Result = extern struct {
 | 
						|
        stdout: String,
 | 
						|
        stderr: String,
 | 
						|
        success: bool,
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
pub const Global = struct {
 | 
						|
    host_triple: []const u8,
 | 
						|
    host_cpu_model: []const u8,
 | 
						|
    host_cpu_features: []const u8,
 | 
						|
};
 | 
						|
pub var global: Global = undefined;
 | 
						|
 | 
						|
pub var initialized = false;
 | 
						|
 | 
						|
// This is meant to call globally, only once per execution
 | 
						|
pub fn initialize_all() void {
 | 
						|
    assert(!initialized);
 | 
						|
    defer initialized = true;
 | 
						|
    inline for (targets) |target| {
 | 
						|
        target.initialize(.{});
 | 
						|
    }
 | 
						|
 | 
						|
    global = .{
 | 
						|
        .host_triple = api.llvm_default_target_triple().to_slice() orelse unreachable,
 | 
						|
        .host_cpu_model = api.llvm_host_cpu_name().to_slice() orelse unreachable,
 | 
						|
        .host_cpu_features = api.llvm_host_cpu_features().to_slice() orelse unreachable,
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
const LldArgvBuilder = struct {
 | 
						|
    buffer: [1024]?[*:0]const u8 = undefined,
 | 
						|
    count: usize = 0,
 | 
						|
 | 
						|
    pub fn add(builder: *LldArgvBuilder, arg: [*:0]const u8) void {
 | 
						|
        builder.buffer[builder.count] = arg;
 | 
						|
        builder.count += 1;
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn flush(builder: *LldArgvBuilder) [:null]const ?[*:0]const u8 {
 | 
						|
        builder.buffer[builder.count] = null;
 | 
						|
        return builder.buffer[0..builder.count :null];
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
pub fn default_initialize() void {
 | 
						|
    assert(lib.GlobalState.initialized);
 | 
						|
    if (!initialized) {
 | 
						|
        initialize_all();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
pub const GenerateObject = struct {
 | 
						|
    path: []const u8,
 | 
						|
    target_triple: []const u8,
 | 
						|
    cpu_model: []const u8,
 | 
						|
    cpu_features: []const u8,
 | 
						|
    target_options: Target.Options,
 | 
						|
};
 | 
						|
 | 
						|
pub const ObjectGenerate = struct {
 | 
						|
    path: []const u8,
 | 
						|
    optimization_level: ?OptimizationLevel,
 | 
						|
    debug_info: bool,
 | 
						|
    optimize_when_possible: u1,
 | 
						|
};
 | 
						|
 | 
						|
pub fn object_generate(module: *Module, target_machine: *Target.Machine, generate: ObjectGenerate) CodeGenerationPipelineResult {
 | 
						|
    module.set_target(target_machine);
 | 
						|
 | 
						|
    if (generate.optimization_level) |optimization_level| {
 | 
						|
        module.run_optimization_pipeline(target_machine, OptimizationPipelineOptions.default(.{ .optimization_level = optimization_level, .debug_info = @intFromBool(generate.debug_info) }));
 | 
						|
    }
 | 
						|
 | 
						|
    const result = module.run_code_generation_pipeline(target_machine, CodeGenerationPipelineOptions{
 | 
						|
        .output_file_path = String.from_slice(generate.path),
 | 
						|
        .output_dwarf_file_path = .{},
 | 
						|
        .flags = .{
 | 
						|
            .code_generation_file_type = .object_file,
 | 
						|
            .optimize_when_possible = generate.optimize_when_possible,
 | 
						|
            .verify_module = @intFromBool(lib.optimization_mode == .Debug or lib.optimization_mode == .ReleaseSafe),
 | 
						|
        },
 | 
						|
    });
 | 
						|
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
pub const LinkOptions = struct {
 | 
						|
    objects: []const [:0]const u8,
 | 
						|
    output_path: [:0]const u8,
 | 
						|
};
 | 
						|
 | 
						|
pub fn link(arena: *Arena, options: LinkOptions) lld.Result {
 | 
						|
    var arg_builder = LldArgvBuilder{};
 | 
						|
    arg_builder.add("ld.lld");
 | 
						|
    arg_builder.add("--error-limit=0");
 | 
						|
    arg_builder.add("-o");
 | 
						|
    arg_builder.add(options.output_path);
 | 
						|
    for (options.objects) |object| {
 | 
						|
        arg_builder.add(object);
 | 
						|
    }
 | 
						|
 | 
						|
    const library_paths = [_][:0]const u8{ "/usr/lib", "/usr/lib/x86_64-linux-gnu" };
 | 
						|
 | 
						|
    const scrt1_object_directory_path = inline for (library_paths) |library_path| {
 | 
						|
        const scrt1_path = library_path ++ "/" ++ "Scrt1.o";
 | 
						|
        const file = lib.os.File.open(scrt1_path, .{ .read = 1 }, .{});
 | 
						|
        if (file.is_valid()) {
 | 
						|
            file.close();
 | 
						|
            break library_path;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        lib.print_string_stderr("Failed to find directory for Scrt1.o\n");
 | 
						|
        lib.os.abort();
 | 
						|
    };
 | 
						|
 | 
						|
    arg_builder.add(arena.join_string(&.{ "-L", scrt1_object_directory_path }));
 | 
						|
 | 
						|
    const link_libcpp = false;
 | 
						|
    if (link_libcpp) {
 | 
						|
        arg_builder.add("-lstdc++");
 | 
						|
    }
 | 
						|
 | 
						|
    const link_libc = true;
 | 
						|
 | 
						|
    const dynamic_linker = true;
 | 
						|
    if (dynamic_linker) {
 | 
						|
        arg_builder.add("-dynamic-linker");
 | 
						|
 | 
						|
        const dynamic_linker_path = "/usr/lib64/ld-linux-x86-64.so.2";
 | 
						|
        arg_builder.add(dynamic_linker_path);
 | 
						|
    }
 | 
						|
 | 
						|
    if (link_libc) {
 | 
						|
        arg_builder.add(arena.join_string(&.{ scrt1_object_directory_path, "/", "Scrt1.o" }));
 | 
						|
        arg_builder.add("-lc");
 | 
						|
    }
 | 
						|
 | 
						|
    const lld_args = arg_builder.flush();
 | 
						|
    const lld_result = api.lld_elf_link(lld_args.ptr, lld_args.len, true, false);
 | 
						|
    const success = lld_result.success and lld_result.stderr.length == 0;
 | 
						|
    if (!success) {
 | 
						|
        for (lld_args) |lld_arg| {
 | 
						|
            lib.print_string_stderr(lib.cstring.to_slice(lld_arg.?));
 | 
						|
            lib.print_string_stderr(" ");
 | 
						|
        }
 | 
						|
        lib.print_string_stderr("\n");
 | 
						|
 | 
						|
        if (lld_result.stdout.length != 0) {
 | 
						|
            lib.print_string_stderr(lld_result.stdout.to_slice() orelse unreachable);
 | 
						|
        }
 | 
						|
 | 
						|
        if (lld_result.stderr.length != 0) {
 | 
						|
            lib.print_string_stderr(lld_result.stderr.to_slice() orelse unreachable);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return lld_result;
 | 
						|
}
 |