aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-09-17 18:29:38 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-09-17 18:29:38 -0700
commitdc478687d95ee0d495cd26182edae78a01db59af (patch)
tree1d01458b78029ec182fd07cdc39b6e5c723907b3 /src/codegen.cpp
parentbc01887376c227a5f42715f48471dcca14b3d31b (diff)
downloadzig-dc478687d95ee0d495cd26182edae78a01db59af.tar.gz
zig-dc478687d95ee0d495cd26182edae78a01db59af.zip
delete all stage1 c++ code not directly related to compiling stage2
Deleted 16,000+ lines of c++ code, including: * an implementation of blake hashing * the cache hash system * compiler.cpp * all the linking code, and everything having to do with building glibc, musl, and mingw-w64 * much of the stage1 compiler internals got slimmed down since it now assumes it is always outputting an object file. More stuff: * stage1 is now built with a different strategy: we have a tiny zig0.cpp which is a slimmed down version of what stage1 main.cpp used to be. Its only purpose is to build stage2 zig code into an object file, which is then linked by the host build system (cmake) into stage1. zig0.cpp uses the same C API that stage2 now has access to, so that stage2 zig code can call into stage1 c++ code. - stage1.h is - stage2.h is - stage1.zig is the main entry point for the Zig/C++ hybrid compiler. It has the functions exported from Zig, called in C++, and bindings for the functions exported from C++, called from Zig. * removed the memory profiling instrumentation from stage1. Abandon ship! * Re-added the sections to the README about how to build stage2 and stage3. * stage2 now knows as a comptime boolean whether it is being compiled as part of stage1 or as stage2. - TODO use this flag to call into stage1 for compiling zig code. * introduce -fdll-export-fns and -fno-dll-export-fns and clarify its relationship to link_mode (static/dynamic) * implement depending on LLVM to detect native target cpu features when LLVM extensions are enabled and zig lacks CPU feature detection for that target architecture. * C importing is broken, will need some stage2 support to function again.
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp2065
1 files changed, 121 insertions, 1944 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index ce6eeb1def..07728ef06e 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8,7 +8,6 @@
#include "analyze.hpp"
#include "ast_render.hpp"
#include "codegen.hpp"
-#include "compiler.hpp"
#include "config.h"
#include "errmsg.hpp"
#include "error.hpp"
@@ -21,7 +20,6 @@
#include "stage2.h"
#include "dump_analysis.hpp"
#include "softfloat.hpp"
-#include "mem_profile.hpp"
#include <stdio.h>
#include <errno.h>
@@ -72,39 +70,6 @@ static const char *symbols_that_llvm_depends_on[] = {
// TODO probably all of compiler-rt needs to go here
};
-void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {
- g->clang_argv = args;
- g->clang_argv_len = len;
-}
-
-void codegen_set_llvm_argv(CodeGen *g, const char **args, size_t len) {
- g->llvm_argv = args;
- g->llvm_argv_len = len;
-}
-
-void codegen_set_test_filter(CodeGen *g, Buf *filter) {
- g->test_filter = filter;
-}
-
-void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) {
- g->test_name_prefix = prefix;
-}
-
-void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch) {
- g->is_versioned = is_versioned;
- g->version_major = major;
- g->version_minor = minor;
- g->version_patch = patch;
-}
-
-void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
- g->each_lib_rpath = each_lib_rpath;
-}
-
-void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) {
- g->err_color = err_color;
-}
-
void codegen_set_strip(CodeGen *g, bool strip) {
g->strip_debug_symbols = strip;
if (!target_has_debug_info(g->zig_target)) {
@@ -112,39 +77,6 @@ void codegen_set_strip(CodeGen *g, bool strip) {
}
}
-void codegen_set_out_name(CodeGen *g, Buf *out_name) {
- g->root_out_name = out_name;
-}
-
-void codegen_add_lib_dir(CodeGen *g, const char *dir) {
- g->lib_dirs.append(dir);
-}
-
-void codegen_add_rpath(CodeGen *g, const char *name) {
- g->rpath_list.append(buf_create_from_str(name));
-}
-
-LinkLib *codegen_add_link_lib(CodeGen *g, Buf *name) {
- return add_link_lib(g, name);
-}
-
-void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib) {
- codegen->forbidden_libs.append(lib);
-}
-
-void codegen_add_framework(CodeGen *g, const char *framework) {
- g->darwin_frameworks.append(buf_create_from_str(framework));
-}
-
-void codegen_set_rdynamic(CodeGen *g, bool rdynamic) {
- g->linker_rdynamic = rdynamic;
-}
-
-void codegen_set_linker_script(CodeGen *g, const char *linker_script) {
- g->linker_script = linker_script;
-}
-
-
static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name);
static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name);
static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name);
@@ -155,7 +87,6 @@ static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *na
static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
LLVMValueRef result_loc, bool non_async);
-static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix);
static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
@@ -389,7 +320,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
}
static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
- if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) {
+ if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->dll_export_fns) {
LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);
}
}
@@ -541,7 +472,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
g->build_mode != BuildModeSmallRelease &&
!fn->def_scope->safety_off;
if (want_fn_safety) {
- if (g->libc_link_lib != nullptr) {
+ if (g->link_libc) {
addLLVMFnAttr(llvm_fn, "sspstrong");
addLLVMFnAttrStr(llvm_fn, "stack-protector-buffer-size", "4");
}
@@ -3859,20 +3790,6 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
zig_unreachable();
}
-static bool want_valgrind_support(CodeGen *g) {
- if (!target_has_valgrind_support(g->zig_target))
- return false;
- switch (g->valgrind_support) {
- case ValgrindSupportDisabled:
- return false;
- case ValgrindSupportEnabled:
- return true;
- case ValgrindSupportAuto:
- return g->build_mode == BuildModeDebug;
- }
- zig_unreachable();
-}
-
static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef byte_count) {
static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
ZigType *usize = g->builtin_types.entry_usize;
@@ -3895,7 +3812,7 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false);
ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false);
// then tell valgrind that the memory is undefined even though we just memset it
- if (want_valgrind_support(g)) {
+ if (g->valgrind_enabled) {
gen_valgrind_undef(g, dest_ptr, byte_count);
}
}
@@ -5598,7 +5515,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, Ir
ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, fill_char, len_val, get_ptr_align(g, ptr_type),
ptr_type->data.pointer.is_volatile);
- if (val_is_undef && want_valgrind_support(g)) {
+ if (val_is_undef && g->valgrind_enabled) {
gen_valgrind_undef(g, dest_ptr_casted, len_val);
}
return nullptr;
@@ -8350,13 +8267,6 @@ static void zig_llvm_emit_output(CodeGen *g) {
exit(1);
}
- if (g->emit_bin) {
- g->link_objects.append(&g->o_file_output_path);
- if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) {
- zig_link_add_compiler_rt(g, g->sub_progress_node);
- }
- }
-
LLVMDisposeModule(g->module);
g->module = nullptr;
LLVMDisposeTargetData(g->target_data_ref);
@@ -8751,75 +8661,12 @@ static const char *subsystem_to_str(TargetSubsystem subsystem) {
zig_unreachable();
}
-static bool detect_dynamic_link(CodeGen *g) {
- if (g->is_dynamic)
- return true;
- if (g->zig_target->os == OsFreestanding)
- return false;
- if (target_os_requires_libc(g->zig_target->os))
- return true;
- if (g->libc_link_lib != nullptr && target_is_glibc(g->zig_target))
- return true;
- // If there are no dynamic libraries then we can disable dynamic linking.
- for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
- LinkLib *link_lib = g->link_libs_list.at(i);
- if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name)))
- continue;
- if (target_is_libcpp_lib_name(g->zig_target, buf_ptr(link_lib->name)))
- continue;
- return true;
- }
- return false;
-}
-
-static bool detect_pic(CodeGen *g) {
- if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr))
- return true;
- switch (g->want_pic) {
- case WantPICDisabled:
- return false;
- case WantPICEnabled:
- return true;
- case WantPICAuto:
- return g->have_dynamic_link;
- }
- zig_unreachable();
-}
-
-static bool detect_stack_probing(CodeGen *g) {
- if (!target_supports_stack_probing(g->zig_target))
- return false;
- switch (g->want_stack_check) {
- case WantStackCheckDisabled:
- return false;
- case WantStackCheckEnabled:
- return true;
- case WantStackCheckAuto:
- return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug;
- }
- zig_unreachable();
-}
-
-static bool detect_sanitize_c(CodeGen *g) {
- if (!target_supports_sanitize_c(g->zig_target))
- return false;
- switch (g->want_sanitize_c) {
- case WantCSanitizeDisabled:
- return false;
- case WantCSanitizeEnabled:
- return true;
- case WantCSanitizeAuto:
- return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug;
- }
- zig_unreachable();
-}
-
// Returns TargetSubsystemAuto to mean "no subsystem"
TargetSubsystem detect_subsystem(CodeGen *g) {
if (g->subsystem != TargetSubsystemAuto)
return g->subsystem;
if (g->zig_target->os == OsWindows) {
- if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic))
+ if (g->have_dllmain_crt_startup)
return TargetSubsystemAuto;
if (g->have_c_main || g->is_test_build || g->have_winmain_crt_startup || g->have_wwinmain_crt_startup)
return TargetSubsystemConsole;
@@ -8831,15 +8678,6 @@ TargetSubsystem detect_subsystem(CodeGen *g) {
return TargetSubsystemAuto;
}
-static bool detect_single_threaded(CodeGen *g) {
- if (g->want_single_threaded)
- return true;
- if (target_is_single_threaded(g->zig_target)) {
- return true;
- }
- return false;
-}
-
static bool detect_err_ret_tracing(CodeGen *g) {
return !g->strip_debug_symbols &&
g->build_mode != BuildModeFastRelease &&
@@ -8847,30 +8685,30 @@ static bool detect_err_ret_tracing(CodeGen *g) {
}
static LLVMCodeModel to_llvm_code_model(CodeGen *g) {
- switch (g->code_model) {
- case CodeModelDefault:
- return LLVMCodeModelDefault;
- case CodeModelTiny:
- return LLVMCodeModelTiny;
- case CodeModelSmall:
- return LLVMCodeModelSmall;
- case CodeModelKernel:
- return LLVMCodeModelKernel;
- case CodeModelMedium:
- return LLVMCodeModelMedium;
- case CodeModelLarge:
- return LLVMCodeModelLarge;
- }
+ switch (g->code_model) {
+ case CodeModelDefault:
+ return LLVMCodeModelDefault;
+ case CodeModelTiny:
+ return LLVMCodeModelTiny;
+ case CodeModelSmall:
+ return LLVMCodeModelSmall;
+ case CodeModelKernel:
+ return LLVMCodeModelKernel;
+ case CodeModelMedium:
+ return LLVMCodeModelMedium;
+ case CodeModelLarge:
+ return LLVMCodeModelLarge;
+ }
- zig_unreachable();
+ zig_unreachable();
}
Buf *codegen_generate_builtin_source(CodeGen *g) {
- g->have_dynamic_link = detect_dynamic_link(g);
- g->have_pic = detect_pic(g);
- g->have_stack_probing = detect_stack_probing(g);
- g->have_sanitize_c = detect_sanitize_c(g);
- g->is_single_threaded = detect_single_threaded(g);
+ // Note that this only runs when zig0 is building the self-hosted zig compiler code,
+ // so it makes a few assumption that are always true for that case. Once we have
+ // built the stage2 zig components then zig is in charge of generating the builtin.zig
+ // file.
+
g->have_err_ret_tracing = detect_err_ret_tracing(g);
Buf *contents = buf_alloc();
@@ -8884,7 +8722,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
const char *name = target_os_name(os_type);
if (os_type == g->zig_target->os) {
- g->target_os_index = i;
cur_os = name;
}
}
@@ -8898,7 +8735,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
ZigLLVM_ArchType arch = target_arch_enum(arch_i);
const char *arch_name = target_arch_name(arch);
if (arch == g->zig_target->arch) {
- g->target_arch_index = arch_i;
cur_arch = arch_name;
}
}
@@ -8913,7 +8749,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
const char *name = target_abi_name(abi);
if (abi == g->zig_target->abi) {
- g->target_abi_index = i;
cur_abi = name;
}
}
@@ -8929,7 +8764,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target);
if (oformat == target_oformat) {
- g->target_oformat_index = i;
cur_obj_fmt = name;
}
}
@@ -8979,23 +8813,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
buf_appendf(contents, "pub const endian = %s;\n", endian_str);
}
- const char *out_type = nullptr;
- switch (g->out_type) {
- case OutTypeExe:
- out_type = "Exe";
- break;
- case OutTypeLib:
- out_type = "Lib";
- break;
- case OutTypeObj:
- case OutTypeUnknown: // This happens when running the `zig builtin` command.
- out_type = "Obj";
- break;
- }
- buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type);
- const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static";
- buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type);
- buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
+ buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n");
+ buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n");
+ buf_appendf(contents, "pub const is_test = false;\n");
buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
buf_append_str(contents, "/// Deprecated: use `std.Target.cpu.arch`\n");
buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
@@ -9018,40 +8838,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);
buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode));
- buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr));
- buf_appendf(contents, "pub const link_libcpp = %s;\n", bool_to_str(g->libcpp_link_lib != nullptr));
+ buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc));
+ buf_appendf(contents, "pub const link_libcpp = %s;\n", bool_to_str(g->link_libcpp));
buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing));
- buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
+ buf_appendf(contents, "pub const valgrind_support = false;\n");
buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
-
- {
- const char *code_model;
- switch (g->code_model) {
- case CodeModelDefault:
- code_model = "default";
- break;
- case CodeModelTiny:
- code_model = "tiny";
- break;
- case CodeModelSmall:
- code_model = "small";
- break;
- case CodeModelKernel:
- code_model = "kernel";
- break;
- case CodeModelMedium:
- code_model = "medium";
- break;
- case CodeModelLarge:
- code_model = "large";
- break;
- default:
- zig_unreachable();
- }
-
- buf_appendf(contents, "pub const code_model = CodeModel.%s;\n", code_model);
- }
+ buf_appendf(contents, "pub const code_model = CodeModel.default;\n");
{
TargetSubsystem detected_subsystem = detect_subsystem(g);
@@ -9060,15 +8853,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
}
- if (g->is_test_build) {
- buf_appendf(contents,
- "pub var test_functions: []TestFn = undefined; // overwritten later\n"
- );
-
- buf_appendf(contents, "pub const test_io_mode = %s;\n",
- g->test_is_evented ? ".evented" : ".blocking");
- }
-
return contents;
}
@@ -9077,95 +8861,35 @@ static ZigPackage *create_test_runner_pkg(CodeGen *g) {
}
static Error define_builtin_compile_vars(CodeGen *g) {
- if (g->std_package == nullptr)
- return ErrorNone;
-
Error err;
- Buf *manifest_dir = buf_alloc();
- os_path_join(get_global_cache_dir(), buf_create_from_str("builtin"), manifest_dir);
-
- CacheHash cache_hash;
- cache_init(&cache_hash, manifest_dir);
-
- Buf *compiler_id;
- if ((err = get_compiler_id(&compiler_id)))
- return err;
-
- // Only a few things affect builtin.zig
- cache_buf(&cache_hash, compiler_id);
- cache_int(&cache_hash, g->build_mode);
- cache_bool(&cache_hash, g->strip_debug_symbols);
- cache_int(&cache_hash, g->out_type);
- cache_bool(&cache_hash, detect_dynamic_link(g));
- cache_bool(&cache_hash, g->is_test_build);
- cache_bool(&cache_hash, g->is_single_threaded);
- cache_bool(&cache_hash, g->test_is_evented);
- cache_int(&cache_hash, g->code_model);
- cache_int(&cache_hash, g->zig_target->is_native_os);
- cache_int(&cache_hash, g->zig_target->is_native_cpu);
- cache_int(&cache_hash, g->zig_target->arch);
- cache_int(&cache_hash, g->zig_target->vendor);
- cache_int(&cache_hash, g->zig_target->os);
- cache_int(&cache_hash, g->zig_target->abi);
- if (g->zig_target->cache_hash != nullptr) {
- cache_mem(&cache_hash, g->zig_target->cache_hash, g->zig_target->cache_hash_len);
- }
- if (g->zig_target->glibc_or_darwin_version != nullptr) {
- cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->major);
- cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->minor);
- cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->patch);
- }
- cache_bool(&cache_hash, g->have_err_ret_tracing);
- cache_bool(&cache_hash, g->libc_link_lib != nullptr);
- cache_bool(&cache_hash, g->libcpp_link_lib != nullptr);
- cache_bool(&cache_hash, g->valgrind_support);
- cache_bool(&cache_hash, g->link_eh_frame_hdr);
- cache_int(&cache_hash, detect_subsystem(g));
-
- Buf digest = BUF_INIT;
- buf_resize(&digest, 0);
- if ((err = cache_hit(&cache_hash, &digest))) {
- // Treat an invalid format error as a cache miss.
- if (err != ErrorInvalidFormat)
- return err;
- }
-
- // We should always get a cache hit because there are no
- // files in the input hash.
- assert(buf_len(&digest) != 0);
-
- Buf *this_dir = buf_alloc();
- os_path_join(manifest_dir, &digest, this_dir);
-
- if ((err = os_make_path(this_dir)))
- return err;
+ if (g->std_package == nullptr)
+ return ErrorNone;
const char *builtin_zig_basename = "builtin.zig";
- Buf *builtin_zig_path = buf_alloc();
- os_path_join(this_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path);
- bool hit;
- if ((err = os_file_exists(builtin_zig_path, &hit)))
- return err;
Buf *contents;
- if (hit) {
- contents = buf_alloc();
- if ((err = os_fetch_file_path(builtin_zig_path, contents))) {
- fprintf(stderr, "Unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err));
+ if (g->builtin_zig_path == nullptr) {
+ // Then this is zig0 building stage2. We can make many assumptions about the compilation.
+ g->builtin_zig_path = buf_alloc();
+ os_path_join(g->output_dir, buf_create_from_str(builtin_zig_basename), g->builtin_zig_path);
+
+ contents = codegen_generate_builtin_source(g);
+ if ((err = os_write_file(g->builtin_zig_path, contents))) {
+ fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err));
exit(1);
}
} else {
- contents = codegen_generate_builtin_source(g);
- if ((err = os_write_file(builtin_zig_path, contents))) {
- fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err));
+ contents = buf_alloc();
+ if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) {
+ fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err));
exit(1);
}
}
assert(g->main_pkg);
assert(g->std_package);
- g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin");
+ g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin");
if (g->is_test_build) {
if (g->test_runner_package == nullptr) {
g->test_runner_package = create_test_runner_pkg(g);
@@ -9180,7 +8904,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
g->std_package->package_table.put(buf_create_from_str("root"), g->root_pkg);
- g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents,
+ g->compile_var_import = add_source_file(g, g->compile_var_package, g->builtin_zig_path, contents,
SourceKindPkgMain);
return ErrorNone;
@@ -9190,17 +8914,8 @@ static void init(CodeGen *g) {
if (g->module)
return;
- g->have_dynamic_link = detect_dynamic_link(g);
- g->have_pic = detect_pic(g);
- g->have_stack_probing = detect_stack_probing(g);
- g->have_sanitize_c = detect_sanitize_c(g);
- g->is_single_threaded = detect_single_threaded(g);
g->have_err_ret_tracing = detect_err_ret_tracing(g);
- if (target_is_single_threaded(g->zig_target)) {
- g->is_single_threaded = true;
- }
-
assert(g->root_out_name);
g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
@@ -9230,7 +8945,7 @@ static void init(CodeGen *g) {
LLVMRelocMode reloc_mode;
if (g->have_pic) {
reloc_mode = LLVMRelocPIC;
- } else if (g->have_dynamic_link) {
+ } else if (g->link_mode_dynamic) {
reloc_mode = LLVMRelocDynamicNoPic;
} else {
reloc_mode = LLVMRelocStatic;
@@ -9336,446 +9051,6 @@ static void init(CodeGen *g) {
}
}
-static void detect_libc(CodeGen *g) {
- Error err;
-
- if (g->libc != nullptr || g->libc_link_lib == nullptr)
- return;
-
- if (target_can_build_libc(g->zig_target)) {
- const char *generic_name = target_libc_generic_name(g->zig_target);
- const char *arch_name = target_arch_name(g->zig_target->arch);
- const char *abi_name = target_abi_name(g->zig_target->abi);
- if (target_is_musl(g->zig_target)) {
- // musl has some overrides. its headers are ABI-agnostic and so they all have the "musl" ABI name.
- abi_name = "musl";
- // some architectures are handled by the same set of headers
- arch_name = target_arch_musl_name(g->zig_target->arch);
- }
- Buf *arch_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s",
- buf_ptr(g->zig_lib_dir), arch_name, target_os_name(g->zig_target->os), abi_name);
- Buf *generic_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "generic-%s",
- buf_ptr(g->zig_lib_dir), generic_name);
- Buf *arch_os_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-any",
- buf_ptr(g->zig_lib_dir), target_arch_name(g->zig_target->arch), target_os_name(g->zig_target->os));
- Buf *generic_os_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "any-%s-any",
- buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os));
-
- g->libc_include_dir_len = 4;
- g->libc_include_dir_list = heap::c_allocator.allocate<const char*>(g->libc_include_dir_len);
- g->libc_include_dir_list[0] = buf_ptr(arch_include_dir);
- g->libc_include_dir_list[1] = buf_ptr(generic_include_dir);
- g->libc_include_dir_list[2] = buf_ptr(arch_os_include_dir);
- g->libc_include_dir_list[3] = buf_ptr(generic_os_include_dir);
- return;
- }
-
- if (g->zig_target->is_native_os) {
- g->libc = heap::c_allocator.create<Stage2LibCInstallation>();
-
- if ((err = stage2_libc_find_native(g->libc))) {
- fprintf(stderr,
- "Unable to link against libc: Unable to find libc installation: %s\n"
- "See `zig libc --help` for more details.\n", err_str(err));
- exit(1);
- }
-
- bool want_sys_dir = !mem_eql_mem(g->libc->include_dir, g->libc->include_dir_len,
- g->libc->sys_include_dir, g->libc->sys_include_dir_len);
- size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0;
- size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs;
- g->libc_include_dir_len = 0;
- g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
-
- g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(
- g->libc->include_dir, g->libc->include_dir_len));
- g->libc_include_dir_len += 1;
-
- if (want_sys_dir) {
- g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(
- g->libc->sys_include_dir, g->libc->sys_include_dir_len));
- g->libc_include_dir_len += 1;
- }
-
- if (want_um_and_shared_dirs != 0) {
- Buf *include_dir_parent = buf_alloc();
- os_path_join(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len),
- buf_create_from_str(".."), include_dir_parent);
-
- Buf *buff1 = buf_alloc();
- os_path_join(include_dir_parent, buf_create_from_str("um"), buff1);
- g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff1);
- g->libc_include_dir_len += 1;
-
- Buf *buff2 = buf_alloc();
- os_path_join(include_dir_parent, buf_create_from_str("shared"), buff2);
- g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff2);
- g->libc_include_dir_len += 1;
- }
- assert(g->libc_include_dir_len == dir_count);
- } else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) &&
- !target_os_is_darwin(g->zig_target->os))
- {
- Buf triple_buf = BUF_INIT;
- target_triple_zig(&triple_buf, g->zig_target);
- fprintf(stderr,
- "Zig is unable to provide a libc for the chosen target '%s'.\n"
- "The target is non-native, so Zig also cannot use the native libc installation.\n"
- "Choose a target which has a libc available (see `zig targets`), or\n"
- "provide a libc installation text file (see `zig libc --help`).\n", buf_ptr(&triple_buf));
- exit(1);
- }
-}
-
-// does not add the "cc" arg
-void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path,
- bool translate_c, FileExt source_kind)
-{
- if (translate_c) {
- args.append("-x");
- args.append("c");
- }
-
- args.append("-nostdinc");
- if (source_kind == FileExtCpp) {
- args.append("-nostdinc++");
- }
- args.append("-fno-spell-checking");
-
- if (g->function_sections) {
- args.append("-ffunction-sections");
- }
-
- if (!translate_c) {
- switch (g->err_color) {
- case ErrColorAuto:
- break;
- case ErrColorOff:
- args.append("-fno-color-diagnostics");
- args.append("-fno-caret-diagnostics");
- break;
- case ErrColorOn:
- args.append("-fcolor-diagnostics");
- args.append("-fcaret-diagnostics");
- break;
- }
- }
-
- for (size_t i = 0; i < g->framework_dirs.length; i += 1) {
- args.append("-iframework");
- args.append(g->framework_dirs.at(i));
- }
-
- if (g->libcpp_link_lib != nullptr) {
- const char *libcxx_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxx" OS_SEP "include",
- buf_ptr(g->zig_lib_dir)));
-
- const char *libcxxabi_include_path = buf_ptr(buf_sprintf("%s" OS_SEP "libcxxabi" OS_SEP "include",
- buf_ptr(g->zig_lib_dir)));
-
- args.append("-isystem");
- args.append(libcxx_include_path);
-
- args.append("-isystem");
- args.append(libcxxabi_include_path);
-
- if (target_abi_is_musl(g->zig_target->abi)) {
- args.append("-D_LIBCPP_HAS_MUSL_LIBC");
- }
- args.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
- args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
- }
-
- args.append("-target");
- args.append(buf_ptr(&g->llvm_triple_str));
-
- switch (source_kind) {
- case FileExtC:
- case FileExtCpp:
- case FileExtHeader:
- // According to Rich Felker libc headers are supposed to go before C language headers.
- // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics
- // and other compiler specific items.
- args.append("-isystem");
- args.append(buf_ptr(g->zig_c_headers_dir));
-
- for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
- const char *include_dir = g->libc_include_dir_list[i];
- args.append("-isystem");
- args.append(include_dir);
- }
-
- if (g->zig_target->llvm_cpu_name != nullptr) {
- args.append("-Xclang");
- args.append("-target-cpu");
- args.append("-Xclang");
- args.append(g->zig_target->llvm_cpu_name);
- }
- if (g->zig_target->llvm_cpu_features != nullptr) {
- // https://github.com/ziglang/zig/issues/5017
- SplitIterator it = memSplit(str(g->zig_target->llvm_cpu_features), str(","));
- Optional<Slice<uint8_t>> flag = SplitIterator_next(&it);
- while (flag.is_some) {
- args.append("-Xclang");
- args.append("-target-feature");
- args.append("-Xclang");
- args.append(buf_ptr(buf_create_from_slice(flag.value)));
- flag = SplitIterator_next(&it);
- }
- }
- if (translate_c) {
- // this gives us access to preprocessing entities, presumably at
- // the cost of performance
- args.append("-Xclang");
- args.append("-detailed-preprocessing-record");
- }
- if (out_dep_path != nullptr) {
- args.append("-MD");
- args.append("-MV");
- args.append("-MF");
- args.append(out_dep_path);
- }
- break;
- case FileExtAsm:
- case FileExtLLVMIr:
- case FileExtLLVMBitCode:
- case FileExtUnknown:
- break;
- }
- for (size_t i = 0; i < g->zig_target->llvm_cpu_features_asm_len; i += 1) {
- args.append(g->zig_target->llvm_cpu_features_asm_ptr[i]);
- }
-
- if (g->zig_target->os == OsFreestanding) {
- args.append("-ffreestanding");
- }
-
- // windows.h has files such as pshpack1.h which do #pragma packing, triggering a clang warning.
- // So for this target, we disable this warning.
- if (g->zig_target->os == OsWindows && target_abi_is_gnu(g->zig_target->abi)) {
- args.append("-Wno-pragma-pack");
- }
-
- if (!g->strip_debug_symbols) {
- args.append("-g");
- }
-
- if (codegen_have_frame_pointer(g)) {
- args.append("-fno-omit-frame-pointer");
- } else {
- args.append("-fomit-frame-pointer");
- }
-
- if (g->have_sanitize_c) {
- args.append("-fsanitize=undefined");
- args.append("-fsanitize-trap=undefined");
- }
-
- switch (g->build_mode) {
- case BuildModeDebug:
- // windows c runtime requires -D_DEBUG if using debug libraries
- args.append("-D_DEBUG");
- args.append("-Og");
-
- if (g->libc_link_lib != nullptr) {
- args.append("-fstack-protector-strong");
- args.append("--param");
- args.append("ssp-buffer-size=4");
- } else {
- args.append("-fno-stack-protector");
- }
- break;
- case BuildModeSafeRelease:
- // See the comment in the BuildModeFastRelease case for why we pass -O2 rather
- // than -O3 here.
- args.append("-O2");
- if (g->libc_link_lib != nullptr) {
- args.append("-D_FORTIFY_SOURCE=2");
- args.append("-fstack-protector-strong");
- args.append("--param");
- args.append("ssp-buffer-size=4");
- } else {
- args.append("-fno-stack-protector");
- }
- break;
- case BuildModeFastRelease:
- args.append("-DNDEBUG");
- // Here we pass -O2 rather than -O3 because, although we do the equivalent of
- // -O3 in Zig code, the justification for the difference here is that Zig
- // has better detection and prevention of undefined behavior, so -O3 is safer for
- // Zig code than it is for C code. Also, C programmers are used to their code
- // running in -O2 and thus the -O3 path has been tested less.
- args.append("-O2");
- args.append("-fno-stack-protector");
- break;
- case BuildModeSmallRelease:
- args.append("-DNDEBUG");
- args.append("-Os");
- args.append("-fno-stack-protector");
- break;
- }
-
- if (target_supports_fpic(g->zig_target) && g->have_pic) {
- args.append("-fPIC");
- }
-
- for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
- args.append(g->clang_argv[arg_i]);
- }
-
-}
-
-void codegen_translate_c(CodeGen *g, Buf *full_path) {
- Error err;
-
- Buf *src_basename = buf_alloc();
- Buf *src_dirname = buf_alloc();
- os_path_split(full_path, src_dirname, src_basename);
-
- Buf noextname = BUF_INIT;
- os_path_extname(src_basename, &noextname, nullptr);
-
- Buf *zig_basename = buf_sprintf("%s.zig", buf_ptr(&noextname));
-
- detect_libc(g);
-
- Buf cache_digest = BUF_INIT;
- buf_resize(&cache_digest, 0);
-
- CacheHash *cache_hash = nullptr;
- if (g->enable_cache) {
- if ((err = create_c_object_cache(g, &cache_hash, true))) {
- // Already printed error; verbose = true
- exit(1);
- }
- cache_file(cache_hash, full_path);
- // to distinguish from generating a C object
- cache_buf(cache_hash, buf_create_from_str("translate-c"));
-
- if ((err = cache_hit(cache_hash, &cache_digest))) {
- if (err != ErrorInvalidFormat) {
- fprintf(stderr, "unable to check cache: %s\n", err_str(err));
- exit(1);
- }
- }
- if (cache_hash->manifest_file_path != nullptr) {
- g->caches_to_release.append(cache_hash);
- }
- }
-
- if (g->enable_cache && buf_len(&cache_digest) != 0) {
- // cache hit
- Buf *cached_path = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s" OS_SEP "%s",
- buf_ptr(g->cache_dir), buf_ptr(&cache_digest), buf_ptr(zig_basename));
- fprintf(stdout, "%s\n", buf_ptr(cached_path));
- return;
- }
-
- // cache miss or cache disabled
- init(g);
-
- Buf *out_dep_path = nullptr;
- const char *out_dep_path_cstr = nullptr;
-
- if (g->enable_cache) {
- buf_alloc();// we can't know the digest until we do the C compiler invocation, so we
- // need a tmp filename.
- out_dep_path = buf_alloc();
- if ((err = get_tmp_filename(g, out_dep_path, buf_sprintf("%s.d", buf_ptr(zig_basename))))) {
- fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err));
- exit(1);
- }
- out_dep_path_cstr = buf_ptr(out_dep_path);
- }
-
- ZigList<const char *> clang_argv = {0};
- add_cc_args(g, clang_argv, out_dep_path_cstr, true, FileExtC);
-
- clang_argv.append(buf_ptr(full_path));
-
- if (g->verbose_cc) {
- fprintf(stderr, "clang");
- for (size_t i = 0; i < clang_argv.length; i += 1) {
- fprintf(stderr, " %s", clang_argv.at(i));
- }
- fprintf(stderr, "\n");
- }
-
- clang_argv.append(nullptr); // to make the [start...end] argument work
-
- const char *resources_path = buf_ptr(g->zig_c_headers_dir);
- Stage2ErrorMsg *errors_ptr;
- size_t errors_len;
- Stage2Ast *ast;
-
- err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
- &clang_argv.at(0), &clang_argv.last(), resources_path);
-
- if (err == ErrorCCompileErrors && errors_len > 0) {
- for (size_t i = 0; i < errors_len; i += 1) {
- Stage2ErrorMsg *clang_err = &errors_ptr[i];
-
- ErrorMsg *err_msg = err_msg_create_with_offset(
- clang_err->filename_ptr ?
- buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : nullptr,
- clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
- buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
- print_err_msg(err_msg, g->err_color);
- }
- exit(1);
- }
-
- if (err) {
- fprintf(stderr, "unable to parse C file: %s\n", err_str(err));
- exit(1);
- }
-
- if (!g->enable_cache) {
- stage2_render_ast(ast, stdout);
- return;
- }
-
- // add the files depended on to the cache system
- if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) {
- // Don't treat the absence of the .d file as a fatal error, the
- // compiler may not produce one eg. when compiling .s files
- if (err != ErrorFileNotFound) {
- fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err));
- exit(1);
- }
- }
- if (err != ErrorFileNotFound) {
- os_delete_file(out_dep_path);
- }
-
- if ((err = cache_final(cache_hash, &cache_digest))) {
- fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
- exit(1);
- }
-
- Buf *artifact_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s",
- buf_ptr(g->cache_dir), buf_ptr(&cache_digest));
-
- if ((err = os_make_path(artifact_dir))) {
- fprintf(stderr, "Unable to make dir: %s\n", err_str(err));
- exit(1);
- }
-
- Buf *cached_path = buf_sprintf("%s" OS_SEP "%s", buf_ptr(artifact_dir), buf_ptr(zig_basename));
-
- FILE *out_file = fopen(buf_ptr(cached_path), "wb");
- if (out_file == nullptr) {
- fprintf(stderr, "Unable to open output file: %s\n", strerror(errno));
- exit(1);
- }
- stage2_render_ast(ast, out_file);
- if (fclose(out_file) != 0) {
- fprintf(stderr, "Unable to write to output file: %s\n", strerror(errno));
- exit(1);
- }
- fprintf(stdout, "%s\n", buf_ptr(cached_path));
-}
-
static void update_test_functions_builtin_decl(CodeGen *g) {
Error err;
@@ -9875,49 +9150,46 @@ static void gen_root_source(CodeGen *g) {
assert(root_import_alias == g->root_import);
assert(g->root_out_name);
- assert(g->out_type != OutTypeUnknown);
-
- if (!g->is_dummy_so) {
- // Zig has lazy top level definitions. Here we semantically analyze the panic function.
- Buf *import_target_path;
- Buf full_path = BUF_INIT;
- ZigType *std_import;
- if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import,
- &import_target_path, &full_path)))
- {
- if (err == ErrorFileNotFound) {
- fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path));
- } else {
- fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err));
- }
- exit(1);
- }
- Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base,
- buf_create_from_str("builtin"));
- assert(builtin_tld != nullptr);
- resolve_top_level_decl(g, builtin_tld, nullptr, false);
- report_errors_and_maybe_exit(g);
- assert(builtin_tld->id == TldIdVar);
- TldVar *builtin_tld_var = (TldVar*)builtin_tld;
- ZigValue *builtin_val = builtin_tld_var->var->const_value;
- assert(builtin_val->type->id == ZigTypeIdMetaType);
- ZigType *builtin_type = builtin_val->data.x_type;
-
- Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base,
- buf_create_from_str("panic"));
- assert(panic_tld != nullptr);
- resolve_top_level_decl(g, panic_tld, nullptr, false);
- report_errors_and_maybe_exit(g);
- assert(panic_tld->id == TldIdVar);
- TldVar *panic_tld_var = (TldVar*)panic_tld;
- ZigValue *panic_fn_val = panic_tld_var->var->const_value;
- assert(panic_fn_val->type->id == ZigTypeIdFn);
- assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction);
- g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry;
- assert(g->panic_fn != nullptr);
+ // Zig has lazy top level definitions. Here we semantically analyze the panic function.
+ Buf *import_target_path;
+ Buf full_path = BUF_INIT;
+ ZigType *std_import;
+ if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import,
+ &import_target_path, &full_path)))
+ {
+ if (err == ErrorFileNotFound) {
+ fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path));
+ } else {
+ fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err));
+ }
+ exit(1);
}
+ Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base,
+ buf_create_from_str("builtin"));
+ assert(builtin_tld != nullptr);
+ resolve_top_level_decl(g, builtin_tld, nullptr, false);
+ report_errors_and_maybe_exit(g);
+ assert(builtin_tld->id == TldIdVar);
+ TldVar *builtin_tld_var = (TldVar*)builtin_tld;
+ ZigValue *builtin_val = builtin_tld_var->var->const_value;
+ assert(builtin_val->type->id == ZigTypeIdMetaType);
+ ZigType *builtin_type = builtin_val->data.x_type;
+
+ Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base,
+ buf_create_from_str("panic"));
+ assert(panic_tld != nullptr);
+ resolve_top_level_decl(g, panic_tld, nullptr, false);
+ report_errors_and_maybe_exit(g);
+ assert(panic_tld->id == TldIdVar);
+ TldVar *panic_tld_var = (TldVar*)panic_tld;
+ ZigValue *panic_fn_val = panic_tld_var->var->const_value;
+ assert(panic_fn_val->type->id == ZigTypeIdFn);
+ assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction);
+ g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry;
+ assert(g->panic_fn != nullptr);
+
if (!g->error_during_imports) {
semantic_analyze(g);
}
@@ -9934,781 +9206,6 @@ static void gen_root_source(CodeGen *g) {
}
-static void print_zig_cc_cmd(ZigList<const char *> *args) {
- for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) {
- const char *space_str = (arg_i == 0) ? "" : " ";
- fprintf(stderr, "%s%s", space_str, args->at(arg_i));
- }
- fprintf(stderr, "\n");
-}
-
-// Caller should delete the file when done or rename it into a better location.
-static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix) {
- Error err;
- buf_resize(out, 0);
- os_path_join(g->cache_dir, buf_create_from_str("tmp" OS_SEP), out);
- if ((err = os_make_path(out))) {
- return err;
- }
- const char base64[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
- assert(array_length(base64) == 64 + 1);
- for (size_t i = 0; i < 12; i += 1) {
- buf_append_char(out, base64[rand() % 64]);
- }
- buf_append_char(out, '-');
- buf_append_buf(out, suffix);
- return ErrorNone;
-}
-
-Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose) {
- Error err;
- CacheHash *cache_hash = heap::c_allocator.create<CacheHash>();
- Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(g->cache_dir));
- cache_init(cache_hash, manifest_dir);
-
- Buf *compiler_id;
- if ((err = get_compiler_id(&compiler_id))) {
- if (verbose) {
- fprintf(stderr, "unable to get compiler id: %s\n", err_str(err));
- }
- return err;
- }
- cache_buf(cache_hash, compiler_id);
- cache_int(cache_hash, g->err_color);
- cache_list_of_str(cache_hash, g->framework_dirs.items, g->framework_dirs.length);
- cache_bool(cache_hash, g->libcpp_link_lib != nullptr);
- cache_buf(cache_hash, g->zig_lib_dir);
- cache_buf(cache_hash, g->zig_c_headers_dir);
- cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);
- cache_int(cache_hash, g->zig_target->is_native_os);
- cache_int(cache_hash, g->zig_target->is_native_cpu);
- cache_int(cache_hash, g->zig_target->arch);
- cache_int(cache_hash, g->zig_target->vendor);
- cache_int(cache_hash, g->zig_target->os);
- cache_int(cache_hash, g->zig_target->abi);
- cache_bool(cache_hash, g->strip_debug_symbols);
- cache_int(cache_hash, g->build_mode);
- cache_bool(cache_hash, g->have_pic);
- cache_bool(cache_hash, g->have_sanitize_c);
- cache_bool(cache_hash, want_valgrind_support(g));
- cache_bool(cache_hash, g->function_sections);
- cache_int(cache_hash, g->code_model);
- cache_bool(cache_hash, codegen_have_frame_pointer(g));
- cache_bool(cache_hash, g->libc_link_lib);
- if (g->zig_target->cache_hash != nullptr) {
- cache_mem(cache_hash, g->zig_target->cache_hash, g->zig_target->cache_hash_len);
- }
-
- for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
- cache_str(cache_hash, g->clang_argv[arg_i]);
- }
-
- *out_cache_hash = cache_hash;
- return ErrorNone;
-}
-
-static bool need_llvm_module(CodeGen *g) {
- return buf_len(&g->main_pkg->root_src_path) != 0;
-}
-
-// before gen_c_objects
-static bool main_output_dir_is_just_one_c_object_pre(CodeGen *g) {
- return g->enable_cache && g->c_source_files.length == 1 && !need_llvm_module(g) &&
- g->out_type == OutTypeObj && g->link_objects.length == 0;
-}
-
-// after gen_c_objects
-static bool main_output_dir_is_just_one_c_object_post(CodeGen *g) {
- return g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g) && g->out_type == OutTypeObj;
-}
-
-// returns true if it was a cache miss
-static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
- Error err;
-
- Buf *artifact_dir;
- Buf *o_final_path;
-
- Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(g->cache_dir));
-
- Buf *c_source_file = buf_create_from_str(c_file->source_path);
- Buf *c_source_basename = buf_alloc();
- os_path_split(c_source_file, nullptr, c_source_basename);
-
- Stage2ProgressNode *child_prog_node = stage2_progress_start(g->sub_progress_node, buf_ptr(c_source_basename),
- buf_len(c_source_basename), 0);
-
- Buf *final_o_basename = buf_alloc();
- if (c_file->preprocessor_only_basename == nullptr) {
- // We special case when doing build-obj for just one C file
- if (main_output_dir_is_just_one_c_object_pre(g)) {
- buf_init_from_buf(final_o_basename, g->root_out_name);
- } else {
- os_path_extname(c_source_basename, final_o_basename, nullptr);
- }
- buf_append_str(final_o_basename, target_o_file_ext(g->zig_target));
- } else {
- buf_init_from_str(final_o_basename, c_file->preprocessor_only_basename);
- }
-
- CacheHash *cache_hash;
- if ((err = create_c_object_cache(g, &cache_hash, true))) {
- // Already printed error; verbose = true
- exit(1);
- }
- cache_file(cache_hash, c_source_file);
-
- // Note: not directory args, just args that always have a file next
- static const char *file_args[] = {
- "-include",
- };
- for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) {
- const char *arg = c_file->args.at(arg_i);
- cache_str(cache_hash, arg);
- for (size_t file_arg_i = 0; file_arg_i < array_length(file_args); file_arg_i += 1) {
- if (strcmp(arg, file_args[file_arg_i]) == 0 && arg_i + 1 < c_file->args.length) {
- arg_i += 1;
- cache_file(cache_hash, buf_create_from_str(c_file->args.at(arg_i)));
- }
- }
- }
-
- Buf digest = BUF_INIT;
- buf_resize(&digest, 0);
- if ((err = cache_hit(cache_hash, &digest))) {
- if (err != ErrorInvalidFormat) {
- if (err == ErrorCacheUnavailable) {
- // already printed error
- } else {
- fprintf(stderr, "unable to check cache when compiling C object: %s\n", err_str(err));
- }
- exit(1);
- }
- }
- bool is_cache_miss = g->disable_c_depfile || (buf_len(&digest) == 0);
- if (is_cache_miss) {
- // we can't know the digest until we do the C compiler invocation, so we
- // need a tmp filename.
- Buf *out_obj_path = buf_alloc();
- if ((err = get_tmp_filename(g, out_obj_path, final_o_basename))) {
- fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err));
- exit(1);
- }
-
- Termination term;
- ZigList<const char *> args = {};
- args.append(buf_ptr(self_exe_path));
- args.append("clang");
-
- if (c_file->preprocessor_only_basename == nullptr) {
- args.append("-c");
- }
-
- Buf *out_dep_path = g->disable_c_depfile ? nullptr : buf_sprintf("%s.d", buf_ptr(out_obj_path));
- const char *out_dep_path_cstr = (out_dep_path == nullptr) ? nullptr : buf_ptr(out_dep_path);
- FileExt ext = classify_file_ext(buf_ptr(c_source_basename), buf_len(c_source_basename));
- add_cc_args(g, args, out_dep_path_cstr, false, ext);
-
- args.append("-o");
- args.append(buf_ptr(out_obj_path));
-
- args.append(buf_ptr(c_source_file));
-
- for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) {
- args.append(c_file->args.at(arg_i));
- }
-
- if (g->verbose_cc) {
- print_zig_cc_cmd(&args);
- }
- os_spawn_process(args, &term);
- if (term.how != TerminationIdClean || term.code != 0) {
- fprintf(stderr, "\nThe following command failed:\n");
- print_zig_cc_cmd(&args);
- exit(1);
- }
-
- if (out_dep_path != nullptr) {
- // add the files depended on to the cache system
- if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) {
- // Don't treat the absence of the .d file as a fatal error, the
- // compiler may not produce one eg. when compiling .s files
- if (err != ErrorFileNotFound) {
- fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err));
- exit(1);
- }
- }
- if (err != ErrorFileNotFound) {
- os_delete_file(out_dep_path);
- }
-
- if ((err = cache_final(cache_hash, &digest))) {
- fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
- exit(1);
- }
- }
- artifact_dir = buf_alloc();
- os_path_join(o_dir, &digest, artifact_dir);
- if ((err = os_make_path(artifact_dir))) {
- fprintf(stderr, "Unable to create output directory '%s': %s",
- buf_ptr(artifact_dir), err_str(err));
- exit(1);
- }
- o_final_path = buf_alloc();
- os_path_join(artifact_dir, final_o_basename, o_final_path);
- if ((err = os_rename(out_obj_path, o_final_path))) {
- fprintf(stderr, "Unable to rename object: %s\n", err_str(err));
- exit(1);
- }
- } else {
- // cache hit
- artifact_dir = buf_alloc();
- os_path_join(o_dir, &digest, artifact_dir);
- o_final_path = buf_alloc();
- os_path_join(artifact_dir, final_o_basename, o_final_path);
- }
-
- g->c_artifact_dir = artifact_dir;
- g->link_objects.append(o_final_path);
- g->caches_to_release.append(cache_hash);
-
- stage2_progress_end(child_prog_node);
-}
-
-// returns true if we had any cache misses
-static void gen_c_objects(CodeGen *g) {
- Error err;
-
- if (g->c_source_files.length == 0)
- return;
-
- Buf *self_exe_path = buf_alloc();
- if ((err = os_self_exe_path(self_exe_path))) {
- fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err));
- exit(1);
- }
-
- codegen_add_time_event(g, "Compile C Objects");
- const char *c_prog_name = "Compile C Objects";
- codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, c_prog_name, strlen(c_prog_name),
- g->c_source_files.length));
-
- for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) {
- CFile *c_file = g->c_source_files.at(c_file_i);
- gen_c_object(g, self_exe_path, c_file);
- }
-}
-
-void codegen_add_object(CodeGen *g, Buf *object_path) {
- g->link_objects.append(object_path);
-}
-
-// Must be coordinated with with CIntType enum
-static const char *c_int_type_names[] = {
- "short",
- "unsigned short",
- "int",
- "unsigned int",
- "long",
- "unsigned long",
- "long long",
- "unsigned long long",
-};
-
-struct GenH {
- ZigList<ZigType *> types_to_declare;
-};
-
-static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_entry) {
- if (type_entry->gen_h_loop_flag)
- return;
- type_entry->gen_h_loop_flag = true;
-
- switch (type_entry->id) {
- case ZigTypeIdInvalid:
- case ZigTypeIdMetaType:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdEnumLiteral:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- case ZigTypeIdBoundFn:
- case ZigTypeIdErrorUnion:
- case ZigTypeIdErrorSet:
- case ZigTypeIdFnFrame:
- case ZigTypeIdAnyFrame:
- zig_unreachable();
- case ZigTypeIdVoid:
- case ZigTypeIdUnreachable:
- return;
- case ZigTypeIdBool:
- g->c_want_stdbool = true;
- return;
- case ZigTypeIdInt:
- g->c_want_stdint = true;
- return;
- case ZigTypeIdFloat:
- return;
- case ZigTypeIdOpaque:
- gen_h->types_to_declare.append(type_entry);
- return;
- case ZigTypeIdStruct:
- if(type_entry->data.structure.layout == ContainerLayoutExtern) {
- for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
- TypeStructField *field = type_entry->data.structure.fields[i];
- prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
- }
- }
- gen_h->types_to_declare.append(type_entry);
- return;
- case ZigTypeIdUnion:
- for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
- TypeUnionField *field = &type_entry->data.unionation.fields[i];
- prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
- }
- gen_h->types_to_declare.append(type_entry);
- return;
- case ZigTypeIdEnum:
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.enumeration.tag_int_type);
- gen_h->types_to_declare.append(type_entry);
- return;
- case ZigTypeIdPointer:
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.pointer.child_type);
- return;
- case ZigTypeIdArray:
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type);
- return;
- case ZigTypeIdVector:
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type);
- return;
- case ZigTypeIdOptional:
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type);
- return;
- case ZigTypeIdFn:
- for (size_t i = 0; i < type_entry->data.fn.fn_type_id.param_count; i += 1) {
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.param_info[i].type);
- }
- prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.return_type);
- return;
- }
-}
-
-static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_buf) {
- assert(type_entry);
-
- for (size_t i = 0; i < array_length(c_int_type_names); i += 1) {
- if (type_entry == g->builtin_types.entry_c_int[i]) {
- buf_init_from_str(out_buf, c_int_type_names[i]);
- return;
- }
- }
- if (type_entry == g->builtin_types.entry_c_longdouble) {
- buf_init_from_str(out_buf, "long double");
- return;
- }
- if (type_entry == g->builtin_types.entry_c_void) {
- buf_init_from_str(out_buf, "void");
- return;
- }
- if (type_entry == g->builtin_types.entry_isize) {
- g->c_want_stdint = true;
- buf_init_from_str(out_buf, "intptr_t");
- return;
- }
- if (type_entry == g->builtin_types.entry_usize) {
- g->c_want_stdint = true;
- buf_init_from_str(out_buf, "uintptr_t");
- return;
- }
-
- prepend_c_type_to_decl_list(g, gen_h, type_entry);
-
- switch (type_entry->id) {
- case ZigTypeIdVoid:
- buf_init_from_str(out_buf, "void");
- break;
- case ZigTypeIdBool:
- buf_init_from_str(out_buf, "bool");
- break;
- case ZigTypeIdUnreachable:
- buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void");
- break;
- case ZigTypeIdFloat:
- switch (type_entry->data.floating.bit_count) {
- case 32:
- buf_init_from_str(out_buf, "float");
- break;
- case 64:
- buf_init_from_str(out_buf, "double");
- break;
- case 80:
- buf_init_from_str(out_buf, "__float80");
- break;
- case 128:
- buf_init_from_str(out_buf, "__float128");
- break;
- default:
- zig_unreachable();
- }
- break;
- case ZigTypeIdInt:
- buf_resize(out_buf, 0);
- buf_appendf(out_buf, "%sint%" PRIu32 "_t",
- type_entry->data.integral.is_signed ? "" : "u",
- type_entry->data.integral.bit_count);
- break;
- case ZigTypeIdPointer:
- {
- Buf child_buf = BUF_INIT;
- ZigType *child_type = type_entry->data.pointer.child_type;
- get_c_type(g, gen_h, child_type, &child_buf);
-
- const char *const_str = type_entry->data.pointer.is_const ? "const " : "";
- buf_resize(out_buf, 0);
- buf_appendf(out_buf, "%s%s *", const_str, buf_ptr(&child_buf));
- break;
- }
- case ZigTypeIdOptional:
- {
- ZigType *child_type = type_entry->data.maybe.child_type;
- if (!type_has_bits(g, child_type)) {
- buf_init_from_str(out_buf, "bool");
- return;
- } else if (type_is_nonnull_ptr(g, child_type)) {
- return get_c_type(g, gen_h, child_type, out_buf);
- } else {
- zig_unreachable();
- }
- }
- case ZigTypeIdStruct:
- case ZigTypeIdOpaque:
- {
- buf_init_from_str(out_buf, "struct ");
- buf_append_buf(out_buf, type_h_name(type_entry));
- return;
- }
- case ZigTypeIdUnion:
- {
- buf_init_from_str(out_buf, "union ");
- buf_append_buf(out_buf, type_h_name(type_entry));
- return;
- }
- case ZigTypeIdEnum:
- {
- buf_init_from_str(out_buf, "enum ");
- buf_append_buf(out_buf, type_h_name(type_entry));
- return;
- }
- case ZigTypeIdArray:
- {
- ZigTypeArray *array_data = &type_entry->data.array;
-
- Buf *child_buf = buf_alloc();
- get_c_type(g, gen_h, array_data->child_type, child_buf);
-
- buf_resize(out_buf, 0);
- buf_appendf(out_buf, "%s", buf_ptr(child_buf));
- return;
- }
- case ZigTypeIdVector:
- zig_panic("TODO implement get_c_type for vector types");
- case ZigTypeIdErrorUnion:
- case ZigTypeIdErrorSet:
- case ZigTypeIdFn:
- zig_panic("TODO implement get_c_type for more types");
- case ZigTypeIdInvalid:
- case ZigTypeIdMetaType:
- case ZigTypeIdBoundFn:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdEnumLiteral:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- case ZigTypeIdFnFrame:
- case ZigTypeIdAnyFrame:
- zig_unreachable();
- }
-}
-
-static const char *preprocessor_alphabet1 = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-static const char *preprocessor_alphabet2 = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-static bool need_to_preprocessor_mangle(Buf *src) {
- for (size_t i = 0; i < buf_len(src); i += 1) {
- const char *alphabet = (i == 0) ? preprocessor_alphabet1 : preprocessor_alphabet2;
- uint8_t byte = buf_ptr(src)[i];
- if (strchr(alphabet, byte) == nullptr) {
- return true;
- }
- }
- return false;
-}
-
-static Buf *preprocessor_mangle(Buf *src) {
- if (!need_to_preprocessor_mangle(src)) {
- return buf_create_from_buf(src);
- }
- Buf *result = buf_alloc();
- for (size_t i = 0; i < buf_len(src); i += 1) {
- const char *alphabet = (i == 0) ? preprocessor_alphabet1 : preprocessor_alphabet2;
- uint8_t byte = buf_ptr(src)[i];
- if (strchr(alphabet, byte) == nullptr) {
- // perform escape
- buf_appendf(result, "_%02x_", byte);
- } else {
- buf_append_char(result, byte);
- }
- }
- return result;
-}
-
-static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) {
- for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {
- ZigType *type_entry = gen_h->types_to_declare.at(type_i);
- switch (type_entry->id) {
- case ZigTypeIdInvalid:
- case ZigTypeIdMetaType:
- case ZigTypeIdVoid:
- case ZigTypeIdBool:
- case ZigTypeIdUnreachable:
- case ZigTypeIdInt:
- case ZigTypeIdFloat:
- case ZigTypeIdPointer:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdEnumLiteral:
- case ZigTypeIdArray:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- case ZigTypeIdErrorUnion:
- case ZigTypeIdErrorSet:
- case ZigTypeIdBoundFn:
- case ZigTypeIdOptional:
- case ZigTypeIdFn:
- case ZigTypeIdVector:
- case ZigTypeIdFnFrame:
- case ZigTypeIdAnyFrame:
- zig_unreachable();
-
- case ZigTypeIdEnum:
- if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
- buf_appendf(out_buf, "enum %s {\n", buf_ptr(type_h_name(type_entry)));
- for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) {
- TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
- Buf *value_buf = buf_alloc();
- bigint_append_buf(value_buf, &enum_field->value, 10);
- buf_appendf(out_buf, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf));
- if (field_i != type_entry->data.enumeration.src_field_count - 1) {
- buf_appendf(out_buf, ",");
- }
- buf_appendf(out_buf, "\n");
- }
- buf_appendf(out_buf, "};\n\n");
- } else {
- buf_appendf(out_buf, "enum %s;\n\n", buf_ptr(type_h_name(type_entry)));
- }
- break;
- case ZigTypeIdStruct:
- if (type_entry->data.structure.layout == ContainerLayoutExtern) {
- buf_appendf(out_buf, "struct %s {\n", buf_ptr(type_h_name(type_entry)));
- for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
- TypeStructField *struct_field = type_entry->data.structure.fields[field_i];
-
- Buf *type_name_buf = buf_alloc();
- get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
-
- if (struct_field->type_entry->id == ZigTypeIdArray) {
- buf_appendf(out_buf, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),
- buf_ptr(struct_field->name),
- struct_field->type_entry->data.array.len);
- } else {
- buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));
- }
-
- }
- buf_appendf(out_buf, "};\n\n");
- } else {
- buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry)));
- }
- break;
- case ZigTypeIdUnion:
- if (type_entry->data.unionation.layout == ContainerLayoutExtern) {
- buf_appendf(out_buf, "union %s {\n", buf_ptr(type_h_name(type_entry)));
- for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {
- TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
-
- Buf *type_name_buf = buf_alloc();
- get_c_type(g, gen_h, union_field->type_entry, type_name_buf);
- buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name));
- }
- buf_appendf(out_buf, "};\n\n");
- } else {
- buf_appendf(out_buf, "union %s;\n\n", buf_ptr(type_h_name(type_entry)));
- }
- break;
- case ZigTypeIdOpaque:
- buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry)));
- break;
- }
- }
-}
-
-static void gen_h_file_functions(CodeGen* g, GenH* gen_h, Buf* out_buf, Buf* export_macro) {
- for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {
- ZigFn *fn_table_entry = g->fn_defs.at(fn_def_i);
-
- if (fn_table_entry->export_list.length == 0)
- continue;
-
- FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
-
- Buf return_type_c = BUF_INIT;
- get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c);
-
- Buf *symbol_name;
- if (fn_table_entry->export_list.length == 0) {
- symbol_name = &fn_table_entry->symbol_name;
- } else {
- GlobalExport *fn_export = &fn_table_entry->export_list.items[0];
- symbol_name = &fn_export->name;
- }
-
- if (export_macro != nullptr) {
- buf_appendf(out_buf, "%s %s %s(",
- buf_ptr(export_macro),
- buf_ptr(&return_type_c),
- buf_ptr(symbol_name));
- } else {
- buf_appendf(out_buf, "%s %s(",
- buf_ptr(&return_type_c),
- buf_ptr(symbol_name));
- }
-
- Buf param_type_c = BUF_INIT;
- if (fn_type_id->param_count > 0) {
- for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {
- FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i];
- AstNode *param_decl_node = get_param_decl_node(fn_table_entry, param_i);
- Buf *param_name = param_decl_node->data.param_decl.name;
-
- const char *comma_str = (param_i == 0) ? "" : ", ";
- const char *restrict_str = param_info->is_noalias ? "restrict" : "";
- get_c_type(g, gen_h, param_info->type, &param_type_c);
-
- if (param_info->type->id == ZigTypeIdArray) {
- // Arrays decay to pointers
- buf_appendf(out_buf, "%s%s%s %s[]", comma_str, buf_ptr(&param_type_c),
- restrict_str, buf_ptr(param_name));
- } else {
- buf_appendf(out_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c),
- restrict_str, buf_ptr(param_name));
- }
- }
- buf_appendf(out_buf, ")");
- } else {
- buf_appendf(out_buf, "void)");
- }
-
- buf_appendf(out_buf, ";\n");
- }
-}
-
-static void gen_h_file_variables(CodeGen* g, GenH* gen_h, Buf* h_buf, Buf* export_macro) {
- for (size_t exp_var_i = 0; exp_var_i < g->global_vars.length; exp_var_i += 1) {
- ZigVar* var = g->global_vars.at(exp_var_i)->var;
- if (var->export_list.length == 0)
- continue;
-
- Buf var_type_c = BUF_INIT;
- get_c_type(g, gen_h, var->var_type, &var_type_c);
-
- if (export_macro != nullptr) {
- buf_appendf(h_buf, "extern %s %s %s;\n",
- buf_ptr(export_macro),
- buf_ptr(&var_type_c),
- var->name);
- } else {
- buf_appendf(h_buf, "extern %s %s;\n",
- buf_ptr(&var_type_c),
- var->name);
- }
- }
-}
-
-static void gen_h_file(CodeGen *g) {
- GenH gen_h_data = {0};
- GenH *gen_h = &gen_h_data;
-
- assert(!g->is_test_build);
- assert(!g->disable_gen_h);
-
- Buf *out_h_path = buf_sprintf("%s" OS_SEP "%s.h", buf_ptr(g->output_dir), buf_ptr(g->root_out_name));
-
- FILE *out_h = fopen(buf_ptr(out_h_path), "wb");
- if (!out_h)
- zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno));
-
- Buf *export_macro = nullptr;
- if (g->is_dynamic) {
- export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)));
- buf_upcase(export_macro);
- }
-
- Buf fns_buf = BUF_INIT;
- buf_resize(&fns_buf, 0);
- gen_h_file_functions(g, gen_h, &fns_buf, export_macro);
-
- Buf vars_buf = BUF_INIT;
- buf_resize(&vars_buf, 0);
- gen_h_file_variables(g, gen_h, &vars_buf, export_macro);
-
- // Types will be populated by exported functions and variables so it has to run last.
- Buf types_buf = BUF_INIT;
- buf_resize(&types_buf, 0);
- gen_h_file_types(g, gen_h, &types_buf);
-
- Buf *ifdef_dance_name = preprocessor_mangle(buf_sprintf("%s_H", buf_ptr(g->root_out_name)));
- buf_upcase(ifdef_dance_name);
-
- fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name));
- fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name));
-
- if (g->c_want_stdbool)
- fprintf(out_h, "#include <stdbool.h>\n");
- if (g->c_want_stdint)
- fprintf(out_h, "#include <stdint.h>\n");
-
- fprintf(out_h, "\n");
-
- if (g->is_dynamic) {
- fprintf(out_h, "#if defined(_WIN32)\n");
- fprintf(out_h, "#define %s __declspec(dllimport)\n", buf_ptr(export_macro));
- fprintf(out_h, "#else\n");
- fprintf(out_h, "#define %s __attribute__((visibility (\"default\")))\n",
- buf_ptr(export_macro));
- fprintf(out_h, "#endif\n");
- fprintf(out_h, "\n");
- }
-
- fprintf(out_h, "#ifdef __cplusplus\n");
- fprintf(out_h, "extern \"C\" {\n");
- fprintf(out_h, "#endif\n");
- fprintf(out_h, "\n");
-
- fprintf(out_h, "%s", buf_ptr(&types_buf));
- fprintf(out_h, "%s\n", buf_ptr(&fns_buf));
- fprintf(out_h, "%s\n", buf_ptr(&vars_buf));
-
- fprintf(out_h, "#ifdef __cplusplus\n");
- fprintf(out_h, "} // extern \"C\"\n");
- fprintf(out_h, "#endif\n\n");
-
- fprintf(out_h, "#endif // %s\n", buf_ptr(ifdef_dance_name));
-
- if (fclose(out_h))
- zig_panic("unable to close h file: %s", strerror(errno));
-}
-
void codegen_print_timing_report(CodeGen *g, FILE *f) {
double start_time = g->timing_events.at(0).time;
double end_time = g->timing_events.last().time;
@@ -10733,174 +9230,14 @@ void codegen_add_time_event(CodeGen *g, const char *name) {
g->timing_events.append({seconds, name});
}
-static void add_cache_pkg(CodeGen *g, CacheHash *ch, ZigPackage *pkg) {
- if (buf_len(&pkg->root_src_path) == 0)
- return;
- pkg->added_to_cache = true;
-
- Buf *rel_full_path = buf_alloc();
- os_path_join(&pkg->root_src_dir, &pkg->root_src_path, rel_full_path);
- cache_file(ch, rel_full_path);
-
- auto it = pkg->package_table.entry_iterator();
- for (;;) {
- auto *entry = it.next();
- if (!entry)
- break;
-
- if (!pkg->added_to_cache) {
- cache_buf(ch, entry->key);
- add_cache_pkg(g, ch, entry->value);
- }
- }
-}
-
-// Called before init()
-// is_cache_hit takes into account gen_c_objects
-static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
- Error err;
-
- Buf *compiler_id;
- if ((err = get_compiler_id(&compiler_id)))
- return err;
-
- CacheHash *ch = &g->cache_hash;
- cache_init(ch, manifest_dir);
-
- add_cache_pkg(g, ch, g->main_pkg);
- if (g->linker_script != nullptr) {
- cache_file(ch, buf_create_from_str(g->linker_script));
- }
- cache_buf(ch, compiler_id);
- cache_buf(ch, g->root_out_name);
- cache_buf(ch, g->zig_lib_dir);
- cache_buf(ch, g->zig_std_dir);
- cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length);
- cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length);
- cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length);
- cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length);
- cache_int(ch, g->build_mode);
- cache_int(ch, g->out_type);
- cache_bool(ch, g->zig_target->is_native_os);
- cache_bool(ch, g->zig_target->is_native_cpu);
- cache_int(ch, g->zig_target->arch);
- cache_int(ch, g->zig_target->vendor);
- cache_int(ch, g->zig_target->os);
- cache_int(ch, g->zig_target->abi);
- if (g->zig_target->cache_hash != nullptr) {
- cache_mem(ch, g->zig_target->cache_hash, g->zig_target->cache_hash_len);
- }
- if (g->zig_target->glibc_or_darwin_version != nullptr) {
- cache_int(ch, g->zig_target->glibc_or_darwin_version->major);
- cache_int(ch, g->zig_target->glibc_or_darwin_version->minor);
- cache_int(ch, g->zig_target->glibc_or_darwin_version->patch);
- }
- if (g->zig_target->dynamic_linker != nullptr) {
- cache_str(ch, g->zig_target->dynamic_linker);
- }
- cache_int(ch, detect_subsystem(g));
- cache_bool(ch, g->strip_debug_symbols);
- cache_bool(ch, g->is_test_build);
- if (g->is_test_build) {
- cache_buf_opt(ch, g->test_filter);
- cache_buf_opt(ch, g->test_name_prefix);
- cache_bool(ch, g->test_is_evented);
- }
- cache_bool(ch, g->link_eh_frame_hdr);
- cache_bool(ch, g->is_single_threaded);
- cache_bool(ch, g->linker_rdynamic);
- cache_bool(ch, g->each_lib_rpath);
- cache_bool(ch, g->disable_gen_h);
- cache_bool(ch, g->bundle_compiler_rt);
- cache_bool(ch, want_valgrind_support(g));
- cache_bool(ch, g->have_pic);
- cache_bool(ch, g->have_dynamic_link);
- cache_bool(ch, g->have_stack_probing);
- cache_bool(ch, g->have_sanitize_c);
- cache_bool(ch, g->is_dummy_so);
- cache_bool(ch, g->function_sections);
- cache_bool(ch, g->enable_dump_analysis);
- cache_bool(ch, g->enable_doc_generation);
- cache_bool(ch, g->emit_bin);
- cache_bool(ch, g->emit_llvm_ir);
- cache_bool(ch, g->emit_asm);
- cache_bool(ch, g->is_versioned);
- cache_usize(ch, g->version_major);
- cache_usize(ch, g->version_minor);
- cache_usize(ch, g->version_patch);
- cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len);
- cache_list_of_str(ch, g->clang_argv, g->clang_argv_len);
- cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
- cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
- if (g->libc) {
- cache_slice(ch, Slice<const char>{g->libc->include_dir, g->libc->include_dir_len});
- cache_slice(ch, Slice<const char>{g->libc->sys_include_dir, g->libc->sys_include_dir_len});
- cache_slice(ch, Slice<const char>{g->libc->crt_dir, g->libc->crt_dir_len});
- cache_slice(ch, Slice<const char>{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len});
- cache_slice(ch, Slice<const char>{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len});
- }
- cache_buf_opt(ch, g->version_script_path);
- cache_buf_opt(ch, g->override_soname);
- cache_buf_opt(ch, g->linker_optimization);
- cache_int(ch, g->linker_gc_sections);
- cache_int(ch, g->linker_allow_shlib_undefined);
- cache_int(ch, g->linker_bind_global_refs_locally);
- cache_bool(ch, g->linker_z_nodelete);
- cache_bool(ch, g->linker_z_defs);
- cache_usize(ch, g->stack_size_override);
-
- // gen_c_objects appends objects to g->link_objects which we want to include in the hash
- gen_c_objects(g);
- cache_list_of_file(ch, g->link_objects.items, g->link_objects.length);
-
- buf_resize(digest, 0);
- if ((err = cache_hit(ch, digest))) {
- if (err != ErrorInvalidFormat)
- return err;
- }
-
- if (ch->manifest_file_path != nullptr) {
- g->caches_to_release.append(ch);
- }
-
- return ErrorNone;
-}
-
static void resolve_out_paths(CodeGen *g) {
assert(g->output_dir != nullptr);
assert(g->root_out_name != nullptr);
if (g->emit_bin) {
- Buf *out_basename = buf_create_from_buf(g->root_out_name);
Buf *o_basename = buf_create_from_buf(g->root_out_name);
- switch (g->out_type) {
- case OutTypeUnknown:
- zig_unreachable();
- case OutTypeObj:
- if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&
- buf_eql_buf(o_basename, out_basename))
- {
- // make it not collide with main output object
- buf_append_str(o_basename, ".root");
- }
- buf_append_str(o_basename, target_o_file_ext(g->zig_target));
- buf_append_str(out_basename, target_o_file_ext(g->zig_target));
- break;
- case OutTypeExe:
- buf_append_str(o_basename, target_o_file_ext(g->zig_target));
- buf_append_str(out_basename, target_exe_file_ext(g->zig_target));
- break;
- case OutTypeLib:
- buf_append_str(o_basename, target_o_file_ext(g->zig_target));
- buf_resize(out_basename, 0);
- buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
- buf_append_buf(out_basename, g->root_out_name);
- buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, g->is_versioned,
- g->version_major, g->version_minor, g->version_patch));
- break;
- }
+ buf_append_str(o_basename, target_o_file_ext(g->zig_target));
os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
- os_path_join(g->output_dir, out_basename, &g->bin_file_output_path);
}
if (g->emit_asm) {
Buf *asm_basename = buf_create_from_buf(g->root_out_name);
@@ -10971,144 +9308,46 @@ static void output_type_information(CodeGen *g) {
}
}
-static void init_output_dir(CodeGen *g, Buf *digest) {
- if (main_output_dir_is_just_one_c_object_post(g)) {
- g->output_dir = buf_alloc();
- os_path_dirname(g->link_objects.at(0), g->output_dir);
- } else {
- g->output_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s",
- buf_ptr(g->cache_dir), buf_ptr(digest));
- }
-}
-
-void codegen_build_and_link(CodeGen *g) {
- Error err;
- assert(g->out_type != OutTypeUnknown);
-
- if (!g->enable_cache) {
- if (g->output_dir == nullptr) {
- g->output_dir = buf_create_from_str(".");
- } else if ((err = os_make_path(g->output_dir))) {
- fprintf(stderr, "Unable to create output directory: %s\n", err_str(err));
- exit(1);
- }
- }
+void codegen_build_object(CodeGen *g) {
+ assert(g->output_dir != nullptr);
- g->have_dynamic_link = detect_dynamic_link(g);
- g->have_pic = detect_pic(g);
- g->is_single_threaded = detect_single_threaded(g);
g->have_err_ret_tracing = detect_err_ret_tracing(g);
- g->have_sanitize_c = detect_sanitize_c(g);
- detect_libc(g);
-
- Buf digest = BUF_INIT;
- if (g->enable_cache) {
- Buf *manifest_dir = buf_alloc();
- os_path_join(g->cache_dir, buf_create_from_str(CACHE_HASH_SUBDIR), manifest_dir);
-
- if ((err = check_cache(g, manifest_dir, &digest))) {
- if (err == ErrorCacheUnavailable) {
- // message already printed
- } else if (err == ErrorNotDir) {
- fprintf(stderr, "Unable to check cache: %s is not a directory\n",
- buf_ptr(manifest_dir));
- } else {
- fprintf(stderr, "Unable to check cache: %s: %s\n", buf_ptr(manifest_dir), err_str(err));
- }
- exit(1);
- }
- } else {
- // There is a call to this in check_cache
- gen_c_objects(g);
- }
-
- if (g->enable_cache && buf_len(&digest) != 0) {
- init_output_dir(g, &digest);
- resolve_out_paths(g);
- } else {
- if (need_llvm_module(g)) {
- init(g);
-
- codegen_add_time_event(g, "Semantic Analysis");
- const char *progress_name = "Semantic Analysis";
- codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
- progress_name, strlen(progress_name), 0));
-
- gen_root_source(g);
- }
- if (g->enable_cache) {
- if (buf_len(&digest) == 0) {
- if ((err = cache_final(&g->cache_hash, &digest))) {
- fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
- exit(1);
- }
- }
- init_output_dir(g, &digest);
+ init(g);
- if ((err = os_make_path(g->output_dir))) {
- fprintf(stderr, "Unable to create output directory: %s\n", err_str(err));
- exit(1);
- }
- }
- resolve_out_paths(g);
+ codegen_add_time_event(g, "Semantic Analysis");
+ const char *progress_name = "Semantic Analysis";
+ codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
+ progress_name, strlen(progress_name), 0));
- if (g->enable_dump_analysis || g->enable_doc_generation) {
- output_type_information(g);
- }
+ gen_root_source(g);
- if (need_llvm_module(g)) {
- codegen_add_time_event(g, "Code Generation");
- {
- const char *progress_name = "Code Generation";
- codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
- progress_name, strlen(progress_name), 0));
- }
+ resolve_out_paths(g);
- do_code_gen(g);
- codegen_add_time_event(g, "LLVM Emit Output");
- {
- const char *progress_name = "LLVM Emit Output";
- codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
- progress_name, strlen(progress_name), 0));
- }
- zig_llvm_emit_output(g);
+ if (g->enable_dump_analysis || g->enable_doc_generation) {
+ output_type_information(g);
+ }
- if (!g->disable_gen_h && (g->out_type == OutTypeObj || g->out_type == OutTypeLib)) {
- codegen_add_time_event(g, "Generate .h");
- {
- const char *progress_name = "Generate .h";
- codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
- progress_name, strlen(progress_name), 0));
- }
- gen_h_file(g);
- }
- }
+ codegen_add_time_event(g, "Code Generation");
+ {
+ const char *progress_name = "Code Generation";
+ codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
+ progress_name, strlen(progress_name), 0));
+ }
- // If we're outputting assembly or llvm IR we skip linking.
- // If we're making a library or executable we must link.
- // If there is more than one object, we have to link them (with -r).
- // Finally, if we didn't make an object from zig source, and we don't have caching enabled,
- // then we have an object from C source that we must copy to the output dir which we do with a -r link.
- if (g->emit_bin &&
- (g->out_type != OutTypeObj || g->link_objects.length > 1 ||
- (!need_llvm_module(g) && !g->enable_cache)))
- {
- codegen_link(g);
- }
+ do_code_gen(g);
+ codegen_add_time_event(g, "LLVM Emit Output");
+ {
+ const char *progress_name = "LLVM Emit Output";
+ codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
+ progress_name, strlen(progress_name), 0));
}
+ zig_llvm_emit_output(g);
- codegen_release_caches(g);
codegen_add_time_event(g, "Done");
codegen_switch_sub_prog_node(g, nullptr);
}
-void codegen_release_caches(CodeGen *g) {
- while (g->caches_to_release.length != 0) {
- cache_release(g->caches_to_release.pop());
- }
-}
-
ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path,
const char *pkg_path)
{
@@ -11125,43 +9364,17 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
return pkg;
}
-CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
- Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node)
-{
- Stage2ProgressNode *child_progress_node = stage2_progress_start(
- parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node,
- name, strlen(name), 0);
-
- CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
- parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_global_cache_dir(), false, child_progress_node);
- child_gen->root_out_name = buf_create_from_str(name);
- child_gen->disable_gen_h = true;
- child_gen->want_stack_check = WantStackCheckDisabled;
- child_gen->want_sanitize_c = WantCSanitizeDisabled;
- child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
- child_gen->verbose_ast = parent_gen->verbose_ast;
- child_gen->verbose_link = parent_gen->verbose_link;
- child_gen->verbose_ir = parent_gen->verbose_ir;
- child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir;
- child_gen->verbose_cimport = parent_gen->verbose_cimport;
- child_gen->verbose_cc = parent_gen->verbose_cc;
- child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features;
- child_gen->llvm_argv = parent_gen->llvm_argv;
-
- codegen_set_strip(child_gen, parent_gen->strip_debug_symbols);
- child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled;
- child_gen->valgrind_support = ValgrindSupportDisabled;
-
- codegen_set_errmsg_color(child_gen, parent_gen->err_color);
-
- child_gen->enable_cache = true;
-
- return child_gen;
+void codegen_destroy(CodeGen *g) {
+ if (g->pass1_arena != nullptr) {
+ g->pass1_arena->destruct(&heap::c_allocator);
+ g->pass1_arena = nullptr;
+ }
+ heap::c_allocator.destroy<CodeGen>(g);
}
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
- OutType out_type, BuildMode build_mode, Buf *override_lib_dir,
- Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
+ BuildMode build_mode, Buf *override_lib_dir,
+ bool is_test_build, Stage2ProgressNode *progress_node)
{
CodeGen *g = heap::c_allocator.create<CodeGen>();
g->emit_bin = true;
@@ -11176,24 +9389,15 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
}
g->subsystem = TargetSubsystemAuto;
- g->libc = libc;
g->zig_target = target;
- g->cache_dir = cache_dir;
- if (override_lib_dir == nullptr) {
- g->zig_lib_dir = get_zig_lib_dir();
- } else {
- g->zig_lib_dir = override_lib_dir;
- }
+ assert(override_lib_dir != nullptr);
+ g->zig_lib_dir = override_lib_dir;
g->zig_std_dir = buf_alloc();
os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
- g->zig_c_headers_dir = buf_alloc();
- os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
-
g->build_mode = build_mode;
- g->out_type = out_type;
g->import_table.init(32);
g->builtin_fn_table.init(32);
g->primitive_type_table.init(32);
@@ -11256,18 +9460,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
g->zig_std_special_dir = buf_alloc();
os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
- assert(target != nullptr);
- if (!target->is_native_os) {
- g->each_lib_rpath = false;
- } else {
- g->each_lib_rpath = true;
- }
-
- if (target_os_requires_libc(g->zig_target->os)) {
- g->libc_link_lib = create_link_lib(buf_create_from_str("c"));
- g->link_libs_list.append(g->libc_link_lib);
- }
-
target_triple_llvm(&g->llvm_triple_str, g->zig_target);
g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8;
@@ -11302,36 +9494,21 @@ void codegen_switch_sub_prog_node(CodeGen *g, Stage2ProgressNode *node) {
}
ZigValue *CodeGen::Intern::for_undefined() {
-#ifdef ZIG_ENABLE_MEM_PROFILE
- mem::intern_counters.x_undefined += 1;
-#endif
return &this->x_undefined;
}
ZigValue *CodeGen::Intern::for_void() {
-#ifdef ZIG_ENABLE_MEM_PROFILE
- mem::intern_counters.x_void += 1;
-#endif
return &this->x_void;
}
ZigValue *CodeGen::Intern::for_null() {
-#ifdef ZIG_ENABLE_MEM_PROFILE
- mem::intern_counters.x_null += 1;
-#endif
return &this->x_null;
}
ZigValue *CodeGen::Intern::for_unreachable() {
-#ifdef ZIG_ENABLE_MEM_PROFILE
- mem::intern_counters.x_unreachable += 1;
-#endif
return &this->x_unreachable;
}
ZigValue *CodeGen::Intern::for_zero_byte() {
-#ifdef ZIG_ENABLE_MEM_PROFILE
- mem::intern_counters.zero_byte += 1;
-#endif
return &this->zero_byte;
}